From: rpeterso@redhat.com <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 38/42] fsck.gfs2: check for duplicate first references
Date: Mon, 8 Apr 2013 07:41:10 -0700 [thread overview]
Message-ID: <1365432074-17615-39-git-send-email-rpeterso@redhat.com> (raw)
In-Reply-To: <1365432074-17615-1-git-send-email-rpeterso@redhat.com>
From: Bob Peterson <rpeterso@redhat.com>
Before this patch, fsck.gfs2 could get into situations where it's
in pass1b searching for the first reference to a block that it knows
has been referenced twice. However, for one reason or another, the
first reference has been deleted. It may seem unlikely because pass1
tries to "undo" its references when it deletes a bad dinode. But
it can still happen, for example, when pass1b decides to delete a
dinode because of a _different_ duplicate reference within the same
dinode. If the first reference was deleted prior to searching for the
original reference, pass1b won't find the original reference. So
prior to this patch, it would just keep on looking, until it found
the second reference. In other words, it would mistake the second
reference for the first reference. Then it would get confused and
treat the reference as a duplicate of itself. Later, it would choose
which reference to delete, and delete its dinode. But since they're
the same reference, it could delete a dinode with a perfectly good
reference (the first invalid reference having already been deleted).
The solution that this patch implements is to check if the first
reference we found is actually the second reference, and if so,
treat it as a first reference. That way, it avoids creating a
second duplicate reference structure, and later when it resolves
the references, it finds there's only one, and it doesn't need to
delete the valid dinode.
rhbz#902920
---
gfs2/fsck/util.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 078d5f6..fc3a0ec 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -330,6 +330,28 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
if (dt->first_ref_found)
return meta_is_good;
+ /* Check for a previous reference to this duplicate */
+ id = find_dup_ref_inode(dt, ip);
+
+ /* We have to be careful here. The original referencing dinode may have
+ deemed to be bad and deleted/freed in pass1. In that case, pass1b
+ wouldn't discover the correct [deleted] original reference. In
+ that case, we don't want to be confused and consider this second
+ reference the same as the first. If we do, we'll never be able to
+ resolve it. The first reference can't be the second reference. */
+ if (id && first && !dt->first_ref_found) {
+ log_info(_("Original reference to block %llu (0x%llx) was "
+ "previously found to be bad and deleted.\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
+ log_info(_("I'll consider the reference from inode %llu "
+ "(0x%llx) the first reference.\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ dt->first_ref_found = 1;
+ return meta_is_good;
+ }
+
/* The first time this is called from pass1 is actually the second
reference. When we go back in pass1b looking for the original
reference, we don't want to increment the reference count because
@@ -341,8 +363,6 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
dt->refs++;
}
- /* Check for a previous reference to this duplicate */
- id = find_dup_ref_inode(dt, ip);
if (id == NULL) {
/* Check for the inode on the invalid inode reference list. */
uint8_t q;
--
1.7.11.7
next prev parent reply other threads:[~2013-04-08 14:41 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-08 14:40 [Cluster-devel] [PATCH 00/42] fsck.gfs2 fixes and improvements rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 01/42] libgfs2: externalize dir_split_leaf rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 02/42] libgfs2: allow dir_split_leaf to receive a leaf buffer rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 03/42] libgfs2: let dir_split_leaf receive a "broken" lindex rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 04/42] fsck.gfs2: Move function find_free_blk to util.c rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 05/42] fsck.gfs2: Split out function to make sure lost+found exists rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 06/42] fsck.gfs2: Check for formal inode mismatch when adding to lost+found rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 07/42] fsck.gfs2: shorten some debug messages in lost+found rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 08/42] fsck.gfs2: Move basic directory entry checks to separate function rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 09/42] fsck.gfs2: Add formal inode check to basic dirent checks rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 10/42] fsck.gfs2: Add new function to check dir hash tables rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 11/42] fsck.gfs2: Special case '..' when processing bad formal inode number rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 12/42] fsck.gfs2: Move function to read directory hash table to util.c rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 13/42] fsck.gfs2: Misc cleanups rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 14/42] fsck.gfs2: Verify dirent hash values correspond to proper leaf block rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 15/42] fsck.gfs2: re-read hash table if directory height or depth changes rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 16/42] fsck.gfs2: fix leaf blocks, don't try to patch the hash table rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 17/42] fsck.gfs2: check leaf depth when validating leaf blocks rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 18/42] fsck.gfs2: small cleanups rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 19/42] fsck.gfs2: reprocess inodes when blocks are added rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 20/42] fsck.gfs2: Remove redundant leaf depth check rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 21/42] fsck.gfs2: link dinodes that only have extended attribute problems rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 22/42] fsck.gfs2: Add clarifying message to duplicate processing rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 23/42] fsck.gfs2: separate function to calculate metadata block header size rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 24/42] fsck.gfs2: Rework the "undo" functions rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 25/42] fsck.gfs2: Check for interrupt when resolving duplicates rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 26/42] fsck.gfs2: Consistent naming of struct duptree variables rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 27/42] fsck.gfs2: Keep proper counts when duplicates are found rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 28/42] fsck.gfs2: print metadata block reference on data errors rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 29/42] fsck.gfs2: print block count values when fixing them rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 30/42] fsck.gfs2: Do not invalidate metablocks of dinodes with invalid mode rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 31/42] fsck.gfs2: Log when unrecoverable data block errors are encountered rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 32/42] fsck.gfs2: don't remove buffers from the list when errors are found rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 33/42] fsck.gfs2: Don't flag GFS1 non-dinode blocks as duplicates rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 34/42] fsck.gfs2: externalize check_leaf rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 35/42] fsck.gfs2 pass2: check leaf blocks when fixing hash table rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 36/42] fsck.gfs2: standardize check_metatree return codes rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 37/42] fsck.gfs2: don't invalidate files with duplicate data block refs rpeterso
2013-04-08 14:41 ` rpeterso [this message]
2013-04-08 14:41 ` [Cluster-devel] [PATCH 39/42] fsck.gfs2: When flagging a duplicate reference, show valid or invalid rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 40/42] fsck.gfs2: major duplicate reference reform rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 41/42] fsck.gfs2: Remove all bad eattr blocks rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 42/42] fsck.gfs2: Remove unused variable 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=1365432074-17615-39-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).