--- ./source/private_module/ld/stub_v3/stub_ld.c	2018-04-11 12:46:26.000000000 +0000
+++ ./source/private_module/ld/stub_v3/stub_ld.c.hotpatch	2020-05-06 09:00:28.000000000 +0000
@@ -98,14 +98,14 @@
     ldDiskTrimReqDelete
 };
 
+uint32_t g_ldPatchSucceed = 0;
+#define STUB_LD_DISK_REQ_DONE_FLAG (0)
+#define STUB_LD_DISK_REQ_CHILD_DONE_FLAG (1)  
+#define STUB_LD_DISK_REQ_DEGRADE_PRE (2)
+
 /**************************************************************************
    : ldCloseInner
      : ر߼
- : logicId: ߼ID
- : 
-   ֵ: RETURN_OK:رճɹ
-           RETURN_ERROR: رʧ
-     : 
 **************************************************************************/
 int32_t stub_ldClose(uint32_t logicId)
 {       
@@ -2084,11 +2084,14 @@
     spin_unlock(&logicDisk->infoLock);
 }
 
-/*Begin Modified by z90006985 DTS2014050604449 20140506*/
+void LdDegradeChkThrowException(void);
 int32_t stub_ldDiskReqDegradePre(LD_S *logicDisk, REQ_S *req)
 {
     LD_REQ_PRIVATE_INFO *private = NULL;
 
+    if (BDM_TEST_AND_SET_BIT(STUB_LD_DISK_REQ_DEGRADE_PRE, (void *)&g_ldPatchSucceed) == 0) {
+        DBG_LogInfo(LOG_ID_LD_0054, "BDM_LD_SPH019:stub_ldDiskReqDegradePre patch active succeed.");      
+    }
     private = (LD_REQ_PRIVATE_INFO*)(void*)req->producerPrivate;
     if ((BDM_TEST_BIT(LD_REQ_FWD_MASK, (void*)&private->flag))||(BDM_TEST_BIT(LD_REQ_EMITTED_MASK, (void*)&private->flag)))
     {
@@ -2100,26 +2103,23 @@
         spin_unlock(&logicDisk->timeoutLock);
         return RETURN_OK;
     }
-    /*DTS2014041510021 begin,ֱӷ*/
     if (atomic_read(&logicDisk->ioCount) >= DEGRADELIMIT)
     {
         spin_unlock(&logicDisk->timeoutLock);
         BDM_PRINT_LIMIT_PERIOD(30*HZ, 1, DBG_LOG_WARNING,LOG_ID_LD_04EF,
                 "Number of degrade io is beyond the limit,ld(%d),ioCount(%d).",
                  logicDisk->logicId, atomic_read(&logicDisk->ioCount));
-    	/*Begin Modified by h00295207 DTS2014071709014 20141114*/
-    	if(NULL != private->timeoutFunc)
-    	{
-    		private->timeoutFunc(req);
-    	}
-		/*End Modified by h00295207 DTS2014071709014 20141114*/
+        LdDegradeChkThrowException();
+        if(NULL != private->timeoutFunc)
+        {
+            private->timeoutFunc(req);
+        }
         req->result = IO_ERR_REDUNDANT_ABORT;
         /* DTS2016022407985 modify by y00376877 20160803 begin */
         BDM_IOD_ADD_DONEQ(req); 
         /* DTS2016022407985 modify by y00376877 20160803 end */
         return RETURN_ERROR;
     }
-    /*DTS2014041510021 end*/
     INIT_LIST_HEAD(&req->childList);
     ANY_TRACE_CALL(LD_DISK_REQ_INFO_DEGRADE, 0, "LD disk req(0x%p) enter time(%llx)", req, jiffies);
     private->deadline = jiffies + LD_MS_TO_JIFFIES(private->fgIoStgy.degradeTimeOut) + 1;
@@ -2676,7 +2676,10 @@
     LD_REQ_PRIVATE_INFO *private = NULL;
     LD_S *logicDisk = NULL;
     int32_t ret = RETURN_ERROR;
-    
+
+    if (BDM_TEST_AND_SET_BIT(STUB_LD_DISK_REQ_DONE_FLAG, (void *)&g_ldPatchSucceed) == 0) {
+        DBG_LogInfo(LOG_ID_LD_0054, "BDM_LD_SPH019:stub_ldDiskReqDone patch active succeed.");      
+    }
     if (NULL == req)
     {
         DBG_LogError(LOG_ID_LD_0054, "Input param failed:req is NULL.");
@@ -2734,19 +2737,19 @@
             REQ_CHILDDONE(req->parent, req);
             return RETURN_ERROR;
         }
-            
+        
         spin_lock(&logicDisk->infoLock);
         if (!list_empty(&req->childList))
         {
             list_del_init(&req->childList);
         }
         /*Begin Modified by z90006985 DTS2014050604449 20140506*/
-        /*DTS2014041510021 begin, ȥIO*/
         if (BDM_TEST_BIT(LD_REQ_INFO_DEGRADE, (void*)&private->flag))
         {
-            atomic_dec(&logicDisk->ioCount);
+            if (atomic_read(&logicDisk->ioCount) > 0) {
+                atomic_dec(&logicDisk->ioCount);
+            }            
         }
-        /*DTS2014041510021 end*/
         /*End Modified by z90006985 DTS2014050604449 20140506*/
         spin_unlock(&logicDisk->infoLock);
         
@@ -2766,10 +2769,7 @@
                 req->objectLba, req->length, private->errLba, private->errLen);
     }
     
-    /*Begin Modified by d00378434 DTS2016121606147 20161213*/
-    /*ӡREQִн*/
     SMART_TP_CALL(LD_PRINT_ERR_RESULT, req);
-    /*End Modified by d00378434 DTS2016121606147 20161213*/
     
     /*ǷתͳһϷ*/
     REQ_CHILDDONE(req->parent, req);
@@ -3257,11 +3257,12 @@
     uint8_t fatherLinkInfo = INVALID_VALUE8;
     /*End Modified by j00279123 CR2016112210947147 20170223*/
 
+    if (BDM_TEST_AND_SET_BIT(STUB_LD_DISK_REQ_CHILD_DONE_FLAG, (void *)&g_ldPatchSucceed) == 0) {
+        DBG_LogInfo(LOG_ID_LD_0054, "BDM_LD_SPH019:stub_ldDiskReqChildDone patch active succeed.");      
+    }
     if (NULL == selfReq || NULL == childReq)
     {
-        /*Begin DTS2018010511782 c00271321 20171226*/
         SYS_BUG(SYS_BUG_MAJ, MODULE_FUNC_HANG, "req is null.");
-        /*End DTS2018010511782 c00271321 20171226*/
         return;
     }
     logHead = bdmGetLogHeadByRet(childReq->result);
@@ -3310,7 +3311,7 @@
     }
     selfReq->result = childReq->result;
     /*ʶREQѾ·*/ 
-    SET_BIT32(private->flag, LD_REQ_EMITTED_MASK);
+    BDM_SET_BIT(LD_REQ_EMITTED_MASK, (void*)&private->flag);
 
     /* ķΧҵIOķΧڣ */
     if (ldChkBadSecNeedRetry(selfReq, childReq, logicDisk, currentErrorInfo, 
@@ -3367,7 +3368,6 @@
         /*Begin Modified by j00279123 CR2016112210947147 20170223*/
         ldSasTimeoutCheck(logicDisk, selfReq, fatherLinkInfo);
         /*End Modified by j00279123 CR2016112210947147 20170223*/
-        /* ѯ*/
         ldDiskReqInquiryStrategy(selfReq);
     }
 }
--- ./source/private_module/ld/stub_v3/stub_ld_forward.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/ld/stub_v3/stub_ld_forward.c.hotpatch	2020-05-03 08:03:21.000000000 +0000
@@ -730,8 +730,9 @@
     return RETURN_OK;
 
 }
-
-
+uint32_t g_ldFwdPatchSucceed = 0;
+#define STUB_FWD_RCV_RESPONSE_IOHANDLE_FLAG (0)
+void stub_fwdRcvResIoCpyPriDataPatch(REQ_S *req, FWD_XRB_DATA_S *xrbData);
 /**************************************************************************
 *     : עxrbӦĺ
 * : *sgl : sglָ
@@ -740,7 +741,6 @@
 *                         : result : xnetصĽֵ
 * : 
 * ֵ  : 
-*     : 
 **************************************************************************/
 void stub_fwdRcvResponseIoHandle(SGL_S *sgl, void *ibdData, void *context, XNET_MSG_RESULT_E result)
 {
@@ -748,6 +748,9 @@
     FWD_XRB_DATA_S *xrbData = (FWD_XRB_DATA_S *)ibdData;
     LD_REQ_PRIVATE_INFO *private = NULL;
 
+    if (BDM_TEST_AND_SET_BIT(STUB_FWD_RCV_RESPONSE_IOHANDLE_FLAG, (void *)&g_ldFwdPatchSucceed) == 0) {
+        DBG_LogInfo(LOG_ID_LD_0054, "BDM_LD_SPH019:stub_fwdRcvResIoCpyPriDataPatch patch active succeed.");      
+    }
     atomic64_inc(&g_ldBackFromOtherCtrl);
     if (NULL == context)
     {
@@ -756,13 +759,10 @@
         return;
     }
 
-    /* begin l90006309@2014/2/16 IO SFMEA */
     SMART_TP_CALL(LD_TP_XNET_BACK_FAIL, req, (int32_t *)&result);
-    /* end l90006309@2014/2/16 IO SFMEA */
 
     if (XNET_MSG_SUCCESS == result)
     {
-        /*ɹxrb  data  Ϊ*/
         if (NULL == xrbData)
         {
             DBG_LogError(LOG_ID_LD_0265, "Input param failed: xrbData is MULL, ibd(0x%p), context(0x%p).", 
@@ -778,7 +778,7 @@
             return;
         }
 
-        memcpy(req->producerPrivate, xrbData->producerPrivate, sizeof(req->producerPrivate));
+        stub_fwdRcvResIoCpyPriDataPatch(req, xrbData);
         req->result = xrbData->result;
 
         /* ӦϢibdе͸ؼϢreq */
@@ -1255,5 +1255,55 @@
     return RETURN_OK;
 }
 
+typedef struct tagLD_REQ_PRIVATE_FlAG{
+    uint32_t low:8;
+    uint32_t degradeFlag:1;
+    uint32_t high:23;
+} LD_REQ_PRIVATE_FlAG;
 
+void stub_fwdRcvResIoCpyPriDataPatch(REQ_S *req, FWD_XRB_DATA_S *xrbData)
+{
+    LD_REQ_PRIVATE_INFO *ldReqprivate = NULL;
+    LD_REQ_PRIVATE_INFO *xrbPrivate = NULL;
+    LD_REQ_PRIVATE_FlAG *ldReqPrivateFlag = NULL;
+    LD_REQ_PRIVATE_FlAG *ldXrbDataPrivateFlag = NULL;
+    uint32_t ldReqOldPrivateFlag = 0;
+    int idx, padNum;
+        
+    ldReqprivate = (LD_REQ_PRIVATE_INFO*)(void*)req->producerPrivate;
+    xrbPrivate = (LD_REQ_PRIVATE_INFO*)(void*)xrbData->producerPrivate;
+    ldReqOldPrivateFlag = ldReqprivate->flag;
+    ldReqPrivateFlag = (LD_REQ_PRIVATE_FlAG *)(void *)(&ldReqprivate->flag);
+    ldXrbDataPrivateFlag = (LD_REQ_PRIVATE_FlAG *)(void *)(&xrbPrivate->flag);
+    
+    memcpy((uint8_t *)req->producerPrivate + sizeof(ldReqprivate->flag), 
+            (uint8_t *)xrbData->producerPrivate + sizeof(ldReqprivate->flag), 
+            offsetof(LD_REQ_PRIVATE_INFO, fgIoStgy) - sizeof(ldReqprivate->flag));
+    memcpy((uint8_t *)req->producerPrivate + offsetof(LD_REQ_PRIVATE_INFO, actionInfo),
+        (uint8_t *)xrbData->producerPrivate + offsetof(LD_REQ_PRIVATE_INFO, actionInfo),
+        sizeof(req->producerPrivate) - offsetof(LD_REQ_PRIVATE_INFO, actionInfo));
+    
+    ldReqPrivateFlag->low = ldXrbDataPrivateFlag->low;
+    if (ldXrbDataPrivateFlag->degradeFlag == 1) {
+        ldReqPrivateFlag->degradeFlag = 1;
+    }
+    ldReqPrivateFlag->high = ldXrbDataPrivateFlag->high;
+
+    ldReqprivate->fgIoStgy.ioTimeOut = xrbPrivate->fgIoStgy.ioTimeOut;
+    ldReqprivate->fgIoStgy.rePairTimeOut = xrbPrivate->fgIoStgy.rePairTimeOut;
+    ldReqprivate->fgIoStgy.sioTimeOut = xrbPrivate->fgIoStgy.sioTimeOut;
+
+    padNum = ARRAY_LEN(ldReqprivate->fgIoStgy.pad);
+    for (idx = 0; idx < padNum; idx++) {
+        ldReqprivate->fgIoStgy.pad[idx] = xrbPrivate->fgIoStgy.pad[idx];
+    }
+    
+    if (BDM_TEST_BIT(LD_REQ_INFO_DEGRADE, (void *)&ldReqprivate->flag)) {
+        BDM_PRINT_LIMIT_PERIOD(BDM_LOG_INTERVAL_HALF_HOUR, 1, DBG_LOG_INFO, LOG_ID_LD_05D8,
+              "BDM_LD_SPH019:req(0x%p),disk(%llu),op(%d),lba(0x%llx),ctrlFlag(0x%llx),oldprvFlag(0x%x),prvFlag(0x%x), xrbFlag(0x%x).",
+              req, req->objectId, req->opCode, req->objectLba, req->ctrlFlag, ldReqOldPrivateFlag, ldReqprivate->flag, xrbPrivate->flag);
+    }
+
+    return;
+}
 
--- ./source/private_module/ld/stub_v3/stub_ld_sync_msg.c	2018-04-22 08:45:38.000000000 +0000
+++ ./source/private_module/ld/stub_v3/stub_ld_sync_msg.c.hotpatch	2020-05-06 03:50:24.000000000 +0000
@@ -2369,7 +2369,7 @@
 /* Add by y90002204 20150826 end */
 
 
-
+void ldModifyDegradeCountHandlePatch(void);
 /**************************************************************************
    : ldIOCtrlCmdTimerHandler
      : IOCTRL鶨ʱ
@@ -2388,7 +2388,7 @@
     /*End Modified by w90005722 DTS2014081104200 20140811*/
     
     UNREFERENCE_PARAM(NULL != context);
-    
+    ldModifyDegradeCountHandlePatch();
     spin_lock(&g_IOCtrlCmdSyncList.spinlock);   
     if (0 == g_IOCtrlCmdSyncList.sum)
     {
@@ -2645,4 +2645,110 @@
 /* PC-Lint */
 LD_USE_TRACE_POINT
 
+void ldModifyDegradeCountPatch(void)
+{
+    uint32_t index = 0;
+    ALL_LD_INFO_S *allDiskInfoPtr = &g_allLdInfo;
+    LD_S *logicDisk = allDiskInfoPtr->ldArrayInfo + MAX_PARTITION_LOGIC_DISK_NUM;
+
+    for (index = MAX_PARTITION_LOGIC_DISK_NUM; index < allDiskInfoPtr->ldNum; index++,logicDisk++) {
+        if (atomic_read(&logicDisk->ioCount) > 4) {
+            atomic_set(&logicDisk->ioCount, 0);
+        }
+    }
+
+    DBG_LogInfo(LOG_ID_LD_0711, "BDM_LD_SPH019: ld modify disk degrade count succeed.");
+    return;
+}
+
+uint32_t g_ldDegradeRepairChkInterval = 3600 * 1000 / RETRY_CHECK_DISK_IOCTRLCMD_MILLISEC;
+uint64_t g_ldDegradeRepairChkCnt = 12;
+uint32_t g_ldChkDegradeCnt = 0;
+
+uint32_t g_ldModifyDegrade = 0;
+#define  LD_MODIFY_DEGRADE_FIRST (0)
+#define  LD_MODIFY_THROW_EXCEPT  (1)
+#define  LD_MODIFY_TIMER_PROC    (2)
+
+void LdDegradeChkThrowException(void)
+{
+    BDM_SET_BIT(LD_MODIFY_THROW_EXCEPT, (void *)&g_ldModifyDegrade);
+    return;
+}
+
+bool LdCheckAndRepairDegradeCountPatch(void)
+{
+    uint32_t index = 0;
+    ALL_LD_INFO_S *allDiskInfoPtr = &g_allLdInfo;
+    LD_S *logicDisk = allDiskInfoPtr->ldArrayInfo + MAX_PARTITION_LOGIC_DISK_NUM;
+    int32_t ioCount = 0;
+    uint64_t chkCount = 0;
+    uint64_t prevIoCount = 0;
+    bool hasNeedChkDisk = FALSE;
+
+    for (index = MAX_PARTITION_LOGIC_DISK_NUM; index < allDiskInfoPtr->ldNum; index++,logicDisk++) {
+        if (logicDisk->state >= LOGIC_DISK_STATE_BUTT) {
+            continue;
+        }
+
+        ioCount = atomic_read(&logicDisk->ioCount);
+        prevIoCount = logicDisk->delayAlloc & 0xFFFFFFFF;
+        chkCount = (logicDisk->delayAlloc >> 32) & 0xFFFFFFFF;
+
+        if (ioCount < 16) {
+            logicDisk->delayAlloc = 0;
+            continue;
+        } else if (prevIoCount == 0) {
+            hasNeedChkDisk = TRUE;
+            prevIoCount = (uint64_t)(uint32_t)ioCount;
+            chkCount++;
+            logicDisk->delayAlloc = ((chkCount & 0xFFFFFFFF) << 32) | (prevIoCount & 0xFFFFFFFF);
+            continue;
+        } else if (prevIoCount == (uint64_t)(uint32_t)ioCount) {
+            chkCount++;
+            if (chkCount >= g_ldDegradeRepairChkCnt) {
+                DBG_LogInfo(0, "BDM_LD_SPH111:Logic disk %u modified degrade io count %d.",
+                            logicDisk->logicId, ioCount);
+                atomic_set(&logicDisk->ioCount, 0);
+                logicDisk->delayAlloc = 0;
+            } else {
+                logicDisk->delayAlloc = ((chkCount & 0xFFFFFFFF) << 32) | (prevIoCount & 0xFFFFFFFF);
+                hasNeedChkDisk = TRUE;
+            }
+            continue;
+        } else {
+            logicDisk->delayAlloc = 0;
+            continue;
+        }
+    }
+
+    return hasNeedChkDisk;
+}
+
+void ldModifyDegradeCountHandlePatch(void)
+{
+    if (BDM_TEST_AND_SET_BIT(LD_MODIFY_TIMER_PROC, (void *)&g_ldModifyDegrade)) {
+        return;
+    }
+
+    if (BDM_TEST_AND_SET_BIT(LD_MODIFY_DEGRADE_FIRST, (void *)&g_ldModifyDegrade) == 0) {
+        ldModifyDegradeCountPatch();
+        BDM_CLEAR_BIT(LD_MODIFY_TIMER_PROC, (void *)&g_ldModifyDegrade);
+        return;
+    }
+
+    if (BDM_TEST_BIT(LD_MODIFY_THROW_EXCEPT, (void *)&g_ldModifyDegrade)) {
+        if (g_ldChkDegradeCnt >= g_ldDegradeRepairChkInterval) {
+            g_ldChkDegradeCnt = 0;
+            if (!LdCheckAndRepairDegradeCountPatch()) {
+                BDM_CLEAR_BIT(LD_MODIFY_THROW_EXCEPT, (void *)&g_ldModifyDegrade);
+            }
+        } else {
+            g_ldChkDegradeCnt++;
+        }
+    } 
+
+    BDM_CLEAR_BIT(LD_MODIFY_TIMER_PROC, (void *)&g_ldModifyDegrade);
+    return;
+}
 
