-do_lock:
- op_data = ll_prep_md_op_data(NULL, parent, de->d_inode,
- de->d_name.name, de->d_name.len,
- 0, LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data))
- RETURN(PTR_ERR(op_data));
-
- if (!IS_POSIXACL(parent) || !exp_connect_umask(exp))
- it->it_create_mode &= ~current_umask();
- it->it_create_mode |= M_CHECK_STALE;
- rc = md_intent_lock(exp, op_data, NULL, 0, it,
- lookup_flags,
- &req, ll_md_blocking_ast, 0);
- it->it_create_mode &= ~M_CHECK_STALE;
- ll_finish_md_op_data(op_data);
-
- /* If req is NULL, then md_intent_lock only tried to do a lock match;
- * if all was well, it will return 1 if it found locks, 0 otherwise. */
- if (req == NULL && rc >= 0) {
- if (!rc)
- goto do_lookup;
- GOTO(out, rc);
- }
-
- if (rc < 0) {
- if (rc != -ESTALE) {
- CDEBUG(D_INFO, "ll_intent_lock: rc %d : it->it_status "
- "%d\n", rc, it->d.lustre.it_status);
- }
- GOTO(out, rc = 0);
- }
-
-revalidate_finish:
- rc = ll_revalidate_it_finish(req, it, de);
- if (rc != 0) {
- if (rc != -ESTALE && rc != -ENOENT)
- ll_intent_release(it);
- GOTO(out, rc = 0);
- }
-
- if ((it->it_op & IT_OPEN) && de->d_inode &&
- !S_ISREG(de->d_inode->i_mode) &&
- !S_ISDIR(de->d_inode->i_mode)) {
- ll_release_openhandle(de, it);
- }
- rc = 1;
-
-out:
- /* We do not free request as it may be reused during following lookup
- * (see comment in mdc/mdc_locks.c::mdc_intent_lock()), request will
- * be freed in ll_lookup_it or in ll_intent_release. But if
- * request was not completed, we need to free it. (bug 5154, 9903) */
- if (req != NULL && !it_disposition(it, DISP_ENQ_COMPLETE))
- ptlrpc_req_finished(req);
- if (rc == 0) {
- /* mdt may grant layout lock for the newly created file, so
- * release the lock to avoid leaking */
- ll_intent_drop_lock(it);
- ll_invalidate_aliases(de->d_inode);
- } else {
- __u64 bits = 0;
- __u64 matched_bits = 0;
-
- CDEBUG(D_DENTRY, "revalidated dentry %.*s (%p) parent %p "
- "inode %p refc %d\n", de->d_name.len,
- de->d_name.name, de, de->d_parent, de->d_inode,
- d_refcount(de));
-
- ll_set_lock_data(exp, de->d_inode, it, &bits);
-
- /* Note: We have to match both LOOKUP and PERM lock
- * here to make sure the dentry is valid and no one
- * changing the permission.
- * But if the client connects < 2.4 server, which will
- * only grant LOOKUP lock, so we can only Match LOOKUP
- * lock for old server */
- if (exp_connect_flags(ll_i2mdexp(de->d_inode)) &&
- OBD_CONNECT_LVB_TYPE)
- matched_bits =
- MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM;
- else
- matched_bits = MDS_INODELOCK_LOOKUP;
-
- if (((bits & matched_bits) == matched_bits) &&
- d_lustre_invalid(de))
- d_lustre_revalidate(de);
- ll_lookup_finish_locks(it, de);
- }
-
-mark:
- if (it != NULL && it->it_op == IT_GETATTR && rc > 0)
- ll_statahead_mark(parent, de);
- RETURN(rc);
-
- /*
- * This part is here to combat evil-evil race in real_lookup on 2.6
- * kernels. The race details are: We enter do_lookup() looking for some
- * name, there is nothing in dcache for this name yet and d_lookup()
- * returns NULL. We proceed to real_lookup(), and while we do this,
- * another process does open on the same file we looking up (most simple
- * reproducer), open succeeds and the dentry is added. Now back to
- * us. In real_lookup() we do d_lookup() again and suddenly find the
- * dentry, so we call d_revalidate on it, but there is no lock, so
- * without this code we would return 0, but unpatched real_lookup just
- * returns -ENOENT in such a case instead of retrying the lookup. Once
- * this is dealt with in real_lookup(), all of this ugly mess can go and
- * we can just check locks in ->d_revalidate without doing any RPCs
- * ever.
- */
-do_lookup:
- if (it != &lookup_it) {
- /* MDS_INODELOCK_UPDATE needed for IT_GETATTR case. */
- if (it->it_op == IT_GETATTR)
- lookup_it.it_op = IT_GETATTR;
- ll_lookup_finish_locks(it, de);
- it = &lookup_it;
- }