ret = bh;
goto cleanup_and_exit;
} else {
-@@ -197,6 +862,66 @@ cleanup_and_exit:
+@@ -197,6 +862,74 @@ cleanup_and_exit:
return ret;
}
+ int namelen = dentry->d_name.len;
+ const u8 *name = dentry->d_name.name;
+ struct inode *dir = dentry->d_parent->d_inode;
-+
++
+ sb = dir->i_sb;
-+ if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
-+ return NULL;
++ /* NFS may look up ".." - look at dx_root directory block */
++ if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
++ if (!(frame = dx_probe(dentry, 0, &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;
+ do {
+ block = dx_get_block(frame->at);
+ if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
+ goto errout;
+ de = (struct ext3_dir_entry_2 *) bh->b_data;
-+ top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
++ top = (struct ext3_dir_entry_2 *)((char *)de + sb->s_blocksize -
+ EXT3_DIR_REC_LEN(0));
+ for (; de < top; de = ext3_next_entry(de))
+ if (ext3_match (namelen, name, de)) {