On Thu, Jan 23, 2025 at 08:41:07PM +0100, Miklos Szeredi wrote: > 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@xxxxxxxxxx> > --- I think this is a good next step but I would first go with the minimal functionality of notifying about mount topology changes for v6.15. Btw, if we notify in do_remount() on the mount that triggered superblock reconfiguration then we also need to trigger in vfs_cmd_reconfigure() aka fsconfig(FSCONFIG_CMD_RECONFIGURE) but the mount that was used to change superblock options is only available in fspick() currently. That would need to be handled. But I think this patch makes more sense in follow-up releases. > 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 --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 */ > > -- > 2.47.1 >