diff options
-rw-r--r-- | source3/modules/onefs_open.c | 33 | ||||
-rw-r--r-- | source3/smbd/process.c | 2 |
2 files changed, 26 insertions, 9 deletions
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 31f27e907a..4ae81356b5 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -423,6 +423,13 @@ static void schedule_defer_open(struct share_mode_lock *lck, if (!request_timed_out(request_time, timeout)) { defer_open(lck, request_time, timeout, req, &state); + } else { + /* A delayed-for-oplocks deferred open timing out should only + * happen if there is a bug or extreme load, since we set the + * timeout to 300 seconds. */ + DEBUG(0, ("Deferred open timeout! request_time=%d.%d, " + "mid=%d\n", request_time.tv_sec, request_time.tv_usec, + req->mid)); } } @@ -885,6 +892,12 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, * stat-only open at this point. */ SMB_ASSERT(fsp->oplock_type == NO_OPLOCK); + + /* The kernel and Samba's version of stat-only differs + * slightly: The kernel doesn't think its stat-only if we're + * truncating. We'd better have a req in order to defer the + * open. */ + SMB_ASSERT(!((flags|flags2) & O_TRUNC)); } /* Do the open. */ @@ -910,9 +923,13 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, /* OneFS Oplock Handling */ if (errno == EINPROGRESS) { + /* If we get EINPROGRESS, the kernel will send us an + * asynchronous semlock event back. Ensure we can defer + * the open, by asserting req. */ + SMB_ASSERT(req); + if (lck == NULL) { - struct deferred_open_record state; struct timespec old_write_time; old_write_time = smb_fname->st.st_ex_mtime; @@ -939,17 +956,15 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, "lock for %s\n", smb_fname_str_dbg(smb_fname))); status = NT_STATUS_SHARING_VIOLATION; + + /* XXXZLK: This will cause us to get a + * semlock event when we aren't + * expecting one. */ goto cleanup_destroy; } - state.delayed_for_oplocks = False; - state.id = id; - - if (req != NULL) { - defer_open(lck, request_time, - timeval_zero(), req, &state); - } - goto cleanup_destroy; + schedule_defer_open(lck, request_time, req); + goto cleanup; } /* Waiting for an oplock */ DEBUG(5,("Async createfile because a client has an " diff --git a/source3/smbd/process.c b/source3/smbd/process.c index dd58ea88fa..ccb7f9dce3 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1306,6 +1306,8 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } if (!change_to_user(conn,session_tag)) { + DEBUG(0, ("Error: Could not change to user. Removing " + "deferred open, mid=%d.\n", req->mid)); reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid)); remove_deferred_open_smb_message(req->mid); return conn; |