Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
[firefly-linux-kernel-4.4.55.git] / fs / notify / inotify / inotify_user.c
index b8d08d0d0a4dbe061b9336dd7f861d32e13c8618..4c5b43d15e6e06d8ef9137f138809ee16280cc43 100644 (file)
@@ -337,7 +337,7 @@ static int inotify_find_inode(const char __user *dirname, struct path *path, uns
        if (error)
                return error;
        /* you can only watch an inode if you have read permissions on it */
-       error = inode_permission(path->dentry->d_inode, MAY_READ);
+       error = inode_permission2(path->mnt, path->dentry->d_inode, MAY_READ);
        if (error)
                path_put(path);
        return error;
@@ -702,6 +702,8 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
        struct fsnotify_group *group;
        struct inode *inode;
        struct path path;
+       struct path alteredpath;
+       struct path *canonical_path = &path;
        struct fd f;
        int ret;
        unsigned flags = 0;
@@ -741,13 +743,22 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
        if (ret)
                goto fput_and_out;
 
+       /* support stacked filesystems */
+       if(path.dentry && path.dentry->d_op) {
+               if (path.dentry->d_op->d_canonical_path) {
+                       path.dentry->d_op->d_canonical_path(&path, &alteredpath);
+                       canonical_path = &alteredpath;
+                       path_put(&path);
+               }
+       }
+
        /* inode held in place by reference to path; group by fget on fd */
-       inode = path.dentry->d_inode;
+       inode = canonical_path->dentry->d_inode;
        group = f.file->private_data;
 
        /* create/update an inode mark */
        ret = inotify_update_watch(group, inode, mask);
-       path_put(&path);
+       path_put(canonical_path);
 fput_and_out:
        fdput(f);
        return ret;