aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/fanotify/fanotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify/fanotify/fanotify.c')
-rw-r--r--fs/notify/fanotify/fanotify.c63
1 files changed, 45 insertions, 18 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index dc638f786d5c..ee9cb3795c2b 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -60,8 +60,8 @@ static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
60} 60}
61 61
62#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 62#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
63static int fanotify_get_response_from_access(struct fsnotify_group *group, 63static int fanotify_get_response(struct fsnotify_group *group,
64 struct fanotify_event_info *event) 64 struct fanotify_perm_event_info *event)
65{ 65{
66 int ret; 66 int ret;
67 67
@@ -142,6 +142,40 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
142 return false; 142 return false;
143} 143}
144 144
145struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask,
146 struct path *path)
147{
148 struct fanotify_event_info *event;
149
150#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
151 if (mask & FAN_ALL_PERM_EVENTS) {
152 struct fanotify_perm_event_info *pevent;
153
154 pevent = kmem_cache_alloc(fanotify_perm_event_cachep,
155 GFP_KERNEL);
156 if (!pevent)
157 return NULL;
158 event = &pevent->fae;
159 pevent->response = 0;
160 goto init;
161 }
162#endif
163 event = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL);
164 if (!event)
165 return NULL;
166init: __maybe_unused
167 fsnotify_init_event(&event->fse, inode, mask);
168 event->tgid = get_pid(task_tgid(current));
169 if (path) {
170 event->path = *path;
171 path_get(&event->path);
172 } else {
173 event->path.mnt = NULL;
174 event->path.dentry = NULL;
175 }
176 return event;
177}
178
145static int fanotify_handle_event(struct fsnotify_group *group, 179static int fanotify_handle_event(struct fsnotify_group *group,
146 struct inode *inode, 180 struct inode *inode,
147 struct fsnotify_mark *inode_mark, 181 struct fsnotify_mark *inode_mark,
@@ -171,25 +205,11 @@ static int fanotify_handle_event(struct fsnotify_group *group,
171 pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode, 205 pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
172 mask); 206 mask);
173 207
174 event = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL); 208 event = fanotify_alloc_event(inode, mask, data);
175 if (unlikely(!event)) 209 if (unlikely(!event))
176 return -ENOMEM; 210 return -ENOMEM;
177 211
178 fsn_event = &event->fse; 212 fsn_event = &event->fse;
179 fsnotify_init_event(fsn_event, inode, mask);
180 event->tgid = get_pid(task_tgid(current));
181 if (data_type == FSNOTIFY_EVENT_PATH) {
182 struct path *path = data;
183 event->path = *path;
184 path_get(&event->path);
185 } else {
186 event->path.mnt = NULL;
187 event->path.dentry = NULL;
188 }
189#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
190 event->response = 0;
191#endif
192
193 ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge); 213 ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge);
194 if (ret) { 214 if (ret) {
195 /* Permission events shouldn't be merged */ 215 /* Permission events shouldn't be merged */
@@ -202,7 +222,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
202 222
203#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 223#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
204 if (mask & FAN_ALL_PERM_EVENTS) { 224 if (mask & FAN_ALL_PERM_EVENTS) {
205 ret = fanotify_get_response_from_access(group, event); 225 ret = fanotify_get_response(group, FANOTIFY_PE(fsn_event));
206 fsnotify_destroy_event(group, fsn_event); 226 fsnotify_destroy_event(group, fsn_event);
207 } 227 }
208#endif 228#endif
@@ -225,6 +245,13 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event)
225 event = FANOTIFY_E(fsn_event); 245 event = FANOTIFY_E(fsn_event);
226 path_put(&event->path); 246 path_put(&event->path);
227 put_pid(event->tgid); 247 put_pid(event->tgid);
248#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
249 if (fsn_event->mask & FAN_ALL_PERM_EVENTS) {
250 kmem_cache_free(fanotify_perm_event_cachep,
251 FANOTIFY_PE(fsn_event));
252 return;
253 }
254#endif
228 kmem_cache_free(fanotify_event_cachep, event); 255 kmem_cache_free(fanotify_event_cachep, event);
229} 256}
230 257