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