[Ocfs2-tools-devel] [PATCH 10/11] tunefs.ocfs2: Support inline_data in tunefs.
Tao Ma
tao.ma at oracle.com
Tue Jul 22 15:52:29 PDT 2008
Allow tunefs.ocfs2 to enable/disable inline_data for a formatted
volume by --fs-features like "inline-data" and "noinline-data".
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
tunefs.ocfs2/Makefile | 3 +-
tunefs.ocfs2/features.c | 21 +++++-
tunefs.ocfs2/inline_data.c | 171 ++++++++++++++++++++++++++++++++++++++++++++
tunefs.ocfs2/sparse_file.c | 2 +-
tunefs.ocfs2/tunefs.c | 1 +
tunefs.ocfs2/tunefs.h | 6 ++
6 files changed, 200 insertions(+), 4 deletions(-)
create mode 100644 tunefs.ocfs2/inline_data.c
diff --git a/tunefs.ocfs2/Makefile b/tunefs.ocfs2/Makefile
index 8333971..c186f7c 100644
--- a/tunefs.ocfs2/Makefile
+++ b/tunefs.ocfs2/Makefile
@@ -27,7 +27,8 @@ CFILES = \
sparse_file.c \
features.c \
resize.c \
- format_slotmap.c
+ format_slotmap.c \
+ inline_data.c
HFILES = tunefs.h
diff --git a/tunefs.ocfs2/features.c b/tunefs.ocfs2/features.c
index 36307c8..b7d39e3 100644
--- a/tunefs.ocfs2/features.c
+++ b/tunefs.ocfs2/features.c
@@ -36,9 +36,11 @@ extern ocfs2_tune_opts opts;
#define TUNEFS_RO_COMPAT_SET OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
#define TUNEFS_RO_COMPAT_CLEAR OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
#define TUNEFS_INCOMPAT_SET (OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC | \
- OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP)
+ OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP | \
+ OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
#define TUNEFS_INCOMPAT_CLEAR (OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC | \
- OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP)
+ OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP | \
+ OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
/*
* Check whether we can add or remove a feature.
@@ -123,6 +125,14 @@ errcode_t feature_check(ocfs2_filesys *fs)
}
}
+ if (opts.clear_feature.incompat & OCFS2_FEATURE_INCOMPAT_INLINE_DATA) {
+ if (!ocfs2_support_inline_data(OCFS2_RAW_SB(fs->fs_super)))
+ goto bail;
+
+ ret = clear_inline_data_check(fs, opts.progname);
+ if (ret)
+ goto bail;
+ }
ret = 0;
bail:
return ret;
@@ -149,6 +159,13 @@ errcode_t update_feature(ocfs2_filesys *fs)
OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP)
ret = reformat_slot_map(fs);
+ if (opts.set_feature.incompat & OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
+ OCFS2_SET_INCOMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
+ OCFS2_FEATURE_INCOMPAT_INLINE_DATA);
+ else if (opts.clear_feature.incompat &
+ OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
+ ret = clear_inline_data_flag(fs, opts.progname);
+
bail:
return ret;
}
diff --git a/tunefs.ocfs2/inline_data.c b/tunefs.ocfs2/inline_data.c
new file mode 100644
index 0000000..25950f2
--- /dev/null
+++ b/tunefs.ocfs2/inline_data.c
@@ -0,0 +1,171 @@
+/*
+ * inline_data.c
+ *
+ * source file of inline data functions for tunefs.
+ *
+ * Copyright (C) 2008 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 as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#include <ocfs2/kernel-rbtree.h>
+#include <tunefs.h>
+#include <assert.h>
+
+struct inline_file {
+ uint64_t blkno;
+ struct inline_file *next;
+};
+
+struct inline_file_list {
+ struct inline_file *files;
+ uint64_t files_num;
+};
+
+struct inline_file_list files_list;
+
+static errcode_t iterate_all_file(ocfs2_filesys *fs,
+ char *progname)
+{
+ errcode_t ret;
+ uint64_t blkno;
+ char *buf;
+ struct ocfs2_dinode *di;
+ struct inline_file *file;
+ ocfs2_inode_scan *scan;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
+ if (ret)
+ goto out;
+
+ di = (struct ocfs2_dinode *)buf;
+
+ ret = ocfs2_open_inode_scan(fs, &scan);
+ if (ret) {
+ com_err(progname, ret, "while opening inode scan");
+ goto out_free;
+ }
+
+ for(;;) {
+ ret = ocfs2_get_next_inode(scan, &blkno, buf);
+ if (ret) {
+ com_err(progname, ret,
+ "while getting next inode");
+ break;
+ }
+ if (blkno == 0)
+ break;
+
+ if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
+ strlen(OCFS2_INODE_SIGNATURE)))
+ continue;
+
+ ocfs2_swap_inode_to_cpu(di);
+
+ if (di->i_fs_generation != fs->fs_super->i_fs_generation)
+ continue;
+
+ if (!(di->i_flags & OCFS2_VALID_FL))
+ continue;
+
+ if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) {
+ ret = ocfs2_malloc0(sizeof(struct inline_file), &file);
+ if (ret)
+ break;
+
+ files_list.files_num++;
+ file->blkno = di->i_blkno;
+ file->next = files_list.files;
+ files_list.files = file;
+ }
+ }
+
+ ocfs2_close_inode_scan(scan);
+out_free:
+ ocfs2_free(&buf);
+
+out:
+ return ret;
+}
+
+errcode_t clear_inline_data_check(ocfs2_filesys *fs, char *progname)
+{
+ errcode_t ret;
+ uint32_t free_clusters;
+
+ memset(&files_list, 0, sizeof(files_list));
+
+ ret = iterate_all_file(fs, progname);
+ if (ret)
+ goto bail;
+
+ ret = get_total_free_clusters(fs, &free_clusters);
+ if (ret)
+ goto bail;
+
+ printf("We have %u clusters free and need %"PRIu64" clusters "
+ "for inline data\n", free_clusters, files_list.files_num);
+
+ if (free_clusters < files_list.files_num) {
+ com_err(progname, 0, "Don't have enough free space.");
+ ret = OCFS2_ET_NO_SPACE;
+ }
+bail:
+ return ret;
+}
+
+errcode_t clear_inline_data_flag(ocfs2_filesys *fs, char *progname)
+{
+ errcode_t ret = 0;
+ struct inline_file *file = files_list.files;
+ ocfs2_cached_inode *ci = NULL;
+
+ while (file) {
+ ret = ocfs2_read_cached_inode(fs, file->blkno, &ci);
+ if (ret)
+ goto bail;
+
+ ret = ocfs2_convert_inline_data_to_extents(ci);
+ if (ret)
+ goto bail;
+
+ file = file->next;
+ }
+
+ if (ocfs2_support_inline_data(OCFS2_RAW_SB(fs->fs_super)))
+ OCFS2_CLEAR_INCOMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
+ OCFS2_FEATURE_INCOMPAT_INLINE_DATA);
+
+bail:
+ if (ci)
+ ocfs2_free_cached_inode(fs, ci);
+ free_inline_data_ctxt();
+ return ret;
+}
+
+void free_inline_data_ctxt(void)
+{
+ struct inline_file *file = files_list.files, *next;
+
+ while (file) {
+ next = file->next;
+ ocfs2_free(&file);
+ file = next;
+ }
+
+ files_list.files = NULL;
+}
diff --git a/tunefs.ocfs2/sparse_file.c b/tunefs.ocfs2/sparse_file.c
index e068524..c890ff9 100644
--- a/tunefs.ocfs2/sparse_file.c
+++ b/tunefs.ocfs2/sparse_file.c
@@ -163,7 +163,7 @@ out:
return ret;
}
-static errcode_t get_total_free_clusters(ocfs2_filesys *fs, uint32_t *clusters)
+errcode_t get_total_free_clusters(ocfs2_filesys *fs, uint32_t *clusters)
{
errcode_t ret;
uint64_t blkno;
diff --git a/tunefs.ocfs2/tunefs.c b/tunefs.ocfs2/tunefs.c
index 6d52062..1924bb2 100644
--- a/tunefs.ocfs2/tunefs.c
+++ b/tunefs.ocfs2/tunefs.c
@@ -1596,6 +1596,7 @@ close:
block_signals(SIG_UNBLOCK);
free_clear_ctxt();
+ free_inline_data_ctxt();
free_opts();
diff --git a/tunefs.ocfs2/tunefs.h b/tunefs.ocfs2/tunefs.h
index c7b4acf..430b5c5 100644
--- a/tunefs.ocfs2/tunefs.h
+++ b/tunefs.ocfs2/tunefs.h
@@ -123,4 +123,10 @@ int validate_vol_size(ocfs2_filesys *fs);
errcode_t online_resize_check(ocfs2_filesys *fs);
errcode_t online_resize_lock(ocfs2_filesys *fs);
errcode_t online_resize_unlock(ocfs2_filesys *fs);
+
+errcode_t get_total_free_clusters(ocfs2_filesys *fs, uint32_t *clusters);
+
+errcode_t clear_inline_data_check(ocfs2_filesys *fs, char *progname);
+errcode_t clear_inline_data_flag(ocfs2_filesys *fs, char *progname);
+void free_inline_data_ctxt(void);
#endif /* _TUNEFS_H */
--
1.5.4.GIT
More information about the Ocfs2-tools-devel
mailing list