cifs: switch to ->iterate_shared()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 20 Apr 2016 21:40:47 +0000 (17:40 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 2 May 2016 23:49:31 +0000 (19:49 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/cifs/cifsfs.c
fs/cifs/readdir.c

index 8920156..aadb593 100644 (file)
@@ -1083,7 +1083,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
 };
 
 const struct file_operations cifs_dir_ops = {
-       .iterate = cifs_readdir,
+       .iterate_shared = cifs_readdir,
        .release = cifs_closedir,
        .read    = generic_read_dir,
        .unlocked_ioctl  = cifs_ioctl,
index 4cfb4d9..867439c 100644 (file)
@@ -80,18 +80,32 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
        struct inode *inode;
        struct super_block *sb = parent->d_sb;
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
 
        cifs_dbg(FYI, "%s: for %s\n", __func__, name->name);
 
        dentry = d_hash_and_lookup(parent, name);
+       if (!dentry) {
+               /*
+                * If we know that the inode will need to be revalidated
+                * immediately, then don't create a new dentry for it.
+                * We'll end up doing an on the wire call either way and
+                * this spares us an invalidation.
+                */
+               if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
+                       return;
+retry:
+               dentry = d_alloc_parallel(parent, name, &wq);
+       }
        if (IS_ERR(dentry))
                return;
-
-       if (dentry) {
+       if (!d_in_lookup(dentry)) {
                inode = d_inode(dentry);
                if (inode) {
-                       if (d_mountpoint(dentry))
-                               goto out;
+                       if (d_mountpoint(dentry)) {
+                               dput(dentry);
+                               return;
+                       }
                        /*
                         * If we're generating inode numbers, then we don't
                         * want to clobber the existing one with the one that
@@ -106,33 +120,22 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
                            (inode->i_mode & S_IFMT) ==
                            (fattr->cf_mode & S_IFMT)) {
                                cifs_fattr_to_inode(inode, fattr);
-                               goto out;
+                               dput(dentry);
+                               return;
                        }
                }
                d_invalidate(dentry);
                dput(dentry);
+               goto retry;
+       } else {
+               inode = cifs_iget(sb, fattr);
+               if (!inode)
+                       inode = ERR_PTR(-ENOMEM);
+               alias = d_splice_alias(inode, dentry);
+               d_lookup_done(dentry);
+               if (alias && !IS_ERR(alias))
+                       dput(alias);
        }
-
-       /*
-        * If we know that the inode will need to be revalidated immediately,
-        * then don't create a new dentry for it. We'll end up doing an on
-        * the wire call either way and this spares us an invalidation.
-        */
-       if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
-               return;
-
-       dentry = d_alloc(parent, name);
-       if (!dentry)
-               return;
-
-       inode = cifs_iget(sb, fattr);
-       if (!inode)
-               goto out;
-
-       alias = d_splice_alias(inode, dentry);
-       if (alias && !IS_ERR(alias))
-               dput(alias);
-out:
        dput(dentry);
 }