Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.25-rc8 /fs/inotify_user.c

Filename:/fs/inotify_user.c
Lines Added:35
Lines Deleted:8
Also changed in: (Previous) 2.6.25-rc7  2.6.25-rc6  2.6.25-rc5  2.6.25-rc4  2.6.25-rc3  2.6.25-rc2 
(Following) 2.6.25-rc9  2.6.25  2.6.25-git14  2.6.25-git15  2.6.25-git16  2.6.25-git17 

Location
[  2.6.25-rc8
  [  fs
     o  inotify_user.c

Patch

diff --git a/fs/inotify_user.c b/fs/inotify_user.c
index 5e00933..7b94a1e 100644
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -41,9 +41,9 @@ static struct kmem_cache *event_cachep __read_mostly;
 static struct vfsmount *inotify_mnt __read_mostly;
 
 /* these are configurable via /proc/sys/fs/inotify/ */
-int inotify_max_user_instances __read_mostly;
-int inotify_max_user_watches __read_mostly;
-int inotify_max_queued_events __read_mostly;
+static int inotify_max_user_instances __read_mostly;
+static int inotify_max_user_watches __read_mostly;
+static int inotify_max_queued_events __read_mostly;
 
 /*
  * Lock ordering:
@@ -79,6 +79,7 @@ struct inotify_device {
    atomic_t      count;      /* reference count */
    struct user_struct   *user;      /* user who opened this dev */
    struct inotify_handle   *ih;      /* inotify handle */
+   struct fasync_struct    *fa;            /* async notification */
    unsigned int      queue_size;   /* size of the queue (bytes) */
    unsigned int      event_count;   /* number of pending events */
    unsigned int      max_events;   /* maximum number of events */
@@ -248,6 +249,19 @@ inotify_dev_get_event(struct inotify_device *dev)
 }
 
 /*
+ * inotify_dev_get_last_event - return the last event in the given dev's queue
+ *
+ * Caller must hold dev->ev_mutex.
+ */
+static inline struct inotify_kernel_event *
+inotify_dev_get_last_event(struct inotify_device *dev)
+{
+   if (list_empty(&dev->events))
+      return NULL;
+   return list_entry(dev->events.prev, struct inotify_kernel_event, list);
+}
+
+/*
  * inotify_dev_queue_event - event handler registered with core inotify, adds
  * a new event to the given device
  *
@@ -269,11 +283,11 @@ static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask,
    /* we can safely put the watch as we don't reference it while
     * generating the event
     */
-   if (mask & IN_IGNORED || mask & IN_ONESHOT)
+   if (mask & IN_IGNORED || w->mask & IN_ONESHOT)
       put_inotify_watch(w); /* final put */
 
    /* coalescing: drop this event if it is a dupe of the previous */
-   last = inotify_dev_get_event(dev);
+   last = inotify_dev_get_last_event(dev);
    if (last && last->event.mask == mask && last->event.wd == wd &&
          last->event.cookie == cookie) {
       const char *lastname = last->name;
@@ -302,6 +316,7 @@ static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask,
    dev->queue_size += sizeof(struct inotify_event) + kevent->event.len;
    list_add_tail(&kevent->list, &dev->events);
    wake_up_interruptible(&dev->wq);
+   kill_fasync(&dev->fa, SIGIO, POLL_IN);
 
 out:
    mutex_unlock(&dev->ev_mutex);
@@ -352,7 +367,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd,
    /* you can only watch an inode if you have read permissions on it */
    error = vfs_permission(nd, MAY_READ);
    if (error)
-      path_release(nd);
+      path_put(&nd->path);
    return error;
 }
 
@@ -490,6 +505,13 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
    return ret;
 }
 
+static int inotify_fasync(int fd, struct file *file, int on)
+{
+   struct inotify_device *dev = file->private_data;
+
+   return fasync_helper(fd, file, on, &dev->fa) >= 0 ? 0 : -EIO;
+}
+
 static int inotify_release(struct inode *ignored, struct file *file)
 {
    struct inotify_device *dev = file->private_data;
@@ -502,6 +524,9 @@ static int inotify_release(struct inode *ignored, struct file *file)
       inotify_dev_event_dequeue(dev);
    mutex_unlock(&dev->ev_mutex);
 
+   if (file->f_flags & FASYNC)
+      inotify_fasync(-1, file, 0);
+
    /* free this device: the put matching the get in inotify_init() */
    put_inotify_dev(dev);
 
@@ -530,6 +555,7 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
 static const struct file_operations inotify_fops = {
    .poll           = inotify_poll,
    .read           = inotify_read,
+   .fasync         = inotify_fasync,
    .release        = inotify_release,
    .unlocked_ioctl = inotify_ioctl,
    .compat_ioctl   = inotify_ioctl,
@@ -577,6 +603,7 @@ asmlinkage long sys_inotify_init(void)
       goto out_free_dev;
    }
    dev->ih = ih;
+   dev->fa = NULL;
 
    filp->f_op = &inotify_fops;
    filp->f_path.mnt = mntget(inotify_mnt);
@@ -640,7 +667,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
       goto fput_and_out;
 
    /* inode held in place by reference to nd; dev by fget on fd */
-   inode = nd.dentry->d_inode;
+   inode = nd.path.dentry->d_inode;
    dev = filp->private_data;
 
    mutex_lock(&dev->up_mutex);
@@ -649,7 +676,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
       ret = create_watch(dev, inode, mask);
    mutex_unlock(&dev->up_mutex);
 
-   path_release(&nd);
+   path_put(&nd.path);
 fput_and_out:
    fput_light(filp, fput_needed);
    return ret;


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.