diff mbox series

[v6,5/6] syscalls/statx10: Add basic test for STATX_DIOALIGN on regular file

Message ID 1684134680-6190-5-git-send-email-xuyang2018.jy@fujitsu.com
State Accepted
Headers show
Series [v6,1/6] include/lapi: Move AT_* related macros to fcntl header | expand

Commit Message

Yang Xu May 15, 2023, 7:11 a.m. UTC
STATX_DIOALIGN is used to get stx_dio_mem_align and stx_dio_offset_align
for files on fs that support direct io. We just check whether these
value are nonzero on ext4 and xfs.

On ext4, files that use certain filesystem features (data journalling,
encryption, and verity) fall back to buffered I/O. But ltp creates own
filesystem by enabling mount_device in tst_test struct. If we set block
device to LTP_DEV environment, we use this block device to mount by using
default mount option. Otherwise, use loop device to simuate it. So it can
avoid these above situations and don't fall back to buffered I/O.

For struct statx member check, we only check stx_dio_mem_align because
these two member is introduced together in separate commit in kernel, so it
is safe.

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 configure.ac                               |  2 +-
 runtest/syscalls                           |  1 +
 testcases/kernel/syscalls/statx/.gitignore |  1 +
 testcases/kernel/syscalls/statx/statx10.c  | 93 ++++++++++++++++++++++
 4 files changed, 96 insertions(+), 1 deletion(-)
 create mode 100644 testcases/kernel/syscalls/statx/statx10.c

Comments

Xiao Yang May 19, 2023, 6:24 a.m. UTC | #1
On 2023/5/15 15:11, Yang Xu wrote:
> STATX_DIOALIGN is used to get stx_dio_mem_align and stx_dio_offset_align
> for files on fs that support direct io. We just check whether these
> value are nonzero on ext4 and xfs.
> 
> On ext4, files that use certain filesystem features (data journalling,
> encryption, and verity) fall back to buffered I/O. But ltp creates own
> filesystem by enabling mount_device in tst_test struct. If we set block
> device to LTP_DEV environment, we use this block device to mount by using
> default mount option. Otherwise, use loop device to simuate it. So it can
> avoid these above situations and don't fall back to buffered I/O.
> 
> For struct statx member check, we only check stx_dio_mem_align because
> these two member is introduced together in separate commit in kernel, so it
> is safe.
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
> ---
>   configure.ac                               |  2 +-
>   runtest/syscalls                           |  1 +
>   testcases/kernel/syscalls/statx/.gitignore |  1 +
>   testcases/kernel/syscalls/statx/statx10.c  | 93 ++++++++++++++++++++++
>   4 files changed, 96 insertions(+), 1 deletion(-)
>   create mode 100644 testcases/kernel/syscalls/statx/statx10.c
> 
> diff --git a/configure.ac b/configure.ac
> index 4c8763376..548288310 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -158,7 +158,7 @@ AC_CHECK_FUNCS(mkdtemp,[],AC_MSG_ERROR(mkdtemp() not found!))
>   AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>])
>   AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>])
>   AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>])
> -AC_CHECK_MEMBERS([struct statx.stx_mnt_id],,,[
> +AC_CHECK_MEMBERS([struct statx.stx_mnt_id, struct statx.stx_dio_mem_align],,,[
>   #define _GNU_SOURCE
>   #include <sys/stat.h>
>   ])
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 9c23a4248..e2548dae5 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1765,6 +1765,7 @@ statx06 statx06
>   statx07 statx07
>   statx08 statx08
>   statx09 statx09
> +statx10 statx10
>   
>   membarrier01 membarrier01
>   
> diff --git a/testcases/kernel/syscalls/statx/.gitignore b/testcases/kernel/syscalls/statx/.gitignore
> index 1cea43c0d..67341ff2d 100644
> --- a/testcases/kernel/syscalls/statx/.gitignore
> +++ b/testcases/kernel/syscalls/statx/.gitignore
> @@ -7,3 +7,4 @@
>   /statx07
>   /statx08
>   /statx09
> +/statx10
> diff --git a/testcases/kernel/syscalls/statx/statx10.c b/testcases/kernel/syscalls/statx/statx10.c
> new file mode 100644
> index 000000000..513a8c262
> --- /dev/null
> +++ b/testcases/kernel/syscalls/statx/statx10.c
> @@ -0,0 +1,93 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
> + * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * It is a basic test for STATX_DIOALIGN mask on ext4 and xfs filesystem.
> + *
> + * - STATX_DIOALIGN   Want stx_dio_mem_align and stx_dio_offset_align value
> + *
> + * Check these two values are nonzero under dio situation when STATX_DIOALIGN
> + * in the request mask.
> + *
> + * On ext4, files that use certain filesystem features (data journaling,
> + * encryption, and verity) fall back to buffered I/O. But ltp creates own
> + * filesystem by enabling mount_device in tst_test struct. If we set block
> + * device to LTP_DEV environment, we use this block device to mount by using
> + * default mount option. Otherwise, use loop device to simuate it. So it can
> + * avoid these above situations and don't fall back to buffered I/O.
> + *
> + * Minimum Linux version required is v6.1.
> + */
> +
> +#define _GNU_SOURCE
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdbool.h>
> +#include "tst_test.h"
> +#include "lapi/stat.h"
> +#include "lapi/fcntl.h"
> +
> +#define MNTPOINT "mnt_point"
> +#define TESTFILE "testfile"
Hi Xu,

I think you should use #define TESTFILE MNTPOINT"/testfile" instead.

> +
> +static void verify_statx(void)
> +{
> +	struct statx buf;
> +
> +	TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTFILE, 0, STATX_DIOALIGN, &buf),
> +		"statx(AT_FDCWD, %s, 0, STATX_DIOALIGN, &buf)", TESTFILE);
> +
> +	if (!(buf.stx_mask & STATX_DIOALIGN)) {
> +		tst_res(TCONF, "Filesystem does not support STATX_DIOALIGN");
> +		return;
> +	}
> +
> +#ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN
> +	if (buf.stx_dio_mem_align != 0)
> +		tst_res(TPASS, "stx_dio_mem_align:%u", buf.stx_dio_mem_align);
> +	else
> +		tst_res(TFAIL, "stx_dio_mem_align was 0, but DIO should be supported");
> +
> +	if (buf.stx_dio_offset_align != 0)
> +		tst_res(TPASS, "stx_dio_offset_align:%u", buf.stx_dio_offset_align);
> +	else
> +		tst_res(TFAIL, "stx_dio_offset_align was 0, but DIO should be supported");
> +#else
> +	tst_res(TCONF, "glibc statx struct miss stx_dio_mem_align field");
> +#endif
> +}
> +
> +static void setup(void)
> +{
> +	int fd = -1;
> +
> +	if (strcmp(tst_device->fs_type, "xfs") && strcmp(tst_device->fs_type, "ext4"))
> +		tst_brk(TCONF, "This test only supports ext4 and xfs");
> +
> +	SAFE_FILE_PRINTF(TESTFILE, "AAAA");
> +	fd = open(TESTFILE, O_RDWR | O_DIRECT);
> +	if (fd == -1) {
> +		if (errno == EINVAL)
> +			tst_brk(TCONF,
> +				"The regular file is not on a filesystem that support DIO");
> +		else
> +			tst_brk(TBROK | TERRNO,
> +				"The regular file is open with O_RDWR | O_DIRECT failed");
> +	}
> +	SAFE_CLOSE(fd);
> +}
> +
> +static struct tst_test test = {
> +	.test_all = verify_statx,
> +	.setup = setup,
> +	.needs_root = 1,
> +	.mntpoint = MNTPOINT,
> +	.mount_device = 1,
> +	.all_filesystems = 1,
> +};
Is it necessary to use all_filesystems? because this test can be run on 
only ext4 and xfs filesystem. It's OK for me if we don't have any better 
way.

Other than that looks good to me.
Reviewed-by: Xiao Yang <yangx.jy@fujitsu.com>

Best Regards,
Xiao Yang
Yang Xu May 19, 2023, 6:45 a.m. UTC | #2
on 2023/05/19 14:24, Yang, Xiao/杨 晓 wrote:
> On 2023/5/15 15:11, Yang Xu wrote:
>> STATX_DIOALIGN is used to get stx_dio_mem_align and stx_dio_offset_align
>> for files on fs that support direct io. We just check whether these
>> value are nonzero on ext4 and xfs.
>>
>> On ext4, files that use certain filesystem features (data journalling,
>> encryption, and verity) fall back to buffered I/O. But ltp creates own
>> filesystem by enabling mount_device in tst_test struct. If we set block
>> device to LTP_DEV environment, we use this block device to mount by using
>> default mount option. Otherwise, use loop device to simuate it. So it can
>> avoid these above situations and don't fall back to buffered I/O.
>>
>> For struct statx member check, we only check stx_dio_mem_align because
>> these two member is introduced together in separate commit in kernel, so it
>> is safe.
>>
>> Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
>> ---
>>    configure.ac                               |  2 +-
>>    runtest/syscalls                           |  1 +
>>    testcases/kernel/syscalls/statx/.gitignore |  1 +
>>    testcases/kernel/syscalls/statx/statx10.c  | 93 ++++++++++++++++++++++
>>    4 files changed, 96 insertions(+), 1 deletion(-)
>>    create mode 100644 testcases/kernel/syscalls/statx/statx10.c
>>
>> diff --git a/configure.ac b/configure.ac
>> index 4c8763376..548288310 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -158,7 +158,7 @@ AC_CHECK_FUNCS(mkdtemp,[],AC_MSG_ERROR(mkdtemp() not found!))
>>    AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>])
>>    AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>])
>>    AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>])
>> -AC_CHECK_MEMBERS([struct statx.stx_mnt_id],,,[
>> +AC_CHECK_MEMBERS([struct statx.stx_mnt_id, struct statx.stx_dio_mem_align],,,[
>>    #define _GNU_SOURCE
>>    #include <sys/stat.h>
>>    ])
>> diff --git a/runtest/syscalls b/runtest/syscalls
>> index 9c23a4248..e2548dae5 100644
>> --- a/runtest/syscalls
>> +++ b/runtest/syscalls
>> @@ -1765,6 +1765,7 @@ statx06 statx06
>>    statx07 statx07
>>    statx08 statx08
>>    statx09 statx09
>> +statx10 statx10
>>    
>>    membarrier01 membarrier01
>>    
>> diff --git a/testcases/kernel/syscalls/statx/.gitignore b/testcases/kernel/syscalls/statx/.gitignore
>> index 1cea43c0d..67341ff2d 100644
>> --- a/testcases/kernel/syscalls/statx/.gitignore
>> +++ b/testcases/kernel/syscalls/statx/.gitignore
>> @@ -7,3 +7,4 @@
>>    /statx07
>>    /statx08
>>    /statx09
>> +/statx10
>> diff --git a/testcases/kernel/syscalls/statx/statx10.c b/testcases/kernel/syscalls/statx/statx10.c
>> new file mode 100644
>> index 000000000..513a8c262
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/statx/statx10.c
>> @@ -0,0 +1,93 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
>> + * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
>> + */
>> +
>> +/*\
>> + * [Description]
>> + *
>> + * It is a basic test for STATX_DIOALIGN mask on ext4 and xfs filesystem.
>> + *
>> + * - STATX_DIOALIGN   Want stx_dio_mem_align and stx_dio_offset_align value
>> + *
>> + * Check these two values are nonzero under dio situation when STATX_DIOALIGN
>> + * in the request mask.
>> + *
>> + * On ext4, files that use certain filesystem features (data journaling,
>> + * encryption, and verity) fall back to buffered I/O. But ltp creates own
>> + * filesystem by enabling mount_device in tst_test struct. If we set block
>> + * device to LTP_DEV environment, we use this block device to mount by using
>> + * default mount option. Otherwise, use loop device to simuate it. So it can
>> + * avoid these above situations and don't fall back to buffered I/O.
>> + *
>> + * Minimum Linux version required is v6.1.
>> + */
>> +
>> +#define _GNU_SOURCE
>> +#include <sys/types.h>
>> +#include <unistd.h>
>> +#include <stdlib.h>
>> +#include <stdbool.h>
>> +#include "tst_test.h"
>> +#include "lapi/stat.h"
>> +#include "lapi/fcntl.h"
>> +
>> +#define MNTPOINT "mnt_point"
>> +#define TESTFILE "testfile"
> Hi Xu,
> 
> I think you should use #define TESTFILE MNTPOINT"/testfile" instead.

Yes, good catch.
> 
>> +
>> +static void verify_statx(void)
>> +{
>> +	struct statx buf;
>> +
>> +	TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTFILE, 0, STATX_DIOALIGN, &buf),
>> +		"statx(AT_FDCWD, %s, 0, STATX_DIOALIGN, &buf)", TESTFILE);
>> +
>> +	if (!(buf.stx_mask & STATX_DIOALIGN)) {
>> +		tst_res(TCONF, "Filesystem does not support STATX_DIOALIGN");
>> +		return;
>> +	}
>> +
>> +#ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN
>> +	if (buf.stx_dio_mem_align != 0)
>> +		tst_res(TPASS, "stx_dio_mem_align:%u", buf.stx_dio_mem_align);
>> +	else
>> +		tst_res(TFAIL, "stx_dio_mem_align was 0, but DIO should be supported");
>> +
>> +	if (buf.stx_dio_offset_align != 0)
>> +		tst_res(TPASS, "stx_dio_offset_align:%u", buf.stx_dio_offset_align);
>> +	else
>> +		tst_res(TFAIL, "stx_dio_offset_align was 0, but DIO should be supported");
>> +#else
>> +	tst_res(TCONF, "glibc statx struct miss stx_dio_mem_align field");
>> +#endif
>> +}
>> +
>> +static void setup(void)
>> +{
>> +	int fd = -1;
>> +
>> +	if (strcmp(tst_device->fs_type, "xfs") && strcmp(tst_device->fs_type, "ext4"))
>> +		tst_brk(TCONF, "This test only supports ext4 and xfs");
>> +
>> +	SAFE_FILE_PRINTF(TESTFILE, "AAAA");
>> +	fd = open(TESTFILE, O_RDWR | O_DIRECT);
>> +	if (fd == -1) {
>> +		if (errno == EINVAL)
>> +			tst_brk(TCONF,
>> +				"The regular file is not on a filesystem that support DIO");
>> +		else
>> +			tst_brk(TBROK | TERRNO,
>> +				"The regular file is open with O_RDWR | O_DIRECT failed");
>> +	}
>> +	SAFE_CLOSE(fd);
>> +}
>> +
>> +static struct tst_test test = {
>> +	.test_all = verify_statx,
>> +	.setup = setup,
>> +	.needs_root = 1,
>> +	.mntpoint = MNTPOINT,
>> +	.mount_device = 1,
>> +	.all_filesystems = 1,
>> +};
> Is it necessary to use all_filesystems? because this test can be run on
> only ext4 and xfs filesystem. It's OK for me if we don't have any better
> way.

AFAIK, we only have a blacklist for skip_filesystem and maybe I can 
introduce a whitelist for this situation.

Best Regards
Yang Xu
> 
> Other than that looks good to me.
> Reviewed-by: Xiao Yang <yangx.jy@fujitsu.com>
> 
> Best Regards,
> Xiao Yang
diff mbox series

Patch

diff --git a/configure.ac b/configure.ac
index 4c8763376..548288310 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,7 +158,7 @@  AC_CHECK_FUNCS(mkdtemp,[],AC_MSG_ERROR(mkdtemp() not found!))
 AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>])
 AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>])
 AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>])
-AC_CHECK_MEMBERS([struct statx.stx_mnt_id],,,[
+AC_CHECK_MEMBERS([struct statx.stx_mnt_id, struct statx.stx_dio_mem_align],,,[
 #define _GNU_SOURCE
 #include <sys/stat.h>
 ])
diff --git a/runtest/syscalls b/runtest/syscalls
index 9c23a4248..e2548dae5 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1765,6 +1765,7 @@  statx06 statx06
 statx07 statx07
 statx08 statx08
 statx09 statx09
+statx10 statx10
 
 membarrier01 membarrier01
 
diff --git a/testcases/kernel/syscalls/statx/.gitignore b/testcases/kernel/syscalls/statx/.gitignore
index 1cea43c0d..67341ff2d 100644
--- a/testcases/kernel/syscalls/statx/.gitignore
+++ b/testcases/kernel/syscalls/statx/.gitignore
@@ -7,3 +7,4 @@ 
 /statx07
 /statx08
 /statx09
+/statx10
diff --git a/testcases/kernel/syscalls/statx/statx10.c b/testcases/kernel/syscalls/statx/statx10.c
new file mode 100644
index 000000000..513a8c262
--- /dev/null
+++ b/testcases/kernel/syscalls/statx/statx10.c
@@ -0,0 +1,93 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test for STATX_DIOALIGN mask on ext4 and xfs filesystem.
+ *
+ * - STATX_DIOALIGN   Want stx_dio_mem_align and stx_dio_offset_align value
+ *
+ * Check these two values are nonzero under dio situation when STATX_DIOALIGN
+ * in the request mask.
+ *
+ * On ext4, files that use certain filesystem features (data journaling,
+ * encryption, and verity) fall back to buffered I/O. But ltp creates own
+ * filesystem by enabling mount_device in tst_test struct. If we set block
+ * device to LTP_DEV environment, we use this block device to mount by using
+ * default mount option. Otherwise, use loop device to simuate it. So it can
+ * avoid these above situations and don't fall back to buffered I/O.
+ *
+ * Minimum Linux version required is v6.1.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include "tst_test.h"
+#include "lapi/stat.h"
+#include "lapi/fcntl.h"
+
+#define MNTPOINT "mnt_point"
+#define TESTFILE "testfile"
+
+static void verify_statx(void)
+{
+	struct statx buf;
+
+	TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTFILE, 0, STATX_DIOALIGN, &buf),
+		"statx(AT_FDCWD, %s, 0, STATX_DIOALIGN, &buf)", TESTFILE);
+
+	if (!(buf.stx_mask & STATX_DIOALIGN)) {
+		tst_res(TCONF, "Filesystem does not support STATX_DIOALIGN");
+		return;
+	}
+
+#ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN
+	if (buf.stx_dio_mem_align != 0)
+		tst_res(TPASS, "stx_dio_mem_align:%u", buf.stx_dio_mem_align);
+	else
+		tst_res(TFAIL, "stx_dio_mem_align was 0, but DIO should be supported");
+
+	if (buf.stx_dio_offset_align != 0)
+		tst_res(TPASS, "stx_dio_offset_align:%u", buf.stx_dio_offset_align);
+	else
+		tst_res(TFAIL, "stx_dio_offset_align was 0, but DIO should be supported");
+#else
+	tst_res(TCONF, "glibc statx struct miss stx_dio_mem_align field");
+#endif
+}
+
+static void setup(void)
+{
+	int fd = -1;
+
+	if (strcmp(tst_device->fs_type, "xfs") && strcmp(tst_device->fs_type, "ext4"))
+		tst_brk(TCONF, "This test only supports ext4 and xfs");
+
+	SAFE_FILE_PRINTF(TESTFILE, "AAAA");
+	fd = open(TESTFILE, O_RDWR | O_DIRECT);
+	if (fd == -1) {
+		if (errno == EINVAL)
+			tst_brk(TCONF,
+				"The regular file is not on a filesystem that support DIO");
+		else
+			tst_brk(TBROK | TERRNO,
+				"The regular file is open with O_RDWR | O_DIRECT failed");
+	}
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test_all = verify_statx,
+	.setup = setup,
+	.needs_root = 1,
+	.mntpoint = MNTPOINT,
+	.mount_device = 1,
+	.all_filesystems = 1,
+};