[PATCH 3/4] btrfs-progs: Check for exclusive operation before issuing ioctl

Goldwyn Rodrigues
2020-08-25T15:04:06Z

Check if an exclusive operation is running and if it is, err with the
name of the exclusive operation running.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
---
cmds/device.c | 14 ++++++++++++++
cmds/filesystem.c | 7 +++++++
2 files changed, 21 insertions(+)

diff --git a/cmds/device.c b/cmds/device.c
index 99ceed93..6acd4ae6 100644
--- a/cmds/device.c
+++ b/cmds/device.c
@@ -61,6 +61,7 @@ static int cmd_device_add(const struct cmd_struct *cmd,
int discard = 1;
int force = 0;
int last_dev;
+ char exop[BTRFS_SYSFS_EXOP_SIZE];

optind = 0;
while (1) {
@@ -96,6 +97,12 @@ static int cmd_device_add(const struct cmd_struct *cmd,
if (fdmnt < 0)
return 1;

+ if (get_exclusive_operation(fdmnt, exop) > 0 && strcmp(exop, "none")) {
+ error("unable to add device: %s in progress", exop);
+ close_file_or_dir(fdmnt, dirstream);
+ return 1;
+ }
+
for (i = optind; i < last_dev; i++){
struct btrfs_ioctl_vol_args ioctl_args;
int devfd, res;
@@ -155,6 +162,7 @@ static int _cmd_device_remove(const struct cmd_struct *cmd,
char *mntpnt;
int i, fdmnt, ret = 0;
DIR *dirstream = NULL;
+ char exop[BTRFS_SYSFS_EXOP_SIZE];

clean_args_no_options(cmd, argc, argv);

@@ -167,6 +175,12 @@ static int _cmd_device_remove(const struct cmd_struct *cmd,
if (fdmnt < 0)
return 1;

+ if (get_exclusive_operation(fdmnt, exop) > 0 && strcmp(exop, "none")) {
+ error("unable to remove device: %s in progress", exop);
+ close_file_or_dir(fdmnt, dirstream);
+ return 1;
+ }
+
for(i = optind; i < argc - 1; i++) {
struct btrfs_ioctl_vol_args arg;
struct btrfs_ioctl_vol_args_v2 argv2 = {0};
diff --git a/cmds/filesystem.c b/cmds/filesystem.c
index 6c1b6908..c3efb405 100644
--- a/cmds/filesystem.c
+++ b/cmds/filesystem.c
@@ -1079,6 +1079,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
char *amount, *path;
DIR *dirstream = NULL;
struct stat st;
+ char exop[BTRFS_SYSFS_EXOP_SIZE];

clean_args_no_options_relaxed(cmd, argc, argv);

@@ -1110,6 +1111,12 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
if (fd < 0)
return 1;

+ if (get_exclusive_operation(fd, exop) > 0 && strcmp(exop, "none")) {
+ error("unable to resize: %s in progress", exop);
+ close_file_or_dir(fd, dirstream);
+ return 1;
+ }
+
printf("Resize '%s' of '%s'\n", path, amount);
memset(&args, 0, sizeof(args));
strncpy_null(args.name, amount);
--
2.26.2