linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH V4] btrfs-progs: preferred_metadata: preferred device for metadata
@ 2020-05-28 18:34 Goffredo Baroncelli
  2020-05-28 18:34 ` [PATCH 1/3] Update headers for the BTRFS_IOC_DEV_PROPERTIES Goffredo Baroncelli
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2020-05-28 18:34 UTC (permalink / raw)
  To: linux-btrfs

Hi all,

this is the user space part of the patches set "[RFC][PATCH V4] btrfs:
preferred_metadata: preferred device for metadata".
Refer to this patches set for the info.

This patch set implements the "btrfs property get/set preferred_metadata".

The first patch adds the ioctl support.
The second patch adds the property handler.
The third patch adds an update of the man page.

BR
G.Baroncelli

-- 
gpg @keyserver.linux.it: Goffredo Baroncelli <kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] Update headers for the BTRFS_IOC_DEV_PROPERTIES.
  2020-05-28 18:34 [RFC][PATCH V4] btrfs-progs: preferred_metadata: preferred device for metadata Goffredo Baroncelli
@ 2020-05-28 18:34 ` Goffredo Baroncelli
  2020-05-28 18:34 ` [PATCH 2/3] Add property "preferred_metadata" to the btrfs property cmd Goffredo Baroncelli
  2020-05-28 18:34 ` [PATCH 3/3] Update man page for preferred_metadata property Goffredo Baroncelli
  2 siblings, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2020-05-28 18:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Goffredo Baroncelli

From: Goffredo Baroncelli <kreijack@inwind.it>

Update the header to add the BTRFS_IOC_DEV_PROPERTIES ioctl:
- add ioctl BTRFS_IOC_DEV_PROPERTIES define
- add struct btrfs_ioctl_dev_properties
- add the BTRFS_DEV_PROPERTY_ define

This ioctl is a base for returning / setting information from / to  the
fields of the btrfs_dev_item object.

For now only the "type" field is returned / set.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 ctree.h |  2 ++
 ioctl.h | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/ctree.h b/ctree.h
index 7757e50c..aa027e1c 100644
--- a/ctree.h
+++ b/ctree.h
@@ -219,6 +219,8 @@ struct btrfs_mapping_tree {
 	struct cache_tree cache_tree;
 };
 
+#define BTRFS_DEV_DEDICATED_METADATA (1ULL << 0)
+
 #define BTRFS_UUID_SIZE 16
 struct btrfs_dev_item {
 	/* the internal btrfs device id */
diff --git a/ioctl.h b/ioctl.h
index ade6dcb9..a4febb95 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -775,6 +775,44 @@ struct btrfs_ioctl_get_subvol_rootref_args {
 };
 BUILD_ASSERT(sizeof(struct btrfs_ioctl_get_subvol_rootref_args) == 4096);
 
+#define BTRFS_DEV_PROPERTY_TYPE		(1ULL << 0)
+#define BTRFS_DEV_PROPERTY_DEV_GROUP	(1ULL << 1)
+#define BTRFS_DEV_PROPERTY_SEEK_SPEED	(1ULL << 2)
+#define BTRFS_DEV_PROPERTY_BANDWIDTH	(1ULL << 3)
+#define BTRFS_DEV_PROPERTY_READ		(1ULL << 60)
+
+/*
+ * The ioctl BTRFS_IOC_DEV_PROPERTIES can read and write the device properties.
+ *
+ * The properties that the user want to write have to be set
+ * in the 'properties' field using the BTRFS_DEV_PROPERTY_xxxx constants.
+ *
+ * If the ioctl is used to read the device properties, the bit
+ * BTRFS_DEV_PROPERTY_READ has to be set in the 'properties' field.
+ * In this case the properties that the user want have to be set in the
+ * 'properties' field. The kernel doesn't return a property that was not
+ * required, however it may return a subset of the requested properties.
+ * The returned properties have the corrispondent BTRFS_DEV_PROPERTY_xxxx
+ * flag set in the 'properties' field.
+ *
+ * Up to 2020/05/11 the only properties that can be read/write is the 'type'
+ * one.
+ */
+struct btrfs_ioctl_dev_properties {
+	__u64	devid;
+	__u64	properties;
+	__u64	type;
+	__u32	dev_group;
+	__u8	seek_speed;
+	__u8	bandwidth;
+
+	/*
+	 * for future expansion
+	 */
+	__u8	unused1[2];
+	__u64	unused2[4];
+};
+
 /* Error codes as returned by the kernel */
 enum btrfs_err_code {
 	notused,
@@ -949,6 +987,8 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
 				struct btrfs_ioctl_ino_lookup_user_args)
 #define BTRFS_IOC_SNAP_DESTROY_V2 _IOW(BTRFS_IOCTL_MAGIC, 63, \
 				   struct btrfs_ioctl_vol_args_v2)
+#define BTRFS_IOC_DEV_PROPERTIES _IOW(BTRFS_IOCTL_MAGIC, 64, \
+				struct btrfs_ioctl_dev_properties)
 
 #ifdef __cplusplus
 }
-- 
2.27.0.rc2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] Add property "preferred_metadata" to the btrfs property cmd.
  2020-05-28 18:34 [RFC][PATCH V4] btrfs-progs: preferred_metadata: preferred device for metadata Goffredo Baroncelli
  2020-05-28 18:34 ` [PATCH 1/3] Update headers for the BTRFS_IOC_DEV_PROPERTIES Goffredo Baroncelli
@ 2020-05-28 18:34 ` Goffredo Baroncelli
  2020-05-28 18:34 ` [PATCH 3/3] Update man page for preferred_metadata property Goffredo Baroncelli
  2 siblings, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2020-05-28 18:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Goffredo Baroncelli

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] Update man page for preferred_metadata property.
  2020-05-28 18:34 [RFC][PATCH V4] btrfs-progs: preferred_metadata: preferred device for metadata Goffredo Baroncelli
  2020-05-28 18:34 ` [PATCH 1/3] Update headers for the BTRFS_IOC_DEV_PROPERTIES Goffredo Baroncelli
  2020-05-28 18:34 ` [PATCH 2/3] Add property "preferred_metadata" to the btrfs property cmd Goffredo Baroncelli
@ 2020-05-28 18:34 ` Goffredo Baroncelli
  2 siblings, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2020-05-28 18:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: 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 "preferred_metadata".

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 Documentation/btrfs-property.asciidoc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/btrfs-property.asciidoc b/Documentation/btrfs-property.asciidoc
index 47960833..e1396bd2 100644
--- a/Documentation/btrfs-property.asciidoc
+++ b/Documentation/btrfs-property.asciidoc
@@ -48,6 +48,9 @@ device as object. For a mounted filesystem, specify a mount point.
 compression::::
 compression algorithm set for an inode, possible values: 'lzo', 'zlib', 'zstd'.
 To disable compression use "" (empty string), 'no' or 'none'.
+preferred_metadata::::
+flag that designate a device as reserved only for metadata/system chunks.
+Possible values: 0 or 1.
 
 *list* [-t <type>] <object>::
 Lists available properties with their descriptions for the given object.
-- 
2.27.0.rc2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-28 18:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-28 18:34 [RFC][PATCH V4] btrfs-progs: preferred_metadata: preferred device for metadata Goffredo Baroncelli
2020-05-28 18:34 ` [PATCH 1/3] Update headers for the BTRFS_IOC_DEV_PROPERTIES Goffredo Baroncelli
2020-05-28 18:34 ` [PATCH 2/3] Add property "preferred_metadata" to the btrfs property cmd Goffredo Baroncelli
2020-05-28 18:34 ` [PATCH 3/3] Update man page for preferred_metadata property Goffredo Baroncelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).