cluster: RHEL6 - gfs2_edit savemeta doesn't save all leaf blocks for large dirs
Bob Peterson
rpeterso at fedoraproject.org
Thu May 26 18:31:11 UTC 2011
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0ce6e0039cd6410a749842e0d963bfa9cdefe950
Commit: 0ce6e0039cd6410a749842e0d963bfa9cdefe950
Parent: 3e4452404678ba4addffe4ece6b67dd2feeec4b9
Author: Bob Peterson <rpeterso at redhat.com>
AuthorDate: Thu May 26 12:59:56 2011 -0500
Committer: Bob Peterson <rpeterso at redhat.com>
CommitterDate: Thu May 26 12:59: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#679566
---
gfs2/edit/savemeta.c | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 655a3bc..7840e03 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -116,9 +116,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))
@@ -370,8 +369,8 @@ static void save_inode_data(int out_fd)
(S_ISDIR(inode->i_di.di_mode) ||
(gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)))
height++;
- else if (height && !(inode->i_di.di_flags & GFS2_DIF_SYSTEM) &&
- !block_is_systemfile() && !S_ISDIR(inode->i_di.di_mode))
+ else if (height && !block_is_systemfile() &&
+ !S_ISDIR(inode->i_di.di_mode))
height--;
osi_list_add(&metabh->b_altlist, &metalist[0]);
for (i = 1; i <= height; i++){
@@ -396,10 +395,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 */
More information about the cluster-commits
mailing list