aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/bmap.c')
-rw-r--r--fs/gfs2/bmap.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index e84e3845a394..08d1be492ef7 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -384,6 +384,35 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
384 return 0; 384 return 0;
385} 385}
386 386
387static int lookup_metapath(struct inode *inode, struct metapath *mp,
388 int create, int *new, u64 *dblock,
389 struct buffer_head **dibh, struct buffer_head **bh)
390{
391 struct gfs2_inode *ip = GFS2_I(inode);
392 unsigned int end_of_metadata = ip->i_height - 1;
393 unsigned int x;
394 int ret = gfs2_meta_inode_buffer(ip, bh);
395 if (ret)
396 return ret;
397
398 *dibh = *bh;
399 get_bh(*dibh);
400
401 for (x = 0; x < end_of_metadata; x++) {
402 lookup_block(ip, *bh, x, mp, create, new, dblock);
403 brelse(*bh);
404 *bh = NULL;
405 if (!dblock)
406 return 0;
407
408 ret = gfs2_meta_indirect_buffer(ip, x+1, *dblock, *new, bh);
409 if (ret)
410 return ret;
411 }
412
413 return lookup_block(ip, *bh, end_of_metadata, mp, create, new, dblock);
414}
415
387static inline void bmap_lock(struct inode *inode, int create) 416static inline void bmap_lock(struct inode *inode, int create)
388{ 417{
389 struct gfs2_inode *ip = GFS2_I(inode); 418 struct gfs2_inode *ip = GFS2_I(inode);
@@ -419,10 +448,8 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
419{ 448{
420 struct gfs2_inode *ip = GFS2_I(inode); 449 struct gfs2_inode *ip = GFS2_I(inode);
421 struct gfs2_sbd *sdp = GFS2_SB(inode); 450 struct gfs2_sbd *sdp = GFS2_SB(inode);
422 struct buffer_head *bh;
423 unsigned int bsize = sdp->sd_sb.sb_bsize; 451 unsigned int bsize = sdp->sd_sb.sb_bsize;
424 unsigned int end_of_metadata; 452 struct buffer_head *bh = NULL;
425 unsigned int x;
426 int error = 0; 453 int error = 0;
427 int new = 0; 454 int new = 0;
428 u64 dblock = 0; 455 u64 dblock = 0;
@@ -459,25 +486,11 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
459 } 486 }
460 487
461 find_metapath(ip, lblock, &mp); 488 find_metapath(ip, lblock, &mp);
462 end_of_metadata = ip->i_height - 1; 489 error = lookup_metapath(inode, &mp, create, &new, &dblock, &dibh, &bh);
463 error = gfs2_meta_inode_buffer(ip, &bh); 490 if (error < 0)
464 if (error)
465 goto out_fail; 491 goto out_fail;
466 dibh = bh; 492 boundary = error;
467 get_bh(dibh);
468
469 for (x = 0; x < end_of_metadata; x++) {
470 lookup_block(ip, bh, x, &mp, create, &new, &dblock);
471 brelse(bh);
472 if (!dblock)
473 goto out_ok;
474 493
475 error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh);
476 if (error)
477 goto out_fail;
478 }
479
480 boundary = lookup_block(ip, bh, end_of_metadata, &mp, create, &new, &dblock);
481 if (dblock) { 494 if (dblock) {
482 map_bh(bh_map, inode->i_sb, dblock); 495 map_bh(bh_map, inode->i_sb, dblock);
483 if (boundary) 496 if (boundary)
@@ -489,6 +502,7 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
489 goto out_brelse; 502 goto out_brelse;
490 } 503 }
491 while(--maxlen && !buffer_boundary(bh_map)) { 504 while(--maxlen && !buffer_boundary(bh_map)) {
505 unsigned int end_of_metadata = ip->i_height - 1;
492 u64 eblock; 506 u64 eblock;
493 507
494 mp.mp_list[end_of_metadata]++; 508 mp.mp_list[end_of_metadata]++;
@@ -501,7 +515,8 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
501 } 515 }
502 } 516 }
503out_brelse: 517out_brelse:
504 brelse(bh); 518 if (bh)
519 brelse(bh);
505out_ok: 520out_ok:
506 error = 0; 521 error = 0;
507out_fail: 522out_fail: