|
@@ -858,6 +858,7 @@ static struct buffer_head *ext3_find_entry(struct inode *dir,
|
|
|
struct buffer_head * bh_use[NAMEI_RA_SIZE];
|
|
|
struct buffer_head * bh, *ret = NULL;
|
|
|
unsigned long start, block, b;
|
|
|
+ const u8 *name = entry->name;
|
|
|
int ra_max = 0; /* Number of bh's in the readahead
|
|
|
buffer, bh_use[] */
|
|
|
int ra_ptr = 0; /* Current index into readahead
|
|
@@ -871,6 +872,16 @@ static struct buffer_head *ext3_find_entry(struct inode *dir,
|
|
|
namelen = entry->len;
|
|
|
if (namelen > EXT3_NAME_LEN)
|
|
|
return NULL;
|
|
|
+ if ((namelen <= 2) && (name[0] == '.') &&
|
|
|
+ (name[1] == '.' || name[1] == 0)) {
|
|
|
+ /*
|
|
|
+ * "." or ".." will only be in the first block
|
|
|
+ * NFS may look up ".."; "." should be handled by the VFS
|
|
|
+ */
|
|
|
+ block = start = 0;
|
|
|
+ nblocks = 1;
|
|
|
+ goto restart;
|
|
|
+ }
|
|
|
if (is_dx(dir)) {
|
|
|
bh = ext3_dx_find_entry(dir, entry, res_dir, &err);
|
|
|
/*
|
|
@@ -961,9 +972,8 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir,
|
|
|
struct qstr *entry, struct ext3_dir_entry_2 **res_dir,
|
|
|
int *err)
|
|
|
{
|
|
|
- struct super_block * sb;
|
|
|
+ struct super_block *sb = dir->i_sb;
|
|
|
struct dx_hash_info hinfo;
|
|
|
- u32 hash;
|
|
|
struct dx_frame frames[2], *frame;
|
|
|
struct ext3_dir_entry_2 *de, *top;
|
|
|
struct buffer_head *bh;
|
|
@@ -972,18 +982,8 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir,
|
|
|
int namelen = entry->len;
|
|
|
const u8 *name = entry->name;
|
|
|
|
|
|
- sb = dir->i_sb;
|
|
|
- /* NFS may look up ".." - look at dx_root directory block */
|
|
|
- if (namelen > 2 || name[0] != '.'|| (namelen == 2 && name[1] != '.')) {
|
|
|
- if (!(frame = dx_probe(entry, dir, &hinfo, frames, err)))
|
|
|
- return NULL;
|
|
|
- } else {
|
|
|
- frame = frames;
|
|
|
- frame->bh = NULL; /* for dx_release() */
|
|
|
- frame->at = (struct dx_entry *)frames; /* hack for zero entry*/
|
|
|
- dx_set_block(frame->at, 0); /* dx_root block is 0 */
|
|
|
- }
|
|
|
- hash = hinfo.hash;
|
|
|
+ if (!(frame = dx_probe(entry, dir, &hinfo, frames, err)))
|
|
|
+ return NULL;
|
|
|
do {
|
|
|
block = dx_get_block(frame->at);
|
|
|
if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
|
|
@@ -1009,7 +1009,7 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir,
|
|
|
}
|
|
|
brelse (bh);
|
|
|
/* Check to see if we should continue to search */
|
|
|
- retval = ext3_htree_next_block(dir, hash, frame,
|
|
|
+ retval = ext3_htree_next_block(dir, hinfo.hash, frame,
|
|
|
frames, NULL);
|
|
|
if (retval < 0) {
|
|
|
ext3_warning(sb, __func__,
|