All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 2/2] Btrfs-progs: add mount-option command
Date: Tue, 18 Sep 2012 10:30:17 +0900	[thread overview]
Message-ID: <5057CEA9.3070707@jp.fujitsu.com> (raw)
In-Reply-To: <5057CDA7.3090201@jp.fujitsu.com>

This patch adds mount-option command.
The command can set/get default mount options.
Now, the command can set/get 24 options.
These options are equal to mount options which store
in fs_info/mount-opt.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
 Makefile             |    5 +-
 btrfs-parse-mntopt.c |  111 +++++++++++++++++++++++++++++++++++++
 btrfs-parse-mntopt.h |   65 ++++++++++++++++++++++
 btrfs.c              |    1 +
 cmds-mount.c         |  150 ++++++++++++++++++++++++++++++++++++++++++++++++++
 commands.h           |    2 +
 ctree.h              |   41 +++++++++++++-
 7 files changed, 372 insertions(+), 3 deletions(-)
 create mode 100644 btrfs-parse-mntopt.c
 create mode 100644 btrfs-parse-mntopt.h
 create mode 100644 cmds-mount.c

diff --git a/Makefile b/Makefile
index c0aaa3d..6f67f4c 100644
--- a/Makefile
+++ b/Makefile
@@ -5,9 +5,10 @@ objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
 	  root-tree.o dir-item.o file-item.o inode-item.o \
 	  inode-map.o crc32c.o rbtree.o extent-cache.o extent_io.o \
 	  volumes.o utils.o btrfs-list.o btrfslabel.o repair.o \
-	  send-stream.o send-utils.o
+	  send-stream.o send-utils.o btrfs-parse-mntopt.o
 cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \
-	       cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o
+	       cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \
+	       cmds-mount.o
 
 CHECKFLAGS= -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise \
 	    -Wuninitialized -Wshadow -Wundef
diff --git a/btrfs-parse-mntopt.c b/btrfs-parse-mntopt.c
new file mode 100644
index 0000000..87b341c
--- /dev/null
+++ b/btrfs-parse-mntopt.c
@@ -0,0 +1,111 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ctree.h"
+#include "btrfs-parse-mntopt.h"
+
+void btrfs_parse_string2mntopt(struct btrfs_root *root, char **options)
+{
+	struct btrfs_super_block *sb = &root->fs_info->super_copy;
+	char *p = NULL;
+	int i = 0;
+
+	memset(&sb->default_mount_opt, 0, sizeof(unsigned long));
+	while ((p = strsep(options, ",")) != NULL) {
+		int token = DEF_MNTOPT_NUM + 1;
+
+		if (!*p)
+			continue;
+		for (i = 0; i < DEF_MNTOPT_NUM; i++) {
+			if (!strcmp(p, toke[i].pattern)) {
+				token = toke[i].token;
+				break;
+			}
+		}
+		if (token > DEF_MNTOPT_NUM) {
+			printf("error: %s\n", p);
+			return;
+		}
+
+		switch (token) {
+		case Opt_degraded:
+			btrfs_set_opt(sb->default_mount_opt, DEGRADED);
+			break;
+
+		case Opt_nodatasum:
+			btrfs_set_opt(sb->default_mount_opt, NODATASUM);
+			break;
+		case Opt_nodatacow:
+			btrfs_set_opt(sb->default_mount_opt, NODATACOW);
+			btrfs_set_opt(sb->default_mount_opt, NODATASUM);
+			break;
+		case Opt_ssd:
+			btrfs_set_opt(sb->default_mount_opt, SSD);
+			break;
+		case Opt_ssd_spread:
+			btrfs_set_opt(sb->default_mount_opt, SSD);
+			btrfs_set_opt(sb->default_mount_opt, SSD_SPREAD);
+			break;
+		case Opt_nossd:
+			btrfs_set_opt(sb->default_mount_opt, NOSSD);
+			btrfs_clear_opt(sb->default_mount_opt, SSD);
+			btrfs_clear_opt(sb->default_mount_opt, SSD_SPREAD);
+			break;
+		case Opt_nobarrier:
+			btrfs_set_opt(sb->default_mount_opt, NOBARRIER);
+			break;
+		case Opt_notreelog:
+			btrfs_set_opt(sb->default_mount_opt, NOTREELOG);
+			break;
+		case Opt_flushoncommit:
+			btrfs_set_opt(sb->default_mount_opt, FLUSHONCOMMIT);
+			break;
+		case Opt_discard:
+			btrfs_set_opt(sb->default_mount_opt, DISCARD);
+			break;
+		case Opt_space_cache:
+			btrfs_set_opt(sb->default_mount_opt, SPACE_CACHE);
+			break;
+		case Opt_no_space_cache:
+			btrfs_clear_opt(sb->default_mount_opt, SPACE_CACHE);
+			break;
+		case Opt_inode_cache:
+			btrfs_set_opt(sb->default_mount_opt, INODE_MAP_CACHE);
+			break;
+		case Opt_clear_cache:
+			btrfs_set_opt(sb->default_mount_opt, CLEAR_CACHE);
+			break;
+		case Opt_user_subvol_rm_allowed:
+			btrfs_set_opt(sb->default_mount_opt,
+					USER_SUBVOL_RM_ALLOWED);
+			break;
+		case Opt_enospc_debug:
+			btrfs_set_opt(sb->default_mount_opt, ENOSPC_DEBUG);
+			break;
+		case Opt_defrag:
+			btrfs_set_opt(sb->default_mount_opt, AUTO_DEFRAG);
+			break;
+		case Opt_recovery:
+			btrfs_set_opt(sb->default_mount_opt, RECOVERY);
+			break;
+		case Opt_skip_balance:
+			btrfs_set_opt(sb->default_mount_opt, SKIP_BALANCE);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+void btrfs_parse_mntopt2string(unsigned long def_opt)
+{
+	if (!def_opt)
+		printf("no default options\n");
+	else {
+		int i = 0;
+		for (i = 0; i < DEF_MNTOPT_NUM; i++) {
+			if (def_opt & (1 << toke[i].token))
+				printf("%s\n", toke[i].pattern);
+		}
+	}
+}
diff --git a/btrfs-parse-mntopt.h b/btrfs-parse-mntopt.h
new file mode 100644
index 0000000..a2745ee
--- /dev/null
+++ b/btrfs-parse-mntopt.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 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 v2 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.
+ *
+ * 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.
+ */
+
+struct match_token {
+	int token;
+	const char *pattern;
+};
+
+typedef struct match_token match_table_t[];
+
+enum {
+	Opt_nodatasum, Opt_nodatacow, Opt_nobarrier, Opt_ssd,
+	Opt_degraded, Opt_compress, Opt_notreelog, Opt_flushoncommit,
+	Opt_ssd_spread, Opt_nossd, Opt_discard, Opt_compress_force,
+	Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
+	Opt_enospc_debug, Opt_defrag, Opt_inode_cache, Opt_recovery,
+	Opt_skip_balance, Opt_check_integrity,
+	Opt_check_integrity_including_extent_data, Opt_fatal_errors,
+	Opt_no_space_cache, DEF_MNTOPT_NUM,
+};
+
+static match_table_t toke = {
+	{Opt_degraded, "degraded"},
+	{Opt_nodatasum, "nodatasum"},
+	{Opt_nodatacow, "nodatacow"},
+	{Opt_nobarrier, "nobarrier"},
+	{Opt_compress, "compress"},
+	{Opt_compress_force, "compress-force"},
+	{Opt_ssd, "ssd"},
+	{Opt_ssd_spread, "ssd_spread"},
+	{Opt_nossd, "nossd"},
+	{Opt_notreelog, "notreelog"},
+	{Opt_flushoncommit, "flushoncommit"},
+	{Opt_discard, "discard"},
+	{Opt_space_cache, "space_cache"},
+	{Opt_no_space_cache, "no_space_cache"},
+	{Opt_clear_cache, "clear_cache"},
+	{Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},
+	{Opt_enospc_debug, "enospc_debug"},
+	{Opt_defrag, "auto_defrag"},
+	{Opt_inode_cache, "inode_map_cache"},
+	{Opt_recovery, "recovery"},
+	{Opt_skip_balance, "skip_balance"},
+	{Opt_check_integrity, "check_int"},
+	{Opt_check_integrity_including_extent_data, "check_int_data"},
+	{Opt_fatal_errors, "fatal_errors"},
+};
+
+void btrfs_parse_string2mntopt(struct btrfs_root *root, char **options);
+void btrfs_parse_mntopt2string(unsigned long def_opt);
diff --git a/btrfs.c b/btrfs.c
index e9d54f8..0d6c9a7 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -246,6 +246,7 @@ const struct cmd_group btrfs_cmd_group = {
 		{ "device", cmd_device, NULL, &device_cmd_group, 0 },
 		{ "scrub", cmd_scrub, NULL, &scrub_cmd_group, 0 },
 		{ "inspect-internal", cmd_inspect, NULL, &inspect_cmd_group, 0 },
+		{ "mount-option", cmd_mount, NULL, &mount_cmd_group, 0 },
 		{ "send", cmd_send, NULL, &send_cmd_group, 0 },
 		{ "receive", cmd_receive, NULL, &receive_cmd_group, 0 },
 		{ "help", cmd_help, cmd_help_usage, NULL, 0 },
diff --git a/cmds-mount.c b/cmds-mount.c
new file mode 100644
index 0000000..cbdb006
--- /dev/null
+++ b/cmds-mount.c
@@ -0,0 +1,150 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 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.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include "ioctl.h"
+#include "ctree.h"
+#include "transaction.h"
+#include "commands.h"
+#include "disk-io.h"
+#include "utils.h"
+#include "btrfs-parse-mntopt.h"
+
+static const char * const mount_cmd_group_usage[] = {
+	"btrfs mount-option <command> [<args>]",
+	NULL
+};
+
+static const char * const cmd_set_mntopt_usage[] = {
+	"btrfs mount-option set [<option>,...] <device>",
+	"Set default mount options",
+	NULL
+};
+
+static int cmd_set_mntopt(int argc, char **argv)
+{
+	struct btrfs_root *root = NULL;
+	struct btrfs_trans_handle *trans = NULL;
+	int ret = 0;
+
+	if (argc != 3)
+		usage(cmd_set_mntopt_usage);
+
+	if (check_mounted(argv[argc - 1])) {
+		fprintf(stderr, "%s is mounted\n", argv[argc - 1]);
+		return 1;
+	}
+
+	root = open_ctree(argv[argc - 1], 0, 1);
+
+	if (!root)
+		printf("error root\n");
+
+	trans = btrfs_start_transaction(root, 1);
+	btrfs_parse_string2mntopt(root, &argv[1]);
+	ret = btrfs_commit_transaction(trans, root);
+
+	close_ctree(root);
+	return ret;
+};
+
+static const char * const cmd_get_mntopt_usage[] = {
+	"btrfs mount-option get <device>",
+	"Get default mount options",
+	NULL
+};
+
+static int cmd_get_mntopt(int argc, char **argv)
+{
+	struct btrfs_root *root = NULL;
+	unsigned long def_opt;
+
+	memset(&def_opt, 0, sizeof(def_opt));
+	if (argc != 2) {
+		usage(cmd_get_mntopt_usage);
+		return 1;
+	}
+
+	if (check_mounted(argv[argc - 1])) {
+		fprintf(stderr, "%s is mounted\n", argv[argc - 1]);
+		return 1;
+	}
+
+	root = open_ctree(argv[argc - 1], 0, 0);
+
+	if (!root) {
+		printf("error root\n");
+		return 1;
+	}
+
+	def_opt = btrfs_super_default_mount_opt(&root->fs_info->super_copy);
+
+	btrfs_parse_mntopt2string(def_opt);
+
+	close_ctree(root);
+	return 0;
+};
+
+static const char * const cmd_clear_mntopt_usage[] = {
+	"btrfs mount-option clear <device>",
+	"Clear default mount options",
+	NULL
+};
+
+static int cmd_clear_mntopt(int argc, char **argv)
+{
+	struct btrfs_root *root = NULL;
+	struct btrfs_trans_handle *trans = NULL;
+	int ret = 0;
+
+	if (argc != 2) {
+		usage(cmd_clear_mntopt_usage);
+		return 1;
+	}
+
+	if (check_mounted(argv[argc - 1])) {
+		fprintf(stderr, "%s is mounted\n", argv[argc - 1]);
+		return 1;
+	}
+
+	root = open_ctree(argv[argc - 1], 0, 1);
+
+	if (!root)
+		printf("error root\n");
+
+	trans = btrfs_start_transaction(root, 1);
+	btrfs_set_super_default_mount_opt(&root->fs_info->super_copy, 0);
+	ret = btrfs_commit_transaction(trans, root);
+
+	close_ctree(root);
+	return ret;
+};
+
+const struct cmd_group mount_cmd_group = {
+	mount_cmd_group_usage, NULL, {
+		{ "set", cmd_set_mntopt, cmd_set_mntopt_usage, NULL, 0 },
+		{ "get", cmd_get_mntopt, cmd_get_mntopt_usage, NULL, 0 },
+		{ "clear", cmd_clear_mntopt, cmd_clear_mntopt_usage, NULL, 0},
+		{0, 0, 0, 0, 0 }
+	}
+};
+
+int cmd_mount(int argc, char **argv)
+{
+	return handle_command_group(&mount_cmd_group, argc, argv);
+}
diff --git a/commands.h b/commands.h
index 1ece87a..6cf91fc 100644
--- a/commands.h
+++ b/commands.h
@@ -88,6 +88,7 @@ extern const struct cmd_group balance_cmd_group;
 extern const struct cmd_group device_cmd_group;
 extern const struct cmd_group scrub_cmd_group;
 extern const struct cmd_group inspect_cmd_group;
+extern const struct cmd_group mount_cmd_group;
 extern const struct cmd_group send_cmd_group;
 extern const struct cmd_group receive_cmd_group;
 
@@ -97,5 +98,6 @@ int cmd_balance(int argc, char **argv);
 int cmd_device(int argc, char **argv);
 int cmd_scrub(int argc, char **argv);
 int cmd_inspect(int argc, char **argv);
+int cmd_mount(int argc, char **argv);
 int cmd_send(int argc, char **argv);
 int cmd_receive(int argc, char **argv);
diff --git a/ctree.h b/ctree.h
index d218b88..4a1bb5b 100644
--- a/ctree.h
+++ b/ctree.h
@@ -401,8 +401,11 @@ struct btrfs_super_block {
 
 	__le64 cache_generation;
 
+	/* default mount options */
+	unsigned long default_mount_opt;
+
 	/* future expansion */
-	__le64 reserved[31];
+	__le64 reserved[30];
 	u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
 	struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
 } __attribute__ ((__packed__));
@@ -1774,6 +1777,8 @@ BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block,
 			 csum_type, 16);
 BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
 			 cache_generation, 64);
+BTRFS_SETGET_STACK_FUNCS(super_default_mount_opt, struct btrfs_super_block,
+			 default_mount_opt, 64);
 
 static inline int btrfs_super_csum_size(struct btrfs_super_block *s)
 {
@@ -2128,3 +2133,37 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
 			struct btrfs_root *root, struct btrfs_path *path,
 			u64 isize);
 #endif
+
+/*
+ * Flags for mount options.
+ *
+ * Note: don't forget to add new options to btrfs_show_options()
+ */
+#define BTRFS_MOUNT_NODATASUM		(1 << 0)
+#define BTRFS_MOUNT_NODATACOW		(1 << 1)
+#define BTRFS_MOUNT_NOBARRIER		(1 << 2)
+#define BTRFS_MOUNT_SSD			(1 << 3)
+#define BTRFS_MOUNT_DEGRADED		(1 << 4)
+#define BTRFS_MOUNT_COMPRESS		(1 << 5)
+#define BTRFS_MOUNT_NOTREELOG           (1 << 6)
+#define BTRFS_MOUNT_FLUSHONCOMMIT       (1 << 7)
+#define BTRFS_MOUNT_SSD_SPREAD		(1 << 8)
+#define BTRFS_MOUNT_NOSSD		(1 << 9)
+#define BTRFS_MOUNT_DISCARD		(1 << 10)
+#define BTRFS_MOUNT_FORCE_COMPRESS      (1 << 11)
+#define BTRFS_MOUNT_SPACE_CACHE		(1 << 12)
+#define BTRFS_MOUNT_CLEAR_CACHE		(1 << 13)
+#define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14)
+#define BTRFS_MOUNT_ENOSPC_DEBUG	 (1 << 15)
+#define BTRFS_MOUNT_AUTO_DEFRAG		(1 << 16)
+#define BTRFS_MOUNT_INODE_MAP_CACHE	(1 << 17)
+#define BTRFS_MOUNT_RECOVERY		(1 << 18)
+#define BTRFS_MOUNT_SKIP_BALANCE	(1 << 19)
+#define BTRFS_MOUNT_CHECK_INTEGRITY	(1 << 20)
+#define BTRFS_MOUNT_CHECK_INTEGRITY_INCLUDING_EXTENT_DATA (1 << 21)
+#define BTRFS_MOUNT_PANIC_ON_FATAL_ERROR	(1 << 22)
+
+#define btrfs_clear_opt(o, opt)		((o) &= ~BTRFS_MOUNT_##opt)
+#define btrfs_set_opt(o, opt)		((o) |= BTRFS_MOUNT_##opt)
+#define btrfs_test_opt(root, opt)	((root)->fs_info->mount_opt& \
+					 BTRFS_MOUNT_##opt)
-- 
1.7.7.6



  parent reply	other threads:[~2012-09-18  1:30 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-18  1:25 [PATCH 0/2] Btrfs: set mount options permanently Hidetoshi Seto
2012-09-18  1:28 ` [PATCH 1/2] Btrfs: make space to keep default mount options Hidetoshi Seto
2012-09-18 12:10   ` David Sterba
2012-09-19  8:31     ` Hidetoshi Seto
2012-09-20 11:05       ` David Sterba
2012-09-18  1:30 ` Hidetoshi Seto [this message]
2012-09-18  2:31   ` [PATCH 2/2] Btrfs-progs: add mount-option command Miao Xie
2012-09-18  4:19     ` Roman Mamedov
2012-09-18  8:19       ` Hugo Mills
2012-09-18 12:06         ` David Sterba
2012-09-19  8:32     ` Hidetoshi Seto
2012-09-20 11:14       ` David Sterba
2012-09-18 12:30   ` David Sterba
2012-09-19  8:32     ` Hidetoshi Seto
2012-09-18 10:03 ` R: " Goffredo Baroncelli <kreijack@libero.it>
2012-09-19  8:31   ` Hidetoshi Seto
2012-09-20 11:28   ` David Sterba
2012-09-18 11:37 ` R: " Goffredo Baroncelli <kreijack@libero.it>

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5057CEA9.3070707@jp.fujitsu.com \
    --to=seto.hidetoshi@jp.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.