@@ -1121,6 +1121,38 @@ out:
return ret;
}
+static int btrfs_device_can_remove(struct btrfs_fs_info *fs_info)
+{
+ u64 all_avail;
+
+ all_avail = fs_info->avail_data_alloc_bits |
+ fs_info->avail_system_alloc_bits |
+ fs_info->avail_metadata_alloc_bits;
+
+ if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) &&
+ fs_info->fs_devices->num_devices <= 4) {
+ printk(KERN_ERR "btrfs: unable to go below four devices "
+ "on raid10\n");
+ return 0;
+ }
+
+ if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) &&
+ fs_info->fs_devices->num_devices <= 2) {
+ printk(KERN_ERR "btrfs: unable to go below two "
+ "devices on raid1\n");
+ return 0;
+ }
+
+ if ((all_avail & BTRFS_BLOCK_GROUP_RAID0) &&
+ fs_info->fs_devices->num_devices <= 2) {
+ printk(KERN_ERR "btrfs: unable to go below two "
+ "devices on raid0\n");
+ return 0;
+ }
+
+ return 1;
+}
+
int btrfs_rm_device(struct btrfs_root *root, char *device_path)
{
struct btrfs_device *device;
@@ -1128,7 +1160,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
struct block_device *bdev;
struct buffer_head *bh = NULL;
struct btrfs_super_block *disk_super;
- u64 all_avail;
u64 devid;
u64 num_devices;
u8 *dev_uuid;
@@ -1137,22 +1168,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
mutex_lock(&uuid_mutex);
mutex_lock(&root->fs_info->volume_mutex);
- all_avail = root->fs_info->avail_data_alloc_bits |
- root->fs_info->avail_system_alloc_bits |
- root->fs_info->avail_metadata_alloc_bits;
-
- if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) &&
- root->fs_info->fs_devices->num_devices <= 4) {
- printk(KERN_ERR "btrfs: unable to go below four devices "
- "on raid10\n");
- ret = -EINVAL;
- goto out;
- }
-
- if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) &&
- root->fs_info->fs_devices->num_devices <= 2) {
- printk(KERN_ERR "btrfs: unable to go below two "
- "devices on raid1\n");
+ if (!btrfs_device_can_remove(root->fs_info)) {
ret = -EINVAL;
goto out;
}