From: rpeterso@redhat.com <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 60/66] fsck.gfs2: Journals not properly checked
Date: Fri, 20 Jan 2012 09:10:41 -0600 [thread overview]
Message-ID: <1327072247-26275-61-git-send-email-rpeterso@redhat.com> (raw)
In-Reply-To: <1327072247-26275-1-git-send-email-rpeterso@redhat.com>
From: Bob Peterson <rpeterso@redhat.com>
The coverity tool found a problem with the previous set of patches that
led me to discover a problem with how journals were being processed
under the new code. The problem was that the journal index was read
in after journal replay. But journal replay relies upon information
in the jindex. This patch rearranges the initializeation sequence
of fsck.gfs2 so that the journal index and rindex are read in and
processed prior to journal recovery.
rhbz#675723
---
gfs2/fsck/fs_recovery.c | 12 ---
gfs2/fsck/initialize.c | 183 +++++++++++++++++++++++++++++++----------------
2 files changed, 122 insertions(+), 73 deletions(-)
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index d3c742a..52303dd 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -572,14 +572,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
*clean_journals = 0;
sdp->jsize = GFS2_DEFAULT_JSIZE;
- /* Get master dinode */
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
-
- /* read in the journal index data */
- if (ji_update(sdp)){
- log_err( _("Unable to read in jindex inode.\n"));
- return -1;
- }
for(i = 0; i < sdp->md.journals; i++) {
if (!sdp->md.journal[i]) {
@@ -608,11 +600,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
*clean_journals += clean;
}
- inode_put(&sdp->md.journal[i]);
}
- inode_put(&sdp->md.jiinode);
- free(sdp->md.journal);
- sdp->md.journal = NULL;
/* Sync the buffers to disk so we get a fresh start. */
fsync(sdp->device_fd);
return error;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 95a6a65..608eb32 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -477,18 +477,13 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
}
/**
- * init_system_inodes
- *
- * Returns: 0 on success, -1 on failure
+ * fetch_rgrps - fetch the resource groups from disk, and check their integrity
*/
-static int init_system_inodes(struct gfs2_sbd *sdp)
+static int fetch_rgrps(struct gfs2_sbd *sdp)
{
- uint64_t inumbuf;
- char *buf;
- struct gfs2_statfs_change sc;
- int rgcount, sane = 1, err = 0;
enum rgindex_trust_level trust_lvl;
- uint64_t addl_mem_needed;
+ int rgcount, sane = 1;
+
const char *level_desc[] = {
_("Checking if all rgrp and rindex values are good"),
_("Checking if rindex values may be easily repaired"),
@@ -503,48 +498,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
_("Too many rgrp misses: rgrps must be unevenly spaced"),
_("Too much damage found: we cannot rebuild this rindex"),
};
-
- /*******************************************************************
- ****************** Initialize important inodes ******************
- *******************************************************************/
-
- log_info( _("Initializing special inodes...\n"));
-
- /* Get root dinode */
- sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
-
- if (sdp->gfs1)
- sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
- else
- gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
- if (!sdp->md.riinode) {
- if (query( _("The gfs2 system rindex inode is missing. "
- "Okay to rebuild it? (y/n) ")))
- build_rindex(sdp);
- }
-
- /*******************************************************************
- ****************** Fill in journal information ******************
- *******************************************************************/
-
- /* rgrepair requires the journals be read in in order to distinguish
- "real" rgrps from rgrps that are just copies left in journals. */
- if (sdp->gfs1)
- sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
- else
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
- if (!sdp->md.jiinode) {
- if (query( _("The gfs2 system jindex inode is missing. "
- "Okay to rebuild it? (y/n) ")))
- build_jindex(sdp);
- }
-
- /* read in the ji data */
- if (ji_update(sdp)){
- log_err( _("Unable to read in jindex inode.\n"));
- return -1;
- }
-
/*******************************************************************
******** Validate and read in resource group information ********
*******************************************************************/
@@ -580,6 +533,34 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
log_info( _("%u resource groups found.\n"), rgcount);
check_rgrps_integrity(sdp);
+ return 0;
+}
+
+/**
+ * init_system_inodes
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int init_system_inodes(struct gfs2_sbd *sdp)
+{
+ uint64_t inumbuf = 0;
+ char *buf;
+ struct gfs2_statfs_change sc;
+ uint64_t addl_mem_needed;
+ int err;
+
+ /*******************************************************************
+ ****************** Initialize important inodes ******************
+ *******************************************************************/
+
+ log_info( _("Initializing special inodes...\n"));
+
+ /* Get root dinode */
+ sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
+
+ err = fetch_rgrps(sdp);
+ if (err)
+ return err;
/*******************************************************************
***************** Initialize more system inodes *****************
@@ -1232,8 +1213,6 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
log_info("Clearing journal %d\n", jnum);
for (seg = 0; seg < ji_nsegment; seg++){
- bh = bget(sdp, lh.lh_first * sdp->bsize);
- memset(bh->b_data, 0, sdp->bsize);
memset(&lh, 0, sizeof(struct gfs_log_header));
lh.lh_header.mh_magic = GFS2_MAGIC;
@@ -1245,6 +1224,8 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
(seg * sbd1->sb_seg_size);
lh.lh_sequence = sequence;
+ bh = bget(sdp, lh.lh_first * sdp->bsize);
+ memset(bh->b_data, 0, sdp->bsize);
gfs_log_header_out(&lh, bh->b_data);
gfs_log_header_out(&lh, bh->b_data + GFS2_BASIC_BLOCK -
sizeof(struct gfs_log_header));
@@ -1269,7 +1250,7 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
struct gfs_jindex ji;
char buf[sizeof(struct gfs_jindex)];
- log_err("Clearing GFS journals (this may take a while)");
+ log_err("Clearing GFS journals (this may take a while)\n");
for (i = 0; i < sdp->md.journals; i++) {
gfs2_readi(sdp->md.jiinode, buf, i * sizeof(struct gfs_jindex),
sizeof(struct gfs_jindex));
@@ -1284,6 +1265,81 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
}
/**
+ * init_rindex - read in the rindex file
+ */
+static int init_rindex(struct gfs2_sbd *sdp)
+{
+ int err;
+
+ if (sdp->gfs1)
+ sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
+ else
+ gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
+
+ if (sdp->md.riinode)
+ return 0;
+
+ if (!query( _("The gfs2 system rindex inode is missing. "
+ "Okay to rebuild it? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid rindex.\n"));
+ return -1;
+ }
+ if ((err = build_rindex(sdp))) {
+ log_crit(_("Error %d rebuilding rindex\n"), err);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * init_jindex - read in the rindex file
+ */
+static int init_jindex(struct gfs2_sbd *sdp)
+{
+ /*******************************************************************
+ ****************** Fill in journal information ******************
+ *******************************************************************/
+
+ /* rgrepair requires the journals be read in in order to distinguish
+ "real" rgrps from rgrps that are just copies left in journals. */
+ if (sdp->gfs1)
+ sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
+ else
+ gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
+
+ if (!sdp->md.jiinode) {
+ int err;
+
+ if (!query( _("The gfs2 system jindex inode is missing. "
+ "Okay to rebuild it? (y/n) "))) {
+ log_crit(_("Error: cannot proceed without a valid "
+ "jindex file.\n"));
+ return -1;
+ }
+ /* In order to rebuild jindex, we need some valid
+ rgrps in memory. Temporarily read those in. */
+ err = fetch_rgrps(sdp);
+ if (err)
+ return err;
+
+ err = build_jindex(sdp);
+ /* Free rgrps read in earlier (re-read them later) */
+ gfs2_rgrp_free(&sdp->rgtree);
+ if (err) {
+ log_crit(_("Error %d rebuilding jindex\n"), err);
+ return err;
+ }
+ }
+
+ /* read in the ji data */
+ if (ji_update(sdp)){
+ log_err( _("Unable to read in jindex inode.\n"));
+ return -1;
+ }
+ return 0;
+}
+
+/**
* initialize - initialize superblock pointer
*
*/
@@ -1372,7 +1428,17 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
if (!sdp->gfs1)
lookup_per_node(sdp, 0);
- /* verify various things */
+ /* We need rindex first in case jindex is missing and needs to read
+ in the rgrps before rebuilding it. */
+ if (init_rindex(sdp))
+ return FSCK_ERROR;
+
+ /* We need to read in jindex in order to replay the journals */
+ if (init_jindex(sdp))
+ return FSCK_ERROR;
+
+ /* If GFS, rebuild the journals. If GFS2, replay them. We don't have
+ the smarts to replay GFS1 journals (neither did gfs_fsck). */
if (sdp->gfs1) {
if (reconstruct_journals(sdp))
@@ -1403,7 +1469,7 @@ mount_fail:
return FSCK_USAGE;
}
-static void destroy_sdp(struct gfs2_sbd *sdp)
+void destroy(struct gfs2_sbd *sdp)
{
if (!opts.no) {
if (block_mounters(sdp, 0)) {
@@ -1425,8 +1491,3 @@ static void destroy_sdp(struct gfs2_sbd *sdp)
"caches.\n"));
}
}
-
-void destroy(struct gfs2_sbd *sdp)
-{
- destroy_sdp(sdp);
-}
--
1.7.7.5
next prev parent reply other threads:[~2012-01-20 15:10 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 01/66] fsck.gfs2: Make functions use sdp rather than sbp rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 02/66] fsck.gfs2: Change "if(" to "if (" rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 03/66] libgfs1: Add gfs1 variable to superblock structure rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 04/66] libgfs2: Make check_sb and read_sb operate on gfs1 rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 05/66] libgfs2: move gfs1 structures to libgfs2 rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 06/66] fsck.gfs2: Check for blocks wrongly inside resource groups rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 07/66] fsck.gfs2: Rename check_leaf to check_ealeaf_block rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 08/66] fsck.gfs2: fsck.gfs2: Delete vestigial buffer_head in check_leaf rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 09/66] fsck.gfs2: fsck.gfs2: Rename nlink functions to be intuitive rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 10/66] fsck.gfs2: fsck.gfs2: Sync di_nlink adding links for lost+found rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 11/66] fsck.gfs2: fsck.gfs2: Make dir entry count 32 bits rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 12/66] fsck.gfs2: get rid of triple negative logic rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 13/66] dirent_repair needs to mark the buffer as modified rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 14/66] fsck.gfs2: fsck.gfs2: Ask to reclaim unlinked meta per-rgrp only rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 15/66] fsck.gfs2: fsck.gfs2: Refactor add_dotdot function in lost+found rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 16/66] libgfs2: libgfs2: Use __FUNCTION__ rather than __FILE__ rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 17/66] fsck.gfs2: fsck.gfs2: Don't stop invalidating blocks on invalid rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 18/66] fsck.gfs2: fsck.gfs2: Find and clear duplicate leaf blocks refs rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 19/66] fsck.gfs2: fsck.gfs2: Move check_num_ptrs from metawalk to pass1 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 20/66] fsck.gfs2: fsck.gfs2: Duplicate ref processing for leaf blocks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 21/66] fsck.gfs2: fsck.gfs2: split check_leaf_blks to be more readable rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 22/66] fsck.gfs2: Shorten output rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 23/66] fsck.gfs2: Make output messages more sensible rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 24/66] fsck.gfs pass2: Refactor function set_dotdot_dir rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 25/66] fsck.gfs2 pass2: Delete extended attributes with inode rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 26/66] fsck.gfs2 pass2: Don't delete invalid inode metadata rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 27/66] fsck.gfs2 pass3: Refactor mark_and_return_parent rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 28/66] fsck.gfs2: misc cosmetic changes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 29/66] fsck.gfs2: Don't use old_leaf if it was a duplicate rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 30/66] fsck.gfs2: Add find_remove_dup, free_block_if_notdup rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 31/66] fsck.gfs2: don't free prev rgrp list repairing rgrps rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 32/66] libgfs2: eliminate gfs1_readi in favor of gfs2_readi rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 33/66] libgfs2: Mark buffer modified adding a new GFS1 block rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 34/66] libgfs2: Use dinode buffer to map gfs1 dinode blocks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 35/66] libgfs2: move block_map functions to fsck.gfs2 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 36/66] libgfs2: eliminate gfs1_rindex_read rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 37/66] libgfs2: combine ri_update and gfs1_ri_update rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 38/66] libgfs2: combine gfs_inode_read and gfs_inode_get rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 39/66] libgfs2: move gfs1 functions from edit to libgfs2 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 40/66] gfs2_edit savemeta: save_inode_data backward for gfs1 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 41/66] libgfs2: expand capabilities to operate on gfs1 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 42/66] fsck.gfs2: Combine block and char device inode types rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 43/66] fsck.gfs2: four-step duplicate elimination process rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 44/66] fsck.gfs2: Add ability to check gfs1 file systems rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 45/66] fsck.gfs2: Remove bad inodes from duplicate tree rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 46/66] fsck.gfs2: Handle duplicate reference to dinode blocks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 47/66] fsck.gfs2: Bad extended attributes not deleted properly rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 48/66] libgfs2: Make rebuild functions not re-read ip rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 49/66] fsck.gfs2: Shorten debug output rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 50/66] fsck.gfs2: Increment link count reporting wrong dinode rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 51/66] fsck.gfs2: system dinodes take priority over user dinodes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 52/66] fsck.gfs2: Recognize partially gfs2-converted dinodes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 53/66] fsck.gfs2: Print step 2 duplicate debug msg first rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 54/66] fsck.gfs2: pass1c counts percentage backward rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 55/66] fsck.gfs2: Speed up rangecheck functions rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 56/66] libgfs2: Make in-core rgrps use rbtree rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 57/66] fsck.gfs2: Fix memory leaks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 58/66] Change man pages and gfs2_convert messages to include GFS rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 59/66] gfs2_edit: Fix memory leaks rpeterso
2012-01-20 15:10 ` rpeterso [this message]
2012-01-20 15:10 ` [Cluster-devel] [PATCH 61/66] fsck.gfs2: Rearrange block types to group all inode types rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 62/66] fsck.gfs2: Fix initialization error return codes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 63/66] fsck.gfs2: Don't use strerror for libgfs2 errors rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 64/66] fsck.gfs2: Fix memory leak in initialize.c rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 65/66] fsck.gfs2: Add return code checks and initializations rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 66/66] libgfs2: Fix null pointer dereference in linked_leaf_search rpeterso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1327072247-26275-61-git-send-email-rpeterso@redhat.com \
--to=rpeterso@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).