All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] f2fs-tools: Fix device zoned model detection
@ 2019-04-22  2:04 Shin'ichiro Kawasaki
  2019-04-22  2:41 ` Chao Yu
  0 siblings, 1 reply; 2+ messages in thread
From: Shin'ichiro Kawasaki @ 2019-04-22  2:04 UTC (permalink / raw)
  To: Jaegeuk Kim, Chao Yu, linux-f2fs-devel; +Cc: Damien Le Moal

A partition device does not have the "zoned" nor "chunk_sectors" sysfs
attribute files. Only the owner block device of the partition has these
files. This causes the detection of the zoned model and zone size of a
partition device to fail when executing mkfs.f2fs.

Fix this problem by using the owner device sysfs directory as the base
directory for accessing the zoned and chunk_sectors files. This is done
by using the device major:minor symbolic link under the /sys/dev/block
directory, reading this link and removing the partition device name from
the link path for a partition device (which is indicated by the presence
of the "partition" file under the directory).

Also add a check for the ENOENT error when opening the device "zoned"
sysfs attribute file. The absence of this file indicates that the
kernel does not support zoned block devices. Since the device file is
already open, it exists, and so the device can safely be assumed as not
being zoned.

Changes from v2:
* Addressed Chao Yu's comment on snprintf buffer length

Changes from v1:
* Addressed Chao Yu's comment on ENOENT and return value checks
* Rewrite of sysfs file handling (simplified)
* Rebased on dev-test tree

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
 lib/libf2fs_zoned.c | 101 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 88 insertions(+), 13 deletions(-)

diff --git a/lib/libf2fs_zoned.c b/lib/libf2fs_zoned.c
index a5f3fea..af00b44 100644
--- a/lib/libf2fs_zoned.c
+++ b/lib/libf2fs_zoned.c
@@ -8,6 +8,7 @@
  */
 #define _LARGEFILE64_SOURCE
 
+#include <f2fs_fs.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -15,6 +16,12 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#ifdef HAVE_SYS_SYSMACROS_H
+#include <sys/sysmacros.h>
+#endif
+#ifdef HAVE_LINUX_LIMITS_H
+#include <linux/limits.h>
+#endif
 #ifndef ANDROID_WINDOWS_HOST
 #include <sys/ioctl.h>
 #endif
@@ -24,27 +31,92 @@
 
 #ifdef HAVE_LINUX_BLKZONED_H
 
+int get_sysfs_path(struct device_info *dev, const char *attr,
+		   char *buf, size_t buflen)
+{
+	struct stat statbuf;
+	char str[PATH_MAX];
+	char sysfs_path[PATH_MAX];
+	ssize_t len;
+	char *delim;
+	int ret;
+
+	if (stat(dev->path, &statbuf) < 0)
+		return -1;
+
+	snprintf(str, sizeof(str), "/sys/dev/block/%d:%d",
+		 major(statbuf.st_rdev), minor(statbuf.st_rdev));
+	len = readlink(str, buf, buflen - 1);
+	if (len < 0)
+		return -1;
+	buf[len] = '\0';
+
+	ret = snprintf(sysfs_path, sizeof(sysfs_path),
+		       "/sys/dev/block/%s", buf);
+	if (ret >= sizeof(sysfs_path))
+		return -1;
+
+	/* Test if the device is a partition */
+	ret = snprintf(str, sizeof(str), "%s/partition", sysfs_path);
+	if (ret >= sizeof(str))
+		return -1;
+	ret = stat(str, &statbuf);
+	if (ret) {
+		if (errno == ENOENT) {
+			/* Not a partition */
+			goto out;
+		}
+		return -1;
+	}
+
+	/*
+	 * The device is a partition: remove the device name from the
+	 * attribute file path to obtain the sysfs path of the holder device.
+	 *   e.g.:  /sys/dev/block/.../sda/sda1 -> /sys/dev/block/.../sda
+	 */
+	delim = strrchr(sysfs_path, '/');
+	if (!delim)
+		return -1;
+	*delim = '\0';
+
+out:
+	ret = snprintf(buf, buflen, "%s/%s", sysfs_path, attr);
+	if (ret >= buflen)
+		return -1;
+
+	return 0;
+}
+
 int f2fs_get_zoned_model(int i)
 {
 	struct device_info *dev = c.devices + i;
-	char str[128];
+	char str[PATH_MAX];
 	FILE *file;
 	int res;
 
 	/* Check that this is a zoned block device */
-	snprintf(str, sizeof(str),
-		 "/sys/block/%s/queue/zoned",
-		 basename(dev->path));
+	res = get_sysfs_path(dev, "queue/zoned", str, sizeof(str));
+	if (res != 0) {
+		MSG(0, "\tError: Failed to get device sysfs path\n");
+		return -1;
+	}
+
 	file = fopen(str, "r");
 	if (!file) {
 		/*
 		 * The kernel does not support zoned block devices, but we have
-		 * a block device file. This means that the device is not zoned
-		 * or is zoned but can be randomly written (i.e. host-aware
-		 * zoned model). Treat the device as a regular block device.
+		 * a block device file. This means that if the zoned file is
+		 * not found, then the device is not zoned or is zoned but can
+		 * be randomly written (i.e. host-aware zoned model).
+		 * Treat the device as a regular block device. Otherwise, signal
+		 * the failure to verify the disk zone model.
 		 */
-		dev->zoned_model = F2FS_ZONED_NONE;
-		return 0;
+		if (errno == ENOENT) {
+			dev->zoned_model = F2FS_ZONED_NONE;
+			return 0;
+		}
+		MSG(0, "\tError: Failed to check the device zoned model\n");
+		return -1;
 	}
 
 	memset(str, 0, sizeof(str));
@@ -77,16 +149,19 @@ int f2fs_get_zone_blocks(int i)
 {
 	struct device_info *dev = c.devices + i;
 	uint64_t sectors;
-	char str[128];
+	char str[PATH_MAX];
 	FILE *file;
 	int res;
 
 	/* Get zone size */
 	dev->zone_blocks = 0;
 
-	snprintf(str, sizeof(str),
-		 "/sys/block/%s/queue/chunk_sectors",
-		 basename(dev->path));
+	res = get_sysfs_path(dev, "queue/chunk_sectors", str, sizeof(str));
+	if (res != 0) {
+		MSG(0, "\tError: Failed to get device sysfs attribute path\n");
+		return -1;
+	}
+
 	file = fopen(str, "r");
 	if (!file)
 		return -1;
-- 
2.20.1

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

* Re: [PATCH v3] f2fs-tools: Fix device zoned model detection
  2019-04-22  2:04 [PATCH v3] f2fs-tools: Fix device zoned model detection Shin'ichiro Kawasaki
@ 2019-04-22  2:41 ` Chao Yu
  0 siblings, 0 replies; 2+ messages in thread
From: Chao Yu @ 2019-04-22  2:41 UTC (permalink / raw)
  To: Shin'ichiro Kawasaki, Jaegeuk Kim, linux-f2fs-devel; +Cc: Damien Le Moal

On 2019/4/22 10:04, Shin'ichiro Kawasaki wrote:
> A partition device does not have the "zoned" nor "chunk_sectors" sysfs
> attribute files. Only the owner block device of the partition has these
> files. This causes the detection of the zoned model and zone size of a
> partition device to fail when executing mkfs.f2fs.
> 
> Fix this problem by using the owner device sysfs directory as the base
> directory for accessing the zoned and chunk_sectors files. This is done
> by using the device major:minor symbolic link under the /sys/dev/block
> directory, reading this link and removing the partition device name from
> the link path for a partition device (which is indicated by the presence
> of the "partition" file under the directory).
> 
> Also add a check for the ENOENT error when opening the device "zoned"
> sysfs attribute file. The absence of this file indicates that the
> kernel does not support zoned block devices. Since the device file is
> already open, it exists, and so the device can safely be assumed as not
> being zoned.
> 
> Changes from v2:
> * Addressed Chao Yu's comment on snprintf buffer length
> 
> Changes from v1:
> * Addressed Chao Yu's comment on ENOENT and return value checks
> * Rewrite of sysfs file handling (simplified)
> * Rebased on dev-test tree
> 
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>

It looks good to me. :)

Reviewed-by: Chao Yu <yuchao0@huawei.com>

Thanks,

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

end of thread, other threads:[~2019-04-22  2:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-22  2:04 [PATCH v3] f2fs-tools: Fix device zoned model detection Shin'ichiro Kawasaki
2019-04-22  2:41 ` Chao Yu

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.