Skip to content

Commit 1d2ef59

Browse files
Al Virotorvalds
Al Viro
authored andcommitted
restore pinning the victim dentry in vfs_rmdir()/vfs_rename_dir()
We used to get the victim pinned by dentry_unhash() prior to commit 64252c7 ("vfs: remove dget() from dentry_unhash()") and ->rmdir() and ->rename() instances relied on that; most of them don't care, but ones that used d_delete() themselves do. As the result, we are getting rmdir() oopses on NFS now. Just grab the reference before locking the victim and drop it explicitly after unlocking, same as vfs_rename_other() does. Signed-off-by: Al Viro <[email protected]> Tested-by: Simon Kirby <[email protected]> Cc: [email protected] (3.0.x) Signed-off-by: Linus Torvalds <[email protected]>
1 parent 003f6c9 commit 1d2ef59

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

fs/namei.c

+4
Original file line numberDiff line numberDiff line change
@@ -2616,6 +2616,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
26162616
if (!dir->i_op->rmdir)
26172617
return -EPERM;
26182618

2619+
dget(dentry);
26192620
mutex_lock(&dentry->d_inode->i_mutex);
26202621

26212622
error = -EBUSY;
@@ -2636,6 +2637,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
26362637

26372638
out:
26382639
mutex_unlock(&dentry->d_inode->i_mutex);
2640+
dput(dentry);
26392641
if (!error)
26402642
d_delete(dentry);
26412643
return error;
@@ -3025,6 +3027,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
30253027
if (error)
30263028
return error;
30273029

3030+
dget(new_dentry);
30283031
if (target)
30293032
mutex_lock(&target->i_mutex);
30303033

@@ -3045,6 +3048,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
30453048
out:
30463049
if (target)
30473050
mutex_unlock(&target->i_mutex);
3051+
dput(new_dentry);
30483052
if (!error)
30493053
if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
30503054
d_move(old_dentry,new_dentry);

0 commit comments

Comments
 (0)