Gitweb:
http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=efd9859b...
Commit: efd9859b14143d5c124bba686a6bc19983d29e42
Parent: 506995267a25075634a1427ec5960b5b98f7556a
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 Dec 20 14:31:24 2012 -0600
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 0f80f87..540f2a9 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1311,6 +1311,23 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head
*bh)
(unsigned long long)block,
(unsigned long long)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;