gfs2-utils: master - fsck.gfs2: Remove all bad eattr blocks
Bob Peterson
rpeterso at fedoraproject.org
Mon May 20 16:18:54 UTC 2013
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=1bae9562287edc528adcb1f39a750a5cb4a5e286
Commit: 1bae9562287edc528adcb1f39a750a5cb4a5e286
Parent: 98544a4b3a1a7251a8230a24e7efdcce306c99bb
Author: Bob Peterson <rpeterso at redhat.com>
AuthorDate: Wed Apr 3 11:52:05 2013 -0700
Committer: Bob Peterson <rpeterso at redhat.com>
CommitterDate: Mon May 20 11:12:47 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.
---
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 b79e999..dc99869 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);
More information about the cluster-commits
mailing list