[GFS2] fix gfs2 block allocation (cleaned up)

This patch fixes bz 450641.

This patch changes the computation for zero_metapath_length(), which it
renames to metapath_branch_start(). When you are extending the metadata
tree, The indirect blocks that point to the new data block must either
diverge from the existing tree either at the inode, or at the first
indirect block. They can diverge at the first indirect block because the
inode has room for 483 pointers while the indirect blocks have room for
509 pointers, so when the tree is grown, there is some free space in the
first indirect block. What metapath_branch_start() now computes is the
height where the first indirect block for the new data block is located.
It can either be 1 (if the indirect block diverges from the inode) or 2
(if it diverges from the first indirect block).

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

authored by Benjamin Marzinski and committed by Steven Whitehouse 5af4e7a0 17c15da0

Changed files
+9 -14
fs
gfs2
+9 -14
fs/gfs2/bmap.c
··· 246 246 247 247 } 248 248 249 - static inline unsigned int zero_metapath_length(const struct metapath *mp, 250 - unsigned height) 249 + static inline unsigned int metapath_branch_start(const struct metapath *mp) 251 250 { 252 - unsigned int i; 253 - for (i = 0; i < height - 1; i++) { 254 - if (mp->mp_list[i] != 0) 255 - return i; 256 - } 257 - return height; 251 + if (mp->mp_list[0] == 0) 252 + return 2; 253 + return 1; 258 254 } 259 255 260 256 /** ··· 432 436 struct gfs2_sbd *sdp = GFS2_SB(inode); 433 437 struct buffer_head *dibh = mp->mp_bh[0]; 434 438 u64 bn, dblock = 0; 435 - unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0; 439 + unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0; 436 440 unsigned dblks = 0; 437 441 unsigned ptrs_per_blk; 438 442 const unsigned end_of_metadata = height - 1; ··· 467 471 /* Building up tree height */ 468 472 state = ALLOC_GROW_HEIGHT; 469 473 iblks = height - ip->i_height; 470 - zmpl = zero_metapath_length(mp, height); 471 - iblks -= zmpl; 472 - iblks += height; 474 + branch_start = metapath_branch_start(mp); 475 + iblks += (height - branch_start); 473 476 } 474 477 } 475 478 ··· 504 509 sizeof(struct gfs2_meta_header)); 505 510 *ptr = zero_bn; 506 511 state = ALLOC_GROW_DEPTH; 507 - for(i = zmpl; i < height; i++) { 512 + for(i = branch_start; i < height; i++) { 508 513 if (mp->mp_bh[i] == NULL) 509 514 break; 510 515 brelse(mp->mp_bh[i]); 511 516 mp->mp_bh[i] = NULL; 512 517 } 513 - i = zmpl; 518 + i = branch_start; 514 519 } 515 520 if (n == 0) 516 521 break;