[Ocfs2-tools-devel] [PATCH 35/50] fsck.ocfs2: Add check for refcount tree in pass1.

Tao Ma tao.ma at oracle.com
Mon Jan 11 07:31:21 PST 2010


In pass1, after we check inode field, we will check
refcount tree if it exists. We don't remove the root
tree if it is invalid, on the other hand, we re-init
it to an empty state so that the following patch can
re-generate the refcount tree for it.

Note:
This patch doesn't handle the issue of redundant check
of refcount tree for reflinked inodes. It will resolved
by the next patch.

Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
 fsck.ocfs2/Makefile               |    1 +
 fsck.ocfs2/fsck.ocfs2.checks.8.in |    6 ++++++
 fsck.ocfs2/include/refcount.h     |   26 ++++++++++++++++++++++++++
 fsck.ocfs2/pass1.c                |    5 +++++
 fsck.ocfs2/refcount.c             |   28 ++++++++++++++++++++++++++++
 5 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 fsck.ocfs2/include/refcount.h

diff --git a/fsck.ocfs2/Makefile b/fsck.ocfs2/Makefile
index 63f86de..d5f5d7e 100644
--- a/fsck.ocfs2/Makefile
+++ b/fsck.ocfs2/Makefile
@@ -54,6 +54,7 @@ HFILES = 	include/fsck.h		\
 		include/pass4.h		\
 		include/pass5.h		\
 		include/problem.h	\
+		include/refcount.h	\
 		include/slot_recovery.h	\
 		include/strings.h	\
 		include/util.h
diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
index 3400d30..b1e7013 100644
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
@@ -651,6 +651,12 @@ of blocks that were found associated with it.
 Answering yes resets the number of clusters to reflect the real number
 of blocks that were associated with the tree.
 
+.SS "REFCOUNT_ROOT_BLOCK_INVALID"
+Root refcount block is the root of the refcount record for a file. It is found
+refering an invalid refcount block.
+
+Answering yes remove this refcount block and clear refcount flag from this file.
+
 \" pass1b.c
 
 .SS "DUP_CLUSTERS_SYSFILE_CLONE"
diff --git a/fsck.ocfs2/include/refcount.h b/fsck.ocfs2/include/refcount.h
new file mode 100644
index 0000000..ed59b16
--- /dev/null
+++ b/fsck.ocfs2/include/refcount.h
@@ -0,0 +1,26 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * refcount.h
+ *
+ * Copyright (C) 2009 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __O2FSCK_REFCOUNT_H__
+#define __O2FSCK_REFCOUNT_H__
+
+#include "fsck.h"
+
+errcode_t o2fsck_check_refcount_tree(o2fsck_state *ost,
+				     struct ocfs2_dinode *di);
+#endif /* __O2FSCK_REFCOUNT_H__ */
+
diff --git a/fsck.ocfs2/pass1.c b/fsck.ocfs2/pass1.c
index edd579f..e605aca 100644
--- a/fsck.ocfs2/pass1.c
+++ b/fsck.ocfs2/pass1.c
@@ -71,6 +71,7 @@
 #include "problem.h"
 #include "util.h"
 #include "xattr.h"
+#include "refcount.h"
 
 static const char *whoami = "pass1";
 
@@ -1413,6 +1414,10 @@ errcode_t o2fsck_pass1(o2fsck_state *ost)
 					o2fsck_verify_inode_fields(fs, ost,
 								   blkno, di);
 				if (di->i_flags & OCFS2_VALID_FL) {
+					ret = o2fsck_check_refcount_tree(ost,
+									 di);
+					if (ret)
+						goto out;
 					ret = o2fsck_check_blocks(fs, ost,
 								  blkno, di);
 					if (ret)
diff --git a/fsck.ocfs2/refcount.c b/fsck.ocfs2/refcount.c
index 365a2c1..5ec7dd4 100644
--- a/fsck.ocfs2/refcount.c
+++ b/fsck.ocfs2/refcount.c
@@ -22,6 +22,8 @@
 #include "problem.h"
 #include "fsck.h"
 #include "extent.h"
+#include "util.h"
+#include "refcount.h"
 
 static const char *whoami = "refcount.c";
 
@@ -284,3 +286,29 @@ out:
 		ocfs2_free(&buf);
 	return 0;
 }
+
+errcode_t o2fsck_check_refcount_tree(o2fsck_state *ost,
+				     struct ocfs2_dinode *di)
+{
+	errcode_t ret;
+	uint64_t c_end = 0;
+	int is_valid = 1;
+
+	if (!(di->i_dyn_features & OCFS2_HAS_REFCOUNT_FL))
+		return 0;
+
+	ret = check_rb(ost, di->i_refcount_loc, di->i_refcount_loc,
+		       &c_end, &is_valid);
+
+	if (!is_valid &&
+	    prompt(ost, PY, PR_REFCOUNT_ROOT_BLOCK_INVALID,
+		   "Refcount tree %"PRIu64 " for inode %"PRIu64" is invalid. "
+		   "Remove it and clear the flag for the inode?",
+		   (uint64_t)di->i_refcount_loc, (uint64_t)di->i_blkno)) {
+		di->i_refcount_loc = 0;
+		di->i_dyn_features &= ~OCFS2_HAS_REFCOUNT_FL;
+
+		o2fsck_write_inode(ost, di->i_blkno, di);
+	}
+	return ret;
+}
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list