cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
From: Bob Peterson <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [gfs2-utils PATCH 08/47] fsck.gfs2: Move basic directory entry checks to separate function
Date: Tue, 14 May 2013 11:21:31 -0500	[thread overview]
Message-ID: <5810615e29e00e927bec962bcc34c1d6d88a6a0e.1368548305.git.rpeterso@redhat.com> (raw)
In-Reply-To: <fb9b8713081b2a9c0238374a0e1926b174717bfd.1368548305.git.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



  parent reply	other threads:[~2013-05-14 16:21 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-14 16:21 [Cluster-devel] [gfs2-utils PATCH 01/47] libgfs2: externalize dir_split_leaf Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 02/47] libgfs2: allow dir_split_leaf to receive a leaf buffer Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 03/47] libgfs2: let dir_split_leaf receive a "broken" lindex Bob Peterson
2013-05-15 16:01   ` Steven Whitehouse
2013-05-20 16:02     ` Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 04/47] fsck.gfs2: Move function find_free_blk to util.c Bob Peterson
2013-05-15 16:04   ` Steven Whitehouse
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 05/47] fsck.gfs2: Split out function to make sure lost+found exists Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 06/47] fsck.gfs2: Check for formal inode mismatch when adding to lost+found Bob Peterson
2013-05-15 16:08   ` Steven Whitehouse
2013-05-17 12:47     ` Bob Peterson
2013-05-17 12:55       ` Steven Whitehouse
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 07/47] fsck.gfs2: shorten some debug messages in lost+found Bob Peterson
2013-05-14 16:21 ` Bob Peterson [this message]
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 09/47] fsck.gfs2: Add formal inode check to basic dirent checks Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 10/47] fsck.gfs2: Add new function to check dir hash tables Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 11/47] fsck.gfs2: Special case '..' when processing bad formal inode number Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 12/47] fsck.gfs2: Move function to read directory hash table to util.c Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 13/47] fsck.gfs2: Misc cleanups Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 14/47] fsck.gfs2: Verify dirent hash values correspond to proper leaf block Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 15/47] fsck.gfs2: re-read hash table if directory height or depth changes Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 16/47] fsck.gfs2: fix leaf blocks, don't try to patch the hash table Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 17/47] fsck.gfs2: check leaf depth when validating leaf blocks Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 18/47] fsck.gfs2: small cleanups Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 19/47] fsck.gfs2: reprocess inodes when blocks are added Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 20/47] fsck.gfs2: Remove redundant leaf depth check Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 21/47] fsck.gfs2: link dinodes that only have extended attribute problems Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 22/47] fsck.gfs2: Add clarifying message to duplicate processing Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 23/47] fsck.gfs2: separate function to calculate metadata block header size Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 24/47] fsck.gfs2: Rework the "undo" functions Bob Peterson
2013-05-16 13:27   ` Steven Whitehouse
2013-05-16 13:49     ` Bob Peterson
2013-05-16 14:02       ` Steven Whitehouse
2013-05-16 15:02         ` Bob Peterson
2013-05-16 15:24           ` Steven Whitehouse
2013-05-20 13:08             ` Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 25/47] fsck.gfs2: Check for interrupt when resolving duplicates Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 26/47] fsck.gfs2: Consistent naming of struct duptree variables Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 27/47] fsck.gfs2: Keep proper counts when duplicates are found Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 28/47] fsck.gfs2: print metadata block reference on data errors Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 29/47] fsck.gfs2: print block count values when fixing them Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 30/47] fsck.gfs2: Do not invalidate metablocks of dinodes with invalid mode Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 31/47] fsck.gfs2: Log when unrecoverable data block errors are encountered Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 32/47] fsck.gfs2: don't remove buffers from the list when errors are found Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 33/47] fsck.gfs2: Don't flag GFS1 non-dinode blocks as duplicates Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 34/47] fsck.gfs2: externalize check_leaf Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 35/47] fsck.gfs2: pass2: check leaf blocks when fixing hash table Bob Peterson
2013-05-14 16:21 ` [Cluster-devel] [gfs2-utils PATCH 36/47] fsck.gfs2: standardize check_metatree return codes Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 37/47] fsck.gfs2: don't invalidate files with duplicate data block refs Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 38/47] fsck.gfs2: check for duplicate first references Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 39/47] fsck.gfs2: When flagging a duplicate reference, show valid or invalid Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 40/47] fsck.gfs2: major duplicate reference reform Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 41/47] fsck.gfs2: Remove all bad eattr blocks Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 42/47] fsck.gfs2: Remove unused variable Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 43/47] fsck.gfs2: double-check transitions from dinode to data Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 44/47] fsck.gfs2: Stop "undo" process when error data block is reached Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 45/47] fsck.gfs2: Don't allocate leaf blocks in pass1 Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 46/47] fsck.gfs2: take hash table start boundaries into account Bob Peterson
2013-05-14 16:22 ` [Cluster-devel] [gfs2-utils PATCH 47/47] fsck.gfs2: delete all duplicates from unrecoverable damaged dinodes Bob Peterson

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=5810615e29e00e927bec962bcc34c1d6d88a6a0e.1368548305.git.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).