diff options
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 4 | ||||
-rw-r--r-- | fs/notify/group.c | 7 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 13 | ||||
-rw-r--r-- | fs/notify/notification.c | 1 | ||||
-rw-r--r-- | include/linux/fsnotify_backend.h | 5 |
5 files changed, 20 insertions, 10 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 1218d10424d0..f0e7a57bc899 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -414,6 +414,10 @@ static int fanotify_release(struct inode *ignored, struct file *file) | |||
414 | 414 | ||
415 | wake_up(&group->fanotify_data.access_waitq); | 415 | wake_up(&group->fanotify_data.access_waitq); |
416 | #endif | 416 | #endif |
417 | |||
418 | if (file->f_flags & FASYNC) | ||
419 | fsnotify_fasync(-1, file, 0); | ||
420 | |||
417 | /* matches the fanotify_init->fsnotify_alloc_group */ | 421 | /* matches the fanotify_init->fsnotify_alloc_group */ |
418 | fsnotify_destroy_group(group); | 422 | fsnotify_destroy_group(group); |
419 | 423 | ||
diff --git a/fs/notify/group.c b/fs/notify/group.c index 1f7305711fc9..bd2625bd88b4 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c | |||
@@ -102,3 +102,10 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) | |||
102 | 102 | ||
103 | return group; | 103 | return group; |
104 | } | 104 | } |
105 | |||
106 | int fsnotify_fasync(int fd, struct file *file, int on) | ||
107 | { | ||
108 | struct fsnotify_group *group = file->private_data; | ||
109 | |||
110 | return fasync_helper(fd, file, on, &group->fsn_fa) >= 0 ? 0 : -EIO; | ||
111 | } | ||
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 00ff82ff7c9f..68f7bec1e664 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -280,19 +280,15 @@ static ssize_t inotify_read(struct file *file, char __user *buf, | |||
280 | return ret; | 280 | return ret; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int inotify_fasync(int fd, struct file *file, int on) | ||
284 | { | ||
285 | struct fsnotify_group *group = file->private_data; | ||
286 | |||
287 | return fasync_helper(fd, file, on, &group->inotify_data.fa) >= 0 ? 0 : -EIO; | ||
288 | } | ||
289 | |||
290 | static int inotify_release(struct inode *ignored, struct file *file) | 283 | static int inotify_release(struct inode *ignored, struct file *file) |
291 | { | 284 | { |
292 | struct fsnotify_group *group = file->private_data; | 285 | struct fsnotify_group *group = file->private_data; |
293 | 286 | ||
294 | pr_debug("%s: group=%p\n", __func__, group); | 287 | pr_debug("%s: group=%p\n", __func__, group); |
295 | 288 | ||
289 | if (file->f_flags & FASYNC) | ||
290 | fsnotify_fasync(-1, file, 0); | ||
291 | |||
296 | /* free this group, matching get was inotify_init->fsnotify_obtain_group */ | 292 | /* free this group, matching get was inotify_init->fsnotify_obtain_group */ |
297 | fsnotify_destroy_group(group); | 293 | fsnotify_destroy_group(group); |
298 | 294 | ||
@@ -335,7 +331,7 @@ static long inotify_ioctl(struct file *file, unsigned int cmd, | |||
335 | static const struct file_operations inotify_fops = { | 331 | static const struct file_operations inotify_fops = { |
336 | .poll = inotify_poll, | 332 | .poll = inotify_poll, |
337 | .read = inotify_read, | 333 | .read = inotify_read, |
338 | .fasync = inotify_fasync, | 334 | .fasync = fsnotify_fasync, |
339 | .release = inotify_release, | 335 | .release = inotify_release, |
340 | .unlocked_ioctl = inotify_ioctl, | 336 | .unlocked_ioctl = inotify_ioctl, |
341 | .compat_ioctl = inotify_ioctl, | 337 | .compat_ioctl = inotify_ioctl, |
@@ -706,7 +702,6 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events) | |||
706 | spin_lock_init(&group->inotify_data.idr_lock); | 702 | spin_lock_init(&group->inotify_data.idr_lock); |
707 | idr_init(&group->inotify_data.idr); | 703 | idr_init(&group->inotify_data.idr); |
708 | group->inotify_data.last_wd = 0; | 704 | group->inotify_data.last_wd = 0; |
709 | group->inotify_data.fa = NULL; | ||
710 | group->inotify_data.user = get_current_user(); | 705 | group->inotify_data.user = get_current_user(); |
711 | 706 | ||
712 | if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > | 707 | if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > |
diff --git a/fs/notify/notification.c b/fs/notify/notification.c index c887b1378f7e..b3963d8c9988 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
@@ -225,6 +225,7 @@ alloc_holder: | |||
225 | mutex_unlock(&group->notification_mutex); | 225 | mutex_unlock(&group->notification_mutex); |
226 | 226 | ||
227 | wake_up(&group->notification_waitq); | 227 | wake_up(&group->notification_waitq); |
228 | kill_fasync(&group->fsn_fa, SIGIO, POLL_IN); | ||
228 | return return_event; | 229 | return return_event; |
229 | } | 230 | } |
230 | 231 | ||
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 1af2f6a722c0..d5b0910d4961 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -148,6 +148,8 @@ struct fsnotify_group { | |||
148 | * a group */ | 148 | * a group */ |
149 | struct list_head marks_list; /* all inode marks for this group */ | 149 | struct list_head marks_list; /* all inode marks for this group */ |
150 | 150 | ||
151 | struct fasync_struct *fsn_fa; /* async notification */ | ||
152 | |||
151 | /* groups can define private fields here or use the void *private */ | 153 | /* groups can define private fields here or use the void *private */ |
152 | union { | 154 | union { |
153 | void *private; | 155 | void *private; |
@@ -156,7 +158,6 @@ struct fsnotify_group { | |||
156 | spinlock_t idr_lock; | 158 | spinlock_t idr_lock; |
157 | struct idr idr; | 159 | struct idr idr; |
158 | u32 last_wd; | 160 | u32 last_wd; |
159 | struct fasync_struct *fa; /* async notification */ | ||
160 | struct user_struct *user; | 161 | struct user_struct *user; |
161 | } inotify_data; | 162 | } inotify_data; |
162 | #endif | 163 | #endif |
@@ -368,6 +369,8 @@ extern void fsnotify_get_group(struct fsnotify_group *group); | |||
368 | extern void fsnotify_put_group(struct fsnotify_group *group); | 369 | extern void fsnotify_put_group(struct fsnotify_group *group); |
369 | /* destroy group */ | 370 | /* destroy group */ |
370 | extern void fsnotify_destroy_group(struct fsnotify_group *group); | 371 | extern void fsnotify_destroy_group(struct fsnotify_group *group); |
372 | /* fasync handler function */ | ||
373 | extern int fsnotify_fasync(int fd, struct file *file, int on); | ||
371 | /* take a reference to an event */ | 374 | /* take a reference to an event */ |
372 | extern void fsnotify_get_event(struct fsnotify_event *event); | 375 | extern void fsnotify_get_event(struct fsnotify_event *event); |
373 | extern void fsnotify_put_event(struct fsnotify_event *event); | 376 | extern void fsnotify_put_event(struct fsnotify_event *event); |