r17128: Missed a logic error in my last patch. Ensure we deal with any
authorJeremy Allison <jra@samba.org>
Wed, 19 Jul 2006 01:30:30 +0000 (01:30 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:38:14 +0000 (11:38 -0500)
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)

source3/smbd/open.c

index b13b4f2a6ce1596512eb172f0fb671c356ee3815..2c259e78223b80384b271fbf05eead0101a75332 100644 (file)
@@ -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 {