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