* [PATCH 0/2][V11] btrfs-progs: allocation_hint disk property
@ 2022-01-26 20:32 Goffredo Baroncelli
2022-01-26 20:32 ` [PATCH 1/2] btrfs-progs: new "allocation_hint" property Goffredo Baroncelli
2022-01-26 20:32 ` [PATCH 2/2] Update man page for allocator_hint property Goffredo Baroncelli
0 siblings, 2 replies; 3+ messages in thread
From: Goffredo Baroncelli @ 2022-01-26 20:32 UTC (permalink / raw)
To: linux-btrfs
Cc: Zygo Blaxell, Josef Bacik, David Sterba, Sinnamohideen Shafeeq,
Paul Jones, Boris Burkov, Goffredo Baroncelli
From: Goffredo Baroncelli <kreijack@inwind.it>
This patches set is the userspace portion of the serie
"[PATCH V11] btrfs: allocation_hint".
Look this patches set for further information.
Changelog
V11:
- find the correct /sys/fs/btrfs/<UUID> directory using the
devinfo/major_minor sysfs file.
- update the man page to the .rst file format
G.Baroncelli
Goffredo Baroncelli (2):
btrfs-progs: new "allocation_hint" property.
Update man page for allocator_hint property.
Documentation/btrfs-property.rst | 21 +++
cmds/property.c | 253 +++++++++++++++++++++++++++++++
kernel-shared/ctree.h | 13 ++
3 files changed, 287 insertions(+)
--
2.34.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] btrfs-progs: new "allocation_hint" property.
2022-01-26 20:32 [PATCH 0/2][V11] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
@ 2022-01-26 20:32 ` Goffredo Baroncelli
2022-01-26 20:32 ` [PATCH 2/2] Update man page for allocator_hint property Goffredo Baroncelli
1 sibling, 0 replies; 3+ messages in thread
From: Goffredo Baroncelli @ 2022-01-26 20:32 UTC (permalink / raw)
To: linux-btrfs
Cc: Zygo Blaxell, Josef Bacik, David Sterba, Sinnamohideen Shafeeq,
Paul Jones, Boris Burkov, Goffredo Baroncelli
From: Goffredo Baroncelli <kreijack@inwind.it>
Handle the property allocation_hint of a btrfs device. Below
an example of use:
$ # set a new value
$ sudo btrfs property set /dev/vde allocation_hint DATA_ONLY
$ # get the current value
$ sudo btrfs property get /dev/vde allocation_hint
devid=4, path=/dev/vde: allocation_hint=DATA_ONLY
The following values are availables:
- DATA_ONLY
- DATA_PREFERRED (default)
- METADATA_PREFERRED
- METADATA_ONLY
Root privileges are required.
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
cmds/property.c | 253 ++++++++++++++++++++++++++++++++++++++++++
kernel-shared/ctree.h | 13 +++
2 files changed, 266 insertions(+)
diff --git a/cmds/property.c b/cmds/property.c
index b3ccc0ff..a409f4e9 100644
--- a/cmds/property.c
+++ b/cmds/property.c
@@ -22,6 +22,7 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/xattr.h>
+#include <sys/sysmacros.h>
#include <uuid/uuid.h>
#include <btrfsutil.h>
#include "cmds/commands.h"
@@ -232,6 +233,252 @@ out:
return ret;
}
+/*
+ * @major, @minor -> device to find
+ * @uuid -> uuid of the filesystem (out)
+ * @devid -> devid (out)
+ *
+ * return -> -ENOTSUP operation not supported (i.e. btrfs doesn't
+ * support allocation_hint)
+ * -> -ENODEV operation supported, but device not mounted
+ * -> -EACCES error accessing sysfs
+ * -> 0 ok
+ */
+#define BTRFSYSFS "/sys/fs/btrfs/"
+static int btrfs_find_devid_uuid_by_major_minor(int major,
+ int minor,
+ u64 *devid,
+ char *uuid) {
+
+ DIR *dp = NULL, *dp2 = NULL;
+ char path[200]; /* should be enough for
+ * /sys/btrfs/<uuid>/devices/<devid>/major_minor
+ */
+ int ret;
+ struct dirent *de;
+ int l;
+
+ strcpy(path, BTRFSYSFS);
+ dp = opendir(path);
+ if (!dp) {
+ ret = -EACCES;
+ goto quit;
+ }
+
+ while ((de = readdir(dp)) != NULL) {
+ if (strlen(de->d_name) != 36)
+ continue;
+
+ strcpy(path + sizeof(BTRFSYSFS) - 1, de->d_name);
+ strcat(path, "/devinfo/");
+
+ dp2 = opendir(path);
+ if (!dp2) {
+ ret = -EACCES;
+ goto quit;
+ }
+
+ l = strlen(path);
+ while ((de = readdir(dp2)) != NULL) {
+ FILE *fp;
+ char buf[100];
+ char *endptr;
+ int r, maj, mnr;
+
+ errno = 0;
+ *devid = strtoull(de->d_name, &endptr, 0);
+
+ /* check for invalid devid */
+ if (errno || *endptr != 0)
+ continue;
+
+
+ strcpy(path + l, de->d_name);
+ strcat(path, "/major_minor");
+
+ fp = fopen(path, "r");
+ if (!fp) {
+ if (errno == -ENOENT)
+ ret = -ENOTSUP;
+ else
+ ret = -EACCES;
+ goto quit;
+ }
+ r = fread(buf, 1, sizeof(buf) - 2, fp);
+ buf[r] = 0;
+ fclose(fp);
+
+ if (!strcmp(buf, "N/A\n"))
+ continue;
+
+ r = sscanf(buf, "%d:%d", &maj, &mnr);
+ if (r != 2) {
+ ret = -EACCES;
+ goto quit;
+ }
+
+ if (maj == major && minor == mnr) {
+ strncpy(uuid,
+ path + sizeof(BTRFSYSFS) - 1,
+ 36);
+ uuid[36] = 0;
+ ret = 0;
+ goto quit;
+ }
+ }
+ }
+
+ ret = -ENODEV;
+quit:
+ if (dp)
+ closedir(dp);
+ if (dp2)
+ closedir(dp2);
+ return ret;
+}
+
+/*
+ * @dev -> device to find
+ * @uuid -> uuid of the filesystem (out)
+ * @devid -> devid (out)
+ *
+ * return -> -ENOTSUP operation not supported (i.e. btrfs doesn't
+ * support allocation_hint)
+ * -> -ENODEV operation supported, but device not mounted
+ * -> -EACCES error accessing sysfs
+ * -> 0 ok
+ */
+static int btrfs_find_devid_uuid_by_dev(const char *dev,
+ u64 *devid,
+ char *uuid)
+{
+ struct stat st;
+ int r;
+
+ r = stat(dev, &st);
+ if (r < 0 && errno == -ENODEV)
+ return -ENODEV;
+ if (r < 0)
+ return -EACCES;
+
+ return btrfs_find_devid_uuid_by_major_minor(major(st.st_rdev),
+ minor(st.st_rdev),
+ devid, uuid);
+}
+
+static struct ull_charp_pair_t {
+ u64 value;
+ const char *descr;
+} allocation_hint_description[] = {
+ {BTRFS_DEV_ALLOCATION_HINT_METADATA_PREFERRED, "METADATA_PREFERRED"},
+ {BTRFS_DEV_ALLOCATION_HINT_METADATA_ONLY, "METADATA_ONLY"},
+ {BTRFS_DEV_ALLOCATION_HINT_DATA_PREFERRED, "DATA_PREFERRED"},
+ {BTRFS_DEV_ALLOCATION_HINT_DATA_ONLY, "DATA_ONLY"},
+ {0, NULL}
+};
+
+static int prop_allocation_hint(enum prop_object_type type,
+ const char *object,
+ const char *name,
+ const char *val,
+ bool force)
+{
+ int ret, fd2 = -1;
+ u64 devid;
+ char sysfs_file[PATH_MAX];
+ int i;
+ u64 v;
+ char buf[1024];
+
+ strcpy(sysfs_file, BTRFSYSFS);
+ ret = btrfs_find_devid_uuid_by_dev(object, &devid,
+ sysfs_file + sizeof(BTRFSYSFS) - 1);
+
+ if (ret)
+ goto out;
+
+ sprintf(sysfs_file + strlen(sysfs_file),
+ "/devinfo/%llu/allocation_hint", devid);
+
+ if (!val) {
+ /* READ */
+ fd2 = open(sysfs_file, O_RDONLY);
+ if (fd2 < 0 && errno == ENOENT) {
+ /* older kernel doesn't have allocation_hint; return nothing */
+ ret = 0;
+ goto out;
+ } else if (fd2 < 0) {
+ error("'allocation_hint' property not available or accessible.");
+ ret = -errno;
+ goto out;
+ }
+
+ ret = read(fd2, buf, sizeof(buf) - 1);
+ if (ret < 0) {
+ error("Unable to read the 'allocation_hint' property.");
+ ret = -errno;
+ goto out;
+ }
+
+ buf[sizeof(buf) - 1] = 0;
+ v = strtoull(buf, NULL, 0);
+
+ for (i = 0 ; allocation_hint_description[i].descr ; i++)
+ if (v == allocation_hint_description[i].value)
+ break;
+
+ if (allocation_hint_description[i].descr)
+ printf("allocation_hint=%s\n",
+ allocation_hint_description[i].descr);
+ else
+ printf("allocation_hint=unknown:%llu\n", v);
+ ret = 0;
+ } else {
+ /* WRITE */
+ for (i = 0 ; allocation_hint_description[i].descr ; i++)
+ if (!strcmp(val, allocation_hint_description[i].descr))
+ break;
+
+ if (allocation_hint_description[i].descr) {
+ v = allocation_hint_description[i].value;
+ } else if (sscanf(val, "%llu", &v) != 1) {
+ error("Invalid value '%s'\n", val);
+ ret = -3;
+ goto out;
+ }
+ if (v & ~BTRFS_DEV_ALLOCATION_HINT_MASK) {
+ error("Invalid value '%s'\n", val);
+ ret = -3;
+ goto out;
+ }
+
+ fd2 = open(sysfs_file, O_RDWR);
+ if (fd2 < 0) {
+ error("'allocation_hint' property not available or accessible for updating.");
+ ret = -errno;
+ goto out;
+ }
+
+ sprintf(buf, "%llu", v);
+
+ ret = write(fd2, buf, strlen(buf));
+
+ if (ret != strlen(buf)) {
+ error("Unable to update 'allocation_hint' property.");
+ ret = -errno;
+ goto out;
+ }
+
+ }
+
+ ret = 0;
+out:
+ if (fd2 >= 0)
+ close(fd2);
+
+ return ret;
+}
+
const struct prop_handler prop_handlers[] = {
{
.name ="ro",
@@ -254,6 +501,12 @@ const struct prop_handler prop_handlers[] = {
.types = prop_object_inode,
.handler = prop_compression
},
+ {
+ .name = "allocation_hint",
+ .desc = "hint to store the data/metadata chunks",
+ .types = prop_object_dev,
+ .handler = prop_allocation_hint
+ },
{NULL, NULL, 0, 0, NULL}
};
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index ab2aaed6..628539c0 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -216,6 +216,19 @@ struct btrfs_mapping_tree {
struct cache_tree cache_tree;
};
+/* btrfs chunk allocation hints */
+#define BTRFS_DEV_ALLOCATION_HINT_BIT_COUNT 2
+#define BTRFS_DEV_ALLOCATION_HINT_MASK ((1ULL << \
+ BTRFS_DEV_ALLOCATION_HINT_BIT_COUNT) - 1)
+/* preferred metadata chunk, but data chunk allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_METADATA_PREFERRED (1ULL)
+/* only metadata chunk are allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_METADATA_ONLY (2ULL)
+/* only data chunk allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_DATA_ONLY (3ULL)
+/* preferred data chunk, but metadata chunk allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_DATA_PREFERRED (0ULL)
+
#define BTRFS_UUID_SIZE 16
struct btrfs_dev_item {
/* the internal btrfs device id */
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] Update man page for allocator_hint property.
2022-01-26 20:32 [PATCH 0/2][V11] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
2022-01-26 20:32 ` [PATCH 1/2] btrfs-progs: new "allocation_hint" property Goffredo Baroncelli
@ 2022-01-26 20:32 ` Goffredo Baroncelli
1 sibling, 0 replies; 3+ messages in thread
From: Goffredo Baroncelli @ 2022-01-26 20:32 UTC (permalink / raw)
To: linux-btrfs
Cc: Zygo Blaxell, Josef Bacik, David Sterba, Sinnamohideen Shafeeq,
Paul Jones, Boris Burkov, Goffredo Baroncelli
From: Goffredo Baroncelli <kreijack@inwind.it>
Update the man page of the btrfs property subcommand to show the use
of the device property "allocation_hint".
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
Documentation/btrfs-property.rst | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/Documentation/btrfs-property.rst b/Documentation/btrfs-property.rst
index 5896faa2..155839fe 100644
--- a/Documentation/btrfs-property.rst
+++ b/Documentation/btrfs-property.rst
@@ -48,6 +48,27 @@ get [-t <type>] <object> [<name>]
compression
compression algorithm set for an inode, possible values: *lzo*, *zlib*, *zstd*.
To disable compression use "" (empty string), *no* or *none*.
+ allocation_hint
+ a device property that instructs how and when the allocator should use a
+ block device.
+ Possible values are:
+
+ METADATA_PREFERRED
+ the device has an higher priority when a new metadata
+ chunk is allocated. Data chunk is allowed only if there is no other
+ possibility.
+ METADATA_ONLY
+ the device is used only for metadata chunk.
+ Data chunk is never allowed.
+ DATA_PREFERRED (default)
+ the device has an higher priority when a new data
+ chunk is allocated. Metadata chunk is allowed only if there is no other
+ possibility.
+ DATA_ONLY
+ the device is used only for data chunk. Metadata chunk is never allowed.
+
+ The default is 'DATA_PREFERRED'; if all the disks have this setting the
+ allocator uses all of them with the same priority.
list [-t <type>] <object>
Lists available properties with their descriptions for the given object.
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-01-26 20:32 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-01-26 20:32 [PATCH 0/2][V11] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
2022-01-26 20:32 ` [PATCH 1/2] btrfs-progs: new "allocation_hint" property Goffredo Baroncelli
2022-01-26 20:32 ` [PATCH 2/2] Update man page for allocator_hint property Goffredo Baroncelli
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.