diff options
Diffstat (limited to 'fs/fat')
-rw-r--r-- | fs/fat/namei_vfat.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 6df8d3d885e5..b8b92c2f9683 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -736,7 +736,12 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
736 | } | 736 | } |
737 | 737 | ||
738 | alias = d_find_alias(inode); | 738 | alias = d_find_alias(inode); |
739 | if (alias && !vfat_d_anon_disconn(alias)) { | 739 | /* |
740 | * Checking "alias->d_parent == dentry->d_parent" to make sure | ||
741 | * FS is not corrupted (especially double linked dir). | ||
742 | */ | ||
743 | if (alias && alias->d_parent == dentry->d_parent && | ||
744 | !vfat_d_anon_disconn(alias)) { | ||
740 | /* | 745 | /* |
741 | * This inode has non anonymous-DCACHE_DISCONNECTED | 746 | * This inode has non anonymous-DCACHE_DISCONNECTED |
742 | * dentry. This means, the user did ->lookup() by an | 747 | * dentry. This means, the user did ->lookup() by an |
@@ -755,12 +760,9 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
755 | 760 | ||
756 | out: | 761 | out: |
757 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 762 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
758 | dentry->d_time = dentry->d_parent->d_inode->i_version; | 763 | if (!inode) |
759 | dentry = d_splice_alias(inode, dentry); | 764 | dentry->d_time = dir->i_version; |
760 | if (dentry) | 765 | return d_splice_alias(inode, dentry); |
761 | dentry->d_time = dentry->d_parent->d_inode->i_version; | ||
762 | return dentry; | ||
763 | |||
764 | error: | 766 | error: |
765 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 767 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
766 | return ERR_PTR(err); | 768 | return ERR_PTR(err); |
@@ -793,7 +795,6 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
793 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; | 795 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; |
794 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ | 796 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ |
795 | 797 | ||
796 | dentry->d_time = dentry->d_parent->d_inode->i_version; | ||
797 | d_instantiate(dentry, inode); | 798 | d_instantiate(dentry, inode); |
798 | out: | 799 | out: |
799 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 800 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
@@ -824,6 +825,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) | |||
824 | clear_nlink(inode); | 825 | clear_nlink(inode); |
825 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; | 826 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; |
826 | fat_detach(inode); | 827 | fat_detach(inode); |
828 | dentry->d_time = dir->i_version; | ||
827 | out: | 829 | out: |
828 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 830 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
829 | 831 | ||
@@ -849,6 +851,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry) | |||
849 | clear_nlink(inode); | 851 | clear_nlink(inode); |
850 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; | 852 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; |
851 | fat_detach(inode); | 853 | fat_detach(inode); |
854 | dentry->d_time = dir->i_version; | ||
852 | out: | 855 | out: |
853 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 856 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
854 | 857 | ||
@@ -889,7 +892,6 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
889 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; | 892 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; |
890 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ | 893 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ |
891 | 894 | ||
892 | dentry->d_time = dentry->d_parent->d_inode->i_version; | ||
893 | d_instantiate(dentry, inode); | 895 | d_instantiate(dentry, inode); |
894 | 896 | ||
895 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 897 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |