[Ocfs2-tools-devel] [PATCH 1/2] ocfs2-tools: create fixed metadata file with tunefs

Tiger Yang tiger.yang at oracle.com
Wed Jan 19 01:25:50 PST 2011


This patch implement a tunefs operation to create fixed metadata file.
The name and size of the new created file must be specified, the
data blocks of the file will be allocated.

Signed-off-by: Tiger Yang <tiger.yang at oracle.com>
---
 include/ocfs2-kernel/ocfs2_fs.h         |    1 +
 tunefs.ocfs2/Makefile                   |    1 +
 tunefs.ocfs2/o2ne_err.et                |    3 +
 tunefs.ocfs2/ocfs2ne.c                  |   13 +++
 tunefs.ocfs2/op_create_fixed_metadata.c |  181 +++++++++++++++++++++++++++++++
 5 files changed, 199 insertions(+), 0 deletions(-)
 create mode 100644 tunefs.ocfs2/op_create_fixed_metadata.c

diff --git a/include/ocfs2-kernel/ocfs2_fs.h b/include/ocfs2-kernel/ocfs2_fs.h
index ffda634..f7dfad0 100644
--- a/include/ocfs2-kernel/ocfs2_fs.h
+++ b/include/ocfs2-kernel/ocfs2_fs.h
@@ -247,6 +247,7 @@
 #define OCFS2_NODUMP_FL		(0x00000040)	/* do not dump file */
 #define OCFS2_NOATIME_FL	(0x00000080)	/* do not update atime */
 #define OCFS2_DIRSYNC_FL	(0x00010000)	/* dirsync behaviour (directories only) */
+#define OCFS2_FIXEDMETA_FL	(0x00200000)	/* do not update meta data */
 
 #define OCFS2_FL_VISIBLE	(0x000100FF)	/* User visible flags */
 #define OCFS2_FL_MODIFIABLE	(0x000100FF)	/* User modifiable flags */
diff --git a/tunefs.ocfs2/Makefile b/tunefs.ocfs2/Makefile
index 1871136..885cdce 100644
--- a/tunefs.ocfs2/Makefile
+++ b/tunefs.ocfs2/Makefile
@@ -42,6 +42,7 @@ OCFS2NE_OPERATIONS =			\
 	op_set_slot_count		\
 	op_update_cluster_stack		\
 	op_set_quota_sync_interval	\
+	op_create_fixed_metadata
 
 sbindir = $(root_sbindir)
 SBIN_PROGRAMS = tunefs.ocfs2
diff --git a/tunefs.ocfs2/o2ne_err.et b/tunefs.ocfs2/o2ne_err.et
index 955c338..f9a5b05 100644
--- a/tunefs.ocfs2/o2ne_err.et
+++ b/tunefs.ocfs2/o2ne_err.et
@@ -52,6 +52,9 @@ ec	TUNEFS_ET_NO_MEMORY,
 ec	TUNEFS_ET_JOURNAL_DIRTY,
 	"At least one journal has uncommitted changes.  Run fsck.ocfs2 to replay all dirty journals"
 
+ec	TUNEFS_ET_INVALID_FILENAME,
+	"Invalid filename"
+
 ec	TUNEFS_ET_INVALID_NUMBER,
 	"Invalid number"
 
diff --git a/tunefs.ocfs2/ocfs2ne.c b/tunefs.ocfs2/ocfs2ne.c
index df4beb9..dbe67ac 100644
--- a/tunefs.ocfs2/ocfs2ne.c
+++ b/tunefs.ocfs2/ocfs2ne.c
@@ -100,6 +100,7 @@ extern struct tunefs_operation update_cluster_stack_op;
 extern struct tunefs_operation cloned_volume_op;
 extern struct tunefs_operation set_usrquota_sync_interval_op;
 extern struct tunefs_operation set_grpquota_sync_interval_op;
+extern struct tunefs_operation create_fixedmeta_op;
 
 /* List of operations we're going to run */
 static LIST_HEAD(tunefs_run_list);
@@ -609,6 +610,17 @@ static struct tunefs_option set_grpquota_sync_interval_option = {
 	.opt_op		= &set_grpquota_sync_interval_op,
 };
 
+static struct tunefs_option create_fixedmeta_option = {
+	.opt_option	= {
+		.name		= "create-fixedmeta",
+		.val		= CHAR_MAX,
+		.has_arg	= 1,
+	},
+	.opt_help	= "   --create-fixedmeta <filename:filesize>",
+	.opt_handle	= &generic_handle_arg,
+	.opt_op		= &create_fixedmeta_op,
+};
+
 /* The order here creates the order in print_usage() */
 static struct tunefs_option *options[] = {
 	&help_option,
@@ -631,6 +643,7 @@ static struct tunefs_option *options[] = {
 	&cloned_volume_option,
 	&set_usrquota_sync_interval_option,
 	&set_grpquota_sync_interval_option,
+	&create_fixedmeta_option,
 	&yes_option,
 	&no_option,
 	NULL,
diff --git a/tunefs.ocfs2/op_create_fixed_metadata.c b/tunefs.ocfs2/op_create_fixed_metadata.c
new file mode 100644
index 0000000..4c1dc98
--- /dev/null
+++ b/tunefs.ocfs2/op_create_fixed_metadata.c
@@ -0,0 +1,181 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * op_create_fixed_metadata.c
+ *
+ * ocfs2 tune utility to create the fixed metadada file.
+ *
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+#include <uuid/uuid.h>
+
+#include "ocfs2/ocfs2.h"
+#include "libocfs2ne.h"
+
+struct fixedmeta_specs {
+	char		fm_name[OCFS2_MAX_FILENAME_LEN];
+	uint64_t	fm_size;
+};
+
+static errcode_t new_file(ocfs2_filesys *fs, uint64_t dir, char *name,
+			  uint64_t size)
+{
+	errcode_t err;
+	uint64_t ino = 0;
+
+	err = ocfs2_new_inode(fs, &ino, S_IFREG | 0644);
+	if (err)
+		return err;
+
+	err = ocfs2_link(fs, dir, name, ino, OCFS2_FT_REG_FILE);
+	if (err)
+		return err;
+
+	err = ocfs2_extend_file(fs, ino, size);
+
+	return err;
+}
+
+static errcode_t create_fixed_metadata_file(ocfs2_filesys *fs, char *name,
+					    uint64_t size)
+{
+	errcode_t err;
+	uint64_t blkno = 0;
+	char *buf = NULL;
+	struct tools_progress *prog = NULL;
+	struct ocfs2_dinode *di = NULL;
+	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);
+
+	if (!tools_interact("Create the %"PRIu64" bytes fixed metadat file %s"
+			    " on device \"%s\"? ", size, name,
+			    fs->fs_devname))
+		return 0;
+
+	prog = tools_progress_start("Creating fixed metadata file",
+				    "create fixedmeta", 1);
+	if (!prog)
+		return TUNEFS_ET_NO_MEMORY;
+
+	err = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (err)
+		goto bail;
+
+	err = ocfs2_lookup(fs, sb->s_root_blkno, name, strlen(name),
+			   NULL, &blkno);
+	if (err != OCFS2_ET_FILE_NOT_FOUND) {
+		if (err == 0) {
+			errorf("File %s has already existed, use "
+			       "toggle_fixedmeta to change it.\n", name);
+			err = TUNEFS_ET_INVALID_FILENAME;
+		}
+		goto bail;
+	}
+
+	err = new_file(fs, sb->s_root_blkno, name, size);
+	if (err)
+		goto bail;
+
+	err = ocfs2_lookup(fs, sb->s_root_blkno, name, strlen(name),
+			   NULL, &blkno);
+	if (err)
+		goto bail;
+
+	err = ocfs2_read_inode(fs, blkno, buf);
+	if (err)
+		goto bail;
+	di = (struct ocfs2_dinode *)buf;
+	di->i_attr |= OCFS2_FIXEDMETA_FL;
+	err = ocfs2_write_inode(fs, blkno, buf);
+bail:
+	if (buf)
+		ocfs2_free(&buf);
+	tools_progress_step(prog, 1);
+	tools_progress_stop(prog);
+
+	return err;
+}
+
+static int create_fixedmeta_parse_option(struct tunefs_operation *op,
+					 char *arg)
+{
+	errcode_t err;
+	char *ns = NULL;
+	struct fixedmeta_specs *fmspecs = NULL;
+
+	err = ocfs2_malloc0(sizeof(struct fixedmeta_specs), &fmspecs);
+	if (err) {
+		tcom_err(err, "while create fixed metadata file options");
+		return 1;
+	}
+
+	err = TUNEFS_ET_INVALID_FILENAME;
+	ns = strtok(arg, ":");
+	if (ns == NULL)
+		goto bail;
+	if (strlen(ns) > OCFS2_MAX_FILENAME_LEN)
+		goto bail;
+	strcpy(fmspecs->fm_name, ns);
+
+	ns = strtok(NULL, ":");
+	if (ns == NULL)
+		goto bail;
+	err = tunefs_get_number(ns, &fmspecs->fm_size);
+	if (err || !(fmspecs->fm_size))
+		goto bail;
+
+	op->to_private = fmspecs;
+	return 0;
+bail:
+	if (fmspecs)
+		ocfs2_free(&fmspecs);
+	errorf("Invalid filename or size: %s\n", arg);
+	return 1;
+}
+
+static int create_fixedmeta_run(struct tunefs_operation *op, ocfs2_filesys *fs,
+				int flags)
+{
+	int rc = 0;
+	errcode_t err;
+	struct fixedmeta_specs *fmspecs = op->to_private;
+
+	err = create_fixed_metadata_file(fs, fmspecs->fm_name,
+					 fmspecs->fm_size);
+	if (err) {
+		tcom_err(err, "- unable to create fixed metadata file %s"
+			 " on device \"%s\"", fmspecs->fm_name,
+			 fs->fs_devname);
+		rc = 1;
+	}
+	ocfs2_free(&fmspecs);
+	op->to_private = NULL;
+
+	return rc;
+}
+
+DEFINE_TUNEFS_OP(create_fixedmeta,
+		 "Usage: op_create_fixedmeta [opts] <device>\n",
+		 TUNEFS_FLAG_RW,
+		 create_fixedmeta_parse_option,
+		 create_fixedmeta_run);
+
+#ifdef DEBUG_EXE
+int main(int argc, char *argv[])
+{
+	return tunefs_op_main(argc, argv, &create_fixedmeta_op);
+}
+#endif
-- 
1.5.4.3




More information about the Ocfs2-tools-devel mailing list