btrfs-progs: device add: support adding zoned device

Check if the target file system is flagged as ZONED. If it is, the
device to be added is flagged PREP_DEVICE_ZONED.  Also add checks to
prevent mixing non-zoned devices and zoned devices.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Naohiro Aota 2021-04-26 15:27:41 +09:00 committed by David Sterba
parent 8c2dfa6387
commit 568f9ed26f

View file

@ -29,6 +29,7 @@
#include "ioctl.h" #include "ioctl.h"
#include "common/utils.h" #include "common/utils.h"
#include "kernel-shared/volumes.h" #include "kernel-shared/volumes.h"
#include "kernel-shared/zoned.h"
#include "cmds/filesystem-usage.h" #include "cmds/filesystem-usage.h"
#include "cmds/commands.h" #include "cmds/commands.h"
@ -65,6 +66,8 @@ static int cmd_device_add(const struct cmd_struct *cmd,
int force = 0; int force = 0;
int last_dev; int last_dev;
bool enqueue = false; bool enqueue = false;
int zoned;
struct btrfs_ioctl_feature_flags feature_flags;
optind = 0; optind = 0;
while (1) { while (1) {
@ -113,12 +116,27 @@ static int cmd_device_add(const struct cmd_struct *cmd,
return 1; return 1;
} }
ret = ioctl(fdmnt, BTRFS_IOC_GET_FEATURES, &feature_flags);
if (ret) {
error("error getting feature flags '%s': %m", mntpnt);
return 1;
}
zoned = (feature_flags.incompat_flags & BTRFS_FEATURE_INCOMPAT_ZONED);
for (i = optind; i < last_dev; i++){ for (i = optind; i < last_dev; i++){
struct btrfs_ioctl_vol_args ioctl_args; struct btrfs_ioctl_vol_args ioctl_args;
int devfd, res; int devfd, res;
u64 dev_block_count = 0; u64 dev_block_count = 0;
char *path; char *path;
if (!zoned && zoned_model(argv[i]) == ZONED_HOST_MANAGED) {
error(
"zoned: cannot add host-managed zoned device to non-zoned filesystem '%s'",
argv[i]);
ret++;
continue;
}
res = test_dev_for_mkfs(argv[i], force); res = test_dev_for_mkfs(argv[i], force);
if (res) { if (res) {
ret++; ret++;
@ -134,7 +152,8 @@ static int cmd_device_add(const struct cmd_struct *cmd,
res = btrfs_prepare_device(devfd, argv[i], &dev_block_count, 0, res = btrfs_prepare_device(devfd, argv[i], &dev_block_count, 0,
PREP_DEVICE_ZERO_END | PREP_DEVICE_VERBOSE | PREP_DEVICE_ZERO_END | PREP_DEVICE_VERBOSE |
(discard ? PREP_DEVICE_DISCARD : 0)); (discard ? PREP_DEVICE_DISCARD : 0) |
(zoned ? PREP_DEVICE_ZONED : 0));
close(devfd); close(devfd);
if (res) { if (res) {
ret++; ret++;