All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically
@ 2020-06-09  8:33 Yang Xu
  2020-06-09  9:24 ` Jan Stancek
  0 siblings, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-09  8:33 UTC (permalink / raw)
  To: ltp

In loop driver code, the sb_bsize was calculated as below
sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev),

it is the super block's block size that the backing file's inode belongs to,
not by using the st_blksize member of stat struct(it uses inode->i_blkbits).

IMO, we don't have the direct ioctl to get this size, just try it from 512 to page_size.

Also, "offset is ignored" belongs to the last test(less than logical_block_size) but not
the second test(equal to logical_block_size).

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../kernel/syscalls/ioctl/ioctl_loop05.c      | 21 ++++++++-----------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
index a96997823..09326042f 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
@@ -71,7 +71,7 @@ static void verify_ioctl_loop(void)
 	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0);
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
 		check_dio_value(1);
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 	} else {
@@ -84,7 +84,7 @@ static void verify_ioctl_loop(void)
 
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 		return;
 	}
@@ -96,8 +96,7 @@ static void verify_ioctl_loop(void)
 
 static void setup(void)
 {
-	int fd;
-	struct stat buf;
+	int pg_size = getpagesize();
 
 	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
 		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
@@ -109,13 +108,6 @@ static void setup(void)
 	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
 	tst_fill_file("test.img", 0, 1024, 1024);
 
-	fd = SAFE_OPEN("test.img", O_RDONLY);
-	SAFE_FSTAT(fd, &buf);
-	SAFE_CLOSE(fd);
-
-	logical_block_size = buf.st_blksize;
-	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
-
 	tst_attach_device(dev_path, "test.img");
 	attach_flag = 1;
 	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
@@ -130,7 +122,12 @@ static void setup(void)
 	 *   size of loop is bigger than the backing device's and the loop
 	 *   needn't transform transfer.
 	 */
-	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
+	for (logical_block_size = 512; logical_block_size < pg_size; logical_block_size += 512) {
+		TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
+		if (ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1) == 0)
+			break;
+	}
+	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
 }
 
 static void cleanup(void)
-- 
2.23.0




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

* [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically
  2020-06-09  8:33 [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically Yang Xu
@ 2020-06-09  9:24 ` Jan Stancek
  2020-06-09  9:48   ` Yang Xu
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Stancek @ 2020-06-09  9:24 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> In loop driver code, the sb_bsize was calculated as below
> sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev),
> 
> it is the super block's block size that the backing file's inode belongs to,
> not by using the st_blksize member of stat struct(it uses inode->i_blkbits).

I'm not sure I follow the above, are you saying the difference is bdev blksize
vs. filesystem blksize? Is the test failing in some scenarios or is this
fix based on code inspection?

> 
> IMO, we don't have the direct ioctl to get this size, just try it from 512 to
> page_size.

Would BLKSSZGET work? It returns bdev_logical_block_size().


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

* [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically
  2020-06-09  9:24 ` Jan Stancek
@ 2020-06-09  9:48   ` Yang Xu
  2020-06-09 10:16     ` Jan Stancek
  0 siblings, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-09  9:48 UTC (permalink / raw)
  To: ltp

Hi Jan

>
> ----- Original Message -----
>> In loop driver code, the sb_bsize was calculated as below
>> sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev),
>>
>> it is the super block's block size that the backing file's inode belongs to,
>> not by using the st_blksize member of stat struct(it uses inode->i_blkbits).
> I'm not sure I follow the above, are you saying the difference is bdev blksize
> vs. filesystem blksize?

I said the loop driver used  dev_logical_block_size(inode->i_sb->s_bdev) but not using
st_blksize. I don't see they have conversion formula so using st_blksize maybe wrong.

>   Is the test failing in some scenarios or is this
> fix based on code inspection?

It affects the result of? ("With nonzero offset less than logical_block_size").
When we can get sb_bdev on other machine(not s390), it should report EINVAL error.

But if we use stat.st_blksize, it passed.

not using st_blksize? result as below:
ioctl_loop05.c:81: INFO: With nonzero offset less than logical_block_size
ioctl_loop05.c:92: PASS: LOOP_SET_DIRECT_IO failed as expected: EINVAL (22)

using st_blksize? result as below:
ioctl_loop05.c:81: INFO: With nonzero offset less than logical_block_size
ioctl_loop05.c:87: PASS: LOOP_SET_DIRECT_IO succeeded


>
>> IMO, we don't have the direct ioctl to get this size, just try it from 512 to
>> page_size.
> Would BLKSSZGET work? It returns bdev_logical_block_size().

But it needs a blockdev, in user space, we can specify bdev, but how can we figure out this inode->i_sb->s_bdev block dev.

>
>
>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20200609/970d8e37/attachment.htm>

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

* [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically
  2020-06-09  9:48   ` Yang Xu
@ 2020-06-09 10:16     ` Jan Stancek
  2020-06-09 10:46       ` Yang Xu
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Stancek @ 2020-06-09 10:16 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> Hi Jan
> 
> >
> > ----- Original Message -----
> >> In loop driver code, the sb_bsize was calculated as below
> >> sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev),
> >>
> >> it is the super block's block size that the backing file's inode belongs
> >> to,
> >> not by using the st_blksize member of stat struct(it uses
> >> inode->i_blkbits).
> > I'm not sure I follow the above, are you saying the difference is bdev
> > blksize
> > vs. filesystem blksize?
> 
> I said the loop driver used  dev_logical_block_size(inode->i_sb->s_bdev) but
> not using
> st_blksize.

I know, but I'm trying to understand what the difference is between those two.

> > Would BLKSSZGET work? It returns bdev_logical_block_size().
> 
> But it needs a blockdev, in user space, we can specify bdev, but how can we
> figure out this inode->i_sb->s_bdev block dev.

Isn't that the block device "test.img" is on?


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

* [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically
  2020-06-09 10:16     ` Jan Stancek
@ 2020-06-09 10:46       ` Yang Xu
  2020-06-09 11:01         ` Jan Stancek
  0 siblings, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-09 10:46 UTC (permalink / raw)
  To: ltp

Hi Jan

> 
> 
> ----- Original Message -----
>> Hi Jan
>>
>>>
>>> ----- Original Message -----
>>>> In loop driver code, the sb_bsize was calculated as below
>>>> sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev),
>>>>
>>>> it is the super block's block size that the backing file's inode belongs
>>>> to,
>>>> not by using the st_blksize member of stat struct(it uses
>>>> inode->i_blkbits).
>>> I'm not sure I follow the above, are you saying the difference is bdev
>>> blksize
>>> vs. filesystem blksize?
>>
>> I said the loop driver used  dev_logical_block_size(inode->i_sb->s_bdev) but
>> not using
>> st_blksize.
> 
> I know, but I'm trying to understand what the difference is between those two.
AFAIK, st_blksize is used to standard io in user space as man-page said 
"/* Block size for filesystem I/O */", it maybe a buffer write used. It 
is a  block size that block in inode used.
But dev_logical_block_size is a min unit thatrequest queue used on block 
layer.

ps? this is my understanding. If it's wrong, please correct me.
> 
>>> Would BLKSSZGET work? It returns bdev_logical_block_size().
>>
>> But it needs a blockdev, in user space, we can specify bdev, but how can we
>> figure out this inode->i_sb->s_bdev block dev.
> 
> Isn't that the block device "test.img" is on?
Do you mean the test.img belong to some block dev, such as /dev/sda1 or 
our mounted block_dev? If so, I think it is.
> 
> 
> 



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

* [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically
  2020-06-09 10:46       ` Yang Xu
@ 2020-06-09 11:01         ` Jan Stancek
  2020-06-10  1:19           ` Yang Xu
  2020-06-10  5:37           ` [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
  0 siblings, 2 replies; 30+ messages in thread
From: Jan Stancek @ 2020-06-09 11:01 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> >>> Would BLKSSZGET work? It returns bdev_logical_block_size().
> >>
> >> But it needs a blockdev, in user space, we can specify bdev, but how can
> >> we
> >> figure out this inode->i_sb->s_bdev block dev.
> > 
> > Isn't that the block device "test.img" is on?
> Do you mean the test.img belong to some block dev, such as /dev/sda1 or
> our mounted block_dev? If so, I think it is.

The former. Say if test.img is in /tmp, then I'd assume "s_bdev" is
/dev/mapper/rhel-root (/dev/dm-0)

$ df -T /tmp/test.img
Filesystem            Type 1K-blocks     Used Available Use% Mounted on
/dev/mapper/rhel-root xfs   66789516 33211340  33578176  50% /


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

* [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically
  2020-06-09 11:01         ` Jan Stancek
@ 2020-06-10  1:19           ` Yang Xu
  2020-06-10  5:37           ` [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
  1 sibling, 0 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-10  1:19 UTC (permalink / raw)
  To: ltp

Hi Jan


> 
> 
> ----- Original Message -----
>>>>> Would BLKSSZGET work? It returns bdev_logical_block_size().
>>>>
>>>> But it needs a blockdev, in user space, we can specify bdev, but how can
>>>> we
>>>> figure out this inode->i_sb->s_bdev block dev.
>>>
>>> Isn't that the block device "test.img" is on?
>> Do you mean the test.img belong to some block dev, such as /dev/sda1 or
>> our mounted block_dev? If so, I think it is.
> 
> The former. Say if test.img is in /tmp, then I'd assume "s_bdev" is
> /dev/mapper/rhel-root (/dev/dm-0)
> 
> $ df -T /tmp/test.img
> Filesystem            Type 1K-blocks     Used Available Use% Mounted on
> /dev/mapper/rhel-root xfs   66789516 33211340  33578176  50% /
I try this, it is ok on my machine. I will send a v2 patch by using 
BLKSSZGET.
> 
> 
> 



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

* [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-09 11:01         ` Jan Stancek
  2020-06-10  1:19           ` Yang Xu
@ 2020-06-10  5:37           ` Yang Xu
  2020-06-10 10:13             ` Jan Stancek
  1 sibling, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-10  5:37 UTC (permalink / raw)
  To: ltp

At the first, we use BLKSSZGET ioctl to get this size, but using wrong
block dev(/dev/loopN) intead of correct backing file block dev(such as /dev/sdaN).

kernel code(driver/block/loop.c  __loop_update_dio function) as below:
---------------------------------------
if (inode->i_sb->s_bdev) {
	sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
	dio_align = sb_bsize - 1;
}
if (dio) {
	if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
		!(lo->lo_offset & dio_align) &&
		mapping->a_ops->direct_IO &&!lo->transfer)
		use_dio = true;
	else
		use_dio = false;
} else {
        use_dio = false;
}
---------------------------------------

Using inode block is wrong because it is for filesystem io(such as we formart
filesystem can specify block size for data or log or metadata), it is not suitable
for logical block size.

Using df cmd (df -T /tmp/xxxxx/test.img)to get the correct block dev.

Also, "offset is ignored" belongs to the last test(less than logical_block_size) but not
the second test(equal to logical_block_size).

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../kernel/syscalls/ioctl/ioctl_loop05.c      | 47 ++++++++++++++-----
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
index a96997823..643892fff 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
@@ -28,12 +28,13 @@
 #include <sys/mount.h>
 #include "lapi/loop.h"
 #include "tst_test.h"
+#include "tst_safe_stdio.h"
 
 #define DIO_MESSAGE "In dio mode"
 #define NON_DIO_MESSAGE "In non dio mode"
 
 static char dev_path[1024], sys_loop_diopath[1024];
-static int dev_num, dev_fd, attach_flag, logical_block_size;
+static int dev_num, dev_fd, block_devfd, attach_flag, logical_block_size;
 
 static void check_dio_value(int flag)
 {
@@ -71,7 +72,7 @@ static void verify_ioctl_loop(void)
 	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0);
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
 		check_dio_value(1);
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 	} else {
@@ -84,7 +85,7 @@ static void verify_ioctl_loop(void)
 
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 		return;
 	}
@@ -94,10 +95,22 @@ static void verify_ioctl_loop(void)
 		tst_res(TFAIL | TTERRNO, "LOOP_SET_DIRECT_IO failed expected EINVAL got");
 }
 
+static void find_backing_bdpath(char *buf)
+{
+	char line[PATH_MAX];
+	FILE *file;
+
+	file = SAFE_FOPEN("1.txt", "r");
+
+	while (fgets(line, sizeof(line), file) != NULL)
+		sscanf(line, "%s", buf);
+	SAFE_FCLOSE(file);
+}
+
 static void setup(void)
 {
-	int fd;
-	struct stat buf;
+	char buf[100];
+	const char *const df_cmd[] = {"df", "-T", ".", NULL};
 
 	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
 		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
@@ -109,13 +122,6 @@ static void setup(void)
 	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
 	tst_fill_file("test.img", 0, 1024, 1024);
 
-	fd = SAFE_OPEN("test.img", O_RDONLY);
-	SAFE_FSTAT(fd, &buf);
-	SAFE_CLOSE(fd);
-
-	logical_block_size = buf.st_blksize;
-	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
-
 	tst_attach_device(dev_path, "test.img");
 	attach_flag = 1;
 	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
@@ -130,13 +136,24 @@ static void setup(void)
 	 *   size of loop is bigger than the backing device's and the loop
 	 *   needn't transform transfer.
 	 */
-	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
+	SAFE_CMD(df_cmd, "1.txt", NULL);
+	find_backing_bdpath(buf);
+	block_devfd = SAFE_OPEN(buf, O_RDWR);
+
+	SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size);
+	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
+	SAFE_CLOSE(block_devfd);
+
+	if (logical_block_size > 512)
+		TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
 }
 
 static void cleanup(void)
 {
 	if (dev_fd > 0)
 		SAFE_CLOSE(dev_fd);
+	if (block_devfd > 0)
+		SAFE_CLOSE(block_devfd);
 	if (attach_flag)
 		tst_detach_device(dev_path);
 }
@@ -150,5 +167,9 @@ static struct tst_test test = {
 	.needs_drivers = (const char *const []) {
 		"loop",
 		NULL
+	},
+	.needs_cmds = (const char *const []) {
+		"df",
+		NULL
 	}
 };
-- 
2.23.0




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

* [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-10  5:37           ` [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
@ 2020-06-10 10:13             ` Jan Stancek
  2020-06-10 10:42               ` Yang Xu
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Stancek @ 2020-06-10 10:13 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> 
> Using df cmd (df -T /tmp/xxxxx/test.img)to get the correct block dev.

What I had in mind was to take "df -T" as inspiration, not call it directly,
but that could work too. See notes below.

> +static void find_backing_bdpath(char *buf)
> +{
> +	char line[PATH_MAX];
> +	FILE *file;
> +
> +	file = SAFE_FOPEN("1.txt", "r");
> +
> +	while (fgets(line, sizeof(line), file) != NULL)
> +		sscanf(line, "%s", buf);

This will take the last line of output, which can be a problem as some
version align output differently. For example:

# df -T .
Filesystem           Type 1K-blocks    Used Available Use% Mounted on
/dev/mapper/vg_dhcp13579-lv_root
                     ext4  46967160 3102232  41472456   7% /

can break output into two lines.

> +	SAFE_FCLOSE(file);
> +}
> +
>  static void setup(void)
>  {
> -	int fd;
> -	struct stat buf;
> +	char buf[100];
> +	const char *const df_cmd[] = {"df", "-T", ".", NULL};
>  
>  	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
>  		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
> @@ -109,13 +122,6 @@ static void setup(void)
>  	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
>  	tst_fill_file("test.img", 0, 1024, 1024);
>  
> -	fd = SAFE_OPEN("test.img", O_RDONLY);
> -	SAFE_FSTAT(fd, &buf);
> -	SAFE_CLOSE(fd);
> -
> -	logical_block_size = buf.st_blksize;
> -	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
> -
>  	tst_attach_device(dev_path, "test.img");
>  	attach_flag = 1;
>  	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
> @@ -130,13 +136,24 @@ static void setup(void)
>  	 *   size of loop is bigger than the backing device's and the loop
>  	 *   needn't transform transfer.
>  	 */
> -	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size),
> TST_RETVAL_EQ0);
> +	SAFE_CMD(df_cmd, "1.txt", NULL);

This could be part of find_backing_bdpath() function.

What I had in mind when I referred to df was something like:
  stat("test.img", &statbuf);
  SAFE_MKNOD("blkdev", S_IFBLK | S_IRWXU, statbuf.st_dev);
  block_devfd = SAFE_OPEN("blkdev", O_RDWR);
What do you think?


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

* [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-10 10:13             ` Jan Stancek
@ 2020-06-10 10:42               ` Yang Xu
  2020-06-10 12:19                 ` Yang Xu
  0 siblings, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-10 10:42 UTC (permalink / raw)
  To: ltp

Hi Jan


> 
> 
> ----- Original Message -----
>>
>> Using df cmd (df -T /tmp/xxxxx/test.img)to get the correct block dev.
> 
> What I had in mind was to take "df -T" as inspiration, not call it directly,
> but that could work too. See notes below.
> 
>> +static void find_backing_bdpath(char *buf)
>> +{
>> +	char line[PATH_MAX];
>> +	FILE *file;
>> +
>> +	file = SAFE_FOPEN("1.txt", "r");
>> +
>> +	while (fgets(line, sizeof(line), file) != NULL)
>> +		sscanf(line, "%s", buf);
> 
> This will take the last line of output, which can be a problem as some
> version align output differently. For example:
> 
> # df -T .
> Filesystem           Type 1K-blocks    Used Available Use% Mounted on
> /dev/mapper/vg_dhcp13579-lv_root
>                       ext4  46967160 3102232  41472456   7% /
> 
> can break output into two lines.
Yes.
> 
>> +	SAFE_FCLOSE(file);
>> +}
>> +
>>   static void setup(void)
>>   {
>> -	int fd;
>> -	struct stat buf;
>> +	char buf[100];
>> +	const char *const df_cmd[] = {"df", "-T", ".", NULL};
>>   
>>   	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
>>   		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
>> @@ -109,13 +122,6 @@ static void setup(void)
>>   	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
>>   	tst_fill_file("test.img", 0, 1024, 1024);
>>   
>> -	fd = SAFE_OPEN("test.img", O_RDONLY);
>> -	SAFE_FSTAT(fd, &buf);
>> -	SAFE_CLOSE(fd);
>> -
>> -	logical_block_size = buf.st_blksize;
>> -	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
>> -
>>   	tst_attach_device(dev_path, "test.img");
>>   	attach_flag = 1;
>>   	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
>> @@ -130,13 +136,24 @@ static void setup(void)
>>   	 *   size of loop is bigger than the backing device's and the loop
>>   	 *   needn't transform transfer.
>>   	 */
>> -	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size),
>> TST_RETVAL_EQ0);
>> +	SAFE_CMD(df_cmd, "1.txt", NULL);
> 
> This could be part of find_backing_bdpath() function.
Yes.
> 
> What I had in mind when I referred to df was something like:
>    stat("test.img", &statbuf);
>    SAFE_MKNOD("blkdev", S_IFBLK | S_IRWXU, statbuf.st_dev);
>    block_devfd = SAFE_OPEN("blkdev", O_RDWR);
> What do you think?
> 
Oh, yes, it is more easier (I have tried this). I will send a v3 for this.

ps: I think I can use this in my other loop patches for loop_configure 
ioctl.
> 
> 



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

* [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-10 10:42               ` Yang Xu
@ 2020-06-10 12:19                 ` Yang Xu
  2020-06-10 13:04                   ` Jan Stancek
  0 siblings, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-10 12:19 UTC (permalink / raw)
  To: ltp

Hi Jan


> Hi Jan
> 
> 
>>
>>
>> ----- Original Message -----
>>>
>>> Using df cmd (df -T /tmp/xxxxx/test.img)to get the correct block dev.
>>
>> What I had in mind was to take "df -T" as inspiration, not call it 
>> directly,
>> but that could work too. See notes below.
>>
>>> +static void find_backing_bdpath(char *buf)
>>> +{
>>> +??? char line[PATH_MAX];
>>> +??? FILE *file;
>>> +
>>> +??? file = SAFE_FOPEN("1.txt", "r");
>>> +
>>> +??? while (fgets(line, sizeof(line), file) != NULL)
>>> +??????? sscanf(line, "%s", buf);
>>
>> This will take the last line of output, which can be a problem as some
>> version align output differently. For example:
>>
>> # df -T .
>> Filesystem?????????? Type 1K-blocks??? Used Available Use% Mounted on
>> /dev/mapper/vg_dhcp13579-lv_root
>> ????????????????????? ext4? 46967160 3102232? 41472456?? 7% /
>>
>> can break output into two lines.
> Yes.
>>
>>> +??? SAFE_FCLOSE(file);
>>> +}
>>> +
>>> ? static void setup(void)
>>> ? {
>>> -??? int fd;
>>> -??? struct stat buf;
>>> +??? char buf[100];
>>> +??? const char *const df_cmd[] = {"df", "-T", ".", NULL};
>>> ????? if (tst_fs_type(".") == TST_TMPFS_MAGIC)
>>> ????????? tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
>>> @@ -109,13 +122,6 @@ static void setup(void)
>>> ????? sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
>>> ????? tst_fill_file("test.img", 0, 1024, 1024);
>>> -??? fd = SAFE_OPEN("test.img", O_RDONLY);
>>> -??? SAFE_FSTAT(fd, &buf);
>>> -??? SAFE_CLOSE(fd);
>>> -
>>> -??? logical_block_size = buf.st_blksize;
>>> -??? tst_res(TINFO, "backing dev logical_block_size is %d", 
>>> logical_block_size);
>>> -
>>> ????? tst_attach_device(dev_path, "test.img");
>>> ????? attach_flag = 1;
>>> ????? dev_fd = SAFE_OPEN(dev_path, O_RDWR);
>>> @@ -130,13 +136,24 @@ static void setup(void)
>>> ?????? *?? size of loop is bigger than the backing device's and the loop
>>> ?????? *?? needn't transform transfer.
>>> ?????? */
>>> -??? TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, 
>>> logical_block_size),
>>> TST_RETVAL_EQ0);
>>> +??? SAFE_CMD(df_cmd, "1.txt", NULL);
>>
>> This could be part of find_backing_bdpath() function.
> Yes.
>>
>> What I had in mind when I referred to df was something like:
>> ?? stat("test.img", &statbuf);
>> ?? SAFE_MKNOD("blkdev", S_IFBLK | S_IRWXU, statbuf.st_dev);
>> ?? block_devfd = SAFE_OPEN("blkdev", O_RDWR);
>> What do you think?
>>
It works well on ext4 or xfs filesystem(user may mount wanted filesystem 
on tmpdir). But if we use btrfs, this
BLKSSZGET will fail because major dev numer is 0. When we meet this 
situation, we don't need to call this ioctl and we can directly test 
becuase it doesn' t have backing file block device align limit.
What do you thin about it?



> Oh, yes, it is more easier (I have tried this). I will send a v3 for this.
> 
> ps: I think I can use this in my other loop patches for loop_configure 
> ioctl.
>>
>>
> 
> 
> 



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

* [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-10 12:19                 ` Yang Xu
@ 2020-06-10 13:04                   ` Jan Stancek
  2020-06-11  4:56                     ` Yang Xu
  2020-06-11  5:32                     ` [LTP] [PATCH v3] " Yang Xu
  0 siblings, 2 replies; 30+ messages in thread
From: Jan Stancek @ 2020-06-10 13:04 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> >>
> >> What I had in mind when I referred to df was something like:
> >> ?? stat("test.img", &statbuf);
> >> ?? SAFE_MKNOD("blkdev", S_IFBLK | S_IRWXU, statbuf.st_dev);
> >> ?? block_devfd = SAFE_OPEN("blkdev", O_RDWR);
> >> What do you think?
> >>
> It works well on ext4 or xfs filesystem(user may mount wanted filesystem
> on tmpdir). But if we use btrfs, this
> BLKSSZGET will fail because major dev numer is 0. When we meet this
> situation, we don't need to call this ioctl and we can directly test
> becuase it doesn' t have backing file block device align limit.
> What do you thin about it?

This I didn't expect. If it's not reliable then perhaps your method
in v1 that incrementally increases it until it works is perhaps most
universal approach. Sorry for the detour to get there.


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

* [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-10 13:04                   ` Jan Stancek
@ 2020-06-11  4:56                     ` Yang Xu
  2020-06-11  5:32                     ` [LTP] [PATCH v3] " Yang Xu
  1 sibling, 0 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-11  4:56 UTC (permalink / raw)
  To: ltp

Hi Jan


> 
> 
> ----- Original Message -----
>>>>
>>>> What I had in mind when I referred to df was something like:
>>>>  ?? stat("test.img", &statbuf);
>>>>  ?? SAFE_MKNOD("blkdev", S_IFBLK | S_IRWXU, statbuf.st_dev);
>>>>  ?? block_devfd = SAFE_OPEN("blkdev", O_RDWR);
>>>> What do you think?
>>>>
>> It works well on ext4 or xfs filesystem(user may mount wanted filesystem
>> on tmpdir). But if we use btrfs, this
>> BLKSSZGET will fail because major dev numer is 0. When we meet this
>> situation, we don't need to call this ioctl and we can directly test
>> becuase it doesn' t have backing file block device align limit.
>> What do you thin about it?
> 
> This I didn't expect. If it's not reliable then perhaps your method
> in v1 that incrementally increases it until it works is perhaps most
> universal approach. Sorry for the detour to get there.
> 
After I trace the stat syscall, btrfs uses virtual block dev, so major 
dev number is 0 since kernel commit[1].

Originally, I want to use that major dev number is 0 to judge whether 
loop driver has align limit on some fileystems. But it sees that they 
don't have direct connection between inode->i_sb->s_bdev (loop used)and 
inode->st_dev(stat used). So using the major dev number to judge whether 
loop driver code has align limits sounds unreasonable.

To aovid this, I will use v1 method with some improvement.


[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/btrfs/inode.c?id=3394e1607eaf870ebba37d303fbd590a4c569908 

> 
> 



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

* [LTP] [PATCH v3] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-10 13:04                   ` Jan Stancek
  2020-06-11  4:56                     ` Yang Xu
@ 2020-06-11  5:32                     ` Yang Xu
  2020-06-11 11:09                       ` Jan Stancek
  2020-06-24 11:32                       ` Cyril Hrubis
  1 sibling, 2 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-11  5:32 UTC (permalink / raw)
  To: ltp

At the first, we use BLKSSZGET ioctl to get this size, but using wrong
block dev(/dev/loopN) intead of correct backing file block dev(such as /dev/sdaN).

kernel code(driver/block/loop.c  __loop_update_dio function) as below:
---------------------------------------
if (inode->i_sb->s_bdev) {
	sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
	dio_align = sb_bsize - 1;
}
if (dio) {
	if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
		!(lo->lo_offset & dio_align) &&
		mapping->a_ops->direct_IO &&!lo->transfer)
		use_dio = true;
	else
		use_dio = false;
} else {
        use_dio = false;
}
-------------------------------------

Using inode block size is also wrong because it is for filesystem io(such as we format
filesystem can specify block size for data or log or metadata), it is not suitable
for logical block size.

Using df cmd (df -T /tmp/xxxxx/test.img)to get the correct block dev.

Also, "offset is ignored" belongs to the third test(less than logical_block_size) but not
the second test(equal to logical_block_size).

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
v2-v3:
1. move SAFE_CMD into find_backing_bdpath function
2. change parsing strategy, comparing with "/dev/" string
 .../kernel/syscalls/ioctl/ioctl_loop05.c      | 50 ++++++++++++++-----
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
index a96997823..0e29b484c 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
@@ -28,12 +28,13 @@
 #include <sys/mount.h>
 #include "lapi/loop.h"
 #include "tst_test.h"
+#include "tst_safe_stdio.h"
 
 #define DIO_MESSAGE "In dio mode"
 #define NON_DIO_MESSAGE "In non dio mode"
 
 static char dev_path[1024], sys_loop_diopath[1024];
-static int dev_num, dev_fd, attach_flag, logical_block_size;
+static int dev_num, dev_fd, block_devfd, attach_flag, logical_block_size;
 
 static void check_dio_value(int flag)
 {
@@ -71,7 +72,7 @@ static void verify_ioctl_loop(void)
 	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0);
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
 		check_dio_value(1);
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 	} else {
@@ -84,7 +85,7 @@ static void verify_ioctl_loop(void)
 
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 		return;
 	}
@@ -94,10 +95,26 @@ static void verify_ioctl_loop(void)
 		tst_res(TFAIL | TTERRNO, "LOOP_SET_DIRECT_IO failed expected EINVAL got");
 }
 
+static void find_backing_bdpath(char *buf)
+{
+	const char *const df_cmd[] = {"df", "-T", ".", NULL};
+	char line[PATH_MAX];
+	FILE *file;
+
+	SAFE_CMD(df_cmd, "1.txt", NULL);
+	file = SAFE_FOPEN("1.txt", "r");
+
+	while (fgets(line, sizeof(line), file) != NULL) {
+		sscanf(line, "%s", buf);
+		if (strstr(buf, "/dev/") != NULL)
+			break;
+	}
+	SAFE_FCLOSE(file);
+}
+
 static void setup(void)
 {
-	int fd;
-	struct stat buf;
+	char buf[100];
 
 	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
 		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
@@ -109,13 +126,6 @@ static void setup(void)
 	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
 	tst_fill_file("test.img", 0, 1024, 1024);
 
-	fd = SAFE_OPEN("test.img", O_RDONLY);
-	SAFE_FSTAT(fd, &buf);
-	SAFE_CLOSE(fd);
-
-	logical_block_size = buf.st_blksize;
-	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
-
 	tst_attach_device(dev_path, "test.img");
 	attach_flag = 1;
 	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
@@ -130,13 +140,23 @@ static void setup(void)
 	 *   size of loop is bigger than the backing device's and the loop
 	 *   needn't transform transfer.
 	 */
-	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
+	find_backing_bdpath(buf);
+	block_devfd = SAFE_OPEN(buf, O_RDWR);
+
+	SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size);
+	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
+	SAFE_CLOSE(block_devfd);
+
+	if (logical_block_size > 512)
+		TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
 }
 
 static void cleanup(void)
 {
 	if (dev_fd > 0)
 		SAFE_CLOSE(dev_fd);
+	if (block_devfd > 0)
+		SAFE_CLOSE(block_devfd);
 	if (attach_flag)
 		tst_detach_device(dev_path);
 }
@@ -150,5 +170,9 @@ static struct tst_test test = {
 	.needs_drivers = (const char *const []) {
 		"loop",
 		NULL
+	},
+	.needs_cmds = (const char *const []) {
+		"df",
+		NULL
 	}
 };
-- 
2.23.0




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

* [LTP] [PATCH v3] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-11  5:32                     ` [LTP] [PATCH v3] " Yang Xu
@ 2020-06-11 11:09                       ` Jan Stancek
  2020-06-12  2:57                         ` Yang Xu
  2020-06-24 11:32                       ` Cyril Hrubis
  1 sibling, 1 reply; 30+ messages in thread
From: Jan Stancek @ 2020-06-11 11:09 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> Using inode block size is also wrong because it is for filesystem io(such as
> we format
> filesystem can specify block size for data or log or metadata), it is not
> suitable
> for logical block size.

If this copes correctly with btrfs too, I don't have objections.
I retested on failing s390 setup and v3 works there OK.


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

* [LTP] [PATCH v3] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-11 11:09                       ` Jan Stancek
@ 2020-06-12  2:57                         ` Yang Xu
  2020-06-24  5:07                           ` Yang Xu
  0 siblings, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-12  2:57 UTC (permalink / raw)
  To: ltp

Hi Jan

> 
> 
> ----- Original Message -----
>> Using inode block size is also wrong because it is for filesystem io(such as
>> we format
>> filesystem can specify block size for data or log or metadata), it is not
>> suitable
>> for logical block size.
> 
> If this copes correctly with btrfs too, I don't have objections.
For btrfs, I think it is also right.
> I retested on failing s390 setup and v3 works there OK.
Thanks for your retest.

Best Regards
Yang Xu
> 
> 
> 



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

* [LTP] [PATCH v3] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-12  2:57                         ` Yang Xu
@ 2020-06-24  5:07                           ` Yang Xu
  0 siblings, 0 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-24  5:07 UTC (permalink / raw)
  To: ltp

Hi
Does anyone have comment on this patch?

Best Regards
Yang Xu

> Hi Jan
> 
>>
>>
>> ----- Original Message -----
>>> Using inode block size is also wrong because it is for filesystem 
>>> io(such as
>>> we format
>>> filesystem can specify block size for data or log or metadata), it is 
>>> not
>>> suitable
>>> for logical block size.
>>
>> If this copes correctly with btrfs too, I don't have objections.
> For btrfs, I think it is also right.
>> I retested on failing s390 setup and v3 works there OK.
> Thanks for your retest.
> 
> Best Regards
> Yang Xu
>>
>>
>>



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

* [LTP] [PATCH v3] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-11  5:32                     ` [LTP] [PATCH v3] " Yang Xu
  2020-06-11 11:09                       ` Jan Stancek
@ 2020-06-24 11:32                       ` Cyril Hrubis
  2020-06-24 13:06                         ` Jan Stancek
                                           ` (2 more replies)
  1 sibling, 3 replies; 30+ messages in thread
From: Cyril Hrubis @ 2020-06-24 11:32 UTC (permalink / raw)
  To: ltp

Hi!
> +static void find_backing_bdpath(char *buf)
> +{
> +	const char *const df_cmd[] = {"df", "-T", ".", NULL};
> +	char line[PATH_MAX];
> +	FILE *file;
> +
> +	SAFE_CMD(df_cmd, "1.txt", NULL);
> +	file = SAFE_FOPEN("1.txt", "r");
> +
> +	while (fgets(line, sizeof(line), file) != NULL) {
> +		sscanf(line, "%s", buf);
> +		if (strstr(buf, "/dev/") != NULL)
> +			break;
> +	}
> +	SAFE_FCLOSE(file);
> +}

I do not like that we are calling df for something like this.

Looking at what that command does it's not that complex. It does
statfs() to get minor and major number, then scans /proc/self/mountinfo
for these, since these are on third column and then just prints whatever
it's in the 10th column. This isn't more complex that what we have here
and avoids needs to execute binaries and parse the output.

Also this function could be in a test library probably in tst_device.h.

>  static void setup(void)
>  {
> -	int fd;
> -	struct stat buf;
> +	char buf[100];
>  
>  	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
>  		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
> @@ -109,13 +126,6 @@ static void setup(void)
>  	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
>  	tst_fill_file("test.img", 0, 1024, 1024);
>  
> -	fd = SAFE_OPEN("test.img", O_RDONLY);
> -	SAFE_FSTAT(fd, &buf);
> -	SAFE_CLOSE(fd);
> -
> -	logical_block_size = buf.st_blksize;
> -	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
> -
>  	tst_attach_device(dev_path, "test.img");
>  	attach_flag = 1;
>  	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
> @@ -130,13 +140,23 @@ static void setup(void)
>  	 *   size of loop is bigger than the backing device's and the loop
>  	 *   needn't transform transfer.
>  	 */
> -	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
> +	find_backing_bdpath(buf);
> +	block_devfd = SAFE_OPEN(buf, O_RDWR);
> +
> +	SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size);
> +	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
> +	SAFE_CLOSE(block_devfd);
> +
> +	if (logical_block_size > 512)
> +		TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
>  }
>  
>  static void cleanup(void)
>  {
>  	if (dev_fd > 0)
>  		SAFE_CLOSE(dev_fd);
> +	if (block_devfd > 0)
> +		SAFE_CLOSE(block_devfd);
>  	if (attach_flag)
>  		tst_detach_device(dev_path);
>  }
> @@ -150,5 +170,9 @@ static struct tst_test test = {
>  	.needs_drivers = (const char *const []) {
>  		"loop",
>  		NULL
> +	},
> +	.needs_cmds = (const char *const []) {
> +		"df",
> +		NULL
>  	}
>  };
> -- 
> 2.23.0
> 
> 
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-24 11:32                       ` Cyril Hrubis
@ 2020-06-24 13:06                         ` Jan Stancek
  2020-06-25 17:10                         ` Yang Xu
  2020-06-28  7:42                         ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Yang Xu
  2 siblings, 0 replies; 30+ messages in thread
From: Jan Stancek @ 2020-06-24 13:06 UTC (permalink / raw)
  To: ltp


----- Original Message -----
> Looking at what that command does it's not that complex. It does
> statfs() to get minor and major number, then scans /proc/self/mountinfo
> for these, since these are on third column and then just prints whatever
> it's in the 10th column. This isn't more complex that what we have here
> and avoids needs to execute binaries and parse the output.

Thanks for mountinfo pointer. We went down the stat() route already,
but hit issues with some filesystems. I tried it now with mountinfo
approach and that does seem to fix btrfs case too, so I agree that
parsing /proc/self/mountinfo rather than df output is nicer.


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

* [LTP] [PATCH v3] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-24 11:32                       ` Cyril Hrubis
  2020-06-24 13:06                         ` Jan Stancek
@ 2020-06-25 17:10                         ` Yang Xu
  2020-06-28  7:42                         ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Yang Xu
  2 siblings, 0 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-25 17:10 UTC (permalink / raw)
  To: ltp

Hi Cyril

Sorry for late reply.
> Hi!
>> +static void find_backing_bdpath(char *buf)
>> +{
>> +	const char *const df_cmd[] = {"df", "-T", ".", NULL};
>> +	char line[PATH_MAX];
>> +	FILE *file;
>> +
>> +	SAFE_CMD(df_cmd, "1.txt", NULL);
>> +	file = SAFE_FOPEN("1.txt", "r");
>> +
>> +	while (fgets(line, sizeof(line), file) != NULL) {
>> +		sscanf(line, "%s", buf);
>> +		if (strstr(buf, "/dev/") != NULL)
>> +			break;
>> +	}
>> +	SAFE_FCLOSE(file);
>> +}
> 
> I do not like that we are calling df for something like this.
> 
> Looking at what that command does it's not that complex. It does
> statfs() to get minor and major number, then scans /proc/self/mountinfo
> for these, since these are on third column and then just prints whatever
> it's in the 10th column. This isn't more complex that what we have here
> and avoids needs to execute binaries and parse the output.
> 
I look statfs manpage, its buf doesn't have  dev_t type member, I think 
it maybe stat function. But stat function has problem when filsystem 
uses virtual block(such as btrfs,fuse, then major numer is 0).
I try to parse /proc/self/mountinfo(this format is not changed over 
10years), as below:

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c 
b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
index a96997823..d6db9cc83 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
@@ -28,12 +28,13 @@
  #include <sys/mount.h>
  #include "lapi/loop.h"
  #include "tst_test.h"
+#include "tst_safe_stdio.h"

  #define DIO_MESSAGE "In dio mode"
  #define NON_DIO_MESSAGE "In non dio mode"

  static char dev_path[1024], sys_loop_diopath[1024];
-static int dev_num, dev_fd, attach_flag, logical_block_size;
+static int dev_num, dev_fd, block_devfd, attach_flag, logical_block_size;

  static void check_dio_value(int flag)
  {
@@ -94,11 +95,34 @@ static void verify_ioctl_loop(void)
                 tst_res(TFAIL | TTERRNO, "LOOP_SET_DIRECT_IO failed 
expected EINVAL got");
  }

-static void setup(void)
+static void find_backing_bdpath(char *buf, char *bd_path)
  {
-       int fd;
-       struct stat buf;
+       char fmt1[1024];
+       char fmt2[1024];
+       char mnt_root[100];
+       char line[PATH_MAX];
+       FILE *file;
+
+       sprintf(fmt1, "%%*i %%*i %%*u:%%*u %%*s %s %%*s %%*s %%*s %%*s 
%%s %%*s", buf);
+       sprintf(fmt2, "%%*i %%*i %%*u:%%*u %%*s %%s %%*s %%*s %%*s %%*s 
%%s %%*s");
+       if (!FILE_LINES_SCANF("/proc/self/mountinfo", fmt1, bd_path)) {
+               tst_res(TINFO, "have %s mntpoint", buf);
+               return;
+       }
+       tst_res(TINFO, "Not have %s mntpoint, try /", buf);
+       file = SAFE_FOPEN("/proc/self/mountinfo", "r");
+       while (fgets(line, sizeof(line), file) != NULL) {
+               sscanf(line, fmt2, mnt_root, bd_path);
+               if(strcmp(mnt_root, "/"))
+                       continue;
+               break;
+       }
+       SAFE_FCLOSE(file);
+}

+static void setup(void)
+{
+       char bd_path[100];
         if (tst_fs_type(".") == TST_TMPFS_MAGIC)
                 tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");

@@ -109,13 +133,6 @@ static void setup(void)
         sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
         tst_fill_file("test.img", 0, 1024, 1024);

-       fd = SAFE_OPEN("test.img", O_RDONLY);
-       SAFE_FSTAT(fd, &buf);
-       SAFE_CLOSE(fd);
-
-       logical_block_size = buf.st_blksize;
-       tst_res(TINFO, "backing dev logical_block_size is %d", 
logical_block_size);
-
         tst_attach_device(dev_path, "test.img");
         attach_flag = 1;
         dev_fd = SAFE_OPEN(dev_path, O_RDWR);
@@ -130,13 +147,21 @@ static void setup(void)
          *   size of loop is bigger than the backing device's and the loop
          *   needn't transform transfer.
          */
-       TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, 
logical_block_size), TST_RETVAL_EQ0);
+       find_backing_bdpath("/tmp", bd_path);
+       block_devfd = SAFE_OPEN(bd_path, O_RDWR);
+       SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size);
+       tst_res(TINFO, "backing dev logical_block_size is %d", 
logical_block_size);
+       SAFE_CLOSE(block_devfd);
+       if (logical_block_size > 512)
+               TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, 
logical_block_size), TST_RETVAL_EQ0);
  }

  static void cleanup(void)
  {
         if (dev_fd > 0)
                 SAFE_CLOSE(dev_fd);
+       if (block_devfd > 0)
+               SAFE_CLOSE(block_devfd);
         if (attach_flag)
                 tst_detach_device(dev_path);
  }
> Also this function could be in a test library probably in tst_device.h.
> 
>>   static void setup(void)
>>   {
>> -	int fd;
>> -	struct stat buf;
>> +	char buf[100];
>>   
>>   	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
>>   		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
>> @@ -109,13 +126,6 @@ static void setup(void)
>>   	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
>>   	tst_fill_file("test.img", 0, 1024, 1024);
>>   
>> -	fd = SAFE_OPEN("test.img", O_RDONLY);
>> -	SAFE_FSTAT(fd, &buf);
>> -	SAFE_CLOSE(fd);
>> -
>> -	logical_block_size = buf.st_blksize;
>> -	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
>> -
>>   	tst_attach_device(dev_path, "test.img");
>>   	attach_flag = 1;
>>   	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
>> @@ -130,13 +140,23 @@ static void setup(void)
>>   	 *   size of loop is bigger than the backing device's and the loop
>>   	 *   needn't transform transfer.
>>   	 */
>> -	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
>> +	find_backing_bdpath(buf);
>> +	block_devfd = SAFE_OPEN(buf, O_RDWR);
>> +
>> +	SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size);
>> +	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
>> +	SAFE_CLOSE(block_devfd);
>> +
>> +	if (logical_block_size > 512)
>> +		TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
>>   }
>>   
>>   static void cleanup(void)
>>   {
>>   	if (dev_fd > 0)
>>   		SAFE_CLOSE(dev_fd);
>> +	if (block_devfd > 0)
>> +		SAFE_CLOSE(block_devfd);
>>   	if (attach_flag)
>>   		tst_detach_device(dev_path);
>>   }
>> @@ -150,5 +170,9 @@ static struct tst_test test = {
>>   	.needs_drivers = (const char *const []) {
>>   		"loop",
>>   		NULL
>> +	},
>> +	.needs_cmds = (const char *const []) {
>> +		"df",
>> +		NULL
>>   	}
>>   };
>> -- 
>> 2.23.0
>>
>>
>>
>>
>> -- 
>> Mailing list info: https://lists.linux.it/listinfo/ltp
> 


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

* [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-06-24 11:32                       ` Cyril Hrubis
  2020-06-24 13:06                         ` Jan Stancek
  2020-06-25 17:10                         ` Yang Xu
@ 2020-06-28  7:42                         ` Yang Xu
  2020-06-28  7:42                           ` [LTP] [PATCH v4 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
  2020-06-29  7:56                           ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
  2 siblings, 2 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-28  7:42 UTC (permalink / raw)
  To: ltp

This api reads the /proc/self/mountinfo and compare path with
the 5th column each row in this file, assign the 10th column
value to dev when match succeed.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 doc/test-writing-guidelines.txt | 11 ++++++++
 include/tst_device.h            |  7 +++++
 lib/newlib_tests/tst_device.c   |  8 ++++++
 lib/tst_device.c                | 47 +++++++++++++++++++++++++++++++++
 4 files changed, 73 insertions(+)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index 6e466ed0f..1fe11abca 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1089,6 +1089,17 @@ FS deferred IO metadata/cache interference, we suggest doing "syncfs" before the
 tst_dev_bytes_written first invocation. And an inline function named tst_dev_sync
 is created for that intention.
 
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
+voud tst_find_backing_dev(const char *path, char *dev);
+-------------------------------------------------------------------------------
+
+This function finds the block dev that this path belongs to, it compares path buf
+with the fifth column of each row in "/proc/self/mountinfo" and list 10th column
+as its block dev.
+
 2.2.16 Formatting a device with a filesystem
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/include/tst_device.h b/include/tst_device.h
index 950cfe1ed..6a1fc5186 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -84,4 +84,11 @@ unsigned long tst_dev_bytes_written(const char *dev);
  */
 void tst_purge_dir(const char *path);
 
+/*
+ * Find the file or path belongs to which block dev
+ * @path  Path to find the backing dev
+ * @dev   The block dev
+ */
+void tst_find_backing_dev(const char *path, char *dev);
+
 #endif	/* TST_DEVICE_H__ */
diff --git a/lib/newlib_tests/tst_device.c b/lib/newlib_tests/tst_device.c
index 1344495b3..ad077affd 100644
--- a/lib/newlib_tests/tst_device.c
+++ b/lib/newlib_tests/tst_device.c
@@ -13,6 +13,7 @@ static void do_test(void)
 {
 	int fd;
 	const char *dev;
+	char block_dev[100];
 	uint64_t ltp_dev_size;
 
 	dev = tst_device->dev;
@@ -29,6 +30,13 @@ static void do_test(void)
 		tst_res(TPASS, "Got expected device size");
 	else
 		tst_res(TFAIL, "Got unexpected device size");
+
+	tst_find_backing_dev("/boot", block_dev);
+	tst_res(TPASS, "/boot belongs to %s block dev", block_dev);
+	tst_find_backing_dev("/", block_dev);
+	tst_res(TPASS, "/ belongs to %s block dev", block_dev);
+	tst_find_backing_dev("/tmp", block_dev);
+	tst_find_backing_dev("/boot/xuyang", block_dev);
 }
 
 static struct tst_test test = {
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 67fe90ed6..97b42eb4f 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -488,3 +488,50 @@ unsigned long tst_dev_bytes_written(const char *dev)
 
 	return dev_bytes_written;
 }
+
+void tst_find_backing_dev(const char *path, char *dev)
+{
+	char fmt[100];
+	char mnt_root[100];
+	char bd_device[100];
+	char line[1024];
+	FILE *file;
+	int flag = 0;
+	int ret;
+	int fd;
+	struct stat st;
+
+	if (access(path, F_OK))
+		tst_brkm(TCONF, NULL, "path(%s) doesn't exist", path);
+
+	sprintf(fmt, "%%*i %%*i %%*u:%%*u %%*s %%s %%*s %%*s %%*s %%*s %%s %%*s");
+	file = SAFE_FOPEN(NULL, "/proc/self/mountinfo", "r");
+	while (fgets(line, sizeof(line), file) != NULL) {
+		ret = sscanf(line, fmt, mnt_root, bd_device);
+		if (ret != 2)
+			 tst_brkm(TCONF, NULL, "paring /proc/self/mountfinfo file failed, expected 2, got %d", ret);
+		if (!strcmp(mnt_root, path)) {
+			strcpy(dev, bd_device);
+			flag = 1;
+			break;
+		}
+		if (!strncmp(mnt_root, path, strlen(mnt_root))) {
+			strcpy(dev, bd_device);
+			flag = 1;
+		}
+	}
+	SAFE_FCLOSE(NULL, file);
+	if (!flag || access(dev, F_OK))
+		tst_brkm(TCONF, NULL, "Can not find backing dev(%s)", path);
+
+	fd = open(dev, O_RDONLY);
+	if (fd < 0)
+		tst_brkm(TWARN | TERRNO, NULL, "open(%s, O_RDONLY) failed", dev);
+	if (stat(dev, &st) < 0) {
+		close(fd);
+		tst_brkm(TWARN | TERRNO, NULL, "stat() failed");
+	}
+	close(fd);
+	if (S_ISBLK(st.st_mode) != 1)
+		tst_brkm(TCONF, NULL, "dev(%s) isn't a block dev", dev);
+}
-- 
2.23.0




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

* [LTP] [PATCH v4 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-28  7:42                         ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Yang Xu
@ 2020-06-28  7:42                           ` Yang Xu
  2020-06-29  7:56                           ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
  1 sibling, 0 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-28  7:42 UTC (permalink / raw)
  To: ltp

At the first, we use BLKSSZGET ioctl to get this size, but using wrong
block dev(/dev/loopN) intead of correct backing file block dev(such as /dev/sdaN).

kernel code(driver/block/loop.c  __loop_update_dio function) as below:
---------------------------------------
if (inode->i_sb->s_bdev) {
	sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
	dio_align = sb_bsize - 1;
}
if (dio) {
	if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
		!(lo->lo_offset & dio_align) &&
		mapping->a_ops->direct_IO &&!lo->transfer)
		use_dio = true;
	else
		use_dio = false;
} else {
        use_dio = false;
}
-------------------------------------

Using inode block size is also wrong because it is for filesystem io(such as we format
filesystem can specify block size for data or log or metadata), it is not suitable
for logical block size.

Using tst_find_backing_dev(path, dev)to get the correct block dev.

Also, "offset is ignored" belongs to the third test(less than logical_block_size) but not
the second test(equal to logical_block_size)

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
v3->v4:
1. using tst_find_backing_dev instead of df command
2. also print block dev name
 .../kernel/syscalls/ioctl/ioctl_loop05.c      | 29 ++++++++++---------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
index a96997823..e3c14faab 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
@@ -32,8 +32,8 @@
 #define DIO_MESSAGE "In dio mode"
 #define NON_DIO_MESSAGE "In non dio mode"
 
-static char dev_path[1024], sys_loop_diopath[1024];
-static int dev_num, dev_fd, attach_flag, logical_block_size;
+static char dev_path[1024], sys_loop_diopath[1024], backing_file_path[1024];;
+static int dev_num, dev_fd, block_devfd, attach_flag, logical_block_size;
 
 static void check_dio_value(int flag)
 {
@@ -71,7 +71,7 @@ static void verify_ioctl_loop(void)
 	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0);
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
 		check_dio_value(1);
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 	} else {
@@ -84,7 +84,7 @@ static void verify_ioctl_loop(void)
 
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 		return;
 	}
@@ -96,8 +96,7 @@ static void verify_ioctl_loop(void)
 
 static void setup(void)
 {
-	int fd;
-	struct stat buf;
+	char bd_path[100];
 
 	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
 		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
@@ -109,13 +108,6 @@ static void setup(void)
 	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
 	tst_fill_file("test.img", 0, 1024, 1024);
 
-	fd = SAFE_OPEN("test.img", O_RDONLY);
-	SAFE_FSTAT(fd, &buf);
-	SAFE_CLOSE(fd);
-
-	logical_block_size = buf.st_blksize;
-	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
-
 	tst_attach_device(dev_path, "test.img");
 	attach_flag = 1;
 	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
@@ -130,13 +122,22 @@ static void setup(void)
 	 *   size of loop is bigger than the backing device's and the loop
 	 *   needn't transform transfer.
 	 */
-	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
+	sprintf(backing_file_path, "%s/test.img", tst_get_tmpdir());
+	tst_find_backing_dev(backing_file_path, bd_path);
+	block_devfd = SAFE_OPEN(bd_path, O_RDWR);
+	SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size);
+	tst_res(TINFO, "backing dev(%s) logical_block_size is %d", bd_path, logical_block_size);
+	SAFE_CLOSE(block_devfd);
+	if (logical_block_size > 512)
+		TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
 }
 
 static void cleanup(void)
 {
 	if (dev_fd > 0)
 		SAFE_CLOSE(dev_fd);
+	if (block_devfd > 0)
+		SAFE_CLOSE(block_devfd);
 	if (attach_flag)
 		tst_detach_device(dev_path);
 }
-- 
2.23.0




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

* [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-06-28  7:42                         ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Yang Xu
  2020-06-28  7:42                           ` [LTP] [PATCH v4 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
@ 2020-06-29  7:56                           ` Jan Stancek
  2020-06-29 10:37                             ` Yang Xu
  1 sibling, 1 reply; 30+ messages in thread
From: Jan Stancek @ 2020-06-29  7:56 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> +This function finds the block dev that this path belongs to, it compares
> path buf
> +with the fifth column of each row in "/proc/self/mountinfo" and list 10th
> column
> +as its block dev.

Why not match major/minor numbers?

You said "But stat function has problem when filsystem uses virtual block
(such as btrfs,fuse, then major numer is 0)." - Why is that a problem
for comparison against /proc/self/mountinfo?


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

* [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-06-29  7:56                           ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
@ 2020-06-29 10:37                             ` Yang Xu
  2020-06-29 11:08                               ` Jan Stancek
  0 siblings, 1 reply; 30+ messages in thread
From: Yang Xu @ 2020-06-29 10:37 UTC (permalink / raw)
  To: ltp

Hi Jan


> 
> 
> ----- Original Message -----
>> +This function finds the block dev that this path belongs to, it compares
>> path buf
>> +with the fifth column of each row in "/proc/self/mountinfo" and list 10th
>> column
>> +as its block dev.
> 
> Why not match major/minor numbers?
> 
> You said "But stat function has problem when filsystem uses virtual block
> (such as btrfs,fuse, then major numer is 0)." - Why is that a problem
> for comparison against /proc/self/mountinfo?
> 
Yes, you are right. I wrongly think btrfs filesystem affects the 10th 
columu value in /proc/self/mountinfo. In actually, it can show the 
correct backing block dev.
so this functon code as below:
void tst_find_backing_dev(const char *path, char *dev)
{
         char fmt[1024];
         struct stat buf;

         if (stat(path, &buf) < 0)
                  tst_brkm(TWARN | TERRNO, NULL, "stat() failed");

         snprintf(fmt, sizeof(fmt), "%%*i %%*i %u:%u %%*s %%*s %%*s %%*s 
%%*s %%*s %%s %%*s",
                         major(buf.st_dev), minor(buf.st_dev));

         SAFE_FILE_LINES_SCANF(NULL, "/proc/self/mountinfo", fmt, dev);

         if (stat(dev, &buf) < 0)
                  tst_brkm(TWARN | TERRNO, NULL, "stat(%s) failed", dev);

         if (S_ISBLK(buf.st_mode) != 1)
                 tst_brkm(TCONF, NULL, "dev(%s) isn't a block dev", dev);
}


ps: If you think it is ok, I will send a v5 patch about this.
> 
> 



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

* [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-06-29 10:37                             ` Yang Xu
@ 2020-06-29 11:08                               ` Jan Stancek
  2020-06-29 11:41                                 ` [LTP] [PATCH v5 " Yang Xu
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Stancek @ 2020-06-29 11:08 UTC (permalink / raw)
  To: ltp

> > You said "But stat function has problem when filsystem uses virtual block
> > (such as btrfs,fuse, then major numer is 0)." - Why is that a problem
> > for comparison against /proc/self/mountinfo?
> > 
> Yes, you are right. I wrongly think btrfs filesystem affects the 10th
> columu value in /proc/self/mountinfo. In actually, it can show the
> correct backing block dev.

I haven't tested your pasted version, but that approach seems better,
since that should work for any path, not just the mount point.


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

* [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-06-29 11:08                               ` Jan Stancek
@ 2020-06-29 11:41                                 ` Yang Xu
  2020-06-29 11:41                                   ` [LTP] [PATCH v5 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
  2020-07-02  9:18                                   ` [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
  0 siblings, 2 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-29 11:41 UTC (permalink / raw)
  To: ltp

This api uses stat() to get major/minor devnumber of the path, assign the
10th column value to dev when match succeeds in "/proc/self/mountinfo".

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 doc/test-writing-guidelines.txt | 11 +++++++++++
 include/tst_device.h            |  7 +++++++
 lib/newlib_tests/tst_device.c   |  8 ++++++++
 lib/tst_device.c                | 21 +++++++++++++++++++++
 4 files changed, 47 insertions(+)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index 6e466ed0f..58116a40e 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1089,6 +1089,17 @@ FS deferred IO metadata/cache interference, we suggest doing "syncfs" before the
 tst_dev_bytes_written first invocation. And an inline function named tst_dev_sync
 is created for that intention.
 
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
+voud tst_find_backing_dev(const char *path, char *dev);
+-------------------------------------------------------------------------------
+
+This function finds the block dev that this path belongs to, it uses stat function
+to get the major/minor number of the path. Then scan them in "/proc/self/mountinfo"
+and list 10th column value as its block dev if match succeeds.
+
 2.2.16 Formatting a device with a filesystem
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/include/tst_device.h b/include/tst_device.h
index 950cfe1ed..6a1fc5186 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -84,4 +84,11 @@ unsigned long tst_dev_bytes_written(const char *dev);
  */
 void tst_purge_dir(const char *path);
 
+/*
+ * Find the file or path belongs to which block dev
+ * @path  Path to find the backing dev
+ * @dev   The block dev
+ */
+void tst_find_backing_dev(const char *path, char *dev);
+
 #endif	/* TST_DEVICE_H__ */
diff --git a/lib/newlib_tests/tst_device.c b/lib/newlib_tests/tst_device.c
index 1344495b3..ad077affd 100644
--- a/lib/newlib_tests/tst_device.c
+++ b/lib/newlib_tests/tst_device.c
@@ -13,6 +13,7 @@ static void do_test(void)
 {
 	int fd;
 	const char *dev;
+	char block_dev[100];
 	uint64_t ltp_dev_size;
 
 	dev = tst_device->dev;
@@ -29,6 +30,13 @@ static void do_test(void)
 		tst_res(TPASS, "Got expected device size");
 	else
 		tst_res(TFAIL, "Got unexpected device size");
+
+	tst_find_backing_dev("/boot", block_dev);
+	tst_res(TPASS, "/boot belongs to %s block dev", block_dev);
+	tst_find_backing_dev("/", block_dev);
+	tst_res(TPASS, "/ belongs to %s block dev", block_dev);
+	tst_find_backing_dev("/tmp", block_dev);
+	tst_find_backing_dev("/boot/xuyang", block_dev);
 }
 
 static struct tst_test test = {
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 67fe90ed6..842bb7ca7 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -31,6 +31,7 @@
 #include <linux/loop.h>
 #include <stdint.h>
 #include <inttypes.h>
+#include <sys/sysmacros.h>
 #include "lapi/syscalls.h"
 #include "test.h"
 #include "safe_macros.h"
@@ -488,3 +489,23 @@ unsigned long tst_dev_bytes_written(const char *dev)
 
 	return dev_bytes_written;
 }
+
+void tst_find_backing_dev(const char *path, char *dev)
+{
+	char fmt[1024];
+	struct stat buf;
+
+	if (stat(path, &buf) < 0)
+		 tst_brkm(TWARN | TERRNO, NULL, "stat() failed");
+
+	snprintf(fmt, sizeof(fmt), "%%*i %%*i %u:%u %%*s %%*s %%*s %%*s %%*s %%*s %%s %%*s",
+			major(buf.st_dev), minor(buf.st_dev));
+
+	SAFE_FILE_LINES_SCANF(NULL, "/proc/self/mountinfo", fmt, dev);
+
+	if (stat(dev, &buf) < 0)
+		 tst_brkm(TWARN | TERRNO, NULL, "stat(%s) failed", dev);
+
+	if (S_ISBLK(buf.st_mode) != 1)
+		tst_brkm(TCONF, NULL, "dev(%s) isn't a block dev", dev);
+}
-- 
2.23.0




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

* [LTP] [PATCH v5 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size
  2020-06-29 11:41                                 ` [LTP] [PATCH v5 " Yang Xu
@ 2020-06-29 11:41                                   ` Yang Xu
  2020-07-02  9:18                                   ` [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
  1 sibling, 0 replies; 30+ messages in thread
From: Yang Xu @ 2020-06-29 11:41 UTC (permalink / raw)
  To: ltp

At the first, we use BLKSSZGET ioctl to get this size, but using wrong
block dev(/dev/loopN) intead of correct backing file block dev(such as /dev/sdaN).

kernel code(driver/block/loop.c  __loop_update_dio function) as below:
---------------------------------------
if (inode->i_sb->s_bdev) {
	sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
	dio_align = sb_bsize - 1;
}
if (dio) {
	if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
		!(lo->lo_offset & dio_align) &&
		mapping->a_ops->direct_IO &&!lo->transfer)
		use_dio = true;
	else
		use_dio = false;
} else {
        use_dio = false;
}
-------------------------------------

Using inode block size is also wrong because it is for filesystem io(such as we format
filesystem can specify block size for data or log or metadata), it is not suitable
for logical block size.

Using tst_find_backing_dev(path, dev)to get the correct block dev.

Also, "offset is ignored" belongs to the third test(less than logical_block_size) but not
the second test(equal to logical_block_size)

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../kernel/syscalls/ioctl/ioctl_loop05.c      | 29 ++++++++++---------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
index a96997823..e3c14faab 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop05.c
@@ -32,8 +32,8 @@
 #define DIO_MESSAGE "In dio mode"
 #define NON_DIO_MESSAGE "In non dio mode"
 
-static char dev_path[1024], sys_loop_diopath[1024];
-static int dev_num, dev_fd, attach_flag, logical_block_size;
+static char dev_path[1024], sys_loop_diopath[1024], backing_file_path[1024];;
+static int dev_num, dev_fd, block_devfd, attach_flag, logical_block_size;
 
 static void check_dio_value(int flag)
 {
@@ -71,7 +71,7 @@ static void verify_ioctl_loop(void)
 	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0);
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
 		check_dio_value(1);
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 	} else {
@@ -84,7 +84,7 @@ static void verify_ioctl_loop(void)
 
 	TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1));
 	if (TST_RET == 0) {
-		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded");
+		tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored");
 		SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0);
 		return;
 	}
@@ -96,8 +96,7 @@ static void verify_ioctl_loop(void)
 
 static void setup(void)
 {
-	int fd;
-	struct stat buf;
+	char bd_path[100];
 
 	if (tst_fs_type(".") == TST_TMPFS_MAGIC)
 		tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag");
@@ -109,13 +108,6 @@ static void setup(void)
 	sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num);
 	tst_fill_file("test.img", 0, 1024, 1024);
 
-	fd = SAFE_OPEN("test.img", O_RDONLY);
-	SAFE_FSTAT(fd, &buf);
-	SAFE_CLOSE(fd);
-
-	logical_block_size = buf.st_blksize;
-	tst_res(TINFO, "backing dev logical_block_size is %d", logical_block_size);
-
 	tst_attach_device(dev_path, "test.img");
 	attach_flag = 1;
 	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
@@ -130,13 +122,22 @@ static void setup(void)
 	 *   size of loop is bigger than the backing device's and the loop
 	 *   needn't transform transfer.
 	 */
-	TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
+	sprintf(backing_file_path, "%s/test.img", tst_get_tmpdir());
+	tst_find_backing_dev(backing_file_path, bd_path);
+	block_devfd = SAFE_OPEN(bd_path, O_RDWR);
+	SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size);
+	tst_res(TINFO, "backing dev(%s) logical_block_size is %d", bd_path, logical_block_size);
+	SAFE_CLOSE(block_devfd);
+	if (logical_block_size > 512)
+		TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0);
 }
 
 static void cleanup(void)
 {
 	if (dev_fd > 0)
 		SAFE_CLOSE(dev_fd);
+	if (block_devfd > 0)
+		SAFE_CLOSE(block_devfd);
 	if (attach_flag)
 		tst_detach_device(dev_path);
 }
-- 
2.23.0




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

* [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-06-29 11:41                                 ` [LTP] [PATCH v5 " Yang Xu
  2020-06-29 11:41                                   ` [LTP] [PATCH v5 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
@ 2020-07-02  9:18                                   ` Jan Stancek
  2020-07-02 12:27                                     ` Cyril Hrubis
  1 sibling, 1 reply; 30+ messages in thread
From: Jan Stancek @ 2020-07-02  9:18 UTC (permalink / raw)
  To: ltp


----- Original Message -----
> This api uses stat() to get major/minor devnumber of the path, assign the
> 10th column value to dev when match succeeds in "/proc/self/mountinfo".
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>

Cyril, any objections to v5?


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

* [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-07-02  9:18                                   ` [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
@ 2020-07-02 12:27                                     ` Cyril Hrubis
  2020-07-02 13:17                                       ` Jan Stancek
  0 siblings, 1 reply; 30+ messages in thread
From: Cyril Hrubis @ 2020-07-02 12:27 UTC (permalink / raw)
  To: ltp

Hi!
> > This api uses stat() to get major/minor devnumber of the path, assign the
> > 10th column value to dev when match succeeds in "/proc/self/mountinfo".
> > 
> > Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> 
> Cyril, any objections to v5?

Looks good, Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev)
  2020-07-02 12:27                                     ` Cyril Hrubis
@ 2020-07-02 13:17                                       ` Jan Stancek
  0 siblings, 0 replies; 30+ messages in thread
From: Jan Stancek @ 2020-07-02 13:17 UTC (permalink / raw)
  To: ltp

----- Original Message -----
> Hi!
> > > This api uses stat() to get major/minor devnumber of the path, assign the
> > > 10th column value to dev when match succeeds in "/proc/self/mountinfo".
> > > 
> > > Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> > 
> > Cyril, any objections to v5?
> 
> Looks good, Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

Thank you, pushed.


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

end of thread, other threads:[~2020-07-02 13:17 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-09  8:33 [LTP] [PATCH] syscalls/ioctl_loop05: Get the logic_block_size dynamically Yang Xu
2020-06-09  9:24 ` Jan Stancek
2020-06-09  9:48   ` Yang Xu
2020-06-09 10:16     ` Jan Stancek
2020-06-09 10:46       ` Yang Xu
2020-06-09 11:01         ` Jan Stancek
2020-06-10  1:19           ` Yang Xu
2020-06-10  5:37           ` [LTP] [PATCH v2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
2020-06-10 10:13             ` Jan Stancek
2020-06-10 10:42               ` Yang Xu
2020-06-10 12:19                 ` Yang Xu
2020-06-10 13:04                   ` Jan Stancek
2020-06-11  4:56                     ` Yang Xu
2020-06-11  5:32                     ` [LTP] [PATCH v3] " Yang Xu
2020-06-11 11:09                       ` Jan Stancek
2020-06-12  2:57                         ` Yang Xu
2020-06-24  5:07                           ` Yang Xu
2020-06-24 11:32                       ` Cyril Hrubis
2020-06-24 13:06                         ` Jan Stancek
2020-06-25 17:10                         ` Yang Xu
2020-06-28  7:42                         ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Yang Xu
2020-06-28  7:42                           ` [LTP] [PATCH v4 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
2020-06-29  7:56                           ` [LTP] [PATCH v4 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
2020-06-29 10:37                             ` Yang Xu
2020-06-29 11:08                               ` Jan Stancek
2020-06-29 11:41                                 ` [LTP] [PATCH v5 " Yang Xu
2020-06-29 11:41                                   ` [LTP] [PATCH v5 2/2] syscalls/ioctl_loop05: Use correct blockdev to get logical_block_size Yang Xu
2020-07-02  9:18                                   ` [LTP] [PATCH v5 1/2] tst_device: Add new api tst_find_backing_dev(path, dev) Jan Stancek
2020-07-02 12:27                                     ` Cyril Hrubis
2020-07-02 13:17                                       ` Jan Stancek

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.