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