aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/ioctl.c75
-rw-r--r--fs/btrfs/ioctl.h2
3 files changed, 80 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 07d956977a07..1166b15e9bf6 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -373,11 +373,13 @@ struct btrfs_super_block {
373 * ones specified below then we will fail to mount 373 * ones specified below then we will fail to mount
374 */ 374 */
375#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) 375#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
376#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (2ULL << 0)
376 377
377#define BTRFS_FEATURE_COMPAT_SUPP 0ULL 378#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
378#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL 379#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
379#define BTRFS_FEATURE_INCOMPAT_SUPP \ 380#define BTRFS_FEATURE_INCOMPAT_SUPP \
380 BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF 381 (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
382 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
381 383
382/* 384/*
383 * A leaf is full of items. offset and size tell us where to find 385 * A leaf is full of items. offset and size tell us where to find
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index c6044733198d..7875a75315d0 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1579,6 +1579,79 @@ out:
1579 return ret; 1579 return ret;
1580} 1580}
1581 1581
1582static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
1583{
1584 struct inode *inode = fdentry(file)->d_inode;
1585 struct btrfs_root *root = BTRFS_I(inode)->root;
1586 struct btrfs_root *new_root;
1587 struct btrfs_dir_item *di;
1588 struct btrfs_trans_handle *trans;
1589 struct btrfs_path *path;
1590 struct btrfs_key location;
1591 struct btrfs_disk_key disk_key;
1592 struct btrfs_super_block *disk_super;
1593 u64 features;
1594 u64 objectid = 0;
1595 u64 dir_id;
1596
1597 if (!capable(CAP_SYS_ADMIN))
1598 return -EPERM;
1599
1600 if (copy_from_user(&objectid, argp, sizeof(objectid)))
1601 return -EFAULT;
1602
1603 if (!objectid)
1604 objectid = root->root_key.objectid;
1605
1606 location.objectid = objectid;
1607 location.type = BTRFS_ROOT_ITEM_KEY;
1608 location.offset = (u64)-1;
1609
1610 new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
1611 if (IS_ERR(new_root))
1612 return PTR_ERR(new_root);
1613
1614 if (btrfs_root_refs(&new_root->root_item) == 0)
1615 return -ENOENT;
1616
1617 path = btrfs_alloc_path();
1618 if (!path)
1619 return -ENOMEM;
1620 path->leave_spinning = 1;
1621
1622 trans = btrfs_start_transaction(root, 1);
1623 if (!trans) {
1624 btrfs_free_path(path);
1625 return -ENOMEM;
1626 }
1627
1628 dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
1629 di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
1630 dir_id, "default", 7, 1);
1631 if (!di) {
1632 btrfs_free_path(path);
1633 btrfs_end_transaction(trans, root);
1634 printk(KERN_ERR "Umm, you don't have the default dir item, "
1635 "this isn't going to work\n");
1636 return -ENOENT;
1637 }
1638
1639 btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
1640 btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
1641 btrfs_mark_buffer_dirty(path->nodes[0]);
1642 btrfs_free_path(path);
1643
1644 disk_super = &root->fs_info->super_copy;
1645 features = btrfs_super_incompat_flags(disk_super);
1646 if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) {
1647 features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL;
1648 btrfs_set_super_incompat_flags(disk_super, features);
1649 }
1650 btrfs_end_transaction(trans, root);
1651
1652 return 0;
1653}
1654
1582/* 1655/*
1583 * there are many ways the trans_start and trans_end ioctls can lead 1656 * there are many ways the trans_start and trans_end ioctls can lead
1584 * to deadlocks. They should only be used by applications that 1657 * to deadlocks. They should only be used by applications that
@@ -1625,6 +1698,8 @@ long btrfs_ioctl(struct file *file, unsigned int
1625 return btrfs_ioctl_snap_create(file, argp, 1); 1698 return btrfs_ioctl_snap_create(file, argp, 1);
1626 case BTRFS_IOC_SNAP_DESTROY: 1699 case BTRFS_IOC_SNAP_DESTROY:
1627 return btrfs_ioctl_snap_destroy(file, argp); 1700 return btrfs_ioctl_snap_destroy(file, argp);
1701 case BTRFS_IOC_DEFAULT_SUBVOL:
1702 return btrfs_ioctl_default_subvol(file, argp);
1628 case BTRFS_IOC_DEFRAG: 1703 case BTRFS_IOC_DEFRAG:
1629 return btrfs_ioctl_defrag(file); 1704 return btrfs_ioctl_defrag(file);
1630 case BTRFS_IOC_RESIZE: 1705 case BTRFS_IOC_RESIZE:
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 79c07b104f91..f1923e0260e3 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -1,3 +1,4 @@
1
1/* 2/*
2 * Copyright (C) 2007 Oracle. All rights reserved. 3 * Copyright (C) 2007 Oracle. All rights reserved.
3 * 4 *
@@ -133,4 +134,5 @@ struct btrfs_ioctl_clone_range_args {
133 struct btrfs_ioctl_search_args) 134 struct btrfs_ioctl_search_args)
134#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ 135#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
135 struct btrfs_ioctl_ino_lookup_args) 136 struct btrfs_ioctl_ino_lookup_args)
137#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
136#endif 138#endif