From: OGAWA Hirofumi Current vfat_lookup() creates negetive dentry blindly if vfat_find() returned a error. It's wrong. If the error isn't -ENOENT, just return error. Signed-off-by: OGAWA Hirofumi Signed-off-by: Andrew Morton --- fs/fat/namei_vfat.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff -puN fs/fat/namei_vfat.c~vfat-fix-vfat_find-error-path-in-vfat_lookup fs/fat/namei_vfat.c --- a/fs/fat/namei_vfat.c~vfat-fix-vfat_find-error-path-in-vfat_lookup +++ a/fs/fat/namei_vfat.c @@ -683,7 +683,7 @@ static struct dentry *vfat_lookup(struct { struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; - struct inode *inode = NULL; + struct inode *inode; struct dentry *alias; int err, table; @@ -693,14 +693,18 @@ static struct dentry *vfat_lookup(struct err = vfat_find(dir, &dentry->d_name, &sinfo); if (err) { - table++; + if (err == -ENOENT) { + table++; + inode = NULL; + goto out; + } goto error; } inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); if (IS_ERR(inode)) { - unlock_super(sb); - return ERR_CAST(inode); + err = PTR_ERR(inode); + goto error; } alias = d_find_alias(inode); if (alias) { @@ -713,7 +717,7 @@ static struct dentry *vfat_lookup(struct } } -error: +out: unlock_super(sb); dentry->d_op = &vfat_dentry_ops[table]; dentry->d_time = dentry->d_parent->d_inode->i_version; @@ -723,6 +727,10 @@ error: dentry->d_time = dentry->d_parent->d_inode->i_version; } return dentry; + +error: + unlock_super(sb); + return ERR_PTR(err); } static int vfat_create(struct inode *dir, struct dentry *dentry, int mode, _