aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/notify/fanotify/fanotify.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index f6900022f69e..060b177146e8 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -100,31 +100,39 @@ static int fanotify_handle_event(struct fsnotify_group *group, struct fsnotify_e
100} 100}
101 101
102static bool should_send_vfsmount_event(struct fsnotify_group *group, struct vfsmount *mnt, 102static bool should_send_vfsmount_event(struct fsnotify_group *group, struct vfsmount *mnt,
103 __u32 mask) 103 struct inode *inode, __u32 mask)
104{ 104{
105 struct fsnotify_mark *fsn_mark; 105 struct fsnotify_mark *mnt_mark;
106 bool send; 106 struct fsnotify_mark *inode_mark;
107 107
108 pr_debug("%s: group=%p vfsmount=%p mask=%x\n", 108 pr_debug("%s: group=%p vfsmount=%p mask=%x\n",
109 __func__, group, mnt, mask); 109 __func__, group, mnt, mask);
110 110
111 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); 111 mnt_mark = fsnotify_find_vfsmount_mark(group, mnt);
112 if (!fsn_mark) 112 if (!mnt_mark)
113 return false; 113 return false;
114 114
115 send = (mask & fsn_mark->mask); 115 mask &= mnt_mark->mask;
116 mask &= ~mnt_mark->ignored_mask;
117
118 if (mask) {
119 inode_mark = fsnotify_find_inode_mark(group, inode);
120 if (inode_mark) {
121 mask &= ~inode_mark->ignored_mask;
122 fsnotify_put_mark(inode_mark);
123 }
124 }
116 125
117 /* find took a reference */ 126 /* find took a reference */
118 fsnotify_put_mark(fsn_mark); 127 fsnotify_put_mark(mnt_mark);
119 128
120 return send; 129 return mask;
121} 130}
122 131
123static bool should_send_inode_event(struct fsnotify_group *group, struct inode *inode, 132static bool should_send_inode_event(struct fsnotify_group *group, struct inode *inode,
124 __u32 mask) 133 __u32 mask)
125{ 134{
126 struct fsnotify_mark *fsn_mark; 135 struct fsnotify_mark *fsn_mark;
127 bool send;
128 136
129 pr_debug("%s: group=%p inode=%p mask=%x\n", 137 pr_debug("%s: group=%p inode=%p mask=%x\n",
130 __func__, group, inode, mask); 138 __func__, group, inode, mask);
@@ -137,20 +145,21 @@ static bool should_send_inode_event(struct fsnotify_group *group, struct inode *
137 * events on the child, don't send it! */ 145 * events on the child, don't send it! */
138 if ((mask & FS_EVENT_ON_CHILD) && 146 if ((mask & FS_EVENT_ON_CHILD) &&
139 !(fsn_mark->mask & FS_EVENT_ON_CHILD)) { 147 !(fsn_mark->mask & FS_EVENT_ON_CHILD)) {
140 send = false; 148 mask = 0;
141 } else { 149 } else {
142 /* 150 /*
143 * We care about children, but do we care about this particular 151 * We care about children, but do we care about this particular
144 * type of event? 152 * type of event?
145 */ 153 */
146 mask = (mask & ~FS_EVENT_ON_CHILD); 154 mask &= ~FS_EVENT_ON_CHILD;
147 send = (fsn_mark->mask & mask); 155 mask &= fsn_mark->mask;
156 mask &= ~fsn_mark->ignored_mask;
148 } 157 }
149 158
150 /* find took a reference */ 159 /* find took a reference */
151 fsnotify_put_mark(fsn_mark); 160 fsnotify_put_mark(fsn_mark);
152 161
153 return send; 162 return mask;
154} 163}
155 164
156static bool fanotify_should_send_event(struct fsnotify_group *group, struct inode *to_tell, 165static bool fanotify_should_send_event(struct fsnotify_group *group, struct inode *to_tell,
@@ -170,7 +179,7 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, struct inod
170 return false; 179 return false;
171 180
172 if (mnt) 181 if (mnt)
173 return should_send_vfsmount_event(group, mnt, mask); 182 return should_send_vfsmount_event(group, mnt, to_tell, mask);
174 else 183 else
175 return should_send_inode_event(group, to_tell, mask); 184 return should_send_inode_event(group, to_tell, mask);
176} 185}