aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-10-13 17:25:45 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-10-20 09:13:40 -0400
commit23591256d61354e20f12e98d7a496ad5c23de74c (patch)
tree3013a6e873a6e0a1d55fbace2fba638a978108c0
parent42fb00838a644d03f9a2a5fbbe0b668a5ff5df4d (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.c13
-rw-r--r--fs/gfs2/bmap.h2
-rw-r--r--fs/gfs2/log.c6
-rw-r--r--fs/gfs2/ops_address.c6
-rw-r--r--fs/gfs2/quota.c5
-rw-r--r--fs/gfs2/recovery.c5
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
436static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, 436static 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
543int gfs2_block_map(struct inode *inode, u64 lblock, int create, 543int 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,
555int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) 555int 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;
15struct page; 15struct page;
16 16
17int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); 17int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page);
18int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh, unsigned int maxlen); 18int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh);
19int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); 19int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);
20 20
21int gfs2_truncatei(struct gfs2_inode *ip, u64 size); 21int 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
313static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) 313static 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,
65int gfs2_get_block(struct inode *inode, sector_t lblock, 65int 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,
94static int gfs2_get_block_direct(struct inode *inode, sector_t lblock, 94static 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) {