aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/hpfs/buffer.c96
1 files changed, 50 insertions, 46 deletions
diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c
index 4d0a1afa058c..139ef1684d07 100644
--- a/fs/hpfs/buffer.c
+++ b/fs/hpfs/buffer.c
@@ -86,7 +86,6 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head
86void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh, 86void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh,
87 int ahead) 87 int ahead)
88{ 88{
89 struct buffer_head *bh;
90 char *data; 89 char *data;
91 90
92 hpfs_lock_assert(s); 91 hpfs_lock_assert(s);
@@ -100,34 +99,32 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe
100 99
101 hpfs_prefetch_sectors(s, secno, 4 + ahead); 100 hpfs_prefetch_sectors(s, secno, 4 + ahead);
102 101
102 if (!(qbh->bh[0] = sb_bread(s, secno + 0))) goto bail0;
103 if (!(qbh->bh[1] = sb_bread(s, secno + 1))) goto bail1;
104 if (!(qbh->bh[2] = sb_bread(s, secno + 2))) goto bail2;
105 if (!(qbh->bh[3] = sb_bread(s, secno + 3))) goto bail3;
106
107 if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) &&
108 likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) &&
109 likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) {
110 return qbh->data = qbh->bh[0]->b_data;
111 }
112
103 qbh->data = data = kmalloc(2048, GFP_NOFS); 113 qbh->data = data = kmalloc(2048, GFP_NOFS);
104 if (!data) { 114 if (!data) {
105 printk("HPFS: hpfs_map_4sectors: out of memory\n"); 115 printk("HPFS: hpfs_map_4sectors: out of memory\n");
106 goto bail; 116 goto bail4;
107 } 117 }
108 118
109 qbh->bh[0] = bh = sb_bread(s, secno); 119 memcpy(data + 0 * 512, qbh->bh[0]->b_data, 512);
110 if (!bh) 120 memcpy(data + 1 * 512, qbh->bh[1]->b_data, 512);
111 goto bail0; 121 memcpy(data + 2 * 512, qbh->bh[2]->b_data, 512);
112 memcpy(data, bh->b_data, 512); 122 memcpy(data + 3 * 512, qbh->bh[3]->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 123
129 return data; 124 return data;
130 125
126 bail4:
127 brelse(qbh->bh[3]);
131 bail3: 128 bail3:
132 brelse(qbh->bh[2]); 129 brelse(qbh->bh[2]);
133 bail2: 130 bail2:
@@ -135,9 +132,6 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe
135 bail1: 132 bail1:
136 brelse(qbh->bh[0]); 133 brelse(qbh->bh[0]);
137 bail0: 134 bail0:
138 kfree(data);
139 printk("HPFS: hpfs_map_4sectors: read error\n");
140 bail:
141 return NULL; 135 return NULL;
142} 136}
143 137
@@ -155,44 +149,54 @@ void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
155 return NULL; 149 return NULL;
156 } 150 }
157 151
158 /*return hpfs_map_4sectors(s, secno, qbh, 0);*/ 152 if (!hpfs_get_sector(s, secno + 0, &qbh->bh[0])) goto bail0;
153 if (!hpfs_get_sector(s, secno + 1, &qbh->bh[1])) goto bail1;
154 if (!hpfs_get_sector(s, secno + 2, &qbh->bh[2])) goto bail2;
155 if (!hpfs_get_sector(s, secno + 3, &qbh->bh[3])) goto bail3;
156
157 if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) &&
158 likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) &&
159 likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) {
160 return qbh->data = qbh->bh[0]->b_data;
161 }
162
159 if (!(qbh->data = kmalloc(2048, GFP_NOFS))) { 163 if (!(qbh->data = kmalloc(2048, GFP_NOFS))) {
160 printk("HPFS: hpfs_get_4sectors: out of memory\n"); 164 printk("HPFS: hpfs_get_4sectors: out of memory\n");
161 return NULL; 165 goto bail4;
162 } 166 }
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; 167 return qbh->data;
172 168
173 bail3: brelse(qbh->bh[2]); 169bail4:
174 bail2: brelse(qbh->bh[1]); 170 brelse(qbh->bh[3]);
175 bail1: brelse(qbh->bh[0]); 171bail3:
176 bail0: 172 brelse(qbh->bh[2]);
173bail2:
174 brelse(qbh->bh[1]);
175bail1:
176 brelse(qbh->bh[0]);
177bail0:
177 return NULL; 178 return NULL;
178} 179}
179 180
180 181
181void hpfs_brelse4(struct quad_buffer_head *qbh) 182void hpfs_brelse4(struct quad_buffer_head *qbh)
182{ 183{
183 brelse(qbh->bh[3]); 184 if (unlikely(qbh->data != qbh->bh[0]->b_data))
184 brelse(qbh->bh[2]); 185 kfree(qbh->data);
185 brelse(qbh->bh[1]);
186 brelse(qbh->bh[0]); 186 brelse(qbh->bh[0]);
187 kfree(qbh->data); 187 brelse(qbh->bh[1]);
188 brelse(qbh->bh[2]);
189 brelse(qbh->bh[3]);
188} 190}
189 191
190void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh) 192void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh)
191{ 193{
192 memcpy(qbh->bh[0]->b_data, qbh->data, 512); 194 if (unlikely(qbh->data != qbh->bh[0]->b_data)) {
193 memcpy(qbh->bh[1]->b_data, qbh->data + 512, 512); 195 memcpy(qbh->bh[0]->b_data, qbh->data + 0 * 512, 512);
194 memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512); 196 memcpy(qbh->bh[1]->b_data, qbh->data + 1 * 512, 512);
195 memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512); 197 memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512);
198 memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512);
199 }
196 mark_buffer_dirty(qbh->bh[0]); 200 mark_buffer_dirty(qbh->bh[0]);
197 mark_buffer_dirty(qbh->bh[1]); 201 mark_buffer_dirty(qbh->bh[1]);
198 mark_buffer_dirty(qbh->bh[2]); 202 mark_buffer_dirty(qbh->bh[2]);