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