aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/export.c4
-rw-r--r--fs/btrfs/inode.c10
-rw-r--r--fs/btrfs/relocation.c2
-rw-r--r--fs/btrfs/super.c172
-rw-r--r--fs/btrfs/tree-log.c2
6 files changed, 158 insertions, 34 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index abbce4d90c1b..07d956977a07 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2335,7 +2335,7 @@ int btrfs_init_cachep(void);
2335void btrfs_destroy_cachep(void); 2335void btrfs_destroy_cachep(void);
2336long btrfs_ioctl_trans_end(struct file *file); 2336long btrfs_ioctl_trans_end(struct file *file);
2337struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, 2337struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
2338 struct btrfs_root *root); 2338 struct btrfs_root *root, int *was_new);
2339int btrfs_commit_write(struct file *file, struct page *page, 2339int btrfs_commit_write(struct file *file, struct page *page,
2340 unsigned from, unsigned to); 2340 unsigned from, unsigned to);
2341struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, 2341struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index ba5c3fd5ab8c..951ef09b82f4 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -95,7 +95,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
95 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); 95 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
96 key.offset = 0; 96 key.offset = 0;
97 97
98 inode = btrfs_iget(sb, &key, root); 98 inode = btrfs_iget(sb, &key, root, NULL);
99 if (IS_ERR(inode)) { 99 if (IS_ERR(inode)) {
100 err = PTR_ERR(inode); 100 err = PTR_ERR(inode);
101 goto fail; 101 goto fail;
@@ -223,7 +223,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
223 223
224 key.type = BTRFS_INODE_ITEM_KEY; 224 key.type = BTRFS_INODE_ITEM_KEY;
225 key.offset = 0; 225 key.offset = 0;
226 dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root)); 226 dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
227 if (!IS_ERR(dentry)) 227 if (!IS_ERR(dentry))
228 dentry->d_op = &btrfs_dentry_operations; 228 dentry->d_op = &btrfs_dentry_operations;
229 return dentry; 229 return dentry;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4deb280f8969..7d10d1ccb0fe 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2153,7 +2153,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
2153 found_key.objectid = found_key.offset; 2153 found_key.objectid = found_key.offset;
2154 found_key.type = BTRFS_INODE_ITEM_KEY; 2154 found_key.type = BTRFS_INODE_ITEM_KEY;
2155 found_key.offset = 0; 2155 found_key.offset = 0;
2156 inode = btrfs_iget(root->fs_info->sb, &found_key, root); 2156 inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
2157 if (IS_ERR(inode)) 2157 if (IS_ERR(inode))
2158 break; 2158 break;
2159 2159
@@ -3687,7 +3687,7 @@ static struct inode *btrfs_iget_locked(struct super_block *s,
3687 * Returns in *is_new if the inode was read from disk 3687 * Returns in *is_new if the inode was read from disk
3688 */ 3688 */
3689struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, 3689struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3690 struct btrfs_root *root) 3690 struct btrfs_root *root, int *new)
3691{ 3691{
3692 struct inode *inode; 3692 struct inode *inode;
3693 3693
@@ -3702,6 +3702,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3702 3702
3703 inode_tree_add(inode); 3703 inode_tree_add(inode);
3704 unlock_new_inode(inode); 3704 unlock_new_inode(inode);
3705 if (new)
3706 *new = 1;
3705 } 3707 }
3706 3708
3707 return inode; 3709 return inode;
@@ -3754,7 +3756,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
3754 return NULL; 3756 return NULL;
3755 3757
3756 if (location.type == BTRFS_INODE_ITEM_KEY) { 3758 if (location.type == BTRFS_INODE_ITEM_KEY) {
3757 inode = btrfs_iget(dir->i_sb, &location, root); 3759 inode = btrfs_iget(dir->i_sb, &location, root, NULL);
3758 return inode; 3760 return inode;
3759 } 3761 }
3760 3762
@@ -3769,7 +3771,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
3769 else 3771 else
3770 inode = new_simple_dir(dir->i_sb, &location, sub_root); 3772 inode = new_simple_dir(dir->i_sb, &location, sub_root);
3771 } else { 3773 } else {
3772 inode = btrfs_iget(dir->i_sb, &location, sub_root); 3774 inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL);
3773 } 3775 }
3774 srcu_read_unlock(&root->fs_info->subvol_srcu, index); 3776 srcu_read_unlock(&root->fs_info->subvol_srcu, index);
3775 3777
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 0109e5606bad..d52759daa53f 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3487,7 +3487,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
3487 key.objectid = objectid; 3487 key.objectid = objectid;
3488 key.type = BTRFS_INODE_ITEM_KEY; 3488 key.type = BTRFS_INODE_ITEM_KEY;
3489 key.offset = 0; 3489 key.offset = 0;
3490 inode = btrfs_iget(root->fs_info->sb, &key, root); 3490 inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
3491 BUG_ON(IS_ERR(inode) || is_bad_inode(inode)); 3491 BUG_ON(IS_ERR(inode) || is_bad_inode(inode));
3492 BTRFS_I(inode)->index_cnt = group->key.objectid; 3492 BTRFS_I(inode)->index_cnt = group->key.objectid;
3493 3493
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f8b4521de907..f878337cee6f 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -63,10 +63,10 @@ static void btrfs_put_super(struct super_block *sb)
63} 63}
64 64
65enum { 65enum {
66 Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, 66 Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
67 Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, 67 Opt_nodatacow, Opt_max_extent, Opt_max_inline, Opt_alloc_start,
68 Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, 68 Opt_nobarrier, Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool,
69 Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio, 69 Opt_noacl, Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio,
70 Opt_flushoncommit, 70 Opt_flushoncommit,
71 Opt_discard, Opt_err, 71 Opt_discard, Opt_err,
72}; 72};
@@ -74,6 +74,7 @@ enum {
74static match_table_t tokens = { 74static match_table_t tokens = {
75 {Opt_degraded, "degraded"}, 75 {Opt_degraded, "degraded"},
76 {Opt_subvol, "subvol=%s"}, 76 {Opt_subvol, "subvol=%s"},
77 {Opt_subvolid, "subvolid=%d"},
77 {Opt_device, "device=%s"}, 78 {Opt_device, "device=%s"},
78 {Opt_nodatasum, "nodatasum"}, 79 {Opt_nodatasum, "nodatasum"},
79 {Opt_nodatacow, "nodatacow"}, 80 {Opt_nodatacow, "nodatacow"},
@@ -157,6 +158,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
157 btrfs_set_opt(info->mount_opt, DEGRADED); 158 btrfs_set_opt(info->mount_opt, DEGRADED);
158 break; 159 break;
159 case Opt_subvol: 160 case Opt_subvol:
161 case Opt_subvolid:
160 case Opt_device: 162 case Opt_device:
161 /* 163 /*
162 * These are parsed by btrfs_parse_early_options 164 * These are parsed by btrfs_parse_early_options
@@ -292,12 +294,13 @@ out:
292 * only when we need to allocate a new super block. 294 * only when we need to allocate a new super block.
293 */ 295 */
294static int btrfs_parse_early_options(const char *options, fmode_t flags, 296static int btrfs_parse_early_options(const char *options, fmode_t flags,
295 void *holder, char **subvol_name, 297 void *holder, char **subvol_name, u64 *subvol_objectid,
296 struct btrfs_fs_devices **fs_devices) 298 struct btrfs_fs_devices **fs_devices)
297{ 299{
298 substring_t args[MAX_OPT_ARGS]; 300 substring_t args[MAX_OPT_ARGS];
299 char *opts, *p; 301 char *opts, *p;
300 int error = 0; 302 int error = 0;
303 int intarg;
301 304
302 if (!options) 305 if (!options)
303 goto out; 306 goto out;
@@ -320,6 +323,12 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
320 case Opt_subvol: 323 case Opt_subvol:
321 *subvol_name = match_strdup(&args[0]); 324 *subvol_name = match_strdup(&args[0]);
322 break; 325 break;
326 case Opt_subvolid:
327 intarg = 0;
328 match_int(&args[0], &intarg);
329 if (intarg)
330 *subvol_objectid = intarg;
331 break;
323 case Opt_device: 332 case Opt_device:
324 error = btrfs_scan_one_device(match_strdup(&args[0]), 333 error = btrfs_scan_one_device(match_strdup(&args[0]),
325 flags, holder, fs_devices); 334 flags, holder, fs_devices);
@@ -347,6 +356,110 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
347 return error; 356 return error;
348} 357}
349 358
359static struct dentry *get_default_root(struct super_block *sb,
360 u64 subvol_objectid)
361{
362 struct btrfs_root *root = sb->s_fs_info;
363 struct btrfs_root *new_root;
364 struct btrfs_dir_item *di;
365 struct btrfs_path *path;
366 struct btrfs_key location;
367 struct inode *inode;
368 struct dentry *dentry;
369 u64 dir_id;
370 int new = 0;
371
372 /*
373 * We have a specific subvol we want to mount, just setup location and
374 * go look up the root.
375 */
376 if (subvol_objectid) {
377 location.objectid = subvol_objectid;
378 location.type = BTRFS_ROOT_ITEM_KEY;
379 location.offset = (u64)-1;
380 goto find_root;
381 }
382
383 path = btrfs_alloc_path();
384 if (!path)
385 return ERR_PTR(-ENOMEM);
386 path->leave_spinning = 1;
387
388 /*
389 * Find the "default" dir item which points to the root item that we
390 * will mount by default if we haven't been given a specific subvolume
391 * to mount.
392 */
393 dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
394 di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
395 if (!di) {
396 /*
397 * Ok the default dir item isn't there. This is weird since
398 * it's always been there, but don't freak out, just try and
399 * mount to root most subvolume.
400 */
401 btrfs_free_path(path);
402 dir_id = BTRFS_FIRST_FREE_OBJECTID;
403 new_root = root->fs_info->fs_root;
404 goto setup_root;
405 }
406
407 btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
408 btrfs_free_path(path);
409
410find_root:
411 new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
412 if (IS_ERR(new_root))
413 return ERR_PTR(PTR_ERR(new_root));
414
415 if (btrfs_root_refs(&new_root->root_item) == 0)
416 return ERR_PTR(-ENOENT);
417
418 dir_id = btrfs_root_dirid(&new_root->root_item);
419setup_root:
420 location.objectid = dir_id;
421 location.type = BTRFS_INODE_ITEM_KEY;
422 location.offset = 0;
423
424 inode = btrfs_iget(sb, &location, new_root, &new);
425 if (!inode)
426 return ERR_PTR(-ENOMEM);
427
428 /*
429 * If we're just mounting the root most subvol put the inode and return
430 * a reference to the dentry. We will have already gotten a reference
431 * to the inode in btrfs_fill_super so we're good to go.
432 */
433 if (!new && sb->s_root->d_inode == inode) {
434 iput(inode);
435 return dget(sb->s_root);
436 }
437
438 if (new) {
439 const struct qstr name = { .name = "/", .len = 1 };
440
441 /*
442 * New inode, we need to make the dentry a sibling of s_root so
443 * everything gets cleaned up properly on unmount.
444 */
445 dentry = d_alloc(sb->s_root, &name);
446 if (!dentry) {
447 iput(inode);
448 return ERR_PTR(-ENOMEM);
449 }
450 d_splice_alias(inode, dentry);
451 } else {
452 /*
453 * We found the inode in cache, just find a dentry for it and
454 * put the reference to the inode we just got.
455 */
456 dentry = d_find_alias(inode);
457 iput(inode);
458 }
459
460 return dentry;
461}
462
350static int btrfs_fill_super(struct super_block *sb, 463static int btrfs_fill_super(struct super_block *sb,
351 struct btrfs_fs_devices *fs_devices, 464 struct btrfs_fs_devices *fs_devices,
352 void *data, int silent) 465 void *data, int silent)
@@ -380,7 +493,7 @@ static int btrfs_fill_super(struct super_block *sb,
380 key.objectid = BTRFS_FIRST_FREE_OBJECTID; 493 key.objectid = BTRFS_FIRST_FREE_OBJECTID;
381 key.type = BTRFS_INODE_ITEM_KEY; 494 key.type = BTRFS_INODE_ITEM_KEY;
382 key.offset = 0; 495 key.offset = 0;
383 inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root); 496 inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
384 if (IS_ERR(inode)) { 497 if (IS_ERR(inode)) {
385 err = PTR_ERR(inode); 498 err = PTR_ERR(inode);
386 goto fail_close; 499 goto fail_close;
@@ -392,12 +505,6 @@ static int btrfs_fill_super(struct super_block *sb,
392 err = -ENOMEM; 505 err = -ENOMEM;
393 goto fail_close; 506 goto fail_close;
394 } 507 }
395#if 0
396 /* this does the super kobj at the same time */
397 err = btrfs_sysfs_add_super(tree_root->fs_info);
398 if (err)
399 goto fail_close;
400#endif
401 508
402 sb->s_root = root_dentry; 509 sb->s_root = root_dentry;
403 510
@@ -489,19 +596,22 @@ static int btrfs_test_super(struct super_block *s, void *data)
489static int btrfs_get_sb(struct file_system_type *fs_type, int flags, 596static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
490 const char *dev_name, void *data, struct vfsmount *mnt) 597 const char *dev_name, void *data, struct vfsmount *mnt)
491{ 598{
492 char *subvol_name = NULL;
493 struct block_device *bdev = NULL; 599 struct block_device *bdev = NULL;
494 struct super_block *s; 600 struct super_block *s;
495 struct dentry *root; 601 struct dentry *root;
496 struct btrfs_fs_devices *fs_devices = NULL; 602 struct btrfs_fs_devices *fs_devices = NULL;
497 fmode_t mode = FMODE_READ; 603 fmode_t mode = FMODE_READ;
604 char *subvol_name = NULL;
605 u64 subvol_objectid = 0;
498 int error = 0; 606 int error = 0;
607 int found = 0;
499 608
500 if (!(flags & MS_RDONLY)) 609 if (!(flags & MS_RDONLY))
501 mode |= FMODE_WRITE; 610 mode |= FMODE_WRITE;
502 611
503 error = btrfs_parse_early_options(data, mode, fs_type, 612 error = btrfs_parse_early_options(data, mode, fs_type,
504 &subvol_name, &fs_devices); 613 &subvol_name, &subvol_objectid,
614 &fs_devices);
505 if (error) 615 if (error)
506 return error; 616 return error;
507 617
@@ -530,6 +640,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
530 goto error_close_devices; 640 goto error_close_devices;
531 } 641 }
532 642
643 found = 1;
533 btrfs_close_devices(fs_devices); 644 btrfs_close_devices(fs_devices);
534 } else { 645 } else {
535 char b[BDEVNAME_SIZE]; 646 char b[BDEVNAME_SIZE];
@@ -547,25 +658,35 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
547 s->s_flags |= MS_ACTIVE; 658 s->s_flags |= MS_ACTIVE;
548 } 659 }
549 660
550 if (!strcmp(subvol_name, ".")) 661 root = get_default_root(s, subvol_objectid);
551 root = dget(s->s_root); 662 if (IS_ERR(root)) {
552 else { 663 error = PTR_ERR(root);
553 mutex_lock(&s->s_root->d_inode->i_mutex); 664 deactivate_locked_super(s);
554 root = lookup_one_len(subvol_name, s->s_root, 665 goto error;
666 }
667 /* if they gave us a subvolume name bind mount into that */
668 if (strcmp(subvol_name, ".")) {
669 struct dentry *new_root;
670 mutex_lock(&root->d_inode->i_mutex);
671 new_root = lookup_one_len(subvol_name, root,
555 strlen(subvol_name)); 672 strlen(subvol_name));
556 mutex_unlock(&s->s_root->d_inode->i_mutex); 673 mutex_unlock(&root->d_inode->i_mutex);
557 674
558 if (IS_ERR(root)) { 675 if (IS_ERR(new_root)) {
559 deactivate_locked_super(s); 676 deactivate_locked_super(s);
560 error = PTR_ERR(root); 677 error = PTR_ERR(new_root);
561 goto error_free_subvol_name; 678 dput(root);
679 goto error_close_devices;
562 } 680 }
563 if (!root->d_inode) { 681 if (!new_root->d_inode) {
564 dput(root); 682 dput(root);
683 dput(new_root);
565 deactivate_locked_super(s); 684 deactivate_locked_super(s);
566 error = -ENXIO; 685 error = -ENXIO;
567 goto error_free_subvol_name; 686 goto error_close_devices;
568 } 687 }
688 dput(root);
689 root = new_root;
569 } 690 }
570 691
571 mnt->mnt_sb = s; 692 mnt->mnt_sb = s;
@@ -580,6 +701,7 @@ error_close_devices:
580 btrfs_close_devices(fs_devices); 701 btrfs_close_devices(fs_devices);
581error_free_subvol_name: 702error_free_subvol_name:
582 kfree(subvol_name); 703 kfree(subvol_name);
704error:
583 return error; 705 return error;
584} 706}
585 707
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 4a9434b622ec..1255fcc8ade5 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -445,7 +445,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
445 key.objectid = objectid; 445 key.objectid = objectid;
446 key.type = BTRFS_INODE_ITEM_KEY; 446 key.type = BTRFS_INODE_ITEM_KEY;
447 key.offset = 0; 447 key.offset = 0;
448 inode = btrfs_iget(root->fs_info->sb, &key, root); 448 inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
449 if (IS_ERR(inode)) { 449 if (IS_ERR(inode)) {
450 inode = NULL; 450 inode = NULL;
451 } else if (is_bad_inode(inode)) { 451 } else if (is_bad_inode(inode)) {