[Cluster-devel] [fsck.gfs2 v2 PATCH 12/40] fsck.gfs2: Separate out functions that may only be done after pass1

Bob Peterson rpeterso at redhat.com
Fri May 6 17:39:05 UTC 2016


This patch adds a new header file and source file which has the
purpose of separating out the functions that may only be called
after pass1 from the functions that pass1 may call. This is to
ensure that there will never be inconsistencies between blockmap
(which pass1 uses) and bitmap (which subsequent passes use).

Signed-off-by: Bob Peterson <rpeterso at redhat.com>
---
 gfs2/fsck/Makefile.am         |   1 +
 gfs2/fsck/afterpass1_common.c | 272 ++++++++++++++++++++++++++++++++++++++++++
 gfs2/fsck/afterpass1_common.h |  31 +++++
 gfs2/fsck/metawalk.c          | 272 +-----------------------------------------
 gfs2/fsck/metawalk.h          |  32 +----
 gfs2/fsck/pass1.c             |  22 ++++
 gfs2/fsck/pass1b.c            |   1 +
 gfs2/fsck/pass2.c             |   1 +
 gfs2/fsck/pass3.c             |   1 +
 gfs2/fsck/pass4.c             |   1 +
 10 files changed, 335 insertions(+), 299 deletions(-)
 create mode 100644 gfs2/fsck/afterpass1_common.c
 create mode 100644 gfs2/fsck/afterpass1_common.h

diff --git a/gfs2/fsck/Makefile.am b/gfs2/fsck/Makefile.am
index 73d957e..ecd05d8 100644
--- a/gfs2/fsck/Makefile.am
+++ b/gfs2/fsck/Makefile.am
@@ -19,6 +19,7 @@ fsck_gfs2_SOURCES = \
 	lost_n_found.c \
 	main.c \
 	metawalk.c \
+	afterpass1_common.c \
 	pass1b.c \
 	pass1.c \
 	pass2.c \
diff --git a/gfs2/fsck/afterpass1_common.c b/gfs2/fsck/afterpass1_common.c
new file mode 100644
index 0000000..36646f8
--- /dev/null
+++ b/gfs2/fsck/afterpass1_common.c
@@ -0,0 +1,272 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <ctype.h>
+#include <fcntl.h>
+#define _(String) gettext(String)
+
+#include <logging.h>
+#include "libgfs2.h"
+#include "fsck.h"
+#include "afterpass1_common.h"
+#include "metawalk.h"
+#include "util.h"
+
+/**
+ * find_remove_dup - find out if this is a duplicate ref.  If so, remove it.
+ *
+ * Returns: 1 if there are any remaining references to this block, else 0.
+ */
+int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
+{
+	struct duptree *dt;
+	struct inode_with_dups *id;
+
+	dt = dupfind(block);
+	if (!dt)
+		return 0;
+
+	/* remove the inode reference id structure for this reference. */
+	id = find_dup_ref_inode(dt, ip);
+	if (!id)
+		goto more_refs;
+
+	dup_listent_delete(dt, id);
+	if (dt->refs == 0) {
+		log_info( _("This was the last reference: it's no longer a "
+			    "duplicate.\n"));
+		dup_delete(dt); /* not duplicate now */
+		return 0;
+	}
+more_refs:
+	log_info( _("%d block reference(s) remain.\n"), dt->refs);
+	return 1; /* references still exist so do not free the block. */
+}
+
+/**
+ * delete_block_if_notdup - delete blocks associated with an inode
+ *
+ * Ignore blocks that are already marked free.
+ * If it has been identified as duplicate, remove the duplicate reference.
+ * If all duplicate references have been removed, delete the block.
+ */
+static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+				  struct gfs2_buffer_head **bh,
+				  const char *btype, int *was_duplicate,
+				  void *private)
+{
+	int q;
+
+	if (!valid_block(ip->i_sbd, block))
+		return meta_error;
+
+	q = bitmap_type(ip->i_sbd, block);
+	if (q == GFS2_BLKST_FREE) {
+		log_info( _("%s block %lld (0x%llx), part of inode "
+			    "%lld (0x%llx), was already free.\n"),
+			  btype, (unsigned long long)block,
+			  (unsigned long long)block,
+			  (unsigned long long)ip->i_di.di_num.no_addr,
+			  (unsigned long long)ip->i_di.di_num.no_addr);
+		return meta_is_good;
+	}
+	if (find_remove_dup(ip, block, btype)) { /* a dup */
+		if (was_duplicate)
+			*was_duplicate = 1;
+		log_err( _("Not clearing duplicate reference in inode "
+			   "at block #%llu (0x%llx) to block #%llu (0x%llx) "
+			   "because it's referenced by another inode.\n"),
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)block, (unsigned long long)block);
+	} else {
+		check_n_fix_bitmap(ip->i_sbd, block, 0, GFS2_BLKST_FREE);
+	}
+	return meta_is_good;
+}
+
+static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
+			 struct gfs2_dirent *prev_de,
+			 struct gfs2_buffer_head *bh,
+			 char *filename, uint32_t *count, int *lindex,
+			 void *private)
+{
+	/* the metawalk_fxn's private field must be set to the dentry
+	 * block we want to clear */
+	uint64_t *dentryblock = (uint64_t *) private;
+	struct gfs2_dirent dentry, *de;
+
+	memset(&dentry, 0, sizeof(struct gfs2_dirent));
+	gfs2_dirent_in(&dentry, (char *)dent);
+	de = &dentry;
+
+	if (de->de_inum.no_addr == *dentryblock)
+		dirent2_del(ip, bh, prev_de, dent);
+	else
+		(*count)++;
+
+	return 0;
+
+}
+
+int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
+			   uint64_t dentryblock)
+{
+	struct metawalk_fxns remove_dentry_fxns = {0};
+	struct gfs2_inode *ip;
+	int q;
+	int error;
+
+	log_debug( _("Removing dentry %llu (0x%llx) from directory %llu"
+		     " (0x%llx)\n"), (unsigned long long)dentryblock,
+		  (unsigned long long)dentryblock,
+		  (unsigned long long)dir, (unsigned long long)dir);
+	if (!valid_block(sdp, dir)) {
+		log_err( _("Parent directory is invalid\n"));
+		return 1;
+	}
+	remove_dentry_fxns.private = &dentryblock;
+	remove_dentry_fxns.check_dentry = remove_dentry;
+
+	q = bitmap_type(sdp, dir);
+	if (q != GFS2_BLKST_DINODE) {
+		log_info( _("Parent block is not an inode...ignoring\n"));
+		return 1;
+	}
+
+	ip = fsck_load_inode(sdp, dir);
+	if (ip == NULL) {
+		stack;
+		return -1;
+	}
+	/* Need to run check_dir with a private var of dentryblock,
+	 * and fxns that remove that dentry if found */
+	error = check_dir(sdp, ip, &remove_dentry_fxns);
+	fsck_inode_put(&ip);
+	return error;
+}
+
+int delete_metadata(struct gfs2_inode *ip, uint64_t block,
+		    struct gfs2_buffer_head **bh, int h, int *is_valid,
+		    int *was_duplicate, void *private)
+{
+	*is_valid = 1;
+	*was_duplicate = 0;
+	return delete_block_if_notdup(ip, block, bh, _("metadata"),
+				      was_duplicate, private);
+}
+
+int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
+{
+	return delete_block_if_notdup(ip, block, NULL, _("leaf"), NULL,
+				      private);
+}
+
+int delete_data(struct gfs2_inode *ip, uint64_t metablock,
+		uint64_t block, void *private, struct gfs2_buffer_head *bh,
+		uint64_t *ptr)
+{
+	return delete_block_if_notdup(ip, block, NULL, _("data"), NULL,
+				      private);
+}
+
+static int del_eattr_generic(struct gfs2_inode *ip, uint64_t block,
+			     uint64_t parent, struct gfs2_buffer_head **bh,
+			     void *private, const char *eatype)
+{
+	int ret = 0;
+	int was_free = 0;
+	int q;
+
+	if (valid_block(ip->i_sbd, block)) {
+		q = bitmap_type(ip->i_sbd, block);
+		if (q == GFS2_BLKST_FREE)
+			was_free = 1;
+		ret = delete_block_if_notdup(ip, block, NULL, eatype,
+					     NULL, private);
+		if (!ret) {
+			*bh = bread(ip->i_sbd, block);
+			if (!was_free)
+				ip->i_di.di_blocks--;
+			bmodified(ip->i_bh);
+		}
+	}
+	/* Even if it's a duplicate reference, we want to eliminate the
+	   reference itself, and adjust di_blocks accordingly. */
+	if (ip->i_di.di_eattr) {
+		if (block == ip->i_di.di_eattr)
+			ip->i_di.di_eattr = 0;
+		bmodified(ip->i_bh);
+	}
+	return ret;
+}
+
+int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+		       struct gfs2_buffer_head **bh, void *private)
+{
+	return del_eattr_generic(ip, block, parent, bh, private,
+				 _("extended attribute"));
+}
+
+int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+		      struct gfs2_buffer_head **bh, void *private)
+{
+	return del_eattr_generic(ip, block, parent, bh, private,
+				 _("indirect extended attribute"));
+}
+
+int delete_eattr_entry(struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh,
+		       struct gfs2_ea_header *ea_hdr,
+		       struct gfs2_ea_header *ea_hdr_prev, void *private)
+{
+	struct gfs2_sbd *sdp = ip->i_sbd;
+	char ea_name[256];
+	uint32_t avail_size;
+	int max_ptrs;
+
+	if (!ea_hdr->ea_name_len){
+		/* Skip this entry for now */
+		return 1;
+	}
+
+	memset(ea_name, 0, sizeof(ea_name));
+	strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
+		ea_hdr->ea_name_len);
+
+	if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
+	   ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
+		/* Skip invalid entry */
+		return 1;
+	}
+
+	if (!ea_hdr->ea_num_ptrs)
+		return 0;
+
+	avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
+	max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) /
+		avail_size;
+
+	if (max_ptrs > ea_hdr->ea_num_ptrs)
+		return 1;
+
+	log_debug( _("  Pointers Required: %d\n  Pointers Reported: %d\n"),
+		   max_ptrs, ea_hdr->ea_num_ptrs);
+
+	return 0;
+}
+
+int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
+			  struct gfs2_buffer_head *leaf_bh,
+			  struct gfs2_ea_header *ea_hdr,
+			  struct gfs2_ea_header *ea_hdr_prev, void *private)
+{
+	uint64_t block = be64_to_cpu(*ea_data_ptr);
+
+	return delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
+				      NULL, private);
+}
diff --git a/gfs2/fsck/afterpass1_common.h b/gfs2/fsck/afterpass1_common.h
new file mode 100644
index 0000000..2a422c7
--- /dev/null
+++ b/gfs2/fsck/afterpass1_common.h
@@ -0,0 +1,31 @@
+#ifndef _AFTERPASS1_H
+#define _AFTERPASS1_H
+
+#include "util.h"
+
+extern int delete_metadata(struct gfs2_inode *ip, uint64_t block,
+			   struct gfs2_buffer_head **bh, int h, int *is_valid,
+			   int *was_duplicate, void *private);
+extern int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
+extern int delete_data(struct gfs2_inode *ip, uint64_t metablock,
+		       uint64_t block, void *private,
+		       struct gfs2_buffer_head *bh, uint64_t *ptr);
+extern int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+		       struct gfs2_buffer_head **bh, void *private);
+extern int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+		      struct gfs2_buffer_head **bh, void *private);
+extern int delete_eattr_entry(struct gfs2_inode *ip,
+			      struct gfs2_buffer_head *leaf_bh,
+			      struct gfs2_ea_header *ea_hdr,
+			      struct gfs2_ea_header *ea_hdr_prev,
+			      void *private);
+extern int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
+				 struct gfs2_buffer_head *leaf_bh,
+				 struct gfs2_ea_header *ea_hdr,
+				 struct gfs2_ea_header *ea_hdr_prev,
+				 void *private);
+extern int find_remove_dup(struct gfs2_inode *ip, uint64_t block,
+			   const char *btype);
+extern int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
+						   uint64_t dentryblock);
+#endif
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 7a77dc9..1f2bc10 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -989,93 +989,6 @@ static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block,
 }
 
 /**
- * delete_block - delete a block associated with an inode
- */
-int delete_block(struct gfs2_inode *ip, uint64_t block,
-		 struct gfs2_buffer_head **bh, const char *btype,
-		 void *private)
-{
-	if (valid_block(ip->i_sbd, block)) {
-		fsck_blockmap_set(ip, block, btype, GFS2_BLKST_FREE);
-		return 0;
-	}
-	return -1;
-}
-
-/**
- * find_remove_dup - find out if this is a duplicate ref.  If so, remove it.
- *
- * Returns: 1 if there are any remaining references to this block, else 0.
- */
-int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
-{
-	struct duptree *dt;
-	struct inode_with_dups *id;
-
-	dt = dupfind(block);
-	if (!dt)
-		return 0;
-
-	/* remove the inode reference id structure for this reference. */
-	id = find_dup_ref_inode(dt, ip);
-	if (!id)
-		goto more_refs;
-
-	dup_listent_delete(dt, id);
-	if (dt->refs == 0) {
-		log_info( _("This was the last reference: it's no longer a "
-			    "duplicate.\n"));
-		dup_delete(dt); /* not duplicate now */
-		return 0;
-	}
-more_refs:
-	log_info( _("%d block reference(s) remain.\n"), dt->refs);
-	return 1; /* references still exist so do not free the block. */
-}
-
-/**
- * delete_block_if_notdup - delete blocks associated with an inode
- *
- * Ignore blocks that are already marked free.
- * If it has been identified as duplicate, remove the duplicate reference.
- * If all duplicate references have been removed, delete the block.
- */
-static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
-				  struct gfs2_buffer_head **bh,
-				  const char *btype, int *was_duplicate,
-				  void *private)
-{
-	int q;
-
-	if (!valid_block(ip->i_sbd, block))
-		return meta_error;
-
-	q = bitmap_type(ip->i_sbd, block);
-	if (q == GFS2_BLKST_FREE) {
-		log_info( _("%s block %lld (0x%llx), part of inode "
-			    "%lld (0x%llx), was already free.\n"),
-			  btype, (unsigned long long)block,
-			  (unsigned long long)block,
-			  (unsigned long long)ip->i_di.di_num.no_addr,
-			  (unsigned long long)ip->i_di.di_num.no_addr);
-		return meta_is_good;
-	}
-	if (find_remove_dup(ip, block, btype)) { /* a dup */
-		if (was_duplicate)
-			*was_duplicate = 1;
-		log_err( _("Not clearing duplicate reference in inode "
-			   "at block #%llu (0x%llx) to block #%llu (0x%llx) "
-			   "because it's referenced by another inode.\n"),
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)block, (unsigned long long)block);
-	} else {
-		fsck_blockmap_set(ip, block, btype, GFS2_BLKST_FREE);
-	}
-	return meta_is_good;
-}
-
-/**
  * check_indirect_eattr
  * @ip: the inode the eattr comes from
  * @indirect_block
@@ -1159,9 +1072,9 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
 						 leaf_pointer_errors,
 						 pass->private);
 		}
-		if (leaf_pointer_errors &&
+		if (pass->delete_block && leaf_pointer_errors &&
 		    leaf_pointer_errors == leaf_pointers) {
-			delete_block(ip, indirect, NULL, "leaf", NULL);
+			pass->delete_block(ip, indirect, NULL, "leaf", NULL);
 			error = 1;
 		}
 	}
@@ -1729,184 +1642,3 @@ int check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip, struct metawalk_fxns
 
 	return error;
 }
-
-static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
-			 struct gfs2_dirent *prev_de,
-			 struct gfs2_buffer_head *bh,
-			 char *filename, uint32_t *count, int *lindex,
-			 void *private)
-{
-	/* the metawalk_fxn's private field must be set to the dentry
-	 * block we want to clear */
-	uint64_t *dentryblock = (uint64_t *) private;
-	struct gfs2_dirent dentry, *de;
-
-	memset(&dentry, 0, sizeof(struct gfs2_dirent));
-	gfs2_dirent_in(&dentry, (char *)dent);
-	de = &dentry;
-
-	if (de->de_inum.no_addr == *dentryblock)
-		dirent2_del(ip, bh, prev_de, dent);
-	else
-		(*count)++;
-
-	return 0;
-
-}
-
-int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
-			   uint64_t dentryblock)
-{
-	struct metawalk_fxns remove_dentry_fxns = {0};
-	struct gfs2_inode *ip;
-	int q;
-	int error;
-
-	log_debug( _("Removing dentry %llu (0x%llx) from directory %llu"
-		     " (0x%llx)\n"), (unsigned long long)dentryblock,
-		  (unsigned long long)dentryblock,
-		  (unsigned long long)dir, (unsigned long long)dir);
-	if (!valid_block(sdp, dir)) {
-		log_err( _("Parent directory is invalid\n"));
-		return 1;
-	}
-	remove_dentry_fxns.private = &dentryblock;
-	remove_dentry_fxns.check_dentry = remove_dentry;
-
-	q = bitmap_type(sdp, dir);
-	if (q != GFS2_BLKST_DINODE) {
-		log_info( _("Parent block is not an inode...ignoring\n"));
-		return 1;
-	}
-
-	ip = fsck_load_inode(sdp, dir);
-	if (ip == NULL) {
-		stack;
-		return -1;
-	}
-	/* Need to run check_dir with a private var of dentryblock,
-	 * and fxns that remove that dentry if found */
-	error = check_dir(sdp, ip, &remove_dentry_fxns);
-	fsck_inode_put(&ip);
-	return error;
-}
-
-int delete_metadata(struct gfs2_inode *ip, uint64_t block,
-		    struct gfs2_buffer_head **bh, int h, int *is_valid,
-		    int *was_duplicate, void *private)
-{
-	*is_valid = 1;
-	*was_duplicate = 0;
-	return delete_block_if_notdup(ip, block, bh, _("metadata"),
-				      was_duplicate, private);
-}
-
-int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
-{
-	return delete_block_if_notdup(ip, block, NULL, _("leaf"), NULL,
-				      private);
-}
-
-int delete_data(struct gfs2_inode *ip, uint64_t metablock,
-		uint64_t block, void *private, struct gfs2_buffer_head *bh,
-		uint64_t *ptr)
-{
-	return delete_block_if_notdup(ip, block, NULL, _("data"), NULL,
-				      private);
-}
-
-static int del_eattr_generic(struct gfs2_inode *ip, uint64_t block,
-			     uint64_t parent, struct gfs2_buffer_head **bh,
-			     void *private, const char *eatype)
-{
-	int ret = 0;
-	int was_free = 0;
-	int q;
-
-	if (valid_block(ip->i_sbd, block)) {
-		q = bitmap_type(ip->i_sbd, block);
-		if (q == GFS2_BLKST_FREE)
-			was_free = 1;
-		ret = delete_block_if_notdup(ip, block, NULL, eatype,
-					     NULL, private);
-		if (!ret) {
-			*bh = bread(ip->i_sbd, block);
-			if (!was_free)
-				ip->i_di.di_blocks--;
-			bmodified(ip->i_bh);
-		}
-	}
-	/* Even if it's a duplicate reference, we want to eliminate the
-	   reference itself, and adjust di_blocks accordingly. */
-	if (ip->i_di.di_eattr) {
-		if (block == ip->i_di.di_eattr)
-			ip->i_di.di_eattr = 0;
-		bmodified(ip->i_bh);
-	}
-	return ret;
-}
-
-int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
-		       struct gfs2_buffer_head **bh, void *private)
-{
-	return del_eattr_generic(ip, block, parent, bh, private,
-				 _("extended attribute"));
-}
-
-int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
-		      struct gfs2_buffer_head **bh, void *private)
-{
-	return del_eattr_generic(ip, block, parent, bh, private,
-				 _("indirect extended attribute"));
-}
-
-int delete_eattr_entry(struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh,
-		       struct gfs2_ea_header *ea_hdr,
-		       struct gfs2_ea_header *ea_hdr_prev, void *private)
-{
-	struct gfs2_sbd *sdp = ip->i_sbd;
-	char ea_name[256];
-	uint32_t avail_size;
-	int max_ptrs;
-
-	if (!ea_hdr->ea_name_len){
-		/* Skip this entry for now */
-		return 1;
-	}
-
-	memset(ea_name, 0, sizeof(ea_name));
-	strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
-		ea_hdr->ea_name_len);
-
-	if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
-	   ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
-		/* Skip invalid entry */
-		return 1;
-	}
-
-	if (!ea_hdr->ea_num_ptrs)
-		return 0;
-
-	avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
-	max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) /
-		avail_size;
-
-	if (max_ptrs > ea_hdr->ea_num_ptrs)
-		return 1;
-
-	log_debug( _("  Pointers Required: %d\n  Pointers Reported: %d\n"),
-		   max_ptrs, ea_hdr->ea_num_ptrs);
-
-	return 0;
-}
-
-int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
-			  struct gfs2_buffer_head *leaf_bh,
-			  struct gfs2_ea_header *ea_hdr,
-			  struct gfs2_ea_header *ea_hdr_prev, void *private)
-{
-	uint64_t block = be64_to_cpu(*ea_data_ptr);
-
-	return delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
-				      NULL, private);
-}
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index d505945..d2f0d97 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -19,33 +19,6 @@ extern int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 extern int check_leaf(struct gfs2_inode *ip, int lindex,
 		      struct metawalk_fxns *pass, uint64_t *leaf_no,
 		      struct gfs2_leaf *leaf, int *ref_count);
-extern int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
-						   uint64_t dentryblock);
-extern int delete_block(struct gfs2_inode *ip, uint64_t block,
-		 struct gfs2_buffer_head **bh, const char *btype,
-		 void *private);
-extern int delete_metadata(struct gfs2_inode *ip, uint64_t block,
-			   struct gfs2_buffer_head **bh, int h, int *is_valid,
-			   int *was_duplicate, void *private);
-extern int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
-extern int delete_data(struct gfs2_inode *ip, uint64_t metablock,
-		       uint64_t block, void *private,
-		       struct gfs2_buffer_head *bh, uint64_t *ptr);
-extern int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
-		       struct gfs2_buffer_head **bh, void *private);
-extern int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
-		      struct gfs2_buffer_head **bh, void *private);
-extern int delete_eattr_entry(struct gfs2_inode *ip,
-			      struct gfs2_buffer_head *leaf_bh,
-			      struct gfs2_ea_header *ea_hdr,
-			      struct gfs2_ea_header *ea_hdr_prev,
-			      void *private);
-extern int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
-				 struct gfs2_buffer_head *leaf_bh,
-				 struct gfs2_ea_header *ea_hdr,
-				 struct gfs2_ea_header *ea_hdr_prev,
-				 void *private);
-
 extern int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 			      const char *btype, int mark, int error_on_dinode,
 			      const char *caller, int line);
@@ -57,8 +30,6 @@ extern int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
 extern struct duptree *dupfind(uint64_t block);
 extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
 					    uint64_t block);
-extern int find_remove_dup(struct gfs2_inode *ip, uint64_t block,
-			   const char *btype);
 
 #define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
 
@@ -154,6 +125,9 @@ struct metawalk_fxns {
 				int h, void *private);
 	int (*undo_check_data) (struct gfs2_inode *ip, uint64_t block,
 				void *private);
+	int (*delete_block) (struct gfs2_inode *ip, uint64_t block,
+			     struct gfs2_buffer_head **bh, const char *btype,
+			     void *private);
 };
 
 #endif /* _METAWALK_H */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index d12e03e..fbacfea 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -83,6 +83,22 @@ static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 				 uint64_t parent, struct gfs2_buffer_head **bh,
 				 void *private);
 static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
+static int delete_block(struct gfs2_inode *ip, uint64_t block,
+			struct gfs2_buffer_head **bh, const char *btype,
+			void *private);
+/**
+ * delete_block - delete a block associated with an inode
+ */
+static int delete_block(struct gfs2_inode *ip, uint64_t block,
+			struct gfs2_buffer_head **bh, const char *btype,
+			void *private)
+{
+	if (valid_block(ip->i_sbd, block)) {
+		fsck_blockmap_set(ip, block, btype, GFS2_BLKST_FREE);
+		return 0;
+	}
+	return -1;
+}
 
 struct metawalk_fxns pass1_fxns = {
 	.private = NULL,
@@ -97,6 +113,7 @@ struct metawalk_fxns pass1_fxns = {
 	.big_file_msg = big_file_comfort,
 	.undo_check_meta = undo_check_metalist,
 	.undo_check_data = undo_check_data,
+	.delete_block = delete_block,
 };
 
 struct metawalk_fxns invalidate_fxns = {
@@ -106,6 +123,7 @@ struct metawalk_fxns invalidate_fxns = {
 	.check_leaf = invalidate_leaf,
 	.check_eattr_indir = invalidate_eattr_indir,
 	.check_eattr_leaf = invalidate_eattr_leaf,
+	.delete_block = delete_block,
 };
 
 /*
@@ -200,6 +218,7 @@ struct metawalk_fxns sysdir_fxns = {
 	.private = NULL,
 	.check_metalist = resuscitate_metalist,
 	.check_dentry = resuscitate_dentry,
+	.delete_block = delete_block,
 };
 
 static int p1check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
@@ -1124,6 +1143,7 @@ struct metawalk_fxns rangecheck_fxns = {
         .check_leaf = rangecheck_leaf,
         .check_eattr_indir = rangecheck_eattr_indir,
         .check_eattr_leaf = rangecheck_eattr_leaf,
+	.delete_block = delete_block,
 };
 
 struct metawalk_fxns eattr_undo_fxns = {
@@ -1131,6 +1151,7 @@ struct metawalk_fxns eattr_undo_fxns = {
 	.check_eattr_indir = undo_eattr_indir_or_leaf,
 	.check_eattr_leaf = undo_eattr_indir_or_leaf,
 	.finish_eattr_indir = finish_eattr_indir,
+	.delete_block = delete_block,
 };
 /* set_ip_blockmap - set the blockmap for a dinode
  *
@@ -1252,6 +1273,7 @@ struct metawalk_fxns alloc_fxns = {
 	.check_eattr_entry = NULL,
 	.check_eattr_extentry = NULL,
 	.finish_eattr_indir = NULL,
+	.delete_block = delete_block,
 };
 
 /*
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 20b603c..a9632d8 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -15,6 +15,7 @@
 #include "util.h"
 #include "metawalk.h"
 #include "inode_hash.h"
+#include "afterpass1_common.h"
 
 struct fxn_info {
 	uint64_t block;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index a215b3c..02d82e4 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -17,6 +17,7 @@
 #include "link.h"
 #include "lost_n_found.h"
 #include "inode_hash.h"
+#include "afterpass1_common.h"
 
 #define MAX_FILENAME 256
 
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 0df427d..d5f4ea2 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -16,6 +16,7 @@
 #include "link.h"
 #include "metawalk.h"
 #include "util.h"
+#include "afterpass1_common.h"
 
 static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 			    uint64_t olddotdot, uint64_t block)
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index ba38e8c..0d6cc9d 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -13,6 +13,7 @@
 #include "inode_hash.h"
 #include "metawalk.h"
 #include "util.h"
+#include "afterpass1_common.h"
 
 struct metawalk_fxns pass4_fxns_delete = {
 	.private = NULL,
-- 
2.5.5




More information about the Cluster-devel mailing list