From: rpeterso@redhat.com <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 08/42] fsck.gfs2: Move basic directory entry checks to separate function
Date: Mon, 8 Apr 2013 07:40:40 -0700 [thread overview]
Message-ID: <1365432074-17615-9-git-send-email-rpeterso@redhat.com> (raw)
In-Reply-To: <1365432074-17615-1-git-send-email-rpeterso@redhat.com>
From: Bob Peterson <rpeterso@redhat.com>
This patch moves a huge chunk of code from bloated function
check_dentry. The moved section of code performs basic directory entry
checks. The code is basically unchanged, but I made clear_eattrs
metawalk functions global.
rhbz#902920
---
gfs2/fsck/pass2.c | 160 ++++++++++++++++++++++++++++++++----------------------
1 file changed, 94 insertions(+), 66 deletions(-)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 3053711..8d66ff4 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -19,6 +19,13 @@
#define MAX_FILENAME 256
+struct metawalk_fxns clear_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,
+};
+
/* Set children's parent inode in dir_info structure - ext2 does not set
* dotdot inode here, but instead in pass3 - should we? */
static int set_parent_dir(struct gfs2_sbd *sdp, struct gfs2_inum child,
@@ -288,51 +295,35 @@ static int bad_formal_ino(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return 0;
}
-/* FIXME: should maybe refactor this a bit - but need to deal with
- * FIXMEs internally first */
-static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
- struct gfs2_dirent *prev_de,
- struct gfs2_buffer_head *bh, char *filename,
- uint32_t *count, void *priv)
+/* basic_dentry_checks - fundamental checks for directory entries
+ *
+ * @ip: pointer to the incode inode structure
+ * @entry: pointer to the inum info
+ * @tmp_name: user-friendly file name
+ * @count: pointer to the entry count
+ * @de: pointer to the directory entry
+ *
+ * Returns: 1 means corruption, nuke the dentry, 0 means checks pass
+ */
+static int basic_dentry_checks(struct gfs2_inode *ip, struct gfs2_dirent *dent,
+ struct gfs2_inum *entry, const char *tmp_name,
+ uint32_t *count, struct gfs2_dirent *de,
+ struct dir_status *ds, uint8_t *q,
+ struct gfs2_buffer_head *bh)
{
struct gfs2_sbd *sdp = ip->i_sbd;
- uint8_t q = 0;
- char tmp_name[MAX_FILENAME];
- struct gfs2_inum entry;
- struct dir_status *ds = (struct dir_status *) priv;
- int error;
- struct gfs2_inode *entry_ip = NULL;
- struct metawalk_fxns clear_eattrs = {0};
- struct gfs2_dirent dentry, *de;
uint32_t calculated_hash;
+ struct gfs2_inode *entry_ip = NULL;
+ int error;
- memset(&dentry, 0, sizeof(struct gfs2_dirent));
- gfs2_dirent_in(&dentry, (char *)dent);
- de = &dentry;
-
- clear_eattrs.check_eattr_indir = delete_eattr_indir;
- clear_eattrs.check_eattr_leaf = delete_eattr_leaf;
- clear_eattrs.check_eattr_entry = clear_eattr_entry;
- clear_eattrs.check_eattr_extentry = clear_eattr_extentry;
-
- entry.no_addr = de->de_inum.no_addr;
- entry.no_formal_ino = de->de_inum.no_formal_ino;
-
- /* Start of checks */
- memset(tmp_name, 0, MAX_FILENAME);
- if (de->de_name_len < MAX_FILENAME)
- strncpy(tmp_name, filename, de->de_name_len);
- else
- strncpy(tmp_name, filename, MAX_FILENAME - 1);
-
- if (!valid_block(ip->i_sbd, entry.no_addr)) {
+ if (!valid_block(ip->i_sbd, entry->no_addr)) {
log_err( _("Block # referenced by directory entry %s in inode "
"%lld (0x%llx) is invalid\n"),
tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
if (query( _("Clear directory entry to out of range block? "
"(y/n) "))) {
- goto nuke_dentry;
+ return 1;
} else {
log_err( _("Directory entry to out of range block remains\n"));
(*count)++;
@@ -349,7 +340,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
de->de_rec_len, de->de_name_len);
if (!query( _("Clear the directory entry? (y/n) "))) {
log_err( _("Directory entry not fixed.\n"));
- goto dentry_is_valid;
+ return 0;
}
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
_("corrupt directory entry"),
@@ -371,7 +362,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
tmp_name)) {
log_err( _("Directory entry hash for %s not "
"fixed.\n"), tmp_name);
- goto dentry_is_valid;
+ return 0;
}
de->de_hash = calculated_hash;
gfs2_dirent_out(de, (char *)dent);
@@ -380,7 +371,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
tmp_name);
}
- q = block_type(entry.no_addr);
+ *q = block_type(entry->no_addr);
/* Get the status of the directory inode */
/**
* 1. Blocks marked "invalid" were invalidated due to duplicate
@@ -394,25 +385,25 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
* 2. Blocks marked "bad" need to have their entire
* metadata tree deleted.
*/
- if (q == gfs2_inode_invalid || q == gfs2_bad_block) {
+ if (*q == gfs2_inode_invalid || *q == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
/* Handle bad blocks */
log_err( _("Found directory entry '%s' pointing to invalid "
"block %lld (0x%llx)\n"), tmp_name,
- (unsigned long long)entry.no_addr,
- (unsigned long long)entry.no_addr);
+ (unsigned long long)entry->no_addr,
+ (unsigned long long)entry->no_addr);
if (!query( _("Delete inode containing bad blocks? (y/n)"))) {
log_warn( _("Entry to inode containing bad blocks remains\n"));
- goto dentry_is_valid;
+ return 0;
}
- if (q == gfs2_bad_block) {
- if (ip->i_di.di_num.no_addr == entry.no_addr)
+ if (*q == gfs2_bad_block) {
+ if (ip->i_di.di_num.no_addr == entry->no_addr)
entry_ip = ip;
else
- entry_ip = fsck_load_inode(sdp, entry.no_addr);
+ entry_ip = fsck_load_inode(sdp, entry->no_addr);
if (ip->i_di.di_eattr) {
check_inode_eattr(entry_ip,
&pass2_fxns_delete);
@@ -421,29 +412,29 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if (entry_ip != ip)
fsck_inode_put(&entry_ip);
}
- fsck_blockmap_set(ip, entry.no_addr,
+ fsck_blockmap_set(ip, entry->no_addr,
_("bad directory entry"), gfs2_block_free);
log_err( _("Inode %lld (0x%llx) was deleted.\n"),
- (unsigned long long)entry.no_addr,
- (unsigned long long)entry.no_addr);
- goto nuke_dentry;
+ (unsigned long long)entry->no_addr,
+ (unsigned long long)entry->no_addr);
+ return 1;
}
- if (q < gfs2_inode_dir || q > gfs2_inode_sock) {
+ if (*q < gfs2_inode_dir || *q > gfs2_inode_sock) {
log_err( _("Directory entry '%s' referencing inode %llu "
"(0x%llx) in dir inode %llu (0x%llx) block type "
"%d: %s.\n"), tmp_name,
- (unsigned long long)entry.no_addr,
- (unsigned long long)entry.no_addr,
+ (unsigned long long)entry->no_addr,
+ (unsigned long long)entry->no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
- q, q == gfs2_inode_invalid ?
+ *q, *q == gfs2_inode_invalid ?
_("was previously marked invalid") :
_("was deleted or is not an inode"));
if (!query( _("Clear directory entry to non-inode block? "
"(y/n) "))) {
log_err( _("Directory entry to non-inode block remains\n"));
- goto dentry_is_valid;
+ return 0;
}
/* Don't decrement the link here: Here in pass2, we increment
@@ -462,20 +453,20 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
count on "delete_block_if_notdup" knowing whether it's
really a duplicate block if we never traversed the metadata
tree for the invalid inode. */
- goto nuke_dentry;
+ return 1;
}
- error = check_file_type(de->de_type, q, sdp->gfs1);
+ error = check_file_type(de->de_type, *q, sdp->gfs1);
if (error < 0) {
log_err( _("Error: directory entry type is "
"incompatible with block type@block %lld "
"(0x%llx) in directory inode %llu (0x%llx).\n"),
- (unsigned long long)entry.no_addr,
- (unsigned long long)entry.no_addr,
+ (unsigned long long)entry->no_addr,
+ (unsigned long long)entry->no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
log_err( _("Directory entry type is %d, block type is %d.\n"),
- de->de_type, q);
+ de->de_type, *q);
stack;
return -1;
}
@@ -483,22 +474,59 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("Type '%s' in dir entry (%s, %llu/0x%llx) conflicts"
" with type '%s' in dinode. (Dir entry is stale.)\n"),
de_type_string(de->de_type), tmp_name,
- (unsigned long long)entry.no_addr,
- (unsigned long long)entry.no_addr,
- block_type_string(q));
+ (unsigned long long)entry->no_addr,
+ (unsigned long long)entry->no_addr,
+ block_type_string(*q));
if (!query( _("Clear stale directory entry? (y/n) "))) {
log_err( _("Stale directory entry remains\n"));
- goto dentry_is_valid;
+ return 0;
}
- if (ip->i_di.di_num.no_addr == entry.no_addr)
+ if (ip->i_di.di_num.no_addr == entry->no_addr)
entry_ip = ip;
else
- entry_ip = fsck_load_inode(sdp, entry.no_addr);
+ entry_ip = fsck_load_inode(sdp, entry->no_addr);
check_inode_eattr(entry_ip, &clear_eattrs);
if (entry_ip != ip)
fsck_inode_put(&entry_ip);
- goto nuke_dentry;
+ return 1;
}
+ return 0;
+}
+
+/* FIXME: should maybe refactor this a bit - but need to deal with
+ * FIXMEs internally first */
+static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
+ struct gfs2_dirent *prev_de,
+ struct gfs2_buffer_head *bh, char *filename,
+ uint32_t *count, void *priv)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+ uint8_t q = 0;
+ char tmp_name[MAX_FILENAME];
+ struct gfs2_inum entry;
+ struct dir_status *ds = (struct dir_status *) priv;
+ int error;
+ struct gfs2_inode *entry_ip = NULL;
+ struct gfs2_dirent dentry, *de;
+
+ memset(&dentry, 0, sizeof(struct gfs2_dirent));
+ gfs2_dirent_in(&dentry, (char *)dent);
+ de = &dentry;
+
+ entry.no_addr = de->de_inum.no_addr;
+ entry.no_formal_ino = de->de_inum.no_formal_ino;
+
+ /* Start of checks */
+ memset(tmp_name, 0, MAX_FILENAME);
+ if (de->de_name_len < MAX_FILENAME)
+ strncpy(tmp_name, filename, de->de_name_len);
+ else
+ strncpy(tmp_name, filename, MAX_FILENAME - 1);
+
+ error = basic_dentry_checks(ip, dent, &entry, tmp_name, count, de,
+ ds, &q, bh);
+ if (error)
+ goto nuke_dentry;
if (!strcmp(".", tmp_name)) {
log_debug( _("Found . dentry in directory %lld (0x%llx)\n"),
--
1.7.11.7
next prev parent reply other threads:[~2013-04-08 14:40 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-08 14:40 [Cluster-devel] [PATCH 00/42] fsck.gfs2 fixes and improvements rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 01/42] libgfs2: externalize dir_split_leaf rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 02/42] libgfs2: allow dir_split_leaf to receive a leaf buffer rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 03/42] libgfs2: let dir_split_leaf receive a "broken" lindex rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 04/42] fsck.gfs2: Move function find_free_blk to util.c rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 05/42] fsck.gfs2: Split out function to make sure lost+found exists rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 06/42] fsck.gfs2: Check for formal inode mismatch when adding to lost+found rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 07/42] fsck.gfs2: shorten some debug messages in lost+found rpeterso
2013-04-08 14:40 ` rpeterso [this message]
2013-04-08 14:40 ` [Cluster-devel] [PATCH 09/42] fsck.gfs2: Add formal inode check to basic dirent checks rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 10/42] fsck.gfs2: Add new function to check dir hash tables rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 11/42] fsck.gfs2: Special case '..' when processing bad formal inode number rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 12/42] fsck.gfs2: Move function to read directory hash table to util.c rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 13/42] fsck.gfs2: Misc cleanups rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 14/42] fsck.gfs2: Verify dirent hash values correspond to proper leaf block rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 15/42] fsck.gfs2: re-read hash table if directory height or depth changes rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 16/42] fsck.gfs2: fix leaf blocks, don't try to patch the hash table rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 17/42] fsck.gfs2: check leaf depth when validating leaf blocks rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 18/42] fsck.gfs2: small cleanups rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 19/42] fsck.gfs2: reprocess inodes when blocks are added rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 20/42] fsck.gfs2: Remove redundant leaf depth check rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 21/42] fsck.gfs2: link dinodes that only have extended attribute problems rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 22/42] fsck.gfs2: Add clarifying message to duplicate processing rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 23/42] fsck.gfs2: separate function to calculate metadata block header size rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 24/42] fsck.gfs2: Rework the "undo" functions rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 25/42] fsck.gfs2: Check for interrupt when resolving duplicates rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 26/42] fsck.gfs2: Consistent naming of struct duptree variables rpeterso
2013-04-08 14:40 ` [Cluster-devel] [PATCH 27/42] fsck.gfs2: Keep proper counts when duplicates are found rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 28/42] fsck.gfs2: print metadata block reference on data errors rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 29/42] fsck.gfs2: print block count values when fixing them rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 30/42] fsck.gfs2: Do not invalidate metablocks of dinodes with invalid mode rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 31/42] fsck.gfs2: Log when unrecoverable data block errors are encountered rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 32/42] fsck.gfs2: don't remove buffers from the list when errors are found rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 33/42] fsck.gfs2: Don't flag GFS1 non-dinode blocks as duplicates rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 34/42] fsck.gfs2: externalize check_leaf rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 35/42] fsck.gfs2 pass2: check leaf blocks when fixing hash table rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 36/42] fsck.gfs2: standardize check_metatree return codes rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 37/42] fsck.gfs2: don't invalidate files with duplicate data block refs rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 38/42] fsck.gfs2: check for duplicate first references rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 39/42] fsck.gfs2: When flagging a duplicate reference, show valid or invalid rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 40/42] fsck.gfs2: major duplicate reference reform rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 41/42] fsck.gfs2: Remove all bad eattr blocks rpeterso
2013-04-08 14:41 ` [Cluster-devel] [PATCH 42/42] fsck.gfs2: Remove unused variable rpeterso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1365432074-17615-9-git-send-email-rpeterso@redhat.com \
--to=rpeterso@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).