aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2009-12-11 16:11:29 -0500
committerChris Mason <chris.mason@oracle.com>2010-03-15 11:00:08 -0400
commit6ef5ed0d386be5c43ec66d6f2999919c0893558b (patch)
tree7ec391a0525506eb03bcbb0b5e19709f530b0b74 /fs/btrfs/ioctl.c
parent73f73415caddbc01d9f10c03e0a677d5b3d11569 (diff)
Btrfs: add ioctl and incompat flag to set the default mount subvol
This patch needs to go along with my previous patch. This lets us set the default dir item's location to whatever root we want to use as our default mounting subvol. With this we don't have to use mount -o subvol=<tree id> anymore to mount a different subvol, we can just set the new one and it will just magically work. I've done some moderate testing with this, mostly just switching the default mount around, mounting subvols and the default mount at the same time and such, everything seems to work. Thanks, Older kernels would generally be able to still mount the filesystem with the default subvolume set, but it would result in a different volume being mounted, which could be an even more unpleasant suprise for users. So if you set your default subvolume, you can't go back to older kernels. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c75
1 files changed, 75 insertions, 0 deletions
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: