aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/inotify_user.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/inotify_user.c b/fs/inotify_user.c
index c509a817068f..a336c9709f3c 100644
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -79,6 +79,7 @@ struct inotify_device {
79 atomic_t count; /* reference count */ 79 atomic_t count; /* reference count */
80 struct user_struct *user; /* user who opened this dev */ 80 struct user_struct *user; /* user who opened this dev */
81 struct inotify_handle *ih; /* inotify handle */ 81 struct inotify_handle *ih; /* inotify handle */
82 struct fasync_struct *fa; /* async notification */
82 unsigned int queue_size; /* size of the queue (bytes) */ 83 unsigned int queue_size; /* size of the queue (bytes) */
83 unsigned int event_count; /* number of pending events */ 84 unsigned int event_count; /* number of pending events */
84 unsigned int max_events; /* maximum number of events */ 85 unsigned int max_events; /* maximum number of events */
@@ -315,6 +316,7 @@ static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask,
315 dev->queue_size += sizeof(struct inotify_event) + kevent->event.len; 316 dev->queue_size += sizeof(struct inotify_event) + kevent->event.len;
316 list_add_tail(&kevent->list, &dev->events); 317 list_add_tail(&kevent->list, &dev->events);
317 wake_up_interruptible(&dev->wq); 318 wake_up_interruptible(&dev->wq);
319 kill_fasync(&dev->fa, SIGIO, POLL_IN);
318 320
319out: 321out:
320 mutex_unlock(&dev->ev_mutex); 322 mutex_unlock(&dev->ev_mutex);
@@ -503,6 +505,13 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
503 return ret; 505 return ret;
504} 506}
505 507
508static int inotify_fasync(int fd, struct file *file, int on)
509{
510 struct inotify_device *dev = file->private_data;
511
512 return fasync_helper(fd, file, on, &dev->fa) >= 0 ? 0 : -EIO;
513}
514
506static int inotify_release(struct inode *ignored, struct file *file) 515static int inotify_release(struct inode *ignored, struct file *file)
507{ 516{
508 struct inotify_device *dev = file->private_data; 517 struct inotify_device *dev = file->private_data;
@@ -515,6 +524,9 @@ static int inotify_release(struct inode *ignored, struct file *file)
515 inotify_dev_event_dequeue(dev); 524 inotify_dev_event_dequeue(dev);
516 mutex_unlock(&dev->ev_mutex); 525 mutex_unlock(&dev->ev_mutex);
517 526
527 if (file->f_flags & FASYNC)
528 inotify_fasync(-1, file, 0);
529
518 /* free this device: the put matching the get in inotify_init() */ 530 /* free this device: the put matching the get in inotify_init() */
519 put_inotify_dev(dev); 531 put_inotify_dev(dev);
520 532
@@ -543,6 +555,7 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
543static const struct file_operations inotify_fops = { 555static const struct file_operations inotify_fops = {
544 .poll = inotify_poll, 556 .poll = inotify_poll,
545 .read = inotify_read, 557 .read = inotify_read,
558 .fasync = inotify_fasync,
546 .release = inotify_release, 559 .release = inotify_release,
547 .unlocked_ioctl = inotify_ioctl, 560 .unlocked_ioctl = inotify_ioctl,
548 .compat_ioctl = inotify_ioctl, 561 .compat_ioctl = inotify_ioctl,
@@ -590,6 +603,7 @@ asmlinkage long sys_inotify_init(void)
590 goto out_free_dev; 603 goto out_free_dev;
591 } 604 }
592 dev->ih = ih; 605 dev->ih = ih;
606 dev->fa = NULL;
593 607
594 filp->f_op = &inotify_fops; 608 filp->f_op = &inotify_fops;
595 filp->f_path.mnt = mntget(inotify_mnt); 609 filp->f_path.mnt = mntget(inotify_mnt);