diff options
-rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
-rw-r--r-- | fs/btrfs/super.c | 49 |
2 files changed, 45 insertions, 10 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index ffeee546a0d7..cd75c906048f 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1064,6 +1064,12 @@ static inline int btrfs_set_root_name(struct btrfs_root *root, | |||
1064 | ((type *)(btrfs_leaf_data(leaf) + \ | 1064 | ((type *)(btrfs_leaf_data(leaf) + \ |
1065 | btrfs_item_offset((leaf)->items + (slot)))) | 1065 | btrfs_item_offset((leaf)->items + (slot)))) |
1066 | 1066 | ||
1067 | /* mount option defines and helpers */ | ||
1068 | #define BTRFS_MOUNT_SUBVOL 0x000001 | ||
1069 | #define btrfs_clear_opt(o, opt) o &= ~BTRFS_MOUNT_##opt | ||
1070 | #define btrfs_set_opt(o, opt) o |= BTRFS_MOUNT_##opt | ||
1071 | #define btrfs_test_opt(sb, opt) (BTRFS_SB(sb)->s_mount_opt & \ | ||
1072 | BTRFS_MOUNT_##opt) | ||
1067 | /* extent-tree.c */ | 1073 | /* extent-tree.c */ |
1068 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | 1074 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, |
1069 | struct btrfs_root *root); | 1075 | struct btrfs_root *root); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8a94be1a773b..66a01cbbbea1 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/writeback.h> | 33 | #include <linux/writeback.h> |
34 | #include <linux/statfs.h> | 34 | #include <linux/statfs.h> |
35 | #include <linux/compat.h> | 35 | #include <linux/compat.h> |
36 | #include <linux/parser.h> | ||
36 | #include "ctree.h" | 37 | #include "ctree.h" |
37 | #include "disk-io.h" | 38 | #include "disk-io.h" |
38 | #include "transaction.h" | 39 | #include "transaction.h" |
@@ -58,6 +59,41 @@ static void btrfs_put_super (struct super_block * sb) | |||
58 | sb->s_fs_info = NULL; | 59 | sb->s_fs_info = NULL; |
59 | } | 60 | } |
60 | 61 | ||
62 | enum { | ||
63 | Opt_subvol, Opt_err, | ||
64 | }; | ||
65 | |||
66 | static match_table_t tokens = { | ||
67 | {Opt_subvol, "subvol=%s"}, | ||
68 | {Opt_err, NULL} | ||
69 | }; | ||
70 | |||
71 | static int parse_options (char * options, | ||
72 | struct btrfs_root *root, | ||
73 | char **subvol_name) | ||
74 | { | ||
75 | char * p; | ||
76 | substring_t args[MAX_OPT_ARGS]; | ||
77 | if (!options) | ||
78 | return 1; | ||
79 | |||
80 | while ((p = strsep (&options, ",")) != NULL) { | ||
81 | int token; | ||
82 | if (!*p) | ||
83 | continue; | ||
84 | |||
85 | token = match_token(p, tokens, args); | ||
86 | switch (token) { | ||
87 | case Opt_subvol: | ||
88 | *subvol_name = match_strdup(&args[0]); | ||
89 | break; | ||
90 | default: | ||
91 | return 0; | ||
92 | } | ||
93 | } | ||
94 | return 1; | ||
95 | } | ||
96 | |||
61 | static int btrfs_fill_super(struct super_block * sb, void * data, int silent) | 97 | static int btrfs_fill_super(struct super_block * sb, void * data, int silent) |
62 | { | 98 | { |
63 | struct inode * inode; | 99 | struct inode * inode; |
@@ -250,22 +286,15 @@ error: | |||
250 | /* end copy & paste */ | 286 | /* end copy & paste */ |
251 | 287 | ||
252 | static int btrfs_get_sb(struct file_system_type *fs_type, | 288 | static int btrfs_get_sb(struct file_system_type *fs_type, |
253 | int flags, const char *identifier, void *data, struct vfsmount *mnt) | 289 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
254 | { | 290 | { |
255 | int ret; | 291 | int ret; |
256 | char *_identifier = kstrdup(identifier, GFP_KERNEL); | 292 | char *subvol_name = NULL; |
257 | char *subvol_name; | ||
258 | const char *dev_name; | ||
259 | |||
260 | subvol_name = _identifier; | ||
261 | dev_name = strsep(&subvol_name, ":"); | ||
262 | if (!dev_name) | ||
263 | return -ENOMEM; | ||
264 | 293 | ||
294 | parse_options((char *)data, NULL, &subvol_name); | ||
265 | ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, | 295 | ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, |
266 | btrfs_fill_super, mnt, | 296 | btrfs_fill_super, mnt, |
267 | subvol_name ? subvol_name : "default"); | 297 | subvol_name ? subvol_name : "default"); |
268 | kfree(_identifier); | ||
269 | return ret; | 298 | return ret; |
270 | } | 299 | } |
271 | 300 | ||