linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Btrfs: set mount options permanently
@ 2012-10-12  3:18 Hidetoshi Seto
  2012-10-12  3:24 ` [PATCH v2 1/4] Btrfs-progs: add mount-option command Hidetoshi Seto
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Hidetoshi Seto @ 2012-10-12  3:18 UTC (permalink / raw)
  To: linux-btrfs

Following patches are going to implement one of unclaimed features
listed in the btrfs wiki:

https://btrfs.wiki.kernel.org/index.php/Project_ideas#Set_mount_options_permanently

Previous v1 post and discussion can be referred from:
http://lwn.net/Articles/516898/

v2:
- Allow operator [+-=] like chmod for setting options
- Save options by words instead of internal bits.
  (e.g. kernel code will translate a word "ssd_spread" to 2 internal
   bits "SSD" and "SSD_SPREAD". However this behavior might be changed
   if kernel updates.)

Special thanks to Kazuhiro Yamashita for his time and efforts.
Again, your comments/reviews are welcomed.

Thanks,
H.Seto


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/4] Btrfs-progs: add mount-option command
  2012-10-12  3:18 [PATCH v2 0/4] Btrfs: set mount options permanently Hidetoshi Seto
@ 2012-10-12  3:24 ` Hidetoshi Seto
  2012-10-12  5:35   ` Tsutomu Itoh
  2012-10-12  8:21   ` Tsutomu Itoh
  2012-10-12  3:24 ` [PATCH v2 2/4] Btrfs-progs: add mount-option command man page Hidetoshi Seto
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 8+ messages in thread
From: Hidetoshi Seto @ 2012-10-12  3:24 UTC (permalink / raw)
  To: linux-btrfs

This patch adds mount-option command that can set/get/clear default
mount options.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
 Makefile             |    4 +-
 btrfs-parse-mntopt.c |  109 +++++++++++++++++++++++++++++
 btrfs-parse-mntopt.h |   66 ++++++++++++++++++
 btrfs.c              |    1 +
 cmds-mount.c         |  185 ++++++++++++++++++++++++++++++++++++++++++++++++++
 commands.h           |    2 +
 ctree.h              |    7 ++-
 7 files changed, 371 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 4894903..c25d982 100644
--- a/Makefile
+++ b/Makefile
@@ -5,10 +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 qgroup.o
+	  send-stream.o send-utils.o qgroup.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-quota.o cmds-qgroup.o
+	       cmds-quota.o cmds-qgroup.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..66a924d
--- /dev/null
+++ b/btrfs-parse-mntopt.c
@@ -0,0 +1,109 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ctree.h"
+#include "btrfs-parse-mntopt.h"
+
+void btrfs_parse_string2mntopt(u64 *optval, int optnum, char **options)
+{
+	char *p, *opts;
+	int i, j;
+	u64 newval = *optval;
+	char overwrite = 0;
+
+	for (i = 0; i < optnum; i++) {
+		char *token, *save_ptr;
+		char revert = 0;
+		u64 orders = 0;
+
+		opts = options[i];
+
+		switch (*opts) {
+		case '=':
+			if (overwrite) {
+				fprintf(stderr, "'=' operator may only be specified once.\n");
+				return;
+			}
+			if (i) {
+				fprintf(stderr, "cannot use operator '=' with '+/-'.\n");
+				return;
+			}
+			if (!*(opts + 1)) {
+				fprintf(stderr, "no options after '='.\n");
+				return;
+			}
+			overwrite = 1;
+			opts++;
+			break;
+		case '-':
+			revert = 1;
+		case '+':
+			if (overwrite) {
+				fprintf(stderr, "cannot use operator '=' with '+/-'.\n");
+				return;
+			}
+			if (!*(opts + 1)) {
+				fprintf(stderr, "no options after '%c'.\n", *opts);
+				return;
+			}
+			opts++;
+			break;
+		default:
+			fprintf(stderr, "options must be specified with '+/-/='.\n");
+			return;
+		}
+
+		for (token = strtok_r(opts, ",", &save_ptr); token != NULL;
+		     token = strtok_r(NULL, ",", &save_ptr)) {
+			char *arg;
+
+			arg = strchr(token, '=');
+			if (arg) {
+				/* TBD: compress=<type> */
+				fprintf(stderr, "format 'option=arg' is not supported.\n");
+				return;
+			}
+
+			for (j = 0; tokens[j].pattern != NULL; j++) {
+				if (!strcmp(token, tokens[j].pattern)) {
+					orders |= (1 << tokens[j].token);
+					break;
+				}
+			}
+			if (!tokens[j].pattern) {
+				fprintf(stderr, "unknown option '%s'.\n", token);
+				printf("supported options : ");
+				btrfs_parse_mntopt2string(-1);
+				return;
+			}
+		}
+
+		if (overwrite)
+			newval = orders;
+		else if (revert)
+			newval &= ~orders;
+		else
+			newval |= orders;
+	}
+
+	*optval = newval;
+}
+
+void btrfs_parse_mntopt2string(u64 optval)
+{
+	if (!optval)
+		printf("no default options\n");
+	else {
+		int i, cont = 0;
+
+		for (i = 0; tokens[i].pattern != NULL; i++) {
+			if (optval & (1 << tokens[i].token)) {
+				if (cont)
+					printf(",");
+				printf("%s", tokens[i].pattern);
+				cont = 1;
+			}
+		}
+		printf("\n");
+	}
+}
diff --git a/btrfs-parse-mntopt.h b/btrfs-parse-mntopt.h
new file mode 100644
index 0000000..784a942
--- /dev/null
+++ b/btrfs-parse-mntopt.h
@@ -0,0 +1,66 @@
+/* btrfs-parse-mntopt.h */
+
+struct match_token {
+	int token;
+	const char *pattern;
+};
+
+typedef struct match_token match_table_t[];
+
+/* copy & pasted from super.c */
+enum {
+	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
+	Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
+	Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
+	Opt_compress_type, Opt_compress_force, Opt_compress_force_type,
+	Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
+	Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
+	Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_inode_cache,
+	Opt_no_space_cache, Opt_recovery, Opt_skip_balance,
+	Opt_check_integrity, Opt_check_integrity_including_extent_data,
+	Opt_check_integrity_print_mask, Opt_fatal_errors,
+	Opt_err,
+};
+
+static match_table_t tokens = {
+/*	{Opt_degraded, "degraded"},		... never be default */
+/*	{Opt_subvol, "subvol=%s"},		... not supported */
+/*	{Opt_subvolid, "subvolid=%d"},		... not supported */
+/*	{Opt_device, "device=%s"},		... not supported */
+	{Opt_nodatasum, "nodatasum"},
+	{Opt_nodatacow, "nodatacow"},
+	{Opt_nobarrier, "nobarrier"},
+/*	{Opt_max_inline, "max_inline=%s"},	... not supported */
+/*	{Opt_alloc_start, "alloc_start=%s"},	... not supported */
+/*	{Opt_thread_pool, "thread_pool=%d"},	... not supported */
+	{Opt_compress, "compress"},
+/*	{Opt_compress_type, "compress=%s"},		... TBD? */
+	{Opt_compress_force, "compress-force"},
+/*	{Opt_compress_force_type, "compress-force=%s"},	... TBD? */
+	{Opt_ssd, "ssd"},
+	{Opt_ssd_spread, "ssd_spread"},
+	{Opt_nossd, "nossd"},
+	{Opt_noacl, "noacl"},
+	{Opt_notreelog, "notreelog"},
+	{Opt_flushoncommit, "flushoncommit"},
+/*	{Opt_ratio, "metadata_ratio=%d"},	... not supported */
+	{Opt_discard, "discard"},
+	{Opt_space_cache, "space_cache"},
+	{Opt_clear_cache, "clear_cache"},
+	{Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},
+/*	{Opt_enospc_debug, "enospc_debug"},	... never be default */
+/*	{Opt_subvolrootid, "subvolrootid=%d"},	... not supported */
+	{Opt_defrag, "autodefrag"},
+	{Opt_inode_cache, "inode_cache"},
+	{Opt_no_space_cache, "nospace_cache"},
+	{Opt_recovery, "recovery"},
+	{Opt_skip_balance, "skip_balance"},
+	{Opt_check_integrity, "check_int"},
+	{Opt_check_integrity_including_extent_data, "check_int_data"},
+/*	{Opt_check_integrity_print_mask, "check_int_print_mask=%d"},
+	{Opt_fatal_errors, "fatal_errors=%s"},	... not supported */
+	{Opt_err, NULL},	/* must be end */
+};
+
+void btrfs_parse_string2mntopt(u64 *optval, int optnum, char **options);
+void btrfs_parse_mntopt2string(u64 optval);
diff --git a/btrfs.c b/btrfs.c
index a229cee..608869d 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -250,6 +250,7 @@ const struct cmd_group btrfs_cmd_group = {
 		{ "receive", cmd_receive, NULL, &receive_cmd_group, 0 },
 		{ "quota", cmd_quota, NULL, &quota_cmd_group, 0 },
 		{ "qgroup", cmd_qgroup, NULL, &qgroup_cmd_group, 0 },
+		{ "mount-option", cmd_mount, NULL, &mount_cmd_group, 0 },
 		{ "help", cmd_help, cmd_help_usage, NULL, 0 },
 		{ "version", cmd_version, cmd_version_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
diff --git a/cmds-mount.c b/cmds-mount.c
new file mode 100644
index 0000000..1752019
--- /dev/null
+++ b/cmds-mount.c
@@ -0,0 +1,185 @@
+/*
+ * 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 int mount_check_device(char *device)
+{
+	int ret;
+
+	ret = check_mounted(device);
+	if (ret == 1) {
+		fprintf(stderr, "%s is mounted\n", device);
+		return 1;
+	}
+	if (ret < 0) {
+		fprintf(stderr, "error checking %s mount status with %d(%s)\n",
+			device, ret, strerror(-1*ret));
+		return 1;
+	}
+	return 0;
+}
+
+static int mount_set_common(char *device, int numopts, char **options)
+{
+	struct btrfs_root *root;
+	struct btrfs_trans_handle *trans;
+	u64 optval = 0;
+	int ret;
+
+	root = open_ctree(device, 0, 1);
+	if (!root) {
+		fprintf(stderr, "error opening ctree of %s\n", device);
+		return 1;
+	}
+
+	if (numopts) {
+		optval = btrfs_super_default_mount_opt(&root->fs_info->super_copy);
+		btrfs_parse_string2mntopt(&optval, numopts, options);
+	}
+
+	trans = btrfs_start_transaction(root, 1);
+	btrfs_set_super_default_mount_opt(&root->fs_info->super_copy, optval);
+	ret = btrfs_commit_transaction(trans, root);
+
+	close_ctree(root);
+
+	return ret;
+}
+
+static int mount_show_common(char *device)
+{
+	struct btrfs_root *root;
+	u64 def_opt;
+
+	root = open_ctree(device, 0, 0);
+	if (!root) {
+		fprintf(stderr, "error opening ctree of %s\n", device);
+		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_set_mntopt_usage[] = {
+	"btrfs mount-option set [[+-=]<mount-option>,...] <device>",
+	"Set default mount options",
+	NULL
+};
+
+static int cmd_set_mntopt(int argc, char **argv)
+{
+	char *device;
+
+	if (check_argc_min(argc, 2)) {
+		usage(cmd_set_mntopt_usage);
+		return 1;
+	}
+
+	device = argv[argc - 1];
+	if (mount_check_device(device))
+		return 1;
+
+	if (argc == 2) {
+		/* get mount option */
+		return mount_show_common(device);
+	}
+	/* set mount option */
+	/*
+	 * Note:
+	 *	argv[0] = "btrfs mount-option set"
+	 *	argv[*] = <options>
+	 *	argv[n] = <device>
+	 */
+	return mount_set_common(device, argc - 2, &argv[1]);
+}
+
+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)
+{
+	char *device;
+
+	if (check_argc_exact(argc, 2)) {
+		usage(cmd_get_mntopt_usage);
+		return 1;
+	}
+
+	device = argv[argc - 1];
+	if (mount_check_device(device))
+		return 1;
+
+	return mount_show_common(device);
+};
+
+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)
+{
+	char *device;
+
+	if (check_argc_exact(argc, 2)) {
+		usage(cmd_clear_mntopt_usage);
+		return 1;
+	}
+
+	device = argv[argc - 1];
+	if (mount_check_device(device))
+		return 1;
+
+	return mount_set_common(device, 0, NULL);
+};
+
+static const char * const mount_cmd_group_usage[] = {
+	"btrfs mount-option <command> [<args>]",
+	NULL
+};
+
+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 bb6d2dd..fea30fd 100644
--- a/commands.h
+++ b/commands.h
@@ -92,6 +92,7 @@ extern const struct cmd_group send_cmd_group;
 extern const struct cmd_group receive_cmd_group;
 extern const struct cmd_group quota_cmd_group;
 extern const struct cmd_group qgroup_cmd_group;
+extern const struct cmd_group mount_cmd_group;
 
 int cmd_subvolume(int argc, char **argv);
 int cmd_filesystem(int argc, char **argv);
@@ -103,6 +104,7 @@ int cmd_send(int argc, char **argv);
 int cmd_receive(int argc, char **argv);
 int cmd_quota(int argc, char **argv);
 int cmd_qgroup(int argc, char **argv);
+int cmd_mount(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
diff --git a/ctree.h b/ctree.h
index 7f55229..363a118 100644
--- a/ctree.h
+++ b/ctree.h
@@ -402,8 +402,11 @@ struct btrfs_super_block {
 
 	__le64 cache_generation;
 
+	/* default mount options */
+	__le64 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__));
@@ -1820,6 +1823,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)
 {
-- 
1.7.7.6



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/4] Btrfs-progs: add mount-option command man page
  2012-10-12  3:18 [PATCH v2 0/4] Btrfs: set mount options permanently Hidetoshi Seto
  2012-10-12  3:24 ` [PATCH v2 1/4] Btrfs-progs: add mount-option command Hidetoshi Seto
@ 2012-10-12  3:24 ` Hidetoshi Seto
  2012-10-14  9:04   ` Goffredo Baroncelli
  2012-10-12  3:24 ` [PATCH v2 3/4] btrfs: make subroutine __btrfs_parse_options Hidetoshi Seto
  2012-10-12  3:25 ` [PATCH v2 4/4] btrfs: support default mount options Hidetoshi Seto
  3 siblings, 1 reply; 8+ messages in thread
From: Hidetoshi Seto @ 2012-10-12  3:24 UTC (permalink / raw)
  To: linux-btrfs

Add mount-option command man page.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
 man/btrfs.8.in |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 4b0a9f9..85d5030 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -52,6 +52,12 @@ btrfs \- control a btrfs filesystem
 \fBbtrfs\fP \fBinspect-internal logical-resolve\fP
 [-Pv] \fI<logical>\fP \fI<path>\fP
 .PP
+\fBbtrfs\fP \fBmount-option set\fP \fI[[<+/-/=><option>,...]...]\fP \fI<device>\fP
+.PP
+\fBbtrfs\fP \fBmount-option get\fP \fI<device>\fP
+.PP
+\fBbtrfs\fP \fBmount-option clear\fP \fI<device>\fP
+.PP
 \fBbtrfs\fP \fBhelp|\-\-help|\-h \fP\fI\fP
 .PP
 \fBbtrfs\fP \fB<command> \-\-help \fP\fI\fP
@@ -319,6 +325,25 @@ skip the path resolving and print the inodes instead
 .IP -v 5
 verbose mode. print count of returned paths and all ioctl() return values
 .RE
+.TP
+
+\fBmount-option set\fP \fI[<+/-/=><option>,...]...]\fP \fI<device>\fP
+With some operators \fB+\fP,\fB-\fP,\fB=\fP and some options,
+set default mount options to the \fI<device>\fP.
+These \fB+\fP,\fB-\fP,\fB=\fP operators mean like \fBchmod\fP operators.
+The operator \fB+\fP causes the selected mount options to be added to existing
+default mount options of the \fI<device>\fP; \fB-\fP causes them to be removed;
+and \fB=\fP causes them to be added and causes unmentioned options to be removed.
+Without options, print default mount options of the \fI<device>\fR.
+.TP
+
+\fBmount-option get\fP \fI<device>\fP
+Print default mount options of the \fI<device>\fR.
+.TP
+
+\fBmount-option clear\fP \fI<device>\fP
+Clear default mount options of the \fI<device>\fR.
+.TP
 
 .SH EXIT STATUS
 \fBbtrfs\fR returns a zero exist status if it succeeds. Non zero is returned in
-- 
1.7.7.6



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/4] btrfs: make subroutine __btrfs_parse_options
  2012-10-12  3:18 [PATCH v2 0/4] Btrfs: set mount options permanently Hidetoshi Seto
  2012-10-12  3:24 ` [PATCH v2 1/4] Btrfs-progs: add mount-option command Hidetoshi Seto
  2012-10-12  3:24 ` [PATCH v2 2/4] Btrfs-progs: add mount-option command man page Hidetoshi Seto
@ 2012-10-12  3:24 ` Hidetoshi Seto
  2012-10-12  3:25 ` [PATCH v2 4/4] btrfs: support default mount options Hidetoshi Seto
  3 siblings, 0 replies; 8+ messages in thread
From: Hidetoshi Seto @ 2012-10-12  3:24 UTC (permalink / raw)
  To: linux-btrfs

Separate long switch statement to be reused.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
 fs/btrfs/super.c |  431 +++++++++++++++++++++++++++---------------------------
 1 files changed, 214 insertions(+), 217 deletions(-)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 83d6f9f..d51aaee 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -349,6 +349,214 @@ static match_table_t tokens = {
 	{Opt_err, NULL},
 };
 
+static int __btrfs_parse_options(struct btrfs_fs_info *info, int token,
+				 substring_t *args)
+{
+	bool compress_force = false;
+	char *compress_type;
+	char *num;
+	int intarg;
+
+	switch (token) {
+	case Opt_degraded:
+		pr_info("btrfs: allowing degraded mounts\n");
+		btrfs_set_opt(info->mount_opt, DEGRADED);
+		break;
+	case Opt_subvol:
+	case Opt_subvolid:
+	case Opt_subvolrootid:
+	case Opt_device:
+		/*
+		 * These are parsed by btrfs_parse_early_options
+		 * and can be happily ignored here.
+		 */
+		break;
+	case Opt_nodatasum:
+		pr_info("btrfs: setting nodatasum\n");
+		btrfs_set_opt(info->mount_opt, NODATASUM);
+		break;
+	case Opt_nodatacow:
+		pr_info("btrfs: setting nodatacow\n");
+		btrfs_set_opt(info->mount_opt, NODATACOW);
+		btrfs_set_opt(info->mount_opt, NODATASUM);
+		break;
+	case Opt_compress_force:
+	case Opt_compress_force_type:
+		compress_force = true;
+	case Opt_compress:
+	case Opt_compress_type:
+		if (token == Opt_compress ||
+		    token == Opt_compress_force ||
+		    strcmp(args[0].from, "zlib") == 0) {
+			compress_type = "zlib";
+			info->compress_type = BTRFS_COMPRESS_ZLIB;
+			btrfs_set_opt(info->mount_opt, COMPRESS);
+		} else if (strcmp(args[0].from, "lzo") == 0) {
+			compress_type = "lzo";
+			info->compress_type = BTRFS_COMPRESS_LZO;
+			btrfs_set_opt(info->mount_opt, COMPRESS);
+			btrfs_set_fs_incompat(info, COMPRESS_LZO);
+		} else if (strncmp(args[0].from, "no", 2) == 0) {
+			compress_type = "no";
+			info->compress_type = BTRFS_COMPRESS_NONE;
+			btrfs_clear_opt(info->mount_opt, COMPRESS);
+			btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
+			compress_force = false;
+		} else
+			return -EINVAL;
+
+		if (compress_force) {
+			btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
+			pr_info("btrfs: force %s compression\n", compress_type);
+		} else
+			pr_info("btrfs: use %s compression\n", compress_type);
+		break;
+	case Opt_ssd:
+		pr_info("btrfs: use ssd allocation scheme\n");
+		btrfs_set_opt(info->mount_opt, SSD);
+		break;
+	case Opt_ssd_spread:
+		pr_info("btrfs: use spread ssd allocation scheme\n");
+		btrfs_set_opt(info->mount_opt, SSD);
+		btrfs_set_opt(info->mount_opt, SSD_SPREAD);
+		break;
+	case Opt_nossd:
+		pr_info("btrfs: not using ssd allocation scheme\n");
+		btrfs_set_opt(info->mount_opt, NOSSD);
+		btrfs_clear_opt(info->mount_opt, SSD);
+		btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
+		break;
+	case Opt_nobarrier:
+		pr_info("btrfs: turning off barriers\n");
+		btrfs_set_opt(info->mount_opt, NOBARRIER);
+		break;
+	case Opt_thread_pool:
+		intarg = 0;
+		match_int(&args[0], &intarg);
+		if (intarg)
+			info->thread_pool_size = intarg;
+		break;
+	case Opt_max_inline:
+		num = match_strdup(&args[0]);
+		if (num) {
+			info->max_inline = memparse(num, NULL);
+			kfree(num);
+
+			if (info->max_inline) {
+				info->max_inline = max_t(u64,
+					info->max_inline,
+					info->tree_root->sectorsize);
+			}
+			pr_info("btrfs: max_inline at %llu\n",
+				(unsigned long long)info->max_inline);
+		}
+		break;
+	case Opt_alloc_start:
+		num = match_strdup(&args[0]);
+		if (num) {
+			info->alloc_start = memparse(num, NULL);
+			kfree(num);
+			pr_info("btrfs: allocations start at %llu\n",
+				(unsigned long long)info->alloc_start);
+		}
+		break;
+	case Opt_noacl:
+		info->sb->s_flags &= ~MS_POSIXACL;
+		break;
+	case Opt_notreelog:
+		pr_info("btrfs: disabling tree log\n");
+		btrfs_set_opt(info->mount_opt, NOTREELOG);
+		break;
+	case Opt_flushoncommit:
+		pr_info("btrfs: turning on flush-on-commit\n");
+		btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
+		break;
+	case Opt_ratio:
+		intarg = 0;
+		match_int(&args[0], &intarg);
+		if (intarg) {
+			info->metadata_ratio = intarg;
+			pr_info("btrfs: metadata ratio %d\n",
+				info->metadata_ratio);
+		}
+		break;
+	case Opt_discard:
+		btrfs_set_opt(info->mount_opt, DISCARD);
+		break;
+	case Opt_space_cache:
+		btrfs_set_opt(info->mount_opt, SPACE_CACHE);
+		break;
+	case Opt_no_space_cache:
+		pr_info("btrfs: disabling disk space caching\n");
+		btrfs_clear_opt(info->mount_opt, SPACE_CACHE);
+		break;
+	case Opt_inode_cache:
+		pr_info("btrfs: enabling inode map caching\n");
+		btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE);
+		break;
+	case Opt_clear_cache:
+		pr_info("btrfs: force clearing of disk cache\n");
+		btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
+		break;
+	case Opt_user_subvol_rm_allowed:
+		btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED);
+		break;
+	case Opt_enospc_debug:
+		btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG);
+		break;
+	case Opt_defrag:
+		pr_info("btrfs: enabling auto defrag");
+		btrfs_set_opt(info->mount_opt, AUTO_DEFRAG);
+		break;
+	case Opt_recovery:
+		pr_info("btrfs: enabling auto recovery");
+		btrfs_set_opt(info->mount_opt, RECOVERY);
+		break;
+	case Opt_skip_balance:
+		btrfs_set_opt(info->mount_opt, SKIP_BALANCE);
+		break;
+#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
+	case Opt_check_integrity_including_extent_data:
+		pr_info("btrfs: enabling check integrity including extent data\n");
+		btrfs_set_opt(info->mount_opt,
+			      CHECK_INTEGRITY_INCLUDING_EXTENT_DATA);
+		btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY);
+		break;
+	case Opt_check_integrity:
+		pr_info("btrfs: enabling check integrity\n");
+		btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY);
+		break;
+	case Opt_check_integrity_print_mask:
+		intarg = 0;
+		match_int(&args[0], &intarg);
+		if (intarg) {
+			info->check_integrity_print_mask = intarg;
+			pr_info("btrfs: check_integrity_print_mask 0x%x\n",
+				info->check_integrity_print_mask);
+		}
+		break;
+#else
+	case Opt_check_integrity_including_extent_data:
+	case Opt_check_integrity:
+	case Opt_check_integrity_print_mask:
+		pr_err("btrfs: support for check_integrity* not compiled in!\n");
+		return -EINVAL;
+#endif
+	case Opt_fatal_errors:
+		if (strcmp(args[0].from, "panic") == 0)
+			btrfs_set_opt(info->mount_opt, PANIC_ON_FATAL_ERROR);
+		else if (strcmp(args[0].from, "bug") == 0)
+			btrfs_clear_opt(info->mount_opt, PANIC_ON_FATAL_ERROR);
+		else
+			return -EINVAL;
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 /*
  * Regular mount options parser.  Everything that is needed only when
  * reading in a new superblock is parsed here.
@@ -358,12 +566,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
 {
 	struct btrfs_fs_info *info = root->fs_info;
 	substring_t args[MAX_OPT_ARGS];
-	char *p, *num, *orig = NULL;
+	char *p, *orig = NULL;
 	u64 cache_gen;
-	int intarg;
 	int ret = 0;
-	char *compress_type;
-	bool compress_force = false;
 
 	cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);
 	if (cache_gen)
@@ -388,222 +593,14 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
 			continue;
 
 		token = match_token(p, tokens, args);
-		switch (token) {
-		case Opt_degraded:
-			printk(KERN_INFO "btrfs: allowing degraded mounts\n");
-			btrfs_set_opt(info->mount_opt, DEGRADED);
-			break;
-		case Opt_subvol:
-		case Opt_subvolid:
-		case Opt_subvolrootid:
-		case Opt_device:
-			/*
-			 * These are parsed by btrfs_parse_early_options
-			 * and can be happily ignored here.
-			 */
-			break;
-		case Opt_nodatasum:
-			printk(KERN_INFO "btrfs: setting nodatasum\n");
-			btrfs_set_opt(info->mount_opt, NODATASUM);
-			break;
-		case Opt_nodatacow:
-			printk(KERN_INFO "btrfs: setting nodatacow\n");
-			btrfs_set_opt(info->mount_opt, NODATACOW);
-			btrfs_set_opt(info->mount_opt, NODATASUM);
-			break;
-		case Opt_compress_force:
-		case Opt_compress_force_type:
-			compress_force = true;
-		case Opt_compress:
-		case Opt_compress_type:
-			if (token == Opt_compress ||
-			    token == Opt_compress_force ||
-			    strcmp(args[0].from, "zlib") == 0) {
-				compress_type = "zlib";
-				info->compress_type = BTRFS_COMPRESS_ZLIB;
-				btrfs_set_opt(info->mount_opt, COMPRESS);
-			} else if (strcmp(args[0].from, "lzo") == 0) {
-				compress_type = "lzo";
-				info->compress_type = BTRFS_COMPRESS_LZO;
-				btrfs_set_opt(info->mount_opt, COMPRESS);
-				btrfs_set_fs_incompat(info, COMPRESS_LZO);
-			} else if (strncmp(args[0].from, "no", 2) == 0) {
-				compress_type = "no";
-				info->compress_type = BTRFS_COMPRESS_NONE;
-				btrfs_clear_opt(info->mount_opt, COMPRESS);
-				btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
-				compress_force = false;
-			} else {
-				ret = -EINVAL;
-				goto out;
-			}
-
-			if (compress_force) {
-				btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
-				pr_info("btrfs: force %s compression\n",
-					compress_type);
-			} else
-				pr_info("btrfs: use %s compression\n",
-					compress_type);
-			break;
-		case Opt_ssd:
-			printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
-			btrfs_set_opt(info->mount_opt, SSD);
-			break;
-		case Opt_ssd_spread:
-			printk(KERN_INFO "btrfs: use spread ssd "
-			       "allocation scheme\n");
-			btrfs_set_opt(info->mount_opt, SSD);
-			btrfs_set_opt(info->mount_opt, SSD_SPREAD);
-			break;
-		case Opt_nossd:
-			printk(KERN_INFO "btrfs: not using ssd allocation "
-			       "scheme\n");
-			btrfs_set_opt(info->mount_opt, NOSSD);
-			btrfs_clear_opt(info->mount_opt, SSD);
-			btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
-			break;
-		case Opt_nobarrier:
-			printk(KERN_INFO "btrfs: turning off barriers\n");
-			btrfs_set_opt(info->mount_opt, NOBARRIER);
-			break;
-		case Opt_thread_pool:
-			intarg = 0;
-			match_int(&args[0], &intarg);
-			if (intarg)
-				info->thread_pool_size = intarg;
-			break;
-		case Opt_max_inline:
-			num = match_strdup(&args[0]);
-			if (num) {
-				info->max_inline = memparse(num, NULL);
-				kfree(num);
-
-				if (info->max_inline) {
-					info->max_inline = max_t(u64,
-						info->max_inline,
-						root->sectorsize);
-				}
-				printk(KERN_INFO "btrfs: max_inline at %llu\n",
-					(unsigned long long)info->max_inline);
-			}
-			break;
-		case Opt_alloc_start:
-			num = match_strdup(&args[0]);
-			if (num) {
-				info->alloc_start = memparse(num, NULL);
-				kfree(num);
-				printk(KERN_INFO
-					"btrfs: allocations start at %llu\n",
-					(unsigned long long)info->alloc_start);
-			}
-			break;
-		case Opt_noacl:
-			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
-			break;
-		case Opt_notreelog:
-			printk(KERN_INFO "btrfs: disabling tree log\n");
-			btrfs_set_opt(info->mount_opt, NOTREELOG);
-			break;
-		case Opt_flushoncommit:
-			printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
-			btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
-			break;
-		case Opt_ratio:
-			intarg = 0;
-			match_int(&args[0], &intarg);
-			if (intarg) {
-				info->metadata_ratio = intarg;
-				printk(KERN_INFO "btrfs: metadata ratio %d\n",
-				       info->metadata_ratio);
-			}
-			break;
-		case Opt_discard:
-			btrfs_set_opt(info->mount_opt, DISCARD);
-			break;
-		case Opt_space_cache:
-			btrfs_set_opt(info->mount_opt, SPACE_CACHE);
-			break;
-		case Opt_no_space_cache:
-			printk(KERN_INFO "btrfs: disabling disk space caching\n");
-			btrfs_clear_opt(info->mount_opt, SPACE_CACHE);
-			break;
-		case Opt_inode_cache:
-			printk(KERN_INFO "btrfs: enabling inode map caching\n");
-			btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE);
-			break;
-		case Opt_clear_cache:
-			printk(KERN_INFO "btrfs: force clearing of disk cache\n");
-			btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
-			break;
-		case Opt_user_subvol_rm_allowed:
-			btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED);
-			break;
-		case Opt_enospc_debug:
-			btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG);
-			break;
-		case Opt_defrag:
-			printk(KERN_INFO "btrfs: enabling auto defrag");
-			btrfs_set_opt(info->mount_opt, AUTO_DEFRAG);
-			break;
-		case Opt_recovery:
-			printk(KERN_INFO "btrfs: enabling auto recovery");
-			btrfs_set_opt(info->mount_opt, RECOVERY);
-			break;
-		case Opt_skip_balance:
-			btrfs_set_opt(info->mount_opt, SKIP_BALANCE);
-			break;
-#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
-		case Opt_check_integrity_including_extent_data:
-			printk(KERN_INFO "btrfs: enabling check integrity"
-			       " including extent data\n");
-			btrfs_set_opt(info->mount_opt,
-				      CHECK_INTEGRITY_INCLUDING_EXTENT_DATA);
-			btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY);
-			break;
-		case Opt_check_integrity:
-			printk(KERN_INFO "btrfs: enabling check integrity\n");
-			btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY);
-			break;
-		case Opt_check_integrity_print_mask:
-			intarg = 0;
-			match_int(&args[0], &intarg);
-			if (intarg) {
-				info->check_integrity_print_mask = intarg;
-				printk(KERN_INFO "btrfs:"
-				       " check_integrity_print_mask 0x%x\n",
-				       info->check_integrity_print_mask);
-			}
-			break;
-#else
-		case Opt_check_integrity_including_extent_data:
-		case Opt_check_integrity:
-		case Opt_check_integrity_print_mask:
-			printk(KERN_ERR "btrfs: support for check_integrity*"
-			       " not compiled in!\n");
-			ret = -EINVAL;
-			goto out;
-#endif
-		case Opt_fatal_errors:
-			if (strcmp(args[0].from, "panic") == 0)
-				btrfs_set_opt(info->mount_opt,
-					      PANIC_ON_FATAL_ERROR);
-			else if (strcmp(args[0].from, "bug") == 0)
-				btrfs_clear_opt(info->mount_opt,
-					      PANIC_ON_FATAL_ERROR);
-			else {
-				ret = -EINVAL;
-				goto out;
-			}
-			break;
-		case Opt_err:
-			printk(KERN_INFO "btrfs: unrecognized mount option "
-			       "'%s'\n", p);
+		if (token == Opt_err) {
+			pr_info("btrfs: unrecognized mount option '%s'\n", p);
 			ret = -EINVAL;
-			goto out;
-		default:
 			break;
 		}
+		ret = __btrfs_parse_options(info, token, args);
+		if (ret)
+			break;
 	}
 out:
 	if (!ret && btrfs_test_opt(root, SPACE_CACHE))
-- 
1.7.7.6



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/4] btrfs: support default mount options
  2012-10-12  3:18 [PATCH v2 0/4] Btrfs: set mount options permanently Hidetoshi Seto
                   ` (2 preceding siblings ...)
  2012-10-12  3:24 ` [PATCH v2 3/4] btrfs: make subroutine __btrfs_parse_options Hidetoshi Seto
@ 2012-10-12  3:25 ` Hidetoshi Seto
  3 siblings, 0 replies; 8+ messages in thread
From: Hidetoshi Seto @ 2012-10-12  3:25 UTC (permalink / raw)
  To: linux-btrfs

Make space to save default mount options in super block.
Parse saved default mount options first and then parse mount options given
when the file system is mounted.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
 fs/btrfs/ctree.h |    7 ++++++-
 fs/btrfs/super.c |   16 ++++++++++++++--
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 0d195b5..eea6bd0 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -461,8 +461,11 @@ struct btrfs_super_block {
 
 	__le64 cache_generation;
 
+	/* default mount options */
+	__le64 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__));
@@ -2581,6 +2584,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)
 {
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index d51aaee..1cadf0e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -567,13 +567,25 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
 	struct btrfs_fs_info *info = root->fs_info;
 	substring_t args[MAX_OPT_ARGS];
 	char *p, *orig = NULL;
-	u64 cache_gen;
+	u64 cache_gen, default_opt;
 	int ret = 0;
 
-	cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);
+	cache_gen = btrfs_super_cache_generation(info->super_copy);
 	if (cache_gen)
 		btrfs_set_opt(info->mount_opt, SPACE_CACHE);
 
+	default_opt = btrfs_super_default_mount_opt(info->super_copy);
+	if (default_opt) {
+		int token;
+		for (token = 0; token < Opt_err; token++) {
+			if (default_opt & (1ul << token)) {
+				ret = __btrfs_parse_options(info, token, args);
+				if (ret)
+					return ret;
+			}
+		}
+	}
+
 	if (!options)
 		goto out;
 
-- 
1.7.7.6



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/4] Btrfs-progs: add mount-option command
  2012-10-12  3:24 ` [PATCH v2 1/4] Btrfs-progs: add mount-option command Hidetoshi Seto
@ 2012-10-12  5:35   ` Tsutomu Itoh
  2012-10-12  8:21   ` Tsutomu Itoh
  1 sibling, 0 replies; 8+ messages in thread
From: Tsutomu Itoh @ 2012-10-12  5:35 UTC (permalink / raw)
  To: Hidetoshi Seto; +Cc: linux-btrfs

Hi, Seto-san,

(2012/10/12 12:24), Hidetoshi Seto wrote:
> This patch adds mount-option command that can set/get/clear default
> mount options.
> 
> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
> ---
>   Makefile             |    4 +-
>   btrfs-parse-mntopt.c |  109 +++++++++++++++++++++++++++++
>   btrfs-parse-mntopt.h |   66 ++++++++++++++++++
>   btrfs.c              |    1 +
>   cmds-mount.c         |  185 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   commands.h           |    2 +
>   ctree.h              |    7 ++-
>   7 files changed, 371 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 4894903..c25d982 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -5,10 +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 qgroup.o
> +	  send-stream.o send-utils.o qgroup.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-quota.o cmds-qgroup.o
> +	       cmds-quota.o cmds-qgroup.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..66a924d
> --- /dev/null
> +++ b/btrfs-parse-mntopt.c
> @@ -0,0 +1,109 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include "ctree.h"
> +#include "btrfs-parse-mntopt.h"
> +
> +void btrfs_parse_string2mntopt(u64 *optval, int optnum, char **options)
> +{
> +	char *p, *opts;
> +	int i, j;
> +	u64 newval = *optval;
> +	char overwrite = 0;
> +
> +	for (i = 0; i < optnum; i++) {
> +		char *token, *save_ptr;
> +		char revert = 0;
> +		u64 orders = 0;
> +
> +		opts = options[i];
> +
> +		switch (*opts) {
> +		case '=':
> +			if (overwrite) {
> +				fprintf(stderr, "'=' operator may only be specified once.\n");
> +				return;
> +			}
> +			if (i) {
> +				fprintf(stderr, "cannot use operator '=' with '+/-'.\n");
> +				return;
> +			}
> +			if (!*(opts + 1)) {
> +				fprintf(stderr, "no options after '='.\n");
> +				return;
> +			}
> +			overwrite = 1;
> +			opts++;
> +			break;
> +		case '-':
> +			revert = 1;
> +		case '+':
> +			if (overwrite) {
> +				fprintf(stderr, "cannot use operator '=' with '+/-'.\n");
> +				return;
> +			}
> +			if (!*(opts + 1)) {
> +				fprintf(stderr, "no options after '%c'.\n", *opts);
> +				return;
> +			}
> +			opts++;
> +			break;
> +		default:
> +			fprintf(stderr, "options must be specified with '+/-/='.\n");
> +			return;
> +		}
> +
> +		for (token = strtok_r(opts, ",", &save_ptr); token != NULL;
> +		     token = strtok_r(NULL, ",", &save_ptr)) {
> +			char *arg;
> +
> +			arg = strchr(token, '=');
> +			if (arg) {
> +				/* TBD: compress=<type> */
> +				fprintf(stderr, "format 'option=arg' is not supported.\n");
> +				return;
> +			}
> +
> +			for (j = 0; tokens[j].pattern != NULL; j++) {
> +				if (!strcmp(token, tokens[j].pattern)) {
> +					orders |= (1 << tokens[j].token);
> +					break;
> +				}
> +			}
> +			if (!tokens[j].pattern) {
> +				fprintf(stderr, "unknown option '%s'.\n", token);
> +				printf("supported options : ");
> +				btrfs_parse_mntopt2string(-1);
> +				return;
> +			}
> +		}
> +
> +		if (overwrite)
> +			newval = orders;
> +		else if (revert)
> +			newval &= ~orders;
> +		else
> +			newval |= orders;
> +	}
> +
> +	*optval = newval;
> +}
> +
> +void btrfs_parse_mntopt2string(u64 optval)
> +{
> +	if (!optval)
> +		printf("no default options\n");
> +	else {
> +		int i, cont = 0;
> +
> +		for (i = 0; tokens[i].pattern != NULL; i++) {
> +			if (optval & (1 << tokens[i].token)) {
> +				if (cont)
> +					printf(",");
> +				printf("%s", tokens[i].pattern);
> +				cont = 1;
> +			}
> +		}
> +		printf("\n");
> +	}
> +}
> diff --git a/btrfs-parse-mntopt.h b/btrfs-parse-mntopt.h
> new file mode 100644
> index 0000000..784a942
> --- /dev/null
> +++ b/btrfs-parse-mntopt.h
> @@ -0,0 +1,66 @@

Please add
 #ifndef _BTRFS_PARSE_MNTOPT_H
 #define _BTRFS_PARSE_MNTOPT_H

> +/* btrfs-parse-mntopt.h */
> +
> +struct match_token {
> +	int token;
> +	const char *pattern;
> +};
> +
> +typedef struct match_token match_table_t[];
> +
> +/* copy & pasted from super.c */
> +enum {
> +	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
> +	Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
> +	Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
> +	Opt_compress_type, Opt_compress_force, Opt_compress_force_type,
> +	Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
> +	Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
> +	Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_inode_cache,
> +	Opt_no_space_cache, Opt_recovery, Opt_skip_balance,
> +	Opt_check_integrity, Opt_check_integrity_including_extent_data,
> +	Opt_check_integrity_print_mask, Opt_fatal_errors,
> +	Opt_err,
> +};
> +
> +static match_table_t tokens = {
> +/*	{Opt_degraded, "degraded"},		... never be default */
> +/*	{Opt_subvol, "subvol=%s"},		... not supported */
> +/*	{Opt_subvolid, "subvolid=%d"},		... not supported */
> +/*	{Opt_device, "device=%s"},		... not supported */
> +	{Opt_nodatasum, "nodatasum"},
> +	{Opt_nodatacow, "nodatacow"},
> +	{Opt_nobarrier, "nobarrier"},
> +/*	{Opt_max_inline, "max_inline=%s"},	... not supported */
> +/*	{Opt_alloc_start, "alloc_start=%s"},	... not supported */
> +/*	{Opt_thread_pool, "thread_pool=%d"},	... not supported */
> +	{Opt_compress, "compress"},
> +/*	{Opt_compress_type, "compress=%s"},		... TBD? */
> +	{Opt_compress_force, "compress-force"},
> +/*	{Opt_compress_force_type, "compress-force=%s"},	... TBD? */
> +	{Opt_ssd, "ssd"},
> +	{Opt_ssd_spread, "ssd_spread"},
> +	{Opt_nossd, "nossd"},
> +	{Opt_noacl, "noacl"},
> +	{Opt_notreelog, "notreelog"},
> +	{Opt_flushoncommit, "flushoncommit"},
> +/*	{Opt_ratio, "metadata_ratio=%d"},	... not supported */
> +	{Opt_discard, "discard"},
> +	{Opt_space_cache, "space_cache"},
> +	{Opt_clear_cache, "clear_cache"},
> +	{Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},
> +/*	{Opt_enospc_debug, "enospc_debug"},	... never be default */
> +/*	{Opt_subvolrootid, "subvolrootid=%d"},	... not supported */
> +	{Opt_defrag, "autodefrag"},
> +	{Opt_inode_cache, "inode_cache"},
> +	{Opt_no_space_cache, "nospace_cache"},
> +	{Opt_recovery, "recovery"},
> +	{Opt_skip_balance, "skip_balance"},
> +	{Opt_check_integrity, "check_int"},
> +	{Opt_check_integrity_including_extent_data, "check_int_data"},
> +/*	{Opt_check_integrity_print_mask, "check_int_print_mask=%d"},
> +	{Opt_fatal_errors, "fatal_errors=%s"},	... not supported */
> +	{Opt_err, NULL},	/* must be end */
> +};
> +
> +void btrfs_parse_string2mntopt(u64 *optval, int optnum, char **options);
> +void btrfs_parse_mntopt2string(u64 optval);

 #endif /* _BTRFS_PARSE_MNTOPT_H */

Thanks,
Tsutomu

> diff --git a/btrfs.c b/btrfs.c
> index a229cee..608869d 100644
> --- a/btrfs.c
> +++ b/btrfs.c
> @@ -250,6 +250,7 @@ const struct cmd_group btrfs_cmd_group = {
>   		{ "receive", cmd_receive, NULL, &receive_cmd_group, 0 },
>   		{ "quota", cmd_quota, NULL, &quota_cmd_group, 0 },
>   		{ "qgroup", cmd_qgroup, NULL, &qgroup_cmd_group, 0 },
> +		{ "mount-option", cmd_mount, NULL, &mount_cmd_group, 0 },
>   		{ "help", cmd_help, cmd_help_usage, NULL, 0 },
>   		{ "version", cmd_version, cmd_version_usage, NULL, 0 },
>   		{ 0, 0, 0, 0, 0 }
> diff --git a/cmds-mount.c b/cmds-mount.c
> new file mode 100644
> index 0000000..1752019
> --- /dev/null
> +++ b/cmds-mount.c
> @@ -0,0 +1,185 @@
> +/*
> + * 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 int mount_check_device(char *device)
> +{
> +	int ret;
> +
> +	ret = check_mounted(device);
> +	if (ret == 1) {
> +		fprintf(stderr, "%s is mounted\n", device);
> +		return 1;
> +	}
> +	if (ret < 0) {
> +		fprintf(stderr, "error checking %s mount status with %d(%s)\n",
> +			device, ret, strerror(-1*ret));
> +		return 1;
> +	}
> +	return 0;
> +}
> +
> +static int mount_set_common(char *device, int numopts, char **options)
> +{
> +	struct btrfs_root *root;
> +	struct btrfs_trans_handle *trans;
> +	u64 optval = 0;
> +	int ret;
> +
> +	root = open_ctree(device, 0, 1);
> +	if (!root) {
> +		fprintf(stderr, "error opening ctree of %s\n", device);
> +		return 1;
> +	}
> +
> +	if (numopts) {
> +		optval = btrfs_super_default_mount_opt(&root->fs_info->super_copy);
> +		btrfs_parse_string2mntopt(&optval, numopts, options);
> +	}
> +
> +	trans = btrfs_start_transaction(root, 1);
> +	btrfs_set_super_default_mount_opt(&root->fs_info->super_copy, optval);
> +	ret = btrfs_commit_transaction(trans, root);
> +
> +	close_ctree(root);
> +
> +	return ret;
> +}
> +
> +static int mount_show_common(char *device)
> +{
> +	struct btrfs_root *root;
> +	u64 def_opt;
> +
> +	root = open_ctree(device, 0, 0);
> +	if (!root) {
> +		fprintf(stderr, "error opening ctree of %s\n", device);
> +		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_set_mntopt_usage[] = {
> +	"btrfs mount-option set [[+-=]<mount-option>,...] <device>",
> +	"Set default mount options",
> +	NULL
> +};
> +
> +static int cmd_set_mntopt(int argc, char **argv)
> +{
> +	char *device;
> +
> +	if (check_argc_min(argc, 2)) {
> +		usage(cmd_set_mntopt_usage);
> +		return 1;
> +	}
> +
> +	device = argv[argc - 1];
> +	if (mount_check_device(device))
> +		return 1;
> +
> +	if (argc == 2) {
> +		/* get mount option */
> +		return mount_show_common(device);
> +	}
> +	/* set mount option */
> +	/*
> +	 * Note:
> +	 *	argv[0] = "btrfs mount-option set"
> +	 *	argv[*] = <options>
> +	 *	argv[n] = <device>
> +	 */
> +	return mount_set_common(device, argc - 2, &argv[1]);
> +}
> +
> +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)
> +{
> +	char *device;
> +
> +	if (check_argc_exact(argc, 2)) {
> +		usage(cmd_get_mntopt_usage);
> +		return 1;
> +	}
> +
> +	device = argv[argc - 1];
> +	if (mount_check_device(device))
> +		return 1;
> +
> +	return mount_show_common(device);
> +};
> +
> +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)
> +{
> +	char *device;
> +
> +	if (check_argc_exact(argc, 2)) {
> +		usage(cmd_clear_mntopt_usage);
> +		return 1;
> +	}
> +
> +	device = argv[argc - 1];
> +	if (mount_check_device(device))
> +		return 1;
> +
> +	return mount_set_common(device, 0, NULL);
> +};
> +
> +static const char * const mount_cmd_group_usage[] = {
> +	"btrfs mount-option <command> [<args>]",
> +	NULL
> +};
> +
> +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 bb6d2dd..fea30fd 100644
> --- a/commands.h
> +++ b/commands.h
> @@ -92,6 +92,7 @@ extern const struct cmd_group send_cmd_group;
>   extern const struct cmd_group receive_cmd_group;
>   extern const struct cmd_group quota_cmd_group;
>   extern const struct cmd_group qgroup_cmd_group;
> +extern const struct cmd_group mount_cmd_group;
>   
>   int cmd_subvolume(int argc, char **argv);
>   int cmd_filesystem(int argc, char **argv);
> @@ -103,6 +104,7 @@ int cmd_send(int argc, char **argv);
>   int cmd_receive(int argc, char **argv);
>   int cmd_quota(int argc, char **argv);
>   int cmd_qgroup(int argc, char **argv);
> +int cmd_mount(int argc, char **argv);
>   
>   /* subvolume exported functions */
>   int test_issubvolume(char *path);
> diff --git a/ctree.h b/ctree.h
> index 7f55229..363a118 100644
> --- a/ctree.h
> +++ b/ctree.h
> @@ -402,8 +402,11 @@ struct btrfs_super_block {
>   
>   	__le64 cache_generation;
>   
> +	/* default mount options */
> +	__le64 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__));
> @@ -1820,6 +1823,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)
>   {
> 



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/4] Btrfs-progs: add mount-option command
  2012-10-12  3:24 ` [PATCH v2 1/4] Btrfs-progs: add mount-option command Hidetoshi Seto
  2012-10-12  5:35   ` Tsutomu Itoh
@ 2012-10-12  8:21   ` Tsutomu Itoh
  1 sibling, 0 replies; 8+ messages in thread
From: Tsutomu Itoh @ 2012-10-12  8:21 UTC (permalink / raw)
  To: Hidetoshi Seto; +Cc: linux-btrfs

Hi,

(2012/10/12 12:24), Hidetoshi Seto wrote:
> This patch adds mount-option command that can set/get/clear default
> mount options.
> 
> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
> ---
>   Makefile             |    4 +-
>   btrfs-parse-mntopt.c |  109 +++++++++++++++++++++++++++++
>   btrfs-parse-mntopt.h |   66 ++++++++++++++++++
>   btrfs.c              |    1 +
>   cmds-mount.c         |  185 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   commands.h           |    2 +
>   ctree.h              |    7 ++-
>   7 files changed, 371 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 4894903..c25d982 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -5,10 +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 qgroup.o
> +	  send-stream.o send-utils.o qgroup.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-quota.o cmds-qgroup.o
> +	       cmds-quota.o cmds-qgroup.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..66a924d
> --- /dev/null
> +++ b/btrfs-parse-mntopt.c
> @@ -0,0 +1,109 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include "ctree.h"
> +#include "btrfs-parse-mntopt.h"
> +
> +void btrfs_parse_string2mntopt(u64 *optval, int optnum, char **options)
> +{
> +	char *p, *opts;
> +	int i, j;
> +	u64 newval = *optval;
> +	char overwrite = 0;
> +
> +	for (i = 0; i < optnum; i++) {
> +		char *token, *save_ptr;
> +		char revert = 0;
> +		u64 orders = 0;
> +
> +		opts = options[i];
> +
> +		switch (*opts) {
> +		case '=':
> +			if (overwrite) {
> +				fprintf(stderr, "'=' operator may only be specified once.\n");
> +				return;
> +			}
> +			if (i) {
> +				fprintf(stderr, "cannot use operator '=' with '+/-'.\n");
> +				return;
> +			}
> +			if (!*(opts + 1)) {
> +				fprintf(stderr, "no options after '='.\n");
> +				return;
> +			}
> +			overwrite = 1;
> +			opts++;
> +			break;
> +		case '-':
> +			revert = 1;
> +		case '+':
> +			if (overwrite) {
> +				fprintf(stderr, "cannot use operator '=' with '+/-'.\n");
> +				return;
> +			}
> +			if (!*(opts + 1)) {
> +				fprintf(stderr, "no options after '%c'.\n", *opts);
> +				return;
> +			}
> +			opts++;
> +			break;
> +		default:
> +			fprintf(stderr, "options must be specified with '+/-/='.\n");
> +			return;
> +		}
> +
> +		for (token = strtok_r(opts, ",", &save_ptr); token != NULL;
> +		     token = strtok_r(NULL, ",", &save_ptr)) {
> +			char *arg;
> +
> +			arg = strchr(token, '=');
> +			if (arg) {
> +				/* TBD: compress=<type> */
> +				fprintf(stderr, "format 'option=arg' is not supported.\n");
> +				return;
> +			}
> +
> +			for (j = 0; tokens[j].pattern != NULL; j++) {
> +				if (!strcmp(token, tokens[j].pattern)) {
> +					orders |= (1 << tokens[j].token);
> +					break;
> +				}
> +			}
> +			if (!tokens[j].pattern) {
> +				fprintf(stderr, "unknown option '%s'.\n", token);
> +				printf("supported options : ");
> +				btrfs_parse_mntopt2string(-1);
> +				return;
> +			}
> +		}
> +
> +		if (overwrite)
> +			newval = orders;
> +		else if (revert)
> +			newval &= ~orders;
> +		else
> +			newval |= orders;
> +	}
> +
> +	*optval = newval;
> +}
> +
> +void btrfs_parse_mntopt2string(u64 optval)
> +{
> +	if (!optval)
> +		printf("no default options\n");
> +	else {
> +		int i, cont = 0;
> +
> +		for (i = 0; tokens[i].pattern != NULL; i++) {
> +			if (optval & (1 << tokens[i].token)) {
> +				if (cont)
> +					printf(",");
> +				printf("%s", tokens[i].pattern);
> +				cont = 1;
> +			}
> +		}
> +		printf("\n");
> +	}
> +}
> diff --git a/btrfs-parse-mntopt.h b/btrfs-parse-mntopt.h
> new file mode 100644
> index 0000000..784a942
> --- /dev/null
> +++ b/btrfs-parse-mntopt.h
> @@ -0,0 +1,66 @@
> +/* btrfs-parse-mntopt.h */
> +
> +struct match_token {
> +	int token;
> +	const char *pattern;
> +};
> +
> +typedef struct match_token match_table_t[];
> +
> +/* copy & pasted from super.c */
> +enum {
> +	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
> +	Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
> +	Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
> +	Opt_compress_type, Opt_compress_force, Opt_compress_force_type,
> +	Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
> +	Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
> +	Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_inode_cache,
> +	Opt_no_space_cache, Opt_recovery, Opt_skip_balance,
> +	Opt_check_integrity, Opt_check_integrity_including_extent_data,
> +	Opt_check_integrity_print_mask, Opt_fatal_errors,
> +	Opt_err,
> +};
> +
> +static match_table_t tokens = {
> +/*	{Opt_degraded, "degraded"},		... never be default */
> +/*	{Opt_subvol, "subvol=%s"},		... not supported */
> +/*	{Opt_subvolid, "subvolid=%d"},		... not supported */
> +/*	{Opt_device, "device=%s"},		... not supported */
> +	{Opt_nodatasum, "nodatasum"},
> +	{Opt_nodatacow, "nodatacow"},
> +	{Opt_nobarrier, "nobarrier"},
> +/*	{Opt_max_inline, "max_inline=%s"},	... not supported */
> +/*	{Opt_alloc_start, "alloc_start=%s"},	... not supported */
> +/*	{Opt_thread_pool, "thread_pool=%d"},	... not supported */
> +	{Opt_compress, "compress"},
> +/*	{Opt_compress_type, "compress=%s"},		... TBD? */
> +	{Opt_compress_force, "compress-force"},
> +/*	{Opt_compress_force_type, "compress-force=%s"},	... TBD? */
> +	{Opt_ssd, "ssd"},
> +	{Opt_ssd_spread, "ssd_spread"},
> +	{Opt_nossd, "nossd"},
> +	{Opt_noacl, "noacl"},
> +	{Opt_notreelog, "notreelog"},
> +	{Opt_flushoncommit, "flushoncommit"},
> +/*	{Opt_ratio, "metadata_ratio=%d"},	... not supported */
> +	{Opt_discard, "discard"},
> +	{Opt_space_cache, "space_cache"},
> +	{Opt_clear_cache, "clear_cache"},
> +	{Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},
> +/*	{Opt_enospc_debug, "enospc_debug"},	... never be default */
> +/*	{Opt_subvolrootid, "subvolrootid=%d"},	... not supported */
> +	{Opt_defrag, "autodefrag"},
> +	{Opt_inode_cache, "inode_cache"},
> +	{Opt_no_space_cache, "nospace_cache"},
> +	{Opt_recovery, "recovery"},
> +	{Opt_skip_balance, "skip_balance"},
> +	{Opt_check_integrity, "check_int"},
> +	{Opt_check_integrity_including_extent_data, "check_int_data"},
> +/*	{Opt_check_integrity_print_mask, "check_int_print_mask=%d"},
> +	{Opt_fatal_errors, "fatal_errors=%s"},	... not supported */
> +	{Opt_err, NULL},	/* must be end */
> +};
> +
> +void btrfs_parse_string2mntopt(u64 *optval, int optnum, char **options);
> +void btrfs_parse_mntopt2string(u64 optval);
> diff --git a/btrfs.c b/btrfs.c
> index a229cee..608869d 100644
> --- a/btrfs.c
> +++ b/btrfs.c
> @@ -250,6 +250,7 @@ const struct cmd_group btrfs_cmd_group = {
>   		{ "receive", cmd_receive, NULL, &receive_cmd_group, 0 },
>   		{ "quota", cmd_quota, NULL, &quota_cmd_group, 0 },
>   		{ "qgroup", cmd_qgroup, NULL, &qgroup_cmd_group, 0 },
> +		{ "mount-option", cmd_mount, NULL, &mount_cmd_group, 0 },
>   		{ "help", cmd_help, cmd_help_usage, NULL, 0 },
>   		{ "version", cmd_version, cmd_version_usage, NULL, 0 },
>   		{ 0, 0, 0, 0, 0 }
> diff --git a/cmds-mount.c b/cmds-mount.c
> new file mode 100644
> index 0000000..1752019
> --- /dev/null
> +++ b/cmds-mount.c
> @@ -0,0 +1,185 @@
> +/*
> + * 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 int mount_check_device(char *device)
> +{
> +	int ret;
> +
> +	ret = check_mounted(device);
> +	if (ret == 1) {
> +		fprintf(stderr, "%s is mounted\n", device);
> +		return 1;
> +	}

I think that "btrfs mount-option get <device>" command should not be an error
even if the device is mounted.

Thanks,
Tsutomu

> +	if (ret < 0) {
> +		fprintf(stderr, "error checking %s mount status with %d(%s)\n",
> +			device, ret, strerror(-1*ret));
> +		return 1;
> +	}
> +	return 0;
> +}



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/4] Btrfs-progs: add mount-option command man page
  2012-10-12  3:24 ` [PATCH v2 2/4] Btrfs-progs: add mount-option command man page Hidetoshi Seto
@ 2012-10-14  9:04   ` Goffredo Baroncelli
  0 siblings, 0 replies; 8+ messages in thread
From: Goffredo Baroncelli @ 2012-10-14  9:04 UTC (permalink / raw)
  To: Hidetoshi Seto; +Cc: linux-btrfs

On 2012-10-12 05:24, Hidetoshi Seto wrote:
> Add mount-option command man page.
> 
> Signed-off-by: Hidetoshi Seto<seto.hidetoshi@jp.fujitsu.com>
> ---
>   man/btrfs.8.in |   25 +++++++++++++++++++++++++
>   1 files changed, 25 insertions(+), 0 deletions(-)
> 
> diff --git a/man/btrfs.8.in b/man/btrfs.8.in
> index 4b0a9f9..85d5030 100644
> --- a/man/btrfs.8.in
> +++ b/man/btrfs.8.in
> @@ -52,6 +52,12 @@ btrfs \- control a btrfs filesystem
>   \fBbtrfs\fP \fBinspect-internal logical-resolve\fP
>   [-Pv] \fI<logical>\fP \fI<path>\fP
>   .PP
> +\fBbtrfs\fP \fBmount-option set\fP \fI[[<+/-/=><option>,...]...]\fP \fI<device>\fP
> +.PP
> +\fBbtrfs\fP \fBmount-option get\fP \fI<device>\fP
> +.PP
> +\fBbtrfs\fP \fBmount-option clear\fP \fI<device>\fP
> +.PP
>   \fBbtrfs\fP \fBhelp|\-\-help|\-h \fP\fI\fP
>   .PP
>   \fBbtrfs\fP \fB<command>  \-\-help \fP\fI\fP
> @@ -319,6 +325,25 @@ skip the path resolving and print the inodes instead
>   .IP -v 5
>   verbose mode. print count of returned paths and all ioctl() return values
>   .RE
> +.TP
> +
> +\fBmount-option set\fP \fI[<+/-/=><option>,...]...]\fP \fI<device>\fP
> +With some operators \fB+\fP,\fB-\fP,\fB=\fP and some options,
> +set default mount options to the \fI<device>\fP.
> +These \fB+\fP,\fB-\fP,\fB=\fP operators mean like \fBchmod\fP operators.
> +The operator \fB+\fP causes the selected mount options to be added to existing
> +default mount options of the \fI<device>\fP; \fB-\fP causes them to be removed;
> +and \fB=\fP causes them to be added and causes unmentioned options to be removed.
> +Without options, print default mount options of the \fI<device>\fR.
> +.TP


Please list all the available options here; otherwise I suggest to list
them in the help of "btrfs mount-option" I think that it would be more
simple ...

> +
> +\fBmount-option get\fP \fI<device>\fP
> +Print default mount options of the \fI<device>\fR.
> +.TP
> +
> +\fBmount-option clear\fP \fI<device>\fP
> +Clear default mount options of the \fI<device>\fR.
> +.TP
> 
>   .SH EXIT STATUS
>   \fBbtrfs\fR returns a zero exist status if it succeeds. Non zero is returned in


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-10-14  9:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-12  3:18 [PATCH v2 0/4] Btrfs: set mount options permanently Hidetoshi Seto
2012-10-12  3:24 ` [PATCH v2 1/4] Btrfs-progs: add mount-option command Hidetoshi Seto
2012-10-12  5:35   ` Tsutomu Itoh
2012-10-12  8:21   ` Tsutomu Itoh
2012-10-12  3:24 ` [PATCH v2 2/4] Btrfs-progs: add mount-option command man page Hidetoshi Seto
2012-10-14  9:04   ` Goffredo Baroncelli
2012-10-12  3:24 ` [PATCH v2 3/4] btrfs: make subroutine __btrfs_parse_options Hidetoshi Seto
2012-10-12  3:25 ` [PATCH v2 4/4] btrfs: support default mount options Hidetoshi Seto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).