summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason2008-05-07 17:43:44 +0200
committerChris Mason2008-09-25 17:04:02 +0200
commita061fc8da7b990faa41ca503e66faef3ecdeead0 (patch)
tree0d3b5b6e4d2164d507d9a16d5b38d373592a5c8f /fs/btrfs/inode.c
parentBtrfs: Fix clone ioctl to not hold the path over inserts (diff)
downloadkernel-qcow2-linux-a061fc8da7b990faa41ca503e66faef3ecdeead0.tar.gz
kernel-qcow2-linux-a061fc8da7b990faa41ca503e66faef3ecdeead0.tar.xz
kernel-qcow2-linux-a061fc8da7b990faa41ca503e66faef3ecdeead0.zip
Btrfs: Add support for online device removal
This required a few structural changes to the code that manages bdev pointers: The VFS super block now gets an anon-bdev instead of a pointer to the lowest bdev. This allows us to avoid swapping the super block bdev pointer around at run time. The code to read in the super block no longer goes through the extent buffer interface. Things got ugly keeping the mapping constant. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f7beb9b0d37a..b437d3bdf95e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2194,6 +2194,8 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
again:
spin_lock(&em_tree->lock);
em = lookup_extent_mapping(em_tree, start, len);
+ if (em)
+ em->bdev = root->fs_info->fs_devices->latest_bdev;
spin_unlock(&em_tree->lock);
if (em) {
@@ -2212,7 +2214,7 @@ again:
em->start = EXTENT_MAP_HOLE;
em->len = (u64)-1;
- em->bdev = inode->i_sb->s_bdev;
+ em->bdev = root->fs_info->fs_devices->latest_bdev;
ret = btrfs_lookup_file_extent(trans, root, path,
objectid, start, trans != NULL);
if (ret < 0) {
@@ -3101,6 +3103,27 @@ out:
return ret;
}
+long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg)
+{
+ struct btrfs_ioctl_vol_args *vol_args;
+ int ret;
+
+ vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS);
+
+ if (!vol_args)
+ return -ENOMEM;
+
+ if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
+ ret = -EFAULT;
+ goto out;
+ }
+ ret = btrfs_rm_device(root, vol_args->name);
+
+out:
+ kfree(vol_args);
+ return ret;
+}
+
int dup_item_to_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path,
@@ -3294,6 +3317,8 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_resize(root, (void __user *)arg);
case BTRFS_IOC_ADD_DEV:
return btrfs_ioctl_add_dev(root, (void __user *)arg);
+ case BTRFS_IOC_RM_DEV:
+ return btrfs_ioctl_rm_dev(root, (void __user *)arg);
case BTRFS_IOC_BALANCE:
return btrfs_balance(root->fs_info->dev_root);
case BTRFS_IOC_CLONE: