+ return it;
+}
+
+static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ struct dentry *de;
+ ENTRY;
+
+ if (nd && !(nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))) {
+ struct lookup_intent *it;
+
+#if defined(HAVE_FILE_IN_STRUCT_INTENT) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+ /* Did we came here from failed revalidate just to propagate
+ * its error? */
+ if (nd->flags & LOOKUP_OPEN)
+ if (IS_ERR(nd->intent.open.file))
+ RETURN((struct dentry *)nd->intent.open.file);
+#endif
+
+ if (ll_d2d(dentry) && ll_d2d(dentry)->lld_it) {
+ it = ll_d2d(dentry)->lld_it;
+ ll_d2d(dentry)->lld_it = NULL;
+ } else {
+ it = ll_convert_intent(&nd->intent.open, nd->flags);
+ if (IS_ERR(it))
+ RETURN((struct dentry *)it);
+ }
+
+ de = ll_lookup_it(parent, dentry, it, nd->flags);
+ if (de)
+ dentry = de;
+ if ((nd->flags & LOOKUP_OPEN) && !IS_ERR(dentry)) { /* Open */
+ if (dentry->d_inode &&
+ it_disposition(it, DISP_OPEN_OPEN)) { /* nocreate */
+#ifdef HAVE_FILE_IN_STRUCT_INTENT
+ if (S_ISFIFO(dentry->d_inode->i_mode)) {
+ // We cannot call open here as it would
+ // deadlock.
+ ptlrpc_req_finished(
+ (struct ptlrpc_request *)
+ it->d.lustre.it_data);
+ } else {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+/* 2.6.1[456] have a bug in open_namei() that forgets to check
+ * nd->intent.open.file for error, so we need to return it as lookup's result
+ * instead */
+ struct file *filp;
+ nd->intent.open.file->private_data = it;
+ filp =lookup_instantiate_filp(nd,dentry,
+ NULL);
+ if (IS_ERR(filp)) {
+ if (de)
+ dput(de);
+ de = (struct dentry *) filp;
+ }
+#else
+ nd->intent.open.file->private_data = it;
+ (void)lookup_instantiate_filp(nd,dentry,
+ NULL);
+#endif
+
+ }
+#else /* HAVE_FILE_IN_STRUCT_INTENT */
+ /* Release open handle as we have no way to
+ * pass it to ll_file_open */
+ ll_release_openhandle(dentry, it);
+#endif /* HAVE_FILE_IN_STRUCT_INTENT */
+ } else if (it_disposition(it, DISP_OPEN_CREATE)) {
+ // XXX This can only reliably work on assumption
+ // that there are NO hashed negative dentries.
+ ll_d2d(dentry)->lld_it = it;
+ it = NULL; /* Will be freed in ll_create_nd */
+ /* We absolutely depend on ll_create_nd to be
+ * called to not leak this intent and possible
+ * data attached to it */
+ }
+ }
+
+ if (it) {
+ ll_intent_release(it);
+ OBD_FREE(it, sizeof(*it));
+ }
+ } else {
+ de = ll_lookup_it(parent, dentry, NULL, 0);
+ }
+
+ RETURN(de);
+}
+#endif
+
+/**
+ * check new allocated inode, new inode shld not have any valid alias
+ */
+static void ll_validate_new_inode(struct inode *new)
+{
+ struct list_head *lp;
+ struct dentry * dentry;
+ int need_inval = 0;
+ int in_recheck = 0;
+
+ if (list_empty(&new->i_dentry))
+ return;
+recheck:
+ spin_lock(&dcache_lock);
+ list_for_each(lp, &new->i_dentry) {
+ dentry = list_entry(lp, struct dentry, d_alias);
+ if (!d_unhashed(dentry) && !(dentry->d_flags & DCACHE_LUSTRE_INVALID)){
+ ll_dump_inode(new);
+ if (in_recheck)
+ LBUG();
+ }
+ need_inval = 1;
+ }
+ spin_unlock(&dcache_lock);
+
+ if (need_inval && !in_recheck) {
+ /* kill all old inode's data pages */
+ truncate_inode_pages(new->i_mapping, 0);
+
+ /* invalidate all dirent and recheck inode */
+ ll_unhash_aliases(new);
+ in_recheck = 1;
+ goto recheck;
+ }
+}
+