diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-24 21:09:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-24 21:09:47 -0400 |
commit | 035cfc61a523343fe0bee5ec54348e26f330a06c (patch) | |
tree | d733127661d643a936416025a46199895fbd18c0 | |
parent | 919c0d14ae93073a3957c018a6d86ceb1e2e454b (diff) | |
parent | 5af4e7a0bea715f2dd7190859a43eb2258b1f388 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes:
[GFS2] fix gfs2 block allocation (cleaned up)
[GFS2] BUG: unable to handle kernel paging request at ffff81002690e000
-rw-r--r-- | fs/gfs2/bmap.c | 23 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 |
2 files changed, 10 insertions, 15 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index c19184f2e70e..bec76b1c2bb0 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -246,15 +246,11 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block, | |||
246 | 246 | ||
247 | } | 247 | } |
248 | 248 | ||
249 | static inline unsigned int zero_metapath_length(const struct metapath *mp, | 249 | static inline unsigned int metapath_branch_start(const struct metapath *mp) |
250 | unsigned height) | ||
251 | { | 250 | { |
252 | unsigned int i; | 251 | if (mp->mp_list[0] == 0) |
253 | for (i = 0; i < height - 1; i++) { | 252 | return 2; |
254 | if (mp->mp_list[i] != 0) | 253 | return 1; |
255 | return i; | ||
256 | } | ||
257 | return height; | ||
258 | } | 254 | } |
259 | 255 | ||
260 | /** | 256 | /** |
@@ -436,7 +432,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, | |||
436 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 432 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
437 | struct buffer_head *dibh = mp->mp_bh[0]; | 433 | struct buffer_head *dibh = mp->mp_bh[0]; |
438 | u64 bn, dblock = 0; | 434 | u64 bn, dblock = 0; |
439 | unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0; | 435 | unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0; |
440 | unsigned dblks = 0; | 436 | unsigned dblks = 0; |
441 | unsigned ptrs_per_blk; | 437 | unsigned ptrs_per_blk; |
442 | const unsigned end_of_metadata = height - 1; | 438 | const unsigned end_of_metadata = height - 1; |
@@ -471,9 +467,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, | |||
471 | /* Building up tree height */ | 467 | /* Building up tree height */ |
472 | state = ALLOC_GROW_HEIGHT; | 468 | state = ALLOC_GROW_HEIGHT; |
473 | iblks = height - ip->i_height; | 469 | iblks = height - ip->i_height; |
474 | zmpl = zero_metapath_length(mp, height); | 470 | branch_start = metapath_branch_start(mp); |
475 | iblks -= zmpl; | 471 | iblks += (height - branch_start); |
476 | iblks += height; | ||
477 | } | 472 | } |
478 | } | 473 | } |
479 | 474 | ||
@@ -509,13 +504,13 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, | |||
509 | sizeof(struct gfs2_meta_header)); | 504 | sizeof(struct gfs2_meta_header)); |
510 | *ptr = zero_bn; | 505 | *ptr = zero_bn; |
511 | state = ALLOC_GROW_DEPTH; | 506 | state = ALLOC_GROW_DEPTH; |
512 | for(i = zmpl; i < height; i++) { | 507 | for(i = branch_start; i < height; i++) { |
513 | if (mp->mp_bh[i] == NULL) | 508 | if (mp->mp_bh[i] == NULL) |
514 | break; | 509 | break; |
515 | brelse(mp->mp_bh[i]); | 510 | brelse(mp->mp_bh[i]); |
516 | mp->mp_bh[i] = NULL; | 511 | mp->mp_bh[i] = NULL; |
517 | } | 512 | } |
518 | i = zmpl; | 513 | i = branch_start; |
519 | } | 514 | } |
520 | if (n == 0) | 515 | if (n == 0) |
521 | break; | 516 | break; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 6387523a3153..3401628d742b 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -195,7 +195,7 @@ ulong_aligned: | |||
195 | depending on architecture. I've experimented with several ways | 195 | depending on architecture. I've experimented with several ways |
196 | of writing this section such as using an else before the goto | 196 | of writing this section such as using an else before the goto |
197 | but this one seems to be the fastest. */ | 197 | but this one seems to be the fastest. */ |
198 | while ((unsigned char *)plong < end - 1) { | 198 | while ((unsigned char *)plong < end - sizeof(unsigned long)) { |
199 | prefetch(plong + 1); | 199 | prefetch(plong + 1); |
200 | if (((*plong) & LBITMASK) != lskipval) | 200 | if (((*plong) & LBITMASK) != lskipval) |
201 | break; | 201 | break; |