Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=39a... Commit: 39a2ee8ab10b7d7117adb124a846da4a083b4af0 Parent: 517c34c060d30e7467e316e96f389ced0c703ef1 Author: Bob Peterson rpeterso@redhat.com AuthorDate: Wed Mar 16 13:00:07 2011 -0500 Committer: Bob Peterson rpeterso@redhat.com CommitterDate: Wed Mar 16 13:01:56 2011 -0500
gfs2_edit savemeta doesn't save all leaf blocks for large dirs
This patch changes the gfs2_edit "savemeta" option so that it processes exhash directories the same way that fsck.gfs2 does, namely, it does a read of the hash table and saves all the leaf blocks from that. Before it was trying to traverse the blocks, but that only works for medium-size exhash directories.
rhbz#679565 --- gfs2/edit/savemeta.c | 24 +++++++++++++++++------- 1 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c index 7c28ae9..a724807 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -130,9 +130,8 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type, inode = inode_get(&sbd, lbh); else inode = gfs_inode_get(&sbd, lbh); - if (inode->i_di.di_flags & GFS2_DIF_EXHASH && - (S_ISDIR(inode->i_di.di_mode) || - (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR))) + if (S_ISDIR(inode->i_di.di_mode) || + (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)) *gstruct_len = sbd.bsize; else if (!inode->i_di.di_height && !block_is_systemfile() && !S_ISDIR(inode->i_di.di_mode)) @@ -385,10 +384,21 @@ static void save_inode_data(int out_fd) } } /* Process directory exhash inodes */ - if (S_ISDIR(inode->i_di.di_mode)) { - if (inode->i_di.di_flags & GFS2_DIF_EXHASH) { - save_indirect_blocks(out_fd, cur_list, metabh, - height, 0); + if (S_ISDIR(inode->i_di.di_mode) && + inode->i_di.di_flags & GFS2_DIF_EXHASH) { + uint64_t leaf_no, old_leaf = -1; + int li; + + for (li = 0; li < (1 << inode->i_di.di_depth); li++) { + gfs2_get_leaf_nr(inode, li, &leaf_no); + if (leaf_no == old_leaf || + gfs2_check_range(&sbd, leaf_no) != 0) + continue; + old_leaf = leaf_no; + mybh = bread(&sbd, leaf_no); + if (gfs2_check_meta(mybh, GFS2_METATYPE_LF) == 0) + save_block(sbd.device_fd, out_fd, leaf_no); + brelse(mybh); } } if (inode->i_di.di_eattr) { /* if this inode has extended attributes */
cluster-commits@lists.stg.fedorahosted.org