[LTP] [PATCH] fanotify13: fix test failure when running iterations

Amir Goldstein amir73il@gmail.com
Mon Jun 1 10:29:43 CEST 2026


On Mon, Jun 1, 2026 at 1:41 AM AnonymeMeow <anonymemeow@gmail.com> wrote:
>
> The FAN_DELETE_SELF test case removes test files, causing later
> iterations to crash. Recreate the removed files after the test to
> restore the expected initial state. And adjust the overlayfs mount
> timing to avoid creating files directly in the filesystem underneath
> the already mounted overlayfs.
>
> Signed-off-by: AnonymeMeow <anonymemeow@gmail.com>
> ---
>
> Hi, Amir,
>
> I think we shouldn't unconditionally recreate the files through the
> overlayfs. Because files created through overlayfs end up in the upper
> dir, but test variant 3 is intended to verify events reported for lower
> dir files opened through overlayfs, then starting from the second
> iteration variant 3 would test events for upper dir files instead, which
> does not match the intended test scenario.

Right. You caught me ;)

>
> Therefore, I updated my previous patch to unmount the overlayfs mount
> and its bind mount before cleaning the upper dir, and mount them back
> afterwards. This avoids modifying the underlying fs while the overlayfs
> is still mounted.
>
> And since modifying the backing fs of a mounted overlayfs is undefined
> behavior, I adjusted the overlayfs setup timing so that the test files
> are created before overlayfs is mounted.

Ok. Let's work on your patch.
Basically, it is correct and I have no objections with merging as is for
the purpose of fixing the problem.

But you strike me as one who appreciates the value (or aesthetics)
of a simpler and more elegant solution, so let me propose it.

>
> With Best Regards,
> AnonymeMeow
>
> ---
>  .../kernel/syscalls/fanotify/fanotify13.c     | 50 +++++++++++++++----
>  1 file changed, 41 insertions(+), 9 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c
> index 76d40eaf7..c4223c3e9 100644
> --- a/testcases/kernel/syscalls/fanotify/fanotify13.c
> +++ b/testcases/kernel/syscalls/fanotify/fanotify13.c
> @@ -53,6 +53,9 @@
>  #define FILE_PATH_ONE MOUNT_PATH"/"FILE_ONE
>  #define FILE_PATH_TWO MOUNT_PATH"/"FILE_TWO
>
> +#define TST_VARIANT_OVL_LOWER (tst_variant & 1)
> +#define TST_VARIANT_OVL_WATCH (tst_variant > 2)
> +
>  #if defined(HAVE_NAME_TO_HANDLE_AT)
>  struct event_t {
>         unsigned long long expected_mask;
> @@ -137,6 +140,22 @@ static void delete_objects(void)
>         }
>  }
>
> +static void clean_upper_dir(void)
> +{
> +       unsigned int i;
> +
> +       SAFE_UMOUNT(MOUNT_PATH);
> +       SAFE_UMOUNT(OVL_MNT);
> +
> +       SAFE_MOUNT(OVL_UPPER, MOUNT_PATH, "none", MS_BIND, NULL);
> +       for (i = 0; i < ARRAY_SIZE(objects); i++)
> +               SAFE_UNLINK(objects[i].path);
> +       SAFE_UMOUNT(MOUNT_PATH);
> +
> +       SAFE_MOUNT_OVERLAY();
> +       SAFE_MOUNT(OVL_MNT, MOUNT_PATH, "none", MS_BIND, NULL);
> +}
> +

static void ovl_upper_dir_rotate(void)
{
        char dname[PATH_MAX];
        static int iter;

        SAFE_UMOUNT(MOUNT_PATH);
        SAFE_UMOUNT(OVL_MNT);

        sprintf(dname, "%s.%d", OVL_UPPER, iter++);
        SAFE_RENAME(OVL_UPPER, dname);
        SAFE_MKDIR(OVL_UPPER, 755);

        SAFE_MOUNT_OVERLAY();
        SAFE_MOUNT(OVL_MNT, MOUNT_PATH, "none", MS_BIND, NULL);
}

static void restore_objects(void)
{
        if (TST_VARIANT_OVL_LOWER)
                ovl_upper_dir_rotate();
        else
                create_objects();

        /* Get the re-created object ids */
        get_object_stats();
}


>  static void get_object_stats(void)
>  {
>         unsigned int i;
> @@ -340,6 +359,15 @@ static void do_test(unsigned int number)
>                         "Did not get an expected event (expected: %llx)",
>                         event_set[i].expected_mask);
>         }
> +
> +       if (tc->mask & FAN_DELETE_SELF) {
> +               if (TST_VARIANT_OVL_LOWER) {
> +                       clean_upper_dir();
> +               } else {
> +                       create_objects();
> +                       get_object_stats();
> +               }
> +       }

        /* Restore to state before delete_objects() */
        if (tc->mask & FAN_DELETE_SELF)
                restore_objects();

>  out:
>         SAFE_CLOSE(fanotify_fd);
>  }
> @@ -367,14 +395,11 @@ static void do_setup(void)
>          */
>         if (tst_variant) {
>                 REQUIRE_HANDLE_TYPE_SUPPORTED_BY_KERNEL(AT_HANDLE_FID);
> -               ovl_mounted = TST_MOUNT_OVERLAY();
> -               if (!ovl_mounted)
> -                       return;
> -
> -               mnt = tst_variant & 1 ? OVL_LOWER : OVL_UPPER;
> +

extra whitespaces and newline not needed

> +               tst_create_overlay_dirs();

trick: if you leave the newline here. diff will be cleaner
(tst_create_overlay_dirs
replaces TST_MOUNT_OVERLAY)

> +               mnt = TST_VARIANT_OVL_LOWER ? OVL_LOWER : OVL_UPPER;
>         } else {
>                 mnt = OVL_BASE_MNTPOINT;
> -
>         }
>         REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_FID, mnt);
>         SAFE_MKDIR(MOUNT_PATH, 0755);
> @@ -385,8 +410,14 @@ static void do_setup(void)
>
>         /* Create file and directory objects for testing on base fs */
>         create_objects();
> +
> +       if (tst_variant) {
> +               ovl_mounted = TST_MOUNT_OVERLAY();
> +               if (!ovl_mounted)
> +                       return;
> +       }
>
> -       if (tst_variant > 2) {
> +       if (TST_VARIANT_OVL_WATCH) {
>                 /* Setup watches on overlayfs */
>                 SAFE_MOUNT(OVL_MNT, MOUNT_PATH, "none", MS_BIND, NULL);
>                 ovl_bind_mounted = 1;
> @@ -416,12 +447,13 @@ static void do_cleanup(void)
>                 SAFE_CLOSE(fanotify_fd);
>         if (ovl_bind_mounted)
>                 SAFE_UMOUNT(MOUNT_PATH);
> +       if (ovl_mounted)
> +               SAFE_UMOUNT(OVL_MNT);
>         if (bind_mounted) {
> +               delete_objects();

This clean is not needed because the entire filesystem was formatted
and mounted and is going to be torn down by the test framework.

>                 SAFE_UMOUNT(MOUNT_PATH);
>                 SAFE_RMDIR(MOUNT_PATH);
>         }
> -       if (ovl_mounted)
> -               SAFE_UMOUNT(OVL_MNT);


Although it is nice to unmount in the reverse order of mounts, the
order of unmounts here is not really significant, so I would avoid the churn.

Thanks,
Amir.


More information about the ltp mailing list