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.hideto...@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


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to