gfs2-utils: RHEL7 - fsck.gfs2: fix corner case sb_seg_size correction for single journal fs
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=f2d6124a...
Commit: f2d6124acc5b185d2674171df3deb6077a35111b
Parent: d6b100b8e2315ab6e072f02bf63a1aacefda6f7d
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Mar 25 22:28:45 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Mar 25 22:34:13 2014 -0500
fsck.gfs2: fix corner case sb_seg_size correction for single journal fs
Spotted an error in the single journal sb_seg_size correction. This
patch fixes it and is an addendum patch to the previous two patches
posted for this bz1053668
Resolves: rhbz#1079507
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/fsck/initialize.c | 22 +++++++++++++++-------
1 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 33cf85b..9ada7d2 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -1414,14 +1414,22 @@ static int correct_journal_seg_size(struct gfs2_sbd *sdp)
}
gfs_jindex_in(&ji_0, buf);
- if (sdp->md.journals == 1 && sbd1->sb_seg_size == 0) {
- if (!query(_("The gfs2 journal segment size is 0 and a correct value\n"
- "cannot be determined in a single-journal filesystem.\n"
- "Continue with default? (y/n) "))) {
- log_crit(_("Error: Cannot proceed without a valid sb_seg_size value.\n"));
- return -1;
+ if (sdp->md.journals == 1) {
+ if (sbd1->sb_seg_size == 0) {
+ if (!query(_("The gfs2 journal segment size is 0 and a"
+ " correct value cannot be determined in a"
+ " single-journal filesystem.\n"
+ "Continue with default? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid"
+ " sb_seg_size value.\n"));
+ return -1;
+ }
+ goto out;
}
- goto out;
+ /* Don't mess with sb_seg_size because we don't know what
+ * it needs to be
+ */
+ return 0;
}
count = gfs2_readi(sdp->md.jiinode, buf, sizeof(struct gfs_jindex),
10 years, 1 month
gfs2-utils: master - fsck.gfs2: fix corner case sb_seg_size correction for single journal fs
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=c6d2155f...
Commit: c6d2155f68d45e603d772884fc75f53e7b651d9f
Parent: d394637d9c6586d8bb5a872f8763b90720f81500
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Mar 25 22:28:45 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Mar 25 22:28:45 2014 -0500
fsck.gfs2: fix corner case sb_seg_size correction for single journal fs
Spotted an error in the single journal sb_seg_size correction. This
patch fixes it and is an addendum patch to the previous two patches
posted for this bz1053668
Resolves: rhbz#1053668
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/fsck/initialize.c | 22 +++++++++++++++-------
1 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 33cf85b..9ada7d2 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -1414,14 +1414,22 @@ static int correct_journal_seg_size(struct gfs2_sbd *sdp)
}
gfs_jindex_in(&ji_0, buf);
- if (sdp->md.journals == 1 && sbd1->sb_seg_size == 0) {
- if (!query(_("The gfs2 journal segment size is 0 and a correct value\n"
- "cannot be determined in a single-journal filesystem.\n"
- "Continue with default? (y/n) "))) {
- log_crit(_("Error: Cannot proceed without a valid sb_seg_size value.\n"));
- return -1;
+ if (sdp->md.journals == 1) {
+ if (sbd1->sb_seg_size == 0) {
+ if (!query(_("The gfs2 journal segment size is 0 and a"
+ " correct value cannot be determined in a"
+ " single-journal filesystem.\n"
+ "Continue with default? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid"
+ " sb_seg_size value.\n"));
+ return -1;
+ }
+ goto out;
}
- goto out;
+ /* Don't mess with sb_seg_size because we don't know what
+ * it needs to be
+ */
+ return 0;
}
count = gfs2_readi(sdp->md.jiinode, buf, sizeof(struct gfs_jindex),
10 years, 1 month
cluster: RHEL6 - gfs2-utils: check and fix bad dinode pointers in gfs1 sb
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=6739cf6a6cc...
Commit: 6739cf6a6cc6c24d20d58f68acdc6d886bff01e7
Parent: 1c5332f5ac6c719b1a4b64a8940925a8a15c0029
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Mar 25 22:08:40 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Mar 25 22:08:40 2014 -0500
gfs2-utils: check and fix bad dinode pointers in gfs1 sb
This patch makes gfs2_convert check for bad values of sb_seg_size,
sb_quota_di and sb_license_di.
In fsck.gfs2, attempts are made to correct these erroneous values.
This v2 patch checks with the user before making changes to the
superblock in fsck.gfs2 and also adds some error messaging as per
Bob's comments.
Resolves: rhbz#1053668
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 29 +++++++++++
gfs2/fsck/initialize.c | 112 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 137 insertions(+), 4 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 9594908..bf3f49b 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1473,6 +1473,24 @@ static int read_gfs1_jiindex(struct gfs2_sbd *sdp)
return -1;
}
+static int sanity_check(struct gfs2_sbd *sdp)
+{
+ int error = 0;
+ if (!raw_gfs1_ondisk_sb.sb_quota_di.no_addr) {
+ log_crit("Error: Superblock Quota inode address is NULL\n");
+ error = 1;
+ }
+ if (!raw_gfs1_ondisk_sb.sb_license_di.no_addr) {
+ log_crit("Error: Superblock Statfs inode address is NULL\n");
+ error = 1;
+ }
+ if (!raw_gfs1_ondisk_sb.sb_seg_size) {
+ log_crit("Error: Superblock segment size is zero\n");
+ error = 1;
+ }
+ return error;
+}
+
/* ------------------------------------------------------------------------- */
/* init - initialization code */
/* Returns: 0 on success, -1 on failure */
@@ -2068,6 +2086,17 @@ int main(int argc, char **argv)
process_parameters(argc, argv, &opts);
error = init(&sb2);
+ /*
+ * Check for some common fs errors
+ */
+ if (!error) {
+ if (sanity_check(&sb2)) {
+ log_crit("%s is not a clean gfs filesytem. Please use the"
+ " fsck.gfs2 utility to correct these errors and"
+ " try again.\n", device);
+ exit(0);
+ }
+ }
/* ---------------------------------------------- */
/* Make them seal their fate. */
/* ---------------------------------------------- */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 789af2c..9abdf0c 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -718,9 +718,25 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
sdp->md.next_inum = be64_to_cpu(inumbuf);
}
- if (sdp->gfs1)
+ if (sdp->gfs1) {
+ /* In gfs1, the license_di is always 3 blocks after the jindex_di */
+ if ((sbd1->sb_license_di.no_addr != sbd1->sb_jindex_di.no_addr + 3) ||
+ (sbd1->sb_license_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 3)) {
+ if (!query( _("The gfs system statfs inode pointer is incorrect. "
+ "Okay to correct? (y/n) "))) {
+ log_err( _("fsck.gfs2 cannot continue without a valid "
+ "statfs file; aborting.\n"));
+ goto fail;
+ }
+ sbd1->sb_license_di.no_addr = sbd1->sb_license_di.no_formal_ino
+ = sbd1->sb_jindex_di.no_addr + 3;
+ }
sdp->md.statfs = inode_read(sdp, sbd1->sb_license_di.no_addr);
- else
+ if (sdp->md.statfs == NULL) {
+ log_crit(_("Error reading statfs inode: %s\n"), strerror(errno));
+ goto fail;
+ }
+ } else
gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
if (!sdp->gfs1 && !sdp->md.statfs) {
if (!query( _("The gfs2 system statfs inode is missing. "
@@ -760,9 +776,26 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
}
- if (sdp->gfs1)
+ if (sdp->gfs1) {
+ /* In gfs1, the quota_di is always 2 blocks after the jindex_di */
+ if ((sbd1->sb_quota_di.no_addr != sbd1->sb_jindex_di.no_addr + 2) ||
+ (sbd1->sb_quota_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 2)) {
+ if (!query( _("The gfs system quota inode pointer is incorrect. "
+ " Okay to correct? (y/n) "))) {
+ log_err( _("fsck.gfs2 cannot continue without a valid "
+ "quota file; aborting.\n"));
+ goto fail;
+ }
+ sbd1->sb_quota_di.no_addr = sbd1->sb_quota_di.no_formal_ino
+ = sbd1->sb_jindex_di.no_addr + 2;
+ }
+
sdp->md.qinode = inode_read(sdp, sbd1->sb_quota_di.no_addr);
- else
+ if (sdp->md.qinode == NULL) {
+ log_crit(_("Error reading quota inode: %s\n"), strerror(errno));
+ goto fail;
+ }
+ } else
gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
if (!sdp->gfs1 && !sdp->md.qinode) {
if (!query( _("The gfs2 system quota inode is missing. "
@@ -1322,7 +1355,72 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
return 0;
}
+static int reset_journal_seg_size(unsigned int jsize, unsigned int nsegs,
+ unsigned int bsize)
+{
+ unsigned int seg_size = jsize / (nsegs * bsize);
+ if (!seg_size)
+ seg_size = 16; /* The default with 128MB journal and 4K bsize */
+ if (seg_size != sbd1->sb_seg_size) {
+ sbd1->sb_seg_size = seg_size;
+ if (!query(_("Computed correct journal segment size to %u."
+ " Reset it? (y/n) "), seg_size)) {
+ log_crit(_("Error: Cannot proceed without a valid journal"
+ " segment size value.\n"));
+ return -1;
+ }
+ log_err(_("Resetting journal segment size to %u\n"), sbd1->sb_seg_size);
+ }
+ return 0;
+}
+
+static int correct_journal_seg_size(struct gfs2_sbd *sdp)
+{
+ int count;
+ struct gfs_jindex ji_0, ji_1;
+ char buf[sizeof(struct gfs_jindex)];
+ unsigned int jsize = GFS2_DEFAULT_JSIZE * 1024 * 1024;
+
+ count = gfs2_readi(sdp->md.jiinode, buf, 0, sizeof(struct gfs_jindex));
+ if (count != sizeof(struct gfs_jindex)) {
+ log_crit(_("Error %d reading system journal index inode. "
+ "Aborting\n"), count);
+ return -1;
+ }
+ gfs_jindex_in(&ji_0, buf);
+
+ if (sdp->md.journals == 1) {
+ if (sbd1->sb_seg_size == 0) {
+ if (!query(_("The gfs2 journal segment size is 0 and a"
+ " correct value cannot be determined in a"
+ " single-journal filesystem.\n"
+ "Continue with default? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid"
+ "sb_seg_size value.\n"));
+ return -1;
+ }
+ goto out;
+ }
+ /* Don't mess with sb_seg_size because we don't know what
+ * it needs to be
+ */
+ return 0;
+ }
+
+ count = gfs2_readi(sdp->md.jiinode, buf, sizeof(struct gfs_jindex),
+ sizeof(struct gfs_jindex));
+ if (count != sizeof(struct gfs_jindex)) {
+ log_crit(_("Error %d reading system journal index inode. "
+ "Aborting\n"), count);
+ return -1;
+ }
+ gfs_jindex_in(&ji_1, buf);
+ jsize = (ji_1.ji_addr - ji_0.ji_addr) * sbd1->sb_bsize;
+out:
+ return reset_journal_seg_size(jsize, ji_0.ji_nsegment, sbd1->sb_bsize);
+}
+
/*
* reconstruct_journals - write fresh journals for GFS1 only
* sdp: the super block
@@ -1335,6 +1433,12 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
struct gfs_jindex ji;
char buf[sizeof(struct gfs_jindex)];
+ /* Ensure that sb_seg_size is valid */
+ if (correct_journal_seg_size(sdp)) {
+ log_crit(_("Failed to set correct journal segment size. Cannot continue\n"));
+ return -1;
+ }
+
log_err("Clearing GFS journals (this may take a while)\n");
for (i = 0; i < sdp->md.journals; i++) {
count = gfs2_readi(sdp->md.jiinode, buf,
10 years, 1 month
cluster: RHEL6 - libgfs2: patch to update gfs1 superblock correctly
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=1c5332f5ac6...
Commit: 1c5332f5ac6c719b1a4b64a8940925a8a15c0029
Parent: cbbe13ce1fafe0ecd9adb01473825f78da7291f2
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Mar 25 22:07:28 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Mar 25 22:07:28 2014 -0500
libgfs2: patch to update gfs1 superblock correctly
gfs2-utils uses the gfs2_sb structure as a template to operate on
both gfs1 and gfs2 superblocks. Some fields of the gfs1 superblock
are not in gfs2 and are replaced by padded fields. These padded
fields were not being written out after modification and were
instead being zeroed out, thereby causing corruption.
This patch fixes gfs2_sb_out() to write out the padded fields.
Resolves: rhbz#1053668
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/libgfs2/ondisk.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index e43cd26..b2f2ffd 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -125,15 +125,20 @@ void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh)
CPOUT_32(sb, str, sb_fs_format);
CPOUT_32(sb, str, sb_multihost_format);
+ CPOUT_32(sb, str, __pad0); /* gfs sb_flags */
CPOUT_32(sb, str, sb_bsize);
CPOUT_32(sb, str, sb_bsize_shift);
+ CPOUT_32(sb, str, __pad1); /* gfs sb_seg_size */
gfs2_inum_out(&sb->sb_master_dir, (char *)&str->sb_master_dir);
gfs2_inum_out(&sb->sb_root_dir, (char *)&str->sb_root_dir);
CPOUT_08(sb, str, sb_lockproto, GFS2_LOCKNAME_LEN);
CPOUT_08(sb, str, sb_locktable, GFS2_LOCKNAME_LEN);
+ gfs2_inum_out(&sb->__pad2, (char *)&str->__pad2); /* gfs rindex */
+ gfs2_inum_out(&sb->__pad3, (char *)&str->__pad3); /* gfs quota */
+ gfs2_inum_out(&sb->__pad4, (char *)&str->__pad4); /* gfs license */
#ifdef GFS2_HAS_UUID
memcpy(str->sb_uuid, sb->sb_uuid, 16);
#endif
10 years, 1 month
cluster: RHEL511 - qdisk: Waits tko cycles to complete initialization instead of tko_up
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=18776f9a3fb...
Commit: 18776f9a3fbe382bae4bd6c0bb78cfd245e751ab
Parent: 760542a89d84cb0fb5683f60afd66c94eb696e00
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Mon Mar 24 15:27:43 2014 +0000
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Mon Mar 24 15:27:43 2014 +0000
qdisk: Waits tko cycles to complete initialization instead of tko_up
Resolves: rhbz#1029191
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
cman/qdisk/main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
index 6ee50fe..cfe0e18 100644
--- a/cman/qdisk/main.c
+++ b/cman/qdisk/main.c
@@ -514,7 +514,7 @@ quorum_init(qd_ctx *ctx, node_info_t *ni, int max, struct h_data *h, int maxh)
return -1;
}
- while (++x <= ctx->qc_tko && _running) {
+ while (++x <= ctx->qc_tko_up && _running) {
read_node_blocks(ctx, ni, max);
check_transitions(ctx, ni, max, NULL);
10 years, 1 month
cluster: RHEL511 - qdisk: Make qdiskd warn if not all nodes are running qdiskd
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=760542a89d8...
Commit: 760542a89d84cb0fb5683f60afd66c94eb696e00
Parent: fde6e0e3a1fc1dac3b95d7cd96315bb2231ccfd5
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Mon Mar 24 15:26:23 2014 +0000
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Mon Mar 24 15:26:23 2014 +0000
qdisk: Make qdiskd warn if not all nodes are running qdiskd
Resolves: rhbz#994187
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
cman/qdisk/main.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
index 1873a05..6ee50fe 100644
--- a/cman/qdisk/main.c
+++ b/cman/qdisk/main.c
@@ -579,6 +579,7 @@ check_cman(qd_ctx *ctx, memb_mask_t mask, memb_mask_t master_mask)
{
cman_node_t nodes[MAX_NODES_DISK];
int retnodes, x;
+ static unsigned int check_cycle = 0;
if (cman_get_nodes(ctx->qc_ch_admin, MAX_NODES_DISK,
&retnodes, nodes) <0 )
@@ -586,6 +587,18 @@ check_cman(qd_ctx *ctx, memb_mask_t mask, memb_mask_t master_mask)
memset(master_mask, 0, sizeof(master_mask));
for (x = 0; x < retnodes; x++) {
+ /* See if the other node is running cman and not qdiskd.
+ * Just do this every 4 times (seconds) so we don't spam syslog
+ * too much. cman_is_listening() can return EBUSY which means
+ * "I don't know". We don't worry about this, and just report
+ * at the next check by which time it will.
+ */
+ check_cycle = (check_cycle + 1) % 4;
+ if ((check_cycle == 1) &&
+ (cman_is_listening(ctx->qc_ch_admin, nodes[x].cn_nodeid,
+ CLUSTER_PORT_QDISKD) == 0)) {
+ clulog(LOG_NOTICE, "node %s is up but not running qdiskd\n", nodes[x].cn_name);
+ }
if (is_bit_set(mask, nodes[x].cn_nodeid-1, sizeof(mask)) &&
nodes[x].cn_member) {
set_bit(master_mask, nodes[x].cn_nodeid-1,
10 years, 1 month
gfs2-utils: RHEL7 - gfs2-utils: check and fix bad dinode pointers in gfs1 sb
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=d6b100b8...
Commit: d6b100b8e2315ab6e072f02bf63a1aacefda6f7d
Parent: 8c6a8ff80b4c02e898fdaf1b2b7a3232ad67a4f9
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Fri Mar 21 10:18:48 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Fri Mar 21 12:49:43 2014 -0500
gfs2-utils: check and fix bad dinode pointers in gfs1 sb
This patch makes gfs2_convert check for bad values of sb_seg_size,
sb_quota_di and sb_license_di.
In fsck.gfs2, attempts are made to correct these erroneous values.
This v2 patch checks with the user before making changes to the
superblock in fsck.gfs2 and also adds some error messaging as per
Bob's comments.
Resolves: rhbz#1079507
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 29 ++++++++++++++
gfs2/fsck/initialize.c | 89 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 118 insertions(+), 0 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index ce056a7..e3343d0 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1553,6 +1553,24 @@ static int read_gfs1_jiindex(struct gfs2_sbd *sdp)
return -1;
}
+static int sanity_check(struct gfs2_sbd *sdp)
+{
+ int error = 0;
+ if (!raw_gfs1_ondisk_sb.sb_quota_di.no_addr) {
+ log_crit(_("Error: Superblock Quota inode address is NULL\n"));
+ error = 1;
+ }
+ if (!raw_gfs1_ondisk_sb.sb_license_di.no_addr) {
+ log_crit(_("Error: Superblock Statfs inode address is NULL\n"));
+ error = 1;
+ }
+ if (!raw_gfs1_ondisk_sb.sb_seg_size) {
+ log_crit(_("Error: Superblock segment size is zero\n"));
+ error = 1;
+ }
+ return error;
+}
+
/* ------------------------------------------------------------------------- */
/* init - initialization code */
/* Returns: 0 on success, -1 on failure */
@@ -2203,6 +2221,17 @@ int main(int argc, char **argv)
process_parameters(argc, argv, &opts);
error = init(&sb2);
+ /*
+ * Check for some common fs errors
+ */
+ if (!error) {
+ if (sanity_check(&sb2)) {
+ log_crit(_("%s is not a clean gfs filesytem. Please use the"
+ " fsck.gfs2 utility to correct these errors and"
+ " try again.\n"), device);
+ exit(0);
+ }
+ }
/* ---------------------------------------------- */
/* Make them seal their fate. */
/* ---------------------------------------------- */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 0f33aa6..33cf85b 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -727,6 +727,19 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
if (sdp->gfs1) {
+ /* In gfs1, the license_di is always 3 blocks after the jindex_di */
+ if ((sbd1->sb_license_di.no_addr != sbd1->sb_jindex_di.no_addr + 3) ||
+ (sbd1->sb_license_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 3)) {
+ if (!query( _("The gfs system statfs inode pointer is incorrect. "
+ "Okay to correct? (y/n) "))) {
+ log_err( _("fsck.gfs2 cannot continue without a valid "
+ "statfs file; aborting.\n"));
+ goto fail;
+ }
+ sbd1->sb_license_di.no_addr = sbd1->sb_license_di.no_formal_ino
+ = sbd1->sb_jindex_di.no_addr + 3;
+ }
+
sdp->md.statfs = lgfs2_inode_read(sdp, sbd1->sb_license_di.no_addr);
if (sdp->md.statfs == NULL) {
log_crit(_("Error reading statfs inode: %s\n"), strerror(errno));
@@ -773,6 +786,19 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
if (sdp->gfs1) {
+ /* In gfs1, the quota_di is always 2 blocks after the jindex_di */
+ if ((sbd1->sb_quota_di.no_addr != sbd1->sb_jindex_di.no_addr + 2) ||
+ (sbd1->sb_quota_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 2)) {
+ if (!query( _("The gfs system quota inode pointer is incorrect. "
+ " Okay to correct? (y/n) "))) {
+ log_err( _("fsck.gfs2 cannot continue without a valid "
+ "quota file; aborting.\n"));
+ goto fail;
+ }
+ sbd1->sb_quota_di.no_addr = sbd1->sb_quota_di.no_formal_ino
+ = sbd1->sb_jindex_di.no_addr + 2;
+ }
+
sdp->md.qinode = lgfs2_inode_read(sdp, sbd1->sb_quota_di.no_addr);
if (sdp->md.qinode == NULL) {
log_crit(_("Error reading quota inode: %s\n"), strerror(errno));
@@ -1354,6 +1380,63 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
return 0;
}
+static int reset_journal_seg_size(unsigned int jsize, unsigned int nsegs,
+ unsigned int bsize)
+{
+ unsigned int seg_size = jsize / (nsegs * bsize);
+ if (!seg_size)
+ seg_size = 16; /* The default with 128MB journal and 4K bsize */
+ if (seg_size != sbd1->sb_seg_size) {
+ sbd1->sb_seg_size = seg_size;
+ if (!query(_("Computed correct journal segment size to %u."
+ " Reset it? (y/n) "), seg_size)) {
+ log_crit(_("Error: Cannot proceed without a valid journal"
+ " segment size value.\n"));
+ return -1;
+ }
+ log_err(_("Resetting journal segment size to %u\n"), sbd1->sb_seg_size);
+ }
+ return 0;
+}
+
+static int correct_journal_seg_size(struct gfs2_sbd *sdp)
+{
+ int count;
+ struct gfs_jindex ji_0, ji_1;
+ char buf[sizeof(struct gfs_jindex)];
+ unsigned int jsize = GFS2_DEFAULT_JSIZE * 1024 * 1024;
+
+ count = gfs2_readi(sdp->md.jiinode, buf, 0, sizeof(struct gfs_jindex));
+ if (count != sizeof(struct gfs_jindex)) {
+ log_crit(_("Error %d reading system journal index inode. "
+ "Aborting\n"), count);
+ return -1;
+ }
+ gfs_jindex_in(&ji_0, buf);
+
+ if (sdp->md.journals == 1 && sbd1->sb_seg_size == 0) {
+ if (!query(_("The gfs2 journal segment size is 0 and a correct value\n"
+ "cannot be determined in a single-journal filesystem.\n"
+ "Continue with default? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid sb_seg_size value.\n"));
+ return -1;
+ }
+ goto out;
+ }
+
+ count = gfs2_readi(sdp->md.jiinode, buf, sizeof(struct gfs_jindex),
+ sizeof(struct gfs_jindex));
+ if (count != sizeof(struct gfs_jindex)) {
+ log_crit(_("Error %d reading system journal index inode. "
+ "Aborting\n"), count);
+ return -1;
+ }
+ gfs_jindex_in(&ji_1, buf);
+
+ jsize = (ji_1.ji_addr - ji_0.ji_addr) * sbd1->sb_bsize;
+out:
+ return reset_journal_seg_size(jsize, ji_0.ji_nsegment, sbd1->sb_bsize);
+}
/*
* reconstruct_journals - write fresh journals for GFS1 only
@@ -1367,6 +1450,12 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
struct gfs_jindex ji;
char buf[sizeof(struct gfs_jindex)];
+ /* Ensure that sb_seg_size is valid */
+ if (correct_journal_seg_size(sdp)) {
+ log_crit(_("Failed to set correct journal segment size. Cannot continue\n"));
+ return -1;
+ }
+
log_err(_("Clearing GFS journals (this may take a while)\n"));
for (i = 0; i < sdp->md.journals; i++) {
count = gfs2_readi(sdp->md.jiinode, buf,
10 years, 1 month
gfs2-utils: RHEL7 - libgfs2: patch to update gfs1 superblock correctly
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=8c6a8ff8...
Commit: 8c6a8ff80b4c02e898fdaf1b2b7a3232ad67a4f9
Parent: e7b57dae8cfd096514b970d200e1e97648b495a6
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Fri Mar 21 10:15:24 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Fri Mar 21 12:48:51 2014 -0500
libgfs2: patch to update gfs1 superblock correctly
gfs2-utils uses the gfs2_sb structure as a template to operate on
both gfs1 and gfs2 superblocks. Some fields of the gfs1 superblock
are not in gfs2 and are replaced by padded fields. These padded
fields were not being written out after modification and were
instead being zeroed out, thereby causing corruption.
This patch fixes gfs2_sb_out() to write out the padded fields.
Resolves: rhbz#1079507
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/libgfs2/ondisk.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index dcc537e..3fbc63f 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -132,15 +132,20 @@ void gfs2_sb_out(const struct gfs2_sb *sb, char *buf)
CPOUT_32(sb, str, sb_fs_format);
CPOUT_32(sb, str, sb_multihost_format);
+ CPOUT_32(sb, str, __pad0); /* gfs sb_flags */
CPOUT_32(sb, str, sb_bsize);
CPOUT_32(sb, str, sb_bsize_shift);
+ CPOUT_32(sb, str, __pad1); /* gfs sb_seg_size */
gfs2_inum_out(&sb->sb_master_dir, (char *)&str->sb_master_dir);
gfs2_inum_out(&sb->sb_root_dir, (char *)&str->sb_root_dir);
CPOUT_08(sb, str, sb_lockproto, GFS2_LOCKNAME_LEN);
CPOUT_08(sb, str, sb_locktable, GFS2_LOCKNAME_LEN);
+ gfs2_inum_out(&sb->__pad2, (char *)&str->__pad2); /* gfs rindex */
+ gfs2_inum_out(&sb->__pad3, (char *)&str->__pad3); /* gfs quota */
+ gfs2_inum_out(&sb->__pad4, (char *)&str->__pad4); /* gfs license */
#ifdef GFS2_HAS_UUID
memcpy(str->sb_uuid, sb->sb_uuid, 16);
#endif
10 years, 1 month
gfs2-utils: master - gfs2-utils: check and fix bad dinode pointers in gfs1 sb
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=d394637d...
Commit: d394637d9c6586d8bb5a872f8763b90720f81500
Parent: f8d4e5711ab545af5ec577386e4e2ce0c111cea1
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Fri Mar 21 10:18:48 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Fri Mar 21 10:18:48 2014 -0500
gfs2-utils: check and fix bad dinode pointers in gfs1 sb
This patch makes gfs2_convert check for bad values of sb_seg_size,
sb_quota_di and sb_license_di.
In fsck.gfs2, attempts are made to correct these erroneous values.
This v2 patch checks with the user before making changes to the
superblock in fsck.gfs2 and also adds some error messaging as per
Bob's comments.
Resolves: rhbz#1053668
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 29 ++++++++++++++
gfs2/fsck/initialize.c | 89 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 118 insertions(+), 0 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 7a7d4df..9f7fa17 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1502,6 +1502,24 @@ static int read_gfs1_jiindex(struct gfs2_sbd *sdp)
return -1;
}
+static int sanity_check(struct gfs2_sbd *sdp)
+{
+ int error = 0;
+ if (!raw_gfs1_ondisk_sb.sb_quota_di.no_addr) {
+ log_crit(_("Error: Superblock Quota inode address is NULL\n"));
+ error = 1;
+ }
+ if (!raw_gfs1_ondisk_sb.sb_license_di.no_addr) {
+ log_crit(_("Error: Superblock Statfs inode address is NULL\n"));
+ error = 1;
+ }
+ if (!raw_gfs1_ondisk_sb.sb_seg_size) {
+ log_crit(_("Error: Superblock segment size is zero\n"));
+ error = 1;
+ }
+ return error;
+}
+
/* ------------------------------------------------------------------------- */
/* init - initialization code */
/* Returns: 0 on success, -1 on failure */
@@ -2152,6 +2170,17 @@ int main(int argc, char **argv)
process_parameters(argc, argv, &opts);
error = init(&sb2);
+ /*
+ * Check for some common fs errors
+ */
+ if (!error) {
+ if (sanity_check(&sb2)) {
+ log_crit(_("%s is not a clean gfs filesytem. Please use the"
+ " fsck.gfs2 utility to correct these errors and"
+ " try again.\n"), device);
+ exit(0);
+ }
+ }
/* ---------------------------------------------- */
/* Make them seal their fate. */
/* ---------------------------------------------- */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 0f33aa6..33cf85b 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -727,6 +727,19 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
if (sdp->gfs1) {
+ /* In gfs1, the license_di is always 3 blocks after the jindex_di */
+ if ((sbd1->sb_license_di.no_addr != sbd1->sb_jindex_di.no_addr + 3) ||
+ (sbd1->sb_license_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 3)) {
+ if (!query( _("The gfs system statfs inode pointer is incorrect. "
+ "Okay to correct? (y/n) "))) {
+ log_err( _("fsck.gfs2 cannot continue without a valid "
+ "statfs file; aborting.\n"));
+ goto fail;
+ }
+ sbd1->sb_license_di.no_addr = sbd1->sb_license_di.no_formal_ino
+ = sbd1->sb_jindex_di.no_addr + 3;
+ }
+
sdp->md.statfs = lgfs2_inode_read(sdp, sbd1->sb_license_di.no_addr);
if (sdp->md.statfs == NULL) {
log_crit(_("Error reading statfs inode: %s\n"), strerror(errno));
@@ -773,6 +786,19 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
if (sdp->gfs1) {
+ /* In gfs1, the quota_di is always 2 blocks after the jindex_di */
+ if ((sbd1->sb_quota_di.no_addr != sbd1->sb_jindex_di.no_addr + 2) ||
+ (sbd1->sb_quota_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 2)) {
+ if (!query( _("The gfs system quota inode pointer is incorrect. "
+ " Okay to correct? (y/n) "))) {
+ log_err( _("fsck.gfs2 cannot continue without a valid "
+ "quota file; aborting.\n"));
+ goto fail;
+ }
+ sbd1->sb_quota_di.no_addr = sbd1->sb_quota_di.no_formal_ino
+ = sbd1->sb_jindex_di.no_addr + 2;
+ }
+
sdp->md.qinode = lgfs2_inode_read(sdp, sbd1->sb_quota_di.no_addr);
if (sdp->md.qinode == NULL) {
log_crit(_("Error reading quota inode: %s\n"), strerror(errno));
@@ -1354,6 +1380,63 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
return 0;
}
+static int reset_journal_seg_size(unsigned int jsize, unsigned int nsegs,
+ unsigned int bsize)
+{
+ unsigned int seg_size = jsize / (nsegs * bsize);
+ if (!seg_size)
+ seg_size = 16; /* The default with 128MB journal and 4K bsize */
+ if (seg_size != sbd1->sb_seg_size) {
+ sbd1->sb_seg_size = seg_size;
+ if (!query(_("Computed correct journal segment size to %u."
+ " Reset it? (y/n) "), seg_size)) {
+ log_crit(_("Error: Cannot proceed without a valid journal"
+ " segment size value.\n"));
+ return -1;
+ }
+ log_err(_("Resetting journal segment size to %u\n"), sbd1->sb_seg_size);
+ }
+ return 0;
+}
+
+static int correct_journal_seg_size(struct gfs2_sbd *sdp)
+{
+ int count;
+ struct gfs_jindex ji_0, ji_1;
+ char buf[sizeof(struct gfs_jindex)];
+ unsigned int jsize = GFS2_DEFAULT_JSIZE * 1024 * 1024;
+
+ count = gfs2_readi(sdp->md.jiinode, buf, 0, sizeof(struct gfs_jindex));
+ if (count != sizeof(struct gfs_jindex)) {
+ log_crit(_("Error %d reading system journal index inode. "
+ "Aborting\n"), count);
+ return -1;
+ }
+ gfs_jindex_in(&ji_0, buf);
+
+ if (sdp->md.journals == 1 && sbd1->sb_seg_size == 0) {
+ if (!query(_("The gfs2 journal segment size is 0 and a correct value\n"
+ "cannot be determined in a single-journal filesystem.\n"
+ "Continue with default? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid sb_seg_size value.\n"));
+ return -1;
+ }
+ goto out;
+ }
+
+ count = gfs2_readi(sdp->md.jiinode, buf, sizeof(struct gfs_jindex),
+ sizeof(struct gfs_jindex));
+ if (count != sizeof(struct gfs_jindex)) {
+ log_crit(_("Error %d reading system journal index inode. "
+ "Aborting\n"), count);
+ return -1;
+ }
+ gfs_jindex_in(&ji_1, buf);
+
+ jsize = (ji_1.ji_addr - ji_0.ji_addr) * sbd1->sb_bsize;
+out:
+ return reset_journal_seg_size(jsize, ji_0.ji_nsegment, sbd1->sb_bsize);
+}
/*
* reconstruct_journals - write fresh journals for GFS1 only
@@ -1367,6 +1450,12 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
struct gfs_jindex ji;
char buf[sizeof(struct gfs_jindex)];
+ /* Ensure that sb_seg_size is valid */
+ if (correct_journal_seg_size(sdp)) {
+ log_crit(_("Failed to set correct journal segment size. Cannot continue\n"));
+ return -1;
+ }
+
log_err(_("Clearing GFS journals (this may take a while)\n"));
for (i = 0; i < sdp->md.journals; i++) {
count = gfs2_readi(sdp->md.jiinode, buf,
10 years, 1 month
gfs2-utils: master - libgfs2: patch to update gfs1 superblock correctly
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=f8d4e571...
Commit: f8d4e5711ab545af5ec577386e4e2ce0c111cea1
Parent: dce63a150565f91d1386e2444d6cb378e8be1dd5
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Fri Mar 21 10:15:24 2014 -0500
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Fri Mar 21 10:15:24 2014 -0500
libgfs2: patch to update gfs1 superblock correctly
gfs2-utils uses the gfs2_sb structure as a template to operate on
both gfs1 and gfs2 superblocks. Some fields of the gfs1 superblock
are not in gfs2 and are replaced by padded fields. These padded
fields were not being written out after modification and were
instead being zeroed out, thereby causing corruption.
This patch fixes gfs2_sb_out() to write out the padded fields.
Resolves: rhbz#1053668
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/libgfs2/ondisk.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index dcc537e..3fbc63f 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -132,15 +132,20 @@ void gfs2_sb_out(const struct gfs2_sb *sb, char *buf)
CPOUT_32(sb, str, sb_fs_format);
CPOUT_32(sb, str, sb_multihost_format);
+ CPOUT_32(sb, str, __pad0); /* gfs sb_flags */
CPOUT_32(sb, str, sb_bsize);
CPOUT_32(sb, str, sb_bsize_shift);
+ CPOUT_32(sb, str, __pad1); /* gfs sb_seg_size */
gfs2_inum_out(&sb->sb_master_dir, (char *)&str->sb_master_dir);
gfs2_inum_out(&sb->sb_root_dir, (char *)&str->sb_root_dir);
CPOUT_08(sb, str, sb_lockproto, GFS2_LOCKNAME_LEN);
CPOUT_08(sb, str, sb_locktable, GFS2_LOCKNAME_LEN);
+ gfs2_inum_out(&sb->__pad2, (char *)&str->__pad2); /* gfs rindex */
+ gfs2_inum_out(&sb->__pad3, (char *)&str->__pad3); /* gfs quota */
+ gfs2_inum_out(&sb->__pad4, (char *)&str->__pad4); /* gfs license */
#ifdef GFS2_HAS_UUID
memcpy(str->sb_uuid, sb->sb_uuid, 16);
#endif
10 years, 1 month