@@ -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;
@@ -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);
@@ -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)
@@ -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)
@@ -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 | \
@@ -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 */
@@ -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)
@@ -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 */
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(-)