]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
Pass parent directory inode and expected name to ->d_revalidate()
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 8 Dec 2024 05:28:51 +0000 (00:28 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 28 Jan 2025 00:25:23 +0000 (19:25 -0500)
->d_revalidate() often needs to access dentry parent and name; that has
to be done carefully, since the locking environment varies from caller
to caller.  We are not guaranteed that dentry in question will not be
moved right under us - not unless the filesystem is such that nothing
on it ever gets renamed.

It can be dealt with, but that results in boilerplate code that isn't
even needed - the callers normally have just found the dentry via dcache
lookup and want to verify that it's in the right place; they already
have the values of ->d_parent and ->d_name stable.  There is a couple
of exceptions (overlayfs and, to less extent, ecryptfs), but for the
majority of calls that song and dance is not needed at all.

It's easier to make ecryptfs and overlayfs find and pass those values if
there's a ->d_revalidate() instance to be called, rather than doing that
in the instances.

This commit only changes the calling conventions; making use of supplied
values is left to followups.

NOTE: some instances need more than just the parent - things like CIFS
may need to build an entire path from filesystem root, so they need
more precautions than the usual boilerplate.  This series doesn't
do anything to that need - these filesystems have to keep their locking
mechanisms (rename_lock loops, use of dentry_path_raw(), private rwsem
a-la v9fs).

One thing to keep in mind when using name is that name->name will normally
point into the pathname being resolved; the filename in question occupies
name->len bytes starting at name->name, and there is NUL somewhere after it,
but it the next byte might very well be '/' rather than '\0'.  Do not
ignore name->len.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Gabriel Krisman Bertazi <gabriel@krisman.be>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
30 files changed:
Documentation/filesystems/locking.rst
Documentation/filesystems/porting.rst
Documentation/filesystems/vfs.rst
fs/9p/vfs_dentry.c
fs/afs/dir.c
fs/ceph/dir.c
fs/coda/dir.c
fs/crypto/fname.c
fs/ecryptfs/dentry.c
fs/exfat/namei.c
fs/fat/namei_vfat.c
fs/fuse/dir.c
fs/gfs2/dentry.c
fs/hfs/sysdep.c
fs/jfs/namei.c
fs/kernfs/dir.c
fs/namei.c
fs/nfs/dir.c
fs/ocfs2/dcache.c
fs/orangefs/dcache.c
fs/overlayfs/super.c
fs/proc/base.c
fs/proc/fd.c
fs/proc/generic.c
fs/proc/proc_sysctl.c
fs/smb/client/dir.c
fs/tracefs/inode.c
fs/vboxsf/dir.c
include/linux/dcache.h
include/linux/fscrypt.h

index f5e3676db954b5bce4c23a0bf723a79d66181fcd..146e7d8aa7360b0954e618b0c3c77f5fcd5e6474 100644 (file)
@@ -17,7 +17,8 @@ dentry_operations
 
 prototypes::
 
-       int (*d_revalidate)(struct dentry *, unsigned int);
+       int (*d_revalidate)(struct inode *, const struct qstr *,
+                           struct dentry *, unsigned int);
        int (*d_weak_revalidate)(struct dentry *, unsigned int);
        int (*d_hash)(const struct dentry *, struct qstr *);
        int (*d_compare)(const struct dentry *,
index 9ab2a3d6f2b47ba2acfde51ff40d06d1c8b099bb..568e7ea3c4aea3cae4c561de709515db345f82ae 100644 (file)
@@ -1141,3 +1141,19 @@ pointer are gone.
 
 set_blocksize() takes opened struct file instead of struct block_device now
 and it *must* be opened exclusive.
+
+---
+
+** mandatory**
+
+->d_revalidate() gets two extra arguments - inode of parent directory and
+name our dentry is expected to have.  Both are stable (dir is pinned in
+non-RCU case and will stay around during the call in RCU case, and name
+is guaranteed to stay unchanging).  Your instance doesn't have to use
+either, but it often helps to avoid a lot of painful boilerplate.
+Note that while name->name is stable and NUL-terminated, it may (and
+often will) have name->name[name->len] equal to '/' rather than '\0' -
+in normal case it points into the pathname being looked up.
+NOTE: if you need something like full path from the root of filesystem,
+you are still on your own - this assists with simple cases, but it's not
+magic.
index 0b18af3f954eb75e72805a04cc486f609dd02b43..7c352ebaae9867fee901dc577f271e881bcb8bbb 100644 (file)
@@ -1251,7 +1251,8 @@ defined:
 .. code-block:: c
 
        struct dentry_operations {
-               int (*d_revalidate)(struct dentry *, unsigned int);
+               int (*d_revalidate)(struct inode *, const struct qstr *,
+                                   struct dentry *, unsigned int);
                int (*d_weak_revalidate)(struct dentry *, unsigned int);
                int (*d_hash)(const struct dentry *, struct qstr *);
                int (*d_compare)(const struct dentry *,
index 01338d4c2d9e6fde95e8e69816781ce968522ef6..872c1abe32958b7cb693761a45b0870719450fa3 100644 (file)
@@ -61,7 +61,7 @@ static void v9fs_dentry_release(struct dentry *dentry)
                p9_fid_put(hlist_entry(p, struct p9_fid, dlist));
 }
 
-static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
+static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct p9_fid *fid;
        struct inode *inode;
@@ -99,9 +99,15 @@ out_valid:
        return 1;
 }
 
+static int v9fs_lookup_revalidate(struct inode *dir, const struct qstr *name,
+                                 struct dentry *dentry, unsigned int flags)
+{
+       return __v9fs_lookup_revalidate(dentry, flags);
+}
+
 const struct dentry_operations v9fs_cached_dentry_operations = {
        .d_revalidate = v9fs_lookup_revalidate,
-       .d_weak_revalidate = v9fs_lookup_revalidate,
+       .d_weak_revalidate = __v9fs_lookup_revalidate,
        .d_delete = v9fs_cached_dentry_delete,
        .d_release = v9fs_dentry_release,
 };
index ada363af5aab8e8e1fc806327dfecae1d4ca14cb..9780013cd83aa74e7ed362c21a62c47fec0fd75c 100644 (file)
@@ -22,7 +22,8 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
                                 unsigned int flags);
 static int afs_dir_open(struct inode *inode, struct file *file);
 static int afs_readdir(struct file *file, struct dir_context *ctx);
-static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
+static int afs_d_revalidate(struct inode *dir, const struct qstr *name,
+                           struct dentry *dentry, unsigned int flags);
 static int afs_d_delete(const struct dentry *dentry);
 static void afs_d_iput(struct dentry *dentry, struct inode *inode);
 static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
@@ -1093,7 +1094,8 @@ static int afs_d_revalidate_rcu(struct dentry *dentry)
  * - NOTE! the hit can be a negative hit too, so we can't assume we have an
  *   inode
  */
-static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int afs_d_revalidate(struct inode *parent_dir, const struct qstr *name,
+                           struct dentry *dentry, unsigned int flags)
 {
        struct afs_vnode *vnode, *dir;
        struct afs_fid fid;
index 0bf388e07a0278f2d3d3815c36290919c7e3b39c..c4c71c24221b6cc2bd4bca0439e081daae46c9d6 100644 (file)
@@ -1940,7 +1940,8 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry,
 /*
  * Check if cached dentry can be trusted.
  */
-static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int ceph_d_revalidate(struct inode *parent_dir, const struct qstr *name,
+                            struct dentry *dentry, unsigned int flags)
 {
        struct ceph_mds_client *mdsc = ceph_sb_to_fs_client(dentry->d_sb)->mdsc;
        struct ceph_client *cl = mdsc->fsc->client;
@@ -1948,7 +1949,7 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
        struct dentry *parent;
        struct inode *dir, *inode;
 
-       valid = fscrypt_d_revalidate(dentry, flags);
+       valid = fscrypt_d_revalidate(parent_dir, name, dentry, flags);
        if (valid <= 0)
                return valid;
 
index 4e552ba7bd43304121fe36f217c84ebc5f88d2c3..a3e2dfeedfbf6a2185dadf13b9b556f84a026915 100644 (file)
@@ -445,7 +445,8 @@ static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
 }
 
 /* called when a cache lookup succeeds */
-static int coda_dentry_revalidate(struct dentry *de, unsigned int flags)
+static int coda_dentry_revalidate(struct inode *dir, const struct qstr *name,
+                                 struct dentry *de, unsigned int flags)
 {
        struct inode *inode;
        struct coda_inode_info *cii;
index 0ad52fbe51c944eded295196a4cd27f91301571a..389f5b2bf63b202d8fa06ed9e7f0d22b853dff71 100644 (file)
@@ -574,7 +574,8 @@ EXPORT_SYMBOL_GPL(fscrypt_fname_siphash);
  * Validate dentries in encrypted directories to make sure we aren't potentially
  * caching stale dentries after a key has been added.
  */
-int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
+int fscrypt_d_revalidate(struct inode *parent_dir, const struct qstr *name,
+                        struct dentry *dentry, unsigned int flags)
 {
        struct dentry *dir;
        int err;
index acaa0825e9bbe4645301af1f2508726f4e9a596a..1dfd5b81d83132f7aa236dafe86553035a3efba7 100644 (file)
@@ -17,7 +17,9 @@
 
 /**
  * ecryptfs_d_revalidate - revalidate an ecryptfs dentry
- * @dentry: The ecryptfs dentry
+ * @dir: inode of expected parent
+ * @name: expected name
+ * @dentry: dentry to revalidate
  * @flags: lookup flags
  *
  * Called when the VFS needs to revalidate a dentry. This
@@ -28,7 +30,8 @@
  * Returns 1 if valid, 0 otherwise.
  *
  */
-static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int ecryptfs_d_revalidate(struct inode *dir, const struct qstr *name,
+                                struct dentry *dentry, unsigned int flags)
 {
        struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
        int rc = 1;
@@ -36,8 +39,15 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
        if (flags & LOOKUP_RCU)
                return -ECHILD;
 
-       if (lower_dentry->d_flags & DCACHE_OP_REVALIDATE)
-               rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
+       if (lower_dentry->d_flags & DCACHE_OP_REVALIDATE) {
+               struct inode *lower_dir = ecryptfs_inode_to_lower(dir);
+               struct name_snapshot n;
+
+               take_dentry_name_snapshot(&n, lower_dentry);
+               rc = lower_dentry->d_op->d_revalidate(lower_dir, &n.name,
+                                                     lower_dentry, flags);
+               release_dentry_name_snapshot(&n);
+       }
 
        if (d_really_is_positive(dentry)) {
                struct inode *inode = d_inode(dentry);
index 97d2774760fe3dead731bc01c02d1764014ec0cc..e3b4feccba07737872359adeec8c183e2b2fcef4 100644 (file)
@@ -31,7 +31,8 @@ static inline void exfat_d_version_set(struct dentry *dentry,
  * If it happened, the negative dentry isn't actually negative anymore.  So,
  * drop it.
  */
-static int exfat_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int exfat_d_revalidate(struct inode *dir, const struct qstr *name,
+                             struct dentry *dentry, unsigned int flags)
 {
        int ret;
 
index 15bf32c21ac0db8b32810bf27aede68bfa2c667a..f9cbd5c6f9327739a797082f70b898c7afcc8968 100644 (file)
@@ -53,7 +53,8 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
        return ret;
 }
 
-static int vfat_revalidate(struct dentry *dentry, unsigned int flags)
+static int vfat_revalidate(struct inode *dir, const struct qstr *name,
+                          struct dentry *dentry, unsigned int flags)
 {
        if (flags & LOOKUP_RCU)
                return -ECHILD;
@@ -64,7 +65,8 @@ static int vfat_revalidate(struct dentry *dentry, unsigned int flags)
        return vfat_revalidate_shortname(dentry);
 }
 
-static int vfat_revalidate_ci(struct dentry *dentry, unsigned int flags)
+static int vfat_revalidate_ci(struct inode *dir, const struct qstr *name,
+                             struct dentry *dentry, unsigned int flags)
 {
        if (flags & LOOKUP_RCU)
                return -ECHILD;
index 494ac372ace07ab4ea06c13a404ecc1d2ccb4f23..d9e9f26917eb81b3bc55e88be450ab70a58a8852 100644 (file)
@@ -192,7 +192,8 @@ static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
  * the lookup once more.  If the lookup results in the same inode,
  * then refresh the attributes, timeouts and mark the dentry valid.
  */
-static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
+static int fuse_dentry_revalidate(struct inode *dir, const struct qstr *name,
+                                 struct dentry *entry, unsigned int flags)
 {
        struct inode *inode;
        struct dentry *parent;
index 2e215e8c3c88e57d6ed17ba6cc5cb22420e99af6..86c338901fab56745aeaa22f05f0febb78ed8940 100644 (file)
@@ -21,7 +21,9 @@
 
 /**
  * gfs2_drevalidate - Check directory lookup consistency
- * @dentry: the mapping to check
+ * @dir: expected parent directory inode
+ * @name: expexted name
+ * @dentry: dentry to check
  * @flags: lookup flags
  *
  * Check to make sure the lookup necessary to arrive at this inode from its
@@ -30,7 +32,8 @@
  * Returns: 1 if the dentry is ok, 0 if it isn't
  */
 
-static int gfs2_drevalidate(struct dentry *dentry, unsigned int flags)
+static int gfs2_drevalidate(struct inode *dir, const struct qstr *name,
+                           struct dentry *dentry, unsigned int flags)
 {
        struct dentry *parent;
        struct gfs2_sbd *sdp;
index 76fa02e3835bf07b8329f0c2de9111a0a143a288..ef54fc8093cf31689eb7c73f418cc9782774e551 100644 (file)
@@ -13,7 +13,8 @@
 
 /* dentry case-handling: just lowercase everything */
 
-static int hfs_revalidate_dentry(struct dentry *dentry, unsigned int flags)
+static int hfs_revalidate_dentry(struct inode *dir, const struct qstr *name,
+                                struct dentry *dentry, unsigned int flags)
 {
        struct inode *inode;
        int diff;
index d68a4e6ac3454406780db6445834126440b69f6b..fc8ede43afde8ef5ad080e7e607660f9df85a9cc 100644 (file)
@@ -1576,7 +1576,8 @@ out:
        return result;
 }
 
-static int jfs_ci_revalidate(struct dentry *dentry, unsigned int flags)
+static int jfs_ci_revalidate(struct inode *dir, const struct qstr *name,
+                            struct dentry *dentry, unsigned int flags)
 {
        /*
         * This is not negative dentry. Always valid.
index 458519e416fe75e97cc454a716d29c06b3586b56..5f0f8b95f44c0caef3397010b21637e0fbfa1a38 100644 (file)
@@ -1109,7 +1109,8 @@ struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
        return ERR_PTR(rc);
 }
 
-static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
+static int kernfs_dop_revalidate(struct inode *dir, const struct qstr *name,
+                                struct dentry *dentry, unsigned int flags)
 {
        struct kernfs_node *kn;
        struct kernfs_root *root;
index 9d30c7aa9aa6e760b5ad4bda7e458ad823c2b3ef..77e5d136faaf1e72b56a6902b5b81f0aac2ffe87 100644 (file)
@@ -921,10 +921,11 @@ out_dput:
        return false;
 }
 
-static inline int d_revalidate(struct dentry *dentry, unsigned int flags)
+static inline int d_revalidate(struct inode *dir, const struct qstr *name,
+                              struct dentry *dentry, unsigned int flags)
 {
        if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE))
-               return dentry->d_op->d_revalidate(dentry, flags);
+               return dentry->d_op->d_revalidate(dir, name, dentry, flags);
        else
                return 1;
 }
@@ -1652,7 +1653,7 @@ static struct dentry *lookup_dcache(const struct qstr *name,
 {
        struct dentry *dentry = d_lookup(dir, name);
        if (dentry) {
-               int error = d_revalidate(dentry, flags);
+               int error = d_revalidate(dir->d_inode, name, dentry, flags);
                if (unlikely(error <= 0)) {
                        if (!error)
                                d_invalidate(dentry);
@@ -1737,19 +1738,20 @@ static struct dentry *lookup_fast(struct nameidata *nd)
                if (read_seqcount_retry(&parent->d_seq, nd->seq))
                        return ERR_PTR(-ECHILD);
 
-               status = d_revalidate(dentry, nd->flags);
+               status = d_revalidate(nd->inode, &nd->last, dentry, nd->flags);
                if (likely(status > 0))
                        return dentry;
                if (!try_to_unlazy_next(nd, dentry))
                        return ERR_PTR(-ECHILD);
                if (status == -ECHILD)
                        /* we'd been told to redo it in non-rcu mode */
-                       status = d_revalidate(dentry, nd->flags);
+                       status = d_revalidate(nd->inode, &nd->last,
+                                             dentry, nd->flags);
        } else {
                dentry = __d_lookup(parent, &nd->last);
                if (unlikely(!dentry))
                        return NULL;
-               status = d_revalidate(dentry, nd->flags);
+               status = d_revalidate(nd->inode, &nd->last, dentry, nd->flags);
        }
        if (unlikely(status <= 0)) {
                if (!status)
@@ -1777,7 +1779,7 @@ again:
        if (IS_ERR(dentry))
                return dentry;
        if (unlikely(!d_in_lookup(dentry))) {
-               int error = d_revalidate(dentry, flags);
+               int error = d_revalidate(inode, name, dentry, flags);
                if (unlikely(error <= 0)) {
                        if (!error) {
                                d_invalidate(dentry);
@@ -3575,7 +3577,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
                if (d_in_lookup(dentry))
                        break;
 
-               error = d_revalidate(dentry, nd->flags);
+               error = d_revalidate(dir_inode, &nd->last, dentry, nd->flags);
                if (likely(error > 0))
                        break;
                if (error)
index 492cffd9d3d845723b5f3d0eea3874b1f1773fe1..9910d9796f4c3adcc309f63fff20d270cebd3852 100644 (file)
@@ -1814,7 +1814,8 @@ __nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags,
        return ret;
 }
 
-static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
+static int nfs_lookup_revalidate(struct inode *dir, const struct qstr *name,
+                                struct dentry *dentry, unsigned int flags)
 {
        return __nfs_lookup_revalidate(dentry, flags, nfs_do_lookup_revalidate);
 }
@@ -2025,7 +2026,8 @@ void nfs_d_prune_case_insensitive_aliases(struct inode *inode)
 EXPORT_SYMBOL_GPL(nfs_d_prune_case_insensitive_aliases);
 
 #if IS_ENABLED(CONFIG_NFS_V4)
-static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
+static int nfs4_lookup_revalidate(struct inode *, const struct qstr *,
+                                 struct dentry *, unsigned int);
 
 const struct dentry_operations nfs4_dentry_operations = {
        .d_revalidate   = nfs4_lookup_revalidate,
@@ -2260,7 +2262,8 @@ full_reval:
        return nfs_do_lookup_revalidate(dir, dentry, flags);
 }
 
-static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
+static int nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name,
+                                 struct dentry *dentry, unsigned int flags)
 {
        return __nfs_lookup_revalidate(dentry, flags,
                        nfs4_do_lookup_revalidate);
index a9b8688aaf30d75e32b5fbec663abcfb8c8dafda..ecb1ce6301c4dd06575ddde0b7a4433e668a8e0f 100644 (file)
@@ -32,7 +32,8 @@ void ocfs2_dentry_attach_gen(struct dentry *dentry)
 }
 
 
-static int ocfs2_dentry_revalidate(struct dentry *dentry, unsigned int flags)
+static int ocfs2_dentry_revalidate(struct inode *dir, const struct qstr *name,
+                                  struct dentry *dentry, unsigned int flags)
 {
        struct inode *inode;
        int ret = 0;    /* if all else fails, just return false */
index 395a00ed8ac75f64b6a4c122ff843689b42f6cac..c32c9a86e8d094a0ccb2f9db07eefb09d6daef8b 100644 (file)
@@ -92,7 +92,8 @@ out_drop:
  *
  * Should return 1 if dentry can still be trusted, else 0.
  */
-static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int orangefs_d_revalidate(struct inode *dir, const struct qstr *name,
+                                struct dentry *dentry, unsigned int flags)
 {
        int ret;
        unsigned long time = (unsigned long) dentry->d_fsdata;
index fe511192f83cb0dd6b60f9078be64e38bc271c5c..86ae6f6da36b68e65652a8baa0fab8e6f8d63336 100644 (file)
@@ -91,7 +91,24 @@ static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak)
                if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE)
                        ret =  d->d_op->d_weak_revalidate(d, flags);
        } else if (d->d_flags & DCACHE_OP_REVALIDATE) {
-               ret = d->d_op->d_revalidate(d, flags);
+               struct dentry *parent;
+               struct inode *dir;
+               struct name_snapshot n;
+
+               if (flags & LOOKUP_RCU) {
+                       parent = READ_ONCE(d->d_parent);
+                       dir = d_inode_rcu(parent);
+                       if (!dir)
+                               return -ECHILD;
+               } else {
+                       parent = dget_parent(d);
+                       dir = d_inode(parent);
+               }
+               take_dentry_name_snapshot(&n, d);
+               ret = d->d_op->d_revalidate(dir, &n.name, d, flags);
+               release_dentry_name_snapshot(&n);
+               if (!(flags & LOOKUP_RCU))
+                       dput(parent);
                if (!ret) {
                        if (!(flags & LOOKUP_RCU))
                                d_invalidate(d);
@@ -127,7 +144,8 @@ static int ovl_dentry_revalidate_common(struct dentry *dentry,
        return ret;
 }
 
-static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags)
+static int ovl_dentry_revalidate(struct inode *dir, const struct qstr *name,
+                                struct dentry *dentry, unsigned int flags)
 {
        return ovl_dentry_revalidate_common(dentry, flags, false);
 }
index 0edf14a9840ef9420e76f80f614df8fea6112d9a..fb5493d0edf02fe2d13e1550ff94ddcd5af8d08f 100644 (file)
@@ -2058,7 +2058,8 @@ void pid_update_inode(struct task_struct *task, struct inode *inode)
  * performed a setuid(), etc.
  *
  */
-static int pid_revalidate(struct dentry *dentry, unsigned int flags)
+static int pid_revalidate(struct inode *dir, const struct qstr *name,
+                         struct dentry *dentry, unsigned int flags)
 {
        struct inode *inode;
        struct task_struct *task;
@@ -2191,7 +2192,8 @@ static int dname_to_vma_addr(struct dentry *dentry,
        return 0;
 }
 
-static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int map_files_d_revalidate(struct inode *dir, const struct qstr *name,
+                                 struct dentry *dentry, unsigned int flags)
 {
        unsigned long vm_start, vm_end;
        bool exact_vma_exists = false;
index 24baf23e864f73eb1fe477909be67e83b1be0973..37aa778d1af7bffa8ccbb55ead82dcad82c0dccf 100644 (file)
@@ -140,7 +140,8 @@ static void tid_fd_update_inode(struct task_struct *task, struct inode *inode,
        security_task_to_inode(task, inode);
 }
 
-static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
+static int tid_fd_revalidate(struct inode *dir, const struct qstr *name,
+                            struct dentry *dentry, unsigned int flags)
 {
        struct task_struct *task;
        struct inode *inode;
index dbe82cf23ee49c98eb12c7bd6869482a69da82d3..8ec90826a49e9e5ff98e180568e6e625318fb4e9 100644 (file)
@@ -216,7 +216,8 @@ void proc_free_inum(unsigned int inum)
        ida_free(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
 }
 
-static int proc_misc_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int proc_misc_d_revalidate(struct inode *dir, const struct qstr *name,
+                                 struct dentry *dentry, unsigned int flags)
 {
        if (flags & LOOKUP_RCU)
                return -ECHILD;
@@ -343,7 +344,8 @@ static const struct file_operations proc_dir_operations = {
        .iterate_shared         = proc_readdir,
 };
 
-static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int proc_net_d_revalidate(struct inode *dir, const struct qstr *name,
+                                struct dentry *dentry, unsigned int flags)
 {
        return 0;
 }
index 27a283d85a6e7df1a7edbfb513ce75832363e2e6..cc9d74a06ff03c14413091579f62f8f4cdec0f62 100644 (file)
@@ -884,7 +884,8 @@ static const struct inode_operations proc_sys_dir_operations = {
        .getattr        = proc_sys_getattr,
 };
 
-static int proc_sys_revalidate(struct dentry *dentry, unsigned int flags)
+static int proc_sys_revalidate(struct inode *dir, const struct qstr *name,
+                              struct dentry *dentry, unsigned int flags)
 {
        if (flags & LOOKUP_RCU)
                return -ECHILD;
index 864b194dbaa0a0bffc3cecac0a3c9fd4ccc9b7a4..8c5d44ee91edfff6513020266f6e62c6f3bdbe3e 100644 (file)
@@ -737,7 +737,8 @@ again:
 }
 
 static int
-cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
+cifs_d_revalidate(struct inode *dir, const struct qstr *name,
+                 struct dentry *direntry, unsigned int flags)
 {
        struct inode *inode;
        int rc;
index cfc614c638daf60620b3d58e1047087f53289540..53214499e384b14dfbf75b7de07def6f3b242dbc 100644 (file)
@@ -457,7 +457,8 @@ static void tracefs_d_release(struct dentry *dentry)
                eventfs_d_release(dentry);
 }
 
-static int tracefs_d_revalidate(struct dentry *dentry, unsigned int flags)
+static int tracefs_d_revalidate(struct inode *inode, const struct qstr *name,
+                               struct dentry *dentry, unsigned int flags)
 {
        struct eventfs_inode *ei = dentry->d_fsdata;
 
index 5f1a14d5b92731d63514c92ac9761ec90e4eb32a..a859ac9b74ba0acea641b73131c51e623bca36ca 100644 (file)
@@ -192,7 +192,8 @@ const struct file_operations vboxsf_dir_fops = {
  * This is called during name resolution/lookup to check if the @dentry in
  * the cache is still valid. the job is handled by vboxsf_inode_revalidate.
  */
-static int vboxsf_dentry_revalidate(struct dentry *dentry, unsigned int flags)
+static int vboxsf_dentry_revalidate(struct inode *dir, const struct qstr *name,
+                                   struct dentry *dentry, unsigned int flags)
 {
        if (flags & LOOKUP_RCU)
                return -ECHILD;
index 8bc567a35718f4481cd1a89854011fb5c0995572..4a6bdadf2f298951fb3ca6b690c3237c454a5ed0 100644 (file)
@@ -144,7 +144,8 @@ enum d_real_type {
 };
 
 struct dentry_operations {
-       int (*d_revalidate)(struct dentry *, unsigned int);
+       int (*d_revalidate)(struct inode *, const struct qstr *,
+                           struct dentry *, unsigned int);
        int (*d_weak_revalidate)(struct dentry *, unsigned int);
        int (*d_hash)(const struct dentry *, struct qstr *);
        int (*d_compare)(const struct dentry *,
index 772f822dc6b82e92903e030b0d5c35512ffc9f55..18855cb44b1c84db81d1a84c72c3b39e6f7c307c 100644 (file)
@@ -192,7 +192,8 @@ struct fscrypt_operations {
                                             unsigned int *num_devs);
 };
 
-int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags);
+int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name,
+                        struct dentry *dentry, unsigned int flags);
 
 static inline struct fscrypt_inode_info *
 fscrypt_get_inode_info(const struct inode *inode)
@@ -711,8 +712,8 @@ static inline u64 fscrypt_fname_siphash(const struct inode *dir,
        return 0;
 }
 
-static inline int fscrypt_d_revalidate(struct dentry *dentry,
-                                      unsigned int flags)
+static inline int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name,
+                                      struct dentry *dentry, unsigned int flags)
 {
        return 1;
 }