diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-10-13 17:25:45 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-10-20 09:13:40 -0400 |
commit | 23591256d61354e20f12e98d7a496ad5c23de74c (patch) | |
tree | 3013a6e873a6e0a1d55fbace2fba638a978108c0 | |
parent | 42fb00838a644d03f9a2a5fbbe0b668a5ff5df4d (diff) |
[GFS2] Fix bmap to map extents properly
This fix means that bmap will map extents of the length requested
by the VFS rather than guessing at it, or just mapping one block
at a time. The other callers of gfs2_block_map are audited to ensure
they send the correct max extent lengths (i.e. set bh->b_size correctly).
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r-- | fs/gfs2/bmap.c | 13 | ||||
-rw-r--r-- | fs/gfs2/bmap.h | 2 | ||||
-rw-r--r-- | fs/gfs2/log.c | 6 | ||||
-rw-r--r-- | fs/gfs2/ops_address.c | 6 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 5 | ||||
-rw-r--r-- | fs/gfs2/recovery.c | 5 |
6 files changed, 21 insertions, 16 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index cc57f2ecd219..06e9a8cb45e9 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -434,8 +434,7 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
434 | */ | 434 | */ |
435 | 435 | ||
436 | static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | 436 | static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, |
437 | struct buffer_head *bh_map, struct metapath *mp, | 437 | struct buffer_head *bh_map, struct metapath *mp) |
438 | unsigned int maxlen) | ||
439 | { | 438 | { |
440 | struct gfs2_inode *ip = GFS2_I(inode); | 439 | struct gfs2_inode *ip = GFS2_I(inode); |
441 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 440 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -448,6 +447,7 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
448 | int new = 0; | 447 | int new = 0; |
449 | u64 dblock = 0; | 448 | u64 dblock = 0; |
450 | int boundary; | 449 | int boundary; |
450 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; | ||
451 | 451 | ||
452 | BUG_ON(maxlen == 0); | 452 | BUG_ON(maxlen == 0); |
453 | 453 | ||
@@ -541,13 +541,13 @@ static inline void bmap_unlock(struct inode *inode, int create) | |||
541 | } | 541 | } |
542 | 542 | ||
543 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, | 543 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, |
544 | struct buffer_head *bh, unsigned int maxlen) | 544 | struct buffer_head *bh) |
545 | { | 545 | { |
546 | struct metapath mp; | 546 | struct metapath mp; |
547 | int ret; | 547 | int ret; |
548 | 548 | ||
549 | bmap_lock(inode, create); | 549 | bmap_lock(inode, create); |
550 | ret = gfs2_block_pointers(inode, lblock, create, bh, &mp, maxlen); | 550 | ret = gfs2_block_pointers(inode, lblock, create, bh, &mp); |
551 | bmap_unlock(inode, create); | 551 | bmap_unlock(inode, create); |
552 | return ret; | 552 | return ret; |
553 | } | 553 | } |
@@ -555,7 +555,7 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int create, | |||
555 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) | 555 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) |
556 | { | 556 | { |
557 | struct metapath mp; | 557 | struct metapath mp; |
558 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0, .b_size = 0 }; | 558 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; |
559 | int ret; | 559 | int ret; |
560 | int create = *new; | 560 | int create = *new; |
561 | 561 | ||
@@ -563,8 +563,9 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi | |||
563 | BUG_ON(!dblock); | 563 | BUG_ON(!dblock); |
564 | BUG_ON(!new); | 564 | BUG_ON(!new); |
565 | 565 | ||
566 | bh.b_size = 1 << (inode->i_blkbits + 5); | ||
566 | bmap_lock(inode, create); | 567 | bmap_lock(inode, create); |
567 | ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp, 32); | 568 | ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp); |
568 | bmap_unlock(inode, create); | 569 | bmap_unlock(inode, create); |
569 | *extlen = bh.b_size >> inode->i_blkbits; | 570 | *extlen = bh.b_size >> inode->i_blkbits; |
570 | *dblock = bh.b_blocknr; | 571 | *dblock = bh.b_blocknr; |
diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h index 0fd379b4cd9e..ac2fd04370dc 100644 --- a/fs/gfs2/bmap.h +++ b/fs/gfs2/bmap.h | |||
@@ -15,7 +15,7 @@ struct gfs2_inode; | |||
15 | struct page; | 15 | struct page; |
16 | 16 | ||
17 | int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); | 17 | int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); |
18 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh, unsigned int maxlen); | 18 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh); |
19 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); | 19 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); |
20 | 20 | ||
21 | int gfs2_truncatei(struct gfs2_inode *ip, u64 size); | 21 | int gfs2_truncatei(struct gfs2_inode *ip, u64 size); |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 72eec6542d6a..0cace3da9dbb 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -312,10 +312,12 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) | |||
312 | 312 | ||
313 | static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) | 313 | static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) |
314 | { | 314 | { |
315 | struct inode *inode = sdp->sd_jdesc->jd_inode; | ||
315 | int error; | 316 | int error; |
316 | struct buffer_head bh_map; | 317 | struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 }; |
317 | 318 | ||
318 | error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, 0, &bh_map, 1); | 319 | bh_map.b_size = 1 << inode->i_blkbits; |
320 | error = gfs2_block_map(inode, lbn, 0, &bh_map); | ||
319 | if (error || !bh_map.b_blocknr) | 321 | if (error || !bh_map.b_blocknr) |
320 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn); | 322 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn); |
321 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); | 323 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); |
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index e0599fed99ce..8d5963c7e123 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -65,7 +65,7 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, | |||
65 | int gfs2_get_block(struct inode *inode, sector_t lblock, | 65 | int gfs2_get_block(struct inode *inode, sector_t lblock, |
66 | struct buffer_head *bh_result, int create) | 66 | struct buffer_head *bh_result, int create) |
67 | { | 67 | { |
68 | return gfs2_block_map(inode, lblock, create, bh_result, 32); | 68 | return gfs2_block_map(inode, lblock, create, bh_result); |
69 | } | 69 | } |
70 | 70 | ||
71 | /** | 71 | /** |
@@ -83,7 +83,7 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock, | |||
83 | { | 83 | { |
84 | int error; | 84 | int error; |
85 | 85 | ||
86 | error = gfs2_block_map(inode, lblock, 0, bh_result, 1); | 86 | error = gfs2_block_map(inode, lblock, 0, bh_result); |
87 | if (error) | 87 | if (error) |
88 | return error; | 88 | return error; |
89 | if (bh_result->b_blocknr == 0) | 89 | if (bh_result->b_blocknr == 0) |
@@ -94,7 +94,7 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock, | |||
94 | static int gfs2_get_block_direct(struct inode *inode, sector_t lblock, | 94 | static int gfs2_get_block_direct(struct inode *inode, sector_t lblock, |
95 | struct buffer_head *bh_result, int create) | 95 | struct buffer_head *bh_result, int create) |
96 | { | 96 | { |
97 | return gfs2_block_map(inode, lblock, 0, bh_result, 32); | 97 | return gfs2_block_map(inode, lblock, 0, bh_result); |
98 | } | 98 | } |
99 | 99 | ||
100 | /** | 100 | /** |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c69b94a55588..a3deae7416c9 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -251,7 +251,7 @@ static int bh_get(struct gfs2_quota_data *qd) | |||
251 | unsigned int block, offset; | 251 | unsigned int block, offset; |
252 | struct buffer_head *bh; | 252 | struct buffer_head *bh; |
253 | int error; | 253 | int error; |
254 | struct buffer_head bh_map; | 254 | struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 }; |
255 | 255 | ||
256 | mutex_lock(&sdp->sd_quota_mutex); | 256 | mutex_lock(&sdp->sd_quota_mutex); |
257 | 257 | ||
@@ -263,7 +263,8 @@ static int bh_get(struct gfs2_quota_data *qd) | |||
263 | block = qd->qd_slot / sdp->sd_qc_per_block; | 263 | block = qd->qd_slot / sdp->sd_qc_per_block; |
264 | offset = qd->qd_slot % sdp->sd_qc_per_block;; | 264 | offset = qd->qd_slot % sdp->sd_qc_per_block;; |
265 | 265 | ||
266 | error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map, 1); | 266 | bh_map.b_size = 1 << ip->i_inode.i_blkbits; |
267 | error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map); | ||
267 | if (error) | 268 | if (error) |
268 | goto fail; | 269 | goto fail; |
269 | error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh); | 270 | error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh); |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 0a8a4b87dcc6..62cd223819b7 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -372,11 +372,12 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | |||
372 | u32 hash; | 372 | u32 hash; |
373 | struct buffer_head *bh; | 373 | struct buffer_head *bh; |
374 | int error; | 374 | int error; |
375 | struct buffer_head bh_map; | 375 | struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 }; |
376 | 376 | ||
377 | lblock = head->lh_blkno; | 377 | lblock = head->lh_blkno; |
378 | gfs2_replay_incr_blk(sdp, &lblock); | 378 | gfs2_replay_incr_blk(sdp, &lblock); |
379 | error = gfs2_block_map(&ip->i_inode, lblock, 0, &bh_map, 1); | 379 | bh_map.b_size = 1 << ip->i_inode.i_blkbits; |
380 | error = gfs2_block_map(&ip->i_inode, lblock, 0, &bh_map); | ||
380 | if (error) | 381 | if (error) |
381 | return error; | 382 | return error; |
382 | if (!bh_map.b_blocknr) { | 383 | if (!bh_map.b_blocknr) { |