+ 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 {
+ if ((nd->flags & LOOKUP_CREATE ) && !(nd->flags & LOOKUP_OPEN)) {
+ /* We are sure this is new dentry, so we need to create
+ our private data and set the dentry ops */
+ ll_dops_init(dentry, 1);
+ RETURN(NULL);
+ }
+ 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);
+ }