--- ./source/private_module/ckg/eh/bst_restore.c	2018-03-29 06:46:18.000000000 +0000
+++ ./source/private_module/ckg/eh/bst_restore.c.hotpatch	2019-05-09 11:20:28.000000000 +0000
@@ -2596,7 +2596,7 @@
     
     return req;
 }
-
+void checkAndSetNewUncScanPerIod(void);
 /**************************************************************************
      : ʱص, һ޸        
  : context: ص
@@ -2609,12 +2609,12 @@
     REQ_S *traverseReq = NULL;
 
     UNREFERENCE_PARAM(context);
-
     if(TRUE == g_isolateSwitchBstRestore)
     {
         DBG_LogDebug(CKGLOG_BST_0066, "The bst restore bgr isolate flag is on.");
         return;
     }
+    checkAndSetNewUncScanPerIod();
     /* Ӻ̨޸ж */
     spin_lock(&g_curRtSwitchSpinlock);
     if (!atomic_read(&g_curRtSwitch))
@@ -3094,3 +3094,25 @@
     return;
 }
 
+#define SMARTSCAN_REPAIR_HALF_HOUR         (30 * 60 * 1000) /* ܻ޸ڰСʱ */
+extern int32_t changeUncPeriod(uint32_t period);
+extern bool g_setUncScanPeriodNew;
+extern uint32_t g_uncScanPeriod;
+void checkAndSetNewUncScanPerIod(void)
+{
+    int32_t result;
+    
+    if (!g_setUncScanPeriodNew)
+    {
+        result = changeUncPeriod((uint32_t)SMARTSCAN_REPAIR_HALF_HOUR);
+        if (RETURN_OK == result)
+        {
+            g_setUncScanPeriodNew = TRUE;
+            g_uncScanPeriod = SMARTSCAN_REPAIR_HALF_HOUR;
+            DBG_LogInfo(CKGLOG_BST_0036, "Set smart repair unc period to new value(%u).", (uint32_t)SMARTSCAN_REPAIR_HALF_HOUR);
+        }
+    }
+
+    return;
+}
+
--- ./source/private_module/ckg/eh/smartrepair.c	2018-02-09 13:47:03.000000000 +0000
+++ ./source/private_module/ckg/eh/smartrepair.c.hotpatch	2019-05-15 06:46:17.000000000 +0000
@@ -29,47 +29,47 @@
 #include "ckg_encrypt_disk.h"
 
 MODULE_ID(PID_BACKSCAN);
-
+typedef struct tagSMARTSCAN_NOT_REPAIR_DISK_INFO_S{spinlock_t lock;uint64_t maxUncNum;uint64_t lbaSum;diskid_t diskId;uint32_t unRepairedTimes;} SMARTSCAN_NOT_REPAIR_DISK_INFO_S;
 /*****************************************************************/
-
-
+/* δ޸UNCҪʧЧһҪʧЧ */
+#define SMARTSCAN_PARALLE_MAX_NOT_REPAIR_TIMES      (24 * 60 * SMARTSCAN_SECOND_IN_ONE_MIN / SMARTSCAN_REPAIR_HALF_HOUR)
 /* ޸IO */
 uint32_t g_uncIoCounter[SMARTSCAN_IO_COUNT_TYPE_BUTT][SMARTSCAN_IO_COUNTER_BUTT];
-
+#define SMARTSCAN_REPAIR_HALF_HOUR         (30 * 60 * 1000) /* ܻ޸ڰСʱ */
 /* SMARTSCAN_DISK_INFO_Sʱ */
 spinlock_t g_uncIoCounterLock;                  
-
+#define SMARTSCAN_UNC_LBA_SUM                (20)/* UNCLBA֮ */
 /* ޸UNCϢID*/
 static uint32_t g_uncDiskUncListPartId;
-
+#define SMARTSCAN_UNC_MAX_NUM                (21)/* UNC */
 /* ޸pool״̬ */
 SMARTSCAN_POOL_STATE_S g_uncPoolState[MAX_POOL_NUM];   
-
+SMARTSCAN_NOT_REPAIR_DISK_INFO_S g_uncNotRepairDiskInfo[MAX_POOL_NUM];
 /* ޸ */
 SMARTSCAN_TASK_INFO_S g_uncTaskInfo;  
-
+uint32_t g_maxUnRepairTimes = SMARTSCAN_PARALLE_MAX_NOT_REPAIR_TIMES;/* δ޸ */
 /* ޸ѯUNCб*/
 //uint64_t 
-
+bool g_unRepairDbgSwitch = FALSE;
 /* ϵͳֵ֧С߼ID */
 uint32_t g_uncMinLogicDiskId = 0;
-
+uint32_t g_maxUnRepairTimesForDbg = SMARTSCAN_PARALLE_MAX_NOT_REPAIR_TIMES;
 /* ϸϢ */
 uint32_t g_uncDebugSwitch = 0;
-
+diskid_t g_diskIdForDbg = INVALID_DISK_ID;
 uint32_t g_maxUncDiskNum;
-
+uint32_t g_uncNumForDbg = INVALID_VALUE32;
 uint32_t g_uncDiskPatitionId;
-
+uint64_t g_uncLbaSumForDbg = INVALID_VALUE64;
 /* ȫӲϢ */
 SMARTSCAN_DISK_INFO_S  *g_uncDisksInfoQue;
-
+#define MAX_UNC_NUM_PER_DISK    (255)
 /* ɨȶ */
 SMARTSCAN_SCHE_QUE_S  g_uncScheQue;
-
+bool g_setUncScanPeriodNew = FALSE;/* µUNCɨʱǷѾ */
 /* ޸ڻλ */
 uint32_t g_uncScanPeriod;
-
+bool g_unRepairInfoInitFlag = FALSE;
 /*DTS2015033005418, modified by yaobo 90004977, 2015/03/30, begin*/
 /*ɨ̨뿪*/
 bool g_isolateSwitchSSDScan = FALSE;
@@ -84,8 +84,8 @@
     childDoneUncScanTaskReq,
     delUncScanReq
 };
-
-
+#define GET_UNC_LBA_SUM(scanDiskReq) (uint64_t)(scanDiskReq->producerPrivate[SMARTSCAN_UNC_LBA_SUM])
+#define SET_UNC_LBA_SUM(scanDiskReq, lbaSum) (scanDiskReq->producerPrivate[SMARTSCAN_UNC_LBA_SUM] = (uint64_t)(lbaSum))
 /* ɨӲREQ ops */
 REQ_OPS_S g_uncScanDiskOps = 
 {
@@ -95,8 +95,8 @@
     childDoneUncScanDiskReq,
     delUncScanReq
 };
-
-
+#define GET_UNC_MAX_NUM(scanDiskReq) (uint64_t)(scanDiskReq->producerPrivate[SMARTSCAN_UNC_MAX_NUM])
+#define SET_UNC_MAX_NUM(scanDiskReq, maxNum) (scanDiskReq->producerPrivate[SMARTSCAN_UNC_MAX_NUM] = (uint64_t)(maxNum))
 /* Ҳ޸REQ ops */
 REQ_OPS_S g_uncRestoreErrIoOps = 
 {
@@ -290,10 +290,10 @@
     scanDiskReq->objectId = (uint64_t)diskInfo->diskId;
     
     SET_UNC_POOL_ID(scanDiskReq, diskInfo->poolId);
-   
     SET_UNC_DISK_INFO(scanDiskReq, diskInfo);
     SET_UNC_IO_STEP(scanDiskReq, SMARTSCAN_QUERY_UNC);
-    
+    SET_UNC_LBA_SUM(scanDiskReq, 0);
+	SET_UNC_MAX_NUM(scanDiskReq, 0);
     return scanDiskReq;
 }
 
@@ -413,10 +413,8 @@
     IOCTRL_GET_DISK_PENDINGLIST_PARAM_S *tempList = NULL;
     REQ_S *scanDiskReq = NULL;
     uint64_t uncNum = 0;
-
     scanDiskReq = (REQ_S *)context;
     diskInfo = GET_UNC_DISK_INFO(scanDiskReq);
-    
     if (RETURN_OK != ret)
     {
         scanDiskReq->result = RETURN_ERROR;
@@ -425,11 +423,16 @@
         IOD_ADD_DONEQ(scanDiskReq);
         return;
     }
-    
     tempList = (IOCTRL_GET_DISK_PENDINGLIST_PARAM_S *)pendingList;
     uncNum = tempList->listNum; 
     diskInfo->uncNum=uncNum;
-
+    SET_UNC_MAX_NUM(scanDiskReq, MAX_UNC_NUM_PER_DISK);
+    if (g_unRepairDbgSwitch){
+        if (g_diskIdForDbg == (diskid_t)scanDiskReq->objectId){
+            diskInfo->uncNum = g_uncNumForDbg;
+            uncNum = g_uncNumForDbg;
+        }
+    }
     /*modified by w90006961 for DTS2014040108034 ,2014-4-23 begin*/
     if(0 != tempList->listNum)
     {
@@ -445,13 +448,10 @@
     {
         gotoNextStep(scanDiskReq, GET_UNC_IO_STEP(scanDiskReq));
     }
-    else
-    {
+    else{
         scanDiskReq->result = RETURN_OK;
         IOD_ADD_DONEQ(scanDiskReq);
     }
-   
-    
     return;
 }
 
@@ -575,14 +575,13 @@
     /*modified by w90006961 for DTS2014063002641 ,2014-6-30 end*/
     struct list_head *pos = NULL;  
     struct list_head *next = NULL;
-    
+    uint64_t uncLbaSum = 0;
     scanReqPrivate = GET_UNC_REQ_PRIVATE(scanDiskReq);
     pendinglist = &scanReqPrivate->pendinglist;
     listNum = pendinglist->listNum;
     itemList = pendinglist->item_List;
     diskId = (diskid_t)scanDiskReq->objectId;
     poolId = GET_UNC_POOL_ID(scanDiskReq);
-    
     if (SMARTSCAN_STATE_POOL_STOP == g_uncPoolState[poolId].poolState)
     {
         scanDiskReq->result = RETURN_ERROR;
@@ -594,24 +593,20 @@
     scanDiskReq->childSum = 0;
     for (index = 0; index < listNum; index++)
     {
-        
         /* ޸REQ, ϱ޸ */                
         uncLba = (itemList + index)->lba;
         uncLen = (itemList + index)->len;
         DBG_LogDebug(0, "SR-:Get disk(%u) uncLba(%llu) uncLen(%llu).",
                         diskId, uncLba, uncLen);
-
+        uncLbaSum += uncLba;
         /*modified by w90006961 for DTS2014063002641 ,2014-6-30 begin*/
         zoneId = allocMenForZoneIdList();
-        if (NULL == zoneId)
-        {
+        if (NULL == zoneId){
             continue;
         }
-        
         /*modified by w90006961 for DTS2014063002641 ,2014-6-30 end*/
         msRestoreDiskReq = allocAndInitUNCReq();
-        if (NULL == msRestoreDiskReq)
-        {
+        if (NULL == msRestoreDiskReq){
             /*modified by w90006961 for DTS2014063002641 ,2014-6-30 begin*/
             freeZoneIdStructByPoint(zoneId);
             /*modified by w90006961 for DTS2014063002641 ,2014-6-30 end*/
@@ -634,18 +629,24 @@
         list_add_tail(&msRestoreDiskReq->childNode, &scanDiskReq->childList); 
         SET_UNC_POOL_ID(msRestoreDiskReq, poolId);
         msRestoreDiskReq = NULL;
-              
+    }
+    if (g_unRepairDbgSwitch){
+        if (diskId == g_diskIdForDbg){
+            listNum = g_uncNumForDbg;
+            uncLbaSum = g_uncLbaSumForDbg;
+        }
+    }
+    /* UNCﵽ¼LBA֮ */
+    if (GET_UNC_MAX_NUM(scanDiskReq) <= listNum){
+        SET_UNC_LBA_SUM(scanDiskReq, uncLbaSum);
     }
     if (0 == scanDiskReq->childSum)
     {
         IOD_ADD_DONEQ(scanDiskReq);
         return RETURN_OK;
     }
-
     atomic_set(&scanDiskReq->notBackNum, (int32_t)scanDiskReq->childSum);
-
-    list_for_each_safe(pos, next, &scanDiskReq->childList)
-    {
+    list_for_each_safe(pos, next, &scanDiskReq->childList){
         list_del(pos);
         msRestoreDiskReq = list_entry(pos, REQ_S, childNode);
         atomic_inc(&g_uncPoolState[poolId].notBacksum);
@@ -658,7 +659,6 @@
                          poolId,diskId,msRestoreDiskReq->objectLba);
         IOD_ADD_STARTQ_FORCE_DISPATCH(msRestoreDiskReq); 
     }
-
     return RETURN_OK;
 }
     
@@ -732,7 +732,7 @@
         FREE_STRUCTURE(uncList, g_uncDiskUncListPartId);
     }
 } 
-
+void checkAndReportDiskPrefail(REQ_S *scanDiskReq);
 /**************************************************************************
      :  ɨӲREQdone: жϵɨDMP REQǷȫ
  :  scanDiskReq : ɨӲREQ
@@ -761,14 +761,14 @@
     {
         incSmartScanIoCount(SMARTSCAN_IO_COUNT_TPYE_SCANDISK, SMARTSCAN_IO_BACK_GOOD);
     } 
-    
     diskInfo = GET_UNC_DISK_INFO(scanDiskReq);
-
     diskInfo->isComplete = B_TRUE;
     diskInfo->completeUtcTime = LVOS_GetTime(NULL);
-
+    if (g_unRepairInfoInitFlag){
+        /* Ƿﵽָδ޸UNCҪϱ̼ʧЧ */
+        checkAndReportDiskPrefail(scanDiskReq);
+    }
     poolId = GET_UNC_POOL_ID(scanDiskReq);     
-    
     decUncScanDiskNum(poolId);  
     freeUNCStruct(scanDiskReq); 
 
@@ -1388,7 +1388,7 @@
 }
 
 
-
+void hotpatchInitUnRepairInfo(void);
 /**************************************************************************
      :  ޸ʱִк
  :  mediascanTask   ̨ɨ
@@ -1404,7 +1404,7 @@
     uint32_t     tskStatus;
     int32_t     ret;
     UNREFERENCE_PARAM(smartScanTask);
-    
+    hotpatchInitUnRepairInfo();
     spin_lock(&(g_uncTaskInfo.stLock));
     executeStatus = g_uncTaskInfo.executeStatus;
     tskStatus = g_uncTaskInfo.tskStatus;
@@ -1912,4 +1912,270 @@
     freeSmartRepairResource();    
 }
 
+void initNotRepairDiskInfo(poolid_t poolId)
+{
+    g_uncNotRepairDiskInfo[poolId].maxUncNum = INVALID_VALUE64;
+    g_uncNotRepairDiskInfo[poolId].diskId = INVALID_DISK_ID;
+    g_uncNotRepairDiskInfo[poolId].lbaSum = INVALID_VALUE64;
+    g_uncNotRepairDiskInfo[poolId].unRepairedTimes = 0;
+}
+
+void clearNotRepairDiskInfo(poolid_t poolId, diskid_t diskId)
+{
+    spin_lock(&(g_uncNotRepairDiskInfo[poolId].lock));
+    if (g_uncNotRepairDiskInfo[poolId].diskId == diskId)
+    {
+        initNotRepairDiskInfo(poolId);
+        CKG_PRINT_LIMIT_PERIOD(CKGLOG_CTRL_INTERVAL, CKGLOG_CTRL_COUNT, DBG_LOG_INFO, CKGLOG_MEDIASCAN_0096,
+            "Clear not repair disk info(disk id:%u, pool id:%u)", diskId, poolId);
+    }
+    spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+    
+    return;
+}
+
+void updateNotRepairDiskInfo(poolid_t poolId, diskid_t diskId, uint64_t lbaSum, uint64_t diskMaxUncNum)
+{
+    int32_t ret;
+    uint32_t maxUnrepairTimes;
+
+    maxUnrepairTimes = g_unRepairDbgSwitch ? g_maxUnRepairTimesForDbg : g_maxUnRepairTimes;
+    
+    spin_lock(&(g_uncNotRepairDiskInfo[poolId].lock));
+    
+    /* Ӳδ¼δ޸ */
+    if (g_uncNotRepairDiskInfo[poolId].diskId == INVALID_DISK_ID)
+    {
+        g_uncNotRepairDiskInfo[poolId].maxUncNum = diskMaxUncNum;
+        g_uncNotRepairDiskInfo[poolId].diskId = diskId;
+        g_uncNotRepairDiskInfo[poolId].lbaSum = lbaSum;
+        g_uncNotRepairDiskInfo[poolId].unRepairedTimes = 1;
+
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        
+        CKG_PRINT_LIMIT_PERIOD(CKGLOG_CTRL_INTERVAL, CKGLOG_CTRL_COUNT, DBG_LOG_INFO, CKGLOG_MEDIASCAN_0096,
+            "Record a not repair disk info(disk id:%u, max unc num:%llu, lba sum:%llu) of pool(%u)", 
+            diskId, diskMaxUncNum, lbaSum, poolId);
+        
+        return;
+    }
+    /* ֮ǰӲѾ¼һδ޸ټ¼ */
+    if (g_uncNotRepairDiskInfo[poolId].diskId != diskId)
+    {
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        return;
+    }
+    else
+    {
+        if (g_uncNotRepairDiskInfo[poolId].lbaSum == lbaSum)
+        {
+            /* LBA֮ͬûв޸ִμ */
+            g_uncNotRepairDiskInfo[poolId].unRepairedTimes++;
+        }
+        else
+        {
+            CKG_PRINT_LIMIT_PERIOD(CKGLOG_CTRL_INTERVAL, CKGLOG_CTRL_COUNT, DBG_LOG_INFO, CKGLOG_MEDIASCAN_0096,
+            "Unrepair disk's lba is diffrent(disk id:%u, max unc num:%llu, unrepair times:%u, pool id:%u), "
+            "old lba sum:%llu, new lba sum:%llu, clear it.", 
+            diskId, 
+            diskMaxUncNum, 
+            g_uncNotRepairDiskInfo[poolId].unRepairedTimes, 
+            poolId, 
+            g_uncNotRepairDiskInfo[poolId].lbaSum, 
+            lbaSum);
+            
+            /* LBA֮Ͳͬ޸δ޸Ϣ */
+            initNotRepairDiskInfo(poolId);
+            
+            spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+            return;
+        }
+
+        /* δ޸Ĵﵽ򱨸̼ʧЧ */
+        if(maxUnrepairTimes < g_uncNotRepairDiskInfo[poolId].unRepairedTimes)
+        {
+            ret = ldCkgNotifyLdHalfLife(g_uncNotRepairDiskInfo[poolId].diskId);
+            if (RETURN_OK != ret)
+            {
+                DBG_LogError(CKGLOG_MEDIASCAN_0096, "Notify pool(%u), disk(%u) "
+                                "halflife failed when %u times not repaired, max unc num is (%llu).",
+                                poolId, 
+                                g_uncNotRepairDiskInfo[poolId].diskId, 
+                                g_uncNotRepairDiskInfo[poolId].unRepairedTimes,
+                                diskMaxUncNum);
+            }
+            else
+            {
+                DBG_LogInfo(CKGLOG_MEDIASCAN_0096, "Pool(%u) disk(%u) not repaired %u times and report prefail, max unc num is (%llu).",
+                         poolId, 
+                         g_uncNotRepairDiskInfo[poolId].diskId, 
+                         g_uncNotRepairDiskInfo[poolId].unRepairedTimes,
+                         diskMaxUncNum);
+                
+                /* ϱԤʧЧɹδ޸Ϣ */
+                initNotRepairDiskInfo(poolId);
+            }
+        }
+    }
+
+    spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+
+    return;
+}
+
+void checkNotRepairDiskInfoValid(poolid_t poolId)
+{
+    DISK_POOL_MEMBER_DISK_S *poolDiskIdList = NULL;
+    int32_t result;
+    bool isFind = FALSE;
+    uint32_t index;
+    uint32_t diskTpye = 0;
+    uint8_t diskState;
+
+    spin_lock(&(g_uncNotRepairDiskInfo[poolId].lock));
+    if (!IS_POOL_EXIST(poolId))
+    {
+        initNotRepairDiskInfo(poolId);
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        return;
+    }
+
+    /* Ӳδ¼δ޸ֱ̣ӷ */
+    if (INVALID_DISK_ID == g_uncNotRepairDiskInfo[poolId].diskId)
+    {
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        return;
+    }
+
+    /* ¼ĲSSDҪ */
+    result = ldIoCtlSync(g_uncNotRepairDiskInfo[poolId].diskId, IOCTRL_GET_DISK_TYPE, &diskTpye);
+    if ((RETURN_OK != result) || (!checkIsSsdDisk(diskTpye)))
+    {
+        initNotRepairDiskInfo(poolId);
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        return;
+    }
+
+    /* ״̬ˣҲҪ */
+    getDiskPoolMemberDiskStatus(poolId, g_uncNotRepairDiskInfo[poolId].diskId, &diskState);
+    if ((DISKPOOL_MEMBER_DISK_NORMAL != diskState))
+    {
+        initNotRepairDiskInfo(poolId);
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        return;
+    }
+    
+    poolDiskIdList = allocPoolDiskListMem();
+    if (NULL == poolDiskIdList)
+    {
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        return;
+    }
+    
+    result = getDiskPoolMemberDisks(poolId, poolDiskIdList);
+    if (RETURN_OK != result)
+    {
+        DBG_LogError(CKGLOG_MEDIASCAN_0096, "Get disk id list failed, pool id(%u), return(%d).",
+                     poolId, result);
+        spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+        freePoolDiskListMem(poolDiskIdList);
+        return;
+    }
+
+    /* 鿴ǰȫֱ¼δ޸ǷǳԱ̣Ҫɾ
+    ͬλ̺ȫֱ¼̲ǳԱ */
+    for (index = 0; index <  poolDiskIdList->memberDiskNum; index++)
+    {
+        if (g_uncNotRepairDiskInfo[poolId].diskId == poolDiskIdList->memberDiskId[index])
+        {
+            isFind = TRUE;
+        }
+    }
+    
+    freePoolDiskListMem(poolDiskIdList);
+
+    if (!isFind)
+    {
+        CKG_PRINT_LIMIT_PERIOD(CKGLOG_CTRL_INTERVAL, CKGLOG_CTRL_COUNT, DBG_LOG_INFO, CKGLOG_MEDIASCAN_0096, 
+                                            "Old disk(disk id:%u, max unc num:%llu, lba sum:%llu, unrepair times:%u)"
+                                            "is not the member disk of pool(%u), clear it.",
+                                            g_uncNotRepairDiskInfo[poolId].diskId, 
+                                            g_uncNotRepairDiskInfo[poolId].maxUncNum, 
+                                            g_uncNotRepairDiskInfo[poolId].lbaSum, 
+                                            g_uncNotRepairDiskInfo[poolId].unRepairedTimes, 
+                                            poolId);
+        
+        initNotRepairDiskInfo(poolId);
+    }
+
+    spin_unlock(&(g_uncNotRepairDiskInfo[poolId].lock));
+
+    return;
+}
+ 
+/**************************************************************************
+     :  Ƿﵽָδ޸UNCҪϱ̼ʧЧ
+ :  scanDiskReq : ɨӲREQ
+ :  
+ ֵ  :  
+     :  
+**************************************************************************/
+void checkAndReportDiskPrefail(REQ_S *scanDiskReq)
+{
+    uint64_t diskMaxUncNum;
+    SMARTSCAN_DISK_INFO_S *diskInfo = NULL;
+    uint64_t lbaSum;
+
+    diskInfo = GET_UNC_DISK_INFO(scanDiskReq);
+    diskMaxUncNum = GET_UNC_MAX_NUM(scanDiskReq);
+    lbaSum = GET_UNC_LBA_SUM(scanDiskReq);
+
+    if (MAX_POOL_NUM <= diskInfo->poolId)
+    {
+        return;
+    }
+
+    /* м¼δ޸ϢǷЧ */
+    checkNotRepairDiskInfoValid(diskInfo->poolId);
+
+    /* ̵UNCδﵽֵҪ֮ǰ¼ȫϢ */
+    if (diskInfo->uncNum < diskMaxUncNum)
+    {
+        clearNotRepairDiskInfo(diskInfo->poolId, diskInfo->diskId);
+
+    }
+    else
+    {
+        /* LBA֮ͲΪ0ŸϢֹȡUNCʱӲڲUNCﵽLBAȫ0ֹԤʧЧ */
+        if (0 != lbaSum)
+        {
+            updateNotRepairDiskInfo(diskInfo->poolId, diskInfo->diskId, lbaSum, diskMaxUncNum);
+        }
+    }
+
+    return;
+}
+
+void hotpatchInitUnRepairInfo(void)
+{
+    uint32_t index;
+    
+    if (!g_unRepairInfoInitFlag)
+    {
+        /* ʼδ޸UNCϢ */
+        for (index = 0; index <  MAX_POOL_NUM; index++)
+        {
+            spin_lock_init(&(g_uncNotRepairDiskInfo[index].lock));
+            g_uncNotRepairDiskInfo[index].maxUncNum = INVALID_VALUE64;
+            g_uncNotRepairDiskInfo[index].diskId = INVALID_DISK_ID;
+            g_uncNotRepairDiskInfo[index].lbaSum = INVALID_VALUE64;
+            g_uncNotRepairDiskInfo[index].unRepairedTimes = 0;
+        }
+        
+        g_unRepairInfoInitFlag = TRUE;
+        DBG_LogInfo(CKGLOG_MEDIASCAN_0096, "hotpatch init unrepair info finished.");
+    }
+
+    return;
+}
 
--- ./source/private_module/ckg/eh/smartrepair_debug.c	2018-04-26 08:06:00.000000000 +0000
+++ ./source/private_module/ckg/eh/smartrepair_debug.c.hotpatch	2019-05-09 11:20:28.000000000 +0000
@@ -498,7 +498,7 @@
     spin_unlock(&g_uncIoCounterLock);
     return;
 }
-
+bool doHotPatchParamAndIsNeedExit(int32_t argc, char *argv[]);
 /**************************************************************************
      :  ޸IO
  :  1)argc: 
@@ -509,7 +509,7 @@
 **************************************************************************/
 void uncShowIoCounter(int32_t argc, char *argv[])
 {
-    UNREFERENCE_PARAM(argv);
+    if (doHotPatchParamAndIsNeedExit(argc, argv)){return;}
 
     if ((2 < argc) || (1 > argc))
     {
@@ -1028,3 +1028,245 @@
     return;
 }
 
+#define DBG_PROC_MAX_UNREPAIR_TIMES_PARAM(result, optArg, optBits, maxUnRepairTimes)\
+        if ('t' == result)\
+        {\
+            DBG_SetOpt(&optBits, 't');\
+            maxUnRepairTimes = (uint32_t)ckgiofStrToU64(optArg);\
+            if ((5 > maxUnRepairTimes))\
+            {\
+                DBG_ShowUsageAndErrMsg("Set max unrepair times fail, times must be greater than 5"\
+                                        "Invalid times(%s).", optArg);\
+                return;\
+            }\
+            continue;\
+        }
+
+#define DBG_PROC_UNC_NUM_PARAM(result, optArg, optBits, uncNum)\
+        if ('u' == result)\
+        {\
+            DBG_SetOpt(&optBits, 'u');\
+            uncNum = (uint32_t)ckgiofStrToU64(optArg);\
+            continue;\
+        }
+
+#define DBG_PROC_UNC_LBA_SUM_PARAM(result, optArg, optBits, lbaSum)\
+        if ('l' == result)\
+        {\
+            DBG_SetOpt(&optBits, 'l');\
+            lbaSum = ckgiofStrToU64(optArg);\
+            continue;\
+        }
+typedef struct tagSMARTSCAN_NOT_REPAIR_DISK_INFO_S
+{
+    spinlock_t lock;
+    uint64_t maxUncNum;
+    uint64_t lbaSum;
+    diskid_t diskId;
+    uint32_t unRepairedTimes;
+} SMARTSCAN_NOT_REPAIR_DISK_INFO_S;
+
+extern SMARTSCAN_NOT_REPAIR_DISK_INFO_S g_uncNotRepairDiskInfo[MAX_POOL_NUM];
+extern bool g_unRepairDbgSwitch; extern uint32_t g_maxUnRepairTimesForDbg;
+extern diskid_t g_diskIdForDbg; extern uint32_t g_uncNumForDbg;
+extern uint64_t g_uncLbaSumForDbg;
+
+void uncDbgShowUnRepairInfo(int32_t argc, char *argv[])
+{
+    uint32_t index;
+
+    if ((4 < argc) || (1 > argc))
+    {
+        DBG_ShowUsageAndErrMsg("Input invalid parameter number!");
+        return ;
+    }
+    UNREFERENCE_PARAM(argv);
+
+    DBG_PrintBuf("Smart scan unrepair info:\n");
+    DBG_PrintBuf("-----------------------------------------\n");
+
+
+    DBG_Print("DiskID  PoolID  UNC Num  UnRepair Times  LBA SUM\n");
+    DBG_Print("------  ------  -------  --------------  ----------------\n");
+
+    for (index = 0; index <  MAX_POOL_NUM; index++)
+    {  
+        if (!IS_POOL_EXIST(index))
+        {
+            DBG_LogDebug(CKGLOG_MEDIASCAN_011A, "poolId %u is not exist.", index);
+            continue;
+        }
+
+        if (!isDiskPoolWorkNode(index))
+        {
+            continue;
+        }
+
+        spin_lock(&(g_uncNotRepairDiskInfo[index].lock));
+        if (INVALID_DISK_ID == g_uncNotRepairDiskInfo[index].diskId)
+        {
+            spin_unlock(&(g_uncNotRepairDiskInfo[index].lock));
+            continue;
+        }
+
+        DBG_PrintBuf("%5u  %5u  %7llu  %7u           %16llu\n", 
+                     g_uncNotRepairDiskInfo[index].diskId, 
+                     index, 
+                     g_uncNotRepairDiskInfo[index].maxUncNum, 
+                     g_uncNotRepairDiskInfo[index].unRepairedTimes,
+                     g_uncNotRepairDiskInfo[index].lbaSum);
+        
+        spin_unlock(&(g_uncNotRepairDiskInfo[index].lock));
+
+    }
+
+    return;
+}
+
+void uncSetUnrepairDbgOn(int32_t argc, char *argv[])
+{
+    UNREFERENCE_PARAM(argv);
+
+    if (3 != argc)
+    {
+        DBG_ShowUsageAndErrMsg("Input err command param.");
+        return ;
+    }
+
+    g_unRepairDbgSwitch = TRUE;
+
+    DBG_Print("Set unrepair debug switch on success ....\n");
+    DBG_LogInfo(CKGLOG_MEDIASCAN_010F, "Set unrepair debug switch on success.");
+}
+
+void uncSetUnrepairDbgOff(int32_t argc, char *argv[])
+{
+    UNREFERENCE_PARAM(argv);
+
+    if (3 != argc)
+    {
+        DBG_ShowUsageAndErrMsg("Input err command param.");
+        return ;
+    }
+
+    g_unRepairDbgSwitch = FALSE;
+
+    DBG_Print("Set unrepair debug switch off success ....\n");
+    DBG_LogInfo(CKGLOG_MEDIASCAN_010F, "Set unrepair debug switch off success.");
+}
+
+void uncDbgSetUnrepairParam(int32_t argc, char *argv[])
+{
+    int32_t result = RETURN_OK;
+    uint64_t diskId = INVALID_DISK_ID;
+    uint32_t uncNum = INVALID_VALUE32;
+    uint64_t lbaSum = INVALID_VALUE64;
+    uint32_t maxUnRepairTimes = 0;
+    uint32_t oldMaxUnRepairTimes;
+
+    DBG_OPT_S opt;   
+    uint32_t optBits = 0;
+    
+    if ((11 < argc) || (1 > argc))
+    {
+        DBG_ShowUsageAndErrMsg("Input invalid parameter number!");
+        return ;
+    }
+
+    if (FALSE == g_unRepairDbgSwitch)
+    {
+        DBG_PrintBuf("Unrepair debug switch if off, can not set unrepair param.\n");
+        return;
+    }
+
+    while ((result = DBG_GetOpt(argc, argv, "k:u:l:t:", &opt)) != -1)
+    {
+        
+        DBG_PROC_DISK_ID_PARAM(result, opt.szOptArg, optBits, diskId);
+        DBG_PROC_UNC_NUM_PARAM(result, opt.szOptArg, optBits, uncNum);
+        DBG_PROC_UNC_LBA_SUM_PARAM(result, opt.szOptArg, optBits, lbaSum);
+        DBG_PROC_MAX_UNREPAIR_TIMES_PARAM(result, opt.szOptArg, optBits, maxUnRepairTimes)
+        DBG_PROC_UNKNOWN_PARAM(result, argv[0], opt.szOptArg)
+        DBG_PROC_ERROR(opt.szErrMsg)
+    }
+
+    if (DBG_TestOpt(optBits, 'k'))
+    {        
+        g_diskIdForDbg = (diskid_t)diskId;
+        DBG_PrintBuf("Set unrepair debug param disk id:%u\n", g_diskIdForDbg);
+        DBG_LogInfo(CKGLOG_MEDIASCAN_010A, "Set unrepair debug param disk id:%u.", g_diskIdForDbg);
+    } 
+    if (DBG_TestOpt(optBits, 'u'))
+    {        
+        g_uncNumForDbg = uncNum;
+        DBG_PrintBuf("Set unrepair debug param unc number:%u\n", g_uncNumForDbg);
+        DBG_LogInfo(CKGLOG_MEDIASCAN_010A, "Set unrepair debug param unc number:%u.", g_uncNumForDbg);
+    }
+    if (DBG_TestOpt(optBits, 'l'))
+    {        
+        g_uncLbaSumForDbg = lbaSum;
+        DBG_PrintBuf("Set unrepair debug param unc lba sum:%llu\n", g_uncLbaSumForDbg);
+        DBG_LogInfo(CKGLOG_MEDIASCAN_010A, "Set unrepair debug param unc lba sum:%llu.", g_uncLbaSumForDbg);
+    }
+    if (DBG_TestOpt(optBits, 't'))
+    {
+        oldMaxUnRepairTimes = g_maxUnRepairTimesForDbg;
+        g_maxUnRepairTimesForDbg = maxUnRepairTimes;
+        DBG_PrintBuf("Set max unrepair times from %u to %u success.\n", oldMaxUnRepairTimes, g_maxUnRepairTimesForDbg);
+        DBG_LogInfo(CKGLOG_MEDIASCAN_010A, "Set max unrepair times from %u to %u success.", oldMaxUnRepairTimes, g_maxUnRepairTimesForDbg);
+    }
+    
+    return;
+}
+
+bool doHotPatchParamAndIsNeedExit(int32_t argc, char *argv[])
+{
+    int32_t result = RETURN_OK;
+    uint64_t hotpatchDbgFlag = INVALID_VALUE64;
+    
+    DBG_OPT_S opt;   
+    uint32_t optBits = 0;
+
+    while ((result = DBG_GetOpt(argc, argv, "h:", &opt)) != -1)
+    {
+        if ('h' == result)
+        {
+            DBG_SetOpt(&optBits, 'h');
+            hotpatchDbgFlag = ckgiofStrToU64(opt.szOptArg);
+            if (3 < hotpatchDbgFlag)
+            {
+                DBG_PrintBuf("Invalid hotpatch debug flag(%llu).\n", hotpatchDbgFlag);
+                DBG_LogInfo(CKGLOG_MEDIASCAN_010A, "Invalid hotpatch debug flag(%llu).", hotpatchDbgFlag);
+                return TRUE;
+            }
+            break;
+        }
+    }
+
+    if (DBG_TestOpt(optBits, 'h'))
+    {
+        switch (hotpatchDbgFlag)
+        {
+            case 0:
+                uncDbgShowUnRepairInfo(argc, argv);
+                break;
+            case 1:
+                uncSetUnrepairDbgOn(argc, argv);
+                break;
+            case 2:
+                uncSetUnrepairDbgOff(argc, argv);
+                break;
+            case 3:
+                uncDbgSetUnrepairParam(argc, argv);
+                break;
+            default:
+                DBG_PrintBuf("Invalid hotpatch debug flag(%llu).\n", hotpatchDbgFlag);
+                DBG_LogInfo(CKGLOG_MEDIASCAN_010A, "Invalid hotpatch debug flag(%llu).", hotpatchDbgFlag);
+                break;
+        }
+        return TRUE;
+    }
+    
+    return FALSE;
+}
+
