[Ocfs2-tools-devel] [PATCH 2/2] tunefs: support for turning off
unwritten extents
Mark Fasheh
mark.fasheh at oracle.com
Thu Nov 8 11:01:27 PST 2007
This can just make re-use of the inode walk which is done for clearing the
sparse files flag.
Signed-off-by: Mark Fasheh <mark.fasheh at oracle.com>
---
tunefs.ocfs2/features.c | 30 +++++++++++++++++++++++++++---
tunefs.ocfs2/sparse_file.c | 31 +++++++++++++++++++++++++------
tunefs.ocfs2/tunefs.h | 3 ++-
3 files changed, 54 insertions(+), 10 deletions(-)
diff --git a/tunefs.ocfs2/features.c b/tunefs.ocfs2/features.c
index 69c0a8a..856e833 100644
--- a/tunefs.ocfs2/features.c
+++ b/tunefs.ocfs2/features.c
@@ -32,7 +32,7 @@ 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_RO_COMPAT_CLEAR OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
#define TUNEFS_INCOMPAT_SET OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC
#define TUNEFS_INCOMPAT_CLEAR OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC
@@ -73,8 +73,15 @@ errcode_t feature_check(ocfs2_filesys *fs)
if (!ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super)))
goto bail;
+ /*
+ * Turning off sparse files means we must also turn
+ * off unwritten extents.
+ */
+ if (ocfs2_writes_unwritten_extents(OCFS2_RAW_SB(fs->fs_super)))
+ opts.clear_feature.ro_compat |= OCFS2_FEATURE_RO_COMPAT_UNWRITTEN;
+
sparse_on = 0;
- ret = clear_sparse_file_check(fs, opts.progname);
+ ret = clear_sparse_file_check(fs, opts.progname, 0);
if (ret)
goto bail;
}
@@ -95,6 +102,21 @@ errcode_t feature_check(ocfs2_filesys *fs)
if (OCFS2_HAS_RO_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN))
goto bail;
+ } else if (opts.clear_feature.ro_compat &
+ OCFS2_FEATURE_RO_COMPAT_UNWRITTEN) {
+ if (!ocfs2_writes_unwritten_extents(OCFS2_RAW_SB(fs->fs_super)))
+ goto bail;
+
+ if (sparse_on) {
+ /*
+ * If we haven't run through the file system
+ * yet, do it now in order to build up our
+ * list of files with unwritten extents.
+ */
+ ret = clear_sparse_file_check(fs, opts.progname, 1);
+ if (ret)
+ goto bail;
+ }
}
ret = 0;
@@ -109,7 +131,9 @@ errcode_t update_feature(ocfs2_filesys *fs)
if (opts.set_feature.incompat & OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC)
ret = set_sparse_file_flag(fs, opts.progname);
else if (opts.clear_feature.incompat
- & OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC)
+ & OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC ||
+ opts.clear_feature.ro_compat
+ & OCFS2_FEATURE_RO_COMPAT_UNWRITTEN)
ret = clear_sparse_file_flag(fs, opts.progname);
if (ret)
goto bail;
diff --git a/tunefs.ocfs2/sparse_file.c b/tunefs.ocfs2/sparse_file.c
index 2d2ba01..8ef6710 100644
--- a/tunefs.ocfs2/sparse_file.c
+++ b/tunefs.ocfs2/sparse_file.c
@@ -26,6 +26,8 @@
#include <tunefs.h>
#include <assert.h>
+extern ocfs2_tune_opts opts;
+
struct multi_link_file {
struct rb_node br_node;
uint64_t blkno;
@@ -76,8 +78,10 @@ struct sparse_file {
struct clear_hole_unwritten_ctxt {
errcode_t ret;
+ int unwritten_only;
uint32_t more_clusters;
uint32_t more_ebs;
+ uint32_t total_unwritten;
struct sparse_file *files;
};
@@ -588,6 +592,9 @@ static void add_hole(void *priv_data, uint32_t hole_start, uint32_t hole_len)
struct clear_hole_unwritten_ctxt *ctxt =
(struct clear_hole_unwritten_ctxt *)priv_data;
+ if (clear_ctxt.unwritten_only)
+ return;
+
ret = ocfs2_malloc0(sizeof(struct hole_list), &hole);
if (ret) {
ctxt->ret = ret;
@@ -617,6 +624,8 @@ static void add_unwritten(void *priv_data, uint32_t start,
return;
}
+ clear_ctxt.total_unwritten += len;
+
unwritten->start = start;
unwritten->len = len;
unwritten->p_start = p_start;
@@ -674,12 +683,15 @@ bail:
return ret;
}
-errcode_t clear_sparse_file_check(ocfs2_filesys *fs, char *progname)
+errcode_t clear_sparse_file_check(ocfs2_filesys *fs, char *progname,
+ int unwritten_only)
{
errcode_t ret;
uint32_t free_clusters = 0;
memset(&clear_ctxt, 0, sizeof(clear_ctxt));
+ clear_ctxt.unwritten_only = unwritten_only;
+
ret = iterate_all_regular(fs, progname, calc_hole_and_unwritten);
if (ret)
goto bail;
@@ -688,9 +700,11 @@ errcode_t clear_sparse_file_check(ocfs2_filesys *fs, char *progname)
if (ret)
goto bail;
- printf("We have %u clusters free and need %u clusters for sparse files "
- "and %u clusters for more extent blocks\n",
- free_clusters, clear_ctxt.more_clusters, clear_ctxt.more_ebs);
+ printf("We have %u clusters free and need %u clusters for sparse "
+ "files, %u clusters for more extent blocks and will need to "
+ "clear %u clusters of unwritten extents.\n",
+ free_clusters, clear_ctxt.more_clusters, clear_ctxt.more_ebs,
+ clear_ctxt.total_unwritten);
if (free_clusters < clear_ctxt.more_clusters + clear_ctxt.more_ebs) {
com_err(progname, 0, "Don't have enough free space.");
@@ -746,6 +760,9 @@ errcode_t clear_sparse_file_flag(ocfs2_filesys *fs, char *progname)
if (ret)
goto bail;
+ if (clear_ctxt.unwritten_only)
+ goto fill_unwritten;
+
/* Iterate all the holes and fill them. */
while (file) {
hole = file->holes;
@@ -785,6 +802,7 @@ errcode_t clear_sparse_file_flag(ocfs2_filesys *fs, char *progname)
* mark it written.
*/
file = clear_ctxt.files;
+fill_unwritten:
while (file) {
if (!file->unwritten)
goto next_file;
@@ -818,8 +836,9 @@ next_file:
OCFS2_CLEAR_RO_COMPAT_FEATURE(super,
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN);
- OCFS2_CLEAR_INCOMPAT_FEATURE(super,
- OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC);
+ if (!clear_ctxt.unwritten_only)
+ OCFS2_CLEAR_INCOMPAT_FEATURE(super,
+ OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC);
bail:
return ret;
diff --git a/tunefs.ocfs2/tunefs.h b/tunefs.ocfs2/tunefs.h
index e7f8c88..566d746 100644
--- a/tunefs.ocfs2/tunefs.h
+++ b/tunefs.ocfs2/tunefs.h
@@ -105,7 +105,8 @@ errcode_t remove_slot_check(ocfs2_filesys *fs);
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_check(ocfs2_filesys *fs, char *progname,
+ int unwritten_only);
errcode_t clear_sparse_file_flag(ocfs2_filesys *fs, char *progname);
void set_unwritten_extents_flag(ocfs2_filesys *fs);
void free_clear_ctxt(void);
--
1.5.0.6
More information about the Ocfs2-tools-devel
mailing list