aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/bmap.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index e27e66046f0a..f1f38ca77a52 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -188,50 +188,45 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
188{ 188{
189 struct gfs2_inode *ip = GFS2_I(inode); 189 struct gfs2_inode *ip = GFS2_I(inode);
190 unsigned new_height = height - ip->i_height; 190 unsigned new_height = height - ip->i_height;
191 struct buffer_head *dibh; 191 struct buffer_head *dibh = mp->mp_bh[0];
192 struct gfs2_dinode *di; 192 struct gfs2_dinode *di;
193 int error;
194 __be64 *bp; 193 __be64 *bp;
195 u64 bn; 194 u64 bn;
196 unsigned n, i = 0; 195 unsigned n, i = 0;
197 196
198 if (height <= ip->i_height) 197 BUG_ON(height <= ip->i_height);
199 return 0;
200
201 error = gfs2_meta_inode_buffer(ip, &dibh);
202 if (error)
203 return error;
204 198
205 do { 199 do {
206 n = new_height - i; 200 n = new_height - i;
207 bn = gfs2_alloc_block(ip, &n); 201 bn = gfs2_alloc_block(ip, &n);
208 gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, n); 202 gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, n);
209 do { 203 do {
210 mp->mp_bh[i] = gfs2_meta_new(ip->i_gl, bn++); 204 mp->mp_bh[i + 1] = gfs2_meta_new(ip->i_gl, bn++);
211 gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[i], 1); 205 gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[i + 1], 1);
212 i++; 206 i++;
213 } while(i < n); 207 } while(i < n);
214 } while(i < new_height); 208 } while(i < new_height);
215 209
216 n = 0; 210 n = 0;
217 bn = mp->mp_bh[0]->b_blocknr; 211 bn = mp->mp_bh[1]->b_blocknr;
218 if (new_height > 1) { 212 if (new_height > 1) {
219 for(; n < new_height-1; n++) { 213 for(; n < new_height-1; n++) {
220 gfs2_metatype_set(mp->mp_bh[n], GFS2_METATYPE_IN, 214 gfs2_metatype_set(mp->mp_bh[n + 1], GFS2_METATYPE_IN,
221 GFS2_FORMAT_IN); 215 GFS2_FORMAT_IN);
222 gfs2_buffer_clear_tail(mp->mp_bh[n], 216 gfs2_buffer_clear_tail(mp->mp_bh[n + 1],
223 sizeof(struct gfs2_meta_header)); 217 sizeof(struct gfs2_meta_header));
224 bp = (__be64 *)(mp->mp_bh[n]->b_data + 218 bp = (__be64 *)(mp->mp_bh[n + 1]->b_data +
225 sizeof(struct gfs2_meta_header)); 219 sizeof(struct gfs2_meta_header));
226 *bp = cpu_to_be64(mp->mp_bh[n+1]->b_blocknr); 220 *bp = cpu_to_be64(mp->mp_bh[n+2]->b_blocknr);
227 brelse(mp->mp_bh[n]); 221 brelse(mp->mp_bh[n+1]);
228 mp->mp_bh[n] = NULL; 222 mp->mp_bh[n+1] = NULL;
229 } 223 }
230 } 224 }
231 gfs2_metatype_set(mp->mp_bh[n], GFS2_METATYPE_IN, GFS2_FORMAT_IN); 225 gfs2_metatype_set(mp->mp_bh[n+1], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
232 gfs2_buffer_copy_tail(mp->mp_bh[n], sizeof(struct gfs2_meta_header), 226 gfs2_buffer_copy_tail(mp->mp_bh[n+1], sizeof(struct gfs2_meta_header),
233 dibh, sizeof(struct gfs2_dinode)); 227 dibh, sizeof(struct gfs2_dinode));
234 brelse(mp->mp_bh[n]); 228 brelse(mp->mp_bh[n+1]);
229 mp->mp_bh[n+1] = NULL;
235 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 230 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
236 di = (struct gfs2_dinode *)dibh->b_data; 231 di = (struct gfs2_dinode *)dibh->b_data;
237 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); 232 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
@@ -240,8 +235,7 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
240 gfs2_add_inode_blocks(&ip->i_inode, new_height); 235 gfs2_add_inode_blocks(&ip->i_inode, new_height);
241 di->di_height = cpu_to_be16(ip->i_height); 236 di->di_height = cpu_to_be16(ip->i_height);
242 di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); 237 di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
243 brelse(dibh); 238 return 0;
244 return error;
245} 239}
246 240
247/** 241/**
@@ -391,11 +385,7 @@ static int lookup_metapath(struct inode *inode, struct metapath *mp,
391 struct gfs2_inode *ip = GFS2_I(inode); 385 struct gfs2_inode *ip = GFS2_I(inode);
392 unsigned int end_of_metadata = ip->i_height - 1; 386 unsigned int end_of_metadata = ip->i_height - 1;
393 unsigned int x; 387 unsigned int x;
394 int ret = gfs2_meta_inode_buffer(ip, &bh); 388 int ret;
395 if (ret)
396 return ret;
397
398 mp->mp_bh[0] = bh;
399 389
400 for (x = 0; x < end_of_metadata; x++) { 390 for (x = 0; x < end_of_metadata; x++) {
401 lookup_block(ip, x, mp, create, new, dblock); 391 lookup_block(ip, x, mp, create, new, dblock);
@@ -515,6 +505,10 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
515 } 505 }
516 size = (lblock + 1) * bsize; 506 size = (lblock + 1) * bsize;
517 507
508 error = gfs2_meta_inode_buffer(ip, &mp.mp_bh[0]);
509 if (error)
510 goto out_fail;
511
518 if (size > arr[ip->i_height]) { 512 if (size > arr[ip->i_height]) {
519 u8 height = ip->i_height; 513 u8 height = ip->i_height;
520 if (!create) 514 if (!create)