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

Bob Peterson rpeterso at fedoraproject.org
Tue Jan 26 21:11:07 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitdiff;h=966e6ce68492ca770a73171db2f97e246dacb959
Commit:        966e6ce68492ca770a73171db2f97e246dacb959
Parent:        5ae8a4155e3a4d19b2e9f46367d855ca998396fb
Author:        Bob Peterson <bob at ganesha.peterson>
AuthorDate:    Mon Jan 25 14:43:14 2010 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Tue Jan 26 15:09:52 2010 -0600

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 ee6a1fc..bb56487 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -496,6 +496,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);
@@ -504,8 +506,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 "
@@ -626,6 +637,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.
@@ -636,8 +649,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