X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fmodules%2Fonefs_cbrl.c;h=2f20d04ddb66a613f9b2464204e68a74da534ed1;hb=bfe4a2baeec6bc4558a617ec67532ea11f865861;hp=a196511427c54f165396e8087b7a568b40091cec;hpb=eaddcfef1ba553744ae9293feaf7585ec9aaa0db;p=samba.git diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c index a196511427c..2f20d04ddb6 100644 --- a/source3/modules/onefs_cbrl.c +++ b/source3/modules/onefs_cbrl.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "smbd/smbd.h" #include "onefs.h" #include @@ -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;