[Ocfs2-tools-devel] [PATCH 1/2] tunefs: add ability to turn on unwritten extents

Mark Fasheh mark.fasheh at oracle.com
Thu Nov 8 11:01:22 PST 2007


If sparse file support is enabled, turning on unwritten extents is just a
matter of writing the ro_compat flag. If the user asks for unwritten and the
file system doesn't support sparse files, we turn on sparse 1st.

The feature set code got a little smarter as a result of this patch - we can
now just use a set of bitfields to represent which features tunefs knows how
to set or clear.

Signed-off-by: Mark Fasheh <mark.fasheh at oracle.com>
---
 tunefs.ocfs2/features.c    |   66 ++++++++++++++++++++++++++++++++++++-------
 tunefs.ocfs2/sparse_file.c |   25 ++++++++++++++++
 tunefs.ocfs2/tunefs.h      |    1 +
 3 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/tunefs.ocfs2/features.c b/tunefs.ocfs2/features.c
index f05100a..69c0a8a 100644
--- a/tunefs.ocfs2/features.c
+++ b/tunefs.ocfs2/features.c
@@ -29,37 +29,75 @@
 
 extern ocfs2_tune_opts opts;
 
+#define TUNEFS_COMPAT_SET	0
+#define TUNEFS_COMPAT_CLEAR	0
+#define TUNEFS_RO_COMPAT_SET	OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
+#define TUNEFS_RO_COMPAT_CLEAR	0
+#define TUNEFS_INCOMPAT_SET	OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC
+#define TUNEFS_INCOMPAT_CLEAR	OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC
+
 /*
  * Check whether we can add or remove a feature.
  *
- * Currently, we only handle "sparse files".
+ * Features which can be SET or CLEARed are represented in the TUNEFS
+ * bitfields above.
  * More feature check may be added if we want to
  * support more options in tunefs.ocfs2.
  */
 errcode_t feature_check(ocfs2_filesys *fs)
 {
 	errcode_t ret = 1;
+	int sparse_on = ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super));
+
+	if (opts.set_feature.compat & ~TUNEFS_COMPAT_SET ||
+	    opts.set_feature.ro_compat & ~TUNEFS_RO_COMPAT_SET ||
+	    opts.set_feature.incompat & ~TUNEFS_INCOMPAT_SET)
+		goto bail;
 
-	if (opts.set_feature.ro_compat != 0 ||
-	    opts.set_feature.compat != 0 ||
-	    opts.clear_feature.ro_compat != 0 ||
-	    opts.clear_feature.compat != 0)
+	if (opts.clear_feature.compat & ~TUNEFS_COMPAT_CLEAR ||
+	    opts.clear_feature.ro_compat & ~TUNEFS_RO_COMPAT_CLEAR ||
+	    opts.clear_feature.incompat & ~TUNEFS_INCOMPAT_CLEAR)
 		goto bail;
 
-	if ((opts.set_feature.incompat ==
-	     OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC) &&
-	     !ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super)))
-		ret = 0;
-	else if (opts.clear_feature.incompat ==
-		 OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC) {
+	if (opts.set_feature.incompat & OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC) {
+		/*
+		 * Allow sparse to pass on an already-sparse file
+		 * system if the user asked for unwritten extents.
+		 */
+		if (ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super)) && 
+		    !(opts.set_feature.ro_compat & OCFS2_FEATURE_RO_COMPAT_UNWRITTEN))
+			goto bail;
+
+		sparse_on = 1;
+	} else if (opts.clear_feature.incompat & OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC) {
 		if (!ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super)))
 			goto bail;
 
+		sparse_on = 0;
 		ret = clear_sparse_file_check(fs, opts.progname);
 		if (ret)
 			goto bail;
 	}
 
+	if (opts.set_feature.ro_compat & OCFS2_FEATURE_RO_COMPAT_UNWRITTEN) {
+		/*
+		 * Disallow setting of unwritten extents unless we
+		 * either have sparse file support, or will also be
+		 * turning it on.
+		 */
+		if (!sparse_on)
+			goto bail;
+
+		/*
+		 * We can't use the helper here because it checks for
+		 * the sparse flag.
+		 */
+		if (OCFS2_HAS_RO_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
+					OCFS2_FEATURE_RO_COMPAT_UNWRITTEN))
+		    goto bail;
+	}
+
+	ret = 0;
 bail:
 	return ret;
 }
@@ -73,6 +111,12 @@ errcode_t update_feature(ocfs2_filesys *fs)
 	else if (opts.clear_feature.incompat
 		 & OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC)
 		ret = clear_sparse_file_flag(fs, opts.progname);
+	if (ret)
+		goto bail;
+
+	if (opts.set_feature.ro_compat & OCFS2_FEATURE_RO_COMPAT_UNWRITTEN)
+		set_unwritten_extents_flag(fs);
 
+bail:
 	return ret;
 }
diff --git a/tunefs.ocfs2/sparse_file.c b/tunefs.ocfs2/sparse_file.c
index 314f08d..2d2ba01 100644
--- a/tunefs.ocfs2/sparse_file.c
+++ b/tunefs.ocfs2/sparse_file.c
@@ -545,6 +545,15 @@ errcode_t set_sparse_file_flag(ocfs2_filesys *fs, char *progname)
 	errcode_t ret;
 	struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
 
+	/*
+	 * The flag to call set_sparse_file may get set as a result of
+	 * unwritten extents being turned on, despite the file system
+	 * already supporting sparse files. We can safely do nothing
+	 * here.
+	 */
+	if (ocfs2_sparse_alloc(super))
+		return 0;
+
 	ret = iterate_all_regular(fs, progname, set_func);
 
 	if (ret)
@@ -556,6 +565,22 @@ bail:
 	return ret;
 }
 
+void set_unwritten_extents_flag(ocfs2_filesys *fs)
+{
+	struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
+
+	/*
+	 * If we hit this, it's a bug - the code in feature_check()
+	 * should have prevented us from getting this far.
+	 *
+	 * XXX: Is it fatal? Should we just refuse the change and
+	 * print a warning to the console?
+	 */
+	assert(ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super)));
+
+	OCFS2_SET_RO_COMPAT_FEATURE(super, OCFS2_FEATURE_RO_COMPAT_UNWRITTEN);
+}
+
 static void add_hole(void *priv_data, uint32_t hole_start, uint32_t hole_len)
 {
 	errcode_t ret;
diff --git a/tunefs.ocfs2/tunefs.h b/tunefs.ocfs2/tunefs.h
index 3124b76..e7f8c88 100644
--- a/tunefs.ocfs2/tunefs.h
+++ b/tunefs.ocfs2/tunefs.h
@@ -107,6 +107,7 @@ errcode_t list_sparse(ocfs2_filesys *fs);
 errcode_t set_sparse_file_flag(ocfs2_filesys *fs, char *progname);
 errcode_t clear_sparse_file_check(ocfs2_filesys *fs, char *progname);
 errcode_t clear_sparse_file_flag(ocfs2_filesys *fs, char *progname);
+void set_unwritten_extents_flag(ocfs2_filesys *fs);
 void free_clear_ctxt(void);
 
 errcode_t feature_check(ocfs2_filesys *fs);
-- 
1.5.0.6




More information about the Ocfs2-tools-devel mailing list