diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/disk-io.c | 24 | ||||
-rw-r--r-- | fs/btrfs/reada.c | 17 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 7 | ||||
-rw-r--r-- | fs/btrfs/super.c | 13 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 7 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 54 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 3 |
7 files changed, 111 insertions, 14 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0e410478ad2..76b82506bf9 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "inode-map.h" | 45 | #include "inode-map.h" |
46 | #include "check-integrity.h" | 46 | #include "check-integrity.h" |
47 | #include "rcu-string.h" | 47 | #include "rcu-string.h" |
48 | #include "dev-replace.h" | ||
48 | 49 | ||
49 | #ifdef CONFIG_X86 | 50 | #ifdef CONFIG_X86 |
50 | #include <asm/cpufeature.h> | 51 | #include <asm/cpufeature.h> |
@@ -2438,7 +2439,11 @@ int open_ctree(struct super_block *sb, | |||
2438 | goto fail_tree_roots; | 2439 | goto fail_tree_roots; |
2439 | } | 2440 | } |
2440 | 2441 | ||
2441 | btrfs_close_extra_devices(fs_devices); | 2442 | /* |
2443 | * keep the device that is marked to be the target device for the | ||
2444 | * dev_replace procedure | ||
2445 | */ | ||
2446 | btrfs_close_extra_devices(fs_info, fs_devices, 0); | ||
2442 | 2447 | ||
2443 | if (!fs_devices->latest_bdev) { | 2448 | if (!fs_devices->latest_bdev) { |
2444 | printk(KERN_CRIT "btrfs: failed to read devices on %s\n", | 2449 | printk(KERN_CRIT "btrfs: failed to read devices on %s\n", |
@@ -2510,6 +2515,14 @@ retry_root_backup: | |||
2510 | goto fail_block_groups; | 2515 | goto fail_block_groups; |
2511 | } | 2516 | } |
2512 | 2517 | ||
2518 | ret = btrfs_init_dev_replace(fs_info); | ||
2519 | if (ret) { | ||
2520 | pr_err("btrfs: failed to init dev_replace: %d\n", ret); | ||
2521 | goto fail_block_groups; | ||
2522 | } | ||
2523 | |||
2524 | btrfs_close_extra_devices(fs_info, fs_devices, 1); | ||
2525 | |||
2513 | ret = btrfs_init_space_info(fs_info); | 2526 | ret = btrfs_init_space_info(fs_info); |
2514 | if (ret) { | 2527 | if (ret) { |
2515 | printk(KERN_ERR "Failed to initial space info: %d\n", ret); | 2528 | printk(KERN_ERR "Failed to initial space info: %d\n", ret); |
@@ -2658,6 +2671,13 @@ retry_root_backup: | |||
2658 | return ret; | 2671 | return ret; |
2659 | } | 2672 | } |
2660 | 2673 | ||
2674 | ret = btrfs_resume_dev_replace_async(fs_info); | ||
2675 | if (ret) { | ||
2676 | pr_warn("btrfs: failed to resume dev_replace\n"); | ||
2677 | close_ctree(tree_root); | ||
2678 | return ret; | ||
2679 | } | ||
2680 | |||
2661 | return 0; | 2681 | return 0; |
2662 | 2682 | ||
2663 | fail_qgroup: | 2683 | fail_qgroup: |
@@ -3300,6 +3320,8 @@ int close_ctree(struct btrfs_root *root) | |||
3300 | /* pause restriper - we want to resume on mount */ | 3320 | /* pause restriper - we want to resume on mount */ |
3301 | btrfs_pause_balance(fs_info); | 3321 | btrfs_pause_balance(fs_info); |
3302 | 3322 | ||
3323 | btrfs_dev_replace_suspend_for_unmount(fs_info); | ||
3324 | |||
3303 | btrfs_scrub_cancel(fs_info); | 3325 | btrfs_scrub_cancel(fs_info); |
3304 | 3326 | ||
3305 | /* wait for any defraggers to finish */ | 3327 | /* wait for any defraggers to finish */ |
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index 9f363e17ec7..c705a48e676 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "volumes.h" | 27 | #include "volumes.h" |
28 | #include "disk-io.h" | 28 | #include "disk-io.h" |
29 | #include "transaction.h" | 29 | #include "transaction.h" |
30 | #include "dev-replace.h" | ||
30 | 31 | ||
31 | #undef DEBUG | 32 | #undef DEBUG |
32 | 33 | ||
@@ -331,6 +332,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, | |||
331 | int nzones = 0; | 332 | int nzones = 0; |
332 | int i; | 333 | int i; |
333 | unsigned long index = logical >> PAGE_CACHE_SHIFT; | 334 | unsigned long index = logical >> PAGE_CACHE_SHIFT; |
335 | int dev_replace_is_ongoing; | ||
334 | 336 | ||
335 | spin_lock(&fs_info->reada_lock); | 337 | spin_lock(&fs_info->reada_lock); |
336 | re = radix_tree_lookup(&fs_info->reada_tree, index); | 338 | re = radix_tree_lookup(&fs_info->reada_tree, index); |
@@ -392,6 +394,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, | |||
392 | } | 394 | } |
393 | 395 | ||
394 | /* insert extent in reada_tree + all per-device trees, all or nothing */ | 396 | /* insert extent in reada_tree + all per-device trees, all or nothing */ |
397 | btrfs_dev_replace_lock(&fs_info->dev_replace); | ||
395 | spin_lock(&fs_info->reada_lock); | 398 | spin_lock(&fs_info->reada_lock); |
396 | ret = radix_tree_insert(&fs_info->reada_tree, index, re); | 399 | ret = radix_tree_insert(&fs_info->reada_tree, index, re); |
397 | if (ret == -EEXIST) { | 400 | if (ret == -EEXIST) { |
@@ -399,13 +402,17 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, | |||
399 | BUG_ON(!re_exist); | 402 | BUG_ON(!re_exist); |
400 | re_exist->refcnt++; | 403 | re_exist->refcnt++; |
401 | spin_unlock(&fs_info->reada_lock); | 404 | spin_unlock(&fs_info->reada_lock); |
405 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | ||
402 | goto error; | 406 | goto error; |
403 | } | 407 | } |
404 | if (ret) { | 408 | if (ret) { |
405 | spin_unlock(&fs_info->reada_lock); | 409 | spin_unlock(&fs_info->reada_lock); |
410 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | ||
406 | goto error; | 411 | goto error; |
407 | } | 412 | } |
408 | prev_dev = NULL; | 413 | prev_dev = NULL; |
414 | dev_replace_is_ongoing = btrfs_dev_replace_is_ongoing( | ||
415 | &fs_info->dev_replace); | ||
409 | for (i = 0; i < nzones; ++i) { | 416 | for (i = 0; i < nzones; ++i) { |
410 | dev = bbio->stripes[i].dev; | 417 | dev = bbio->stripes[i].dev; |
411 | if (dev == prev_dev) { | 418 | if (dev == prev_dev) { |
@@ -422,6 +429,14 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, | |||
422 | /* cannot read ahead on missing device */ | 429 | /* cannot read ahead on missing device */ |
423 | continue; | 430 | continue; |
424 | } | 431 | } |
432 | if (dev_replace_is_ongoing && | ||
433 | dev == fs_info->dev_replace.tgtdev) { | ||
434 | /* | ||
435 | * as this device is selected for reading only as | ||
436 | * a last resort, skip it for read ahead. | ||
437 | */ | ||
438 | continue; | ||
439 | } | ||
425 | prev_dev = dev; | 440 | prev_dev = dev; |
426 | ret = radix_tree_insert(&dev->reada_extents, index, re); | 441 | ret = radix_tree_insert(&dev->reada_extents, index, re); |
427 | if (ret) { | 442 | if (ret) { |
@@ -434,10 +449,12 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, | |||
434 | BUG_ON(fs_info == NULL); | 449 | BUG_ON(fs_info == NULL); |
435 | radix_tree_delete(&fs_info->reada_tree, index); | 450 | radix_tree_delete(&fs_info->reada_tree, index); |
436 | spin_unlock(&fs_info->reada_lock); | 451 | spin_unlock(&fs_info->reada_lock); |
452 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | ||
437 | goto error; | 453 | goto error; |
438 | } | 454 | } |
439 | } | 455 | } |
440 | spin_unlock(&fs_info->reada_lock); | 456 | spin_unlock(&fs_info->reada_lock); |
457 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | ||
441 | 458 | ||
442 | kfree(bbio); | 459 | kfree(bbio); |
443 | return re; | 460 | return re; |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 61157a26cf2..30cbf6921c0 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -2843,12 +2843,17 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
2843 | return -EIO; | 2843 | return -EIO; |
2844 | } | 2844 | } |
2845 | 2845 | ||
2846 | if (dev->scrub_device) { | 2846 | btrfs_dev_replace_lock(&fs_info->dev_replace); |
2847 | if (dev->scrub_device || | ||
2848 | (!is_dev_replace && | ||
2849 | btrfs_dev_replace_is_ongoing(&fs_info->dev_replace))) { | ||
2850 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | ||
2847 | mutex_unlock(&fs_info->scrub_lock); | 2851 | mutex_unlock(&fs_info->scrub_lock); |
2848 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 2852 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); |
2849 | scrub_workers_put(fs_info); | 2853 | scrub_workers_put(fs_info); |
2850 | return -EINPROGRESS; | 2854 | return -EINPROGRESS; |
2851 | } | 2855 | } |
2856 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | ||
2852 | sctx = scrub_setup_ctx(dev, is_dev_replace); | 2857 | sctx = scrub_setup_ctx(dev, is_dev_replace); |
2853 | if (IS_ERR(sctx)) { | 2858 | if (IS_ERR(sctx)) { |
2854 | mutex_unlock(&fs_info->scrub_lock); | 2859 | mutex_unlock(&fs_info->scrub_lock); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index ad4380684b9..def4f24b58d 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include "export.h" | 55 | #include "export.h" |
56 | #include "compression.h" | 56 | #include "compression.h" |
57 | #include "rcu-string.h" | 57 | #include "rcu-string.h" |
58 | #include "dev-replace.h" | ||
58 | 59 | ||
59 | #define CREATE_TRACE_POINTS | 60 | #define CREATE_TRACE_POINTS |
60 | #include <trace/events/btrfs.h> | 61 | #include <trace/events/btrfs.h> |
@@ -1225,8 +1226,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1225 | return 0; | 1226 | return 0; |
1226 | 1227 | ||
1227 | if (*flags & MS_RDONLY) { | 1228 | if (*flags & MS_RDONLY) { |
1229 | /* | ||
1230 | * this also happens on 'umount -rf' or on shutdown, when | ||
1231 | * the filesystem is busy. | ||
1232 | */ | ||
1228 | sb->s_flags |= MS_RDONLY; | 1233 | sb->s_flags |= MS_RDONLY; |
1229 | 1234 | ||
1235 | btrfs_dev_replace_suspend_for_unmount(fs_info); | ||
1236 | btrfs_scrub_cancel(fs_info); | ||
1237 | |||
1230 | ret = btrfs_commit_super(root); | 1238 | ret = btrfs_commit_super(root); |
1231 | if (ret) | 1239 | if (ret) |
1232 | goto restore; | 1240 | goto restore; |
@@ -1263,6 +1271,11 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1263 | if (ret) | 1271 | if (ret) |
1264 | goto restore; | 1272 | goto restore; |
1265 | 1273 | ||
1274 | ret = btrfs_resume_dev_replace_async(fs_info); | ||
1275 | if (ret) { | ||
1276 | pr_warn("btrfs: failed to resume dev_replace\n"); | ||
1277 | goto restore; | ||
1278 | } | ||
1266 | sb->s_flags &= ~MS_RDONLY; | 1279 | sb->s_flags &= ~MS_RDONLY; |
1267 | } | 1280 | } |
1268 | 1281 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 7b297354e73..bcc6b65be3b 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "tree-log.h" | 30 | #include "tree-log.h" |
31 | #include "inode-map.h" | 31 | #include "inode-map.h" |
32 | #include "volumes.h" | 32 | #include "volumes.h" |
33 | #include "dev-replace.h" | ||
33 | 34 | ||
34 | #define BTRFS_ROOT_TRANS_TAG 0 | 35 | #define BTRFS_ROOT_TRANS_TAG 0 |
35 | 36 | ||
@@ -845,7 +846,9 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
845 | return ret; | 846 | return ret; |
846 | 847 | ||
847 | ret = btrfs_run_dev_stats(trans, root->fs_info); | 848 | ret = btrfs_run_dev_stats(trans, root->fs_info); |
848 | BUG_ON(ret); | 849 | WARN_ON(ret); |
850 | ret = btrfs_run_dev_replace(trans, root->fs_info); | ||
851 | WARN_ON(ret); | ||
849 | 852 | ||
850 | ret = btrfs_run_qgroups(trans, root->fs_info); | 853 | ret = btrfs_run_qgroups(trans, root->fs_info); |
851 | BUG_ON(ret); | 854 | BUG_ON(ret); |
@@ -868,6 +871,8 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
868 | switch_commit_root(fs_info->extent_root); | 871 | switch_commit_root(fs_info->extent_root); |
869 | up_write(&fs_info->extent_commit_sem); | 872 | up_write(&fs_info->extent_commit_sem); |
870 | 873 | ||
874 | btrfs_after_dev_replace_commit(fs_info); | ||
875 | |||
871 | return 0; | 876 | return 0; |
872 | } | 877 | } |
873 | 878 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 5777e6a9aab..a4e0963bf45 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "check-integrity.h" | 36 | #include "check-integrity.h" |
37 | #include "rcu-string.h" | 37 | #include "rcu-string.h" |
38 | #include "math.h" | 38 | #include "math.h" |
39 | #include "dev-replace.h" | ||
39 | 40 | ||
40 | static int init_first_rw_device(struct btrfs_trans_handle *trans, | 41 | static int init_first_rw_device(struct btrfs_trans_handle *trans, |
41 | struct btrfs_root *root, | 42 | struct btrfs_root *root, |
@@ -505,7 +506,8 @@ error: | |||
505 | return ERR_PTR(-ENOMEM); | 506 | return ERR_PTR(-ENOMEM); |
506 | } | 507 | } |
507 | 508 | ||
508 | void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) | 509 | void btrfs_close_extra_devices(struct btrfs_fs_info *fs_info, |
510 | struct btrfs_fs_devices *fs_devices, int step) | ||
509 | { | 511 | { |
510 | struct btrfs_device *device, *next; | 512 | struct btrfs_device *device, *next; |
511 | 513 | ||
@@ -528,6 +530,21 @@ again: | |||
528 | continue; | 530 | continue; |
529 | } | 531 | } |
530 | 532 | ||
533 | if (device->devid == BTRFS_DEV_REPLACE_DEVID) { | ||
534 | /* | ||
535 | * In the first step, keep the device which has | ||
536 | * the correct fsid and the devid that is used | ||
537 | * for the dev_replace procedure. | ||
538 | * In the second step, the dev_replace state is | ||
539 | * read from the device tree and it is known | ||
540 | * whether the procedure is really active or | ||
541 | * not, which means whether this device is | ||
542 | * used or whether it should be removed. | ||
543 | */ | ||
544 | if (step == 0 || device->is_tgtdev_for_dev_replace) { | ||
545 | continue; | ||
546 | } | ||
547 | } | ||
531 | if (device->bdev) { | 548 | if (device->bdev) { |
532 | blkdev_put(device->bdev, device->mode); | 549 | blkdev_put(device->bdev, device->mode); |
533 | device->bdev = NULL; | 550 | device->bdev = NULL; |
@@ -536,7 +553,8 @@ again: | |||
536 | if (device->writeable) { | 553 | if (device->writeable) { |
537 | list_del_init(&device->dev_alloc_list); | 554 | list_del_init(&device->dev_alloc_list); |
538 | device->writeable = 0; | 555 | device->writeable = 0; |
539 | fs_devices->rw_devices--; | 556 | if (!device->is_tgtdev_for_dev_replace) |
557 | fs_devices->rw_devices--; | ||
540 | } | 558 | } |
541 | list_del_init(&device->dev_list); | 559 | list_del_init(&device->dev_list); |
542 | fs_devices->num_devices--; | 560 | fs_devices->num_devices--; |
@@ -594,7 +612,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
594 | if (device->bdev) | 612 | if (device->bdev) |
595 | fs_devices->open_devices--; | 613 | fs_devices->open_devices--; |
596 | 614 | ||
597 | if (device->writeable) { | 615 | if (device->writeable && !device->is_tgtdev_for_dev_replace) { |
598 | list_del_init(&device->dev_alloc_list); | 616 | list_del_init(&device->dev_alloc_list); |
599 | fs_devices->rw_devices--; | 617 | fs_devices->rw_devices--; |
600 | } | 618 | } |
@@ -718,7 +736,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
718 | fs_devices->rotating = 1; | 736 | fs_devices->rotating = 1; |
719 | 737 | ||
720 | fs_devices->open_devices++; | 738 | fs_devices->open_devices++; |
721 | if (device->writeable) { | 739 | if (device->writeable && !device->is_tgtdev_for_dev_replace) { |
722 | fs_devices->rw_devices++; | 740 | fs_devices->rw_devices++; |
723 | list_add(&device->dev_alloc_list, | 741 | list_add(&device->dev_alloc_list, |
724 | &fs_devices->alloc_list); | 742 | &fs_devices->alloc_list); |
@@ -1350,16 +1368,22 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1350 | root->fs_info->avail_system_alloc_bits | | 1368 | root->fs_info->avail_system_alloc_bits | |
1351 | root->fs_info->avail_metadata_alloc_bits; | 1369 | root->fs_info->avail_metadata_alloc_bits; |
1352 | 1370 | ||
1353 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) && | 1371 | num_devices = root->fs_info->fs_devices->num_devices; |
1354 | root->fs_info->fs_devices->num_devices <= 4) { | 1372 | btrfs_dev_replace_lock(&root->fs_info->dev_replace); |
1373 | if (btrfs_dev_replace_is_ongoing(&root->fs_info->dev_replace)) { | ||
1374 | WARN_ON(num_devices < 1); | ||
1375 | num_devices--; | ||
1376 | } | ||
1377 | btrfs_dev_replace_unlock(&root->fs_info->dev_replace); | ||
1378 | |||
1379 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) && num_devices <= 4) { | ||
1355 | printk(KERN_ERR "btrfs: unable to go below four devices " | 1380 | printk(KERN_ERR "btrfs: unable to go below four devices " |
1356 | "on raid10\n"); | 1381 | "on raid10\n"); |
1357 | ret = -EINVAL; | 1382 | ret = -EINVAL; |
1358 | goto out; | 1383 | goto out; |
1359 | } | 1384 | } |
1360 | 1385 | ||
1361 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) && | 1386 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) && num_devices <= 2) { |
1362 | root->fs_info->fs_devices->num_devices <= 2) { | ||
1363 | printk(KERN_ERR "btrfs: unable to go below two " | 1387 | printk(KERN_ERR "btrfs: unable to go below two " |
1364 | "devices on raid1\n"); | 1388 | "devices on raid1\n"); |
1365 | ret = -EINVAL; | 1389 | ret = -EINVAL; |
@@ -2935,6 +2959,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl, | |||
2935 | u64 allowed; | 2959 | u64 allowed; |
2936 | int mixed = 0; | 2960 | int mixed = 0; |
2937 | int ret; | 2961 | int ret; |
2962 | u64 num_devices; | ||
2938 | 2963 | ||
2939 | if (btrfs_fs_closing(fs_info) || | 2964 | if (btrfs_fs_closing(fs_info) || |
2940 | atomic_read(&fs_info->balance_pause_req) || | 2965 | atomic_read(&fs_info->balance_pause_req) || |
@@ -2963,10 +2988,17 @@ int btrfs_balance(struct btrfs_balance_control *bctl, | |||
2963 | } | 2988 | } |
2964 | } | 2989 | } |
2965 | 2990 | ||
2991 | num_devices = fs_info->fs_devices->num_devices; | ||
2992 | btrfs_dev_replace_lock(&fs_info->dev_replace); | ||
2993 | if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace)) { | ||
2994 | BUG_ON(num_devices < 1); | ||
2995 | num_devices--; | ||
2996 | } | ||
2997 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | ||
2966 | allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE; | 2998 | allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE; |
2967 | if (fs_info->fs_devices->num_devices == 1) | 2999 | if (num_devices == 1) |
2968 | allowed |= BTRFS_BLOCK_GROUP_DUP; | 3000 | allowed |= BTRFS_BLOCK_GROUP_DUP; |
2969 | else if (fs_info->fs_devices->num_devices < 4) | 3001 | else if (num_devices < 4) |
2970 | allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1); | 3002 | allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1); |
2971 | else | 3003 | else |
2972 | allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | | 3004 | allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | |
@@ -3591,6 +3623,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
3591 | devices_info[ndevs].total_avail = total_avail; | 3623 | devices_info[ndevs].total_avail = total_avail; |
3592 | devices_info[ndevs].dev = device; | 3624 | devices_info[ndevs].dev = device; |
3593 | ++ndevs; | 3625 | ++ndevs; |
3626 | WARN_ON(ndevs > fs_devices->rw_devices); | ||
3594 | } | 3627 | } |
3595 | 3628 | ||
3596 | /* | 3629 | /* |
@@ -4773,6 +4806,7 @@ static void fill_device_from_item(struct extent_buffer *leaf, | |||
4773 | device->io_align = btrfs_device_io_align(leaf, dev_item); | 4806 | device->io_align = btrfs_device_io_align(leaf, dev_item); |
4774 | device->io_width = btrfs_device_io_width(leaf, dev_item); | 4807 | device->io_width = btrfs_device_io_width(leaf, dev_item); |
4775 | device->sector_size = btrfs_device_sector_size(leaf, dev_item); | 4808 | device->sector_size = btrfs_device_sector_size(leaf, dev_item); |
4809 | WARN_ON(device->devid == BTRFS_DEV_REPLACE_DEVID); | ||
4776 | device->is_tgtdev_for_dev_replace = 0; | 4810 | device->is_tgtdev_for_dev_replace = 0; |
4777 | 4811 | ||
4778 | ptr = (unsigned long)btrfs_device_uuid(dev_item); | 4812 | ptr = (unsigned long)btrfs_device_uuid(dev_item); |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 58d79375dea..37d0157167b 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -268,7 +268,8 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
268 | int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | 268 | int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, |
269 | struct btrfs_fs_devices **fs_devices_ret); | 269 | struct btrfs_fs_devices **fs_devices_ret); |
270 | int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); | 270 | int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); |
271 | void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices); | 271 | void btrfs_close_extra_devices(struct btrfs_fs_info *fs_info, |
272 | struct btrfs_fs_devices *fs_devices, int step); | ||
272 | int btrfs_find_device_missing_or_by_path(struct btrfs_root *root, | 273 | int btrfs_find_device_missing_or_by_path(struct btrfs_root *root, |
273 | char *device_path, | 274 | char *device_path, |
274 | struct btrfs_device **device); | 275 | struct btrfs_device **device); |