diff --git a/fs/fat/os_adapt/fatfs.c b/fs/fat/os_adapt/fatfs.c
index 933b169f008202043f3a2efab3e66c05d62b4645..a8aba58ce9dac2cfe14875c5ca58bb47170a13e9 100755
--- a/fs/fat/os_adapt/fatfs.c
+++ b/fs/fat/os_adapt/fatfs.c
@@ -1372,7 +1372,8 @@ int fatfs_readdir(struct Vnode *vp, struct fs_dirent_s *idir)
DEF_NAMBUF;
INIT_NAMBUF(fs);
for (i = 0; i < idir->read_cnt; i++) {
- result = dir_read(dp, 0);
+ /* using dir_read_massive to promote performance */
+ result = dir_read_massive(dp, 0);
if (result == FR_NO_FILE) {
break;
} else if (result != FR_OK) {
@@ -1596,7 +1597,7 @@ static int fatfs_set_part_info(los_part *part)
return -ENOMEM;
}
(void)memset_s(buf, disk->sector_size, 0, disk->sector_size);
- ret = los_disk_read(part->disk_id, buf, 0, 1);
+ ret = los_disk_read(part->disk_id, buf, 0, 1, TRUE); /* TRUE when not reading large data */
if (ret < 0) {
free(buf);
return -EIO;
diff --git a/fs/include/disk.h b/fs/include/disk.h
index d4362be4150b7b253cd62c52fbbc026c643a8911..b9d64f45b29b4ad92e747087af7bcf576ea7c2c2 100644
--- a/fs/include/disk.h
+++ b/fs/include/disk.h
@@ -303,6 +303,7 @@ INT32 los_disk_deinit(INT32 diskID);
* @param buf [OUT] Type #VOID * memory which used to store read data.
* @param sector [IN] Type #UINT64 expected start sector number to read.
* @param count [IN] Type #UINT32 expected sector count to read.
+ * @param useRead [IN] Type #BOOL set FALSE to use the write block for optimization
*
* @retval #0 Read success.
* @retval #-1 Read failed.
@@ -312,7 +313,7 @@ INT32 los_disk_deinit(INT32 diskID);
* @see los_disk_write
*
*/
-INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count);
+INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead);
/**
* @ingroup disk
@@ -438,6 +439,7 @@ INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum);
* @param buf [OUT] Type #VOID * memory which used to store the data to be read.
* @param sector [IN] Type #UINT64 start sector number of chosen partition.
* @param count [IN] Type #UINT32 the expected sector count for reading.
+ * @param useRead [IN] Type #BOOL FALSE when reading large contiguous data, TRUE for other situations
*
* @retval #0 Read success.
* @retval #-1 Read failed.
@@ -447,7 +449,7 @@ INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum);
* @see los_part_read
*
*/
-INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count);
+INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead);
/**
* @ingroup disk
@@ -477,6 +479,30 @@ INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count);
*/
INT32 los_part_write(INT32 pt, const VOID *buf, UINT64 sector, UINT32 count);
+/**
+ * @ingroup disk
+ * @brief Clear the bcache data
+ *
+ * @par Description:
+ * Flush the data and mark the block as unused.
+ *
+ * @attention
+ *
+ *
+ * @param drvID [IN] Type #INT32 disk id
+ *
+ * @retval #0 Write success.
+ * @retval #-1 Write failed.
+ *
+ * @par Dependency:
+ *
+ * @see los_part_read
+ *
+ */
+INT32 los_disk_cache_clear(INT32 drvID);
+
/**
* @ingroup disk
* @brief Get information of chosen partition.
diff --git a/fs/vfs/bcache/src/bcache.c b/fs/vfs/bcache/src/bcache.c
index a28fe701b963aeaafcc3ddf9382a65e0fa417009..b04b0057276833600e3d7f8f864d350a6f6bb66c 100644
--- a/fs/vfs/bcache/src/bcache.c
+++ b/fs/vfs/bcache/src/bcache.c
@@ -45,11 +45,38 @@
#define ASYNC_EVENT_BIT 0x01
#ifdef DEBUG
-#define D(args) printf(args)
+#define D(args) printf args
#else
#define D(args)
#endif
+#ifdef BCACHE_ANALYSE
+UINT32 g_memSize;
+volatile UINT32 g_blockNum;
+volatile UINT32 g_dataSize;
+volatile UINT8 *g_memStart;
+volatile UINT32 g_switchTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 };
+volatile UINT32 g_hitTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 };
+#endif
+
+VOID BcacheAnalyse(UINT32 level)
+{
+ (VOID)level;
+#ifdef BCACHE_ANALYSE
+ int i;
+
+ PRINTK("Bcache information:\n");
+ PRINTK(" mem: %u\n", g_memSize);
+ PRINTK(" block number: %u\n", g_blockNum);
+ PRINTK("index, switch, hit\n");
+ for (i = 0; i < g_blockNum; i++) {
+ PRINTK("%5d, %6d, %3d\n", i, g_switchTimes[i], g_hitTimes[i]);
+ }
+#else
+ PRINTK("Bcache hasn't started\n");
+#endif
+}
+
#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
UINT32 g_syncThreadPrio = CONFIG_FS_FAT_SYNC_THREAD_PRIO;
@@ -623,6 +650,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
if (block != NULL) {
D(("bcache block = %llu found in cache\n", num));
+#ifdef BCACHE_ANALYSE
+ UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize;
+ PRINTK(", [HIT], %llu, %u\n", num, index);
+ g_hitTimes[index]++;
+#endif
if (first != block) {
ListMoveBlockToHead(bc, block);
@@ -647,6 +679,11 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
if (block == NULL) {
return -ENOMEM;
}
+#ifdef BCACHE_ANALYSE
+ UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize;
+ PRINTK(", [MISS], %llu, %u\n", num, index);
+ g_switchTimes[index]++;
+#endif
BlockInit(bc, block, num);
if (readData == TRUE) {
@@ -667,6 +704,16 @@ static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlo
return ENOERR;
}
+INT32 BcacheClearCache(OsBcache *bc)
+{
+ OsBcacheBlock *block = NULL;
+ OsBcacheBlock *next = NULL;
+ LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(block, next, &bc->listHead, OsBcacheBlock, listNode) {
+ DelBlock(bc, block);
+ }
+ return 0;
+}
+
static INT32 BcacheInitCache(OsBcache *bc,
UINT8 *memStart,
UINT32 memSize,
@@ -701,6 +748,13 @@ static INT32 BcacheInitCache(OsBcache *bc,
dataMem = blockMem + (sizeof(OsBcacheBlock) * blockNum);
dataMem += ALIGN_DISP((UINTPTR)dataMem);
+#ifdef BCACHE_ANALYSE
+ g_memSize = memSize;
+ g_blockNum = blockNum;
+ g_dataSize = bc->blockSize;
+ g_memStart = dataMem;
+#endif
+
for (i = 0; i < blockNum; i++) {
block = (OsBcacheBlock *)(VOID *)blockMem;
block->data = dataMem;
@@ -710,7 +764,7 @@ static INT32 BcacheInitCache(OsBcache *bc,
bc->wStart = block;
}
- LOS_ListAdd(&bc->freeListHead, &block->listNode);
+ LOS_ListTailInsert(&bc->freeListHead, &block->listNode);
blockMem += sizeof(OsBcacheBlock);
dataMem += bc->blockSize;
@@ -768,7 +822,7 @@ INT32 BlockCacheDrvCreate(VOID *handle,
return ENOERR;
}
-INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
+INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector, BOOL useRead)
{
OsBcacheBlock *block = NULL;
UINT8 *tempBuf = buf;
@@ -777,6 +831,9 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
INT32 ret = ENOERR;
UINT64 pos;
UINT64 num;
+#ifdef BCACHE_ANALYSE
+ PRINTK("bcache read:\n");
+#endif
if (bc == NULL || buf == NULL || len == NULL) {
return -EPERM;
@@ -796,7 +853,8 @@ INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector)
(VOID)pthread_mutex_lock(&bc->bcacheMutex);
- ret = BcacheGetBlock(bc, num, TRUE, &block);
+ /* useRead should be FALSE when reading large contiguous data */
+ ret = BcacheGetBlock(bc, num, useRead, &block);
if (ret != ENOERR) {
(VOID)pthread_mutex_unlock(&bc->bcacheMutex);
break;
@@ -841,6 +899,9 @@ INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector
UINT32 currentSize;
UINT64 pos;
UINT64 num;
+#ifdef BCACHE_ANALYSE
+ PRINTK("bcache write:\n");
+#endif
pos = sector * bc->sectorSize;
num = pos >> bc->blockSizeLog2;
diff --git a/fs/vfs/disk/disk.c b/fs/vfs/disk/disk.c
index 433dd5eae3c82a907623bb236b2ebb8108a90ade..e7dfe5bd01a64ab56da1558c9ba2c0267f3649a7 100755
--- a/fs/vfs/disk/disk.c
+++ b/fs/vfs/disk/disk.c
@@ -798,7 +798,7 @@ INT32 DiskPartitionRegister(los_disk *disk)
return ENOERR;
}
-INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count)
+INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
{
#ifdef LOSCFG_FS_FAT_CACHE
UINT32 len;
@@ -830,7 +830,8 @@ INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count)
goto ERROR_HANDLE;
}
len = disk->bcache->sectorSize * count;
- result = BlockCacheRead(disk->bcache, (UINT8 *)buf, &len, sector);
+ /* useRead should be FALSE when reading large contiguous data */
+ result = BlockCacheRead(disk->bcache, (UINT8 *)buf, &len, sector, useRead);
if (result != ENOERR) {
PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len);
}
@@ -975,7 +976,7 @@ ERROR_HANDLE:
return VFS_ERROR;
}
-INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count)
+INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
{
const los_part *part = get_part(pt);
los_disk *disk = NULL;
@@ -1017,7 +1018,8 @@ INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count)
goto ERROR_HANDLE;
}
- ret = los_disk_read((INT32)part->disk_id, buf, sector, count);
+ /* useRead should be FALSE when reading large contiguous data */
+ ret = los_disk_read((INT32)part->disk_id, buf, sector, count, useRead);
if (ret < 0) {
goto ERROR_HANDLE;
}
@@ -1148,6 +1150,29 @@ ERROR_HANDLE:
return VFS_ERROR;
}
+INT32 los_disk_cache_clear(INT32 drvID)
+{
+ INT32 result;
+ los_disk *disk = NULL;
+
+ result = OsSdSync(drvID);
+ if (result != 0) {
+ PRINTK("[ERROR]disk cache clear failed!n");
+ return result;
+ }
+
+ disk = get_disk(drvID);
+ if (disk == NULL) {
+ return -1;
+ }
+
+ DISK_LOCK(&disk->disk_mutex);
+ result = BcacheClearCache(disk->bcache);
+ DISK_UNLOCK(&disk->disk_mutex);
+
+ return result;
+}
+
#ifdef LOSCFG_FS_FAT_CACHE
static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
{
diff --git a/fs/vfs/include/bcache/bcache.h b/fs/vfs/include/bcache/bcache.h
index 8fc3efd9ff55c62846de5c86d50a1e4323508d6b..24bf96c093dcc1d2669072e194c5045b3b2f7252 100644
--- a/fs/vfs/include/bcache/bcache.h
+++ b/fs/vfs/include/bcache/bcache.h
@@ -131,6 +131,7 @@ typedef struct tagOsBcache {
* @param len [IN] number of bytes to read
* @param num [IN] starting block number
* @param pos [IN] starting position inside starting block
+ * @param useRead [IN] whether use the read block or write block
*
* @attention
*
@@ -147,7 +148,8 @@ typedef struct tagOsBcache {
INT32 BlockCacheRead(OsBcache *bc,
UINT8 *buf,
UINT32 *len,
- UINT64 pos);
+ UINT64 pos,
+ BOOL useRead);
/**
* @ingroup bcache
@@ -251,6 +253,7 @@ OsBcache *BlockCacheInit(struct Vnode *devNode,
*/
VOID BlockCacheDeinit(OsBcache *bc);
+INT32 BcacheClearCache(OsBcache *bc);
INT32 OsSdSync(INT32 id);
#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
diff --git a/kernel/common/los_rootfs.c b/kernel/common/los_rootfs.c
index ad40a88028df565a62b83b35931f03f659b9644d..ddf0b240b83d3a6cb6479c27b39634703036da33 100644
--- a/kernel/common/los_rootfs.c
+++ b/kernel/common/los_rootfs.c
@@ -248,8 +248,9 @@ STATIC INT32 GetArgs(CHAR **args)
PRINT_ERR("Get EMMC disk failed!\n");
goto ERROUT;
}
+ /* param4 is TRUE for not reading large contiguous data */
ret = los_disk_read(g_emmcDisk->disk_id, cmdLine, COMMAND_LINE_ADDR / EMMC_SEC_SIZE,
- COMMAND_LINE_SIZE / EMMC_SEC_SIZE);
+ COMMAND_LINE_SIZE / EMMC_SEC_SIZE, TRUE);
if (ret != 0) {
PRINT_ERR("Read EMMC command line failed!\n");
goto ERROUT;