diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-05-07 11:43:44 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | a061fc8da7b990faa41ca503e66faef3ecdeead0 (patch) | |
tree | 0d3b5b6e4d2164d507d9a16d5b38d373592a5c8f /fs/btrfs/inode.c | |
parent | 5d9cd9ecbf40b8bd5045a3c2f1feb35db6a12266 (diff) |
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.c | 27 |
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, | |||
2194 | again: | 2194 | again: |
2195 | spin_lock(&em_tree->lock); | 2195 | spin_lock(&em_tree->lock); |
2196 | em = lookup_extent_mapping(em_tree, start, len); | 2196 | em = lookup_extent_mapping(em_tree, start, len); |
2197 | if (em) | ||
2198 | em->bdev = root->fs_info->fs_devices->latest_bdev; | ||
2197 | spin_unlock(&em_tree->lock); | 2199 | spin_unlock(&em_tree->lock); |
2198 | 2200 | ||
2199 | if (em) { | 2201 | if (em) { |
@@ -2212,7 +2214,7 @@ again: | |||
2212 | 2214 | ||
2213 | em->start = EXTENT_MAP_HOLE; | 2215 | em->start = EXTENT_MAP_HOLE; |
2214 | em->len = (u64)-1; | 2216 | em->len = (u64)-1; |
2215 | em->bdev = inode->i_sb->s_bdev; | 2217 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
2216 | ret = btrfs_lookup_file_extent(trans, root, path, | 2218 | ret = btrfs_lookup_file_extent(trans, root, path, |
2217 | objectid, start, trans != NULL); | 2219 | objectid, start, trans != NULL); |
2218 | if (ret < 0) { | 2220 | if (ret < 0) { |
@@ -3101,6 +3103,27 @@ out: | |||
3101 | return ret; | 3103 | return ret; |
3102 | } | 3104 | } |
3103 | 3105 | ||
3106 | long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) | ||
3107 | { | ||
3108 | struct btrfs_ioctl_vol_args *vol_args; | ||
3109 | int ret; | ||
3110 | |||
3111 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); | ||
3112 | |||
3113 | if (!vol_args) | ||
3114 | return -ENOMEM; | ||
3115 | |||
3116 | if (copy_from_user(vol_args, arg, sizeof(*vol_args))) { | ||
3117 | ret = -EFAULT; | ||
3118 | goto out; | ||
3119 | } | ||
3120 | ret = btrfs_rm_device(root, vol_args->name); | ||
3121 | |||
3122 | out: | ||
3123 | kfree(vol_args); | ||
3124 | return ret; | ||
3125 | } | ||
3126 | |||
3104 | int dup_item_to_inode(struct btrfs_trans_handle *trans, | 3127 | int dup_item_to_inode(struct btrfs_trans_handle *trans, |
3105 | struct btrfs_root *root, | 3128 | struct btrfs_root *root, |
3106 | struct btrfs_path *path, | 3129 | struct btrfs_path *path, |
@@ -3294,6 +3317,8 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
3294 | return btrfs_ioctl_resize(root, (void __user *)arg); | 3317 | return btrfs_ioctl_resize(root, (void __user *)arg); |
3295 | case BTRFS_IOC_ADD_DEV: | 3318 | case BTRFS_IOC_ADD_DEV: |
3296 | return btrfs_ioctl_add_dev(root, (void __user *)arg); | 3319 | return btrfs_ioctl_add_dev(root, (void __user *)arg); |
3320 | case BTRFS_IOC_RM_DEV: | ||
3321 | return btrfs_ioctl_rm_dev(root, (void __user *)arg); | ||
3297 | case BTRFS_IOC_BALANCE: | 3322 | case BTRFS_IOC_BALANCE: |
3298 | return btrfs_balance(root->fs_info->dev_root); | 3323 | return btrfs_balance(root->fs_info->dev_root); |
3299 | case BTRFS_IOC_CLONE: | 3324 | case BTRFS_IOC_CLONE: |