aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/disk-io.c24
-rw-r--r--fs/btrfs/reada.c17
-rw-r--r--fs/btrfs/scrub.c7
-rw-r--r--fs/btrfs/super.c13
-rw-r--r--fs/btrfs/transaction.c7
-rw-r--r--fs/btrfs/volumes.c54
-rw-r--r--fs/btrfs/volumes.h3
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
2663fail_qgroup: 2683fail_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
40static int init_first_rw_device(struct btrfs_trans_handle *trans, 41static 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
508void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) 509void 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,
268int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, 268int 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);
270int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); 270int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
271void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices); 271void btrfs_close_extra_devices(struct btrfs_fs_info *fs_info,
272 struct btrfs_fs_devices *fs_devices, int step);
272int btrfs_find_device_missing_or_by_path(struct btrfs_root *root, 273int 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);