+ if (count != 0) {
+ EXIT;
+ return;
+ }
+
+ rc = obd_unpin(sbi->ll_md_exp, &handle, flag);
+ EXIT;
+ return;
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#ifdef LUSTRE_KERNEL_VERSION
+static int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd)
+{
+ int rc;
+ ENTRY;
+
+ if (nd && nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
+ rc = ll_revalidate_it(dentry, nd->flags, &nd->intent);
+ else
+ rc = ll_revalidate_it(dentry, 0, NULL);
+
+ RETURN(rc);
+}
+#else
+int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd)
+{
+ int rc;
+ ENTRY;
+
+ if (nd && !(nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))) {
+ struct lookup_intent *it;
+ it = ll_convert_intent(&nd->intent.open, nd->flags);
+ if (IS_ERR(it))
+ RETURN(0);
+ if (it->it_op == (IT_OPEN|IT_CREAT))
+ if (nd->intent.open.flags & O_EXCL) {
+ CDEBUG(D_VFSTRACE, "create O_EXCL, returning 0\n");
+ rc = 0;
+ goto out_it;
+ }
+
+ rc = ll_revalidate_it(dentry, nd->flags, it);
+
+ if (rc && (nd->flags & LOOKUP_OPEN) &&
+ it_disposition(it, DISP_OPEN_OPEN)) {/*Open*/
+#ifdef HAVE_FILE_IN_STRUCT_INTENT
+// XXX Code duplication with ll_lookup_nd
+ 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))
+ rc = 0;
+#endif
+ }
+#else
+ ll_release_openhandle(dentry, it);
+#endif /* HAVE_FILE_IN_STRUCT_INTENT */
+ }
+ if (!rc && (nd->flags & LOOKUP_CREATE) &&
+ it_disposition(it, DISP_OPEN_CREATE)) {
+ /* We created something but we may only return
+ * negative dentry here, so save request in dentry,
+ * if lookup will be called later on, it will
+ * pick the request, otherwise it would be freed
+ * with dentry */
+ ll_d2d(dentry)->lld_it = it;
+ it = NULL; /* avoid freeing */
+ }
+
+out_it:
+ if (it) {
+ ll_intent_release(it);
+ OBD_FREE(it, sizeof(*it));
+ }
+ } else {
+ rc = ll_revalidate_it(dentry, 0, NULL);
+ }
+
+ RETURN(rc);