cluster: RHEL6 - fsck.gfs2: Remove all bad eattr blocks

Bob Peterson rpeterso at fedoraproject.org
Tue May 21 12:24:13 UTC 2013


Gitweb:        http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=d2c1adbcd728fc611b59292e1ac7aca6699af5a2
Commit:        d2c1adbcd728fc611b59292e1ac7aca6699af5a2
Parent:        73cd9def968ad89bc28e02a8c8f8d630e1114c5b
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Wed Apr 3 11:52:05 2013 -0700
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri May 17 15:30:46 2013 -0500

fsck.gfs2: Remove all bad eattr blocks

Before this patch, bad extended attributes were not properly removed
from a dinode, and blocks were not freed. This patch properly
removes them all.

rhbz#902920
---
 gfs2/fsck/pass1.c  |   12 ++++++++----
 gfs2/fsck/pass1c.c |    8 +++++++-
 gfs2/fsck/pass2.c  |   18 ++++++++++--------
 3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 85ad49a..90e3829 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -486,6 +486,8 @@ static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc)
 static int ask_remove_inode_eattr(struct gfs2_inode *ip,
 				  struct block_count *bc)
 {
+	if (ip->i_di.di_eattr == 0)
+		return 0; /* eattr was removed prior to this call */
 	log_err( _("Inode %lld (0x%llx) has unrecoverable Extended Attribute "
 		   "errors.\n"), (unsigned long long)ip->i_di.di_num.no_addr,
 		 (unsigned long long)ip->i_di.di_num.no_addr);
@@ -1073,11 +1075,13 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 	if (fsck_abort)
 		return 0;
 
-	error = check_inode_eattr(ip, &pass1_fxns);
+	if (!error) {
+		error = check_inode_eattr(ip, &pass1_fxns);
 
-	if (error &&
-	    !(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT))
-		ask_remove_inode_eattr(ip, &bc);
+		if (error &&
+		    !(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT))
+			ask_remove_inode_eattr(ip, &bc);
+	}
 
 	if (ip->i_di.di_blocks != 
 		(1 + bc.indir_count + bc.data_count + bc.ea_count)) {
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index f9bfa6a..16e3db3 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -10,6 +10,12 @@
 #include "util.h"
 #include "metawalk.h"
 
+struct metawalk_fxns pass1c_fxns_delete = {
+	.private = NULL,
+	.check_eattr_indir = delete_eattr_indir,
+	.check_eattr_leaf = delete_eattr_leaf,
+};
+
 static int remove_eattr_entry(struct gfs2_sbd *sdp,
 			      struct gfs2_buffer_head *leaf_bh,
 			      struct gfs2_ea_header *curr,
@@ -60,7 +66,7 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
 static int ask_remove_eattr(struct gfs2_inode *ip)
 {
 	if (query( _("Remove the bad Extended Attribute? (y/n) "))) {
-		ip->i_di.di_eattr = 0;
+		check_inode_eattr(ip, &pass1c_fxns_delete);
 		bmodified(ip->i_bh);
 		log_err( _("Bad Extended Attribute removed.\n"));
 		return 1;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 11ceab9..99481c9 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -18,11 +18,13 @@
 
 #define MAX_FILENAME 256
 
-struct metawalk_fxns clear_eattrs = {
+struct metawalk_fxns pass2_fxns;
+
+struct metawalk_fxns delete_eattrs = {
 	.check_eattr_indir = delete_eattr_indir,
 	.check_eattr_leaf = delete_eattr_leaf,
-	.check_eattr_entry = clear_eattr_entry,
-	.check_eattr_extentry = clear_eattr_extentry,
+	.check_eattr_entry = delete_eattr_entry,
+	.check_eattr_extentry = delete_eattr_extentry,
 };
 
 /* Set children's parent inode in dir_info structure - ext2 does not set
@@ -597,7 +599,7 @@ static int basic_dentry_checks(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			entry_ip = ip;
 		else
 			entry_ip = fsck_load_inode(sdp, entry->no_addr);
-		check_inode_eattr(entry_ip, &clear_eattrs);
+		check_inode_eattr(entry_ip, &delete_eattrs);
 		if (entry_ip != ip)
 			fsck_inode_put(&entry_ip);
 		return 1;
@@ -681,7 +683,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				entry_ip = ip;
 			else
 				entry_ip = fsck_load_inode(sdp, entry.no_addr);
-			check_inode_eattr(entry_ip, &clear_eattrs);
+			check_inode_eattr(entry_ip, &delete_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
 			goto nuke_dentry;
@@ -712,7 +714,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				entry_ip = ip;
 			else
 				entry_ip = fsck_load_inode(sdp, entry.no_addr);
-			check_inode_eattr(entry_ip, &clear_eattrs);
+			check_inode_eattr(entry_ip, &delete_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
 			goto nuke_dentry;
@@ -742,7 +744,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				entry_ip = ip;
 			else
 				entry_ip = fsck_load_inode(sdp, entry.no_addr);
-			check_inode_eattr(entry_ip, &clear_eattrs);
+			check_inode_eattr(entry_ip, &delete_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
 
@@ -762,7 +764,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				entry_ip = ip;
 			else
 				entry_ip = fsck_load_inode(sdp, entry.no_addr);
-			check_inode_eattr(entry_ip, &clear_eattrs);
+			check_inode_eattr(entry_ip, &delete_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
 


More information about the cluster-commits mailing list