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