Gitweb:
http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=aaf46833...
Commit: aaf46833cb46dc1bbfaf59041b0a8ca87ca916ab
Parent: fadb42f8f3c97b5a4106682abef660c2ea2e0b73
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 9 12:27:57 2015 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Thu Jan 22 14:12:08 2015 -0600
fsck.gfs2: Rebuild system files if they don't have the SYS bit set
This patch checks for the GFS2_DIF_SYSTEM bit on system dinodes. If the
bit is not set, the dinode is assumed to be corrupt and rebuilt.
If the jindex is rebuilt, it needs to be re-read.
---
gfs2/fsck/pass1.c | 55 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 2841b8c..4348683 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -27,6 +27,7 @@
#include "util.h"
#include "link.h"
#include "metawalk.h"
+#include "fs_recovery.h"
struct special_blocks gfs1_rindex_blks;
@@ -1241,7 +1242,8 @@ static int check_system_inode(struct gfs2_sbd *sdp,
struct gfs2_inode **sysinode,
const char *filename,
int builder(struct gfs2_sbd *sdp),
- enum gfs2_mark_block mark)
+ enum gfs2_mark_block mark,
+ struct gfs2_inode *sysdir, int needs_sysbit)
{
uint64_t iblock = 0;
struct dir_status ds = {0};
@@ -1282,6 +1284,24 @@ static int check_system_inode(struct gfs2_sbd *sdp,
if (mark == gfs2_inode_dir)
dirtree_insert((*sysinode)->i_di.di_num);
}
+ /* Make sure it's marked as a system file/directory */
+ if (needs_sysbit &&
+ !((*sysinode)->i_di.di_flags & GFS2_DIF_SYSTEM)) {
+ log_err( _("System inode %s is missing the 'system' "
+ "flag. It should be rebuilt.\n"), filename);
+ if (sysdir && query(_("Delete the corrupt %s system "
+ "inode? (y/n) "), filename)) {
+ inode_put(sysinode);
+ gfs2_dirent_del(sysdir, filename,
+ strlen(filename));
+ /* Set the blockmap (but not bitmap) back to
+ 'free' so that it gets checked like any
+ normal dinode. */
+ gfs2_blockmap_set(bl, iblock, gfs2_block_free);
+ log_err( _("Removed system inode \"%s\".\n"),
+ filename);
+ }
+ }
} else
log_info( _("System inode for '%s' is corrupt or missing.\n"),
filename);
@@ -1290,18 +1310,22 @@ static int check_system_inode(struct gfs2_sbd *sdp,
lost+found then, but we *need* our system inodes before we can
do any of that. */
if (!(*sysinode) || ds.q != mark) {
- log_err( _("Invalid or missing %s system inode (should be %d, "
- "is %d).\n"), filename, mark, ds.q);
+ log_err( _("Invalid or missing %s system inode (should be "
+ "'%s', is '%s').\n"), filename,
+ block_type_string(mark),
+ block_type_string(ds.q));
if (query(_("Create new %s system inode? (y/n) "), filename)) {
log_err( _("Rebuilding system file \"%s\"\n"),
filename);
error = builder(sdp);
if (error) {
- log_err( _("Error trying to rebuild system "
- "file %s: Cannot continue\n"),
+ log_err( _("Error rebuilding system "
+ "inode %s: Cannot continue\n"),
filename);
return error;
}
+ if (*sysinode == sdp->md.jiinode)
+ ji_update(sdp);
fsck_blockmap_set(*sysinode,
(*sysinode)->i_di.di_num.no_addr,
filename, mark);
@@ -1367,7 +1391,8 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
sdp->master_dir->i_di.di_num.no_addr,
"master", gfs2_inode_dir);
if (check_system_inode(sdp, &sdp->master_dir, "master",
- build_master, gfs2_inode_dir)) {
+ build_master, gfs2_inode_dir,
+ NULL, 1)) {
stack;
return -1;
}
@@ -1377,39 +1402,41 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
fsck_blockmap_set(sdp->md.rooti, sdp->md.rooti->i_di.di_num.no_addr,
"root", gfs2_inode_dir);
if (check_system_inode(sdp, &sdp->md.rooti, "root", build_root,
- gfs2_inode_dir)) {
+ gfs2_inode_dir, NULL, 0)) {
stack;
return -1;
}
if (!sdp->gfs1 &&
check_system_inode(sdp, &sdp->md.inum, "inum", build_inum,
- gfs2_inode_file)) {
+ gfs2_inode_file, sdp->master_dir, 1)) {
stack;
return -1;
}
if (check_system_inode(sdp, &sdp->md.statfs, "statfs", build_statfs,
- gfs2_inode_file)) {
+ gfs2_inode_file, sdp->master_dir, !sdp->gfs1)) {
stack;
return -1;
}
if (check_system_inode(sdp, &sdp->md.jiinode, "jindex", build_jindex,
- (sdp->gfs1 ? gfs2_inode_file : gfs2_inode_dir))) {
+ (sdp->gfs1 ? gfs2_inode_file : gfs2_inode_dir),
+ sdp->master_dir, !sdp->gfs1)) {
stack;
return -1;
}
if (check_system_inode(sdp, &sdp->md.riinode, "rindex", build_rindex,
- gfs2_inode_file)) {
+ gfs2_inode_file, sdp->master_dir, !sdp->gfs1)) {
stack;
return -1;
}
if (check_system_inode(sdp, &sdp->md.qinode, "quota", build_quota,
- gfs2_inode_file)) {
+ gfs2_inode_file, sdp->master_dir, !sdp->gfs1)) {
stack;
return -1;
}
if (!sdp->gfs1 &&
check_system_inode(sdp, &sdp->md.pinode, "per_node",
- build_per_node, gfs2_inode_dir)) {
+ build_per_node, gfs2_inode_dir,
+ sdp->master_dir, 1)) {
stack;
return -1;
}
@@ -1438,7 +1465,7 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
sprintf(jname, "journal%d", sdp->md.journals);
if (check_system_inode(sdp, &sdp->md.journal[sdp->md.journals],
jname, build_a_journal,
- gfs2_inode_file)) {
+ gfs2_inode_file, sdp->md.jiinode, 1)) {
stack;
return -1;
}