/** * Fail any deferred requests that are attached to this oplock, and clear the deferred list * * @return int Number of deferred requests that were failed */ public int failDeferredRequests() { // Check if there are any deferred requests if (m_deferredRequests == null) return 0; int failCnt = 0; synchronized (m_deferredRequests) { for (DeferredRequest deferReq : m_deferredRequests) { // Get the deferred session/packet details SMBSrvSession sess = deferReq.getDeferredSession(); SMBSrvPacket pkt = deferReq.getDeferredPacket(); try { // Return an error for the deferred file open request if (sess.sendAsyncErrorResponseSMB(pkt, SMBStatus.NTAccessDenied, SMBStatus.NTErr) == true) { // Update the failed request count failCnt++; // DEBUG if (Debug.EnableDbg && sess.hasDebug(SMBSrvSession.DBG_OPLOCK)) Debug.println("Oplock break timeout, oplock=" + this); } else if (Debug.EnableDbg && sess.hasDebug(SMBSrvSession.DBG_OPLOCK)) Debug.println("Failed to send open reject, oplock break timed out, oplock=" + this); } catch (IOException ex) { } finally { // Make sure the packet is released back to the memory pool if (pkt != null) sess.getPacketPool().releasePacket(pkt); } } // Clear the deferred request list m_deferredRequests.clear(); } // Return the count of failed requests return failCnt; }
/** * Requeue deferred requests to the thread pool for processing, oplock has been released * * @return int Number of deferred requests requeued */ public int requeueDeferredRequests() { // Check if there are any deferred requests if (m_deferredRequests == null) return 0; int requeueCnt = 0; synchronized (m_deferredRequests) { for (DeferredRequest deferReq : m_deferredRequests) { // Get the deferred session/packet details SMBSrvSession sess = deferReq.getDeferredSession(); SMBSrvPacket pkt = deferReq.getDeferredPacket(); // DEBUG if (Debug.EnableDbg && sess.hasDebug(SMBSrvSession.DBG_OPLOCK)) Debug.println( "Release oplock, queued deferred request to thread pool sess=" + sess.getUniqueId() + ", pkt=" + pkt); try { // Queue the deferred request to the thread pool for processing sess.getThreadPool().queueRequest(new CIFSThreadRequest(sess, pkt)); } catch (Throwable ex) { // Failed to queue the request to the thread pool, release the deferred packet back to the // memory pool sess.getPacketPool().releasePacket(pkt); } } // Clear the deferred request list m_deferredRequests.clear(); } // Return the count of requeued requests return requeueCnt; }
/** * Add a deferred session/packet, whilst an oplock break is in progress * * @param deferredSess SMBSrvSession * @param deferredPkt SMBSrvPacket * @exception DeferFailedException If the session/packet cannot be deferred */ public void addDeferredSession(SMBSrvSession deferredSess, SMBSrvPacket deferredPkt) throws DeferFailedException { // Allocate the deferred request list, if required if (m_deferredRequests == null) { synchronized (this) { if (m_deferredRequests == null) m_deferredRequests = new ArrayList<DeferredRequest>(MaxDeferredRequests); } } // Add the request to the list if there are spare slots synchronized (m_deferredRequests) { if (m_deferredRequests.size() < MaxDeferredRequests) { // Add the deferred request to the list m_deferredRequests.add(new DeferredRequest(deferredSess, deferredPkt)); // Update the deferred processing count for the CIFS packet deferredPkt.incrementDeferredCount(); // Set the time that the oplock break was sent to the client, if this is the first deferred // request if (m_deferredRequests.size() == 1) m_oplockBreakTime = System.currentTimeMillis(); // DEBUG if (Debug.EnableDbg && deferredSess.hasDebug(SMBSrvSession.DBG_OPLOCK)) Debug.println( "Added deferred request, list=" + m_deferredRequests.size() + ", oplock=" + this); } else throw new DeferFailedException("No more deferred slots available on oplock"); } }
/** Run the CIFS request */ public void runRequest() { // Check if the session is still alive if (m_sess.isShutdown() == false) { SMBSrvPacket smbPkt = null; try { // Get the packet handler and read in the CIFS request WinsockNetBIOSPacketHandler pktHandler = (WinsockNetBIOSPacketHandler) m_sess.getPacketHandler(); smbPkt = pktHandler.readPacket(); // Clear the read in progress flag for the session m_sess.setReadInProgress(false); // DEBUG // Debug.println("[SMB] Read packet, sess=" + m_sess.getUniqueId() + " ,pkt=" + smbPkt); // If the request packet is not valid then close the session if (smbPkt == null) { // Close the session m_sess.hangupSession("Client closed socket"); } else { // Re-enable read events for this socket channel // m_reqHandler.requeueSocketEvent( m_socketEvent, // pktHandler.getSocket().getSocket()); } // Process the CIFS request m_sess.processPacket(smbPkt); smbPkt = null; // Process any asynchronous packets (oplock breaks and change notifications) int asyncCnt = m_sess.sendQueuedAsyncResponses(); // DEBUG if (asyncCnt > 0 && Debug.EnableInfo && m_sess.hasDebug(SMBSrvSession.DBG_SOCKET)) Debug.println( "Sent queued async packets (JNI/NIO) count=" + asyncCnt + ", sess=" + m_sess.getUniqueId() + ", addr=" + m_sess.getRemoteAddress().getHostAddress()); } catch (Throwable ex) { Debug.println(ex); } finally { // Make sure the request packet is returned to the pool if (smbPkt != null) m_sess.getPacketPool().releasePacket(smbPkt); } } }