@@ -44,9 +44,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
44
44
struct btrfs_fs_info * fs_info ,
45
45
struct btrfs_device * srcdev ,
46
46
struct btrfs_device * tgtdev );
47
- static int btrfs_dev_replace_find_srcdev (struct btrfs_root * root , u64 srcdevid ,
48
- char * srcdev_name ,
49
- struct btrfs_device * * device );
50
47
static u64 __btrfs_dev_replace_cancel (struct btrfs_fs_info * fs_info );
51
48
static int btrfs_dev_replace_kthread (void * data );
52
49
static 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
302
dev_replace -> cursor_left_last_write_of_item ;
306
303
}
307
304
308
- int btrfs_dev_replace_start (struct btrfs_root * root ,
309
- struct btrfs_ioctl_dev_replace_args * args )
305
+ int btrfs_dev_replace_start (struct btrfs_root * root , char * tgtdev_name ,
306
+ u64 srcdevid , char * srcdev_name , int read_src )
310
307
{
311
308
struct btrfs_trans_handle * trans ;
312
309
struct btrfs_fs_info * fs_info = root -> fs_info ;
@@ -315,29 +312,16 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
315
312
struct btrfs_device * tgt_device = NULL ;
316
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
315
/* the disk copy procedure reuses the scrub code */
331
316
mutex_lock (& fs_info -> volume_mutex );
332
- ret = btrfs_dev_replace_find_srcdev (root , args -> start .srcdevid ,
333
- args -> start .srcdev_name ,
334
- & src_device );
317
+ ret = btrfs_find_device_by_devspec (root , srcdevid ,
318
+ srcdev_name , & src_device );
335
319
if (ret ) {
336
320
mutex_unlock (& fs_info -> volume_mutex );
337
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
325
src_device , & tgt_device );
342
326
mutex_unlock (& fs_info -> volume_mutex );
343
327
if (ret )
@@ -364,18 +348,17 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
364
348
break ;
365
349
case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED :
366
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
352
goto leave ;
369
353
}
370
354
371
- dev_replace -> cont_reading_from_srcdev_mode =
372
- args -> start .cont_reading_from_srcdev_mode ;
355
+ dev_replace -> cont_reading_from_srcdev_mode = read_src ;
373
356
WARN_ON (!src_device );
374
357
dev_replace -> srcdev = src_device ;
375
358
WARN_ON (!tgt_device );
376
359
dev_replace -> tgtdev = tgt_device ;
377
360
378
- btrfs_info_in_rcu (root -> fs_info ,
361
+ btrfs_info_in_rcu (fs_info ,
379
362
"dev_replace from %s (devid %llu) to %s started" ,
380
363
src_device -> missing ? "<missing disk>" :
381
364
rcu_str_deref (src_device -> name ),
@@ -396,14 +379,13 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
396
379
dev_replace -> item_needs_writeback = 1 ;
397
380
atomic64_set (& dev_replace -> num_write_errors , 0 );
398
381
atomic64_set (& dev_replace -> num_uncorrectable_read_errors , 0 );
399
- args -> result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR ;
400
382
btrfs_dev_replace_unlock (dev_replace , 1 );
401
383
402
384
ret = btrfs_sysfs_add_device_link (tgt_device -> fs_devices , tgt_device );
403
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
390
/* force writing the updated state information to disk */
409
391
trans = btrfs_start_transaction (root , 0 );
@@ -421,11 +403,9 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
421
403
btrfs_device_get_total_bytes (src_device ),
422
404
& dev_replace -> scrub_progress , 0 , 1 );
423
405
424
- ret = btrfs_dev_replace_finishing (root -> fs_info , ret );
425
- /* don't warn if EINPROGRESS, someone else might be running scrub */
406
+ ret = btrfs_dev_replace_finishing (fs_info , ret );
426
407
if (ret == - EINPROGRESS ) {
427
- args -> result = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS ;
428
- ret = 0 ;
408
+ ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS ;
429
409
} else {
430
410
WARN_ON (ret );
431
411
}
@@ -440,6 +420,35 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
440
420
return ret ;
441
421
}
442
422
423
+ int 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
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
569
ASSERT (list_empty (& src_device -> resized_list ));
561
570
tgt_device -> commit_total_bytes = src_device -> commit_total_bytes ;
562
571
tgt_device -> commit_bytes_used = src_device -> bytes_used ;
563
- if (fs_info -> sb -> s_bdev == src_device -> bdev )
564
- fs_info -> sb -> s_bdev = tgt_device -> bdev ;
565
- if (fs_info -> fs_devices -> latest_bdev == src_device -> bdev )
566
- fs_info -> fs_devices -> latest_bdev = tgt_device -> bdev ;
572
+
573
+ btrfs_assign_next_active_device (fs_info , src_device , tgt_device );
574
+
567
575
list_add (& tgt_device -> dev_alloc_list , & fs_info -> fs_devices -> alloc_list );
568
576
fs_info -> fs_devices -> rw_devices ++ ;
569
577
@@ -626,25 +634,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
626
634
write_unlock (& em_tree -> lock );
627
635
}
628
636
629
- static 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
-
648
637
void btrfs_dev_replace_status (struct btrfs_fs_info * fs_info ,
649
638
struct btrfs_ioctl_dev_replace_args * args )
650
639
{
0 commit comments