[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