From 60433b154dc345f8883b15d657e3f7d5c21fc6a1 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Thu, 14 May 2009 23:14:03 +0000 Subject: s3 onefs: Fix 1 second share mode delay handling When racing to the open and loosing we may get a share_mode violation. In this case handle the 1-second delay via a defferred open properly. This requires us to retrieve the share_mode_lock before deferring open so we don't dereference a NULL pointer assuming we already had the lck because we were the first opener. --- source3/modules/onefs_open.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index fa1f883c59..b9a2c30734 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -1095,9 +1095,39 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, state.id = id; state.failed = false; - if ((req != NULL) - && !request_timed_out(request_time, - timeout)) { + /* + * We hit the race that when we did the stat + * on the file it did not exist, and someone + * has created it in between the stat and the + * open_file() call. Retrieve the share_mode + * lock on the newly opened file so we can + * defer our request. + */ + if (lck == NULL) { + struct timespec old_write_time; + old_write_time = get_mtimespec(psbuf); + + lck = get_share_mode_lock(talloc_tos(), + id, conn->connectpath, fname, + &old_write_time); + if (lck == NULL) { + DEBUG(0, + ("onefs_open_file_ntcreate:" + " Could not get share " + "mode lock for %s\n", + fname)); + /* This will cause us to return + * immediately skipping the + * the 1 second delay, which + * isn't a big deal */ + status = NT_STATUS_SHARING_VIOLATION; + goto cleanup_destroy; + } + } + + if ((req != NULL) && + !request_timed_out(request_time, timeout)) + { defer_open(lck, request_time, timeout, req, &state); } -- cgit