btrfs-progs: add helpers for parsing filesystem exclusive operation

Since kernel 5.10, the file /sys/fs/btrfs/FSID/exclusive_operation
exports textual id of the running exclusive operation (balance, device
add/remove, ...). Add definitions and parsing functions so they can be
used to check before another operation is started and potentially
blocks.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2020-11-05 01:06:29 +01:00
parent 34f0594bca
commit 639ddf61ca
2 changed files with 63 additions and 0 deletions

View file

@ -1925,3 +1925,53 @@ int sysfs_read_file(int fd, char *buf, size_t size)
memset(buf, 0, size);
return read(fd, buf, size);
}
static const char exclop_def[][16] = {
[BTRFS_EXCLOP_NONE] "none",
[BTRFS_EXCLOP_BALANCE] "balance",
[BTRFS_EXCLOP_DEV_ADD] "device add",
[BTRFS_EXCLOP_DEV_REMOVE] "device remove",
[BTRFS_EXCLOP_DEV_REPLACE] "device replace",
[BTRFS_EXCLOP_RESIZE] "resize",
[BTRFS_EXCLOP_SWAP_ACTIVATE] "swap activate",
};
/*
* Read currently running exclusive operation from sysfs. If this is not
* available, return BTRFS_EXCLOP_UNKNOWN
*/
int get_fs_exclop(int fd)
{
int sysfs_fd;
char buf[32];
int ret;
int i;
sysfs_fd = sysfs_open_fsid_file(fd, "exclusive_operation");
if (sysfs_fd < 0)
return BTRFS_EXCLOP_UNKNOWN;
memset(buf, 0, sizeof(buf));
ret = sysfs_read_file(sysfs_fd, buf, sizeof(buf));
close(sysfs_fd);
if (ret <= 0)
return BTRFS_EXCLOP_UNKNOWN;
i = strlen(buf) - 1;
while (i > 0 && isspace(buf[i])) i--;
if (i > 0)
buf[i + 1] = 0;
for (i = 0; i < ARRAY_SIZE(exclop_def); i++) {
if (strcmp(exclop_def[i], buf) == 0)
return i;
}
return BTRFS_EXCLOP_UNKNOWN;
}
const char *get_fs_exclop_name(int op)
{
if (0 <= op && op <= ARRAY_SIZE(exclop_def))
return exclop_def[op];
return "UNKNOWN";
}

View file

@ -52,6 +52,17 @@
#define UNITS_HUMAN (UNITS_HUMAN_BINARY)
#define UNITS_DEFAULT (UNITS_HUMAN)
enum exclusive_operation {
BTRFS_EXCLOP_NONE,
BTRFS_EXCLOP_BALANCE,
BTRFS_EXCLOP_DEV_ADD,
BTRFS_EXCLOP_DEV_REMOVE,
BTRFS_EXCLOP_DEV_REPLACE,
BTRFS_EXCLOP_RESIZE,
BTRFS_EXCLOP_SWAP_ACTIVATE,
BTRFS_EXCLOP_UNKNOWN = -1,
};
void units_set_mode(unsigned *units, unsigned mode);
void units_set_base(unsigned *units, unsigned base);
@ -76,6 +87,8 @@ int get_fs_info(const char *path, struct btrfs_ioctl_fs_info_args *fi_args,
struct btrfs_ioctl_dev_info_args **di_ret);
int get_fsid(const char *path, u8 *fsid, int silent);
int get_fsid_fd(int fd, u8 *fsid);
int get_fs_exclop(int fd);
const char *get_fs_exclop_name(int op);
int get_label(const char *btrfs_dev, char *label);
int set_label(const char *btrfs_dev, const char *label);