Skip to content

Commit 88acff6

Browse files
asjkdave
authored andcommitted
btrfs: cleanup assigning next active device with a check
Creates helper fucntion as needed by the device delete and replace operations. Also now it checks if the next device being assigned is an active device. Signed-off-by: Anand Jain <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 8ed01ab commit 88acff6

File tree

3 files changed

+48
-22
lines changed

3 files changed

+48
-22
lines changed

fs/btrfs/dev-replace.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,9 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
569569
ASSERT(list_empty(&src_device->resized_list));
570570
tgt_device->commit_total_bytes = src_device->commit_total_bytes;
571571
tgt_device->commit_bytes_used = src_device->bytes_used;
572-
if (fs_info->sb->s_bdev &&
573-
(fs_info->sb->s_bdev == src_device->bdev))
574-
fs_info->sb->s_bdev = tgt_device->bdev;
575-
if (fs_info->fs_devices->latest_bdev == src_device->bdev)
576-
fs_info->fs_devices->latest_bdev = tgt_device->bdev;
572+
573+
btrfs_assign_next_active_device(fs_info, src_device, tgt_device);
574+
577575
list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);
578576
fs_info->fs_devices->rw_devices++;
579577

fs/btrfs/volumes.c

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,10 +1756,49 @@ static int btrfs_check_raid_min_devices(struct btrfs_fs_info *fs_info,
17561756
return 0;
17571757
}
17581758

1759+
struct btrfs_device *btrfs_find_next_active_device(struct btrfs_fs_devices *fs_devs,
1760+
struct btrfs_device *device)
1761+
{
1762+
struct btrfs_device *next_device;
1763+
1764+
list_for_each_entry(next_device, &fs_devs->devices, dev_list) {
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+
*/
1779+
void 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+
17591799
int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
17601800
{
17611801
struct btrfs_device *device;
1762-
struct btrfs_device *next_device;
17631802
struct btrfs_fs_devices *cur_devices;
17641803
u64 num_devices;
17651804
int ret = 0;
@@ -1846,13 +1885,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
18461885
if (device->missing)
18471886
device->fs_devices->missing_devices--;
18481887

1849-
next_device = list_entry(root->fs_info->fs_devices->devices.next,
1850-
struct btrfs_device, dev_list);
1851-
if (root->fs_info->sb->s_bdev &&
1852-
(root->fs_info->sb->s_bdev == device->bdev))
1853-
root->fs_info->sb->s_bdev = next_device->bdev;
1854-
if (device->bdev == root->fs_info->fs_devices->latest_bdev)
1855-
root->fs_info->fs_devices->latest_bdev = next_device->bdev;
1888+
btrfs_assign_next_active_device(root->fs_info, device, NULL);
18561889

18571890
if (device->bdev) {
18581891
device->fs_devices->open_devices--;
@@ -1981,8 +2014,6 @@ void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info,
19812014
void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
19822015
struct btrfs_device *tgtdev)
19832016
{
1984-
struct btrfs_device *next_device;
1985-
19862017
mutex_lock(&uuid_mutex);
19872018
WARN_ON(!tgtdev);
19882019
mutex_lock(&fs_info->fs_devices->device_list_mutex);
@@ -1995,13 +2026,8 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
19952026
}
19962027
fs_info->fs_devices->num_devices--;
19972028

1998-
next_device = list_entry(fs_info->fs_devices->devices.next,
1999-
struct btrfs_device, dev_list);
2000-
if (fs_info->sb->s_bdev &&
2001-
(tgtdev->bdev == fs_info->sb->s_bdev))
2002-
fs_info->sb->s_bdev = next_device->bdev;
2003-
if (tgtdev->bdev == fs_info->fs_devices->latest_bdev)
2004-
fs_info->fs_devices->latest_bdev = next_device->bdev;
2029+
btrfs_assign_next_active_device(fs_info, tgtdev, NULL);
2030+
20052031
list_del_rcu(&tgtdev->dev_list);
20062032

20072033
call_rcu(&tgtdev->rcu, free_device);

fs/btrfs/volumes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
445445
struct btrfs_fs_devices **fs_devices_ret);
446446
int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
447447
void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices, int step);
448+
void btrfs_assign_next_active_device(struct btrfs_fs_info *fs_info,
449+
struct btrfs_device *device, struct btrfs_device *this_dev);
448450
int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
449451
char *device_path,
450452
struct btrfs_device **device);

0 commit comments

Comments
 (0)