- it->it_create_mode |= S_IFREG;
- it->it_create_mode &= ~current->fs->umask;
-
- reqsize[req_buffers++] = sizeof(struct mds_rec_create);
- reqsize[req_buffers++] = data->namelen + 1;
- reqsize[req_buffers++] = obddev->u.cli.cl_max_mds_easize;
- req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_DLM_VERSION,
- LDLM_ENQUEUE, req_buffers, reqsize, NULL);
+ int do_join = !!(it->it_flags & O_JOIN_FILE);
+ CFS_LIST_HEAD(cancels);
+ int count = 0;
+ int mode;
+
+ it->it_create_mode = (it->it_create_mode & ~S_IFMT) | S_IFREG;
+
+ size[DLM_INTENT_REC_OFF] = sizeof(struct mdt_rec_create);
+ /* parent capability */
+ size[DLM_INTENT_REC_OFF + 1] = op_data->op_capa1 ?
+ sizeof(struct lustre_capa) : 0;
+ /* child capability, used for replay only */
+ size[DLM_INTENT_REC_OFF + 2] = sizeof(struct lustre_capa);
+ size[DLM_INTENT_REC_OFF + 3] = op_data->op_namelen + 1;
+ /* As an optimization, we allocate an RPC request buffer for
+ * at least a default-sized LOV EA even if we aren't sending
+ * one.
+ */
+ size[DLM_INTENT_REC_OFF + 4] = max(lmmsize,
+ obddev->u.cli.cl_default_mds_easize);
+
+ /* XXX: openlock is not cancelled for cross-refs. */
+ /* If inode is known, cancel conflicting OPEN locks. */
+ if (fid_is_sane(&op_data->op_fid2)) {
+ if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC))
+ mode = LCK_CW;
+#ifdef FMODE_EXEC
+ else if (it->it_flags & FMODE_EXEC)
+ mode = LCK_PR;
+#endif
+ else
+ mode = LCK_CR;
+ count = mdc_resource_get_unused(exp, &op_data->op_fid2,
+ &cancels, mode,
+ MDS_INODELOCK_OPEN);
+ }
+
+ /* If CREATE or JOIN_FILE, cancel parent's UPDATE lock. */
+ if (it->it_op & IT_CREAT || it->it_flags & O_JOIN_FILE)
+ mode = LCK_EX;
+ else
+ mode = LCK_CR;
+ count += mdc_resource_get_unused(exp, &op_data->op_fid1,
+ &cancels, mode,
+ MDS_INODELOCK_UPDATE);
+
+ if (do_join)
+ size[DLM_INTENT_REC_OFF + 5] =
+ sizeof(struct mdt_rec_join);
+
+ req = ldlm_prep_enqueue_req(exp, 8 + do_join, size, &cancels,
+ count);