buffer.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/fs/hpfs/buffer.c
  4. *
  5. * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  6. *
  7. * general buffer i/o
  8. */
  9. #include <linux/sched.h>
  10. #include <linux/slab.h>
  11. #include <linux/blkdev.h>
  12. #include "hpfs_fn.h"
  13. secno hpfs_search_hotfix_map(struct super_block *s, secno sec)
  14. {
  15. unsigned i;
  16. struct hpfs_sb_info *sbi = hpfs_sb(s);
  17. for (i = 0; unlikely(i < sbi->n_hotfixes); i++) {
  18. if (sbi->hotfix_from[i] == sec) {
  19. return sbi->hotfix_to[i];
  20. }
  21. }
  22. return sec;
  23. }
  24. unsigned hpfs_search_hotfix_map_for_range(struct super_block *s, secno sec, unsigned n)
  25. {
  26. unsigned i;
  27. struct hpfs_sb_info *sbi = hpfs_sb(s);
  28. for (i = 0; unlikely(i < sbi->n_hotfixes); i++) {
  29. if (sbi->hotfix_from[i] >= sec && sbi->hotfix_from[i] < sec + n) {
  30. n = sbi->hotfix_from[i] - sec;
  31. }
  32. }
  33. return n;
  34. }
  35. void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n)
  36. {
  37. struct buffer_head *bh;
  38. struct blk_plug plug;
  39. if (n <= 0 || unlikely(secno >= hpfs_sb(s)->sb_fs_size))
  40. return;
  41. if (unlikely(hpfs_search_hotfix_map_for_range(s, secno, n) != n))
  42. return;
  43. bh = sb_find_get_block(s, secno);
  44. if (bh) {
  45. if (buffer_uptodate(bh)) {
  46. brelse(bh);
  47. return;
  48. }
  49. brelse(bh);
  50. }
  51. blk_start_plug(&plug);
  52. while (n > 0) {
  53. if (unlikely(secno >= hpfs_sb(s)->sb_fs_size))
  54. break;
  55. sb_breadahead(s, secno);
  56. secno++;
  57. n--;
  58. }
  59. blk_finish_plug(&plug);
  60. }
  61. /* Map a sector into a buffer and return pointers to it and to the buffer. */
  62. void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp,
  63. int ahead)
  64. {
  65. struct buffer_head *bh;
  66. hpfs_lock_assert(s);
  67. hpfs_prefetch_sectors(s, secno, ahead);
  68. cond_resched();
  69. *bhp = bh = sb_bread(s, hpfs_search_hotfix_map(s, secno));
  70. if (bh != NULL)
  71. return bh->b_data;
  72. else {
  73. pr_err("%s(): read error\n", __func__);
  74. return NULL;
  75. }
  76. }
  77. /* Like hpfs_map_sector but don't read anything */
  78. void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp)
  79. {
  80. struct buffer_head *bh;
  81. /*return hpfs_map_sector(s, secno, bhp, 0);*/
  82. hpfs_lock_assert(s);
  83. cond_resched();
  84. if ((*bhp = bh = sb_getblk(s, hpfs_search_hotfix_map(s, secno))) != NULL) {
  85. if (!buffer_uptodate(bh)) wait_on_buffer(bh);
  86. set_buffer_uptodate(bh);
  87. return bh->b_data;
  88. } else {
  89. pr_err("%s(): getblk failed\n", __func__);
  90. return NULL;
  91. }
  92. }
  93. /* Map 4 sectors into a 4buffer and return pointers to it and to the buffer. */
  94. void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh,
  95. int ahead)
  96. {
  97. char *data;
  98. hpfs_lock_assert(s);
  99. cond_resched();
  100. if (secno & 3) {
  101. pr_err("%s(): unaligned read\n", __func__);
  102. return NULL;
  103. }
  104. hpfs_prefetch_sectors(s, secno, 4 + ahead);
  105. if (!hpfs_map_sector(s, secno + 0, &qbh->bh[0], 0)) goto bail0;
  106. if (!hpfs_map_sector(s, secno + 1, &qbh->bh[1], 0)) goto bail1;
  107. if (!hpfs_map_sector(s, secno + 2, &qbh->bh[2], 0)) goto bail2;
  108. if (!hpfs_map_sector(s, secno + 3, &qbh->bh[3], 0)) goto bail3;
  109. if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) &&
  110. likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) &&
  111. likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) {
  112. return qbh->data = qbh->bh[0]->b_data;
  113. }
  114. qbh->data = data = kmalloc(2048, GFP_NOFS);
  115. if (!data) {
  116. pr_err("%s(): out of memory\n", __func__);
  117. goto bail4;
  118. }
  119. memcpy(data + 0 * 512, qbh->bh[0]->b_data, 512);
  120. memcpy(data + 1 * 512, qbh->bh[1]->b_data, 512);
  121. memcpy(data + 2 * 512, qbh->bh[2]->b_data, 512);
  122. memcpy(data + 3 * 512, qbh->bh[3]->b_data, 512);
  123. return data;
  124. bail4:
  125. brelse(qbh->bh[3]);
  126. bail3:
  127. brelse(qbh->bh[2]);
  128. bail2:
  129. brelse(qbh->bh[1]);
  130. bail1:
  131. brelse(qbh->bh[0]);
  132. bail0:
  133. return NULL;
  134. }
  135. /* Don't read sectors */
  136. void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
  137. struct quad_buffer_head *qbh)
  138. {
  139. cond_resched();
  140. hpfs_lock_assert(s);
  141. if (secno & 3) {
  142. pr_err("%s(): unaligned read\n", __func__);
  143. return NULL;
  144. }
  145. if (!hpfs_get_sector(s, secno + 0, &qbh->bh[0])) goto bail0;
  146. if (!hpfs_get_sector(s, secno + 1, &qbh->bh[1])) goto bail1;
  147. if (!hpfs_get_sector(s, secno + 2, &qbh->bh[2])) goto bail2;
  148. if (!hpfs_get_sector(s, secno + 3, &qbh->bh[3])) goto bail3;
  149. if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) &&
  150. likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) &&
  151. likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) {
  152. return qbh->data = qbh->bh[0]->b_data;
  153. }
  154. if (!(qbh->data = kmalloc(2048, GFP_NOFS))) {
  155. pr_err("%s(): out of memory\n", __func__);
  156. goto bail4;
  157. }
  158. return qbh->data;
  159. bail4:
  160. brelse(qbh->bh[3]);
  161. bail3:
  162. brelse(qbh->bh[2]);
  163. bail2:
  164. brelse(qbh->bh[1]);
  165. bail1:
  166. brelse(qbh->bh[0]);
  167. bail0:
  168. return NULL;
  169. }
  170. void hpfs_brelse4(struct quad_buffer_head *qbh)
  171. {
  172. if (unlikely(qbh->data != qbh->bh[0]->b_data))
  173. kfree(qbh->data);
  174. brelse(qbh->bh[0]);
  175. brelse(qbh->bh[1]);
  176. brelse(qbh->bh[2]);
  177. brelse(qbh->bh[3]);
  178. }
  179. void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh)
  180. {
  181. if (unlikely(qbh->data != qbh->bh[0]->b_data)) {
  182. memcpy(qbh->bh[0]->b_data, qbh->data + 0 * 512, 512);
  183. memcpy(qbh->bh[1]->b_data, qbh->data + 1 * 512, 512);
  184. memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512);
  185. memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512);
  186. }
  187. mark_buffer_dirty(qbh->bh[0]);
  188. mark_buffer_dirty(qbh->bh[1]);
  189. mark_buffer_dirty(qbh->bh[2]);
  190. mark_buffer_dirty(qbh->bh[3]);
  191. }