Commit 562d7b15 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: handle device lookup with btrfs_dev_lookup_args

We have a lot of device lookup functions that all do something slightly
different.  Clean this up by adding a struct to hold the different
lookup criteria, and then pass this around to btrfs_find_device() so it
can do the proper matching based on the lookup criteria.
Reviewed-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 8b41393f
...@@ -70,6 +70,7 @@ static int btrfs_dev_replace_kthread(void *data); ...@@ -70,6 +70,7 @@ static int btrfs_dev_replace_kthread(void *data);
int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info) int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
{ {
struct btrfs_dev_lookup_args args = { .devid = BTRFS_DEV_REPLACE_DEVID };
struct btrfs_key key; struct btrfs_key key;
struct btrfs_root *dev_root = fs_info->dev_root; struct btrfs_root *dev_root = fs_info->dev_root;
struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
...@@ -100,8 +101,7 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info) ...@@ -100,8 +101,7 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
* We don't have a replace item or it's corrupted. If there is * We don't have a replace item or it's corrupted. If there is
* a replace target, fail the mount. * a replace target, fail the mount.
*/ */
if (btrfs_find_device(fs_info->fs_devices, if (btrfs_find_device(fs_info->fs_devices, &args)) {
BTRFS_DEV_REPLACE_DEVID, NULL, NULL)) {
btrfs_err(fs_info, btrfs_err(fs_info,
"found replace target device without a valid replace item"); "found replace target device without a valid replace item");
ret = -EUCLEAN; ret = -EUCLEAN;
...@@ -163,8 +163,7 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info) ...@@ -163,8 +163,7 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
* We don't have an active replace item but if there is a * We don't have an active replace item but if there is a
* replace target, fail the mount. * replace target, fail the mount.
*/ */
if (btrfs_find_device(fs_info->fs_devices, if (btrfs_find_device(fs_info->fs_devices, &args)) {
BTRFS_DEV_REPLACE_DEVID, NULL, NULL)) {
btrfs_err(fs_info, btrfs_err(fs_info,
"replace devid present without an active replace item"); "replace devid present without an active replace item");
ret = -EUCLEAN; ret = -EUCLEAN;
...@@ -175,11 +174,10 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info) ...@@ -175,11 +174,10 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
break; break;
case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
dev_replace->srcdev = btrfs_find_device(fs_info->fs_devices, dev_replace->tgtdev = btrfs_find_device(fs_info->fs_devices, &args);
src_devid, NULL, NULL); args.devid = src_devid;
dev_replace->tgtdev = btrfs_find_device(fs_info->fs_devices, dev_replace->srcdev = btrfs_find_device(fs_info->fs_devices, &args);
BTRFS_DEV_REPLACE_DEVID,
NULL, NULL);
/* /*
* allow 'btrfs dev replace_cancel' if src/tgt device is * allow 'btrfs dev replace_cancel' if src/tgt device is
* missing * missing
......
...@@ -1602,6 +1602,7 @@ static int exclop_start_or_cancel_reloc(struct btrfs_fs_info *fs_info, ...@@ -1602,6 +1602,7 @@ static int exclop_start_or_cancel_reloc(struct btrfs_fs_info *fs_info,
static noinline int btrfs_ioctl_resize(struct file *file, static noinline int btrfs_ioctl_resize(struct file *file,
void __user *arg) void __user *arg)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
u64 new_size; u64 new_size;
...@@ -1657,7 +1658,8 @@ static noinline int btrfs_ioctl_resize(struct file *file, ...@@ -1657,7 +1658,8 @@ static noinline int btrfs_ioctl_resize(struct file *file,
btrfs_info(fs_info, "resizing devid %llu", devid); btrfs_info(fs_info, "resizing devid %llu", devid);
} }
device = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL); args.devid = devid;
device = btrfs_find_device(fs_info->fs_devices, &args);
if (!device) { if (!device) {
btrfs_info(fs_info, "resizer unable to find device %llu", btrfs_info(fs_info, "resizer unable to find device %llu",
devid); devid);
...@@ -3317,22 +3319,21 @@ static long btrfs_ioctl_fs_info(struct btrfs_fs_info *fs_info, ...@@ -3317,22 +3319,21 @@ static long btrfs_ioctl_fs_info(struct btrfs_fs_info *fs_info,
static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info, static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
void __user *arg) void __user *arg)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
struct btrfs_ioctl_dev_info_args *di_args; struct btrfs_ioctl_dev_info_args *di_args;
struct btrfs_device *dev; struct btrfs_device *dev;
int ret = 0; int ret = 0;
char *s_uuid = NULL;
di_args = memdup_user(arg, sizeof(*di_args)); di_args = memdup_user(arg, sizeof(*di_args));
if (IS_ERR(di_args)) if (IS_ERR(di_args))
return PTR_ERR(di_args); return PTR_ERR(di_args);
args.devid = di_args->devid;
if (!btrfs_is_empty_uuid(di_args->uuid)) if (!btrfs_is_empty_uuid(di_args->uuid))
s_uuid = di_args->uuid; args.uuid = di_args->uuid;
rcu_read_lock(); rcu_read_lock();
dev = btrfs_find_device(fs_info->fs_devices, di_args->devid, s_uuid, dev = btrfs_find_device(fs_info->fs_devices, &args);
NULL);
if (!dev) { if (!dev) {
ret = -ENODEV; ret = -ENODEV;
goto out; goto out;
......
...@@ -4067,6 +4067,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, ...@@ -4067,6 +4067,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
u64 end, struct btrfs_scrub_progress *progress, u64 end, struct btrfs_scrub_progress *progress,
int readonly, int is_dev_replace) int readonly, int is_dev_replace)
{ {
struct btrfs_dev_lookup_args args = { .devid = devid };
struct scrub_ctx *sctx; struct scrub_ctx *sctx;
int ret; int ret;
struct btrfs_device *dev; struct btrfs_device *dev;
...@@ -4114,7 +4115,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, ...@@ -4114,7 +4115,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
goto out_free_ctx; goto out_free_ctx;
mutex_lock(&fs_info->fs_devices->device_list_mutex); mutex_lock(&fs_info->fs_devices->device_list_mutex);
dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL); dev = btrfs_find_device(fs_info->fs_devices, &args);
if (!dev || (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) && if (!dev || (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) &&
!is_dev_replace)) { !is_dev_replace)) {
mutex_unlock(&fs_info->fs_devices->device_list_mutex); mutex_unlock(&fs_info->fs_devices->device_list_mutex);
...@@ -4287,11 +4288,12 @@ int btrfs_scrub_cancel_dev(struct btrfs_device *dev) ...@@ -4287,11 +4288,12 @@ int btrfs_scrub_cancel_dev(struct btrfs_device *dev)
int btrfs_scrub_progress(struct btrfs_fs_info *fs_info, u64 devid, int btrfs_scrub_progress(struct btrfs_fs_info *fs_info, u64 devid,
struct btrfs_scrub_progress *progress) struct btrfs_scrub_progress *progress)
{ {
struct btrfs_dev_lookup_args args = { .devid = devid };
struct btrfs_device *dev; struct btrfs_device *dev;
struct scrub_ctx *sctx = NULL; struct scrub_ctx *sctx = NULL;
mutex_lock(&fs_info->fs_devices->device_list_mutex); mutex_lock(&fs_info->fs_devices->device_list_mutex);
dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL); dev = btrfs_find_device(fs_info->fs_devices, &args);
if (dev) if (dev)
sctx = dev->scrub_ctx; sctx = dev->scrub_ctx;
if (sctx) if (sctx)
......
...@@ -812,9 +812,13 @@ static noinline struct btrfs_device *device_list_add(const char *path, ...@@ -812,9 +812,13 @@ static noinline struct btrfs_device *device_list_add(const char *path,
device = NULL; device = NULL;
} else { } else {
struct btrfs_dev_lookup_args args = {
.devid = devid,
.uuid = disk_super->dev_item.uuid,
};
mutex_lock(&fs_devices->device_list_mutex); mutex_lock(&fs_devices->device_list_mutex);
device = btrfs_find_device(fs_devices, devid, device = btrfs_find_device(fs_devices, &args);
disk_super->dev_item.uuid, NULL);
/* /*
* If this disk has been pulled into an fs devices created by * If this disk has been pulled into an fs devices created by
...@@ -2324,10 +2328,9 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_device *tgtdev) ...@@ -2324,10 +2328,9 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_device *tgtdev)
static struct btrfs_device *btrfs_find_device_by_path( static struct btrfs_device *btrfs_find_device_by_path(
struct btrfs_fs_info *fs_info, const char *device_path) struct btrfs_fs_info *fs_info, const char *device_path)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
int ret = 0; int ret = 0;
struct btrfs_super_block *disk_super; struct btrfs_super_block *disk_super;
u64 devid;
u8 *dev_uuid;
struct block_device *bdev; struct block_device *bdev;
struct btrfs_device *device; struct btrfs_device *device;
...@@ -2336,14 +2339,14 @@ static struct btrfs_device *btrfs_find_device_by_path( ...@@ -2336,14 +2339,14 @@ static struct btrfs_device *btrfs_find_device_by_path(
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
devid = btrfs_stack_device_id(&disk_super->dev_item); args.devid = btrfs_stack_device_id(&disk_super->dev_item);
dev_uuid = disk_super->dev_item.uuid; args.uuid = disk_super->dev_item.uuid;
if (btrfs_fs_incompat(fs_info, METADATA_UUID)) if (btrfs_fs_incompat(fs_info, METADATA_UUID))
device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid, args.fsid = disk_super->metadata_uuid;
disk_super->metadata_uuid);
else else
device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid, args.fsid = disk_super->fsid;
disk_super->fsid);
device = btrfs_find_device(fs_info->fs_devices, &args);
btrfs_release_disk_super(disk_super); btrfs_release_disk_super(disk_super);
if (!device) if (!device)
...@@ -2359,11 +2362,12 @@ struct btrfs_device *btrfs_find_device_by_devspec( ...@@ -2359,11 +2362,12 @@ struct btrfs_device *btrfs_find_device_by_devspec(
struct btrfs_fs_info *fs_info, u64 devid, struct btrfs_fs_info *fs_info, u64 devid,
const char *device_path) const char *device_path)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
struct btrfs_device *device; struct btrfs_device *device;
if (devid) { if (devid) {
device = btrfs_find_device(fs_info->fs_devices, devid, NULL, args.devid = devid;
NULL); device = btrfs_find_device(fs_info->fs_devices, &args);
if (!device) if (!device)
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
return device; return device;
...@@ -2373,14 +2377,11 @@ struct btrfs_device *btrfs_find_device_by_devspec( ...@@ -2373,14 +2377,11 @@ struct btrfs_device *btrfs_find_device_by_devspec(
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if (strcmp(device_path, "missing") == 0) { if (strcmp(device_path, "missing") == 0) {
/* Find first missing device */ args.missing = true;
list_for_each_entry(device, &fs_info->fs_devices->devices, device = btrfs_find_device(fs_info->fs_devices, &args);
dev_list) { if (!device)
if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA,
&device->dev_state) && !device->bdev)
return device;
}
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
return device;
} }
return btrfs_find_device_by_path(fs_info, device_path); return btrfs_find_device_by_path(fs_info, device_path);
...@@ -2460,6 +2461,7 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info) ...@@ -2460,6 +2461,7 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
*/ */
static int btrfs_finish_sprout(struct btrfs_trans_handle *trans) static int btrfs_finish_sprout(struct btrfs_trans_handle *trans)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_fs_info *fs_info = trans->fs_info;
struct btrfs_root *root = fs_info->chunk_root; struct btrfs_root *root = fs_info->chunk_root;
struct btrfs_path *path; struct btrfs_path *path;
...@@ -2469,7 +2471,6 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans) ...@@ -2469,7 +2471,6 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans)
struct btrfs_key key; struct btrfs_key key;
u8 fs_uuid[BTRFS_FSID_SIZE]; u8 fs_uuid[BTRFS_FSID_SIZE];
u8 dev_uuid[BTRFS_UUID_SIZE]; u8 dev_uuid[BTRFS_UUID_SIZE];
u64 devid;
int ret; int ret;
path = btrfs_alloc_path(); path = btrfs_alloc_path();
...@@ -2506,13 +2507,14 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans) ...@@ -2506,13 +2507,14 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans)
dev_item = btrfs_item_ptr(leaf, path->slots[0], dev_item = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_dev_item); struct btrfs_dev_item);
devid = btrfs_device_id(leaf, dev_item); args.devid = btrfs_device_id(leaf, dev_item);
read_extent_buffer(leaf, dev_uuid, btrfs_device_uuid(dev_item), read_extent_buffer(leaf, dev_uuid, btrfs_device_uuid(dev_item),
BTRFS_UUID_SIZE); BTRFS_UUID_SIZE);
read_extent_buffer(leaf, fs_uuid, btrfs_device_fsid(dev_item), read_extent_buffer(leaf, fs_uuid, btrfs_device_fsid(dev_item),
BTRFS_FSID_SIZE); BTRFS_FSID_SIZE);
device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid, args.uuid = dev_uuid;
fs_uuid); args.fsid = fs_uuid;
device = btrfs_find_device(fs_info->fs_devices, &args);
BUG_ON(!device); /* Logic error */ BUG_ON(!device); /* Logic error */
if (device->fs_devices->seeding) { if (device->fs_devices->seeding) {
...@@ -6754,6 +6756,33 @@ blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, ...@@ -6754,6 +6756,33 @@ blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
return BLK_STS_OK; return BLK_STS_OK;
} }
static bool dev_args_match_fs_devices(const struct btrfs_dev_lookup_args *args,
const struct btrfs_fs_devices *fs_devices)
{
if (args->fsid == NULL)
return true;
if (memcmp(fs_devices->metadata_uuid, args->fsid, BTRFS_FSID_SIZE) == 0)
return true;
return false;
}
static bool dev_args_match_device(const struct btrfs_dev_lookup_args *args,
const struct btrfs_device *device)
{
ASSERT((args->devid != (u64)-1) || args->missing);
if ((args->devid != (u64)-1) && device->devid != args->devid)
return false;
if (args->uuid && memcmp(device->uuid, args->uuid, BTRFS_UUID_SIZE) != 0)
return false;
if (!args->missing)
return true;
if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) &&
!device->bdev)
return true;
return false;
}
/* /*
* Find a device specified by @devid or @uuid in the list of @fs_devices, or * Find a device specified by @devid or @uuid in the list of @fs_devices, or
* return NULL. * return NULL.
...@@ -6761,33 +6790,27 @@ blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, ...@@ -6761,33 +6790,27 @@ blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
* If devid and uuid are both specified, the match must be exact, otherwise * If devid and uuid are both specified, the match must be exact, otherwise
* only devid is used. * only devid is used.
*/ */
struct btrfs_device *btrfs_find_device(struct btrfs_fs_devices *fs_devices, struct btrfs_device *btrfs_find_device(const struct btrfs_fs_devices *fs_devices,
u64 devid, u8 *uuid, u8 *fsid) const struct btrfs_dev_lookup_args *args)
{ {
struct btrfs_device *device; struct btrfs_device *device;
struct btrfs_fs_devices *seed_devs; struct btrfs_fs_devices *seed_devs;
if (!fsid || !memcmp(fs_devices->metadata_uuid, fsid, BTRFS_FSID_SIZE)) { if (dev_args_match_fs_devices(args, fs_devices)) {
list_for_each_entry(device, &fs_devices->devices, dev_list) { list_for_each_entry(device, &fs_devices->devices, dev_list) {
if (device->devid == devid && if (dev_args_match_device(args, device))
(!uuid || memcmp(device->uuid, uuid,
BTRFS_UUID_SIZE) == 0))
return device; return device;
} }
} }
list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) { list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
if (!fsid || if (!dev_args_match_fs_devices(args, seed_devs))
!memcmp(seed_devs->metadata_uuid, fsid, BTRFS_FSID_SIZE)) { continue;
list_for_each_entry(device, &seed_devs->devices, list_for_each_entry(device, &seed_devs->devices, dev_list) {
dev_list) { if (dev_args_match_device(args, device))
if (device->devid == devid &&
(!uuid || memcmp(device->uuid, uuid,
BTRFS_UUID_SIZE) == 0))
return device; return device;
} }
} }
}
return NULL; return NULL;
} }
...@@ -6951,6 +6974,7 @@ static void warn_32bit_meta_chunk(struct btrfs_fs_info *fs_info, ...@@ -6951,6 +6974,7 @@ static void warn_32bit_meta_chunk(struct btrfs_fs_info *fs_info,
static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
struct btrfs_chunk *chunk) struct btrfs_chunk *chunk)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
struct btrfs_fs_info *fs_info = leaf->fs_info; struct btrfs_fs_info *fs_info = leaf->fs_info;
struct extent_map_tree *map_tree = &fs_info->mapping_tree; struct extent_map_tree *map_tree = &fs_info->mapping_tree;
struct map_lookup *map; struct map_lookup *map;
...@@ -7028,11 +7052,12 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, ...@@ -7028,11 +7052,12 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
map->stripes[i].physical = map->stripes[i].physical =
btrfs_stripe_offset_nr(leaf, chunk, i); btrfs_stripe_offset_nr(leaf, chunk, i);
devid = btrfs_stripe_devid_nr(leaf, chunk, i); devid = btrfs_stripe_devid_nr(leaf, chunk, i);
args.devid = devid;
read_extent_buffer(leaf, uuid, (unsigned long) read_extent_buffer(leaf, uuid, (unsigned long)
btrfs_stripe_dev_uuid_nr(chunk, i), btrfs_stripe_dev_uuid_nr(chunk, i),
BTRFS_UUID_SIZE); BTRFS_UUID_SIZE);
map->stripes[i].dev = btrfs_find_device(fs_info->fs_devices, args.uuid = uuid;
devid, uuid, NULL); map->stripes[i].dev = btrfs_find_device(fs_info->fs_devices, &args);
if (!map->stripes[i].dev && if (!map->stripes[i].dev &&
!btrfs_test_opt(fs_info, DEGRADED)) { !btrfs_test_opt(fs_info, DEGRADED)) {
free_extent_map(em); free_extent_map(em);
...@@ -7150,6 +7175,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, ...@@ -7150,6 +7175,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info,
static int read_one_dev(struct extent_buffer *leaf, static int read_one_dev(struct extent_buffer *leaf,
struct btrfs_dev_item *dev_item) struct btrfs_dev_item *dev_item)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
struct btrfs_fs_info *fs_info = leaf->fs_info; struct btrfs_fs_info *fs_info = leaf->fs_info;
struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
struct btrfs_device *device; struct btrfs_device *device;
...@@ -7158,11 +7184,13 @@ static int read_one_dev(struct extent_buffer *leaf, ...@@ -7158,11 +7184,13 @@ static int read_one_dev(struct extent_buffer *leaf,
u8 fs_uuid[BTRFS_FSID_SIZE]; u8 fs_uuid[BTRFS_FSID_SIZE];
u8 dev_uuid[BTRFS_UUID_SIZE]; u8 dev_uuid[BTRFS_UUID_SIZE];
devid = btrfs_device_id(leaf, dev_item); devid = args.devid = btrfs_device_id(leaf, dev_item);
read_extent_buffer(leaf, dev_uuid, btrfs_device_uuid(dev_item), read_extent_buffer(leaf, dev_uuid, btrfs_device_uuid(dev_item),
BTRFS_UUID_SIZE); BTRFS_UUID_SIZE);
read_extent_buffer(leaf, fs_uuid, btrfs_device_fsid(dev_item), read_extent_buffer(leaf, fs_uuid, btrfs_device_fsid(dev_item),
BTRFS_FSID_SIZE); BTRFS_FSID_SIZE);
args.uuid = dev_uuid;
args.fsid = fs_uuid;
if (memcmp(fs_uuid, fs_devices->metadata_uuid, BTRFS_FSID_SIZE)) { if (memcmp(fs_uuid, fs_devices->metadata_uuid, BTRFS_FSID_SIZE)) {
fs_devices = open_seed_devices(fs_info, fs_uuid); fs_devices = open_seed_devices(fs_info, fs_uuid);
...@@ -7170,8 +7198,7 @@ static int read_one_dev(struct extent_buffer *leaf, ...@@ -7170,8 +7198,7 @@ static int read_one_dev(struct extent_buffer *leaf,
return PTR_ERR(fs_devices); return PTR_ERR(fs_devices);
} }
device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid, device = btrfs_find_device(fs_info->fs_devices, &args);
fs_uuid);
if (!device) { if (!device) {
if (!btrfs_test_opt(fs_info, DEGRADED)) { if (!btrfs_test_opt(fs_info, DEGRADED)) {
btrfs_report_missing_device(fs_info, devid, btrfs_report_missing_device(fs_info, devid,
...@@ -7840,12 +7867,14 @@ static void btrfs_dev_stat_print_on_load(struct btrfs_device *dev) ...@@ -7840,12 +7867,14 @@ static void btrfs_dev_stat_print_on_load(struct btrfs_device *dev)
int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info, int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info,
struct btrfs_ioctl_get_dev_stats *stats) struct btrfs_ioctl_get_dev_stats *stats)
{ {
BTRFS_DEV_LOOKUP_ARGS(args);
struct btrfs_device *dev; struct btrfs_device *dev;
struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
int i; int i;
mutex_lock(&fs_devices->device_list_mutex); mutex_lock(&fs_devices->device_list_mutex);
dev = btrfs_find_device(fs_info->fs_devices, stats->devid, NULL, NULL); args.devid = stats->devid;
dev = btrfs_find_device(fs_info->fs_devices, &args);
mutex_unlock(&fs_devices->device_list_mutex); mutex_unlock(&fs_devices->device_list_mutex);
if (!dev) { if (!dev) {
...@@ -7921,6 +7950,7 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, ...@@ -7921,6 +7950,7 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info,
u64 chunk_offset, u64 devid, u64 chunk_offset, u64 devid,
u64 physical_offset, u64 physical_len) u64 physical_offset, u64 physical_len)
{ {
struct btrfs_dev_lookup_args args = { .devid = devid };
struct extent_map_tree *em_tree = &fs_info->mapping_tree; struct extent_map_tree *em_tree = &fs_info->mapping_tree;
struct extent_map *em; struct extent_map *em;
struct map_lookup *map; struct map_lookup *map;
...@@ -7976,7 +8006,7 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, ...@@ -7976,7 +8006,7 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info,
} }
/* Make sure no dev extent is beyond device boundary */ /* Make sure no dev extent is beyond device boundary */
dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL); dev = btrfs_find_device(fs_info->fs_devices, &args);
if (!dev) { if (!dev) {
btrfs_err(fs_info, "failed to find devid %llu", devid); btrfs_err(fs_info, "failed to find devid %llu", devid);
ret = -EUCLEAN; ret = -EUCLEAN;
......
...@@ -451,6 +451,22 @@ struct btrfs_balance_control { ...@@ -451,6 +451,22 @@ struct btrfs_balance_control {
struct btrfs_balance_progress stat; struct btrfs_balance_progress stat;
}; };
/*
* Search for a given device by the set parameters
*/
struct btrfs_dev_lookup_args {
u64 devid;
u8 *uuid;
u8 *fsid;
bool missing;
};
/* We have to initialize to -1 because BTRFS_DEV_REPLACE_DEVID is 0 */
#define BTRFS_DEV_LOOKUP_ARGS_INIT { .devid = (u64)-1 }
#define BTRFS_DEV_LOOKUP_ARGS(name) \
struct btrfs_dev_lookup_args name = BTRFS_DEV_LOOKUP_ARGS_INIT
enum btrfs_map_op { enum btrfs_map_op {
BTRFS_MAP_READ, BTRFS_MAP_READ,
BTRFS_MAP_WRITE, BTRFS_MAP_WRITE,
...@@ -515,8 +531,8 @@ void __exit btrfs_cleanup_fs_uuids(void); ...@@ -515,8 +531,8 @@ void __exit btrfs_cleanup_fs_uuids(void);
int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len); int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
int btrfs_grow_device(struct btrfs_trans_handle *trans, int btrfs_grow_device(struct btrfs_trans_handle *trans,
struct btrfs_device *device, u64 new_size); struct btrfs_device *device, u64 new_size);
struct btrfs_device *btrfs_find_device(struct btrfs_fs_devices *fs_devices, struct btrfs_device *btrfs_find_device(const struct btrfs_fs_devices *fs_devices,
u64 devid, u8 *uuid, u8 *fsid); const struct btrfs_dev_lookup_args *args);
int btrfs_shrink_device(struct btrfs_device *device, u64 new_size); int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *path); int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *path);
int btrfs_balance(struct btrfs_fs_info *fs_info, int btrfs_balance(struct btrfs_fs_info *fs_info,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment