at v2.6.13 175 lines 4.0 kB view raw
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 9#include "hpfs_fn.h" 10 11void 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 19void 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 29void *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 47void *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 66void *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 = (char *)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 122void *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 155void 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 164void 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}