diff options
author | Eric Paris <eparis@redhat.com> | 2009-12-17 21:24:28 -0500 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2010-07-28 09:58:57 -0400 |
commit | 1c529063a3e4c15eaae28db31326a7aaab7091b5 (patch) | |
tree | 100a27418becd6c23eeb1b7c4426fea006d6bfd6 /fs/notify/fanotify/fanotify.c | |
parent | ca9c726eea013394d1e846331b117effb21ead83 (diff) |
fanotify: should_send_event needs to handle vfsmounts
currently should_send_event in fanotify only cares about marks on inodes.
This patch extends that interface to indicate that it cares about events
that happened on vfsmounts.
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs/notify/fanotify/fanotify.c')
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index aa5e92661142..202be8adb2ec 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/fsnotify_backend.h> | 2 | #include <linux/fsnotify_backend.h> |
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/kernel.h> /* UINT_MAX */ | 4 | #include <linux/kernel.h> /* UINT_MAX */ |
5 | #include <linux/mount.h> | ||
5 | #include <linux/types.h> | 6 | #include <linux/types.h> |
6 | 7 | ||
7 | #include "fanotify.h" | 8 | #include "fanotify.h" |
@@ -99,24 +100,35 @@ static int fanotify_handle_event(struct fsnotify_group *group, struct fsnotify_e | |||
99 | return ret; | 100 | return ret; |
100 | } | 101 | } |
101 | 102 | ||
102 | static bool fanotify_should_send_event(struct fsnotify_group *group, struct inode *inode, | 103 | static bool should_send_vfsmount_event(struct fsnotify_group *group, struct vfsmount *mnt, |
103 | struct vfsmount *mnt, __u32 mask, void *data, | 104 | __u32 mask) |
104 | int data_type) | ||
105 | { | 105 | { |
106 | struct fsnotify_mark *fsn_mark; | 106 | struct fsnotify_mark *fsn_mark; |
107 | bool send; | 107 | bool send; |
108 | 108 | ||
109 | pr_debug("%s: group=%p inode=%p mask=%x data=%p data_type=%d\n", | 109 | pr_debug("%s: group=%p vfsmount=%p mask=%x\n", |
110 | __func__, group, inode, mask, data, data_type); | 110 | __func__, group, mnt, mask); |
111 | 111 | ||
112 | /* sorry, fanotify only gives a damn about files and dirs */ | 112 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); |
113 | if (!S_ISREG(inode->i_mode) && | 113 | if (!fsn_mark) |
114 | !S_ISDIR(inode->i_mode)) | ||
115 | return false; | 114 | return false; |
116 | 115 | ||
117 | /* if we don't have enough info to send an event to userspace say no */ | 116 | send = (mask & fsn_mark->mask); |
118 | if (data_type != FSNOTIFY_EVENT_PATH) | 117 | |
119 | return false; | 118 | /* find took a reference */ |
119 | fsnotify_put_mark(fsn_mark); | ||
120 | |||
121 | return send; | ||
122 | } | ||
123 | |||
124 | static bool should_send_inode_event(struct fsnotify_group *group, struct inode *inode, | ||
125 | __u32 mask) | ||
126 | { | ||
127 | struct fsnotify_mark *fsn_mark; | ||
128 | bool send; | ||
129 | |||
130 | pr_debug("%s: group=%p inode=%p mask=%x\n", | ||
131 | __func__, group, inode, mask); | ||
120 | 132 | ||
121 | fsn_mark = fsnotify_find_inode_mark(group, inode); | 133 | fsn_mark = fsnotify_find_inode_mark(group, inode); |
122 | if (!fsn_mark) | 134 | if (!fsn_mark) |
@@ -142,6 +154,28 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, struct inod | |||
142 | return send; | 154 | return send; |
143 | } | 155 | } |
144 | 156 | ||
157 | static bool fanotify_should_send_event(struct fsnotify_group *group, struct inode *to_tell, | ||
158 | struct vfsmount *mnt, __u32 mask, void *data, | ||
159 | int data_type) | ||
160 | { | ||
161 | pr_debug("%s: group=%p to_tell=%p mnt=%p mask=%x data=%p data_type=%d\n", | ||
162 | __func__, group, to_tell, mnt, mask, data, data_type); | ||
163 | |||
164 | /* sorry, fanotify only gives a damn about files and dirs */ | ||
165 | if (!S_ISREG(to_tell->i_mode) && | ||
166 | !S_ISDIR(to_tell->i_mode)) | ||
167 | return false; | ||
168 | |||
169 | /* if we don't have enough info to send an event to userspace say no */ | ||
170 | if (data_type != FSNOTIFY_EVENT_PATH) | ||
171 | return false; | ||
172 | |||
173 | if (mnt) | ||
174 | return should_send_vfsmount_event(group, mnt, mask); | ||
175 | else | ||
176 | return should_send_inode_event(group, to_tell, mask); | ||
177 | } | ||
178 | |||
145 | const struct fsnotify_ops fanotify_fsnotify_ops = { | 179 | const struct fsnotify_ops fanotify_fsnotify_ops = { |
146 | .handle_event = fanotify_handle_event, | 180 | .handle_event = fanotify_handle_event, |
147 | .should_send_event = fanotify_should_send_event, | 181 | .should_send_event = fanotify_should_send_event, |