diff options
-rw-r--r-- | fs/ext3/namei.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 672cea16a8b9..d093cbbe38b7 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -858,6 +858,7 @@ static struct buffer_head *ext3_find_entry(struct inode *dir, | |||
858 | struct buffer_head * bh_use[NAMEI_RA_SIZE]; | 858 | struct buffer_head * bh_use[NAMEI_RA_SIZE]; |
859 | struct buffer_head * bh, *ret = NULL; | 859 | struct buffer_head * bh, *ret = NULL; |
860 | unsigned long start, block, b; | 860 | unsigned long start, block, b; |
861 | const u8 *name = entry->name; | ||
861 | int ra_max = 0; /* Number of bh's in the readahead | 862 | int ra_max = 0; /* Number of bh's in the readahead |
862 | buffer, bh_use[] */ | 863 | buffer, bh_use[] */ |
863 | int ra_ptr = 0; /* Current index into readahead | 864 | int ra_ptr = 0; /* Current index into readahead |
@@ -871,6 +872,16 @@ static struct buffer_head *ext3_find_entry(struct inode *dir, | |||
871 | namelen = entry->len; | 872 | namelen = entry->len; |
872 | if (namelen > EXT3_NAME_LEN) | 873 | if (namelen > EXT3_NAME_LEN) |
873 | return NULL; | 874 | return NULL; |
875 | if ((namelen <= 2) && (name[0] == '.') && | ||
876 | (name[1] == '.' || name[1] == 0)) { | ||
877 | /* | ||
878 | * "." or ".." will only be in the first block | ||
879 | * NFS may look up ".."; "." should be handled by the VFS | ||
880 | */ | ||
881 | block = start = 0; | ||
882 | nblocks = 1; | ||
883 | goto restart; | ||
884 | } | ||
874 | if (is_dx(dir)) { | 885 | if (is_dx(dir)) { |
875 | bh = ext3_dx_find_entry(dir, entry, res_dir, &err); | 886 | bh = ext3_dx_find_entry(dir, entry, res_dir, &err); |
876 | /* | 887 | /* |
@@ -961,9 +972,8 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, | |||
961 | struct qstr *entry, struct ext3_dir_entry_2 **res_dir, | 972 | struct qstr *entry, struct ext3_dir_entry_2 **res_dir, |
962 | int *err) | 973 | int *err) |
963 | { | 974 | { |
964 | struct super_block * sb; | 975 | struct super_block *sb = dir->i_sb; |
965 | struct dx_hash_info hinfo; | 976 | struct dx_hash_info hinfo; |
966 | u32 hash; | ||
967 | struct dx_frame frames[2], *frame; | 977 | struct dx_frame frames[2], *frame; |
968 | struct ext3_dir_entry_2 *de, *top; | 978 | struct ext3_dir_entry_2 *de, *top; |
969 | struct buffer_head *bh; | 979 | struct buffer_head *bh; |
@@ -972,18 +982,8 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, | |||
972 | int namelen = entry->len; | 982 | int namelen = entry->len; |
973 | const u8 *name = entry->name; | 983 | const u8 *name = entry->name; |
974 | 984 | ||
975 | sb = dir->i_sb; | 985 | if (!(frame = dx_probe(entry, dir, &hinfo, frames, err))) |
976 | /* NFS may look up ".." - look at dx_root directory block */ | 986 | return NULL; |
977 | if (namelen > 2 || name[0] != '.'|| (namelen == 2 && name[1] != '.')) { | ||
978 | if (!(frame = dx_probe(entry, dir, &hinfo, frames, err))) | ||
979 | return NULL; | ||
980 | } else { | ||
981 | frame = frames; | ||
982 | frame->bh = NULL; /* for dx_release() */ | ||
983 | frame->at = (struct dx_entry *)frames; /* hack for zero entry*/ | ||
984 | dx_set_block(frame->at, 0); /* dx_root block is 0 */ | ||
985 | } | ||
986 | hash = hinfo.hash; | ||
987 | do { | 987 | do { |
988 | block = dx_get_block(frame->at); | 988 | block = dx_get_block(frame->at); |
989 | if (!(bh = ext3_bread (NULL,dir, block, 0, err))) | 989 | if (!(bh = ext3_bread (NULL,dir, block, 0, err))) |
@@ -1009,7 +1009,7 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, | |||
1009 | } | 1009 | } |
1010 | brelse (bh); | 1010 | brelse (bh); |
1011 | /* Check to see if we should continue to search */ | 1011 | /* Check to see if we should continue to search */ |
1012 | retval = ext3_htree_next_block(dir, hash, frame, | 1012 | retval = ext3_htree_next_block(dir, hinfo.hash, frame, |
1013 | frames, NULL); | 1013 | frames, NULL); |
1014 | if (retval < 0) { | 1014 | if (retval < 0) { |
1015 | ext3_warning(sb, __func__, | 1015 | ext3_warning(sb, __func__, |