summaryrefslogtreecommitdiff
path: root/source3/smbd/open.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-07-19 01:30:30 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:38:14 -0500
commit4815e2c3441ce2cb18aa7fcb9ae1fe97bbcabd80 (patch)
treea5cb2ae955d85db4fea59038d3f8f3befa18a486 /source3/smbd/open.c
parent0e292222c30c269c17e68acf1bbef787c1e946ed (diff)
downloadsamba-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)
Diffstat (limited to 'source3/smbd/open.c')
-rw-r--r--source3/smbd/open.c47
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 {