Merge branch 'work.rmdir' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 4 Jun 2018 16:53:33 +0000 (09:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 4 Jun 2018 16:53:33 +0000 (09:53 -0700)
Pull rmdir update from Al Viro:
 "More shrink_dcache_parent()-related stuff - killing the main source of
  potentially contended calls of that on large subtrees"

* 'work.rmdir' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  rmdir(),rename(): do shrink_dcache_parent() only on success

fs/namei.c

index 4eb9169..9666e5e 100644 (file)
@@ -3852,11 +3852,11 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
        if (error)
                goto out;
 
-       shrink_dcache_parent(dentry);
        error = dir->i_op->rmdir(dir, dentry);
        if (error)
                goto out;
 
+       shrink_dcache_parent(dentry);
        dentry->d_inode->i_flags |= S_DEAD;
        dont_mount(dentry);
        detach_mounts(dentry);
@@ -4439,8 +4439,6 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                    old_dir->i_nlink >= max_links)
                        goto out;
        }
-       if (is_dir && !(flags & RENAME_EXCHANGE) && target)
-               shrink_dcache_parent(new_dentry);
        if (!is_dir) {
                error = try_break_deleg(source, delegated_inode);
                if (error)
@@ -4457,8 +4455,10 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                goto out;
 
        if (!(flags & RENAME_EXCHANGE) && target) {
-               if (is_dir)
+               if (is_dir) {
+                       shrink_dcache_parent(new_dentry);
                        target->i_flags |= S_DEAD;
+               }
                dont_mount(new_dentry);
                detach_mounts(new_dentry);
        }