Fix the overwriting of errno before use in a DEBUG statement and use the return value...
[samba.git] / source3 / modules / onefs_cbrl.c
index a196511427c54f165396e8087b7a568b40091cec..2f20d04ddb66a613f9b2464204e68a74da534ed1 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "includes.h"
+#include "smbd/smbd.h"
 #include "onefs.h"
 
 #include <ifs/ifs_syscalls.h>
@@ -28,8 +29,6 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_LOCKING
 
-extern struct blocking_lock_record *blocking_lock_queue;
-
 static uint64_t onefs_get_new_id(void) {
        static uint64_t id = 0;
 
@@ -84,6 +83,7 @@ static char *onefs_cbrl_blr_state_str(const struct blocking_lock_record *blr)
 
 static void onefs_cbrl_enumerate_blq(const char *fn)
 {
+       struct smbd_server_connection *sconn = smbd_server_conn;
        struct blocking_lock_record *blr;
 
        if (DEBUGLVL(10))
@@ -91,28 +91,58 @@ static void onefs_cbrl_enumerate_blq(const char *fn)
 
        DEBUG(10, ("CBRL BLR records (%s):\n", fn));
 
-       for (blr = blocking_lock_queue; blr; blr = blr->next)
-               DEBUGADD(10, ("%s\n", onefs_cbrl_blr_state_str(blr)));
+       if (sconn->using_smb2) {
+               struct smbd_smb2_request *smb2req;
+               for (smb2req = sconn->smb2.requests; smb2req; smb2req = nextreq) {
+                       blr = get_pending_smb2req_blr(smb2req);
+                       if (blr) {
+                               DEBUGADD(10, ("%s\n", onefs_cbrl_blr_state_str(blr)));
+                       }
+               }
+       } else {
+               for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next)
+                       DEBUGADD(10, ("%s\n", onefs_cbrl_blr_state_str(blr)));
+       }
 }
 
 static struct blocking_lock_record *onefs_cbrl_find_blr(uint64_t id)
 {
+       struct smbd_server_connection *sconn = smbd_server_conn;
        struct blocking_lock_record *blr;
        struct onefs_cbrl_blr_state *bs;
 
        onefs_cbrl_enumerate_blq("onefs_cbrl_find_blr");
 
-       for (blr = blocking_lock_queue; blr; blr = blr->next) {
-               bs = (struct onefs_cbrl_blr_state *)blr->blr_private;
-
-               /* We don't control all of the BLRs on the BLQ. */
-               if (bs == NULL)
-                       continue;
-
-               if (bs->id == id) {
-                       DEBUG(10, ("found %s\n",
-                           onefs_cbrl_blr_state_str(blr)));
-                       break;
+       if (sconn->using_smb2) {
+               struct smbd_smb2_request *smb2req;
+               for (smb2req = sconn->smb2.requests; smb2req; smb2req = nextreq) {
+                       blr = get_pending_smb2req_blr(smb2req);
+                       if (!blr) {
+                               continue;
+                       }
+                       bs = (struct onefs_cbrl_blr_state *)blr->blr_private;
+                       if (bs == NULL) {
+                               continue;
+                       }
+                       if (bs->id == id) {
+                               DEBUG(10, ("found %s\n",
+                                   onefs_cbrl_blr_state_str(blr)));
+                               break;
+                       }
+               }
+       } else {
+               for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
+                       bs = (struct onefs_cbrl_blr_state *)blr->blr_private;
+
+                       /* We don't control all of the BLRs on the BLQ. */
+                       if (bs == NULL)
+                               continue;
+
+                       if (bs->id == id) {
+                               DEBUG(10, ("found %s\n",
+                                   onefs_cbrl_blr_state_str(blr)));
+                               break;
+                       }
                }
        }
 
@@ -150,8 +180,13 @@ static void onefs_cbrl_async_success(uint64_t id)
        else
                bs->state = ONEFS_CBRL_NONE;
 
+       /* Self contend our own level 2 oplock. The kernel handles
+        * contention of other opener's level 2 oplocks. */
+       contend_level2_oplocks_begin(blr->fsp,
+           LEVEL2_CONTEND_WINDOWS_BRL);
+
        /* Process the queue, to try the next lock or finish up. */
-       process_blocking_lock_queue();
+       process_blocking_lock_queue(smbd_server_conn);
 }
 
 static void onefs_cbrl_async_failure(uint64_t id)
@@ -174,7 +209,7 @@ static void onefs_cbrl_async_failure(uint64_t id)
 
        /* Process the queue. It will end up trying to retake the same lock,
         * see the error in onefs_cbrl_lock_windows() and fail. */
-       process_blocking_lock_queue();
+       process_blocking_lock_queue(smbd_server_conn);
 }
 
 static struct cbrl_event_ops cbrl_ops =
@@ -215,8 +250,8 @@ static void onefs_init_cbrl(void)
 
        DEBUG(10, ("cbrl_event_fd = %d\n", cbrl_event_fd));
 
-       /* Register the oplock event_fd with samba's event system */
-       cbrl_fde = event_add_fd(smbd_event_context(),
+       /* Register the CBRL event_fd with samba's event system */
+       cbrl_fde = event_add_fd(server_event_context(),
                                     NULL,
                                     cbrl_event_fd,
                                     EVENT_FD_READ,
@@ -366,6 +401,10 @@ failure:
        return status;
 
 success:
+       /* Self contend our own level 2 oplock. The kernel handles
+        * contention of other opener's level 2 oplocks. */
+       contend_level2_oplocks_begin(br_lck->fsp,
+           LEVEL2_CONTEND_WINDOWS_BRL);
 
        END_PROFILE(syscall_brl_lock);
 
@@ -400,6 +439,10 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle,
                return false;
        }
 
+       /* For symmetry purposes, end our oplock contention even though its
+        * currently a no-op. */
+       contend_level2_oplocks_end(br_lck->fsp, LEVEL2_CONTEND_WINDOWS_BRL);
+
        DEBUG(10, ("returning true.\n"));
        return true;