[XFS] Fix regression introduced by remount fixup
[pandora-kernel.git] / fs / inotify_user.c
index 6676c06..6024942 100644 (file)
@@ -354,20 +354,20 @@ static void inotify_dev_event_dequeue(struct inotify_device *dev)
 }
 
 /*
- * find_inode - resolve a user-given path to a specific inode and return a nd
+ * find_inode - resolve a user-given path to a specific inode
  */
-static int find_inode(const char __user *dirname, struct nameidata *nd,
+static int find_inode(const char __user *dirname, struct path *path,
                      unsigned flags)
 {
        int error;
 
-       error = __user_walk(dirname, flags, nd);
+       error = user_path_at(AT_FDCWD, dirname, flags, path);
        if (error)
                return error;
        /* you can only watch an inode if you have read permissions on it */
-       error = vfs_permission(nd, MAY_READ);
+       error = inode_permission(path->dentry->d_inode, MAY_READ);
        if (error)
-               path_put(&nd->path);
+               path_put(path);
        return error;
 }
 
@@ -566,7 +566,7 @@ static const struct inotify_operations inotify_user_ops = {
        .destroy_watch  = free_inotify_user_watch,
 };
 
-asmlinkage long sys_inotify_init(void)
+asmlinkage long sys_inotify_init1(int flags)
 {
        struct inotify_device *dev;
        struct inotify_handle *ih;
@@ -574,7 +574,14 @@ asmlinkage long sys_inotify_init(void)
        struct file *filp;
        int fd, ret;
 
-       fd = get_unused_fd();
+       /* Check the IN_* constants for consistency.  */
+       BUILD_BUG_ON(IN_CLOEXEC != O_CLOEXEC);
+       BUILD_BUG_ON(IN_NONBLOCK != O_NONBLOCK);
+
+       if (flags & ~(IN_CLOEXEC | IN_NONBLOCK))
+               return -EINVAL;
+
+       fd = get_unused_fd_flags(flags & O_CLOEXEC);
        if (fd < 0)
                return fd;
 
@@ -610,7 +617,7 @@ asmlinkage long sys_inotify_init(void)
        filp->f_path.dentry = dget(inotify_mnt->mnt_root);
        filp->f_mapping = filp->f_path.dentry->d_inode->i_mapping;
        filp->f_mode = FMODE_READ;
-       filp->f_flags = O_RDONLY;
+       filp->f_flags = O_RDONLY | (flags & O_NONBLOCK);
        filp->private_data = dev;
 
        INIT_LIST_HEAD(&dev->events);
@@ -638,11 +645,16 @@ out_put_fd:
        return ret;
 }
 
-asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
+asmlinkage long sys_inotify_init(void)
+{
+       return sys_inotify_init1(0);
+}
+
+asmlinkage long sys_inotify_add_watch(int fd, const char __user *pathname, u32 mask)
 {
        struct inode *inode;
        struct inotify_device *dev;
-       struct nameidata nd;
+       struct path path;
        struct file *filp;
        int ret, fput_needed;
        unsigned flags = 0;
@@ -662,12 +674,12 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
        if (mask & IN_ONLYDIR)
                flags |= LOOKUP_DIRECTORY;
 
-       ret = find_inode(path, &nd, flags);
+       ret = find_inode(pathname, &path, flags);
        if (unlikely(ret))
                goto fput_and_out;
 
-       /* inode held in place by reference to nd; dev by fget on fd */
-       inode = nd.path.dentry->d_inode;
+       /* inode held in place by reference to path; dev by fget on fd */
+       inode = path.dentry->d_inode;
        dev = filp->private_data;
 
        mutex_lock(&dev->up_mutex);
@@ -676,7 +688,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_put(&nd.path);
+       path_put(&path);
 fput_and_out:
        fput_light(filp, fput_needed);
        return ret;