[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [gfs2-utils PATCH 41/47] 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#872564
---
 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 ee7e2c5..ad6690b 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -487,6 +487,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);
@@ -1074,11 +1076,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 26d47d5..b918de1 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -12,6 +12,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,
@@ -62,7 +68,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 8b38b43..5c27a35 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -20,11 +20,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
@@ -599,7 +601,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;
@@ -683,7 +685,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;
@@ -714,7 +716,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;
@@ -744,7 +746,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);
 
@@ -764,7 +766,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);
 
-- 
1.7.11.7


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]