[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