+ de = ll_lookup_it(parent, dentry, NULL, 0);
+
+ RETURN(de);
+}
+#else
+struct lookup_intent *ll_convert_intent(struct open_intent *oit,
+ int lookup_flags)
+{
+ struct lookup_intent *it;
+
+ OBD_ALLOC(it, sizeof(*it));
+ if (!it)
+ return ERR_PTR(-ENOMEM);
+
+ if (lookup_flags & LOOKUP_OPEN) {
+ it->it_op = IT_OPEN;
+ if (lookup_flags & LOOKUP_CREATE)
+ it->it_op |= IT_CREAT;
+ it->it_create_mode = oit->create_mode;
+ it->it_flags = oit->flags;
+ } else {
+ it->it_op = IT_GETATTR;
+ }
+
+#ifndef HAVE_FILE_IN_STRUCT_INTENT
+ /* Since there is no way to pass our intent to ll_file_open,
+ * just check the file is there. Actual open will be done
+ * in ll_file_open */
+ if (it->it_op & IT_OPEN)
+ it->it_op = IT_LOOKUP;
+#endif
+
+ 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 {
+ struct file *filp;
+ nd->intent.open.file->private_data = it;
+ filp =lookup_instantiate_filp(nd,dentry,
+ NULL);
+#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 */
+ if (IS_ERR(filp)) {
+ if (de)
+ dput(de);
+ de = (struct dentry *) filp;
+ }
+#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);
+ }