From b48ead62cb5b8a27dc53162a8120ce03d42e035a Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 25 Feb 2008 05:36:46 +0000 Subject: [PATCH] DEVEL15-windows-smb-async-store-20080224 LICENSE MIT Add two new configuration knobs to control the behavior of smb_WriteData. HKLM\SOFTWARE\OpenAFS\Client DWORD EnableSMBAsyncStore (default: 1) DWORD SMBAsyncStoreSize (default: 32K) Instead of tying the async store size to either the chunksize (too large) or the buffer block size (too small) provide an intermediate value that can be independently controlled. In the future it would be desireable for the async store size to be dynamically determined based upon measurable characteristics of the network. In the meantime, 32KB is an acceptable performance compromise that should work well on 1Gbit networks and low-speed cellular networks. (cherry picked from commit f95915a55ae579bab4052f24f6fedca21d114567) --- src/WINNT/afsd/afsd_init.c | 24 +++++++++++++++++++++ src/WINNT/afsd/cm_config.h | 1 + src/WINNT/afsd/smb.c | 44 ++++++++++++++++++++++---------------- src/WINNT/afsd/smb.h | 2 ++ 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 2d2d7869bf..aa3d42fd1d 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -1389,6 +1389,30 @@ int afsd_InitSMB(char **reasonP, void *aMBfunc) (BYTE *) &dwValue, &dummyLen); if (code == ERROR_SUCCESS) smb_StoreAnsiFilenames = dwValue ? 1 : 0; + afsi_log("StoreAnsiFilenames = %d", smb_StoreAnsiFilenames); + + dummyLen = sizeof(DWORD); + code = RegQueryValueEx(parmKey, "EnableSMBAsyncStore", NULL, NULL, + (BYTE *) &dwValue, &dummyLen); + if (code == ERROR_SUCCESS) + smb_AsyncStore = dwValue ? 1 : 0; + afsi_log("EnableSMBAsyncStore = %d", smb_AsyncStore); + + dummyLen = sizeof(DWORD); + code = RegQueryValueEx(parmKey, "SMBAsyncStoreSize", NULL, NULL, + (BYTE *) &dwValue, &dummyLen); + if (code == ERROR_SUCCESS) { + /* Should check for >= blocksize && <= chunksize && round down to multiple of blocksize */ + if (dwValue > cm_chunkSize) + smb_AsyncStoreSize = cm_chunkSize; + else if (dwValue < cm_data.buf_blockSize) + smb_AsyncStoreSize = cm_data.buf_blockSize; + else + smb_AsyncStoreSize = (dwValue & ~(cm_data.buf_blockSize-1)); + } else + smb_AsyncStoreSize = CM_CONFIGDEFAULT_ASYNCSTORESIZE; + afsi_log("SMBAsyncStoreSize = %d", smb_AsyncStoreSize); + RegCloseKey (parmKey); } diff --git a/src/WINNT/afsd/cm_config.h b/src/WINNT/afsd/cm_config.h index d1b0017582..9a2f87ffd0 100644 --- a/src/WINNT/afsd/cm_config.h +++ b/src/WINNT/afsd/cm_config.h @@ -12,6 +12,7 @@ #define CM_CONFIGDEFAULT_CACHESIZE 98304 #define CM_CONFIGDEFAULT_BLOCKSIZE 4096 +#define CM_CONFIGDEFAULT_ASYNCSTORESIZE 32768 /* 32K */ #define CM_CONFIGDEFAULT_STATS 10000 #define CM_CONFIGDEFAULT_CHUNKSIZE 18 /* 256KB */ #define CM_CONFIGDEFAULT_DAEMONS 1 diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index b9972471f9..c0ed2cd791 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -69,6 +69,8 @@ osi_mutex_t smb_StartedLock; unsigned char smb_LANadapter = LANA_INVALID; unsigned char smb_sharename[NCBNAMSZ+1] = {0}; int smb_LanAdapterChangeDetected = 0; +afs_uint32 smb_AsyncStore = 1; +afs_uint32 smb_AsyncStoreSize = CM_CONFIGDEFAULT_ASYNCSTORESIZE; BOOL isGateway = FALSE; @@ -6478,8 +6480,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, osi_hyper_t bufferOffset; afs_uint32 bufIndex; /* index in buffer where our data is */ int doWriteBack = 0; - osi_hyper_t writeBackOffset;/* offset of region to write back when - * I/O is done */ + osi_hyper_t writeBackOffset;/* offset of region to write back when I/O is done */ DWORD filter = 0; cm_req_t req; @@ -6544,14 +6545,15 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, * based upon cm_chunkSize but we desire cm_chunkSize to be large * so that we can read larger amounts of data at a time. */ - if ((thyper.LowPart & ~(cm_data.buf_blockSize-1)) != + if (smb_AsyncStore && + (thyper.LowPart & ~(cm_data.buf_blockSize-1)) != (offset.LowPart & ~(cm_data.buf_blockSize-1))) { /* they're different */ doWriteBack = 1; writeBackOffset.HighPart = offset.HighPart; - writeBackOffset.LowPart = offset.LowPart & ~(cm_data.buf_blockSize-1); + writeBackOffset.LowPart = offset.LowPart & ~(smb_AsyncStoreSize-1); } - + *writtenp = count; /* now, copy the data one buffer at a time, until we've filled the @@ -6700,20 +6702,26 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, } lock_ReleaseMutex(&fidp->mx); - if (code == 0 && doWriteBack) { - long code2; + if (code == 0) { + if (smb_AsyncStore) { + if (doWriteBack) { + long code2; - lock_ObtainMutex(&scp->mx); - osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE", - fidp->fid); - code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); - osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x", - fidp->fid, code2); - lock_ReleaseMutex(&scp->mx); - cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, - writeBackOffset.HighPart, - *writtenp & ~(cm_data.blockSize-1), 0, userp); - /* cm_SyncOpDone is called at the completion of cm_BkgStore */ + lock_ObtainMutex(&scp->mx); + osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE", + fidp->fid); + code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); + osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x", + fidp->fid, code2); + lock_ReleaseMutex(&scp->mx); + cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, + writeBackOffset.HighPart, + *writtenp & ~(cm_data.blockSize-1), 0, userp); + /* cm_SyncOpDone is called at the completion of cm_BkgStore */ + } + } else { + cm_BufWrite(scp, offsetp, *writtenp, 0, userp, &req); + } } cm_ReleaseSCache(scp); diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index 6fb61c81d6..083e53f723 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -671,6 +671,8 @@ extern int smb_maxMpxRequests; /* max # of mpx requests */ extern int smb_StoreAnsiFilenames; extern int smb_hideDotFiles; extern unsigned int smb_IsDotFile(char *lastComp); +extern afs_uint32 smb_AsyncStore; +extern afs_uint32 smb_AsyncStoreSize; /* the following are used for smb auth */ extern int smb_authType; /* Type of SMB authentication to be used. One from below. */