summaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2019-01-10 12:04:31 -0500
committerJan Kara <jack@suse.cz>2019-02-06 09:25:11 -0500
commita0a92d261f2922f4b5d2c0a98d6c41a89c7f5edd (patch)
tree958b51acde8238d308c2ca0986feeb95dc1fd864 /fs/notify
parent45a9fb3725d8868a9b4192afd1a1f2bff1cc5ffb (diff)
fsnotify: move mask out of struct fsnotify_event
Common fsnotify_event helpers have no need for the mask field. It is only used by backend code, so move the field out of the abstract fsnotify_event struct and into the concrete backend event structs. This change packs struct inotify_event_info better on 64bit machine and will allow us to cram some more fields into struct fanotify_event_info. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fanotify/fanotify.c11
-rw-r--r--fs/notify/fanotify/fanotify.h1
-rw-r--r--fs/notify/fanotify/fanotify_user.c10
-rw-r--r--fs/notify/inotify/inotify.h1
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c9
-rw-r--r--fs/notify/inotify/inotify_user.c5
-rw-r--r--fs/notify/notification.c22
7 files changed, 23 insertions, 36 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 3723f3d18d20..98197802bbfb 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -36,20 +36,22 @@ static bool should_merge(struct fsnotify_event *old_fsn,
36static int fanotify_merge(struct list_head *list, struct fsnotify_event *event) 36static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
37{ 37{
38 struct fsnotify_event *test_event; 38 struct fsnotify_event *test_event;
39 struct fanotify_event_info *new;
39 40
40 pr_debug("%s: list=%p event=%p\n", __func__, list, event); 41 pr_debug("%s: list=%p event=%p\n", __func__, list, event);
42 new = FANOTIFY_E(event);
41 43
42 /* 44 /*
43 * Don't merge a permission event with any other event so that we know 45 * Don't merge a permission event with any other event so that we know
44 * the event structure we have created in fanotify_handle_event() is the 46 * the event structure we have created in fanotify_handle_event() is the
45 * one we should check for permission response. 47 * one we should check for permission response.
46 */ 48 */
47 if (fanotify_is_perm_event(event->mask)) 49 if (fanotify_is_perm_event(new->mask))
48 return 0; 50 return 0;
49 51
50 list_for_each_entry_reverse(test_event, list, list) { 52 list_for_each_entry_reverse(test_event, list, list) {
51 if (should_merge(test_event, event)) { 53 if (should_merge(test_event, event)) {
52 test_event->mask |= event->mask; 54 FANOTIFY_E(test_event)->mask |= new->mask;
53 return 1; 55 return 1;
54 } 56 }
55 } 57 }
@@ -173,7 +175,8 @@ struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
173 if (!event) 175 if (!event)
174 goto out; 176 goto out;
175init: __maybe_unused 177init: __maybe_unused
176 fsnotify_init_event(&event->fse, inode, mask); 178 fsnotify_init_event(&event->fse, inode);
179 event->mask = mask;
177 if (FAN_GROUP_FLAG(group, FAN_REPORT_TID)) 180 if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
178 event->pid = get_pid(task_pid(current)); 181 event->pid = get_pid(task_pid(current));
179 else 182 else
@@ -280,7 +283,7 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event)
280 event = FANOTIFY_E(fsn_event); 283 event = FANOTIFY_E(fsn_event);
281 path_put(&event->path); 284 path_put(&event->path);
282 put_pid(event->pid); 285 put_pid(event->pid);
283 if (fanotify_is_perm_event(fsn_event->mask)) { 286 if (fanotify_is_perm_event(event->mask)) {
284 kmem_cache_free(fanotify_perm_event_cachep, 287 kmem_cache_free(fanotify_perm_event_cachep,
285 FANOTIFY_PE(fsn_event)); 288 FANOTIFY_PE(fsn_event));
286 return; 289 return;
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index ea05b8a401e7..e630d787d4c3 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -14,6 +14,7 @@ extern struct kmem_cache *fanotify_perm_event_cachep;
14 */ 14 */
15struct fanotify_event_info { 15struct fanotify_event_info {
16 struct fsnotify_event fse; 16 struct fsnotify_event fse;
17 u32 mask;
17 /* 18 /*
18 * We hold ref to this path so it may be dereferenced at any point 19 * We hold ref to this path so it may be dereferenced at any point
19 * during this object's lifetime 20 * during this object's lifetime
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 9c870b0d2b56..dea47d07cc29 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -131,9 +131,9 @@ static int fill_event_metadata(struct fsnotify_group *group,
131 metadata->metadata_len = FAN_EVENT_METADATA_LEN; 131 metadata->metadata_len = FAN_EVENT_METADATA_LEN;
132 metadata->vers = FANOTIFY_METADATA_VERSION; 132 metadata->vers = FANOTIFY_METADATA_VERSION;
133 metadata->reserved = 0; 133 metadata->reserved = 0;
134 metadata->mask = fsn_event->mask & FANOTIFY_OUTGOING_EVENTS; 134 metadata->mask = event->mask & FANOTIFY_OUTGOING_EVENTS;
135 metadata->pid = pid_vnr(event->pid); 135 metadata->pid = pid_vnr(event->pid);
136 if (unlikely(fsn_event->mask & FAN_Q_OVERFLOW)) 136 if (unlikely(event->mask & FAN_Q_OVERFLOW))
137 metadata->fd = FAN_NOFD; 137 metadata->fd = FAN_NOFD;
138 else { 138 else {
139 metadata->fd = create_fd(group, event, file); 139 metadata->fd = create_fd(group, event, file);
@@ -230,7 +230,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
230 fanotify_event_metadata.event_len)) 230 fanotify_event_metadata.event_len))
231 goto out_close_fd; 231 goto out_close_fd;
232 232
233 if (fanotify_is_perm_event(event->mask)) 233 if (fanotify_is_perm_event(FANOTIFY_E(event)->mask))
234 FANOTIFY_PE(event)->fd = fd; 234 FANOTIFY_PE(event)->fd = fd;
235 235
236 if (fd != FAN_NOFD) 236 if (fd != FAN_NOFD)
@@ -316,7 +316,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
316 * Permission events get queued to wait for response. Other 316 * Permission events get queued to wait for response. Other
317 * events can be destroyed now. 317 * events can be destroyed now.
318 */ 318 */
319 if (!fanotify_is_perm_event(kevent->mask)) { 319 if (!fanotify_is_perm_event(FANOTIFY_E(kevent)->mask)) {
320 fsnotify_destroy_event(group, kevent); 320 fsnotify_destroy_event(group, kevent);
321 } else { 321 } else {
322 if (ret <= 0) { 322 if (ret <= 0) {
@@ -401,7 +401,7 @@ static int fanotify_release(struct inode *ignored, struct file *file)
401 */ 401 */
402 while (!fsnotify_notify_queue_is_empty(group)) { 402 while (!fsnotify_notify_queue_is_empty(group)) {
403 fsn_event = fsnotify_remove_first_event(group); 403 fsn_event = fsnotify_remove_first_event(group);
404 if (!(fsn_event->mask & FANOTIFY_PERM_EVENTS)) { 404 if (!(FANOTIFY_E(fsn_event)->mask & FANOTIFY_PERM_EVENTS)) {
405 spin_unlock(&group->notification_lock); 405 spin_unlock(&group->notification_lock);
406 fsnotify_destroy_event(group, fsn_event); 406 fsnotify_destroy_event(group, fsn_event);
407 spin_lock(&group->notification_lock); 407 spin_lock(&group->notification_lock);
diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h
index 7e4578d35b61..74ae60305189 100644
--- a/fs/notify/inotify/inotify.h
+++ b/fs/notify/inotify/inotify.h
@@ -5,6 +5,7 @@
5 5
6struct inotify_event_info { 6struct inotify_event_info {
7 struct fsnotify_event fse; 7 struct fsnotify_event fse;
8 u32 mask;
8 int wd; 9 int wd;
9 u32 sync_cookie; 10 u32 sync_cookie;
10 int name_len; 11 int name_len;
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index f4184b4f3815..fe97299975f2 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -43,11 +43,11 @@ static bool event_compare(struct fsnotify_event *old_fsn,
43{ 43{
44 struct inotify_event_info *old, *new; 44 struct inotify_event_info *old, *new;
45 45
46 if (old_fsn->mask & FS_IN_IGNORED)
47 return false;
48 old = INOTIFY_E(old_fsn); 46 old = INOTIFY_E(old_fsn);
49 new = INOTIFY_E(new_fsn); 47 new = INOTIFY_E(new_fsn);
50 if ((old_fsn->mask == new_fsn->mask) && 48 if (old->mask & FS_IN_IGNORED)
49 return false;
50 if ((old->mask == new->mask) &&
51 (old_fsn->inode == new_fsn->inode) && 51 (old_fsn->inode == new_fsn->inode) &&
52 (old->name_len == new->name_len) && 52 (old->name_len == new->name_len) &&
53 (!old->name_len || !strcmp(old->name, new->name))) 53 (!old->name_len || !strcmp(old->name, new->name)))
@@ -114,7 +114,8 @@ int inotify_handle_event(struct fsnotify_group *group,
114 } 114 }
115 115
116 fsn_event = &event->fse; 116 fsn_event = &event->fse;
117 fsnotify_init_event(fsn_event, inode, mask); 117 fsnotify_init_event(fsn_event, inode);
118 event->mask = mask;
118 event->wd = i_mark->wd; 119 event->wd = i_mark->wd;
119 event->sync_cookie = cookie; 120 event->sync_cookie = cookie;
120 event->name_len = len; 121 event->name_len = len;
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 798f1253141a..e2901fbb9f76 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -189,7 +189,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
189 */ 189 */
190 pad_name_len = round_event_name_len(fsn_event); 190 pad_name_len = round_event_name_len(fsn_event);
191 inotify_event.len = pad_name_len; 191 inotify_event.len = pad_name_len;
192 inotify_event.mask = inotify_mask_to_arg(fsn_event->mask); 192 inotify_event.mask = inotify_mask_to_arg(event->mask);
193 inotify_event.wd = event->wd; 193 inotify_event.wd = event->wd;
194 inotify_event.cookie = event->sync_cookie; 194 inotify_event.cookie = event->sync_cookie;
195 195
@@ -634,7 +634,8 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events)
634 return ERR_PTR(-ENOMEM); 634 return ERR_PTR(-ENOMEM);
635 } 635 }
636 group->overflow_event = &oevent->fse; 636 group->overflow_event = &oevent->fse;
637 fsnotify_init_event(group->overflow_event, NULL, FS_Q_OVERFLOW); 637 fsnotify_init_event(group->overflow_event, NULL);
638 oevent->mask = FS_Q_OVERFLOW;
638 oevent->wd = -1; 639 oevent->wd = -1;
639 oevent->sync_cookie = 0; 640 oevent->sync_cookie = 0;
640 oevent->name_len = 0; 641 oevent->name_len = 0;
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index 3c3e36745f59..027d5d5bb90e 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -71,7 +71,7 @@ void fsnotify_destroy_event(struct fsnotify_group *group,
71 struct fsnotify_event *event) 71 struct fsnotify_event *event)
72{ 72{
73 /* Overflow events are per-group and we don't want to free them */ 73 /* Overflow events are per-group and we don't want to free them */
74 if (!event || event->mask == FS_Q_OVERFLOW) 74 if (!event || event == group->overflow_event)
75 return; 75 return;
76 /* 76 /*
77 * If the event is still queued, we have a problem... Do an unreliable 77 * If the event is still queued, we have a problem... Do an unreliable
@@ -194,23 +194,3 @@ void fsnotify_flush_notify(struct fsnotify_group *group)
194 } 194 }
195 spin_unlock(&group->notification_lock); 195 spin_unlock(&group->notification_lock);
196} 196}
197
198/*
199 * fsnotify_create_event - Allocate a new event which will be sent to each
200 * group's handle_event function if the group was interested in this
201 * particular event.
202 *
203 * @inode the inode which is supposed to receive the event (sometimes a
204 * parent of the inode to which the event happened.
205 * @mask what actually happened.
206 * @data pointer to the object which was actually affected
207 * @data_type flag indication if the data is a file, path, inode, nothing...
208 * @name the filename, if available
209 */
210void fsnotify_init_event(struct fsnotify_event *event, struct inode *inode,
211 u32 mask)
212{
213 INIT_LIST_HEAD(&event->list);
214 event->inode = inode;
215 event->mask = mask;
216}