--- ./source/private_module/ramcache/algorithm/destage/destage_base.c	2018-03-06 06:55:39.000000000 +0000
+++ ./source/private_module/ramcache/algorithm/destage/destage_base.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -173,7 +173,7 @@
     cacheBase->isWriteBackDsgOpen = TRUE;
     cacheBase->isNormalDsgOpen = FALSE;
     cacheBase->isSysDsgOpen = FALSE;
-
+    cacheBase->pad = FALSE;
     spinLockListInit(&cacheBase->sysDsgCmdList);
 }
 
@@ -261,17 +261,17 @@
 bool isCacheBaseNeedDestage(CACHE_BASE_S *cacheBase,int32_t dsgType)
 {
     bool isNeedDestage = TRUE;
-    
+
     switch(dsgType)
     {
         case DESTAGE_TYPE_WT_FAULT_DESTAGE:
+        case DESTAGE_TYPE_WRITETHROUGH:
+            isNeedDestage = !cacheBase->pad;
             break;
         case DESTAGE_TYPE_RECOVER_WRITEHOLE_OK_WRITE_ERROR:
         case DESTAGE_TYPE_WRITEBACK:
             isNeedDestage = cacheBase->isNormalDsgOpen && cacheBase->isWriteBackDsgOpen;
             break;
-        case DESTAGE_TYPE_WRITETHROUGH:
-            break;
         case DESTAGE_TYPE_FORCE_DESTAGE:
             isNeedDestage = cacheBase->isSysDsgOpen && cacheBase->isWriteBackDsgOpen;
             break;
--- ./source/private_module/ramcache/algorithm/destage/destage_ctrl.c	2018-03-23 03:50:15.000000000 +0000
+++ ./source/private_module/ramcache/algorithm/destage/destage_ctrl.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -1308,77 +1308,77 @@
     schedCacheCmdInBase(cmd);
     return;
 }
-
+extern atomic_t g_firstIn;extern void waitCacheBaseDsgDoneOld(IN CACHE_CMD_S *cmd);extern void waitCacheBaseDsgDoneNew(IN CACHE_CMD_S *cmd);
 void waitCacheBaseWriteBackDsgDone(IN CACHE_CMD_S *cmd)
 {
-    CACHE_BASE_S *base = NULL;
 
-    base = getCacheBaseFromCmd(cmd);
-    if(NULL == base)
+    if ((CMD_RECOVER_VOLUME_CACHE_FAULT == cmd->cmdType
+        || CMD_SET_VOLUME_CACHE_FORCE_MIRROR_FLAG == cmd->cmdType
+        || CMD_SET_STRIPE_CACHE_FORCE_MIRROR_FLAG == cmd->cmdType) && 1 == atomic_read(&g_firstIn))
     {
-        cacheSysCmdChildDone(cmd,RETURN_ERROR);
-        return;
+        waitCacheBaseDsgDoneNew(cmd);
     }
-    lockBgrTask();
-    spin_lock(&base->baseLock);
-    base->isWriteBackDsgOpen = FALSE; // ֹͣҪĻдˢ
-    spin_unlock(&base->baseLock);
-    unlockBgrTask();
-
-    /* ȵǰˢ̷ */
-    if(0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITEBACK])
-        && 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_FORCE_DESTAGE])
-        && 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_RECOVER_WRITEHOLE_OK_WRITE_ERROR]))
+    else
     {
-        endLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
-                                (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_END);
-        cacheSysCmdChildDone(cmd, RETURN_OK);
-        return;
+        waitCacheBaseDsgDoneOld(cmd);
     }
-
-    CACHE_LOGINFO_LIMIT(CACHE_LOG_ID_0206,"volumeId (0x%llx) base type (%u) has chunknum(%u,%u,%u) is dsging when stop destage",
-                                base->volumeId,base->baseType,
-                                atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITEBACK]),
-                                atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_FORCE_DESTAGE]),
-                                atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_RECOVER_WRITEHOLE_OK_WRITE_ERROR]));
-
-     /* ȴ */
-    if (0 >= IOD_CREATE_TIMER("stop base write destage timer", 8,//ms
-                               (IOD_TIMER_FUNC)waitCacheBaseWriteBackDsgDone, cmd,
-                               IOD_TIMER_TYPE_ONE))
+    if (!jiffies)
     {
-        DBG_LogError(CACHE_LOG_ID_0205, "Create timer for stop write destage failed.");
-        cmd->retValue = RETURN_ERROR;
-        endLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
-                                (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_END);
-        cacheSysCmdChildDone(cmd,RETURN_ERROR);
-        return;
+    	CACHE_LOGINFO_LIMIT(CACHE_LOG_ID_0206,"is dsging when stop destage");
+                                
     }
-    startLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
-                                  (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_START);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
     return;
 
 }
-
+extern void reOpenCacheBaseDsgSwitchNew(IN CACHE_CMD_S *cmd);extern void reOpenCacheBaseDsgSwitchOld(IN CACHE_CMD_S *cmd);
 void reOpenCacheBaseWriteBackDsgSwitch(IN CACHE_CMD_S *cmd)
 {
-    CACHE_BASE_S *cacheBase = NULL;
-
-    cacheBase = getCacheBaseFromCmd(cmd);
-    if(NULL == cacheBase)
+    if (CMD_RECOVER_VOLUME_CACHE_FAULT == cmd->cmdType
+        || CMD_SET_VOLUME_CACHE_FORCE_MIRROR_FLAG == cmd->cmdType
+        || CMD_SET_STRIPE_CACHE_FORCE_MIRROR_FLAG == cmd->cmdType)
     {
-        cacheSysCmdChildDone(cmd, RETURN_ERROR);
-        return;
+        reOpenCacheBaseDsgSwitchNew(cmd);
+    }
+    else
+    {
+        reOpenCacheBaseDsgSwitchOld(cmd);
     }
 
-    lockBgrTask();
-    spin_lock(&cacheBase->baseLock);
-    cmd->isbackgroundTaskStart = TASK_NOT_START;
-    cacheBase->isWriteBackDsgOpen = TRUE;
-    spin_unlock(&cacheBase->baseLock);
-    unlockBgrTask();
 
-    cacheSysCmdChildDone(cmd,RETURN_OK);
+
+
+
+
+
     return;
 }
 
@@ -2071,3 +2071,150 @@
 }
 
 
+void waitCacheBaseDsgDoneOld(IN CACHE_CMD_S *cmd)
+{
+    CACHE_BASE_S *base = NULL;
+
+    base = getCacheBaseFromCmd(cmd);
+    if(NULL == base)
+    {
+        cacheSysCmdChildDone(cmd,RETURN_ERROR);
+        return;
+    }
+    lockBgrTask();
+    spin_lock(&base->baseLock);
+    base->isWriteBackDsgOpen = FALSE; // ֹͣҪĻдˢ
+    spin_unlock(&base->baseLock);
+    unlockBgrTask();
+
+    /* ȵǰˢ̷ */
+    if(0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITEBACK])
+        && 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_FORCE_DESTAGE])
+        && 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_RECOVER_WRITEHOLE_OK_WRITE_ERROR]))
+    {
+        endLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
+                                (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_END);
+        cacheSysCmdChildDone(cmd, RETURN_OK);
+        return;
+    }
+
+    CACHE_LOGINFO_LIMIT(CACHE_LOG_ID_0206,"volumeId (0x%llx) base type (%u) has chunknum(%u,%u,%u) is dsging when stop destage",
+                                base->volumeId,base->baseType,
+                                atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITEBACK]),
+                                atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_FORCE_DESTAGE]),
+                                atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_RECOVER_WRITEHOLE_OK_WRITE_ERROR]));
+
+     /* ȴ */
+    if (0 >= IOD_CREATE_TIMER("stop base write destage timer", 8,//ms
+                               (IOD_TIMER_FUNC)waitCacheBaseWriteBackDsgDone, cmd,
+                               IOD_TIMER_TYPE_ONE))
+    {
+        DBG_LogError(CACHE_LOG_ID_0205, "Create timer for stop write destage failed.");
+        cmd->retValue = RETURN_ERROR;
+        endLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
+                                (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_END);
+        cacheSysCmdChildDone(cmd,RETURN_ERROR);
+        return;
+    }
+    startLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
+                                  (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_START);
+    return;
+}
+void waitCacheBaseDsgDoneNew(IN CACHE_CMD_S *cmd)
+{
+    CACHE_BASE_S *base = NULL;
+    base = getCacheBaseFromCmd(cmd);
+    if(NULL == base)
+    {
+        cacheSysCmdChildDone(cmd,RETURN_ERROR);
+        return;
+    }
+
+    lockBgrTask();
+    spin_lock(&base->baseLock);
+    base->isWriteBackDsgOpen = FALSE;
+    base->pad = TRUE;
+    spin_unlock(&base->baseLock);
+    unlockBgrTask();
+
+	if(0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITEBACK])
+	&& 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_FORCE_DESTAGE])
+	&& 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_RECOVER_WRITEHOLE_OK_WRITE_ERROR])
+	&& 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITETHROUGH])
+	&& 0 == atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WT_FAULT_DESTAGE]))
+	{
+		endLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
+							(DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_END);
+		cacheSysCmdChildDone(cmd, RETURN_OK);
+		return;
+	}
+
+	CACHE_LOGINFO_LIMIT(CACHE_LOG_ID_0206,"volumeId (0x%llx) base type (%u) has chunknum(%u,%u,%u,%u,%u) is dsging when stop destage",
+								base->volumeId,base->baseType,
+								atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITEBACK]),
+								atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_FORCE_DESTAGE]),
+								atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_RECOVER_WRITEHOLE_OK_WRITE_ERROR]),
+								atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WRITETHROUGH]),
+                                atomic_read(&base->chunkDestagingNum[DESTAGE_TYPE_WT_FAULT_DESTAGE]));
+
+    if (0 >= IOD_CREATE_TIMER("stop base write destage timer", 8,//ms
+                               (IOD_TIMER_FUNC)waitCacheBaseWriteBackDsgDone, cmd,
+                               IOD_TIMER_TYPE_ONE))
+    {
+        DBG_LogError(CACHE_LOG_ID_0205, "Create timer for stop write destage failed.");
+        cmd->retValue = RETURN_ERROR;
+        endLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
+                                (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_END);
+        cacheSysCmdChildDone(cmd,RETURN_ERROR);
+        return;
+    }
+    startLogcbbTaskStatistics(cmd, (uint64_t)WAIT_CACHE_BASE_WB_DSG_FINISH,
+                                  (DBG_LABEL_STAT_E)WAIT_CACHE_BASE_WB_DSG_FINISH_START);
+    return;
+}
+
+void reOpenCacheBaseDsgSwitchOld(IN CACHE_CMD_S *cmd)
+{
+    CACHE_BASE_S *cacheBase = NULL;
+
+    cacheBase = getCacheBaseFromCmd(cmd);
+    if(NULL == cacheBase)
+    {
+        cacheSysCmdChildDone(cmd, RETURN_ERROR);
+        return;
+    }
+
+    lockBgrTask();
+    spin_lock(&cacheBase->baseLock);
+    cmd->isbackgroundTaskStart = TASK_NOT_START;
+    cacheBase->isWriteBackDsgOpen = TRUE;
+    spin_unlock(&cacheBase->baseLock);
+    unlockBgrTask();
+
+    cacheSysCmdChildDone(cmd,RETURN_OK);
+    return;
+}
+
+void reOpenCacheBaseDsgSwitchNew(IN CACHE_CMD_S *cmd)
+{
+    CACHE_BASE_S *cacheBase = NULL;
+
+    cacheBase = getCacheBaseFromCmd(cmd);
+    if(NULL == cacheBase)
+    {
+        cacheSysCmdChildDone(cmd, RETURN_ERROR);
+        return;
+    }
+
+    lockBgrTask();
+    spin_lock(&cacheBase->baseLock);
+    cmd->isbackgroundTaskStart = TASK_NOT_START;
+    cacheBase->isWriteBackDsgOpen = TRUE;
+    cacheBase->pad = FALSE;
+    spin_unlock(&cacheBase->baseLock);
+    unlockBgrTask();
+
+    cacheSysCmdChildDone(cmd,RETURN_OK);
+    return;
+}
+
--- ./source/private_module/ramcache/algorithm/destage/destage_stripe.c	2018-03-06 06:55:39.000000000 +0000
+++ ./source/private_module/ramcache/algorithm/destage/destage_stripe.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -714,8 +714,6 @@
     reqComm->chunkList = NULL;
     cacheCkg = getCacheCkgFromWriteChunk(chunk);
 
-    chunk->isWriteThrough = !(dsgPriv->isWriteholeBack);
-
     if (((B_FALSE == isFullWriteChunk(chunk))
         || (TIER_TYPE_SSD == cacheCkg->ckgDsgData.tierId))
         && B_FALSE == checkCkgCanDestage(cacheCkg,destageReq,dsgType))
@@ -738,7 +736,9 @@
             return RETURN_ERROR;
         }
     }
-
+    spin_lock(&chunk->stateLock);
+    chunk->isWriteThrough = !(dsgPriv->isWriteholeBack);
+    spin_unlock(&chunk->stateLock);
     /*destage req*/
     dsgPriv->genReqList = genDestageReqList(destageReq);
     if (unlikely(NULL == dsgPriv->genReqList))
--- ./source/private_module/ramcache/algorithm/destage/destage_volume_algorithm.c	2018-03-06 06:55:39.000000000 +0000
+++ ./source/private_module/ramcache/algorithm/destage/destage_volume_algorithm.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -816,15 +816,12 @@
 LIST_NODE_S *pttWtSelectFromTimepoint(DESTAGE_TIMEPOINT_S *destageTimepoint, WRITE_CHUNK_S **emptyChunkList)
 {
     LIST_NODE_S *chunkList = NULL;
-
     void *curNode, *nextNode;
-
     CHUNK_DSG_INFO_S *chunkDsgInfo;
     CACHE_BASE_DSG_DATA_S *cacheBaseDsgInfo;
     WRITE_CHUNK_S *writeChunk;
     WRITE_CHUNK_S *lastChunk = NULL;
     CACHE_BASE_S  *cacheBase;
-
     int32_t maxSelectChunkNum = 1;
     int32_t selectChunkNum;
     int32_t result;
@@ -832,7 +829,8 @@
     uint64_t startTime = jiffies;
     void *chunkTable;
 	PTT_WT_DESTAGE_S* pttWtDestageObj;
-
+    DESTAGE_OBJ_S* pttDsgObj;
+    uint16_t pttId;
     uint64_t lastSelectLba = 0ULL;
     int32_t isSeqFlowWait = FALSE;
 
@@ -853,7 +851,9 @@
     {
         chunkDsgInfo = container_of(curNode, CHUNK_DSG_INFO_S, lruNode);
         writeChunk = GET_CHUNK_ENTRY_BY_DSG_INFO(chunkDsgInfo);
-        pttWtDestageObj = GET_PTT_WT_DESTAGE_OBJ(chunkDsgInfo->destageObj);
+        pttId = getCachePartitionIdFromWriteChunk(writeChunk);
+        pttDsgObj = getPttDestageObj(pttId, DESTAGE_TYPE_WRITETHROUGH);
+        pttWtDestageObj = GET_PTT_WT_DESTAGE_OBJ(pttDsgObj);/* DTS2018072411166 ӷobjȡ */
         if (checkChunkInBoundary(cacheBase, writeChunk, lastChunk))
         {
             break;
@@ -874,13 +874,15 @@
             atomic_dec(&cacheBase->chunkCntInDestageTable[DESTAGE_TYPE_WRITETHROUGH]);
             atomic_dec(&(pttWtDestageObj->ops.waitChunkCnt));
             atomic64_dec(&destageTimepoint->ref);
-            spinLockListAddTail(&chunkDsgInfo->listNode, &pttWtDestageObj->faultDestageTable);
-            chunkDsgInfo->destageType = DESTAGE_TYPE_WT_FAULT_DESTAGE;
-
+            spin_lock(&writeChunk->stateLock);
             lockWriteChunk(writeChunk);
             writeChunk->needWtFaultDsg = B_FALSE;
+            chunkDsgInfo->destageType = DESTAGE_TYPE_WT_FAULT_DESTAGE;
+            chunkDsgInfo->destageObj = &pttWtDestageObj->ops;
             unlockWriteChunk(writeChunk);
+            spin_unlock(&writeChunk->stateLock);
 
+            spinLockListAddTail(&chunkDsgInfo->listNode, &pttWtDestageObj->faultDestageTable);
             CACHE_LOGINFO_LIMIT(0, "insert fault dsg."LOG_FORMAT_WRITE_CHUNK, LOG_PARAM_WRITE_CHUNK(writeChunk));
             continue;
         }
@@ -946,9 +948,7 @@
         FREE_LIST_NODE_CHAIN(chunkList);
         return NULL;
     }
-
     return chunkList;
-
 }
 
 LIST_NODE_S *pttForceDsgSelectFromTimePoint(DESTAGE_TIMEPOINT_S *destageTimepoint, WRITE_CHUNK_S **emptyChunkList)
@@ -3642,6 +3642,8 @@
         atomic_inc(&cacheBase->chunkDestagingNum[DESTAGE_TYPE_WT_FAULT_DESTAGE]);
         if (RETURN_OK == startChunkDestage(writeChunk))
         {
+            atomic_inc(&cacheBase->chunkDestagingNum[writeChunk->predestageType]);
+            atomic_dec(&cacheBase->chunkDestagingNum[DESTAGE_TYPE_WT_FAULT_DESTAGE]);
             INC_DBG_LABEL_STAT(PTT_FAULT_DSG_FOUND_CHUNK);
             CACHE_LOGINFO_LIMIT(0, "select fault dsg."LOG_FORMAT_WRITE_CHUNK, LOG_PARAM_WRITE_CHUNK(writeChunk));
             spinLockListDelNoLock(&chunkDsgInfo->listNode, &destageObj->faultDestageTable);
@@ -3650,10 +3652,8 @@
 
             incWriteChunkRef(writeChunk, WRITE_CHUNK_START_DESTAGE);
             chunkDsgInfo->destageObj = NULL;
-
             result = insertDataToListNode(&chunkList, writeChunk, LIST_NODE_ALLOC_TYPE_28);
             SYS_BUG_EXP(RETURN_OK == result, SYS_BUG_CRI, MODULE_FUNC_END, "Bug: (%s) not satisfy.", "RETURN_OK == result");
-
             UNREFERENCE_PARAM(result);
 
             if (++selectChunkNum >= PTT_WT_SELECT_CHUNK_NUM)
--- ./source/private_module/ramcache/algorithm/evict/evict_frame.c	2018-02-09 13:47:03.000000000 +0000
+++ ./source/private_module/ramcache/algorithm/evict/evict_frame.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -400,7 +400,7 @@
 
     return;
 }
-
+extern void initWtDsgSwitch(void);
 /**************************************************************************
      :  ʱʱ
  :
@@ -412,7 +412,7 @@
 void evictTimerTimeOutFuc(IN void * arg)
 {
     uint32_t i;
-
+    initWtDsgSwitch();
     UNREFERENCE_PARAM(arg);
 
     for (i = 0; i < MAX_EVICT_PARTITION_NUM; i++)
--- ./source/private_module/ramcache/debug/diagnose/diagnose_cache.c	2018-03-23 03:50:15.000000000 +0000
+++ ./source/private_module/ramcache/debug/diagnose/diagnose_cache.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -6421,9 +6421,9 @@
     if (0 == argc)
     {
         DBG_Print("cache show puleyhigh %d, 1:yes, 0:no; g_isNeedAdjustPoolRetryNum:%d.\n", g_isPurleyHigh, g_isNeedAdjustPoolRetryNum);
+
         return RETURN_OK;
     }
-
     if ( 0 == strcmp(argv[0], "on") )
     {
         g_isPurleyHigh = TRUE;
@@ -6439,17 +6439,17 @@
     }
 
     if (argc == 2)
-    {
-        if ( 0 == strcmp(argv[0], "on") )
-        {
+	{
+        if ( 0 == strcmp(argv[1], "on") )
+		{
             g_isNeedAdjustPoolRetryNum = TRUE;
         }
-        else if ( 0 == strcmp(argv[0], "off") )
-        {
+        else if ( 0 == strcmp(argv[1], "off") )
+		{
             g_isNeedAdjustPoolRetryNum = FALSE;
         }
         else
-        {
+		{
             DBG_Print("please input on or off!\n");
             return RETURN_ERROR;
         }
@@ -8248,4 +8248,3 @@
     }
     return;
 }
-
--- ./source/private_module/ramcache/debug/diagnose/diagnose_cache_obj.c	2018-02-09 13:47:03.000000000 +0000
+++ ./source/private_module/ramcache/debug/diagnose/diagnose_cache_obj.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -623,7 +623,7 @@
     DBG_Print("  taskRuningRef                     : %-26d\n", atomic_read(&cacheBase->taskRuningRef));
 
     DBG_Print("  isWriteBackDsgOpen               : %-26u\n", cacheBase->isWriteBackDsgOpen);
-
+    DBG_Print("  isWriteThroughDsgOpen            : %-26u\n", cacheBase->pad ? 0 : 1);
     DBG_Print("  sysDsgCmdList sum                : %-26u\n", cacheBase->sysDsgCmdList.sum); /* ϵͳˢУڼ¼ص, пж*/
 
     DBG_Print("  list node in task list            : %-26s", " ");
@@ -928,10 +928,10 @@
 
     DBG_Print("  bgrRuningRef                     : %-26d:  %d\n",  atomic_read(&cacheBase1->taskRuningRef),
                                                                     atomic_read(&cacheBase2->taskRuningRef));
-
     DBG_Print("  isWriteBackDsgOpen               : %-26u:  %u\n",  cacheBase1->isWriteBackDsgOpen,
                                                                     cacheBase2->isWriteBackDsgOpen);
-
+    DBG_Print("  isWriteThroughDsgOpen            : %-26u:  %u\n",  cacheBase1->pad ? 0 : 1,
+                                                                    cacheBase2->pad ? 0 : 1);
     DBG_Print("  list node in bgr list            : %-d %d:  %d %d\n", IS_LIST_NODE_INIT(&cacheBase1->bgrNode[0])? 0:1, IS_LIST_NODE_INIT(&cacheBase1->bgrNode[1])? 0:1,
                                                                        IS_LIST_NODE_INIT(&cacheBase2->bgrNode[0])? 0:1, IS_LIST_NODE_INIT(&cacheBase2->bgrNode[1])? 0:1);
     DBG_Print("  sysDsgCmdList sum                : %-26u : %u\n", cacheBase1->sysDsgCmdList.sum,
@@ -5150,10 +5150,8 @@
     {
         return RETURN_ERROR;
     }
-
     UNREFERENCE_PARAM(argc);
     UNREFERENCE_PARAM(argv);
-
 #ifdef MACRO_CACHE_SPC1
     DBG_Print("compile version                 : spc1 macro 1021 1132 \n");
 #else
@@ -5179,11 +5177,11 @@
     DBG_Print("Async Prefetch Cur Req Concur   : %d\n", atomic_read(&g_asyncPrefetchReqConcurrent));
     DBG_Print("Cache update state              : %d\n", getUpdateState());
     DBG_Print("Cache force write back type     : %d\n", g_forceWriteBackType);
-
     DBG_Print("VNode 0 mirror nid              : %d\n", getVNodeMirrorCtrl(0));
     DBG_Print("VNode 1 mirror nid              : %d\n", getVNodeMirrorCtrl(1));
     DBG_Print("VNode 2 mirror nid              : %d\n", getVNodeMirrorCtrl(2));
     DBG_Print("VNode 3 mirror nid              : %d\n", getVNodeMirrorCtrl(3));
+	
     return RETURN_OK;
 }
 int32_t diagShowCacheLimitIo(int32_t argc, char *argv[])
--- ./source/private_module/ramcache/iocore/write/write_base.c	2018-02-09 13:47:03.000000000 +0000
+++ ./source/private_module/ramcache/iocore/write/write_base.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -548,9 +548,7 @@
 PRIVATE void stripeCachehandleMirrorDifErrAfterMirror(REQ_S* req, uint64_t volId, bool *needRetry)
 {
     CACHE_WRITEDATA_REQ_PRIVATE_S *ioPrivate = NULL;
-
     ioPrivate = GET_CACHE_REQ_PRIVATE(req);
-
     if (ioPrivate->mirCommon.difErrRetryCnt > 0)
     {
         *needRetry = TRUE;
@@ -566,6 +564,7 @@
             {
                 CACHE_LOGINFO_LIMIT(CACHE_LOG_ID_220B,"Check Dif Crc error,IO become write through.");
                 ioPrivate->writeThrough = TRUE;
+                ioPrivate->writeVolatile = TRUE;
                 ioPrivate->mirCommon.needCheckdif = FALSE;
             }
         }
@@ -576,6 +575,7 @@
             {
                 CACHE_LOGINFO_LIMIT(CACHE_LOG_ID_220B,"difErrRetryCnt(1),IO become write through.");
                 ioPrivate->writeThrough = TRUE;
+                ioPrivate->writeVolatile = TRUE;
                 ioPrivate->mirCommon.needCheckdif = FALSE;
             }
         }
@@ -587,6 +587,7 @@
             CACHE_LOGINFO_LIMIT(CACHE_LOG_ID_220B,"difErrRetryCnt(0),IO become write through.");
             *needRetry = TRUE;
             ioPrivate->writeThrough = TRUE;
+            ioPrivate->writeVolatile = TRUE;
             ioPrivate->mirCommon.needCheckdif = FALSE;
         }
         else
@@ -594,7 +595,6 @@
             *needRetry = FALSE;
         }
     }
-
     return;
 }
 
@@ -704,6 +704,7 @@
         {
             CACHE_IO_BACKBAD(CACHE_IO_COUNTER_DIF_STRIPE_LBA);
             ioPrivate->writeThrough = TRUE;
+            ioPrivate->writeVolatile = TRUE;
             ioPrivate->mirCommon.needCheckdif = FALSE;
         }
     }
@@ -759,7 +760,6 @@
     }
 
     CACHE_IO_BACKGOOD(STRIPE_WRITE_CHILD_WRITE_MIRROR);
-
     /* ɹд */
     stpCacheWriteDataToChunk(baseObj, req);
     UNREFERENCE_PARAM(opattr);
--- ./source/private_module/ramcache/iocore/write/write_stripe.c	2018-03-23 03:50:15.000000000 +0000
+++ ./source/private_module/ramcache/iocore/write/write_stripe.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -1639,7 +1639,7 @@
     CACHE_BASE_S *cacheBase = NULL;
     REQ_S *req = ctx;
     uint32_t pageNum = 0;
-    
+
     ioPrivate = GET_CACHE_REQ_PRIVATE(req);
     writeChunk = ioPrivate->common.writeChunk;
     cacheBase = ioPrivate->common.cacheBasePtr;
@@ -1707,44 +1707,44 @@
                          WRITE_HOST_VOLATILE_DIRTY_DATA);
         return;
     }
-    else if ((!ioPrivate->allocQuotaBeforeMirror
-          && isCacheBaseWriteVolatile(cacheBase) 
-          && isCacheBaseCanWriteMirror(cacheBase))
-          || (0 != isAllVolumeCacheWriteThroughBak))
-    {
-        /* µУھǻдڱغ뵽͸д
-           ҪѶԶ˵İ͸ддٵ͸дд */
-        //DBG_LogInfo(CACHE_LOG_ID_133B, "writing back and writint through is matched.");
-        ioPrivate->writeVolatile = TRUE;
-        ioPrivate->writeThrough  = TRUE;
 
-        /* Ȱquotaͷ */
-        ioPrivate->needFreeQuota = FALSE;
-        cacheBase->ops->freeCacheDirtyDataQuota(cacheBase,
-                                  getQuotaObjFromWriteChunk(ioPrivate->common.writeChunk),
-                                  req->objectId,
-                                  ioPrivate->common.pageNum);
-
-        UPDATE_IO_STEP_TIME(cacheBase, req, IO_STEP_OP_WRITE_SUB_REQ_SEND_MIRR, B_FALSE);
-        INC_DBG_LABEL_STAT(REMOTE_SGL_22);
-        writeStpCacheToPeer(req);
-        CACHE_IO_BACK(WRITE_LOCAL_CHUNK, ret);
-        return;
-    }
-    
-    if (unlikely(ioPrivate->writeThrough))
-    {
-        writeDataToChunk(writeChunk,
-                         req->sgl,
-                         req->bufOffsetNByte,
-                         req->objectLba,
-                         req->length,
-                         NULL,
-                         writeDataDone,
-                         req,
-                         WRITE_THROUGH_HOST_DIRTY_DATA);
-        return;
-    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
     writeDataToChunk(writeChunk,
                      req->sgl,
--- ./source/private_module/ramcache/iocore/write/write_volume.c	2018-02-09 13:47:03.000000000 +0000
+++ ./source/private_module/ramcache/iocore/write/write_volume.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -833,7 +833,7 @@
 {
     CACHE_WRITEDATA_REQ_PRIVATE_S *ioPrivate = NULL;
     WRITE_CHUNK_S * writeChunk = NULL;
-    CACHE_BASE_S *cacheBase = NULL;
+
     REQ_S *req = ctx;
 
     UNREFERENCE_PARAM(ret);
@@ -843,7 +843,7 @@
     CACHE_FTDS_TRACE_RECORD_BUF(req,CACHE_FTDS_TRACE_VOL_ALLOC_DIRTY_AFTER, NULL);
 
     CACHE_IO_START(WRITE_LOCAL_CHUNK);
-    cacheBase = GET_CACHE_BASE_FROM_WRITE_CHUNK(writeChunk);
+
 
     /* ftds only Դǰ ҪReq */
     copyCtxTrace2Req(req);
@@ -864,47 +864,47 @@
                          WRITE_HOST_VOLATILE_DIRTY_DATA);
         return;
     }
-    else if (!ioPrivate->allocQuotaBeforeMirror
-          && isCacheBaseWriteVolatile(cacheBase)
-          && isCacheBaseCanWriteMirror(cacheBase))
-    {
-        /* µУھǻдڱغ뵽͸д
-           ҪѶԶ˵İ͸ддٵ͸дд */
-        ioPrivate->writeVolatile = TRUE;
-        ioPrivate->writeThrough  = TRUE;
-
-        /* Ȱquotaͷ */
-        ioPrivate->needFreeQuota = FALSE;
-        cacheBase->ops->freeCacheDirtyDataQuota(cacheBase,
-                                  getQuotaObjFromWriteChunk(ioPrivate->common.writeChunk),
-                                  req->objectId,
-                                  ioPrivate->common.pageNum);
-
-        freeRemoteSglChain(req);
-        CACHE_LOGINFO_LIMIT(0, "Retry mirror write(%p):"LOG_FORMAT_REQ,
-                       req, LOG_PARAM_REQ(req));
-        UPDATE_IO_STEP_TIME(cacheBase, req, IO_STEP_OP_WRITE_SUB_REQ_SEND_MIRR, B_FALSE);
-        writeVolCacheToPeer(req);
-        CACHE_IO_BACK(WRITE_LOCAL_CHUNK, ret);
-        return;
-    }
 
 
-    if (unlikely(ioPrivate->writeThrough))
-    {
-//        copyCtxTrace2Req(req);
-        writeDataToChunk(writeChunk,
-                         req->sgl,
-                         req->bufOffsetNByte,
-                         req->objectLba,
-                         req->length,
-                         req->remoteSgl,
-                         writeDataDone,
-                         req,
-                         WRITE_THROUGH_HOST_DIRTY_DATA);
-        return;
-    }
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    if(!jiffies){CACHE_LOGINFO_LIMIT(0, "Retry mirror write(%p):"LOG_FORMAT_REQ,req, LOG_PARAM_REQ(req));}
 //    copyCtxTrace2Req(req);
     writeDataToChunk(writeChunk,
                      req->sgl,
--- ./source/private_module/ramcache/iocore/write/writehole.c	2018-03-27 03:28:56.000000000 +0000
+++ ./source/private_module/ramcache/iocore/write/writehole.c.hotpatch	2018-09-18 13:12:54.000000000 +0000
@@ -1524,13 +1524,13 @@
         {
             if (NULL != writeChunk)
             {
-                spin_lock(&writeChunk->stateLock);
                 /* ״̬˵ǻָchunk */
                 if (!IS_WRITE_CHUNK_FAULT(writeChunk))
                 {
                     setWriteChunkFaultType(cacheBase, writeChunk, CHUNK_FAULT_TYPE_WRITE_HOLE_LOG_FAULT, __FUNCTION__);
                     writeChunk->priv.stripePriv.isCkgWriteHole = TRUE;
                 }
+                spin_lock(&writeChunk->stateLock);
                 // writehole meduim errorԻָߵdestaging״̬Ҫ˵
                 if(writeChunk->state != WRITE_CK_STATE_DESTAGING)
                 {
--- ./source/private_module/ramcache/metadata/cachechunk/cache_chunk.c	2018-04-26 09:14:15.000000000 +0000
+++ ./source/private_module/ramcache/metadata/cachechunk/cache_chunk.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -175,6 +175,7 @@
 	writeChunk->needWtFaultDsg = B_FALSE;
     writeChunk->forceMirrorState = CHUNK_FORCE_MIRROR_STATE_FREE;
     writeChunk->isWriteThrough = B_FALSE;;
+    writeChunk->seqInfo.triggerInterval = FALSE; //Ƿvolatileݱɾ
     INIT_LIST_HEAD(&(writeChunk->listNode));
 
     for(i  = 0; i < CHUNK_HANG_FOR_BUTT; i++)
@@ -187,7 +188,6 @@
 
     writeChunk->memDbgLog = createMemoryDbgLog();
     spin_lock_init(&writeChunk->stateLock);
-
     initChunkDestageData(writeChunk);
     SET_WRITE_CHUNK_CPS_CHUNK(writeChunk, NULL);
 }
@@ -272,6 +272,7 @@
 	volWriteChunk->needWtFaultDsg = B_FALSE;
     volWriteChunk->faultType      = CHUNK_FAULT_TYPE_NONE;
     volWriteChunk->faultPageCnt   = 0;
+    volWriteChunk->seqInfo.triggerInterval = FALSE;  //Ƿvolatileݱɾ
     atomic_set(&(volWriteChunk->dirtyPageCnt), 0);
     atomic_set(&(volWriteChunk->dirtyQuotaCnt), 0);
     volWriteChunk->data           = NULL;
@@ -325,7 +326,6 @@
     SET_WRITE_CHUNK_CPS_CHUNK(volWriteChunk, NULL);
 
     setWriteChunkValidType(volWriteChunk, WRITE_CHUNK_VALID);
-
     return RETURN_OK;
 }
 
@@ -358,7 +358,7 @@
     stpWriteChunk->predestageType    = 0;
 	stpWriteChunk->needWtFaultDsg = B_FALSE;
     stpWriteChunk->state          = WRITE_CK_STATE_INIT;
-
+    stpWriteChunk->seqInfo.triggerInterval = FALSE;  //Ƿvolatileݱɾ
     /* ʼʷ״ֱ̬ܿӸֵ */
     stpWriteChunk->hisEvent.chunkEvent = 0;
     stpWriteChunk->hisTrace.chunkTrace[0] =0;
@@ -1669,25 +1669,20 @@
     WRITE_CHUNK_S *nextWriteChunk = NULL;
     int32_t ret = RETURN_OK;
     int32_t callBackRet = RETURN_OK;
-
-    /* ǷҪchunk ??  */
+    uint64_t curTime = jiffies;
     currentWriteChunk = writeChunk;
     while (NULL != currentWriteChunk)
     {
-        /* Ȱһڵȡ */
         nextWriteChunk = getNextOldTpWriteChunk(currentWriteChunk, trace);
         callBackRet = callback(currentWriteChunk, arg);
-        /* δɾͷŵǰü */
         if (RETURN_CACHE_HAS_DEL != callBackRet)
         {
             if (RETURN_OK != callBackRet)
             {
                 ret = RETURN_ERROR;
             }
-
             if (currentWriteChunk != writeChunk)
             {
-                /* ҪȼӼöֵ1 */
                 decAndCheckWriteChunkRef(currentWriteChunk, trace + 1);
             }
         }
@@ -1696,6 +1691,11 @@
             ; /* ǰchunkɾ */
         }
         currentWriteChunk = nextWriteChunk;
+        if(LVOS_TIME_AFTER((OSP_ULONG)jiffies, (OSP_ULONG)(curTime + 20)))
+        {
+            LVOS_usleep(10);
+            curTime = jiffies;
+        }
     }
 
     return ret;
@@ -3793,8 +3793,8 @@
     return;
 }
 
-
-
+extern void setWriteChunkFaultPageCnt(WRITE_CHUNK_S *writeChunk,OUT int32_t *dirtyPageCnt,OUT int32_t *dirtyParityPageCnt,OUT uint32_t *pageUnitCnt);
+extern void insertBaseToBgrFaultRecoverTask(CACHE_BASE_S *baseObj,WRITE_CHUNK_S *writeChunk);
 void updateWriteChunkFaultPageCnt(CACHE_BASE_S *baseObj, WRITE_CHUNK_S *writeChunk,
                                   int32_t pageCnt, int32_t parityCnt, const OSP_CHAR* pcFunName)
 {
@@ -3818,7 +3818,7 @@
 
     return;
 }
-
+extern void removeFaultWriteChunkFromBaseNoLock(CACHE_BASE_S *cacheBase,WRITE_CHUNK_S *writeChunk);
 PRIVATE inline void updateCacheBaseSpecialFaultCnt(CACHE_BASE_S *cacheBase,
                                                    uint32_t faultType,
                                                    int32_t cnt)
@@ -3858,7 +3858,7 @@
 
     }
 }
-
+extern void insertFaultWriteChunkToBaseNoLock(CACHE_BASE_S *baseObj,WRITE_CHUNK_S *writeChunk);
 /**************************************************************************
      :  faultchunk
  :CACHE_BASE_S  *baseObj,
@@ -3949,92 +3949,92 @@
 
     return;
 }
-
-
+extern void updateBaseAndDomainFaultChunkCnt(CACHE_BASE_S  *baseObj,WRITE_CHUNK_S *writeChunk,uint32_t faultType,const OSP_CHAR* pcFunName,bool isAddFault);
+extern void getWriteChunkFaultPageCnt(WRITE_CHUNK_S *writeChunk,OUT int32_t *dirtyPageCnt,OUT int32_t *dirtyParityPageCnt,OUT uint32_t *pageUnitCnt);
 void setWriteChunkFaultType(IN CACHE_BASE_S  *cacheBase,
                             IN WRITE_CHUNK_S *writeChunk,
                             IN uint32_t faultType,
                             IN const OSP_CHAR* pcFunName)
 {
     uint32_t oldFaultType;
-    int32_t dirtyParityPageCnt;
 
     int32_t incFaultPageCnt;
     int32_t decFaultPageCnt;
     uint32_t incPageUnitCnt;
     uint32_t decPageUnitCnt;
-    int32_t oldFaultPageCnt;
-
+    int32_t incDirtyParityPageCnt;
+    int32_t decDirtyParityPageCnt;
+    lockWriteChunk(writeChunk);
+    if (faultType == writeChunk->faultType)
+    {
+        unlockWriteChunk(writeChunk);
+        return;
+    }
+    unlockWriteChunk(writeChunk);
+    spinLockListLock(&cacheBase->faultWriteChunkList);
+    spin_lock(&writeChunk->stateLock);
     lockWriteChunk(writeChunk);
     if (faultType == writeChunk->faultType)
     {
         unlockWriteChunk(writeChunk);
+        spin_unlock(&writeChunk->stateLock);
+        spinLockListUnLock(&cacheBase->faultWriteChunkList);
         return;
     }
 
     if (!IS_WRITE_CHUNK_FAULT(writeChunk))
     {
-        incWriteChunkFaultCnt(cacheBase, writeChunk, faultType, pcFunName,
-                              &incFaultPageCnt, &dirtyParityPageCnt, &incPageUnitCnt);
-        writeChunk->faultType = faultType;
+        writeChunk->faultType = (uint8_t)faultType;
+        setWriteChunkFaultPageCnt(writeChunk, &incFaultPageCnt, &incDirtyParityPageCnt, &incPageUnitCnt);
+        atomic_inc(&cacheBase->faultChunkNum);
+        insertFaultWriteChunkToBaseNoLock(cacheBase,writeChunk);
         unlockWriteChunk(writeChunk);
-
+        spin_unlock(&writeChunk->stateLock);
+        spinLockListUnLock(&cacheBase->faultWriteChunkList);
+        updateBaseAndDomainFaultChunkCnt(cacheBase, writeChunk, faultType, pcFunName, TRUE);
+        insertBaseToBgrFaultRecoverTask(cacheBase,writeChunk);
         addWriteChunkFaultQuota(cacheBase, writeChunk,1, incPageUnitCnt);
-        updateWriteChunkFaultPageCnt(cacheBase, writeChunk,
-                                 incFaultPageCnt,
-                                 dirtyParityPageCnt,
-                                 pcFunName);
-        insertFaultWriteChunkToBase(cacheBase,writeChunk);
+        updateWriteChunkFaultPageCnt(cacheBase, writeChunk,incFaultPageCnt,incDirtyParityPageCnt,pcFunName);
+
     }
     else if (CHUNK_FAULT_TYPE_NONE != faultType)
     {
         /* Ϊfault  */
         oldFaultType = writeChunk->faultType;
-        oldFaultPageCnt = writeChunk->faultPageCnt;
         writeChunk->faultType = faultType;
-
-        /* ӼظΪָɹ */
-
-        incWriteChunkFaultCnt(cacheBase, writeChunk, faultType, pcFunName,
-                              &incFaultPageCnt, &dirtyParityPageCnt, &incPageUnitCnt);
-
-        decWriteChunkFaultCnt(cacheBase, writeChunk, oldFaultType, pcFunName,
-                              &decFaultPageCnt, &dirtyParityPageCnt, &decPageUnitCnt);
-
-        decFaultPageCnt = oldFaultPageCnt;
-        writeChunk->faultPageCnt = (int16_t)atomic_read(&writeChunk->dirtyPageCnt);
-
+        getWriteChunkFaultPageCnt(writeChunk, &decFaultPageCnt, &decDirtyParityPageCnt, &decPageUnitCnt);
+        setWriteChunkFaultPageCnt(writeChunk, &incFaultPageCnt, &incDirtyParityPageCnt, &incPageUnitCnt);
+        insertFaultWriteChunkToBaseNoLock(cacheBase,writeChunk);
         unlockWriteChunk(writeChunk);
+        spin_unlock(&writeChunk->stateLock);
+        spinLockListUnLock(&cacheBase->faultWriteChunkList);
+        updateBaseAndDomainFaultChunkCnt(cacheBase, writeChunk, faultType, pcFunName, TRUE);
+        updateBaseAndDomainFaultChunkCnt(cacheBase, writeChunk, oldFaultType, pcFunName, FALSE);
+        insertBaseToBgrFaultRecoverTask(cacheBase,writeChunk);
+        updateWriteChunkFaultPageCnt(cacheBase, writeChunk, incFaultPageCnt, incDirtyParityPageCnt, pcFunName);
+        updateWriteChunkFaultPageCnt(cacheBase, writeChunk, -decFaultPageCnt, -decDirtyParityPageCnt, pcFunName);
 
-        /* ıfaultpagequotaɣҪchunk */
-        updateWriteChunkFaultPageCnt(cacheBase, writeChunk,
-                                 incFaultPageCnt,
-                                 dirtyParityPageCnt,
-                                 pcFunName);
-
-        updateWriteChunkFaultPageCnt(cacheBase, writeChunk,
-                                     -decFaultPageCnt,
-                                     -dirtyParityPageCnt,
-                                     pcFunName);
-        insertFaultWriteChunkToBase(cacheBase,writeChunk);
     }
     else
     {
         /* chunk ״̬Ϊ */
         oldFaultType = writeChunk->faultType;
         writeChunk->faultType = faultType;
-        decWriteChunkFaultCnt(cacheBase, writeChunk, oldFaultType, pcFunName,
-                              &decFaultPageCnt, &dirtyParityPageCnt, &decPageUnitCnt);
-        unlockWriteChunk(writeChunk);
+        getWriteChunkFaultPageCnt(writeChunk, &decFaultPageCnt, &decDirtyParityPageCnt, &decPageUnitCnt);
+        removeFaultWriteChunkFromBaseNoLock(cacheBase,writeChunk);
 
+        if(atomic_dec_and_test(&cacheBase->faultChunkNum))
+        {
+            SET_CACHE_BASE_NORMAL(cacheBase);
+        }
+        unlockWriteChunk(writeChunk);
+        spin_unlock(&writeChunk->stateLock);
+        spinLockListUnLock(&cacheBase->faultWriteChunkList);
+        updateBaseAndDomainFaultChunkCnt(cacheBase, writeChunk, oldFaultType, pcFunName, FALSE);
         subWriteChunkFaultQuota(cacheBase, writeChunk, 1, decPageUnitCnt);
-        updateWriteChunkFaultPageCnt(cacheBase, writeChunk,
-                                     -decFaultPageCnt,
-                                     -dirtyParityPageCnt,
-                                     pcFunName);
-        removeFaultWriteChunkFromBase(cacheBase,writeChunk);
-    }
+        updateWriteChunkFaultPageCnt(cacheBase, writeChunk, -decFaultPageCnt, -decDirtyParityPageCnt, pcFunName);
 
+    }
 }
 
 /**************************************************************************
@@ -5422,7 +5422,7 @@
 
     return ret;
 }
-
+void repairFsCacheBaseDirtyQuotaCnt(CACHE_BASE_S *cacheBase);
 int32_t setFlagInWholeRWChunkNoFreeQuota(WRITE_CHUNK_S *writeChunk,
                               void          *arg,
                               int32_t       opCode,
@@ -5488,9 +5488,9 @@
     }
 
     /* chunkļ */
-
     freeQuotaArg->dirtyPageCnt += ((uint32_t)(0 - quota));
     updateWriteChunkPageCount(writeChunk, setFlagData.dirtyPage, quota, FALSE, __FUNCTION__);
+    repairFsCacheBaseDirtyQuotaCnt(writeChunk->cacheBase);
     updateReadChunkPageCount(readChunk, setFlagData.cleanPage);
     if (NULL != cpsReadChunk)
     {
@@ -6819,34 +6819,34 @@
 void DeleteVolatileDataInSettingWorkerCtrl(WRITE_CHUNK_S *writeChunk,
                                                  PT_SET_NEW_WORK_CTRL_ARG *setCtrlArg)
 {
-    int32_t  dirtyPageCnt = 0;
-
-     /* chunkеvolatile */
-    dirtyPageCnt = atomic_read(&writeChunk->dirtyPageCnt);
-
+    int32_t deltaDirtyPageCnt = 0;
     if (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk) || !IS_WRITE_CHUNK_PAIRTY_VALID(writeChunk))
     {
+        deltaDirtyPageCnt = atomic_read(&writeChunk->dirtyPageCnt);
         clearHostViewVolatileData(writeChunk);
+        deltaDirtyPageCnt -= atomic_read(&writeChunk->dirtyPageCnt);
+        if(IS_WRITE_CHUNK_FAULT(writeChunk) && deltaDirtyPageCnt > 0)
+        {
+            updateWriteChunkFaultPageCnt(GET_CACHE_BASE_FROM_WRITE_CHUNK(writeChunk), writeChunk, -deltaDirtyPageCnt, 0, __FUNCTION__);
+        }
+        
     }
-
     /* dirtypagecnt仯˵͸дʧvolatileɾ
           Ҫɾʱɾ (ֵ)*/
-    if ((dirtyPageCnt != atomic_read(&writeChunk->dirtyPageCnt))
+    if ((TRUE == writeChunk->seqInfo.triggerInterval)
         && (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk)))
     {
+        writeChunk->seqInfo.triggerInterval = FALSE;
         forceDeleteCleanDataInVolumeCache(writeChunk);
     }
-
     if (0 != atomic_read(&writeChunk->dirtyPageCnt))
     {
         return ;
     }
-
     /* ¼Ҫɾдchunk,
       üֻbase档*/
     incWriteChunkRef(writeChunk, WC_TRACE_REF_SET_WORK_CTRL_ADD);
     list_add_tail(&writeChunk->listNode, &setCtrlArg->listHead);
-
     return;
 
 }
@@ -7027,7 +7027,7 @@
     setWriteChunkTrace(writeChunk, 0, RC_TRACE_REF_RECOVER, CHUNK_REF_TRACE);
     writeChunk->predestageType    = DESTAGE_TYPE_MINIMUM;
 	writeChunk->needWtFaultDsg = B_FALSE;
-
+    writeChunk->seqInfo.triggerInterval = FALSE;
     counterListInit(&writeChunk->reqWriteWaitList);
 
     spin_lock(&writeChunk->stateLock);
@@ -8482,3 +8482,158 @@
 
 
 
+atomic_t g_repairBaseQuotaMutex = ATOMIC_INIT(0);
+void repairFsCacheBaseDirtyQuotaCnt(CACHE_BASE_S *cacheBase)
+{
+    int32_t tmpQuota = 0;
+    bool isFs = isFileSystemCacheBase(cacheBase);
+    
+    tmpQuota = atomic_read(&cacheBase->dirtyQuota);
+    
+    if (tmpQuota < 0 && isFs)
+    {
+        if (1 == atomic_inc_return(&g_repairBaseQuotaMutex))
+        {
+            atomic_add((tmpQuota*(-1)), &cacheBase->dirtyQuota);
+        }
+        atomic_dec(&g_repairBaseQuotaMutex);
+    }
+    
+    return;
+}
+
+void insertBaseToBgrFaultRecoverTask(CACHE_BASE_S *baseObj,WRITE_CHUNK_S *writeChunk)
+{
+    if (IS_WRITE_CHUNK_MEDIUM_ERROR(writeChunk)
+      || IS_WRITE_CHUNK_NORMAL_FAULT(writeChunk)
+      || IS_WRITE_CHUNK_WRITE_HOLE_LOG_MEDIUM_FAULT(writeChunk)
+      || IS_WRITE_CHUNK_WRITE_HOLE_LOG_NEED_RETRY_FAULT(writeChunk)
+      || IS_WRITE_CHUNK_NEED_RETRY_FAULT(writeChunk))
+    {
+        addBaseToFaultRecoverTask(baseObj);
+    }
+    return;
+}
+void insertFaultWriteChunkToBaseNoLock(CACHE_BASE_S *baseObj,WRITE_CHUNK_S *writeChunk)
+{
+
+    if (IS_LIST_NODE_INIT(&writeChunk->nodeInBase[CHUNK_HANG_FOR_FAULT]))
+    {
+        spinLockListAddTailNoLock(&writeChunk->nodeInBase[CHUNK_HANG_FOR_FAULT], &baseObj->faultWriteChunkList);
+    }
+
+    return;
+}
+
+void removeFaultWriteChunkFromBaseNoLock(CACHE_BASE_S *cacheBase,WRITE_CHUNK_S *writeChunk)
+{
+    if (!IS_LIST_NODE_INIT(&writeChunk->nodeInBase[CHUNK_HANG_FOR_FAULT]))
+    {
+        spinLockListDelNoLock(&writeChunk->nodeInBase[CHUNK_HANG_FOR_FAULT], &cacheBase->faultWriteChunkList);
+        INIT_LIST_NODE(&writeChunk->nodeInBase[CHUNK_HANG_FOR_FAULT]);
+    }
+
+    return;
+}
+void updateBaseAndDomainFaultChunkCnt(CACHE_BASE_S  *baseObj,
+                                      WRITE_CHUNK_S *writeChunk,
+                                      uint32_t       faultType,
+                                      const OSP_CHAR* pcFunName,
+                                      bool           isAddFault)
+{
+    /* Ҫϳڴӡ϶־ */
+    CACHE_LOGWARN_LIMIT_VAR(NO_LOGID, 5 * 60 * HZ, 20, "Function(%s) update fault chunk(volume id: 0x%llx, basetype:%u, update(%d)).",
+                            pcFunName, baseObj->volumeId, baseObj->baseType, isAddFault);
+    CACHE_LOGINFO_LIMIT_VAR(NO_LOGID, 5 * 60 * HZ, 20, LOG_FORMAT_WRITE_CHUNK, LOG_PARAM_WRITE_CHUNK(writeChunk));
+
+    if (isAddFault)
+    {
+        updateCacheBaseSpecialFaultCnt(baseObj, faultType, 1);
+        updateDiskDomainFaultChunkCnt(baseObj, faultType, 1);
+    }
+    else
+    {
+        updateCacheBaseSpecialFaultCnt(baseObj, faultType, -1);
+        updateDiskDomainFaultChunkCnt(baseObj, faultType, -1);
+    }
+    return;
+}
+
+
+void setWriteChunkFaultPageCnt(WRITE_CHUNK_S *writeChunk,
+                           OUT int32_t *dirtyPageCnt,
+                           OUT int32_t *dirtyParityPageCnt,
+                           OUT uint32_t *pageUnitCnt)
+{
+    uint32_t chunkSize;
+
+    chunkSize = WRITE_CHUNK_SIZE(writeChunk);
+    *pageUnitCnt = chunkSize / SEC_PER_PAGE_UNIT;
+
+    *dirtyPageCnt = atomic_read(&writeChunk->dirtyPageCnt);
+    writeChunk->faultPageCnt = (int16_t)*dirtyPageCnt;
+
+    *dirtyParityPageCnt = (IS_STRIPE_CACHE_WRITE_CHUNK(writeChunk)) ? (int32_t)STRIPE_WRITE_CHUNK_PARITY_SIZE(writeChunk) / SEC_PER_PAGE : 0;
+
+    return;
+}
+
+
+void getWriteChunkFaultPageCnt(WRITE_CHUNK_S *writeChunk,
+                           OUT int32_t *dirtyPageCnt,
+                           OUT int32_t *dirtyParityPageCnt,
+                           OUT uint32_t *pageUnitCnt)
+{
+    uint32_t chunkSize;
+
+    chunkSize = WRITE_CHUNK_SIZE(writeChunk);
+    *pageUnitCnt = chunkSize / SEC_PER_PAGE_UNIT;
+
+    *dirtyPageCnt = (int32_t)writeChunk->faultPageCnt;
+    writeChunk->faultPageCnt = 0;
+
+    *dirtyParityPageCnt = (IS_STRIPE_CACHE_WRITE_CHUNK(writeChunk)) ? (int32_t)STRIPE_WRITE_CHUNK_PARITY_SIZE(writeChunk) / SEC_PER_PAGE : 0;
+    return;
+}
+
+atomic_t g_firstIn = ATOMIC_INIT(0);
+void initWtDsgSwitch(void)
+{
+    CACHE_OBJ_S* curCacheObj = NULL;
+
+    if (0 == atomic_read(&g_firstIn))
+    {
+        lockCacheObjGlobalList();
+
+        curCacheObj = getNextCacheObj(NULL);
+        while (NULL != curCacheObj)
+        {
+            if ((NULL == curCacheObj->volumeCache) && (NULL == curCacheObj->stripeCache))
+            {
+                curCacheObj = getNextCacheObj(curCacheObj);
+                continue;
+            }
+
+            if (NULL != curCacheObj->volumeCache)
+            {
+                spin_lock(&curCacheObj->volumeCache->baseLock);
+                curCacheObj->volumeCache->pad = FALSE;
+                spin_unlock(&curCacheObj->volumeCache->baseLock);
+            }
+
+            if (NULL != curCacheObj->stripeCache)
+            {
+                spin_lock(&curCacheObj->stripeCache->baseLock);
+                curCacheObj->stripeCache->pad = FALSE;
+                spin_unlock(&curCacheObj->stripeCache->baseLock);
+            }
+
+            curCacheObj = getNextCacheObj(curCacheObj);
+        }
+
+        unlockCacheObjGlobalList();
+
+        atomic_inc(&g_firstIn);
+    }
+    return;
+}
--- ./source/private_module/ramcache/metadata/mutex/meta_mutex.c	2018-03-27 03:28:56.000000000 +0000
+++ ./source/private_module/ramcache/metadata/mutex/meta_mutex.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -724,11 +724,11 @@
 
 	if (RETURN_OK != dsgWriteChunk->destageResult)
 	{
-		lockWriteChunk(curWriteChunk);
+		spin_lock(&curWriteChunk->stateLock);
 		curWriteChunk->needWtFaultDsg = B_TRUE;
-		unlockWriteChunk(curWriteChunk);
-	}
+		spin_unlock(&curWriteChunk->stateLock);
 
+	}
 
 
     return RETURN_OK;
@@ -784,9 +784,15 @@
 
 PRIVATE void writeChunkDestageDoneNoRetry(WRITE_CHUNK_S *writeChunk, uint32_t faultType, CACHE_BASE_S *cacheBase)
 {
-	int32_t  dirtyPageCnt = 0;
 	INC_DBG_LABEL_STAT(WRITE_CK_DSG_DONE_NO_RETRY);
-
+	
+        /* chunkеvolatile */
+	if (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk)
+	    || !IS_WRITE_CHUNK_PAIRTY_VALID(writeChunk))
+	{
+	    clearHostViewVolatileData(writeChunk);
+	}
+    
 	setWriteChunkFaultType(cacheBase, writeChunk, faultType, __FUNCTION__);
 
 	/* ʱchunk fault */
@@ -795,19 +801,13 @@
 	    setWriteChunkTpListDestageFault(writeChunk);
 	}
 
-	/* chunkеvolatile */
-	dirtyPageCnt = atomic_read(&writeChunk->dirtyPageCnt);
-	if (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk)
-	    || !IS_WRITE_CHUNK_PAIRTY_VALID(writeChunk))
-	{
-	    clearHostViewVolatileData(writeChunk);
-	}
 
 	 /* dirtypageɾ仯˵volatile͸дʧܵIO,
 	 Ҫɾ ʱɾ*/
-	if ((dirtyPageCnt != atomic_read(&writeChunk->dirtyPageCnt))
+	if ((TRUE == writeChunk->seqInfo.triggerInterval)
 	    && (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk)))
 	{
+	    writeChunk->seqInfo.triggerInterval = FALSE;
 	    forceDeleteCleanDataInVolumeCache(writeChunk);
 	}
 }
@@ -920,25 +920,25 @@
 
 void writeChunkDestageDoneNeedRetryRet(WRITE_CHUNK_S *writeChunk, int32_t destageResult)
 {
-    int32_t  dirtyPageCnt = 0;
-
-    if (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk))
-    {
-        volumeWriteChunkDestageDone(writeChunk);
-    }
-
-    dirtyPageCnt = atomic_read(&writeChunk->dirtyPageCnt);
     /*͸дʧvolatile*/
     if (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk) || !IS_WRITE_CHUNK_PAIRTY_VALID(writeChunk))
     {
        clearHostViewVolatileData(writeChunk);
     }
+    
+
+
+    if (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk))
+    {
+        volumeWriteChunkDestageDone(writeChunk);
+    }
 
      /* dirtypageɾ仯˵volatile͸дʧܵIO,
      Ҫɾ ʱɾ*/
-    if ((dirtyPageCnt != atomic_read(&writeChunk->dirtyPageCnt))
+    if ((TRUE == writeChunk->seqInfo.triggerInterval)
        && (IS_VOLUME_CACHE_WRITE_CHUNK(writeChunk)))
     {
+       writeChunk->seqInfo.triggerInterval = FALSE;
        forceDeleteCleanDataInVolumeCache(writeChunk);
     }
 
--- ./source/private_module/ramcache/metadata/pagectrl/page_ctrl.c	2018-02-09 13:47:03.000000000 +0000
+++ ./source/private_module/ramcache/metadata/pagectrl/page_ctrl.c.hotpatch	2018-08-30 13:43:38.000000000 +0000
@@ -296,7 +296,6 @@
     uint8_t copyBitMap;
     void *hostView = NULL;
 
-
     hostView = GET_WRITE_HOST_VIEW_PAGE_CTRL(pageCtrl);
     *freePage = NULL;
 
@@ -343,7 +342,6 @@
             (*quota)++;
         }
 
-
         return RETURN_OK;
     }
 
@@ -362,8 +360,6 @@
         WRITE_PAGE_CTRL_CHECK_DIF(pageCtrl);
         return RETURN_OK;
     }
-
-
     /*
      * ԭҳеҳеǳͻ
      * 2:ҳԭҳPage_CtrlУԭҳûбҳдǵݿҳ
@@ -371,6 +367,10 @@
     copyBitMap = ((~bitMap) & GET_WRITE_HOST_DIRTY_BITMAP(pageCtrl));
     if (RETURN_OK == TEST_AND_ADD_PAGE_VALIDBITMAP(localPageCtrl, copyBitMap))
     {
+        if (!IS_ZERO_PAGE(localPageCtrl) && IS_ZERO_PAGE(hostView))
+        {
+            (*quota)++; 
+        }
         pageCopyByBitMap(GET_PAGE_ADDR(localPageCtrl), GET_PAGE_ADDR(hostView), copyBitMap);
         replaceWritePageHostView(pageCtrl, localPageCtrl, bitMap, dirtyPage, freePage);
 
@@ -3161,7 +3161,7 @@
     uint8_t leftCleanBitMap;
     void *freeWritePage = NULL;
     void *freeReadPage = NULL;
-
+    WRITE_CHUNK_S * curWriteChunk = NULL;
     uint32_t dirtyFlag;
 
 
@@ -3182,7 +3182,11 @@
         UNLOCK_PAGE_CTRL(pageCtrlLock);
         return RETURN_OK;
     }
-
+    curWriteChunk = setFlagData->writeChunk;
+    if(likely(NULL != curWriteChunk)  && (0 != volatileBitMap))
+    {
+        curWriteChunk->seqInfo.triggerInterval = TRUE;
+    }
     /* 20170321 ҳлдݣֻɾ͸дλͼӦ */
     if (unlikely(0 != writeBackBitMap))
     { 
@@ -3222,12 +3226,9 @@
         CLEAR_READ_FLAG(readPageCtrl);
     }
     /* ͬⵥDTS2014072206869 end */
-
     UNLOCK_PAGE_CTRL(pageCtrlLock);
-
     /* ͷдҳ */
     DEC_PAGE_REF_BY_USAGE(freeWritePage, PAGE_USAGE_CACHE_WRITE_PAGE_REF);
-
     /* ͬⵥDTS2014072206869 begin */
     /* ͷŶҳ,ҳδͷ˵Ѿתɾ,Ӹɾҳ */
     if (NULL_PAGE_BITMAP == leftCleanBitMap)
@@ -3239,7 +3240,6 @@
         setFlagData->cleanPage++;
     }
     /* ͬⵥDTS2014072206869 end */
-
     return RETURN_OK;
 }
 
