diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-25 16:53:30 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | 8f18cf13396caae5a3d7ae91201cfb15181a9642 (patch) | |
tree | ff4bfc2e7f45f10d176b969408cdb469ae3f7194 /fs/btrfs/inode.c | |
parent | 5e478dc9828ad33d7b08dcdf277e13f14a7c1be7 (diff) |
Btrfs: Make the resizer work based on shrinking and growing devices
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b31f52d4f2ca..4d12aa532c5b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/kernel.h> | ||
19 | #include <linux/bio.h> | 20 | #include <linux/bio.h> |
20 | #include <linux/buffer_head.h> | 21 | #include <linux/buffer_head.h> |
21 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
@@ -2887,9 +2888,12 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
2887 | { | 2888 | { |
2888 | u64 new_size; | 2889 | u64 new_size; |
2889 | u64 old_size; | 2890 | u64 old_size; |
2891 | u64 devid = 1; | ||
2890 | struct btrfs_ioctl_vol_args *vol_args; | 2892 | struct btrfs_ioctl_vol_args *vol_args; |
2891 | struct btrfs_trans_handle *trans; | 2893 | struct btrfs_trans_handle *trans; |
2894 | struct btrfs_device *device = NULL; | ||
2892 | char *sizestr; | 2895 | char *sizestr; |
2896 | char *devstr = NULL; | ||
2893 | int ret = 0; | 2897 | int ret = 0; |
2894 | int namelen; | 2898 | int namelen; |
2895 | int mod = 0; | 2899 | int mod = 0; |
@@ -2909,9 +2913,25 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
2909 | goto out; | 2913 | goto out; |
2910 | } | 2914 | } |
2911 | 2915 | ||
2916 | mutex_lock(&root->fs_info->fs_mutex); | ||
2912 | sizestr = vol_args->name; | 2917 | sizestr = vol_args->name; |
2918 | devstr = strchr(sizestr, ':'); | ||
2919 | if (devstr) { | ||
2920 | char *end; | ||
2921 | sizestr = devstr + 1; | ||
2922 | *devstr = '\0'; | ||
2923 | devstr = vol_args->name; | ||
2924 | devid = simple_strtoull(devstr, &end, 10); | ||
2925 | printk("resizing devid %Lu\n", devid); | ||
2926 | } | ||
2927 | device = btrfs_find_device(root, devid, NULL); | ||
2928 | if (!device) { | ||
2929 | printk("resizer unable to find device %Lu\n", devid); | ||
2930 | ret = -EINVAL; | ||
2931 | goto out_unlock; | ||
2932 | } | ||
2913 | if (!strcmp(sizestr, "max")) | 2933 | if (!strcmp(sizestr, "max")) |
2914 | new_size = root->fs_info->sb->s_bdev->bd_inode->i_size; | 2934 | new_size = device->bdev->bd_inode->i_size; |
2915 | else { | 2935 | else { |
2916 | if (sizestr[0] == '-') { | 2936 | if (sizestr[0] == '-') { |
2917 | mod = -1; | 2937 | mod = -1; |
@@ -2923,12 +2943,11 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
2923 | new_size = btrfs_parse_size(sizestr); | 2943 | new_size = btrfs_parse_size(sizestr); |
2924 | if (new_size == 0) { | 2944 | if (new_size == 0) { |
2925 | ret = -EINVAL; | 2945 | ret = -EINVAL; |
2926 | goto out; | 2946 | goto out_unlock; |
2927 | } | 2947 | } |
2928 | } | 2948 | } |
2929 | 2949 | ||
2930 | mutex_lock(&root->fs_info->fs_mutex); | 2950 | old_size = device->total_bytes; |
2931 | old_size = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
2932 | 2951 | ||
2933 | if (mod < 0) { | 2952 | if (mod < 0) { |
2934 | if (new_size > old_size) { | 2953 | if (new_size > old_size) { |
@@ -2944,7 +2963,7 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
2944 | ret = -EINVAL; | 2963 | ret = -EINVAL; |
2945 | goto out_unlock; | 2964 | goto out_unlock; |
2946 | } | 2965 | } |
2947 | if (new_size > root->fs_info->sb->s_bdev->bd_inode->i_size) { | 2966 | if (new_size > device->bdev->bd_inode->i_size) { |
2948 | ret = -EFBIG; | 2967 | ret = -EFBIG; |
2949 | goto out_unlock; | 2968 | goto out_unlock; |
2950 | } | 2969 | } |
@@ -2952,13 +2971,14 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
2952 | do_div(new_size, root->sectorsize); | 2971 | do_div(new_size, root->sectorsize); |
2953 | new_size *= root->sectorsize; | 2972 | new_size *= root->sectorsize; |
2954 | 2973 | ||
2955 | printk("new size is %Lu\n", new_size); | 2974 | printk("new size for %s is %llu\n", device->name, (unsigned long long)new_size); |
2975 | |||
2956 | if (new_size > old_size) { | 2976 | if (new_size > old_size) { |
2957 | trans = btrfs_start_transaction(root, 1); | 2977 | trans = btrfs_start_transaction(root, 1); |
2958 | ret = btrfs_grow_extent_tree(trans, root, new_size); | 2978 | ret = btrfs_grow_device(trans, device, new_size); |
2959 | btrfs_commit_transaction(trans, root); | 2979 | btrfs_commit_transaction(trans, root); |
2960 | } else { | 2980 | } else { |
2961 | ret = btrfs_shrink_extent_tree(root, new_size); | 2981 | ret = btrfs_shrink_device(device, new_size); |
2962 | } | 2982 | } |
2963 | 2983 | ||
2964 | out_unlock: | 2984 | out_unlock: |