windows-smb-async-store-20080224
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 25 Feb 2008 05:33:54 +0000 (05:33 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 25 Feb 2008 05:33:54 +0000 (05:33 +0000)
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.

src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_config.h
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb.h

index fb21e5f..e5f5431 100644 (file)
@@ -1385,6 +1385,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);
     }
 
index d1b0017..9a2f87f 100644 (file)
@@ -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
index 93996f8..a44ee14 100644 (file)
@@ -64,6 +64,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;
 
@@ -6183,8 +6185,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;
 
@@ -6249,14 +6250,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
@@ -6400,20 +6402,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);
index 72ae0a9..6a80a93 100644 (file)
@@ -656,6 +656,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. */