aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/dev-replace.c99
-rw-r--r--fs/btrfs/dev-replace.h4
-rw-r--r--fs/btrfs/ioctl.c60
-rw-r--r--fs/btrfs/volumes.c379
-rw-r--r--fs/btrfs/volumes.h9
-rw-r--r--include/uapi/linux/btrfs.h15
6 files changed, 324 insertions, 242 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 26bcb487f958..1f193f742f21 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -44,9 +44,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
44 struct btrfs_fs_info *fs_info, 44 struct btrfs_fs_info *fs_info,
45 struct btrfs_device *srcdev, 45 struct btrfs_device *srcdev,
46 struct btrfs_device *tgtdev); 46 struct btrfs_device *tgtdev);
47static int btrfs_dev_replace_find_srcdev(struct btrfs_root *root, u64 srcdevid,
48 char *srcdev_name,
49 struct btrfs_device **device);
50static u64 __btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info); 47static u64 __btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info);
51static int btrfs_dev_replace_kthread(void *data); 48static int btrfs_dev_replace_kthread(void *data);
52static int btrfs_dev_replace_continue_on_mount(struct btrfs_fs_info *fs_info); 49static int btrfs_dev_replace_continue_on_mount(struct btrfs_fs_info *fs_info);
@@ -305,8 +302,8 @@ void btrfs_after_dev_replace_commit(struct btrfs_fs_info *fs_info)
305 dev_replace->cursor_left_last_write_of_item; 302 dev_replace->cursor_left_last_write_of_item;
306} 303}
307 304
308int btrfs_dev_replace_start(struct btrfs_root *root, 305int btrfs_dev_replace_start(struct btrfs_root *root, char *tgtdev_name,
309 struct btrfs_ioctl_dev_replace_args *args) 306 u64 srcdevid, char *srcdev_name, int read_src)
310{ 307{
311 struct btrfs_trans_handle *trans; 308 struct btrfs_trans_handle *trans;
312 struct btrfs_fs_info *fs_info = root->fs_info; 309 struct btrfs_fs_info *fs_info = root->fs_info;
@@ -315,29 +312,16 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
315 struct btrfs_device *tgt_device = NULL; 312 struct btrfs_device *tgt_device = NULL;
316 struct btrfs_device *src_device = NULL; 313 struct btrfs_device *src_device = NULL;
317 314
318 switch (args->start.cont_reading_from_srcdev_mode) {
319 case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS:
320 case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID:
321 break;
322 default:
323 return -EINVAL;
324 }
325
326 if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') ||
327 args->start.tgtdev_name[0] == '\0')
328 return -EINVAL;
329
330 /* the disk copy procedure reuses the scrub code */ 315 /* the disk copy procedure reuses the scrub code */
331 mutex_lock(&fs_info->volume_mutex); 316 mutex_lock(&fs_info->volume_mutex);
332 ret = btrfs_dev_replace_find_srcdev(root, args->start.srcdevid, 317 ret = btrfs_find_device_by_devspec(root, srcdevid,
333 args->start.srcdev_name, 318 srcdev_name, &src_device);
334 &src_device);
335 if (ret) { 319 if (ret) {
336 mutex_unlock(&fs_info->volume_mutex); 320 mutex_unlock(&fs_info->volume_mutex);
337 return ret; 321 return ret;
338 } 322 }
339 323
340 ret = btrfs_init_dev_replace_tgtdev(root, args->start.tgtdev_name, 324 ret = btrfs_init_dev_replace_tgtdev(root, tgtdev_name,
341 src_device, &tgt_device); 325 src_device, &tgt_device);
342 mutex_unlock(&fs_info->volume_mutex); 326 mutex_unlock(&fs_info->volume_mutex);
343 if (ret) 327 if (ret)
@@ -364,18 +348,17 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
364 break; 348 break;
365 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: 349 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
366 case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: 350 case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
367 args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED; 351 ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED;
368 goto leave; 352 goto leave;
369 } 353 }
370 354
371 dev_replace->cont_reading_from_srcdev_mode = 355 dev_replace->cont_reading_from_srcdev_mode = read_src;
372 args->start.cont_reading_from_srcdev_mode;
373 WARN_ON(!src_device); 356 WARN_ON(!src_device);
374 dev_replace->srcdev = src_device; 357 dev_replace->srcdev = src_device;
375 WARN_ON(!tgt_device); 358 WARN_ON(!tgt_device);
376 dev_replace->tgtdev = tgt_device; 359 dev_replace->tgtdev = tgt_device;
377 360
378 btrfs_info_in_rcu(root->fs_info, 361 btrfs_info_in_rcu(fs_info,
379 "dev_replace from %s (devid %llu) to %s started", 362 "dev_replace from %s (devid %llu) to %s started",
380 src_device->missing ? "<missing disk>" : 363 src_device->missing ? "<missing disk>" :
381 rcu_str_deref(src_device->name), 364 rcu_str_deref(src_device->name),
@@ -396,14 +379,13 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
396 dev_replace->item_needs_writeback = 1; 379 dev_replace->item_needs_writeback = 1;
397 atomic64_set(&dev_replace->num_write_errors, 0); 380 atomic64_set(&dev_replace->num_write_errors, 0);
398 atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); 381 atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0);
399 args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
400 btrfs_dev_replace_unlock(dev_replace, 1); 382 btrfs_dev_replace_unlock(dev_replace, 1);
401 383
402 ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); 384 ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device);
403 if (ret) 385 if (ret)
404 btrfs_err(root->fs_info, "kobj add dev failed %d\n", ret); 386 btrfs_err(fs_info, "kobj add dev failed %d\n", ret);
405 387
406 btrfs_wait_ordered_roots(root->fs_info, -1); 388 btrfs_wait_ordered_roots(fs_info, -1);
407 389
408 /* force writing the updated state information to disk */ 390 /* force writing the updated state information to disk */
409 trans = btrfs_start_transaction(root, 0); 391 trans = btrfs_start_transaction(root, 0);
@@ -421,11 +403,9 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
421 btrfs_device_get_total_bytes(src_device), 403 btrfs_device_get_total_bytes(src_device),
422 &dev_replace->scrub_progress, 0, 1); 404 &dev_replace->scrub_progress, 0, 1);
423 405
424 ret = btrfs_dev_replace_finishing(root->fs_info, ret); 406 ret = btrfs_dev_replace_finishing(fs_info, ret);
425 /* don't warn if EINPROGRESS, someone else might be running scrub */
426 if (ret == -EINPROGRESS) { 407 if (ret == -EINPROGRESS) {
427 args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS; 408 ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS;
428 ret = 0;
429 } else { 409 } else {
430 WARN_ON(ret); 410 WARN_ON(ret);
431 } 411 }
@@ -440,6 +420,35 @@ leave:
440 return ret; 420 return ret;
441} 421}
442 422
423int btrfs_dev_replace_by_ioctl(struct btrfs_root *root,
424 struct btrfs_ioctl_dev_replace_args *args)
425{
426 int ret;
427
428 switch (args->start.cont_reading_from_srcdev_mode) {
429 case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS:
430 case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID:
431 break;
432 default:
433 return -EINVAL;
434 }
435
436 if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') ||
437 args->start.tgtdev_name[0] == '\0')
438 return -EINVAL;
439
440 ret = btrfs_dev_replace_start(root, args->start.tgtdev_name,
441 args->start.srcdevid,
442 args->start.srcdev_name,
443 args->start.cont_reading_from_srcdev_mode);
444 args->result = ret;
445 /* don't warn if EINPROGRESS, someone else might be running scrub */
446 if (ret == BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS)
447 ret = 0;
448
449 return ret;
450}
451
443/* 452/*
444 * blocked until all flighting bios are finished. 453 * blocked until all flighting bios are finished.
445 */ 454 */
@@ -560,10 +569,9 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
560 ASSERT(list_empty(&src_device->resized_list)); 569 ASSERT(list_empty(&src_device->resized_list));
561 tgt_device->commit_total_bytes = src_device->commit_total_bytes; 570 tgt_device->commit_total_bytes = src_device->commit_total_bytes;
562 tgt_device->commit_bytes_used = src_device->bytes_used; 571 tgt_device->commit_bytes_used = src_device->bytes_used;
563 if (fs_info->sb->s_bdev == src_device->bdev) 572
564 fs_info->sb->s_bdev = tgt_device->bdev; 573 btrfs_assign_next_active_device(fs_info, src_device, tgt_device);
565 if (fs_info->fs_devices->latest_bdev == src_device->bdev) 574
566 fs_info->fs_devices->latest_bdev = tgt_device->bdev;
567 list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); 575 list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);
568 fs_info->fs_devices->rw_devices++; 576 fs_info->fs_devices->rw_devices++;
569 577
@@ -626,25 +634,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
626 write_unlock(&em_tree->lock); 634 write_unlock(&em_tree->lock);
627} 635}
628 636
629static int btrfs_dev_replace_find_srcdev(struct btrfs_root *root, u64 srcdevid,
630 char *srcdev_name,
631 struct btrfs_device **device)
632{
633 int ret;
634
635 if (srcdevid) {
636 ret = 0;
637 *device = btrfs_find_device(root->fs_info, srcdevid, NULL,
638 NULL);
639 if (!*device)
640 ret = -ENOENT;
641 } else {
642 ret = btrfs_find_device_missing_or_by_path(root, srcdev_name,
643 device);
644 }
645 return ret;
646}
647
648void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, 637void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
649 struct btrfs_ioctl_dev_replace_args *args) 638 struct btrfs_ioctl_dev_replace_args *args)
650{ 639{
diff --git a/fs/btrfs/dev-replace.h b/fs/btrfs/dev-replace.h
index 29e3ef5f96bd..e922b42d91df 100644
--- a/fs/btrfs/dev-replace.h
+++ b/fs/btrfs/dev-replace.h
@@ -25,8 +25,10 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info);
25int btrfs_run_dev_replace(struct btrfs_trans_handle *trans, 25int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
26 struct btrfs_fs_info *fs_info); 26 struct btrfs_fs_info *fs_info);
27void btrfs_after_dev_replace_commit(struct btrfs_fs_info *fs_info); 27void btrfs_after_dev_replace_commit(struct btrfs_fs_info *fs_info);
28int btrfs_dev_replace_start(struct btrfs_root *root, 28int btrfs_dev_replace_by_ioctl(struct btrfs_root *root,
29 struct btrfs_ioctl_dev_replace_args *args); 29 struct btrfs_ioctl_dev_replace_args *args);
30int btrfs_dev_replace_start(struct btrfs_root *root, char *tgtdev_name,
31 u64 srcdevid, char *srcdev_name, int read_src);
30void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, 32void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
31 struct btrfs_ioctl_dev_replace_args *args); 33 struct btrfs_ioctl_dev_replace_args *args);
32int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info, 34int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index b0ccb3b03d94..aa97dfe8ae70 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2676,6 +2676,60 @@ out:
2676 return ret; 2676 return ret;
2677} 2677}
2678 2678
2679static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
2680{
2681 struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
2682 struct btrfs_ioctl_vol_args_v2 *vol_args;
2683 int ret;
2684
2685 if (!capable(CAP_SYS_ADMIN))
2686 return -EPERM;
2687
2688 ret = mnt_want_write_file(file);
2689 if (ret)
2690 return ret;
2691
2692 vol_args = memdup_user(arg, sizeof(*vol_args));
2693 if (IS_ERR(vol_args)) {
2694 ret = PTR_ERR(vol_args);
2695 goto err_drop;
2696 }
2697
2698 /* Check for compatibility reject unknown flags */
2699 if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED)
2700 return -EOPNOTSUPP;
2701
2702 if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
2703 1)) {
2704 ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
2705 goto out;
2706 }
2707
2708 mutex_lock(&root->fs_info->volume_mutex);
2709 if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID) {
2710 ret = btrfs_rm_device(root, NULL, vol_args->devid);
2711 } else {
2712 vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
2713 ret = btrfs_rm_device(root, vol_args->name, 0);
2714 }
2715 mutex_unlock(&root->fs_info->volume_mutex);
2716 atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
2717
2718 if (!ret) {
2719 if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID)
2720 btrfs_info(root->fs_info, "device deleted: id %llu",
2721 vol_args->devid);
2722 else
2723 btrfs_info(root->fs_info, "device deleted: %s",
2724 vol_args->name);
2725 }
2726out:
2727 kfree(vol_args);
2728err_drop:
2729 mnt_drop_write_file(file);
2730 return ret;
2731}
2732
2679static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) 2733static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
2680{ 2734{
2681 struct btrfs_root *root = BTRFS_I(file_inode(file))->root; 2735 struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
@@ -2703,7 +2757,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
2703 2757
2704 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 2758 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
2705 mutex_lock(&root->fs_info->volume_mutex); 2759 mutex_lock(&root->fs_info->volume_mutex);
2706 ret = btrfs_rm_device(root, vol_args->name); 2760 ret = btrfs_rm_device(root, vol_args->name, 0);
2707 mutex_unlock(&root->fs_info->volume_mutex); 2761 mutex_unlock(&root->fs_info->volume_mutex);
2708 2762
2709 if (!ret) 2763 if (!ret)
@@ -4387,7 +4441,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg)
4387 1)) { 4441 1)) {
4388 ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; 4442 ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
4389 } else { 4443 } else {
4390 ret = btrfs_dev_replace_start(root, p); 4444 ret = btrfs_dev_replace_by_ioctl(root, p);
4391 atomic_set( 4445 atomic_set(
4392 &root->fs_info->mutually_exclusive_operation_running, 4446 &root->fs_info->mutually_exclusive_operation_running,
4393 0); 4447 0);
@@ -5480,6 +5534,8 @@ long btrfs_ioctl(struct file *file, unsigned int
5480 return btrfs_ioctl_add_dev(root, argp); 5534 return btrfs_ioctl_add_dev(root, argp);
5481 case BTRFS_IOC_RM_DEV: 5535 case BTRFS_IOC_RM_DEV:
5482 return btrfs_ioctl_rm_dev(file, argp); 5536 return btrfs_ioctl_rm_dev(file, argp);
5537 case BTRFS_IOC_RM_DEV_V2:
5538 return btrfs_ioctl_rm_dev_v2(file, argp);
5483 case BTRFS_IOC_FS_INFO: 5539 case BTRFS_IOC_FS_INFO:
5484 return btrfs_ioctl_fs_info(root, argp); 5540 return btrfs_ioctl_fs_info(root, argp);
5485 case BTRFS_IOC_DEV_INFO: 5541 case BTRFS_IOC_DEV_INFO:
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index dff515a134cd..e0290303bb35 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -118,6 +118,21 @@ const u64 btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
118 [BTRFS_RAID_RAID6] = BTRFS_BLOCK_GROUP_RAID6, 118 [BTRFS_RAID_RAID6] = BTRFS_BLOCK_GROUP_RAID6,
119}; 119};
120 120
121/*
122 * Table to convert BTRFS_RAID_* to the error code if minimum number of devices
123 * condition is not met. Zero means there's no corresponding
124 * BTRFS_ERROR_DEV_*_NOT_MET value.
125 */
126const int btrfs_raid_mindev_error[BTRFS_NR_RAID_TYPES] = {
127 [BTRFS_RAID_RAID10] = BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET,
128 [BTRFS_RAID_RAID1] = BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET,
129 [BTRFS_RAID_DUP] = 0,
130 [BTRFS_RAID_RAID0] = 0,
131 [BTRFS_RAID_SINGLE] = 0,
132 [BTRFS_RAID_RAID5] = BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET,
133 [BTRFS_RAID_RAID6] = BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET,
134};
135
121static int init_first_rw_device(struct btrfs_trans_handle *trans, 136static int init_first_rw_device(struct btrfs_trans_handle *trans,
122 struct btrfs_root *root, 137 struct btrfs_root *root,
123 struct btrfs_device *device); 138 struct btrfs_device *device);
@@ -699,7 +714,8 @@ static noinline int device_list_add(const char *path,
699 * if there is new btrfs on an already registered device, 714 * if there is new btrfs on an already registered device,
700 * then remove the stale device entry. 715 * then remove the stale device entry.
701 */ 716 */
702 btrfs_free_stale_device(device); 717 if (ret > 0)
718 btrfs_free_stale_device(device);
703 719
704 *fs_devices_ret = fs_devices; 720 *fs_devices_ret = fs_devices;
705 721
@@ -988,6 +1004,56 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
988 return ret; 1004 return ret;
989} 1005}
990 1006
1007void btrfs_release_disk_super(struct page *page)
1008{
1009 kunmap(page);
1010 put_page(page);
1011}
1012
1013int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
1014 struct page **page, struct btrfs_super_block **disk_super)
1015{
1016 void *p;
1017 pgoff_t index;
1018
1019 /* make sure our super fits in the device */
1020 if (bytenr + PAGE_SIZE >= i_size_read(bdev->bd_inode))
1021 return 1;
1022
1023 /* make sure our super fits in the page */
1024 if (sizeof(**disk_super) > PAGE_SIZE)
1025 return 1;
1026
1027 /* make sure our super doesn't straddle pages on disk */
1028 index = bytenr >> PAGE_SHIFT;
1029 if ((bytenr + sizeof(**disk_super) - 1) >> PAGE_SHIFT != index)
1030 return 1;
1031
1032 /* pull in the page with our super */
1033 *page = read_cache_page_gfp(bdev->bd_inode->i_mapping,
1034 index, GFP_KERNEL);
1035
1036 if (IS_ERR_OR_NULL(*page))
1037 return 1;
1038
1039 p = kmap(*page);
1040
1041 /* align our pointer to the offset of the super block */
1042 *disk_super = p + (bytenr & ~PAGE_MASK);
1043
1044 if (btrfs_super_bytenr(*disk_super) != bytenr ||
1045 btrfs_super_magic(*disk_super) != BTRFS_MAGIC) {
1046 btrfs_release_disk_super(*page);
1047 return 1;
1048 }
1049
1050 if ((*disk_super)->label[0] &&
1051 (*disk_super)->label[BTRFS_LABEL_SIZE - 1])
1052 (*disk_super)->label[BTRFS_LABEL_SIZE - 1] = '\0';
1053
1054 return 0;
1055}
1056
991/* 1057/*
992 * Look for a btrfs signature on a device. This may be called out of the mount path 1058 * Look for a btrfs signature on a device. This may be called out of the mount path
993 * and we are not allowed to call set_blocksize during the scan. The superblock 1059 * and we are not allowed to call set_blocksize during the scan. The superblock
@@ -999,13 +1065,11 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
999 struct btrfs_super_block *disk_super; 1065 struct btrfs_super_block *disk_super;
1000 struct block_device *bdev; 1066 struct block_device *bdev;
1001 struct page *page; 1067 struct page *page;
1002 void *p;
1003 int ret = -EINVAL; 1068 int ret = -EINVAL;
1004 u64 devid; 1069 u64 devid;
1005 u64 transid; 1070 u64 transid;
1006 u64 total_devices; 1071 u64 total_devices;
1007 u64 bytenr; 1072 u64 bytenr;
1008 pgoff_t index;
1009 1073
1010 /* 1074 /*
1011 * we would like to check all the supers, but that would make 1075 * we would like to check all the supers, but that would make
@@ -1018,41 +1082,14 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
1018 mutex_lock(&uuid_mutex); 1082 mutex_lock(&uuid_mutex);
1019 1083
1020 bdev = blkdev_get_by_path(path, flags, holder); 1084 bdev = blkdev_get_by_path(path, flags, holder);
1021
1022 if (IS_ERR(bdev)) { 1085 if (IS_ERR(bdev)) {
1023 ret = PTR_ERR(bdev); 1086 ret = PTR_ERR(bdev);
1024 goto error; 1087 goto error;
1025 } 1088 }
1026 1089
1027 /* make sure our super fits in the device */ 1090 if (btrfs_read_disk_super(bdev, bytenr, &page, &disk_super))
1028 if (bytenr + PAGE_SIZE >= i_size_read(bdev->bd_inode))
1029 goto error_bdev_put;
1030
1031 /* make sure our super fits in the page */
1032 if (sizeof(*disk_super) > PAGE_SIZE)
1033 goto error_bdev_put; 1091 goto error_bdev_put;
1034 1092
1035 /* make sure our super doesn't straddle pages on disk */
1036 index = bytenr >> PAGE_SHIFT;
1037 if ((bytenr + sizeof(*disk_super) - 1) >> PAGE_SHIFT != index)
1038 goto error_bdev_put;
1039
1040 /* pull in the page with our super */
1041 page = read_cache_page_gfp(bdev->bd_inode->i_mapping,
1042 index, GFP_NOFS);
1043
1044 if (IS_ERR_OR_NULL(page))
1045 goto error_bdev_put;
1046
1047 p = kmap(page);
1048
1049 /* align our pointer to the offset of the super block */
1050 disk_super = p + (bytenr & ~PAGE_MASK);
1051
1052 if (btrfs_super_bytenr(disk_super) != bytenr ||
1053 btrfs_super_magic(disk_super) != BTRFS_MAGIC)
1054 goto error_unmap;
1055
1056 devid = btrfs_stack_device_id(&disk_super->dev_item); 1093 devid = btrfs_stack_device_id(&disk_super->dev_item);
1057 transid = btrfs_super_generation(disk_super); 1094 transid = btrfs_super_generation(disk_super);
1058 total_devices = btrfs_super_num_devices(disk_super); 1095 total_devices = btrfs_super_num_devices(disk_super);
@@ -1060,8 +1097,6 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
1060 ret = device_list_add(path, disk_super, devid, fs_devices_ret); 1097 ret = device_list_add(path, disk_super, devid, fs_devices_ret);
1061 if (ret > 0) { 1098 if (ret > 0) {
1062 if (disk_super->label[0]) { 1099 if (disk_super->label[0]) {
1063 if (disk_super->label[BTRFS_LABEL_SIZE - 1])
1064 disk_super->label[BTRFS_LABEL_SIZE - 1] = '\0';
1065 printk(KERN_INFO "BTRFS: device label %s ", disk_super->label); 1100 printk(KERN_INFO "BTRFS: device label %s ", disk_super->label);
1066 } else { 1101 } else {
1067 printk(KERN_INFO "BTRFS: device fsid %pU ", disk_super->fsid); 1102 printk(KERN_INFO "BTRFS: device fsid %pU ", disk_super->fsid);
@@ -1073,9 +1108,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
1073 if (!ret && fs_devices_ret) 1108 if (!ret && fs_devices_ret)
1074 (*fs_devices_ret)->total_devices = total_devices; 1109 (*fs_devices_ret)->total_devices = total_devices;
1075 1110
1076error_unmap: 1111 btrfs_release_disk_super(page);
1077 kunmap(page);
1078 put_page(page);
1079 1112
1080error_bdev_put: 1113error_bdev_put:
1081 blkdev_put(bdev, flags); 1114 blkdev_put(bdev, flags);
@@ -1688,32 +1721,92 @@ out:
1688 return ret; 1721 return ret;
1689} 1722}
1690 1723
1691int btrfs_rm_device(struct btrfs_root *root, char *device_path) 1724/*
1725 * Verify that @num_devices satisfies the RAID profile constraints in the whole
1726 * filesystem. It's up to the caller to adjust that number regarding eg. device
1727 * replace.
1728 */
1729static int btrfs_check_raid_min_devices(struct btrfs_fs_info *fs_info,
1730 u64 num_devices)
1731{
1732 u64 all_avail;
1733 unsigned seq;
1734 int i;
1735
1736 do {
1737 seq = read_seqbegin(&fs_info->profiles_lock);
1738
1739 all_avail = fs_info->avail_data_alloc_bits |
1740 fs_info->avail_system_alloc_bits |
1741 fs_info->avail_metadata_alloc_bits;
1742 } while (read_seqretry(&fs_info->profiles_lock, seq));
1743
1744 for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) {
1745 if (!(all_avail & btrfs_raid_group[i]))
1746 continue;
1747
1748 if (num_devices < btrfs_raid_array[i].devs_min) {
1749 int ret = btrfs_raid_mindev_error[i];
1750
1751 if (ret)
1752 return ret;
1753 }
1754 }
1755
1756 return 0;
1757}
1758
1759struct btrfs_device *btrfs_find_next_active_device(struct btrfs_fs_devices *fs_devs,
1760 struct btrfs_device *device)
1692{ 1761{
1693 struct btrfs_device *device;
1694 struct btrfs_device *next_device; 1762 struct btrfs_device *next_device;
1695 struct block_device *bdev; 1763
1696 struct buffer_head *bh = NULL; 1764 list_for_each_entry(next_device, &fs_devs->devices, dev_list) {
1697 struct btrfs_super_block *disk_super; 1765 if (next_device != device &&
1766 !next_device->missing && next_device->bdev)
1767 return next_device;
1768 }
1769
1770 return NULL;
1771}
1772
1773/*
1774 * Helper function to check if the given device is part of s_bdev / latest_bdev
1775 * and replace it with the provided or the next active device, in the context
1776 * where this function called, there should be always be another device (or
1777 * this_dev) which is active.
1778 */
1779void btrfs_assign_next_active_device(struct btrfs_fs_info *fs_info,
1780 struct btrfs_device *device, struct btrfs_device *this_dev)
1781{
1782 struct btrfs_device *next_device;
1783
1784 if (this_dev)
1785 next_device = this_dev;
1786 else
1787 next_device = btrfs_find_next_active_device(fs_info->fs_devices,
1788 device);
1789 ASSERT(next_device);
1790
1791 if (fs_info->sb->s_bdev &&
1792 (fs_info->sb->s_bdev == device->bdev))
1793 fs_info->sb->s_bdev = next_device->bdev;
1794
1795 if (fs_info->fs_devices->latest_bdev == device->bdev)
1796 fs_info->fs_devices->latest_bdev = next_device->bdev;
1797}
1798
1799int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
1800{
1801 struct btrfs_device *device;
1698 struct btrfs_fs_devices *cur_devices; 1802 struct btrfs_fs_devices *cur_devices;
1699 u64 all_avail;
1700 u64 devid;
1701 u64 num_devices; 1803 u64 num_devices;
1702 u8 *dev_uuid;
1703 unsigned seq;
1704 int ret = 0; 1804 int ret = 0;
1705 bool clear_super = false; 1805 bool clear_super = false;
1806 char *dev_name = NULL;
1706 1807
1707 mutex_lock(&uuid_mutex); 1808 mutex_lock(&uuid_mutex);
1708 1809
1709 do {
1710 seq = read_seqbegin(&root->fs_info->profiles_lock);
1711
1712 all_avail = root->fs_info->avail_data_alloc_bits |
1713 root->fs_info->avail_system_alloc_bits |
1714 root->fs_info->avail_metadata_alloc_bits;
1715 } while (read_seqretry(&root->fs_info->profiles_lock, seq));
1716
1717 num_devices = root->fs_info->fs_devices->num_devices; 1810 num_devices = root->fs_info->fs_devices->num_devices;
1718 btrfs_dev_replace_lock(&root->fs_info->dev_replace, 0); 1811 btrfs_dev_replace_lock(&root->fs_info->dev_replace, 0);
1719 if (btrfs_dev_replace_is_ongoing(&root->fs_info->dev_replace)) { 1812 if (btrfs_dev_replace_is_ongoing(&root->fs_info->dev_replace)) {
@@ -1722,78 +1815,23 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1722 } 1815 }
1723 btrfs_dev_replace_unlock(&root->fs_info->dev_replace, 0); 1816 btrfs_dev_replace_unlock(&root->fs_info->dev_replace, 0);
1724 1817
1725 if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) && num_devices <= 4) { 1818 ret = btrfs_check_raid_min_devices(root->fs_info, num_devices - 1);
1726 ret = BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET; 1819 if (ret)
1727 goto out;
1728 }
1729
1730 if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) && num_devices <= 2) {
1731 ret = BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET;
1732 goto out; 1820 goto out;
1733 }
1734 1821
1735 if ((all_avail & BTRFS_BLOCK_GROUP_RAID5) && 1822 ret = btrfs_find_device_by_devspec(root, devid, device_path,
1736 root->fs_info->fs_devices->rw_devices <= 2) { 1823 &device);
1737 ret = BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET; 1824 if (ret)
1738 goto out;
1739 }
1740 if ((all_avail & BTRFS_BLOCK_GROUP_RAID6) &&
1741 root->fs_info->fs_devices->rw_devices <= 3) {
1742 ret = BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET;
1743 goto out; 1825 goto out;
1744 }
1745
1746 if (strcmp(device_path, "missing") == 0) {
1747 struct list_head *devices;
1748 struct btrfs_device *tmp;
1749
1750 device = NULL;
1751 devices = &root->fs_info->fs_devices->devices;
1752 /*
1753 * It is safe to read the devices since the volume_mutex
1754 * is held.
1755 */
1756 list_for_each_entry(tmp, devices, dev_list) {
1757 if (tmp->in_fs_metadata &&
1758 !tmp->is_tgtdev_for_dev_replace &&
1759 !tmp->bdev) {
1760 device = tmp;
1761 break;
1762 }
1763 }
1764 bdev = NULL;
1765 bh = NULL;
1766 disk_super = NULL;
1767 if (!device) {
1768 ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
1769 goto out;
1770 }
1771 } else {
1772 ret = btrfs_get_bdev_and_sb(device_path,
1773 FMODE_WRITE | FMODE_EXCL,
1774 root->fs_info->bdev_holder, 0,
1775 &bdev, &bh);
1776 if (ret)
1777 goto out;
1778 disk_super = (struct btrfs_super_block *)bh->b_data;
1779 devid = btrfs_stack_device_id(&disk_super->dev_item);
1780 dev_uuid = disk_super->dev_item.uuid;
1781 device = btrfs_find_device(root->fs_info, devid, dev_uuid,
1782 disk_super->fsid);
1783 if (!device) {
1784 ret = -ENOENT;
1785 goto error_brelse;
1786 }
1787 }
1788 1826
1789 if (device->is_tgtdev_for_dev_replace) { 1827 if (device->is_tgtdev_for_dev_replace) {
1790 ret = BTRFS_ERROR_DEV_TGT_REPLACE; 1828 ret = BTRFS_ERROR_DEV_TGT_REPLACE;
1791 goto error_brelse; 1829 goto out;
1792 } 1830 }
1793 1831
1794 if (device->writeable && root->fs_info->fs_devices->rw_devices == 1) { 1832 if (device->writeable && root->fs_info->fs_devices->rw_devices == 1) {
1795 ret = BTRFS_ERROR_DEV_ONLY_WRITABLE; 1833 ret = BTRFS_ERROR_DEV_ONLY_WRITABLE;
1796 goto error_brelse; 1834 goto out;
1797 } 1835 }
1798 1836
1799 if (device->writeable) { 1837 if (device->writeable) {
@@ -1801,6 +1839,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1801 list_del_init(&device->dev_alloc_list); 1839 list_del_init(&device->dev_alloc_list);
1802 device->fs_devices->rw_devices--; 1840 device->fs_devices->rw_devices--;
1803 unlock_chunks(root); 1841 unlock_chunks(root);
1842 dev_name = kstrdup(device->name->str, GFP_KERNEL);
1843 if (!dev_name) {
1844 ret = -ENOMEM;
1845 goto error_undo;
1846 }
1804 clear_super = true; 1847 clear_super = true;
1805 } 1848 }
1806 1849
@@ -1842,12 +1885,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1842 if (device->missing) 1885 if (device->missing)
1843 device->fs_devices->missing_devices--; 1886 device->fs_devices->missing_devices--;
1844 1887
1845 next_device = list_entry(root->fs_info->fs_devices->devices.next, 1888 btrfs_assign_next_active_device(root->fs_info, device, NULL);
1846 struct btrfs_device, dev_list);
1847 if (device->bdev == root->fs_info->sb->s_bdev)
1848 root->fs_info->sb->s_bdev = next_device->bdev;
1849 if (device->bdev == root->fs_info->fs_devices->latest_bdev)
1850 root->fs_info->fs_devices->latest_bdev = next_device->bdev;
1851 1889
1852 if (device->bdev) { 1890 if (device->bdev) {
1853 device->fs_devices->open_devices--; 1891 device->fs_devices->open_devices--;
@@ -1883,63 +1921,23 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1883 * at this point, the device is zero sized. We want to 1921 * at this point, the device is zero sized. We want to
1884 * remove it from the devices list and zero out the old super 1922 * remove it from the devices list and zero out the old super
1885 */ 1923 */
1886 if (clear_super && disk_super) { 1924 if (clear_super) {
1887 u64 bytenr; 1925 struct block_device *bdev;
1888 int i; 1926
1889 1927 bdev = blkdev_get_by_path(dev_name, FMODE_READ | FMODE_EXCL,
1890 /* make sure this device isn't detected as part of 1928 root->fs_info->bdev_holder);
1891 * the FS anymore 1929 if (!IS_ERR(bdev)) {
1892 */ 1930 btrfs_scratch_superblocks(bdev, dev_name);
1893 memset(&disk_super->magic, 0, sizeof(disk_super->magic)); 1931 blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
1894 set_buffer_dirty(bh);
1895 sync_dirty_buffer(bh);
1896
1897 /* clear the mirror copies of super block on the disk
1898 * being removed, 0th copy is been taken care above and
1899 * the below would take of the rest
1900 */
1901 for (i = 1; i < BTRFS_SUPER_MIRROR_MAX; i++) {
1902 bytenr = btrfs_sb_offset(i);
1903 if (bytenr + BTRFS_SUPER_INFO_SIZE >=
1904 i_size_read(bdev->bd_inode))
1905 break;
1906
1907 brelse(bh);
1908 bh = __bread(bdev, bytenr / 4096,
1909 BTRFS_SUPER_INFO_SIZE);
1910 if (!bh)
1911 continue;
1912
1913 disk_super = (struct btrfs_super_block *)bh->b_data;
1914
1915 if (btrfs_super_bytenr(disk_super) != bytenr ||
1916 btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
1917 continue;
1918 }
1919 memset(&disk_super->magic, 0,
1920 sizeof(disk_super->magic));
1921 set_buffer_dirty(bh);
1922 sync_dirty_buffer(bh);
1923 } 1932 }
1924 } 1933 }
1925 1934
1926 ret = 0;
1927
1928 if (bdev) {
1929 /* Notify udev that device has changed */
1930 btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
1931
1932 /* Update ctime/mtime for device path for libblkid */
1933 update_dev_time(device_path);
1934 }
1935
1936error_brelse:
1937 brelse(bh);
1938 if (bdev)
1939 blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
1940out: 1935out:
1936 kfree(dev_name);
1937
1941 mutex_unlock(&uuid_mutex); 1938 mutex_unlock(&uuid_mutex);
1942 return ret; 1939 return ret;
1940
1943error_undo: 1941error_undo:
1944 if (device->writeable) { 1942 if (device->writeable) {
1945 lock_chunks(root); 1943 lock_chunks(root);
@@ -1948,7 +1946,7 @@ error_undo:
1948 device->fs_devices->rw_devices++; 1946 device->fs_devices->rw_devices++;
1949 unlock_chunks(root); 1947 unlock_chunks(root);
1950 } 1948 }
1951 goto error_brelse; 1949 goto out;
1952} 1950}
1953 1951
1954void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info, 1952void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
@@ -2017,8 +2015,6 @@ void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info,
2017void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, 2015void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
2018 struct btrfs_device *tgtdev) 2016 struct btrfs_device *tgtdev)
2019{ 2017{
2020 struct btrfs_device *next_device;
2021
2022 mutex_lock(&uuid_mutex); 2018 mutex_lock(&uuid_mutex);
2023 WARN_ON(!tgtdev); 2019 WARN_ON(!tgtdev);
2024 mutex_lock(&fs_info->fs_devices->device_list_mutex); 2020 mutex_lock(&fs_info->fs_devices->device_list_mutex);
@@ -2030,12 +2026,8 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
2030 2026
2031 fs_info->fs_devices->num_devices--; 2027 fs_info->fs_devices->num_devices--;
2032 2028
2033 next_device = list_entry(fs_info->fs_devices->devices.next, 2029 btrfs_assign_next_active_device(fs_info, tgtdev, NULL);
2034 struct btrfs_device, dev_list); 2030
2035 if (tgtdev->bdev == fs_info->sb->s_bdev)
2036 fs_info->sb->s_bdev = next_device->bdev;
2037 if (tgtdev->bdev == fs_info->fs_devices->latest_bdev)
2038 fs_info->fs_devices->latest_bdev = next_device->bdev;
2039 list_del_rcu(&tgtdev->dev_list); 2031 list_del_rcu(&tgtdev->dev_list);
2040 2032
2041 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 2033 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
@@ -2110,6 +2102,31 @@ int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
2110} 2102}
2111 2103
2112/* 2104/*
2105 * Lookup a device given by device id, or the path if the id is 0.
2106 */
2107int btrfs_find_device_by_devspec(struct btrfs_root *root, u64 devid,
2108 char *devpath,
2109 struct btrfs_device **device)
2110{
2111 int ret;
2112
2113 if (devid) {
2114 ret = 0;
2115 *device = btrfs_find_device(root->fs_info, devid, NULL,
2116 NULL);
2117 if (!*device)
2118 ret = -ENOENT;
2119 } else {
2120 if (!devpath || !devpath[0])
2121 return -EINVAL;
2122
2123 ret = btrfs_find_device_missing_or_by_path(root, devpath,
2124 device);
2125 }
2126 return ret;
2127}
2128
2129/*
2113 * does all the dirty work required for changing file system's UUID. 2130 * does all the dirty work required for changing file system's UUID.
2114 */ 2131 */
2115static int btrfs_prepare_sprout(struct btrfs_root *root) 2132static int btrfs_prepare_sprout(struct btrfs_root *root)
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 7507be74f7da..19f6bb861640 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -340,7 +340,7 @@ struct btrfs_raid_attr {
340}; 340};
341 341
342extern const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES]; 342extern const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES];
343 343extern const int btrfs_raid_mindev_error[BTRFS_NR_RAID_TYPES];
344extern const u64 btrfs_raid_group[BTRFS_NR_RAID_TYPES]; 344extern const u64 btrfs_raid_group[BTRFS_NR_RAID_TYPES];
345 345
346struct map_lookup { 346struct map_lookup {
@@ -445,13 +445,18 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
445 struct btrfs_fs_devices **fs_devices_ret); 445 struct btrfs_fs_devices **fs_devices_ret);
446int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); 446int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
447void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices, int step); 447void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices, int step);
448void btrfs_assign_next_active_device(struct btrfs_fs_info *fs_info,
449 struct btrfs_device *device, struct btrfs_device *this_dev);
448int btrfs_find_device_missing_or_by_path(struct btrfs_root *root, 450int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
449 char *device_path, 451 char *device_path,
450 struct btrfs_device **device); 452 struct btrfs_device **device);
453int btrfs_find_device_by_devspec(struct btrfs_root *root, u64 devid,
454 char *devpath,
455 struct btrfs_device **device);
451struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, 456struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
452 const u64 *devid, 457 const u64 *devid,
453 const u8 *uuid); 458 const u8 *uuid);
454int btrfs_rm_device(struct btrfs_root *root, char *device_path); 459int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid);
455void btrfs_cleanup_fs_uuids(void); 460void btrfs_cleanup_fs_uuids(void);
456int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len); 461int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
457int btrfs_grow_device(struct btrfs_trans_handle *trans, 462int btrfs_grow_device(struct btrfs_trans_handle *trans,
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index dea893199257..3975e683af72 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -36,6 +36,14 @@ struct btrfs_ioctl_vol_args {
36#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) 36#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
37#define BTRFS_SUBVOL_RDONLY (1ULL << 1) 37#define BTRFS_SUBVOL_RDONLY (1ULL << 1)
38#define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2) 38#define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2)
39#define BTRFS_DEVICE_SPEC_BY_ID (1ULL << 3)
40
41#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED \
42 (BTRFS_SUBVOL_CREATE_ASYNC | \
43 BTRFS_SUBVOL_RDONLY | \
44 BTRFS_SUBVOL_QGROUP_INHERIT | \
45 BTRFS_DEVICE_SPEC_BY_ID)
46
39#define BTRFS_FSID_SIZE 16 47#define BTRFS_FSID_SIZE 16
40#define BTRFS_UUID_SIZE 16 48#define BTRFS_UUID_SIZE 16
41#define BTRFS_UUID_UNPARSED_SIZE 37 49#define BTRFS_UUID_UNPARSED_SIZE 37
@@ -76,7 +84,10 @@ struct btrfs_ioctl_vol_args_v2 {
76 }; 84 };
77 __u64 unused[4]; 85 __u64 unused[4];
78 }; 86 };
79 char name[BTRFS_SUBVOL_NAME_MAX + 1]; 87 union {
88 char name[BTRFS_SUBVOL_NAME_MAX + 1];
89 u64 devid;
90 };
80}; 91};
81 92
82/* 93/*
@@ -659,5 +670,7 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
659 struct btrfs_ioctl_feature_flags[2]) 670 struct btrfs_ioctl_feature_flags[2])
660#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \ 671#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
661 struct btrfs_ioctl_feature_flags[3]) 672 struct btrfs_ioctl_feature_flags[3])
673#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \
674 struct btrfs_ioctl_vol_args_v2)
662 675
663#endif /* _UAPI_LINUX_BTRFS_H */ 676#endif /* _UAPI_LINUX_BTRFS_H */