Gitweb:
http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=77be7299969...
Commit: 77be7299969e63c4874d11aeb692c0a03efa6d5d
Parent: 3bb261e473a972f0b183be3870794c6e4df8f97d
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Dec 19 09:09:27 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Thu Jan 3 07:35:14 2013 -0700
fsck.gfs2: Detect and fix mismatch in GFS1 formal inode number
This patch adds code to fsck.gfs2 that checks and fixes
GFS1 formal inode numbers. In GFS1 only, the formal inode number
is supposed to match the block address. If it doesn't, it's a
problem that should be fixed. If the problem goes undetected,
further conversions to GFS2 via the gfs2_convert tool will treat
the dinode as not being GFS1, which, in turn, yields the wrong
type number in the dirent. This causes the file in question to
be improperly treated (by gfs2_convert) as a GFS2 fifo
(DT_FIFO==1) rather than a GFS1 file (GFS_FILE_REG==1). The end
result is something like this, from pass2 in fsck.gfs2, after
the gfs2_convert:
Type 'fifo' in dir entry (lost_file_20431, 20431/0x4fcf)
conflicts with type 'file' in dinode. (Dir entry is stale.)
rhbz#888053
---
gfs2/fsck/pass1.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index d1209e6..9a2398a 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1309,6 +1309,23 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head
*bh)
log_err( _("Address in inode at block #%" PRIu64
" (0x%" PRIx64 ") not fixed\n"), block, block);
}
+ if (sdp->gfs1 && ip->i_di.di_num.no_formal_ino != block) {
+ log_err( _("Inode #%llu (0x%llx): GFS1 formal inode number "
+ "mismatch: was %llu (0x%llx)\n"),
+ (unsigned long long)block, (unsigned long long)block,
+ (unsigned long long)ip->i_di.di_num.no_formal_ino,
+ (unsigned long long)ip->i_di.di_num.no_formal_ino);
+ if (query( _("Fix formal inode number in inode #%llu"
+ " (0x%llx)? (y/n) "), (unsigned long long)block,
+ (unsigned long long)block)) {
+ ip->i_di.di_num.no_formal_ino = block;
+ bmodified(ip->i_bh);
+ } else
+ log_err( _("Inode number in inode at block #%lld "
+ "(0x%llx) not fixed\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
+ }
error = handle_ip(sdp, ip);
fsck_inode_put(&ip);
return error;