Hi, Since this commit: commit ec44610fe2b86daef70f3f53f47d2a2542d7094f Author: Amir Goldstein <amir73il@xxxxxxxxx> Date: Tue Aug 10 18:12:19 2021 +0300 fsnotify: count all objects with attached connectors Kernel fsnotify can't finish a stress testcase that used to pass quickly. Kernel hung at umount. Can not be killed but restarting the server. Reproducer text is attached. Thanks, Murphy --- reproducer test.sh start ------------------------------------- #!/bin/bash cc fanotify_init_stress.c -o fanotify_init_stress || exit cc fanotify_flush_stress.c -o fanotify_flush_stress || exit export TIMEOUT=10s STRESSES="fanotify_flush_stress fanotify_init_stress" function cleanup_processes() { while ps jf | egrep "fanotify_flush_stress|fanotify_init_stress" | grep -v grep ; do killall fanotify_init_stress > /dev/null 2>&1 killall fanotify_flush_stress > /dev/null 2>&1 sleep 1 done } SCRATCH_MNT=/fsn fallocate -l 1G fsn.img || exit mkfs.xfs -f fsn.img || exit mkdir -p $SCRATCH_MNT mount -o loop fsn.img $SCRATCH_MNT || exit touch $SCRATCH_MNT/testfile for i in $STRESSES do for j in $STRESSES do echo testing $i $j ./$i $SCRATCH_MNT $TIMEOUT > /dev/null 2>&1 & ./$i $SCRATCH_MNT/testfile $TIMEOUT > /dev/null 2>&1 & ./$j $SCRATCH_MNT $TIMEOUT > /dev/null 2>&1 & ./$j $SCRATCH_MNT/testfile $TIMEOUT > /dev/null 2>&1 & sleep $TIMEOUT cleanup_processes done done sleep $TIMEOUT sync umount $SCRATCH_MNT rm -rf fsn* tmp --- reproducer test.sh end ------------------------------------- --- reproducer fanotify_flush_stress.c start---------------- #define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */ #include <errno.h> #include <fcntl.h> #include <limits.h> #include <poll.h> #include <stdio.h> #include <stdlib.h> #include <sys/fanotify.h> #include <unistd.h> #include <string.h> int main(int argc, char *argv[]) { char buf; int fd; #if 0 /* Check mount point is supplied */ if (argc != 2) { fprintf(stderr, "Usage: %s MOUNT\n", argv[0]); exit(EXIT_FAILURE); } #endif printf("%s on %s\n", argv[0], argv[1]); /* Create the file descriptor for accessing the fanotify API */ fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK, O_RDONLY | O_LARGEFILE); if (fd == -1) { perror("fanotify_init"); exit(EXIT_FAILURE); } /* Loop marking all kinds of events and flush */ while (1) { if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_ACCESS | FAN_MODIFY | FAN_OPEN_PERM | FAN_CLOSE | FAN_OPEN | FAN_ACCESS_PERM | FAN_ONDIR | FAN_EVENT_ON_CHILD, -1, argv[1]) == -1) perror("fanotify_mark add"); if (fanotify_mark(fd, FAN_MARK_FLUSH | FAN_MARK_MOUNT, 0, -1, argv[1]) == -1) perror("fanotify_mark flush mount"); if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_ACCESS | FAN_MODIFY | FAN_OPEN_PERM | FAN_CLOSE | FAN_OPEN | FAN_ACCESS_PERM | FAN_ONDIR | FAN_EVENT_ON_CHILD, -1, argv[1]) == -1) perror("fanotify_mark add"); if (fanotify_mark(fd, FAN_MARK_FLUSH, 0, -1, argv[1]) == -1) perror("fanotify_mark flush"); } close(fd); exit(EXIT_SUCCESS); } --- reproducer fanotify_flush_stress.c end ---------------- --- reproducer fanotify_init_stress.c start -----------_ #define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */ #include <errno.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <sys/fanotify.h> int main(int argc, char *argv[]) { char buf; int fd; #if 0 /* Check mount point is supplied */ if (argc != 2) { fprintf(stderr, "Usage: %s MOUNT\n", argv[0]); exit(EXIT_FAILURE); } #endif printf("%s on %s\n", argv[0], argv[1]); while (1) { /* Create the file descriptor for accessing the fanotify API */ fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK, O_RDONLY | O_LARGEFILE); if (fd == -1) perror("fanotify_init"); if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_ACCESS | FAN_MODIFY | FAN_OPEN_PERM | FAN_CLOSE | FAN_OPEN | FAN_ACCESS_PERM | FAN_ONDIR | FAN_EVENT_ON_CHILD, -1, argv[1]) == -1) perror("fanotify_mark"); close(fd); } exit(EXIT_SUCCESS); } --- reproducer fanotify_init_stress.c end -----------_