File 0003-btrfs-progs-add-helpers-for-parsing-filesystem-exclu.patch of Package btrfsprogs.24931
From 639ddf61ca6dc0008a18ca63f05bccf6e5837bbe Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.com>
Date: Thu, 5 Nov 2020 01:06:29 +0100
Subject: [PATCH] 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>
---
utils.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
utils.h | 13 +++++++++++++
2 files changed, 63 insertions(+)
--- a/utils.c
+++ b/utils.c
@@ -2631,3 +2631,53 @@
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";
+}
--- a/utils.h
+++ b/utils.h
@@ -63,6 +63,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);
@@ -112,6 +123,8 @@
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 is_seen_fsid(u8 *fsid, struct seen_fsid *seen_fsid_hash[]);
int add_seen_fsid(u8 *fsid, struct seen_fsid *seen_fsid_hash[],