diff options
-rw-r--r-- | source3/include/smb_macros.h | 2 | ||||
-rw-r--r-- | source3/locking/locking.c | 26 | ||||
-rw-r--r-- | source3/param/loadparm.c | 8 | ||||
-rw-r--r-- | source3/smbd/blocking.c | 6 | ||||
-rw-r--r-- | source3/smbd/reply.c | 12 |
5 files changed, 44 insertions, 10 deletions
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 3fdd90f510..c19be784a1 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -166,7 +166,7 @@ #define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__) #define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1)) -#define SMB_ROUNDUP_ALLOCATION(s) (SMB_ROUNDUP((SMB_OFF_T)((s)+1), ((SMB_OFF_T)SMB_ROUNDUP_ALLOCATION_SIZE))) +#define SMB_ROUNDUP_ALLOCATION(s) ((s) ? (SMB_ROUNDUP((SMB_OFF_T)((s)+1), ((SMB_OFF_T)SMB_ROUNDUP_ALLOCATION_SIZE))) : 0 ) /* Extra macros added by Ying Chen at IBM - speed increase by inlining. */ #define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2) diff --git a/source3/locking/locking.c b/source3/locking/locking.c index dd6ca62e70..8f3e4a278e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -97,7 +97,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ -NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, +static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { NTSTATUS status; @@ -142,6 +142,30 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, } /**************************************************************************** + Utility function called by locking requests. This is *DISGISTING*. It also + appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000 + is so slow on the locking tests...... ? This is the reason. Much though I hate + it, we need this. JRA. +****************************************************************************/ + +NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid, + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) +{ + int j, maxj = lp_lock_spin_count(); + int sleeptime = lp_lock_sleep_time(); + NTSTATUS status; + + for (j = 0; j < maxj; j++) { + status = do_lock(fsp, conn, lock_pid, count, offset, lock_type); + if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && + !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) + break; + usleep(sleeptime); + } + return status; +} + +/**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index ec7d768023..12dedc7a01 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -198,6 +198,8 @@ typedef struct int min_passwd_length; int oplock_break_wait_time; int winbind_cache_time; + int iLockSpinCount; + int iLockSpinTime; #ifdef WITH_LDAP_SAM char *szLdapMachineSuffix; char *szLdapUserSuffix; @@ -965,6 +967,8 @@ static struct parm_struct parm_table[] = { {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE}, {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL}, {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL}, + {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL}, {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, @@ -1319,6 +1323,8 @@ static void init_globals(void) Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ Globals.enhanced_browsing = True; + Globals.iLockSpinCount = 3; /* Try 2 times. */ + Globals.iLockSpinTime = 10; /* usec. */ #ifdef MMAP_BLACKLIST Globals.bUseMmap = False; #else @@ -1659,6 +1665,8 @@ FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size) FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest) FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length) FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time) +FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount) +FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime) FN_LOCAL_STRING(lp_preexec, szPreExec) FN_LOCAL_STRING(lp_postexec, szPostExec) FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec) diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index bc8c54caf7..d4a53d9a6d 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -279,7 +279,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - status = do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, + status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK); if (NT_STATUS_V(status)) { if ((errno != EACCES) && (errno != EAGAIN)) { @@ -345,7 +345,7 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL(inbuf,smb_vwv3); errno = 0; - status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, + status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK); if (NT_STATUS_IS_ERR(status)) { if((errno != EACCES) && (errno != EAGAIN)) { @@ -417,7 +417,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - status = do_lock(fsp,conn,lock_pid,count,offset, + status = do_lock_spin(fsp,conn,lock_pid,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); if (NT_STATUS_IS_ERR(status)) break; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 9d5d34e410..cbcad435d2 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1545,7 +1545,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length * for a write lock. JRA. */ - status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), + status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK); if (NT_STATUS_V(status)) { @@ -2366,7 +2366,7 @@ int reply_lock(connection_struct *conn, DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", fsp->fd, fsp->fnum, (double)offset, (double)count)); - status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK); + status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK); if (NT_STATUS_V(status)) { if (lp_blocking_locks(SNUM(conn))) { /* @@ -3808,6 +3808,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); } /* Setup the timeout in seconds. */ + lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000); /* Now do any requested locks */ @@ -3829,10 +3830,11 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); return ERROR_DOS(ERRDOS,ERRnoaccess); } - DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s\n", - (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); + DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n", + (double)offset, (double)count, (unsigned int)lock_pid, + (int)lock_timeout, fsp->fsp_name )); - status = do_lock(fsp,conn,lock_pid, count,offset, + status = do_lock_spin(fsp,conn,lock_pid, count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); if (NT_STATUS_V(status)) { if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) { |