+ if (it->it_op & IT_CREAT) {
+ op_data = ll_prep_md_op_data(NULL, parent, NULL,
+ de->d_name.name, de->d_name.len,
+ 0, LUSTRE_OPC_CREATE, NULL);
+ } else {
+ 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 ((it->it_op == IT_OPEN) && de->d_inode) {
+ struct inode *inode = de->d_inode;
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct obd_client_handle **och_p;
+ __u64 *och_usecount;
+
+ /*
+ * We used to check for MDS_INODELOCK_OPEN here, but in fact
+ * just having LOOKUP lock is enough to justify inode is the
+ * same. And if inode is the same and we have suitable
+ * openhandle, then there is no point in doing another OPEN RPC
+ * just to throw away newly received openhandle. There are no
+ * security implications too, if file owner or access mode is
+ * change, LOOKUP lock is revoked.
+ */
+
+
+ if (it->it_flags & FMODE_WRITE) {
+ och_p = &lli->lli_mds_write_och;
+ och_usecount = &lli->lli_open_fd_write_count;
+ } else if (it->it_flags & FMODE_EXEC) {
+ och_p = &lli->lli_mds_exec_och;
+ och_usecount = &lli->lli_open_fd_exec_count;
+ } else {
+ och_p = &lli->lli_mds_read_och;
+ och_usecount = &lli->lli_open_fd_read_count;
+ }
+ /* Check for the proper lock. */
+ if (!ll_have_md_lock(inode, MDS_INODELOCK_LOOKUP))
+ goto do_lock;
+ down(&lli->lli_och_sem);
+ if (*och_p) { /* Everything is open already, do nothing */
+ /*(*och_usecount)++; Do not let them steal our open
+ handle from under us */
+ /* XXX The code above was my original idea, but in case
+ we have the handle, but we cannot use it due to later
+ checks (e.g. O_CREAT|O_EXCL flags set), nobody
+ would decrement counter increased here. So we just
+ hope the lock won't be invalidated in between. But
+ if it would be, we'll reopen the open request to
+ MDS later during file open path */
+ up(&lli->lli_och_sem);
+ ll_finish_md_op_data(op_data);
+ RETURN(1);
+ } else {
+ up(&lli->lli_och_sem);
+ }
+ }
+
+do_lock:
+ it->it_create_mode &= ~current->fs->umask;
+ it->it_flags |= O_CHECK_STALE;
+ rc = md_intent_lock(exp, op_data, NULL, 0, it,
+ lookup_flags,
+ &req, ll_md_blocking_ast, 0);
+ it->it_flags &= ~O_CHECK_STALE;
+ ll_finish_md_op_data(op_data);
+ /* If req is NULL, then md_intent_lock only tried to do a lock match;