diff options
Diffstat (limited to 'fs/gfs2/bmap.c')
-rw-r--r-- | fs/gfs2/bmap.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 93fa427bb5f5..e4effc47abfc 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -59,7 +59,6 @@ struct strip_mine { | |||
59 | static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, | 59 | static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, |
60 | u64 block, struct page *page) | 60 | u64 block, struct page *page) |
61 | { | 61 | { |
62 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
63 | struct inode *inode = &ip->i_inode; | 62 | struct inode *inode = &ip->i_inode; |
64 | struct buffer_head *bh; | 63 | struct buffer_head *bh; |
65 | int release = 0; | 64 | int release = 0; |
@@ -95,7 +94,7 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
95 | set_buffer_uptodate(bh); | 94 | set_buffer_uptodate(bh); |
96 | if (!gfs2_is_jdata(ip)) | 95 | if (!gfs2_is_jdata(ip)) |
97 | mark_buffer_dirty(bh); | 96 | mark_buffer_dirty(bh); |
98 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) | 97 | if (!gfs2_is_writeback(ip)) |
99 | gfs2_trans_add_bh(ip->i_gl, bh, 0); | 98 | gfs2_trans_add_bh(ip->i_gl, bh, 0); |
100 | 99 | ||
101 | if (release) { | 100 | if (release) { |
@@ -453,8 +452,8 @@ static inline void bmap_unlock(struct inode *inode, int create) | |||
453 | * Returns: errno | 452 | * Returns: errno |
454 | */ | 453 | */ |
455 | 454 | ||
456 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, | 455 | int gfs2_block_map(struct inode *inode, sector_t lblock, |
457 | struct buffer_head *bh_map) | 456 | struct buffer_head *bh_map, int create) |
458 | { | 457 | { |
459 | struct gfs2_inode *ip = GFS2_I(inode); | 458 | struct gfs2_inode *ip = GFS2_I(inode); |
460 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 459 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -470,6 +469,7 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int create, | |||
470 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; | 469 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; |
471 | struct metapath mp; | 470 | struct metapath mp; |
472 | u64 size; | 471 | u64 size; |
472 | struct buffer_head *dibh = NULL; | ||
473 | 473 | ||
474 | BUG_ON(maxlen == 0); | 474 | BUG_ON(maxlen == 0); |
475 | 475 | ||
@@ -500,6 +500,8 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int create, | |||
500 | error = gfs2_meta_inode_buffer(ip, &bh); | 500 | error = gfs2_meta_inode_buffer(ip, &bh); |
501 | if (error) | 501 | if (error) |
502 | goto out_fail; | 502 | goto out_fail; |
503 | dibh = bh; | ||
504 | get_bh(dibh); | ||
503 | 505 | ||
504 | for (x = 0; x < end_of_metadata; x++) { | 506 | for (x = 0; x < end_of_metadata; x++) { |
505 | lookup_block(ip, bh, x, &mp, create, &new, &dblock); | 507 | lookup_block(ip, bh, x, &mp, create, &new, &dblock); |
@@ -518,13 +520,8 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int create, | |||
518 | if (boundary) | 520 | if (boundary) |
519 | set_buffer_boundary(bh_map); | 521 | set_buffer_boundary(bh_map); |
520 | if (new) { | 522 | if (new) { |
521 | struct buffer_head *dibh; | 523 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
522 | error = gfs2_meta_inode_buffer(ip, &dibh); | 524 | gfs2_dinode_out(ip, dibh->b_data); |
523 | if (!error) { | ||
524 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
525 | gfs2_dinode_out(ip, dibh->b_data); | ||
526 | brelse(dibh); | ||
527 | } | ||
528 | set_buffer_new(bh_map); | 525 | set_buffer_new(bh_map); |
529 | goto out_brelse; | 526 | goto out_brelse; |
530 | } | 527 | } |
@@ -545,6 +542,8 @@ out_brelse: | |||
545 | out_ok: | 542 | out_ok: |
546 | error = 0; | 543 | error = 0; |
547 | out_fail: | 544 | out_fail: |
545 | if (dibh) | ||
546 | brelse(dibh); | ||
548 | bmap_unlock(inode, create); | 547 | bmap_unlock(inode, create); |
549 | return error; | 548 | return error; |
550 | } | 549 | } |
@@ -560,7 +559,7 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi | |||
560 | BUG_ON(!new); | 559 | BUG_ON(!new); |
561 | 560 | ||
562 | bh.b_size = 1 << (inode->i_blkbits + 5); | 561 | bh.b_size = 1 << (inode->i_blkbits + 5); |
563 | ret = gfs2_block_map(inode, lblock, create, &bh); | 562 | ret = gfs2_block_map(inode, lblock, &bh, create); |
564 | *extlen = bh.b_size >> inode->i_blkbits; | 563 | *extlen = bh.b_size >> inode->i_blkbits; |
565 | *dblock = bh.b_blocknr; | 564 | *dblock = bh.b_blocknr; |
566 | if (buffer_new(&bh)) | 565 | if (buffer_new(&bh)) |
@@ -684,7 +683,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
684 | if (metadata) | 683 | if (metadata) |
685 | revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs; | 684 | revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs; |
686 | 685 | ||
687 | error = gfs2_rindex_hold(sdp, &ip->i_alloc.al_ri_gh); | 686 | error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); |
688 | if (error) | 687 | if (error) |
689 | return error; | 688 | return error; |
690 | 689 | ||
@@ -786,7 +785,7 @@ out_rg_gunlock: | |||
786 | out_rlist: | 785 | out_rlist: |
787 | gfs2_rlist_free(&rlist); | 786 | gfs2_rlist_free(&rlist); |
788 | out: | 787 | out: |
789 | gfs2_glock_dq_uninit(&ip->i_alloc.al_ri_gh); | 788 | gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh); |
790 | return error; | 789 | return error; |
791 | } | 790 | } |
792 | 791 | ||
@@ -879,7 +878,6 @@ static int gfs2_block_truncate_page(struct address_space *mapping) | |||
879 | { | 878 | { |
880 | struct inode *inode = mapping->host; | 879 | struct inode *inode = mapping->host; |
881 | struct gfs2_inode *ip = GFS2_I(inode); | 880 | struct gfs2_inode *ip = GFS2_I(inode); |
882 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
883 | loff_t from = inode->i_size; | 881 | loff_t from = inode->i_size; |
884 | unsigned long index = from >> PAGE_CACHE_SHIFT; | 882 | unsigned long index = from >> PAGE_CACHE_SHIFT; |
885 | unsigned offset = from & (PAGE_CACHE_SIZE-1); | 883 | unsigned offset = from & (PAGE_CACHE_SIZE-1); |
@@ -911,7 +909,7 @@ static int gfs2_block_truncate_page(struct address_space *mapping) | |||
911 | err = 0; | 909 | err = 0; |
912 | 910 | ||
913 | if (!buffer_mapped(bh)) { | 911 | if (!buffer_mapped(bh)) { |
914 | gfs2_get_block(inode, iblock, bh, 0); | 912 | gfs2_block_map(inode, iblock, bh, 0); |
915 | /* unmapped? It's a hole - nothing to do */ | 913 | /* unmapped? It's a hole - nothing to do */ |
916 | if (!buffer_mapped(bh)) | 914 | if (!buffer_mapped(bh)) |
917 | goto unlock; | 915 | goto unlock; |
@@ -931,7 +929,7 @@ static int gfs2_block_truncate_page(struct address_space *mapping) | |||
931 | err = 0; | 929 | err = 0; |
932 | } | 930 | } |
933 | 931 | ||
934 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) | 932 | if (!gfs2_is_writeback(ip)) |
935 | gfs2_trans_add_bh(ip->i_gl, bh, 0); | 933 | gfs2_trans_add_bh(ip->i_gl, bh, 0); |
936 | 934 | ||
937 | zero_user_page(page, offset, length, KM_USER0); | 935 | zero_user_page(page, offset, length, KM_USER0); |
@@ -1224,8 +1222,13 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, | |||
1224 | do_div(lblock_stop, bsize); | 1222 | do_div(lblock_stop, bsize); |
1225 | } else { | 1223 | } else { |
1226 | unsigned int shift = sdp->sd_sb.sb_bsize_shift; | 1224 | unsigned int shift = sdp->sd_sb.sb_bsize_shift; |
1225 | u64 end_of_file = (ip->i_di.di_size + sdp->sd_sb.sb_bsize - 1) >> shift; | ||
1227 | lblock = offset >> shift; | 1226 | lblock = offset >> shift; |
1228 | lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; | 1227 | lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; |
1228 | if (lblock_stop > end_of_file) { | ||
1229 | *alloc_required = 1; | ||
1230 | return 0; | ||
1231 | } | ||
1229 | } | 1232 | } |
1230 | 1233 | ||
1231 | for (; lblock < lblock_stop; lblock += extlen) { | 1234 | for (; lblock < lblock_stop; lblock += extlen) { |