diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/namei.c b/fs/namei.c index 16df7277a92e..b86b96fe1dc3 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2176,8 +2176,10 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2176 | error = security_inode_rmdir(dir, dentry); | 2176 | error = security_inode_rmdir(dir, dentry); |
2177 | if (!error) { | 2177 | if (!error) { |
2178 | error = dir->i_op->rmdir(dir, dentry); | 2178 | error = dir->i_op->rmdir(dir, dentry); |
2179 | if (!error) | 2179 | if (!error) { |
2180 | dentry->d_inode->i_flags |= S_DEAD; | 2180 | dentry->d_inode->i_flags |= S_DEAD; |
2181 | dont_mount(dentry); | ||
2182 | } | ||
2181 | } | 2183 | } |
2182 | } | 2184 | } |
2183 | mutex_unlock(&dentry->d_inode->i_mutex); | 2185 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -2261,7 +2263,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2261 | if (!error) { | 2263 | if (!error) { |
2262 | error = dir->i_op->unlink(dir, dentry); | 2264 | error = dir->i_op->unlink(dir, dentry); |
2263 | if (!error) | 2265 | if (!error) |
2264 | dentry->d_inode->i_flags |= S_DEAD; | 2266 | dont_mount(dentry); |
2265 | } | 2267 | } |
2266 | } | 2268 | } |
2267 | mutex_unlock(&dentry->d_inode->i_mutex); | 2269 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -2572,17 +2574,20 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
2572 | return error; | 2574 | return error; |
2573 | 2575 | ||
2574 | target = new_dentry->d_inode; | 2576 | target = new_dentry->d_inode; |
2575 | if (target) { | 2577 | if (target) |
2576 | mutex_lock(&target->i_mutex); | 2578 | mutex_lock(&target->i_mutex); |
2577 | dentry_unhash(new_dentry); | ||
2578 | } | ||
2579 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | 2579 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
2580 | error = -EBUSY; | 2580 | error = -EBUSY; |
2581 | else | 2581 | else { |
2582 | if (target) | ||
2583 | dentry_unhash(new_dentry); | ||
2582 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | 2584 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
2585 | } | ||
2583 | if (target) { | 2586 | if (target) { |
2584 | if (!error) | 2587 | if (!error) { |
2585 | target->i_flags |= S_DEAD; | 2588 | target->i_flags |= S_DEAD; |
2589 | dont_mount(new_dentry); | ||
2590 | } | ||
2586 | mutex_unlock(&target->i_mutex); | 2591 | mutex_unlock(&target->i_mutex); |
2587 | if (d_unhashed(new_dentry)) | 2592 | if (d_unhashed(new_dentry)) |
2588 | d_rehash(new_dentry); | 2593 | d_rehash(new_dentry); |
@@ -2614,7 +2619,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | |||
2614 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | 2619 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
2615 | if (!error) { | 2620 | if (!error) { |
2616 | if (target) | 2621 | if (target) |
2617 | target->i_flags |= S_DEAD; | 2622 | dont_mount(new_dentry); |
2618 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) | 2623 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) |
2619 | d_move(old_dentry, new_dentry); | 2624 | d_move(old_dentry, new_dentry); |
2620 | } | 2625 | } |