[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-btrfs
Subject:    [PATCH 2/3] Add property "preferred_metadata" to the btrfs property cmd.
From:       Goffredo Baroncelli <kreijack () libero ! it>
Date:       2020-05-28 18:34:55
Message-ID: 20200528183456.18030-3-kreijack () libero ! it
[Download RAW message or body]

From: Goffredo Baroncelli <kreijack@inwind.it>

Handle the property preferred_metadata to a btrfs device. Below
an example of use:

$ # set a new value
$ sudo btrfs property set /dev/vde preferred_metadata 1

$ # get the current value
$ sudo btrfs property get /dev/vde preferred_metadata
devid=4, path=/dev/vde: dedicated_metadata=1

Root privileges are required.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 props.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 140 insertions(+)

diff --git a/props.c b/props.c
index 67d106af..123b3813 100644
--- a/props.c
+++ b/props.c
@@ -20,6 +20,7 @@
 #include <sys/xattr.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
 
 #include <btrfsutil.h>
 
@@ -166,6 +167,139 @@ out:
 	return ret;
 }
 
+static int btrfs_find_devid_and_mnt(const char *devpath, int *devid,
+				    char *path, int maxpath)
+{
+	int ret, i, fd;
+	DIR *dir;
+	struct stat stdevpath;
+	struct btrfs_ioctl_fs_info_args fi_args;
+	struct btrfs_ioctl_dev_info_args dev_info;
+
+	ret = get_btrfs_mount(devpath, path, maxpath);
+	if (ret)
+		return ret;
+
+	fd = btrfs_open_dir(path, &dir, 1);
+	if (fd < 0)
+		return fd;
+
+	ret = stat(devpath, &stdevpath);
+	if (ret) {
+		error("cannot stat '%s'", devpath);
+		goto out;
+	}
+
+	ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
+        if (ret < 0) {
+                if (errno == EPERM)
+                        return -errno;
+                error("cannot get filesystem info: %m");
+		ret = -10;
+		goto out;
+        }
+
+	for (i = 0 ; i <= fi_args.max_id ; i++) {
+		struct stat st;
+                memset(&dev_info, 0, sizeof(dev_info));
+                ret = get_device_info(fd, i, &dev_info);
+                if (ret == -ENODEV)
+                        continue;
+                if (ret) {
+                        error("cannot get info about device devid=%d", i);
+                        goto out;
+                }
+
+		if (!dev_info.path)
+			/* missing devices */
+			continue;
+
+		ret = stat((char*)dev_info.path, &st);
+		if (ret) {
+			error("cannot stat '%s'", devpath);
+			goto out;
+		}
+
+		if (major(st.st_rdev) == major(stdevpath.st_rdev) &&
+		    minor(st.st_rdev) == minor(stdevpath.st_rdev)) {
+			*devid = dev_info.devid;
+			ret = 0;
+			goto out;
+		}
+	}
+
+	ret = -12;
+
+out:
+	close_file_or_dir(fd, dir);
+	return ret;
+}
+
+static int prop_preferred_metadata(enum prop_object_type type,
+				   const char *object,
+				   const char *name,
+				   const char *value)
+{
+	int ret, devid, fd, ival;
+	char path[PATH_MAX];
+	DIR *dir;
+	struct btrfs_ioctl_dev_properties props;
+
+	ret = btrfs_find_devid_and_mnt(object, &devid, path, sizeof(path));
+	if (ret)
+                return -5;
+
+	fd = btrfs_open_dir(path, &dir, 1);
+	if (fd < 0)
+		return fd;
+
+	memset(&props, 0, sizeof(props));
+	props.devid = devid;
+	props.properties = BTRFS_DEV_PROPERTY_TYPE|BTRFS_DEV_PROPERTY_READ;
+	ret = ioctl(fd, BTRFS_IOC_DEV_PROPERTIES, &props);
+	if (ret < 0) {
+		error("Cannot perform BTRFS_IOC_DEV_PROPERTIES ioctl on '%s'",
+				path);
+		ret = -1;
+		goto out;
+	}
+
+	if (!value) {
+		printf("devid=%d, path=%s: dedicated_metadata=%d\n",
+			devid, object,
+			!!(props.type & BTRFS_DEV_DEDICATED_METADATA));
+		ret = 0;
+		goto out;
+	}
+
+	ret = sscanf(value, "%d", &ival);
+	if (ret != 1) {
+		error("Cannot parse '%s'", value);
+		ret = -3;
+		goto out;
+	}
+
+	if (ival)
+		props.type |= BTRFS_DEV_DEDICATED_METADATA;
+	else
+		props.type &= ~BTRFS_DEV_DEDICATED_METADATA;
+
+	props.properties = BTRFS_DEV_PROPERTY_TYPE;
+	props.devid = devid;
+	ret = ioctl(fd, BTRFS_IOC_DEV_PROPERTIES, &props);
+	if (ret < 0) {
+		error("Cannot perform BTRFS_IOC_DEV_PROPERTIES ioctl on '%s'",
+			path);
+		ret = -4;
+		goto out;
+	}
+
+	ret = 0;
+out:
+	close_file_or_dir(fd, dir);
+	return ret;
+}
+
 const struct prop_handler prop_handlers[] = {
 	{
 		.name ="ro",
@@ -187,5 +321,11 @@ const struct prop_handler prop_handlers[] = {
 		.read_only = 0,
 	 	.types = prop_object_inode, prop_compression
 	},
+	{
+		.name = "preferred_metadata",
+		.desc = "preferred disk for storing metadata information",
+		.types = prop_object_dev,
+		.handler = prop_preferred_metadata,
+	},
 	{NULL, NULL, 0, 0, NULL}
 };
-- 
2.27.0.rc2

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic