diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2008-11-06 15:53:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-06 18:41:21 -0500 |
commit | 068f5ae05c51d2cee6b31cb3da06775dd83bd348 (patch) | |
tree | a5e0d4ddd6f4edcc23ea58d9b86d8edd1ec6e2f8 /fs/fat/namei_vfat.c | |
parent | a993b542bb4cd3e5a64863b7ef892bbebec2239b (diff) |
vfat: Fix vfat_find() error path in vfat_lookup()
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 <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/fat/namei_vfat.c')
-rw-r--r-- | fs/fat/namei_vfat.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 1536bc3ca0f0..419deabfb9be 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -683,7 +683,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
683 | { | 683 | { |
684 | struct super_block *sb = dir->i_sb; | 684 | struct super_block *sb = dir->i_sb; |
685 | struct fat_slot_info sinfo; | 685 | struct fat_slot_info sinfo; |
686 | struct inode *inode = NULL; | 686 | struct inode *inode; |
687 | struct dentry *alias; | 687 | struct dentry *alias; |
688 | int err, table; | 688 | int err, table; |
689 | 689 | ||
@@ -693,14 +693,18 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
693 | 693 | ||
694 | err = vfat_find(dir, &dentry->d_name, &sinfo); | 694 | err = vfat_find(dir, &dentry->d_name, &sinfo); |
695 | if (err) { | 695 | if (err) { |
696 | table++; | 696 | if (err == -ENOENT) { |
697 | table++; | ||
698 | inode = NULL; | ||
699 | goto out; | ||
700 | } | ||
697 | goto error; | 701 | goto error; |
698 | } | 702 | } |
699 | inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); | 703 | inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); |
700 | brelse(sinfo.bh); | 704 | brelse(sinfo.bh); |
701 | if (IS_ERR(inode)) { | 705 | if (IS_ERR(inode)) { |
702 | unlock_super(sb); | 706 | err = PTR_ERR(inode); |
703 | return ERR_CAST(inode); | 707 | goto error; |
704 | } | 708 | } |
705 | alias = d_find_alias(inode); | 709 | alias = d_find_alias(inode); |
706 | if (alias) { | 710 | if (alias) { |
@@ -713,7 +717,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
713 | } | 717 | } |
714 | 718 | ||
715 | } | 719 | } |
716 | error: | 720 | out: |
717 | unlock_super(sb); | 721 | unlock_super(sb); |
718 | dentry->d_op = &vfat_dentry_ops[table]; | 722 | dentry->d_op = &vfat_dentry_ops[table]; |
719 | dentry->d_time = dentry->d_parent->d_inode->i_version; | 723 | dentry->d_time = dentry->d_parent->d_inode->i_version; |
@@ -723,6 +727,10 @@ error: | |||
723 | dentry->d_time = dentry->d_parent->d_inode->i_version; | 727 | dentry->d_time = dentry->d_parent->d_inode->i_version; |
724 | } | 728 | } |
725 | return dentry; | 729 | return dentry; |
730 | |||
731 | error: | ||
732 | unlock_super(sb); | ||
733 | return ERR_PTR(err); | ||
726 | } | 734 | } |
727 | 735 | ||
728 | static int vfat_create(struct inode *dir, struct dentry *dentry, int mode, | 736 | static int vfat_create(struct inode *dir, struct dentry *dentry, int mode, |