diff options
author | Jeremy Allison <jra@samba.org> | 2006-07-19 01:30:30 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:38:14 -0500 |
commit | 4815e2c3441ce2cb18aa7fcb9ae1fe97bbcabd80 (patch) | |
tree | a5cb2ae955d85db4fea59038d3f8f3befa18a486 | |
parent | 0e292222c30c269c17e68acf1bbef787c1e946ed (diff) | |
download | samba-4815e2c3441ce2cb18aa7fcb9ae1fe97bbcabd80.tar.gz samba-4815e2c3441ce2cb18aa7fcb9ae1fe97bbcabd80.tar.bz2 samba-4815e2c3441ce2cb18aa7fcb9ae1fe97bbcabd80.zip |
r17128: Missed a logic error in my last patch. Ensure we deal with any
oplocks that were granted when we had released the lock. Fix
strange case where stat open grants a batch oplock on file
create, but grants no oplock on file open.
Jeremy.
(This used to be commit b7374835e6ec0c98fc4020623f0a37c0c173b8aa)
-rw-r--r-- | source3/smbd/open.c | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index b13b4f2a6c..2c259e7822 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -623,8 +623,11 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, BOOL delay_it = False; BOOL have_level2 = False; - if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) { + if (oplock_request & INTERNAL_OPEN_ONLY) { fsp->oplock_type = NO_OPLOCK; + } + + if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) { return False; } @@ -1582,10 +1585,43 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, return NT_STATUS_SHARING_VIOLATION; } + /* + * The share entry is again *locked*..... + */ + + /* First pass - send break only on batch oplocks. */ + if (delay_for_oplocks(lck, fsp, 1, oplock_request)) { + schedule_defer_open(lck, request_time); + fd_close(conn, fsp); + file_free(fsp); + TALLOC_FREE(lck); + return NT_STATUS_SHARING_VIOLATION; + } + status = open_mode_check(conn, fname, lck, access_mask, share_access, create_options, &file_existed); + if (NT_STATUS_IS_OK(status)) { + /* We might be going to allow this open. Check oplock status again. */ + /* Second pass - send break for both batch or exclusive oplocks. */ + if (delay_for_oplocks(lck, fsp, 2, oplock_request)) { + schedule_defer_open(lck, request_time); + fd_close(conn, fsp); + file_free(fsp); + TALLOC_FREE(lck); + return NT_STATUS_SHARING_VIOLATION; + } + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { + /* DELETE_PENDING is not deferred for a second */ + fd_close(conn, fsp); + file_free(fsp); + TALLOC_FREE(lck); + return status; + } + if (!NT_STATUS_IS_OK(status)) { struct deferred_open_record state; @@ -1609,10 +1645,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, return status; } - /* - * The share entry is again *locked*..... - */ - /* note that we ignore failure for the following. It is basically a hack for NFS, and NFS will never set one of these only read them. Nobody but Samba can ever set a deny @@ -1653,6 +1685,11 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, fsp->access_mask = access_mask; if (file_existed) { + /* stat opens on existing files don't get oplocks. */ + if (is_stat_open(fsp->access_mask)) { + fsp->oplock_type = NO_OPLOCK; + } + if (!(flags2 & O_TRUNC)) { info = FILE_WAS_OPENED; } else { |