From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Thu, 25 Aug 2011 13:01:10 -0400 (EDT) Subject: [Cluster-devel] [PATCH 51/56] fsck.gfs2: system dinodes take priority over user Message-ID: <206091840.166253.1314291670544.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit >From b836875303346bfbe264279b441e864c043daadd Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Tue, 23 Aug 2011 09:31:40 -0500 Subject: [PATCH 51/56] fsck.gfs2: system dinodes take priority over user dinodes In testing fsck.gfs2 I noticed some incorrect behavior: If a block was referenced incorrectly by two dinodes, fsck deleted which ever reference it found first. Therefore, if a system dinode and a user dinode referenced the same block, fsck.gfs2 could mistakenly delete the system dinode. For example, a journal could get deleted because a user dinode improperly referenced one of its blocks. This patch gives priority to system dinodes when resolving duplicates. rhbz#675723 --- gfs2/fsck/pass1b.c | 9 ++++++++- gfs2/fsck/util.c | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c index 67e878c..a56ea31 100644 --- a/gfs2/fsck/pass1b.c +++ b/gfs2/fsck/pass1b.c @@ -486,7 +486,14 @@ static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b, continue; /* don't delete the dinode */ } } - + /* If this reference is from a system inode, for example, if + it's data or metadata inside a journal, the reference + should take priority over user dinodes that reference the + block. */ + if (!found_good_ref && fsck_system_inode(sdp, id->block_no)) { + found_good_ref = 1; + continue; /* don't delete the dinode */ + } log_warn( _("Inode %s (%lld/0x%llx) references block " "%llu (0x%llx) as '%s', but the block is " "really %s.\n"), diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c index ae9213f..aa3e4ff 100644 --- a/gfs2/fsck/util.c +++ b/gfs2/fsck/util.c @@ -283,8 +283,18 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block, inode reference list otherwise put it on the normal list. */ if (!inode_valid || q == gfs2_inode_invalid) osi_list_add_prev(&id->list, &dt->ref_invinode_list); - else - osi_list_add_prev(&id->list, &dt->ref_inode_list); + else { + /* If this is a system dinode, we want the duplicate + processing to find it first. That way references + from inside journals, et al, will take priority. + We don't want to delete journals in favor of dinodes + that reference a block inside a journal. */ + if (fsck_system_inode(ip->i_sbd, id->block_no)) + osi_list_add(&id->list, &dt->ref_inode_list); + else + osi_list_add_prev(&id->list, + &dt->ref_inode_list); + } } id->reftypecount[reftype]++; id->dup_count++; -- 1.7.4.4