···1919#endif2020 struct list_head mnt_mounts; /* list of children, anchored here */2121 struct list_head mnt_child; /* and going through their mnt_child */2222- /* yet to be moved - fsnotify ones go here */2322 const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */2423 struct list_head mnt_list;2524 struct list_head mnt_expire; /* link in fs-specific expiry list */···2728 struct list_head mnt_slave; /* slave list entry */2829 struct mount *mnt_master; /* slave is on master->mnt_slave_list */2930 struct mnt_namespace *mnt_ns; /* containing namespace */3131+#ifdef CONFIG_FSNOTIFY3232+ struct hlist_head mnt_fsnotify_marks;3333+ __u32 mnt_fsnotify_mask;3434+#endif3035 int mnt_id; /* mount identifier */3136 int mnt_group_id; /* peer group identifier */3237 int mnt_expiry_mark; /* true if marked for expiry */
···26262727#include <linux/fsnotify_backend.h>2828#include "fsnotify.h"2929+#include "../mount.h"29303031/*3132 * Clear all of the marks on an inode when it is being evicted from core···206205 struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL;207206 struct fsnotify_group *inode_group, *vfsmount_group;208207 struct fsnotify_event *event = NULL;209209- struct vfsmount *mnt;208208+ struct mount *mnt;210209 int idx, ret = 0;211210 /* global tests shouldn't care about events on child only the specific event */212211 __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);213212214213 if (data_is == FSNOTIFY_EVENT_PATH)215215- mnt = ((struct path *)data)->mnt;214214+ mnt = real_mount(((struct path *)data)->mnt);216215 else217216 mnt = NULL;218217···263262 /* we didn't use the vfsmount_mark */264263 vfsmount_group = NULL;265264 } else if (vfsmount_group > inode_group) {266266- ret = send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,265265+ ret = send_to_group(to_tell, &mnt->mnt, NULL, vfsmount_mark, mask, data,267266 data_is, cookie, file_name, &event);268267 inode_group = NULL;269268 } else {270270- ret = send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,269269+ ret = send_to_group(to_tell, &mnt->mnt, inode_mark, vfsmount_mark,271270 mask, data, data_is, cookie, file_name,272271 &event);273272 }
+12-7
fs/notify/vfsmount_mark.c
···28282929#include <linux/fsnotify_backend.h>3030#include "fsnotify.h"3131+#include "../mount.h"31323233void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)3334{3435 struct fsnotify_mark *mark, *lmark;3536 struct hlist_node *pos, *n;3737+ struct mount *m = real_mount(mnt);3638 LIST_HEAD(free_list);37393840 spin_lock(&mnt->mnt_root->d_lock);3939- hlist_for_each_entry_safe(mark, pos, n, &mnt->mnt_fsnotify_marks, m.m_list) {4141+ hlist_for_each_entry_safe(mark, pos, n, &m->mnt_fsnotify_marks, m.m_list) {4042 list_add(&mark->m.free_m_list, &free_list);4143 hlist_del_init_rcu(&mark->m.m_list);4244 fsnotify_get_mark(mark);···6159 */6260static void fsnotify_recalc_vfsmount_mask_locked(struct vfsmount *mnt)6361{6262+ struct mount *m = real_mount(mnt);6463 struct fsnotify_mark *mark;6564 struct hlist_node *pos;6665 __u32 new_mask = 0;67666867 assert_spin_locked(&mnt->mnt_root->d_lock);69687070- hlist_for_each_entry(mark, pos, &mnt->mnt_fsnotify_marks, m.m_list)6969+ hlist_for_each_entry(mark, pos, &m->mnt_fsnotify_marks, m.m_list)7170 new_mask |= mark->mask;7272- mnt->mnt_fsnotify_mask = new_mask;7171+ m->mnt_fsnotify_mask = new_mask;7372}74737574/*···104101static struct fsnotify_mark *fsnotify_find_vfsmount_mark_locked(struct fsnotify_group *group,105102 struct vfsmount *mnt)106103{104104+ struct mount *m = real_mount(mnt);107105 struct fsnotify_mark *mark;108106 struct hlist_node *pos;109107110108 assert_spin_locked(&mnt->mnt_root->d_lock);111109112112- hlist_for_each_entry(mark, pos, &mnt->mnt_fsnotify_marks, m.m_list) {110110+ hlist_for_each_entry(mark, pos, &m->mnt_fsnotify_marks, m.m_list) {113111 if (mark->group == group) {114112 fsnotify_get_mark(mark);115113 return mark;···144140 struct fsnotify_group *group, struct vfsmount *mnt,145141 int allow_dups)146142{143143+ struct mount *m = real_mount(mnt);147144 struct fsnotify_mark *lmark;148145 struct hlist_node *node, *last = NULL;149146 int ret = 0;···159154 mark->m.mnt = mnt;160155161156 /* is mark the first mark? */162162- if (hlist_empty(&mnt->mnt_fsnotify_marks)) {163163- hlist_add_head_rcu(&mark->m.m_list, &mnt->mnt_fsnotify_marks);157157+ if (hlist_empty(&m->mnt_fsnotify_marks)) {158158+ hlist_add_head_rcu(&mark->m.m_list, &m->mnt_fsnotify_marks);164159 goto out;165160 }166161167162 /* should mark be in the middle of the current list? */168168- hlist_for_each_entry(lmark, node, &mnt->mnt_fsnotify_marks, m.m_list) {163163+ hlist_for_each_entry(lmark, node, &m->mnt_fsnotify_marks, m.m_list) {169164 last = node;170165171166 if ((lmark->group == group) && !allow_dups) {
-5
include/linux/mount.h
···5151 struct dentry *mnt_root; /* root of the mounted tree */5252 struct super_block *mnt_sb; /* pointer to superblock */5353 int mnt_flags;5454- /* 4 bytes hole on 64bits arches without fsnotify */5555-#ifdef CONFIG_FSNOTIFY5656- __u32 mnt_fsnotify_mask;5757- struct hlist_head mnt_fsnotify_marks;5858-#endif5954};60556156struct file; /* forward dec */