vfs: add d_canonical_path for stacked filesystem support
authorDaniel Rosenberg <drosen@google.com>
Fri, 12 Feb 2016 00:44:15 +0000 (16:44 -0800)
committerStricted <info@stricted.net>
Thu, 11 Oct 2018 16:03:56 +0000 (18:03 +0200)
Inotify does not currently know when a filesystem
is acting as a wrapper around another fs. This means
that inotify watchers will miss any modifications to
the base file, as well as any made in a separate
stacked fs that points to the same file.
d_canonical_path solves this problem by allowing the fs
to map a dentry to a path in the lower fs. Inotify
can use it to find the appropriate place to watch to
be informed of all changes to a file.

Change-Id: I09563baffad1711a045e45c1bd0bd8713c2cc0b6
Signed-off-by: Daniel Rosenberg <drosen@google.com>
fs/notify/inotify/inotify_user.c
include/linux/dcache.h

index 941e59d7ffe7f86eb20bed7f9b6ec8a8929cf81d..dac2dbfcef43d649ab7796ce74109e5c8fea08f2 100644 (file)
@@ -770,7 +770,7 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
        /* 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);
+                       path.dentry->d_op->d_canonical_path(path.dentry, &alteredpath);
                        canonical_path = &alteredpath;
                        path_put(&path);
                }
@@ -849,7 +849,7 @@ static int __init inotify_user_setup(void)
        BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
        BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
 
-       BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
+       BUG_ON(hweight32(ALL_INOTIFY_BITS) != 22);
 
        inotify_inode_mark_cachep = KMEM_CACHE(inotify_inode_mark, SLAB_PANIC);
        event_priv_cachep = KMEM_CACHE(inotify_event_private_data, SLAB_PANIC);
index 0ab0ed8bdaa2d186d018ba9952623a65e2f7a8b2..22c77df4001fc3388cfb8d72996393230c30080b 100644 (file)
@@ -158,7 +158,7 @@ struct dentry_operations {
        char *(*d_dname)(struct dentry *, char *, int);
        struct vfsmount *(*d_automount)(struct path *);
        int (*d_manage)(struct dentry *, bool);
-       void (*d_canonical_path)(const struct path *, struct path *);
+       void (*d_canonical_path)(const struct dentry *, struct path *);
 } ____cacheline_aligned;
 
 /*