diff mbox series

[v4,4/4] vfs: add notifications for mount attribute change

Message ID 20250123194108.1025273-5-mszeredi@redhat.com (mailing list archive)
State New
Headers show
Series mount notification | expand

Commit Message

Miklos Szeredi Jan. 23, 2025, 7:41 p.m. UTC
Notify when mount flags, propagation or idmap changes.

Just like attach and detach, no details are given in the notification, only
the mount ID.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 fs/namespace.c                   | 27 +++++++++++++++++++++++++++
 fs/notify/fanotify/fanotify.c    |  2 +-
 fs/notify/fanotify/fanotify.h    |  2 +-
 fs/notify/fsnotify.c             |  2 +-
 include/linux/fanotify.h         |  2 +-
 include/linux/fsnotify.h         |  5 +++++
 include/linux/fsnotify_backend.h |  5 ++++-
 include/uapi/linux/fanotify.h    |  1 +
 8 files changed, 41 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/fs/namespace.c b/fs/namespace.c
index 948348a37f6c..9b9b13665dce 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2807,6 +2807,9 @@  static int do_change_type(struct path *path, int ms_flags)
 		change_mnt_propagation(m, type);
 	unlock_mount_hash();
 
+	for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
+		fsnotify_mnt_change(m->mnt_ns, &m->mnt);
+
  out_unlock:
 	namespace_unlock();
 	return err;
@@ -3089,6 +3092,12 @@  static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags)
 	unlock_mount_hash();
 	up_read(&sb->s_umount);
 
+	if (!ret) {
+		down_read(&namespace_sem);
+		fsnotify_mnt_change(mnt->mnt_ns, &mnt->mnt);
+		up_read(&namespace_sem);
+	}
+
 	mnt_warn_timestamp_expiry(path, &mnt->mnt);
 
 	return ret;
@@ -3141,6 +3150,13 @@  static int do_remount(struct path *path, int ms_flags, int sb_flags,
 		up_write(&sb->s_umount);
 	}
 
+	if (!err) {
+		down_read(&namespace_sem);
+		fsnotify_mnt_change(mnt->mnt_ns, &mnt->mnt);
+		up_read(&namespace_sem);
+	}
+
+
 	mnt_warn_timestamp_expiry(path, &mnt->mnt);
 
 	put_fs_context(fc);
@@ -4708,6 +4724,8 @@  static int do_mount_setattr(struct path *path, struct mount_kattr *kattr)
 				return err;
 			}
 		}
+	} else {
+		down_read(&namespace_sem);
 	}
 
 	err = -EINVAL;
@@ -4743,10 +4761,19 @@  static int do_mount_setattr(struct path *path, struct mount_kattr *kattr)
 out:
 	unlock_mount_hash();
 
+	if (!err) {
+		struct mount *m;
+
+		for (m = mnt; m; m = kattr->recurse ? next_mnt(m, mnt) : NULL)
+			fsnotify_mnt_change(m->mnt_ns, &m->mnt);
+	}
+
 	if (kattr->propagation) {
 		if (err)
 			cleanup_group_ids(mnt, NULL);
 		namespace_unlock();
+	} else {
+		up_read(&namespace_sem);
 	}
 
 	return err;
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index b1937f92f105..c7ddd145f3d8 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -934,7 +934,7 @@  static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
 	BUILD_BUG_ON(FAN_FS_ERROR != FS_ERROR);
 	BUILD_BUG_ON(FAN_RENAME != FS_RENAME);
 
-	BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 23);
+	BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 24);
 
 	mask = fanotify_group_event_mask(group, iter_info, &match_mask,
 					 mask, data, data_type, dir);
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index f1a7cbedc9e3..8d6289da06f1 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -471,7 +471,7 @@  static inline bool fanotify_is_error_event(u32 mask)
 
 static inline bool fanotify_is_mnt_event(u32 mask)
 {
-	return mask & (FAN_MNT_ATTACH | FAN_MNT_DETACH);
+	return mask & FANOTIFY_MOUNT_EVENTS;
 }
 
 static inline const struct path *fanotify_event_path(struct fanotify_event *event)
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 2b2c3fd907c7..5872dd27172d 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -660,7 +660,7 @@  static __init int fsnotify_init(void)
 {
 	int ret;
 
-	BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 25);
+	BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 26);
 
 	ret = init_srcu_struct(&fsnotify_mark_srcu);
 	if (ret)
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index fc142be2542d..61e112d25303 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -100,7 +100,7 @@ 
 /* Events that can only be reported with data type FSNOTIFY_EVENT_ERROR */
 #define FANOTIFY_ERROR_EVENTS	(FAN_FS_ERROR)
 
-#define FANOTIFY_MOUNT_EVENTS	(FAN_MNT_ATTACH | FAN_MNT_DETACH)
+#define FANOTIFY_MOUNT_EVENTS	(FAN_MNT_ATTACH | FAN_MNT_DETACH | FAN_MNT_CHANGE)
 
 /* Events that user can request to be notified on */
 #define FANOTIFY_EVENTS		(FANOTIFY_PATH_EVENTS | \
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index ea998551dd0d..ba3e05c69aaa 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -483,4 +483,9 @@  static inline void fsnotify_mnt_move(struct mnt_namespace *ns, struct vfsmount *
 	fsnotify_mnt(FS_MNT_MOVE, ns, mnt);
 }
 
+static inline void fsnotify_mnt_change(struct mnt_namespace *ns, struct vfsmount *mnt)
+{
+	fsnotify_mnt(FS_MNT_CHANGE, ns, mnt);
+}
+
 #endif	/* _LINUX_FS_NOTIFY_H */
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 6c3e3a4a7b10..54e01803e309 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -58,6 +58,8 @@ 
 
 #define FS_MNT_ATTACH		0x01000000	/* Mount was attached */
 #define FS_MNT_DETACH		0x02000000	/* Mount was detached */
+#define FS_MNT_CHANGE		0x04000000	/* Mount was changed */
+
 #define FS_MNT_MOVE		(FS_MNT_ATTACH | FS_MNT_DETACH)
 
 /*
@@ -106,7 +108,8 @@ 
 			     FS_EVENTS_POSS_ON_CHILD | \
 			     FS_DELETE_SELF | FS_MOVE_SELF | \
 			     FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
-			     FS_ERROR | FS_MNT_ATTACH | FS_MNT_DETACH)
+			     FS_ERROR | \
+			     FS_MNT_ATTACH | FS_MNT_DETACH | FS_MNT_CHANGE )
 
 /* Extra flags that may be reported with event or control handling of events */
 #define ALL_FSNOTIFY_FLAGS  (FS_ISDIR | FS_EVENT_ON_CHILD | FS_DN_MULTISHOT)
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
index 69340e483ae7..256fc5755b45 100644
--- a/include/uapi/linux/fanotify.h
+++ b/include/uapi/linux/fanotify.h
@@ -27,6 +27,7 @@ 
 #define FAN_OPEN_EXEC_PERM	0x00040000	/* File open/exec in perm check */
 #define FAN_MNT_ATTACH		0x01000000	/* Mount was attached */
 #define FAN_MNT_DETACH		0x02000000	/* Mount was detached */
+#define FAN_MNT_CHANGE		0x04000000	/* Mount was changed */
 
 #define FAN_EVENT_ON_CHILD	0x08000000	/* Interested in child events */