[LTP] [PATCH v3] lib: Add proper filesystem skiplist
Cyril Hrubis
chrubis@suse.cz
Fri Mar 12 15:05:38 CET 2021
Hi!
> The approach with flags we added for FUSE does not scale at all, we need
> a proper skiplist so that we can skip individual filesystems.
>
> The motivation here is the addition of tmpfs to the supported
> filesystems check. One of the problems there is that sync() is no-op on
> tmpfs and hence the syncfs test fails. After this patchset we can simply
> skip syncfs test on tmpfs by setting the right skiplist.
>
> As a bonus point the list of unsupported filesystem gets nicely
> propagated to the metadata as well.
>
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> Co-authored-by: Martin Doucha <mdoucha@suse.cz>
This would be just Signed-off-by:
> ---
>
> Moving the skiplist logic from has_kernel_support() to tst_fs_is_supported()
> misses the point of my objection. This is the code I had in mind when I was
> commenting on the patchset.
>
> include/tst_fs.h | 26 +++++++---
> include/tst_test.h | 9 +++-
> lib/tst_supported_fs_types.c | 51 ++++++++++++++-----
> lib/tst_test.c | 2 +-
> .../kernel/syscalls/fsconfig/fsconfig01.c | 2 +-
> testcases/kernel/syscalls/fsmount/fsmount01.c | 2 +-
> testcases/kernel/syscalls/fsmount/fsmount02.c | 2 +-
> testcases/kernel/syscalls/fsopen/fsopen01.c | 2 +-
> testcases/kernel/syscalls/fspick/fspick01.c | 2 +-
> testcases/kernel/syscalls/fspick/fspick02.c | 2 +-
> .../kernel/syscalls/move_mount/move_mount01.c | 2 +-
> .../kernel/syscalls/move_mount/move_mount02.c | 2 +-
> .../kernel/syscalls/open_tree/open_tree01.c | 2 +-
> .../kernel/syscalls/open_tree/open_tree02.c | 2 +-
> .../sync_file_range/sync_file_range02.c | 2 +-
> testcases/lib/tst_supported_fs.c | 4 +-
> 16 files changed, 79 insertions(+), 35 deletions(-)
>
> diff --git a/include/tst_fs.h b/include/tst_fs.h
> index 4f7dd68d2..ae58a9647 100644
> --- a/include/tst_fs.h
> +++ b/include/tst_fs.h
> @@ -44,6 +44,9 @@ enum {
> #define OVL_WORK OVL_BASE_MNTPOINT"/work"
> #define OVL_MNT OVL_BASE_MNTPOINT"/ovl"
>
> +#define TST_FS_NATIVE 1
> +#define TST_FS_FUSE 2
> +
> /*
> * @path: path is the pathname of any file within the mounted file system
> * @mult: mult should be TST_KB, TST_MB or TST_GB
> @@ -167,18 +170,29 @@ int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
> */
> int tst_prealloc_file(const char *path, size_t bs, size_t bcount);
>
> -#define TST_FS_SKIP_FUSE 0x01
> -
> /*
> - * Return 1 if a specified fiilsystem is supported
> - * Return 0 if a specified fiilsystem isn't supported
> + * Return TST_FS_NATIVE if a specified filesystem is supported by kernel
> + * Return TST_FS_FUSE if a specified filesystem is supported through FUSE
> + * Return 0 if a specified filesystem isn't supported
> + *
> + * @fs_type A filesystem type to check the support for.
> */
> -int tst_fs_is_supported(const char *fs_type, int flags);
> +int tst_fs_is_supported(const char *fs_type);
>
> /*
> * Returns NULL-terminated array of kernel-supported filesystems.
> + *
> + * @skiplist A NULL terminated array of filesystems to skip.
> + */
> +const char **tst_get_supported_fs_types(const char *const *skiplist);
> +
> +/*
> + * Returns 1 if filesystem is in skiplist 0 otherwise.
> + *
> + * @fs_type A filesystem type to lookup.
> + * @skiplist A NULL terminated array of fileystemsytems to skip.
> */
> -const char **tst_get_supported_fs_types(int flags);
> +int tst_fs_in_skiplist(const char *fs_type, const char *const *skiplist);
>
> /*
> * Creates and writes to files on given path until write fails with ENOSPC
> diff --git a/include/tst_test.h b/include/tst_test.h
> index 1fbebe752..4eee6f897 100644
> --- a/include/tst_test.h
> +++ b/include/tst_test.h
> @@ -159,6 +159,13 @@ struct tst_test {
> */
> int all_filesystems:1;
>
> + /*
> + * The skip_filesystem is a NULL terminated list of filesystems the
> + * test does not support. It can also be used to disable whole class of
> + * filesystems with a special keyworks such as "fuse".
> + */
> + const char *const *skip_filesystems;
> +
> /* Minimum number of online CPU required by the test */
> unsigned long min_cpus;
>
> @@ -197,8 +204,6 @@ struct tst_test {
>
> /* Device filesystem type override NULL == default */
> const char *dev_fs_type;
> - /* Flags to be passed to tst_get_supported_fs_types() */
> - int dev_fs_flags;
>
> /* Options passed to SAFE_MKFS() when format_device is set */
> const char *const *dev_fs_opts;
> diff --git a/lib/tst_supported_fs_types.c b/lib/tst_supported_fs_types.c
> index 00ede549d..7a420f481 100644
> --- a/lib/tst_supported_fs_types.c
> +++ b/lib/tst_supported_fs_types.c
> @@ -45,7 +45,22 @@ static int has_mkfs(const char *fs_type)
> return 1;
> }
>
> -static int has_kernel_support(const char *fs_type, int flags)
> +int tst_fs_in_skiplist(const char *fs_type, const char *const *skiplist)
> +{
> + unsigned int i;
> +
> + if (!skiplist)
> + return 0;
> +
> + for (i = 0; skiplist[i]; i++) {
> + if (!strcmp(fs_type, skiplist[i]))
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static int has_kernel_support(const char *fs_type)
> {
> static int fuse_supported = -1;
> const char *tmpdir = getenv("TMPDIR");
> @@ -58,7 +73,7 @@ static int has_kernel_support(const char *fs_type, int flags)
> mount("/dev/zero", tmpdir, fs_type, 0, NULL);
> if (errno != ENODEV) {
> tst_res(TINFO, "Kernel supports %s", fs_type);
> - return 1;
> + return TST_FS_NATIVE;
> }
>
> /* Is FUSE supported by kernel? */
> @@ -84,26 +99,36 @@ static int has_kernel_support(const char *fs_type, int flags)
> return 0;
> }
>
> - if (flags & TST_FS_SKIP_FUSE) {
> - tst_res(TINFO, "Skipping FUSE as requested by the test");
> - return 0;
> - }
> -
> tst_res(TINFO, "FUSE does support %s", fs_type);
> - return 1;
> + return TST_FS_FUSE;
> }
>
> -int tst_fs_is_supported(const char *fs_type, int flags)
> +int tst_fs_is_supported(const char *fs_type)
> {
> - return has_kernel_support(fs_type, flags) && has_mkfs(fs_type);
> + if (has_mkfs(fs_type))
> + return has_kernel_support(fs_type);
> +
> + return 0;
> }
>
> -const char **tst_get_supported_fs_types(int flags)
> +const char **tst_get_supported_fs_types(const char *const *skiplist)
> {
> - unsigned int i, j = 0;
> + unsigned int ret, skip_fuse, i, j = 0;
> +
> + skip_fuse = tst_fs_in_skiplist("fuse", skiplist);
>
> for (i = 0; fs_type_whitelist[i]; i++) {
> - if (tst_fs_is_supported(fs_type_whitelist[i], flags))
> + if (tst_fs_in_skiplist(fs_type_whitelist[i], skiplist))
I guess that we should print here that the filesystem is skipped
otherwise there will be no information why it was skipped in the test
output.
> + continue;
> +
> + ret = tst_fs_is_supported(fs_type_whitelist[i]);
> +
> + if (ret == TST_FS_FUSE && skip_fuse) {
> + tst_res(TINFO, "Skipping FUSE as requested by test");
> + continue;
And here we produce two messages for FUSE based filesystems, one that
it's supported and second that it's skipped in a case that it's
supported.
It would probably be more consistent if we called the
tst_fs_is_supported() unconditionally and filtered out skipped
filesystems only if we get positive return value from
tst_fs_is_supported().
--
Cyril Hrubis
chrubis@suse.cz
More information about the ltp
mailing list