summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/modules/onefs_open.c33
-rw-r--r--source3/smbd/process.c2
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;