diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 41 |
1 files changed, 18 insertions, 23 deletions
diff --git a/fs/namei.c b/fs/namei.c index 2826db35dc25..0b3138de2a3b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -721,31 +721,22 @@ static int follow_automount(struct path *path, unsigned flags, | |||
721 | if (!path->dentry->d_op || !path->dentry->d_op->d_automount) | 721 | if (!path->dentry->d_op || !path->dentry->d_op->d_automount) |
722 | return -EREMOTE; | 722 | return -EREMOTE; |
723 | 723 | ||
724 | /* We don't want to mount if someone supplied AT_NO_AUTOMOUNT | 724 | /* We don't want to mount if someone's just doing a stat - |
725 | * and this is the terminal part of the path. | 725 | * unless they're stat'ing a directory and appended a '/' to |
726 | * the name. | ||
727 | * | ||
728 | * We do, however, want to mount if someone wants to open or | ||
729 | * create a file of any type under the mountpoint, wants to | ||
730 | * traverse through the mountpoint or wants to open the | ||
731 | * mounted directory. Also, autofs may mark negative dentries | ||
732 | * as being automount points. These will need the attentions | ||
733 | * of the daemon to instantiate them before they can be used. | ||
726 | */ | 734 | */ |
727 | if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_PARENT)) | 735 | if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY | |
728 | return -EISDIR; /* we actually want to stop here */ | 736 | LOOKUP_OPEN | LOOKUP_CREATE | LOOKUP_AUTOMOUNT)) && |
737 | path->dentry->d_inode) | ||
738 | return -EISDIR; | ||
729 | 739 | ||
730 | /* | ||
731 | * We don't want to mount if someone's just doing a stat and they've | ||
732 | * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and | ||
733 | * appended a '/' to the name. | ||
734 | */ | ||
735 | if (!(flags & LOOKUP_FOLLOW)) { | ||
736 | /* We do, however, want to mount if someone wants to open or | ||
737 | * create a file of any type under the mountpoint, wants to | ||
738 | * traverse through the mountpoint or wants to open the mounted | ||
739 | * directory. | ||
740 | * Also, autofs may mark negative dentries as being automount | ||
741 | * points. These will need the attentions of the daemon to | ||
742 | * instantiate them before they can be used. | ||
743 | */ | ||
744 | if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY | | ||
745 | LOOKUP_OPEN | LOOKUP_CREATE)) && | ||
746 | path->dentry->d_inode) | ||
747 | return -EISDIR; | ||
748 | } | ||
749 | current->total_link_count++; | 740 | current->total_link_count++; |
750 | if (current->total_link_count >= 40) | 741 | if (current->total_link_count >= 40) |
751 | return -ELOOP; | 742 | return -ELOOP; |
@@ -2619,6 +2610,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2619 | if (!dir->i_op->rmdir) | 2610 | if (!dir->i_op->rmdir) |
2620 | return -EPERM; | 2611 | return -EPERM; |
2621 | 2612 | ||
2613 | dget(dentry); | ||
2622 | mutex_lock(&dentry->d_inode->i_mutex); | 2614 | mutex_lock(&dentry->d_inode->i_mutex); |
2623 | 2615 | ||
2624 | error = -EBUSY; | 2616 | error = -EBUSY; |
@@ -2639,6 +2631,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2639 | 2631 | ||
2640 | out: | 2632 | out: |
2641 | mutex_unlock(&dentry->d_inode->i_mutex); | 2633 | mutex_unlock(&dentry->d_inode->i_mutex); |
2634 | dput(dentry); | ||
2642 | if (!error) | 2635 | if (!error) |
2643 | d_delete(dentry); | 2636 | d_delete(dentry); |
2644 | return error; | 2637 | return error; |
@@ -3028,6 +3021,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
3028 | if (error) | 3021 | if (error) |
3029 | return error; | 3022 | return error; |
3030 | 3023 | ||
3024 | dget(new_dentry); | ||
3031 | if (target) | 3025 | if (target) |
3032 | mutex_lock(&target->i_mutex); | 3026 | mutex_lock(&target->i_mutex); |
3033 | 3027 | ||
@@ -3048,6 +3042,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
3048 | out: | 3042 | out: |
3049 | if (target) | 3043 | if (target) |
3050 | mutex_unlock(&target->i_mutex); | 3044 | mutex_unlock(&target->i_mutex); |
3045 | dput(new_dentry); | ||
3051 | if (!error) | 3046 | if (!error) |
3052 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) | 3047 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) |
3053 | d_move(old_dentry,new_dentry); | 3048 | d_move(old_dentry,new_dentry); |