[Ocfs2-tools-devel] [PATCH 7/9] fsck.ocfs2: Implement Pass 1D's prompt for dup fixes.

Joel Becker joel.becker at oracle.com
Thu Jul 30 12:25:05 PDT 2009


For each inode claiming shared clusters, ask about cloning or deleting
them.

Chain allocators are skipped, as they are not safe to clone or delete.
They are very location specific.  If they are sharing with another chain
allocator, pass0 should have handled it.  If they are sharing with a
regular inode, that inode can be cloned or deleted.

The other system files can be cloned but not deleted.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 fsck.ocfs2/fsck.ocfs2.checks.8.in |   24 +++++++++++
 fsck.ocfs2/pass1b.c               |   77 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
index 1f68fe3..c053329 100644
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
@@ -541,6 +541,30 @@ allocator.
 Answering yes will invert the bit in the allocator to match the use of the
 cluster -- either allocated and in use or free.
 
+\" pass1b.c
+
+.SS "DUP_CLUSTERS_SYSFILE_CLONE"
+A system file inode claims clusters that are also claimed by another inode.
+ocfs2 does not allow this.  System files may be cloned but may not be
+deleted.  Allocation system files may not be cloned or deleted.
+
+Answering yes will copy the data of this inode to newly allocated extents.
+This will break the claim on the overcommitted clusters.
+
+.SS "DUP_CLUSTERS_CLONE"
+An inode claims clusters that are also claimed by another inode.  ocfs2
+does not allow this.
+
+Answering yes will copy the data of this inode to newly allocated extents.
+This will break the claim on the overcommitted clusters.
+
+.SS "DUP_CLUSTERS_DELETE"
+An inode claims clusters that are also claimed by another inode.  ocfs2
+does not allow this.
+
+Answering yes will remove this inode, thus breaking its claim on the
+overcommitted clusters.
+
 \" pass2.c
 
 .SS "DIRENT_DOTTY_DUP"
diff --git a/fsck.ocfs2/pass1b.c b/fsck.ocfs2/pass1b.c
index 20b9dab..f45f0f9 100644
--- a/fsck.ocfs2/pass1b.c
+++ b/fsck.ocfs2/pass1b.c
@@ -956,6 +956,10 @@ static void print_inode_path(struct dup_inode *di)
 		fprintf(stdout, "<%"PRIu64">\n", di->di_ino);
 }
 
+/*
+ * Walk the owning inodes of a dup_cluster, calling func().  func() may
+ * return non-zero to abort the walk.
+ */
 static void for_each_owner(struct dup_context *dct, struct dup_cluster *dc,
 			   int (*func)(struct dup_cluster *dc,
 				       struct dup_inode *di,
@@ -996,11 +1000,77 @@ static int print_func(struct dup_cluster *dc, struct dup_inode *di,
 	return 0;
 }
 
+/* Context for fix_dups_func() */
+struct fix_dup_context {
+	o2fsck_state *fd_ost;
+	struct dup_context *fd_dct;
+	errcode_t fd_err;
+};
+
+static void print_chain_warning(void)
+{
+	static int chain_warning = 0;
+
+	if (chain_warning)
+		return;
+
+	printf("The filesystem is safe to read.  You may wish to mount "
+	       "it read-only and copy data to a new filesystem.\n");
+	chain_warning = 1;
+}
+
+static int fix_dups_func(struct dup_cluster *dc, struct dup_inode *di,
+			 void *priv_data)
+{
+	struct fix_dup_context *fd = priv_data;
+
+	if (di->di_flags & OCFS2_CHAIN_FL) {
+		printf("Inode \"%s\" is a chain allocator and cannot "
+		       "be cloned or deleted.\n",
+		       di->di_path);
+		print_chain_warning();
+		return 0;
+	}
+
+	if (di->di_flags & OCFS2_SYSTEM_FL) {
+		if (prompt(fd->fd_ost, PY, PR_DUP_CLUSTERS_SYSFILE_CLONE,
+			   "Inode \"%s\" is a system file. It may be "
+			   "cloned but not deleted. Clone inode \"%s\" to "
+			   "break claims on clusters it shares with other "
+			   "inodes?",
+			   di->di_path, di->di_path)) {
+			return 0;
+		}
+	} else {
+		if (prompt(fd->fd_ost, PY, PR_DUP_CLUSTERS_CLONE,
+			   "Inode \"%s\" may be cloned or deleted to "
+			   "break the claim it has on its clusters. "
+			   "Clone inode \"%s\" to break claims on "
+			   "clusters it shares with other inodes?",
+			   di->di_path, di->di_path)) {
+			return 0;
+		}
+		if (prompt(fd->fd_ost, PN, PR_DUP_CLUSTERS_DELETE,
+			   "Delete inode \"%s\" to break claims on "
+			   "clusters it shares with other inodes?",
+			   di->di_path)) {
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
 static errcode_t o2fsck_pass1d(o2fsck_state *ost, struct dup_context *dct)
 {
+	errcode_t ret = 0;
 	struct dup_cluster *dc;
 	struct rb_node *node = rb_first(&dct->dup_clusters);
 	uint64_t dups;
+	struct fix_dup_context fd = {
+		.fd_ost = ost,
+		.fd_dct = dct,
+	};
 
 	whoami = "pass1d";
 	printf("Pass 1d: Reconciling multiply-claimed clusters\n");
@@ -1016,9 +1086,14 @@ static errcode_t o2fsck_pass1d(o2fsck_state *ost, struct dup_context *dct)
 		       "inodes:\n",
 		       dc->dc_cluster);
 		for_each_owner(dct, dc, print_func, NULL);
+		for_each_owner(dct, dc, fix_dups_func, &fd);
+		if (fd.fd_err) {
+			ret = fd.fd_err;
+			break;
+		}
 	}
 
-	return 0;
+	return ret;
 }
 
 
-- 
1.6.3.3




More information about the Ocfs2-tools-devel mailing list