git: 75293aaeea78 - stable/15 - inotify: Avoid resetting the cookie

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 29 Dec 2025 17:07:14 UTC
The branch stable/15 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=75293aaeea785b342da41aac811213889ea0512c

commit 75293aaeea785b342da41aac811213889ea0512c
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-12-21 23:49:26 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-12-29 14:31:33 +0000

    inotify: Avoid resetting the cookie
    
    The IN_MOVED_FROM and _TO events only apply to names in a watched
    directory, never to a watched directory itself.  So, the cookie value
    there is always zero, and in particular we should not reset the
    caller-provided cookie value, as it may be used later.
    
    Add a regression test.
    
    Reported by:    arrowd
    MFC after:      1 week
    
    (cherry picked from commit da8ab13249420e85935b89794f333f0755e56385)
---
 sys/kern/vfs_inotify.c        |  7 ++-----
 tests/sys/kern/inotify_test.c | 31 +++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c
index fd1ef39b13f7..716fdc96e5fb 100644
--- a/sys/kern/vfs_inotify.c
+++ b/sys/kern/vfs_inotify.c
@@ -723,7 +723,6 @@ vn_inotify(struct vnode *vp, struct vnode *dvp, struct componentname *cnp,
 				}
 				break;
 			case IN_MOVED_FROM:
-				cookie = 0;
 				selfevent = IN_MOVE_SELF;
 				break;
 			case _IN_ATTRIB_LINKCOUNT:
@@ -734,10 +733,8 @@ vn_inotify(struct vnode *vp, struct vnode *dvp, struct componentname *cnp,
 				break;
 			}
 
-			if ((selfevent & ~_IN_DIR_EVENTS) != 0) {
-				inotify_log(vp, NULL, 0, selfevent | isdir,
-				    cookie);
-			}
+			if ((selfevent & ~_IN_DIR_EVENTS) != 0)
+				inotify_log(vp, NULL, 0, selfevent | isdir, 0);
 		}
 
 		/*
diff --git a/tests/sys/kern/inotify_test.c b/tests/sys/kern/inotify_test.c
index 713db55afc22..0a4df4e5fcaa 100644
--- a/tests/sys/kern/inotify_test.c
+++ b/tests/sys/kern/inotify_test.c
@@ -761,6 +761,36 @@ ATF_TC_BODY(inotify_event_move, tc)
 	close_inotify(ifd);
 }
 
+ATF_TC_WITHOUT_HEAD(inotify_event_move_dir);
+ATF_TC_BODY(inotify_event_move_dir, tc)
+{
+	char dir[PATH_MAX], subdir1[PATH_MAX], subdir2[PATH_MAX];
+	uint32_t cookie1, cookie2;
+	int error, ifd, wd1, wd2;
+
+	ifd = inotify(IN_NONBLOCK);
+
+	wd1 = watch_dir(ifd, IN_MOVE, dir);
+	snprintf(subdir1, sizeof(subdir1), "%s/subdir", dir);
+	error = mkdir(subdir1, 0755);
+	ATF_REQUIRE(error == 0);
+	wd2 = inotify_add_watch(ifd, subdir1, IN_MOVE);
+	ATF_REQUIRE(wd2 != -1);
+
+	snprintf(subdir2, sizeof(subdir2), "%s/newsubdir", dir);
+	error = rename(subdir1, subdir2);
+	ATF_REQUIRE(error == 0);
+
+	cookie1 = consume_event_cookie(ifd, wd1, IN_MOVED_FROM, IN_ISDIR,
+	    "subdir");
+	cookie2 = consume_event_cookie(ifd, wd1, IN_MOVED_TO, IN_ISDIR,
+	    "newsubdir");
+	ATF_REQUIRE_MSG(cookie1 == cookie2,
+	    "expected cookie %u, got %u", cookie1, cookie2);
+
+	close_inotify(ifd);
+}
+
 ATF_TC_WITHOUT_HEAD(inotify_event_open);
 ATF_TC_BODY(inotify_event_open, tc)
 {
@@ -858,6 +888,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, inotify_event_create);
 	ATF_TP_ADD_TC(tp, inotify_event_delete);
 	ATF_TP_ADD_TC(tp, inotify_event_move);
+	ATF_TP_ADD_TC(tp, inotify_event_move_dir);
 	ATF_TP_ADD_TC(tp, inotify_event_open);
 	ATF_TP_ADD_TC(tp, inotify_event_unmount);
 	return (atf_no_error());