if (!request)
RETURN(0);
- if (it_disposition(it, DISP_LOOKUP_NEG))
+ if (it_disposition(it, DISP_LOOKUP_NEG)) {
+ /*Sometimes, revalidate_it might also create node in MDS,
+ *So we need check whether it is really created, if not,
+ *just return the -ENOENT, if it is, return -ESTALE anyway.
+ *which is original done in mdc_intent_lock,
+ *but no chance for new fid allocation in client.
+ */
+ if (it_disposition(it, DISP_OPEN_CREATE) &&
+ !it_open_error(DISP_OPEN_CREATE, it)) {
+ /*These 2 req finished is for balancing 2 add ref
+ *in mdc_intent_lock, since there are no create_node
+ *and file_open following revalidate_it*/
+ it_set_disposition(it, DISP_ENQ_COMPLETE);
+ if (it_disposition(it, DISP_OPEN_CREATE) &&
+ !it_open_error(DISP_OPEN_CREATE, it))
+ ptlrpc_req_finished(request);
+ if (it_disposition(it, DISP_OPEN_OPEN) &&
+ !it_open_error(DISP_OPEN_OPEN, it))
+ ptlrpc_req_finished(request);
+
+ RETURN(-ESTALE);
+ }
RETURN(-ENOENT);
+ }
rc = ll_prep_inode(&de->d_inode,
request, offset, NULL);
OBD_ALLOC_PTR(op_data);
if (op_data == NULL)
RETURN(-ENOMEM);
-
- ll_prepare_md_op_data(op_data, parent, de->d_inode,
+
+ ll_prepare_md_op_data(op_data, parent, NULL,
de->d_name.name, de->d_name.len, 0);
+ if (it->it_op & IT_CREAT ||
+ (it->it_op & IT_OPEN && it->it_create_mode & O_CREAT)) {
+ struct lu_placement_hint hint = { .ph_pname = NULL,
+ .ph_cname = &de->d_name,
+ .ph_opc = LUSTRE_OPC_CREATE };
+
+ rc = ll_fid_md_alloc(ll_i2sbi(parent), &op_data->fid2,
+ &hint);
+ if (rc) {
+ CERROR("can't allocate new fid, rc %d\n", rc);
+ LBUG();
+ }
+ }
rc = md_intent_lock(exp, op_data, NULL, 0, it, lookup_flags,
&req, ll_md_blocking_ast, 0);
OBD_FREE_PTR(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 (req == NULL && rc >= 0) {
GOTO(out, rc);
+ }
if (rc < 0) {
if (rc != -ESTALE) {
rc = ll_revalidate_it_finish(req, 1, it, de);
if (rc != 0) {
- ll_intent_release(it);
+ if (rc != -ESTALE)
+ ll_intent_release(it);
GOTO(out, rc = 0);
}
if ((it->it_op & IT_OPEN) && de->d_inode &&