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 *