cluster: RHEL56 - fsck.gfs2: Don't add extended attrib blocks to list twice

Bob Peterson rpeterso at fedoraproject.org
Sat Apr 10 04:54:06 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=800465eaed0ecdee931feb52f9e30467f624c00e
Commit:        800465eaed0ecdee931feb52f9e30467f624c00e
Parent:        0827d8708cef94e2f063a8fd9071f468f7eeec54
Author:        Bob Peterson <bob at ganesha.peterson>
AuthorDate:    Mon Jan 25 14:43:14 2010 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri Apr 9 23:43:47 2010 -0500

fsck.gfs2: Don't add extended attrib blocks to list twice

This patch adds a simple check to pass1 where it is adding a
block to the list of blocks that contain an extended attribute.
If the block is already on the list, no need to add it again.
This can sometimes happen in duplicate reference situations and
other obscure code paths.

Since pass1 processes the file system sequentially by block number
it's enough to check against the block most recently added to the
list.  This is a performance increase; early versions of this
code ran the entire linked list of special blocks.  If the file
system was labelled for selinux, it could have millions of entries
on the linked list, causing an enormous slowdown.

rhbz#455300
---
 gfs2/fsck/pass1.c |   26 ++++++++++++++++++++++----
 1 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 3ae0cc6..f7c81ff 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -509,6 +509,8 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
 			      int leaf_pointer_errors, void *private)
 {
 	struct block_count *bc = (struct block_count *) private;
+	osi_list_t *head;
+	struct special_blocks *b = NULL;
 
 	if (leaf_pointer_errors == leaf_pointers) /* All eas were bad */
 		return ask_remove_inode_eattr(ip, bc);
@@ -517,8 +519,17 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
 		   (unsigned long long)ip->i_di.di_num.no_addr,
 		   (unsigned long long)ip->i_di.di_num.no_addr);
 	/* Mark the inode as having an eattr in the block map
-	   so pass1c can check it. */
-	gfs2_special_add(&ip->i_sbd->eattr_blocks, ip->i_di.di_num.no_addr);
+	   so pass1c can check it. We may have previously added this inode
+	   to the eattr_blocks list and if we did, it would be the first
+	   one on the list.  So check that one only (to save time) and
+	   if that one matches, no need to add it again. */
+	if (!osi_list_empty(&ip->i_sbd->eattr_blocks.list)) {
+		head = &ip->i_sbd->eattr_blocks.list;
+		b = osi_list_entry(head->next, struct special_blocks, list);
+	}
+	if (!b || b->block != ip->i_di.di_num.no_addr)
+		gfs2_special_add(&ip->i_sbd->eattr_blocks,
+				 ip->i_di.di_num.no_addr);
 	if (!leaf_pointer_errors)
 		return 0;
 	log_err( _("Inode %lld (0x%llx) has recoverable indirect "
@@ -639,6 +650,8 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 			    void *private)
 {
 	struct gfs2_sbd *sdp = ip->i_sbd;
+	osi_list_t *head;
+	struct special_blocks *b = NULL;
 
 	/* This inode contains an eattr - it may be invalid, but the
 	 * eattr attributes points to a non-zero block.
@@ -649,8 +662,13 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 		     "block(s) attached.\n"),
 		   (unsigned long long)ip->i_di.di_num.no_addr,
 		   (unsigned long long)ip->i_di.di_num.no_addr);
-	gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
-	if(gfs2_check_range(sdp, block)) {
+	if (!osi_list_empty(&ip->i_sbd->eattr_blocks.list)) {
+		head = &ip->i_sbd->eattr_blocks.list;
+		b = osi_list_entry(head->next, struct special_blocks, list);
+	}
+	if (!b || b->block != ip->i_di.di_num.no_addr)
+		gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
+	if (gfs2_check_range(sdp, block)) {
 		log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf "
 			    "block #%llu (0x%llx) is out of range.\n"),
 			 (unsigned long long)ip->i_di.di_num.no_addr,


More information about the cluster-commits mailing list