]> Pileus Git - ~andy/linux/commitdiff
Btrfs: Use mount -o subvol to select the subvol directory instead of dev:
authorChris Mason <chris.mason@oracle.com>
Wed, 29 Aug 2007 13:11:44 +0000 (09:11 -0400)
committerDavid Woodhouse <dwmw2@hera.kernel.org>
Wed, 29 Aug 2007 13:11:44 +0000 (09:11 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.h
fs/btrfs/super.c

index ffeee546a0d74e90cc8b4649e29696eafa2c68d4..cd75c906048f288396b96d4c8cf0bfb85302745e 100644 (file)
@@ -1064,6 +1064,12 @@ static inline int btrfs_set_root_name(struct btrfs_root *root,
        ((type *)(btrfs_leaf_data(leaf) + \
        btrfs_item_offset((leaf)->items + (slot))))
 
+/* mount option defines and helpers */
+#define BTRFS_MOUNT_SUBVOL             0x000001
+#define btrfs_clear_opt(o, opt)                o &= ~BTRFS_MOUNT_##opt
+#define btrfs_set_opt(o, opt)          o |= BTRFS_MOUNT_##opt
+#define btrfs_test_opt(sb, opt)                (BTRFS_SB(sb)->s_mount_opt & \
+                                        BTRFS_MOUNT_##opt)
 /* extent-tree.c */
 int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
                         struct btrfs_root *root);
index 8a94be1a773b08ce1f2cd9a970f2a973d3bd91ec..66a01cbbbea177b03c94d3a91e8a38d2db672221 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/writeback.h>
 #include <linux/statfs.h>
 #include <linux/compat.h>
+#include <linux/parser.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -58,6 +59,41 @@ static void btrfs_put_super (struct super_block * sb)
        sb->s_fs_info = NULL;
 }
 
+enum {
+       Opt_subvol, Opt_err,
+};
+
+static match_table_t tokens = {
+       {Opt_subvol, "subvol=%s"},
+       {Opt_err, NULL}
+};
+
+static int parse_options (char * options,
+                         struct btrfs_root *root,
+                         char **subvol_name)
+{
+       char * p;
+       substring_t args[MAX_OPT_ARGS];
+       if (!options)
+               return 1;
+
+       while ((p = strsep (&options, ",")) != NULL) {
+               int token;
+               if (!*p)
+                       continue;
+
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case Opt_subvol:
+                       *subvol_name = match_strdup(&args[0]);
+                       break;
+               default:
+                       return 0;
+               }
+       }
+       return 1;
+}
+
 static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
 {
        struct inode * inode;
@@ -250,22 +286,15 @@ error:
 /* end copy & paste */
 
 static int btrfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *identifier, void *data, struct vfsmount *mnt)
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
        int ret;
-       char *_identifier = kstrdup(identifier, GFP_KERNEL);
-       char *subvol_name;
-       const char *dev_name;
-
-       subvol_name = _identifier;
-       dev_name = strsep(&subvol_name, ":");
-       if (!dev_name)
-               return -ENOMEM;
+       char *subvol_name = NULL;
 
+       parse_options((char *)data, NULL, &subvol_name);
        ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data,
                        btrfs_fill_super, mnt,
                        subvol_name ? subvol_name : "default");
-       kfree(_identifier);
        return ret;
 }