cluster: STABLE2 - GFS2: make gfs2_fsck conform to fsck(8) exit codes
Bob Peterson
rpeterso@fedoraproject.org
Sun Feb 22 06:17:00 GMT 2009
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=fcfe6e5517a8cb2cf406e8ee16717fef30177d54
Commit: fcfe6e5517a8cb2cf406e8ee16717fef30177d54
Parent: 4c8966c74e8493de3a88dabf6290db9cf4c876ae
Author: Bob Peterson <rpeterso@redhat.com>
AuthorDate: Sun Feb 22 00:15:54 2009 -0600
Committer: Bob Peterson <rpeterso@redhat.com>
CommitterDate: Sun Feb 22 00:15:54 2009 -0600
GFS2: make gfs2_fsck conform to fsck(8) exit codes
bz 474705
This patch makes gfs2_fsck use the standard exit codes
documented in the fsck(8) man page.
---
gfs2/fsck/fsck.h | 16 ++++++++++-
gfs2/fsck/initialize.c | 25 ++++++-----------
gfs2/fsck/main.c | 71 ++++++++++++++++++++++++++++-------------------
gfs2/fsck/metawalk.c | 13 ++++++++-
gfs2/fsck/pass1.c | 23 +++++++++------
gfs2/fsck/pass1b.c | 8 +++---
gfs2/fsck/pass1c.c | 6 ++--
gfs2/fsck/pass2.c | 51 +++++++++++++++++++++++++---------
gfs2/fsck/pass3.c | 17 +++++++++---
gfs2/fsck/pass4.c | 16 ++++++++---
gfs2/fsck/pass5.c | 12 +++++---
gfs2/fsck/rgrepair.c | 4 +++
12 files changed, 173 insertions(+), 89 deletions(-)
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 3bf618c..ac04593 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -9,6 +9,19 @@
#define query(opts, fmt, args...) gfs2_query(&fsck_abort, opts, fmt, ##args)
+/*
+ * Exit codes used by fsck-type programs
+ * Copied from e2fsck's e2fsck.h
+ */
+#define FSCK_OK 0 /* No errors */
+#define FSCK_NONDESTRUCT 1 /* File system errors corrected */
+#define FSCK_REBOOT 2 /* System should be rebooted */
+#define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */
+#define FSCK_ERROR 8 /* Operational error */
+#define FSCK_USAGE 16 /* Usage or syntax error */
+#define FSCK_CANCELED 32 /* Aborted with a signal or ^C */
+#define FSCK_LIBRARY 128 /* Shared library error */
+
struct inode_info
{
osi_list_t list;
@@ -74,7 +87,8 @@ extern osi_list_t dir_hash[FSCK_HASH_SIZE];
extern osi_list_t inode_hash[FSCK_HASH_SIZE];
extern struct gfs2_block_list *bl;
extern uint64_t last_fs_block, last_reported_block;
-extern int skip_this_pass, fsck_abort, fsck_query;
+extern int skip_this_pass, fsck_abort;
+extern int errors_found, errors_corrected;
extern uint64_t last_data_block;
extern uint64_t first_data_block;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 8dbd0e3..a2bf517 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -323,33 +323,33 @@ static int fill_super_block(struct gfs2_sbd *sdp)
}
/**
- * init_sbp - initialize superblock pointer
+ * initialize - initialize superblock pointer
*
*/
-static int init_sbp(struct gfs2_sbd *sbp)
+int initialize(struct gfs2_sbd *sbp)
{
if(opts.no) {
if ((sbp->device_fd = open(opts.device, O_RDONLY)) < 0) {
log_crit("Unable to open device: %s\n", opts.device);
- return -1;
+ return FSCK_USAGE;
}
} else {
/* read in sb from disk */
if ((sbp->device_fd = open(opts.device, O_RDWR)) < 0){
log_crit("Unable to open device: %s\n", opts.device);
- return -1;
+ return FSCK_USAGE;
}
}
if (fill_super_block(sbp)) {
stack;
- return -1;
+ return FSCK_ERROR;
}
/* Change lock protocol to be fsck_* instead of lock_* */
if(!opts.no) {
if(block_mounters(sbp, 1)) {
log_err("Unable to block other mounters\n");
- return -1;
+ return FSCK_USAGE;
}
}
@@ -359,13 +359,13 @@ static int init_sbp(struct gfs2_sbd *sbp)
if(!opts.no)
block_mounters(sbp, 0);
stack;
- return -1;
+ return FSCK_ERROR;
}
if (init_system_inodes(sbp))
- return -1;
+ return FSCK_ERROR;
- return 0;
+ return FSCK_OK;
}
static void destroy_sbp(struct gfs2_sbd *sbp)
@@ -382,13 +382,6 @@ static void destroy_sbp(struct gfs2_sbd *sbp)
close(sbp->device_fd);
}
-int initialize(struct gfs2_sbd *sbp)
-{
-
- return init_sbp(sbp);
-
-}
-
void destroy(struct gfs2_sbd *sbp)
{
destroy_sbp(sbp);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 17c9772..c076bf3 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -20,6 +20,7 @@ osi_list_t inode_hash[FSCK_HASH_SIZE];
struct gfs2_block_list *bl;
uint64_t last_fs_block, last_reported_block = -1;
int skip_this_pass = FALSE, fsck_abort = FALSE;
+int errors_found = 0, errors_corrected = 0;
const char *pass = "";
uint64_t last_data_block;
uint64_t first_data_block;
@@ -57,7 +58,7 @@ int read_cmdline(int argc, char **argv, struct gfs2_options *opts)
case 'h':
usage(argv[0]);
- exit(0);
+ exit(FSCK_OK);
break;
case 'n':
opts->no = 1;
@@ -70,7 +71,7 @@ int read_cmdline(int argc, char **argv, struct gfs2_options *opts)
break;
case 'V':
version();
- exit(0);
+ exit(FSCK_OK);
break;
case 'y':
opts->yes = 1;
@@ -78,13 +79,11 @@ int read_cmdline(int argc, char **argv, struct gfs2_options *opts)
case ':':
case '?':
fprintf(stderr, "Please use '-h' for usage.\n");
- exit(1);
- break;
+ return FSCK_USAGE;
default:
fprintf(stderr, "Bad programmer! You forgot to catch"
" the %c flag\n", c);
- exit(1);
- break;
+ return FSCK_USAGE;
}
}
@@ -92,11 +91,11 @@ int read_cmdline(int argc, char **argv, struct gfs2_options *opts)
opts->device = (argv[optind]);
if(!opts->device) {
fprintf(stderr, "Please use '-h' for usage.\n");
- exit(1);
+ return FSCK_USAGE;
}
} else {
fprintf(stderr, "No device specified. Use '-h' for usage.\n");
- exit(1);
+ return FSCK_USAGE;
}
return 0;
}
@@ -175,8 +174,10 @@ int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
* system inodes before we can do any of that. */
if(!sysinode || ds.q.block_type != mark) {
log_err("Invalid or missing %s system inode.\n", filename);
- if (query(&opts, "Create new %s system inode? (y/n) ",
- filename)) {
+ errors_found++;
+ if ((errors_corrected +=
+ query(&opts, "Create new %s system inode? (y/n) ",
+ filename))) {
builder(sysinode->i_sbd);
gfs2_block_set(sysinode->i_sbd, bl,
sysinode->i_di.di_num.no_addr,
@@ -250,22 +251,23 @@ int main(int argc, char **argv)
struct gfs2_sbd *sbp = &sb;
int j;
enum update_flags update_sys_files;
+ int error = 0;
memset(sbp, 0, sizeof(*sbp));
- if(read_cmdline(argc, argv, &opts))
- return 1;
+ if((error = read_cmdline(argc, argv, &opts)))
+ exit(error);
setbuf(stdout, NULL);
log_notice("Initializing fsck\n");
- if (initialize(sbp))
- return 1;
+ if ((error = initialize(sbp)))
+ exit(error);
signal(SIGINT, interrupt);
log_notice("Starting pass1\n");
pass = "pass 1";
last_reported_block = 0;
- if (pass1(sbp))
- return 1;
+ if ((error = pass1(sbp)))
+ exit(error);
if (skip_this_pass || fsck_abort) {
skip_this_pass = FALSE;
log_notice("Pass1 interrupted \n");
@@ -280,8 +282,8 @@ int main(int argc, char **argv)
last_reported_block = 0;
pass = "pass 1b";
log_notice("Starting pass1b\n");
- if(pass1b(sbp))
- return 1;
+ if((error = pass1b(sbp)))
+ exit(error);
if (skip_this_pass || fsck_abort) {
skip_this_pass = FALSE;
log_notice("Pass1b interrupted \n");
@@ -293,8 +295,8 @@ int main(int argc, char **argv)
last_reported_block = 0;
pass = "pass 1c";
log_notice("Starting pass1c\n");
- if(pass1c(sbp))
- return 1;
+ if((error = pass1c(sbp)))
+ exit(error);
if (skip_this_pass || fsck_abort) {
skip_this_pass = FALSE;
log_notice("Pass1c interrupted \n");
@@ -306,8 +308,8 @@ int main(int argc, char **argv)
last_reported_block = 0;
pass = "pass 2";
log_notice("Starting pass2\n");
- if (pass2(sbp))
- return 1;
+ if ((error = pass2(sbp)))
+ exit(error);
if (skip_this_pass || fsck_abort) {
skip_this_pass = FALSE;
log_notice("Pass2 interrupted \n");
@@ -319,8 +321,8 @@ int main(int argc, char **argv)
last_reported_block = 0;
pass = "pass 3";
log_notice("Starting pass3\n");
- if (pass3(sbp))
- return 1;
+ if ((error = pass3(sbp)))
+ exit(error);
if (skip_this_pass || fsck_abort) {
skip_this_pass = FALSE;
log_notice("Pass3 interrupted \n");
@@ -332,8 +334,8 @@ int main(int argc, char **argv)
last_reported_block = 0;
pass = "pass 4";
log_notice("Starting pass4\n");
- if (pass4(sbp))
- return 1;
+ if ((error = pass4(sbp)))
+ exit(error);
if (skip_this_pass || fsck_abort) {
skip_this_pass = FALSE;
log_notice("Pass4 interrupted \n");
@@ -345,14 +347,17 @@ int main(int argc, char **argv)
last_reported_block = 0;
pass = "pass 5";
log_notice("Starting pass5\n");
- if (pass5(sbp))
- return 1;
+ if ((error = pass5(sbp)))
+ exit(error);
if (skip_this_pass || fsck_abort) {
skip_this_pass = FALSE;
log_notice("Pass5 interrupted \n");
+ error = FSCK_CANCELED;
}
else
log_notice("Pass5 complete \n");
+ } else {
+ error = FSCK_CANCELED;
}
update_sys_files = (opts.no ? not_updated : updated);
/* Free up our system inodes */
@@ -376,5 +381,13 @@ int main(int argc, char **argv)
destroy(sbp);
log_notice("gfs2_fsck complete \n");
- return 0;
+ if (!error) {
+ if (!errors_found)
+ error = FSCK_OK;
+ else if (errors_found == errors_corrected)
+ error = FSCK_NONDESTRUCT;
+ else
+ error = FSCK_UNCORRECTED;
+ }
+ exit(error);
}
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 9915d8d..69a2caf 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -175,12 +175,15 @@ int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
bh->b_blocknr, bh->b_blocknr, (*count) + 1,
ip->i_di.di_num.no_addr,
ip->i_di.di_num.no_addr);
+ errors_found++;
if (query(&opts, "Attempt to repair it? (y/n) ")) {
if (dirent_repair(ip, bh, &de, dent, type,
first))
break;
- else
+ else {
+ errors_corrected++;
*update = updated;
+ }
}
else {
log_err("Corrupt directory entry ignored, "
@@ -257,8 +260,10 @@ void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
PRIx64 ") %s.\n", ip->i_di.di_num.no_addr,
ip->i_di.di_num.no_addr, *leaf_no, *leaf_no, msg);
}
+ errors_found++;
if (*leaf_no == *bad_leaf ||
query(&opts, "Attempt to patch around it? (y/n) ")) {
+ errors_corrected++;
gfs2_put_leaf_nr(ip, index, old_leaf);
}
else
@@ -308,10 +313,12 @@ int check_leaf(struct gfs2_inode *ip, enum update_flags *update,
ip->i_di.di_num.no_addr,
old_leaf, old_leaf, ref_count,
exp_count);
+ errors_found++;
if (query(&opts, "Attempt to fix it? (y/n) "))
{
int factor = 0, divisor = ref_count;
+ errors_corrected++;
lbh = bread(&sbp->buf_list, old_leaf);
while (divisor > 1) {
factor++;
@@ -422,7 +429,9 @@ int check_leaf(struct gfs2_inode *ip, enum update_flags *update,
" doesn't match number of entries found - is %u, found %u\n",
leaf_no, leaf_no, ip->i_di.di_num.no_addr,
leaf.lf_entries, count);
+ errors_found++;
if(query(&opts, "Update leaf entry count? (y/n) ")) {
+ errors_corrected++;
leaf.lf_entries = count;
gfs2_leaf_out(&leaf, lbh->b_data);
log_warn("Leaf entry count updated\n");
@@ -497,8 +506,10 @@ static int check_eattr_entries(struct gfs2_inode *ip,
ea_hdr_prev,
update_it,
pass->private)) {
+ errors_found++;
if (query(&opts, "Repair the bad EA? "
"(y/n) ")) {
+ errors_corrected++;
ea_hdr->ea_num_ptrs = i;
ea_hdr->ea_data_len =
cpu_to_be32(tot_ealen);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index a33ad16..ab724aa 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -181,7 +181,8 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
log_err(" at block #%" PRIu64 " (0x%" PRIx64 ")",
block, block);
log_err(".\n");
- if (query(&opts, "Clear the bad EA? (y/n) ")) {
+ errors_found++;
+ if ((errors_corrected += query(&opts, "Clear the bad EA? (y/n) "))) {
if (block == 0)
block = ip->i_di.di_eattr;
gfs2_block_clear(sdp, bl, block, gfs2_eattr_block);
@@ -575,8 +576,10 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
"): Bad inode address found: %" PRIu64 " (0x%" PRIx64 ")\n",
block, block, ip->i_di.di_num.no_addr,
ip->i_di.di_num.no_addr);
- if(query(&opts, "Fix address in inode at block #%"
- PRIu64 " (0x%" PRIx64 ")? (y/n) ", block, block)) {
+ errors_found++;
+ if((errors_corrected +=
+ query(&opts, "Fix address in inode at block #%"
+ PRIu64 " (0x%" PRIx64 ")? (y/n) ", block, block))) {
ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
f = updated;
@@ -758,7 +761,9 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr,
ip->i_di.di_blocks,
1 + bc.indir_count + bc.data_count + bc.ea_count);
- if(query(&opts, "Fix ondisk block count? (y/n) ")) {
+ errors_found++;
+ if ((errors_corrected +=
+ query(&opts, "Fix ondisk block count? (y/n) "))) {
ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count +
bc.ea_count;
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
@@ -856,7 +861,7 @@ int pass1(struct gfs2_sbd *sbp)
rgd = osi_list_entry(tmp, struct rgrp_list, list);
if(gfs2_rgrp_read(sbp, rgd)){
stack;
- return -1;
+ return FSCK_ERROR;
}
log_debug("RG at %" PRIu64 " (0x%" PRIx64 ") is %u long\n",
rgd->ri.ri_addr, rgd->ri.ri_addr, rgd->ri.ri_length);
@@ -864,7 +869,7 @@ int pass1(struct gfs2_sbd *sbp)
if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i,
gfs2_meta_other)){
stack;
- return -1;
+ return FSCK_ERROR;
}
}
@@ -879,7 +884,7 @@ int pass1(struct gfs2_sbd *sbp)
warm_fuzzy_stuff(block);
if (fsck_abort) { /* if asked to abort */
gfs2_rgrp_relse(rgd, not_updated);
- return 0;
+ return FSCK_OK;
}
if (skip_this_pass) {
printf("Skipping pass 1 is not a good idea.\n");
@@ -892,12 +897,12 @@ int pass1(struct gfs2_sbd *sbp)
stack;
brelse(bh, not_updated);
gfs2_rgrp_relse(rgd, not_updated);
- return -1;
+ return FSCK_ERROR;
}
brelse(bh, not_updated);
first = 0;
}
gfs2_rgrp_relse(rgd, not_updated);
}
- return 0;
+ return FSCK_OK;
}
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 88306ad..3a32db0 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -460,14 +460,14 @@ int pass1b(struct gfs2_sbd *sbp)
osi_list_t *tmp = NULL, *x;
struct metawalk_fxns find_dirents = {0};
find_dirents.check_dentry = &find_dentry;
- int rc = 0;
+ int rc = FSCK_OK;
log_info("Looking for duplicate blocks...\n");
/* If there were no dups in the bitmap, we don't need to do anymore */
if(osi_list_empty(&sbp->dup_blocks.list)) {
log_info("No duplicate blocks found\n");
- return 0;
+ return FSCK_OK;
}
/* Rescan the fs looking for pointers to blocks that are in
@@ -483,7 +483,7 @@ int pass1b(struct gfs2_sbd *sbp)
i, i);
if(gfs2_block_check(sbp, bl, i, &q)) {
stack;
- rc = -1;
+ rc = FSCK_ERROR;
goto out;
}
if((q.block_type == gfs2_inode_dir) ||
@@ -497,7 +497,7 @@ int pass1b(struct gfs2_sbd *sbp)
b = osi_list_entry(tmp, struct blocks, list);
if(find_block_ref(sbp, i, b)) {
stack;
- rc = -1;
+ rc = FSCK_ERROR;
goto out;
}
}
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index fa0e0db..df827df 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -242,7 +242,7 @@ int pass1c(struct gfs2_sbd *sbp)
block_no = ea_block->block;
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
- return 0;
+ return FSCK_OK;
bh = bread(&sbp->buf_list, block_no);
if (gfs2_check_meta(bh, GFS2_METATYPE_IN)) { /* if a dinode */
log_info("EA in inode %"PRIu64" (0x%" PRIx64 ")\n",
@@ -258,7 +258,7 @@ int pass1c(struct gfs2_sbd *sbp)
if(error < 0) {
stack;
brelse(bh, not_updated);
- return -1;
+ return FSCK_ERROR;
}
fsck_inode_put(ip, want_updated); /* dinode_out,
@@ -267,5 +267,5 @@ int pass1c(struct gfs2_sbd *sbp)
brelse(bh, want_updated);
}
}
- return 0;
+ return FSCK_OK;
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 3d29f88..68dcd5c 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -193,8 +193,10 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err("\tName length found = %u\n"
"\tHash expected = %u (0x%x)\n",
de->de_name_len, calculated_hash, calculated_hash);
+ errors_found++;
if(query(&opts, "Fix directory hash for %s? (y/n) ",
filename)) {
+ errors_corrected++;
de->de_hash = calculated_hash;
gfs2_dirent_out(de, (char *)dent);
log_err("Directory entry hash for %s fixed.\n", filename);
@@ -215,8 +217,10 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if(gfs2_check_range(ip->i_sbd, entryblock)) {
log_err("Block # referenced by directory entry %s is out of range\n",
tmp_name);
+ errors_found++;
if(query(&opts,
"Clear directory entry tp out of range block? (y/n) ")) {
+ errors_corrected++;
log_err("Clearing %s\n", tmp_name);
dirent2_del(ip, bh, prev_de, dent);
*update = updated;
@@ -241,8 +245,10 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* Handle bad blocks */
log_err("Found a bad directory entry: %s\n", filename);
+ errors_found++;
if(query(&opts, "Clear entry to inode containing bad blocks? (y/n)")) {
+ errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, update, &clear_eattrs);
fsck_inode_put(entry_ip, not_updated);
@@ -275,10 +281,11 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr,
q.block_type);
+ errors_found++;
if(query(&opts, "Clear directory entry to non-inode block? (y/n) ")) {
/* FIXME: make sure all blocks referenced by
* this inode are cleared in the bitmap */
-
+ errors_corrected++;
dirent2_del(ip, bh, prev_de, dent);
*update = updated;
log_warn("Directory entry '%s' cleared\n", tmp_name);
@@ -302,7 +309,9 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
de_type_string(de->de_type), tmp_name,
de->de_inum.no_addr, de->de_inum.no_addr,
block_type_string(&q));
+ errors_found++;
if(query(&opts, "Clear stale directory entry? (y/n) ")) {
+ errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, update, &clear_eattrs);
fsck_inode_put(entry_ip, not_updated);
@@ -325,8 +334,10 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err("Already found '.' entry in directory %" PRIu64 " (0x%"
PRIx64 ")\n",
ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr);
+ errors_found++;
if(query(&opts, "Clear duplicate '.' entry? (y/n) ")) {
+ errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, update,
&clear_eattrs);
@@ -358,7 +369,9 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
" (0x%" PRIx64 ").\n",
de->de_inum.no_addr, de->de_inum.no_addr,
ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr);
+ errors_found++;
if(query(&opts, "Remove '.' reference? (y/n) ")) {
+ errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, update,
&clear_eattrs);
@@ -392,8 +405,10 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err("Already found '..' entry in directory %" PRIu64 " (0x%"
PRIx64 ")\n",
ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr);
+ errors_found++;
if(query(&opts, "Clear duplicate '..' entry? (y/n) ")) {
+ errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, update,
&clear_eattrs);
@@ -419,7 +434,9 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
PRIx64 ") pointing to"
" something that's not a directory",
ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr);
+ errors_found++;
if(query(&opts, "Clear bad '..' directory entry? (y/n) ")) {
+ errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, update,
&clear_eattrs);
@@ -472,7 +489,9 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err("%s: Hard link to block %" PRIu64" (0x%" PRIx64
") detected.\n", filename, entryblock, entryblock);
+ errors_found++;
if(query(&opts, "Clear hard link to directory? (y/n) ")) {
+ errors_corrected++;
*update = 1;
dirent2_del(ip, bh, prev_de, dent);
@@ -583,10 +602,12 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
sysinode->i_di.di_num.no_addr,
sysinode->i_di.di_num.no_addr,
sysinode->i_di.di_entries, ds.entry_count);
+ errors_found++;
if(query(&opts, "Fix entries for %s inode %" PRIu64 " (0x%"
PRIx64 ")? (y/n) ", dirname,
sysinode->i_di.di_num.no_addr,
sysinode->i_di.di_num.no_addr)) {
+ errors_corrected++;
sysinode->i_di.di_entries = ds.entry_count;
log_warn("Entries updated\n");
update = 1;
@@ -641,26 +662,26 @@ int pass2(struct gfs2_sbd *sbp)
/* Check all the system directory inodes. */
if (check_system_dir(sbp->md.jiinode, "jindex", build_jindex)) {
stack;
- return -1;
+ return FSCK_ERROR;
}
if (check_system_dir(sbp->md.pinode, "per_node", build_per_node)) {
stack;
- return -1;
+ return FSCK_ERROR;
}
if (check_system_dir(sbp->master_dir, "master", build_master)) {
stack;
- return -1;
+ return FSCK_ERROR;
}
if (check_system_dir(sbp->md.rooti, "root", build_root)) {
stack;
- return -1;
+ return FSCK_ERROR;
}
log_info("Checking directory inodes.\n");
/* Grab each directory inode, and run checks on it */
for(i = 0; i < last_fs_block; i++) {
warm_fuzzy_stuff(i);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
- return 0;
+ return FSCK_OK;
/* Skip the system inodes - they're checked above */
if (is_system_dir(sbp, i))
@@ -669,7 +690,7 @@ int pass2(struct gfs2_sbd *sbp)
if(gfs2_block_check(sbp, bl, i, &q)) {
log_err("Can't get block %"PRIu64 " (0x%" PRIx64
") from block list\n", i, i);
- return -1;
+ return FSCK_ERROR;
}
if(q.block_type != gfs2_inode_dir)
@@ -687,33 +708,35 @@ int pass2(struct gfs2_sbd *sbp)
if(check_metatree(ip, &pass2_fxns)) {
stack;
free(ip);
- return -1;
+ return FSCK_ERROR;
}
fsck_inode_put(ip, not_updated);
}
error = check_dir(sbp, i, &pass2_fxns);
if(error < 0) {
stack;
- return -1;
+ return FSCK_ERROR;
}
if (error > 0) {
struct dir_info *di = NULL;
error = find_di(sbp, i, &di);
if(error < 0) {
stack;
- return -1;
+ return FSCK_ERROR;
}
if(error == 0) {
/* FIXME: factor */
+ errors_found++;
if(query(&opts, "Remove directory entry for bad"
" inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
" (0x%" PRIx64 ")? (y/n)", i, i, di->treewalk_parent,
di->treewalk_parent)) {
+ errors_corrected++;
error = remove_dentry_from_dir(sbp, di->treewalk_parent,
i);
if(error < 0) {
stack;
- return -1;
+ return FSCK_ERROR;
}
if(error > 0) {
log_warn("Unable to find dentry for %"
@@ -736,12 +759,12 @@ int pass2(struct gfs2_sbd *sbp)
if(!(filename = malloc(sizeof(char) * filename_len))) {
log_err("Unable to allocate name string\n");
stack;
- return -1;
+ return FSCK_ERROR;
}
if(!memset(filename, 0, sizeof(char) * filename_len)) {
log_err("Unable to zero name string\n");
stack;
- return -1;
+ return FSCK_ERROR;
}
memcpy(filename, tmp_name, filename_len);
@@ -766,7 +789,7 @@ int pass2(struct gfs2_sbd *sbp)
else
fsck_inode_put(ip, not_updated); /* does a brelse */
}
- return 0;
+ return FSCK_OK;
}
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index aa8d007..a5c0202 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -113,10 +113,13 @@ struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
"is bad - reattaching to lost+found");
/* FIXME: add a dinode for this entry instead? */
+
+ errors_found++;
if(query(&opts, "Remove directory entry for bad"
" inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
" (0x%" PRIx64 ")? (y/n)", di->dinode, di->dinode,
di->treewalk_parent, di->treewalk_parent)) {
+ errors_corrected++;
error = remove_dentry_from_dir(sbp, di->treewalk_parent,
di->dinode);
if(error < 0) {
@@ -203,19 +206,21 @@ int pass3(struct gfs2_sbd *sbp)
* failure and put the parent inode in a
* param */
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
- return 0;
+ return FSCK_OK;
tdi = mark_and_return_parent(sbp, di);
/* FIXME: Factor this ? */
if(!tdi) {
if(gfs2_block_check(sbp, bl, di->dinode, &q)) {
stack;
- return -1;
+ return FSCK_ERROR;
}
if(q.bad_block) {
log_err("Found unlinked directory containing bad block\n");
+ errors_found++;
if(query(&opts,
"Clear unlinked directory with bad blocks? (y/n) ")) {
+ errors_corrected++;
gfs2_block_set(sbp, bl,
di->dinode,
gfs2_block_free);
@@ -244,7 +249,9 @@ int pass3(struct gfs2_sbd *sbp)
* with eattrs */
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err("Unlinked directory has zero size.\n");
+ errors_found++;
if(query(&opts, "Remove zero-size unlinked directory? (y/n) ")) {
+ errors_corrected++;
gfs2_block_set(sbp, bl,
di->dinode,
gfs2_block_free);
@@ -254,11 +261,13 @@ int pass3(struct gfs2_sbd *sbp)
log_err("Zero-size unlinked directory remains\n");
}
}
+ errors_found++;
if(query(&opts, "Add unlinked directory to lost+found? (y/n) ")) {
+ errors_corrected++;
if(add_inode_to_lf(ip)) {
fsck_inode_put(ip, not_updated);
stack;
- return -1;
+ return FSCK_ERROR;
}
log_warn("Directory relinked to lost+found\n");
} else {
@@ -278,5 +287,5 @@ int pass3(struct gfs2_sbd *sbp)
if(lf_dip)
log_debug("At end of pass3, lost+found entries is %u\n",
lf_dip->i_di.di_entries);
- return 0;
+ return FSCK_OK;
}
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 3ec380d..2998e3a 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -40,7 +40,7 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
f = not_updated;
if(!(ii = osi_list_entry(tmp, struct inode_info, list))) {
log_crit("osi_list_foreach broken in scan_info_list!!\n");
- exit(1);
+ exit(FSCK_ERROR);
}
log_debug("Checking reference count on inode at block %" PRIu64
" (0x%" PRIx64 ")\n", ii->inode, ii->inode);
@@ -53,8 +53,10 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
}
if(q.bad_block) {
log_err("Unlinked inode contains bad blocks\n", ii->inode);
+ errors_found++;
if(query(&opts,
"Clear unlinked inode with bad blocks? (y/n) ")) {
+ errors_corrected++;
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
continue;
@@ -81,7 +83,9 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
* them. */
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err("Unlinked inode has zero size\n");
+ errors_found++;
if(query(&opts, "Clear zero-size unlinked inode? (y/n) ")) {
+ errors_corrected++;
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
fsck_inode_put(ip, not_updated);
@@ -89,7 +93,9 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
}
}
+ errors_found++;
if(query(&opts, "Add unlinked inode to lost+found? (y/n)")) {
+ errors_corrected++;
f = updated;
if(add_inode_to_lf(ip)) {
stack;
@@ -110,8 +116,10 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
ii->inode, ii->link_count, ii->counted_links);
/* Read in the inode, adjust the link count,
* and write it back out */
+ errors_found++;
if(query(&opts, "Update link count for inode %"
PRIu64 " (0x%" PRIx64 ") ? (y/n) ", ii->inode, ii->inode)) {
+ errors_corrected++;
ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */
fix_inode_count(sbp, ii, ip);
fsck_inode_put(ip, updated); /* out, brelse, free */
@@ -158,16 +166,16 @@ int pass4(struct gfs2_sbd *sbp)
log_info("Checking inode reference counts.\n");
for (i = 0; i < FSCK_HASH_SIZE; i++) {
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
- return 0;
+ return FSCK_OK;
list = &inode_hash[i];
if(scan_inode_list(sbp, list)) {
stack;
- return -1;
+ return FSCK_ERROR;
}
}
if(lf_dip)
log_debug("At end of pass4, lost+found entries is %u\n",
lf_dip->i_di.di_entries);
- return 0;
+ return FSCK_OK;
}
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 2a2cf4e..60e4e65 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -96,8 +96,10 @@ int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int buflen,
log_err("Metadata type is %u (%s)\n", q.block_type,
block_type_string(&q));
+ errors_found++;
if(query(&opts, "Fix bitmap for block %"
PRIu64" (0x%" PRIx64 ") ? (y/n) ", block, block)) {
+ errors_corrected++;
if(gfs2_set_bitmap(sbp, block, block_status))
log_err("Failed.\n");
else
@@ -154,10 +156,12 @@ enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
* means that the total number of blocks we've counted
* exceeds the blocks in the rg */
log_err("Internal fsck error - AAHHH!\n");
- exit(1);
+ exit(FSCK_ERROR);
}
if(update) {
+ errors_found++;
if(query(&opts, "Update resource group counts? (y/n) ")) {
+ errors_corrected++;
log_warn("Resource group counts updated\n");
/* write out the rgrp */
gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data);
@@ -186,14 +190,14 @@ int pass5(struct gfs2_sbd *sbp)
enum update_flags f;
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
- return 0;
+ return FSCK_OK;
log_info("Verifying Resource Group #%" PRIu64 "\n", rg_count);
memset(count, 0, sizeof(count));
rgp = osi_list_entry(tmp, struct rgrp_list, list);
if(gfs2_rgrp_read(sbp, rgp)){
stack;
- return -1;
+ return FSCK_ERROR;
}
rg_count++;
/* Compare the bitmaps and report the differences */
@@ -203,5 +207,5 @@ int pass5(struct gfs2_sbd *sbp)
/* Fix up superblock info based on this - don't think there's
* anything to do here... */
- return 0;
+ return FSCK_OK;
}
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index fce2f17..599cae6 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -372,8 +372,10 @@ int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n",
rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr,
(int)x+1, (int)rg->ri.ri_length);
+ errors_found++;
if (query(&opts, "Fix the RG? (y/n)")) {
+ errors_corrected++;
log_err("Attempting to repair the RG.\n");
rg->bh[x] = bread(&sdp->nvbuf_list, rg->ri.ri_addr + x);
if (x) {
@@ -504,7 +506,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
PRIx32);
/* If we modified the index, write it back to disk. */
if (rindex_modified) {
+ errors_found++;
if (query(&opts, "Fix the index? (y/n)")) {
+ errors_corrected++;
gfs2_rindex_out(&expected->ri, (char *)&buf);
gfs2_writei(sdp->md.riinode, (char *)&buf,
rg * sizeof(struct gfs2_rindex),
More information about the Cluster-cvs
mailing list