更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
bcache.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "bcache.h"
33#include "assert.h"
34#include "stdlib.h"
35#include "linux/delay.h"
36#include "disk_pri.h"
37#include "user_copy.h"
38
39#undef HALARC_ALIGNMENT
40#define DMA_ALLGN 64
41#define HALARC_ALIGNMENT DMA_ALLGN
42#define BCACHE_MAGIC_NUM 20132016
43#define BCACHE_STATCK_SIZE 0x3000
44#define ASYNC_EVENT_BIT 0x01
45
46#ifdef DEBUG
47#define D(args) printf args
48#else
49#define D(args)
50#endif
51
52#ifdef BCACHE_ANALYSE
56volatile UINT8 *g_memStart;
57volatile UINT32 g_switchTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 };
58volatile UINT32 g_hitTimes[CONFIG_FS_FAT_BLOCK_NUMS] = { 0 };
59#endif
60
62{
63 (VOID)level;
64#ifdef BCACHE_ANALYSE
65 int i;
66
67 PRINTK("Bcache information:\n");
68 PRINTK(" mem: %u\n", g_memSize);
69 PRINTK(" block number: %u\n", g_blockNum);
70 PRINTK("index, switch, hit\n");
71 for (i = 0; i < g_blockNum; i++) {
72 PRINTK("%5d, %6d, %3d\n", i, g_switchTimes[i], g_hitTimes[i]);
73 }
74#else
75 PRINTK("Bcache hasn't started\n");
76#endif
77}
78
79#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD //
80
81UINT32 g_syncThreadPrio = CONFIG_FS_FAT_SYNC_THREAD_PRIO; //同步任务优先级
82UINT32 g_dirtyRatio = CONFIG_FS_FAT_DIRTY_RATIO;
83UINT32 g_syncInterval = CONFIG_FS_FAT_SYNC_INTERVAL;
84
86{
87 if ((dirtyRatio != g_dirtyRatio) && (dirtyRatio <= 100)) { /* The ratio cannot exceed 100% */
88 g_dirtyRatio = dirtyRatio;
89 }
90}
91///设置同步间隔,5秒
93{
94 g_syncInterval = interval;
95}
96///设置同步任务优先级,10
98{
99 INT32 ret = VFS_ERROR;
100 INT32 diskID;
101 los_disk *disk = NULL;
102 if ((prio == 0) || (prio >= OS_TASK_PRIORITY_LOWEST)) { /* The priority can not be zero */
103 return ret;
104 }
105
106 g_syncThreadPrio = prio;
107
108 /*
109 * If the name is NULL, it only sets the value of a global variable,
110 * and takes effect the next time the thread is created.
111 */
112 if (name == NULL) {
113 return ENOERR;
114 }
115
116 /* If the name is not NULL, it shall return an error if can't find the disk corresponding to name. */
117 diskID = los_get_diskid_byname(name);//获取磁盘ID
118 disk = get_disk(diskID);//获取磁盘信息
119 if (disk == NULL) {
120 return ret;
121 }
122
123 if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR) {
124 PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__);
125 return ret;
126 }
127 if ((disk->disk_status == STAT_INUSED) && (disk->bcache != NULL)) {
128 ret = LOS_TaskPriSet(disk->bcache->syncTaskId, prio);//设置任务优先级
129 }
130 if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR) {
131 PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__);
132 return VFS_ERROR;
133 }
134 return ret;
135}
136#endif
137///红黑树找块
139{
140 OsBcacheBlock *block = NULL;
141 struct rb_node *node = bc->rbRoot.rb_node;
142
143 for (; node != NULL; node = (block->num < num) ? node->rb_right : node->rb_left) {
144 block = rb_entry(node, OsBcacheBlock, rbNode);
145 if (block->num == num) {
146 return block;
147 }
148 }
149 return NULL;
150}
151///添加缓存块
152static VOID RbAddBlock(OsBcache *bc, OsBcacheBlock *block)
153{
154 struct rb_node *node = bc->rbRoot.rb_node;
155 struct rb_node **link = NULL;
156 OsBcacheBlock *b = NULL;
157
158 if (node == NULL) {
159 rb_link_node(&block->rbNode, NULL, &bc->rbRoot.rb_node);
160 } else {
161 for (; node != NULL; link = (b->num > block->num) ? &node->rb_left : &node->rb_right, node = *link) {
162 b = rb_entry(node, OsBcacheBlock, rbNode);
163 if (b->num == block->num) {
164 PRINT_ERR("RbAddBlock fail, b->num = %llu, block->num = %llu\n", b->num, block->num);
165 return;
166 }
167 }
168 rb_link_node(&block->rbNode, &b->rbNode, link);
169 }
170 rb_insert_color(&block->rbNode, &bc->rbRoot);
171}
172///删除红黑树块
173static inline VOID RbDelBlock(OsBcache *bc, OsBcacheBlock *block)
174{
175 rb_erase(&block->rbNode, &bc->rbRoot);
176}
177///删除红黑树块
178static inline VOID ListMoveBlockToHead(OsBcache *bc, OsBcacheBlock *block)
179{
180 LOS_ListDelete(&block->listNode);
181 LOS_ListAdd(&bc->listHead, &block->listNode);
182}
183///释放块
184static inline VOID FreeBlock(OsBcache *bc, OsBcacheBlock *block)
185{
186 block->used = FALSE;
187 LOS_ListAdd(&bc->freeListHead, &block->listNode);
188}
189
191{
192 UINT32 i, log2;
193
194 i = val;
195 log2 = 0;
196 while ((i & 1) == 0) { /* Check if the last bit is 1 */
197 i >>= 1;
198 log2++;
199 }
200 if (i != 1) { /* Not the power of 2 */
201 return 0;
202 }
203
204 return log2;
205}
206
207static INT32 FindFlagPos(const UINT32 *arr, UINT32 len, UINT32 *p1, UINT32 *p2)
208{
209 UINT32 *start = p1;
210 UINT32 *end = p2;
211 UINT32 i, j, tmp;
212 UINT32 val = 1;
213
214 *start = BCACHE_MAGIC_NUM;
215 *end = 0;
216 for (i = 0; i < len; i++) {
217 for (j = 0; j < UNSIGNED_INTEGER_BITS; j++) {
218 tmp = arr[i] << j;
219 tmp = tmp >> UNINT_MAX_SHIFT_BITS;
220 if (tmp != val) {
221 continue;
222 }
223 if (val && (*start == BCACHE_MAGIC_NUM)) {
224 *start = (i << UNINT_LOG2_SHIFT) + j;
225 val = 1 - val; /* Control parity by 0 and 1 */
226 } else if (val && (*start != BCACHE_MAGIC_NUM)) {
227 *start = 0;
228 return VFS_ERROR;
229 } else {
230 *end = (i << UNINT_LOG2_SHIFT) + j;
231 val = 1 - val; /* Control parity by 0 and 1 */
232 }
233 }
234 }
235 if (*start == BCACHE_MAGIC_NUM) {
236 *start = 0;
237 return VFS_ERROR;
238 }
239 if (*end == 0) {
240 *end = len << UNINT_LOG2_SHIFT;
241 }
242
243 return ENOERR;
244}
245
246static INT32 BlockRead(OsBcache *bc, OsBcacheBlock *block, UINT8 *buf)
247{
248 INT32 ret = bc->breadFun(bc->priv, buf, bc->sectorPerBlock,
249 (block->num) << GetValLog2(bc->sectorPerBlock));
250 if (ret) {
251 PRINT_ERR("BlockRead, brread_fn error, ret = %d\n", ret);
252 if (block->modified == FALSE) {
253 if (block->listNode.pstNext != NULL) {
254 LOS_ListDelete(&block->listNode); /* list del block */
255 RbDelBlock(bc, block);
256 }
257 FreeBlock(bc, block);
258 }
259 return ret;
260 }
261
262 block->readFlag = TRUE;
263 return ENOERR;
264}
265
267{
268 UINT32 i, n, f, sectorPos, val, start, pos, currentSize;
269 UINT32 flagUse = bc->sectorPerBlock >> UNINT_LOG2_SHIFT;
270 UINT32 flag = UINT_MAX;
271 INT32 ret, bits;
272
273 if (block->readFlag == TRUE) {
274 return ENOERR;
275 }
276
277 for (i = 0; i < flagUse; i++) {
278 flag &= block->flag[i];
279 }
280
281 if (flag == UINT_MAX) {
282 return ENOERR;
283 }
284
285 ret = BlockRead(bc, block, bc->rwBuffer);
286 if (ret != ENOERR) {
287 return ret;
288 }
289
290 for (i = 0, sectorPos = 0; i < flagUse; i++) {
291 val = block->flag[i];
292 /* use unsigned integer for bit map */
293 for (f = 0, bits = UNSIGNED_INTEGER_BITS; bits > 0; val = ~(val << n), f++, bits = bits - (INT32)n) {
294 if (val == 0) {
295 n = UNSIGNED_INTEGER_BITS;
296 } else {
297 n = (UINT32)CLZ(val);
298 }
299 sectorPos += n;
300 if (((f % EVEN_JUDGED) != 0) || (n == 0)) { /* Number of leading zeros of n is zero */
301 goto LOOP;
302 }
303 if (sectorPos > ((i + 1) << UNINT_LOG2_SHIFT)) {
304 start = sectorPos - n;
305 currentSize = (((i + 1) << UNINT_LOG2_SHIFT) - start) * bc->sectorSize;
306 } else {
307 start = sectorPos - n;
308 currentSize = n * bc->sectorSize;
309 }
310 pos = start * bc->sectorSize;
311 if (memcpy_s(block->data + pos, bc->blockSize - pos, bc->rwBuffer + pos, currentSize) != EOK) {
312 return VFS_ERROR;
313 }
314LOOP:
315 if (sectorPos > ((i + 1) << UNINT_LOG2_SHIFT)) {
316 sectorPos = (i + 1) << UNINT_LOG2_SHIFT;
317 }
318 }
319 }
320
321 return ENOERR;
322}
323
324static VOID BcacheSetFlag(const OsBcache *bc, OsBcacheBlock *block, UINT32 pos, UINT32 size)
325{
326 UINT32 start, num, i, j, k;
327
328 if (bc->sectorSize == 0) {
329 PRINT_ERR("BcacheSetFlag sectorSize is equal to zero! \n");
330 return;
331 }
332
333 start = pos / bc->sectorSize;
334 num = size / bc->sectorSize;
335
336 i = start / UNSIGNED_INTEGER_BITS;
337 j = start % UNSIGNED_INTEGER_BITS;
338 for (k = 0; k < num; k++) {
339 block->flag[i] |= 1u << (UNINT_MAX_SHIFT_BITS - j);
340 j++;
341 if (j == UNSIGNED_INTEGER_BITS) {
342 j = 0;
343 i++;
344 }
345 }
346}
347
349{
350 INT32 ret = ENOERR;
351 UINT32 len, start, end;
352
353 if (block->modified == TRUE) {
354 D(("bcache writing block = %llu\n", block->num));
355
356 ret = FindFlagPos(block->flag, bc->sectorPerBlock >> UNINT_LOG2_SHIFT, &start, &end);
357 if (ret == ENOERR) {
358 len = end - start;
359 } else {
360 ret = BcacheGetFlag(bc, block);
361 if (ret != ENOERR) {
362 return ret;
363 }
364
365 len = bc->sectorPerBlock;
366 }
367
368 ret = bc->bwriteFun(bc->priv, (const UINT8 *)(block->data + (start * bc->sectorSize)),
369 len, (block->num * bc->sectorPerBlock) + start);
370 if (ret == ENOERR) {
371 block->modified = FALSE;
372 bc->modifiedBlock--;
373 } else {
374 PRINT_ERR("BcacheSyncBlock fail, ret = %d, len = %u, block->num = %llu, start = %u\n",
375 ret, len, block->num, start);
376 }
377 }
378 return ret;
379}
380
381static void NumListAdd(OsBcache *bc, OsBcacheBlock *block)
382{
383 OsBcacheBlock *temp = NULL;
384
385 LOS_DL_LIST_FOR_EACH_ENTRY(temp, &bc->numHead, OsBcacheBlock, numNode) {
386 if (temp->num > block->num) {
387 LOS_ListTailInsert(&temp->numNode, &block->numNode);
388 return;
389 }
390 }
391
392 LOS_ListTailInsert(&bc->numHead, &block->numNode);
393}
394
395static void AddBlock(OsBcache *bc, OsBcacheBlock *block)
396{
397 RbAddBlock(bc, block);
398 NumListAdd(bc, block);
399 bc->sumNum += block->num;
400 bc->nBlock++;
401 LOS_ListAdd(&bc->listHead, &block->listNode);
402}
403
404static void DelBlock(OsBcache *bc, OsBcacheBlock *block)
405{
406 LOS_ListDelete(&block->listNode); /* lru list del */
407 LOS_ListDelete(&block->numNode); /* num list del */
408 bc->sumNum -= block->num;
409 bc->nBlock--;
410 RbDelBlock(bc, block); /* rb tree del */
411 FreeBlock(bc, block); /* free list add */
412}
413
414static BOOL BlockAllDirty(const OsBcache *bc, OsBcacheBlock *block)
415{
416 UINT32 start = 0;
417 UINT32 end = 0;
418 UINT32 len = bc->sectorPerBlock >> UNINT_LOG2_SHIFT;
419
420 if (block->modified == TRUE) {
421 if (block->allDirty) {
422 return TRUE;
423 }
424
425 if (FindFlagPos(block->flag, len, &start, &end) == ENOERR) {
426 if ((end - start) == bc->sectorPerBlock) {
427 block->allDirty = TRUE;
428 return TRUE;
429 }
430 }
431 }
432
433 return FALSE;
434}
435
437{
438 OsBcacheBlock *base = bc->wStart;
439 OsBcacheBlock *end = bc->wEnd;
440 while (base < end) {
441 if (base->used == FALSE) {
442 base->used = TRUE;
443 LOS_ListDelete(&base->listNode);
444 return base;
445 }
446 base++;
447 }
448
449 return NULL;
450}
451
452/* try get free block first, if failed free a useless block */
454{
455 LOS_DL_LIST *node = NULL;
456 OsBcacheBlock *block = NULL;
457
458 LOS_DL_LIST_FOR_EACH_ENTRY(block, &bc->freeListHead, OsBcacheBlock, listNode) {
459 if (block->readBuff == read) {
460 block->used = TRUE;
461 LOS_ListDelete(&block->listNode);
462 return block; /* get free one */
463 }
464 }
465
466 node = bc->listHead.pstPrev;
467 while (node != &bc->listHead) {
468 block = LOS_DL_LIST_ENTRY(node, OsBcacheBlock, listNode);
469 node = block->listNode.pstPrev;
470
471 if (block->readBuff == read) {
472 if (block->modified == TRUE) {
473 BcacheSyncBlock(bc, block);
474 }
475
476 DelBlock(bc, block);
477 block->used = TRUE;
478 LOS_ListDelete(&block->listNode);
479 return block; /* get used one */
480 }
481 }
482
483 return NULL;
484}
485
486/* flush combined blocks */
487static VOID WriteMergedBlocks(OsBcache *bc, OsBcacheBlock *begin, int blocks)
488{
489 INT32 ret;
490 OsBcacheBlock *cur = NULL;
491 OsBcacheBlock *next = NULL;
492 UINT32 len = blocks * bc->sectorPerBlock;
493 UINT64 pos = begin->num * bc->sectorPerBlock;
494
495 ret = bc->bwriteFun(bc->priv, (const UINT8 *)begin->data, len, pos);
496 if (ret != ENOERR) {
497 PRINT_ERR("WriteMergedBlocks bwriteFun failed ret %d\n", ret);
498 return;
499 }
500
501 bc->modifiedBlock -= blocks;
502 cur = begin;
503 while (blocks > 0) {
504 next = LOS_DL_LIST_ENTRY(cur->numNode.pstNext, OsBcacheBlock, numNode);
505 DelBlock(bc, cur);
506 cur->modified = FALSE;
507 blocks--;
508 cur = next;
509 }
510}
511
512/* find continue blocks and flush them */
513static VOID MergeSyncBlocks(OsBcache *bc, OsBcacheBlock *start)
514{
515 INT32 mergedBlock = 0;
516 OsBcacheBlock *cur = start;
517 OsBcacheBlock *last = NULL;
518
519 while (cur <= bc->wEnd) {
520 if (!cur->used || !BlockAllDirty(bc, cur)) {
521 break;
522 }
523
524 if (last && (last->num + 1 != cur->num)) {
525 break;
526 }
527
528 mergedBlock++;
529 last = cur;
530 cur++;
531 }
532
533 if (mergedBlock > 0) {
534 WriteMergedBlocks(bc, start, mergedBlock);
535 }
536}
537
538/* get the min write block num of block cache buffer */
540{
541 UINT64 ret = 0;
542 OsBcacheBlock *block = NULL;
543
544 LOS_DL_LIST_FOR_EACH_ENTRY(block, &bc->numHead, OsBcacheBlock, numNode) {
545 if (!block->readBuff) {
546 ret = block->num;
547 break;
548 }
549 }
550
551 return ret;
552}
553
555{
556 OsBcacheBlock *last = NULL;
557 OsBcacheBlock *prefer = NULL;
558
559 if (read) { /* read */
560 return GetSlowBlock(bc, TRUE);
561 }
562
563 /* fallback, this may happen when the block previously flushed, use read buffer */
564 if (bc->nBlock && num < GetMinWriteNum(bc)) {
565 return GetSlowBlock(bc, TRUE);
566 }
567
568 last = RbFindBlock(bc, num - 1); /* num=0 is ok */
569 if (last == NULL || last->readBuff) {
570 return GetBaseBlock(bc); /* new block */
571 }
572
573 prefer = last + 1;
574 if (prefer > bc->wEnd) {
575 prefer = bc->wStart;
576 }
577
578 /* this is a sync thread synced block! */
579 if (prefer->used && !prefer->modified) {
580 prefer->used = FALSE;
581 DelBlock(bc, prefer);
582 }
583
584 if (prefer->used) {
585 MergeSyncBlocks(bc, prefer);
586 }
587
588 if (prefer->used) {
589 BcacheSyncBlock(bc, prefer);
590 DelBlock(bc, prefer);
591 }
592
593 prefer->used = TRUE;
594 LOS_ListDelete(&prefer->listNode); /* del from free list */
595
596 return prefer;
597}
598
600{
601 LOS_DL_LIST *node = NULL;
602 OsBcacheBlock *block = NULL;
603 INT32 ret = ENOERR;
604
605 D(("bcache cache sync\n"));
606
608 node = bc->listHead.pstPrev;
609 while (&bc->listHead != node) {
610 block = LOS_DL_LIST_ENTRY(node, OsBcacheBlock, listNode);
611 ret = BcacheSyncBlock(bc, block);
612 if (ret != ENOERR) {
613 PRINT_ERR("BcacheSync error, ret = %d\n", ret);
614 break;
615 }
616 node = node->pstPrev;
617 }
619
620 return ret;
621}
622
623static VOID BlockInit(OsBcache *bc, OsBcacheBlock *block, UINT64 num)
624{
625 (VOID)memset_s(block->flag, sizeof(block->flag), 0, sizeof(block->flag));
626 block->num = num;
627 block->readFlag = FALSE;
628 if (block->modified == TRUE) {
629 block->modified = FALSE;
630 bc->modifiedBlock--;
631 }
632 block->allDirty = FALSE;
633}
634
635static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlock **dblock)
636{
637 INT32 ret;
638 OsBcacheBlock *block = NULL;
639 OsBcacheBlock *first = NULL;
640
641 /*
642 * First check if the most recently used block is the requested block,
643 * this can improve performance when using byte access functions.
644 */
645 if (LOS_ListEmpty(&bc->listHead) == FALSE) {
646 first = LOS_DL_LIST_ENTRY(bc->listHead.pstNext, OsBcacheBlock, listNode);
647 block = (first->num == num) ? first : RbFindBlock(bc, num);
648 }
649
650 if (block != NULL) {
651 D(("bcache block = %llu found in cache\n", num));
652#ifdef BCACHE_ANALYSE
653 UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize;
654 PRINTK(", [HIT], %llu, %u\n", num, index);
655 g_hitTimes[index]++;
656#endif
657
658 if (first != block) {
659 ListMoveBlockToHead(bc, block);
660 }
661 *dblock = block;
662
663 if ((bc->prereadFun != NULL) && (readData == TRUE) && (block->pgHit == 1)) {
664 block->pgHit = 0;
665 bc->prereadFun(bc, block);
666 }
667
668 return ENOERR;
669 }
670
671 D(("bcache block = %llu NOT found in cache\n", num));
672
673 block = AllocNewBlock(bc, readData, num);
674 if (block == NULL) {
675 block = GetSlowBlock(bc, readData);
676 }
677
678 if (block == NULL) {
679 return -ENOMEM;
680 }
681#ifdef BCACHE_ANALYSE
682 UINT32 index = ((UINT32)(block->data - g_memStart)) / g_dataSize;
683 PRINTK(", [MISS], %llu, %u\n", num, index);
684 g_switchTimes[index]++;
685#endif
686 BlockInit(bc, block, num);
687
688 if (readData == TRUE) {
689 D(("bcache reading block = %llu\n", block->num));
690
691 ret = BlockRead(bc, block, block->data);
692 if (ret != ENOERR) {
693 return ret;
694 }
695 if (bc->prereadFun != NULL) {
696 bc->prereadFun(bc, block);
697 }
698 }
699
700 AddBlock(bc, block);
701
702 *dblock = block;
703 return ENOERR;
704}
705
707{
708 OsBcacheBlock *block = NULL;
709 OsBcacheBlock *next = NULL;
710 LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(block, next, &bc->listHead, OsBcacheBlock, listNode) {
711 DelBlock(bc, block);
712 }
713 return 0;
714}
715///块设备缓存初始化
717 UINT8 *memStart,
718 UINT32 memSize,
719 UINT32 blockSize)
720{
721 UINT8 *blockMem = NULL;
722 UINT8 *dataMem = NULL;
723 OsBcacheBlock *block = NULL;
724 UINT32 blockNum, i;
725
727 LOS_ListInit(&bc->numHead);
728 bc->sumNum = 0;
729 bc->nBlock = 0;
730
731 if (!GetValLog2(blockSize)) {
732 PRINT_ERR("GetValLog2(%u) return 0.\n", blockSize);
733 return -EINVAL;
734 }
735
736 bc->rbRoot.rb_node = NULL;
737 bc->memStart = memStart;
738 bc->blockSize = blockSize;
739 bc->blockSizeLog2 = GetValLog2(blockSize);
740 bc->modifiedBlock = 0;
741
742 /* init block memory pool */
744
745 blockNum = (memSize - DMA_ALLGN) / (sizeof(OsBcacheBlock) + bc->blockSize);
746 blockMem = bc->memStart;
747 dataMem = blockMem + (sizeof(OsBcacheBlock) * blockNum);
748 dataMem += ALIGN_DISP((UINTPTR)dataMem);
749
750#ifdef BCACHE_ANALYSE
751 g_memSize = memSize;
752 g_blockNum = blockNum;
753 g_dataSize = bc->blockSize;
754 g_memStart = dataMem;
755#endif
756
757 for (i = 0; i < blockNum; i++) {
758 block = (OsBcacheBlock *)(VOID *)blockMem;
759 block->data = dataMem;
760 block->readBuff = (i < CONFIG_FS_FAT_READ_NUMS) ? TRUE : FALSE;
761
762 if (i == CONFIG_FS_FAT_READ_NUMS) {
763 bc->wStart = block;
764 }
765
767
768 blockMem += sizeof(OsBcacheBlock);
769 dataMem += bc->blockSize;
770 }
771
772 bc->wEnd = block;
773
774 return ENOERR;
775}
776///读块设备数据
777static INT32 DrvBread(struct Vnode *priv, UINT8 *buf, UINT32 len, UINT64 pos)
778{
779 struct block_operations *bops = (struct block_operations *)((struct drv_data *)priv->data)->ops;
780
781 INT32 ret = bops->read(priv, buf, pos, len);
782 if (ret != (INT32)len) {
783 PRINT_ERR("%s failure\n", __FUNCTION__);
784 return ret;
785 }
786 return ENOERR;
787}
788///写块设备数据
789static INT32 DrvBwrite(struct Vnode *priv, const UINT8 *buf, UINT32 len, UINT64 pos)
790{
791 struct block_operations *bops = (struct block_operations *)((struct drv_data *)priv->data)->ops;
792 INT32 ret = bops->write(priv, buf, pos, len);
793 if (ret != (INT32)len) {
794 PRINT_ERR("%s failure\n", __FUNCTION__);
795 return ret;
796 }
797 return ENOERR;
798}
799///初始化块设备
801 UINT8 *memStart,
802 UINT32 memSize,
803 UINT32 blockSize,
804 OsBcache *bc)
805{
806 INT32 ret;
807 bc->priv = handle;
808 bc->breadFun = DrvBread; //设置读块设备函数
809 bc->bwriteFun = DrvBwrite; //设置写块设备函数
810
811 ret = BcacheInitCache(bc, memStart, memSize, blockSize);
812 if (ret != ENOERR) {
813 return ret;
814 }
815
816 if (pthread_mutex_init(&bc->bcacheMutex, NULL) != ENOERR) {
817 return VFS_ERROR;
818 }
819 bc->bcacheMutex.attr.type = PTHREAD_MUTEX_RECURSIVE;
820
821 return ENOERR;
822}
823///读块设备缓存
824INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector, BOOL useRead)
825{
826 OsBcacheBlock *block = NULL;
827 UINT8 *tempBuf = buf;
828 UINT32 size;
829 UINT32 currentSize;
830 INT32 ret = ENOERR;
831 UINT64 pos;
832 UINT64 num;
833#ifdef BCACHE_ANALYSE
834 PRINTK("bcache read:\n");
835#endif
836
837 if (bc == NULL || buf == NULL || len == NULL) {
838 return -EPERM;
839 }
840
841 size = *len;
842 pos = sector * bc->sectorSize;
843 num = pos >> bc->blockSizeLog2;
844 pos = pos & (bc->blockSize - 1);
845
846 while (size > 0) {
847 if ((size + pos) > bc->blockSize) {
848 currentSize = bc->blockSize - (UINT32)pos;
849 } else {
850 currentSize = size;
851 }
852
854
855 /* useRead should be FALSE when reading large contiguous data */
856 ret = BcacheGetBlock(bc, num, useRead, &block);
857 if (ret != ENOERR) {
859 break;
860 }
861
862 if ((block->readFlag == FALSE) && (block->modified == TRUE)) {
863 ret = BcacheGetFlag(bc, block);
864 if (ret != ENOERR) {
866 return ret;
867 }
868 } else if ((block->readFlag == FALSE) && (block->modified == FALSE)) {
869 ret = BlockRead(bc, block, block->data);
870 if (ret != ENOERR) {
872 return ret;
873 }
874 }
875
876 if (LOS_CopyFromKernel((VOID *)tempBuf, size, (VOID *)(block->data + pos), currentSize) != EOK) {
878 return VFS_ERROR;
879 }
880
882
883 tempBuf += currentSize;
884 size -= currentSize;
885 pos = 0;
886 num++;
887 }
888 *len -= size;
889 return ret;
890}
891///写块设备缓存
892INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector)
893{
894 OsBcacheBlock *block = NULL;
895 const UINT8 *tempBuf = buf;
896 UINT32 size = *len;
897 INT32 ret = ENOERR;
898 UINT32 currentSize;
899 UINT64 pos;
900 UINT64 num;
901#ifdef BCACHE_ANALYSE
902 PRINTK("bcache write:\n");
903#endif
904
905 pos = sector * bc->sectorSize;
906 num = pos >> bc->blockSizeLog2;
907 pos = pos & (bc->blockSize - 1);
908
909 D(("bcache write len = %u pos = %llu bnum = %llu\n", *len, pos, num));
910
911 while (size > 0) {
912 if ((size + pos) > bc->blockSize) {
913 currentSize = bc->blockSize - (UINT32)pos;
914 } else {
915 currentSize = size;
916 }
917
919 ret = BcacheGetBlock(bc, num, FALSE, &block);
920 if (ret != ENOERR) {
922 break;
923 }
924
925 if (LOS_CopyToKernel((VOID *)(block->data + pos), bc->blockSize - (UINT32)pos,
926 (VOID *)tempBuf, currentSize) != EOK) {
928 return VFS_ERROR;
929 }
930 if (block->modified == FALSE) {
931 block->modified = TRUE;
932 bc->modifiedBlock++;
933 }
934 if ((pos == 0) && (currentSize == bc->blockSize)) {
935 (void)memset_s(block->flag, sizeof(block->flag), 0xFF, sizeof(block->flag));
936 block->allDirty = TRUE;
937 } else {
938 BcacheSetFlag(bc, block, (UINT32)pos, currentSize);
939 }
941
942 tempBuf += currentSize;
943 size -= currentSize;
944 pos = 0;
945 num++;
946 }
947 *len -= size;
948 return ret;
949}
950///块缓存同步
952{
953 return BcacheSync(bc);
954}
955
957{
958#ifdef LOSCFG_FS_FAT_CACHE
959 INT32 ret;
960 los_disk *disk = get_disk(id);
961 if ((disk == NULL) || (disk->disk_status == STAT_UNUSED)) {
962 return VFS_ERROR;
963 }
964 if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR) {
965 PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__);
966 return VFS_ERROR;
967 }
968 if ((disk->disk_status == STAT_INUSED) && (disk->bcache != NULL)) {
969 ret = BcacheSync(disk->bcache);
970 } else {
971 ret = VFS_ERROR;
972 }
973 if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR) {
974 PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__);
975 return VFS_ERROR;
976 }
977 return ret;
978#else
979 return VFS_ERROR;
980#endif
981}
982
984{
985 INT32 diskID = los_get_diskid_byname(name);
986 return OsSdSync(diskID);
987}
988
990{
991#ifdef LOSCFG_FS_FAT_CACHE
992 INT32 ret;
993 los_disk *disk = get_disk(id);
994 if (disk == NULL) {
995 return VFS_ERROR;
996 }
997
998 if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR) {
999 PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__);
1000 return VFS_ERROR;
1001 }
1002 if ((disk->disk_status == STAT_INUSED) && (disk->bcache != NULL)) {
1003 ret = (INT32)((disk->bcache->modifiedBlock * PERCENTAGE) / GetFatBlockNums());
1004 } else {
1005 ret = VFS_ERROR;
1006 }
1007 if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR) {
1008 PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__);
1009 return VFS_ERROR;
1010 }
1011 return ret;
1012#else
1013 return VFS_ERROR;
1014#endif
1015}
1016
1018{
1019 INT32 diskID = los_get_diskid_byname(name);
1020 return BcacheGetDirtyRatio(diskID);
1021}
1022
1023#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
1025{
1026 INT32 diskID = (INT32)id;
1027 INT32 dirtyRatio;
1028 while (1) {
1029 dirtyRatio = BcacheGetDirtyRatio(diskID);
1030 if (dirtyRatio > (INT32)g_dirtyRatio) {
1031 (VOID)OsSdSync(diskID);
1032 }
1033 msleep(g_syncInterval);
1034 }
1035}
1036///块缓存同步任务初始化,开了个内核任务.
1038{
1039 UINT32 ret;
1040 TSK_INIT_PARAM_S appTask;
1041
1042 (VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
1044 appTask.uwStackSize = BCACHE_STATCK_SIZE;
1045 appTask.pcName = "bcache_sync_task";
1046 appTask.usTaskPrio = g_syncThreadPrio;//任务优先级
1047 appTask.auwArgs[0] = (UINTPTR)id;
1048 appTask.uwResved = LOS_TASK_STATUS_DETACHED;
1049 ret = LOS_TaskCreate(&bc->syncTaskId, &appTask);
1050 if (ret != ENOERR) {
1051 PRINT_ERR("Bcache sync task create failed in %s, %d\n", __FUNCTION__, __LINE__);
1052 }
1053}
1054
1056{
1057 if (bc != NULL) {
1058 if (LOS_TaskDelete(bc->syncTaskId) != ENOERR) {
1059 PRINT_ERR("Bcache sync task delete failed in %s, %d\n", __FUNCTION__, __LINE__);
1060 }
1061 }
1062}
1063#endif
1064
1065OsBcache *BlockCacheInit(struct Vnode *devNode, UINT32 sectorSize, UINT32 sectorPerBlock,
1066 UINT32 blockNum, UINT64 blockCount)
1067{
1068 OsBcache *bcache = NULL;
1069 struct Vnode *blkDriver = devNode;
1070 UINT8 *bcacheMem = NULL;
1071 UINT8 *rwBuffer = NULL;
1072 UINT32 blockSize, memSize;
1073
1074 if ((blkDriver == NULL) || (sectorSize * sectorPerBlock * blockNum == 0) || (blockCount == 0)) {
1075 return NULL;
1076 }
1077
1078 blockSize = sectorSize * sectorPerBlock;
1079 if ((((UINT64)(sizeof(OsBcacheBlock) + blockSize) * blockNum) + DMA_ALLGN) > UINT_MAX) {
1080 return NULL;
1081 }
1082 memSize = ((sizeof(OsBcacheBlock) + blockSize) * blockNum) + DMA_ALLGN;
1083
1084 bcache = (OsBcache *)zalloc(sizeof(OsBcache));
1085 if (bcache == NULL) {
1086 PRINT_ERR("bcache_init : malloc %u Bytes failed!\n", sizeof(OsBcache));
1087 return NULL;
1088 }
1089
1090 bcacheMem = (UINT8 *)zalloc(memSize);
1091 if (bcacheMem == NULL) {
1092 PRINT_ERR("bcache_init : malloc %u Bytes failed!\n", memSize);
1093 goto ERROR_OUT_WITH_BCACHE;
1094 }
1095
1096 rwBuffer = (UINT8 *)memalign(DMA_ALLGN, blockSize);
1097 if (rwBuffer == NULL) {
1098 PRINT_ERR("bcache_init : malloc %u Bytes failed!\n", blockSize);
1099 goto ERROR_OUT_WITH_MEM;
1100 }
1101
1102 bcache->rwBuffer = rwBuffer;
1103 bcache->sectorSize = sectorSize;
1104 bcache->sectorPerBlock = sectorPerBlock;
1105 bcache->blockCount = blockCount;
1106
1107 if (BlockCacheDrvCreate(blkDriver, bcacheMem, memSize, blockSize, bcache) != ENOERR) {
1108 goto ERROR_OUT_WITH_BUFFER;
1109 }
1110
1111 return bcache;
1112
1113ERROR_OUT_WITH_BUFFER:
1114 free(rwBuffer);
1115ERROR_OUT_WITH_MEM:
1116 free(bcacheMem);
1117ERROR_OUT_WITH_BCACHE:
1118 free(bcache);
1119 return NULL;
1120}
1121
1123{
1124 if (bcache != NULL) {
1125 (VOID)pthread_mutex_destroy(&bcache->bcacheMutex);
1126 free(bcache->memStart);
1127 bcache->memStart = NULL;
1128 free(bcache->rwBuffer);
1129 bcache->rwBuffer = NULL;
1130 free(bcache);
1131 }
1132}
1133
1134static VOID BcacheAsyncPrereadThread(VOID *arg)
1135{
1136 OsBcache *bc = (OsBcache *)arg;
1137 OsBcacheBlock *block = NULL;
1138 INT32 ret;
1139 UINT32 i;
1140
1141 for (;;) {
1142 ret = (INT32)LOS_EventRead(&bc->bcacheEvent, PREREAD_EVENT_MASK,
1143 LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
1144 if (ret != ASYNC_EVENT_BIT) {
1145 PRINT_ERR("The event read in %s, %d is error!!!\n", __FUNCTION__, __LINE__);
1146 continue;
1147 }
1148
1149 for (i = 1; i <= PREREAD_BLOCK_NUM; i++) {
1150 if ((bc->curBlockNum + i) >= bc->blockCount) {
1151 break;
1152 }
1153
1154 (VOID)pthread_mutex_lock(&bc->bcacheMutex);
1155 ret = BcacheGetBlock(bc, bc->curBlockNum + i, TRUE, &block);
1156 if (ret != ENOERR) {
1157 PRINT_ERR("read block %llu error : %d!\n", bc->curBlockNum, ret);
1158 }
1159
1161 }
1162
1163 if (block != NULL) {
1164 block->pgHit = 1; /* preread complete */
1165 }
1166 }
1167}
1168
1170{
1171 UINT32 ret;
1172 OsBcache *bc = arg1;
1173 const OsBcacheBlock *block = arg2;
1174
1175 if (OsCurrTaskGet()->taskID != bc->prereadTaskId) {
1176 bc->curBlockNum = block->num;
1177 ret = LOS_EventWrite(&bc->bcacheEvent, ASYNC_EVENT_BIT);
1178 if (ret != ENOERR) {
1179 PRINT_ERR("Write event failed in %s, %d\n", __FUNCTION__, __LINE__);
1180 }
1181 }
1182}
1183
1185{
1186 UINT32 ret;
1187 TSK_INIT_PARAM_S appTask;
1188
1189 ret = LOS_EventInit(&bc->bcacheEvent);
1190 if (ret != ENOERR) {
1191 PRINT_ERR("Async event init failed in %s, %d\n", __FUNCTION__, __LINE__);
1192 return ret;
1193 }
1194
1195 (VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
1197 appTask.uwStackSize = BCACHE_STATCK_SIZE;
1198 appTask.pcName = "bcache_async_task";
1199 appTask.usTaskPrio = BCACHE_PREREAD_PRIO;
1200 appTask.auwArgs[0] = (UINTPTR)bc;
1201 appTask.uwResved = LOS_TASK_STATUS_DETACHED;
1202 ret = LOS_TaskCreate(&bc->prereadTaskId, &appTask);
1203 if (ret != ENOERR) {
1204 PRINT_ERR("Bcache async task create failed in %s, %d\n", __FUNCTION__, __LINE__);
1205 }
1206
1207 return ret;
1208}
1209
1211{
1212 UINT32 ret = LOS_NOK;
1213
1214 if (bc != NULL) {
1215 ret = LOS_TaskDelete(bc->prereadTaskId);
1216 if (ret != ENOERR) {
1217 PRINT_ERR("Bcache async task delete failed in %s, %d\n", __FUNCTION__, __LINE__);
1218 }
1219
1220 ret = LOS_EventDestroy(&bc->bcacheEvent);
1221 if (ret != ENOERR) {
1222 PRINT_ERR("Async event destroy failed in %s, %d\n", __FUNCTION__, __LINE__);
1223 return ret;
1224 }
1225 }
1226
1227 return ret;
1228}
INT32 BlockCacheDrvCreate(VOID *handle, UINT8 *memStart, UINT32 memSize, UINT32 blockSize, OsBcache *bc)
初始化块设备
Definition: bcache.c:800
static UINT32 GetValLog2(UINT32 val)
Definition: bcache.c:190
static VOID BcacheSetFlag(const OsBcache *bc, OsBcacheBlock *block, UINT32 pos, UINT32 size)
Definition: bcache.c:324
static VOID MergeSyncBlocks(OsBcache *bc, OsBcacheBlock *start)
Definition: bcache.c:513
VOID ResumeAsyncPreread(OsBcache *arg1, const OsBcacheBlock *arg2)
Definition: bcache.c:1169
UINT32 g_syncInterval
Definition: bcache.c:83
OsBcache * BlockCacheInit(struct Vnode *devNode, UINT32 sectorSize, UINT32 sectorPerBlock, UINT32 blockNum, UINT64 blockCount)
Definition: bcache.c:1065
static void DelBlock(OsBcache *bc, OsBcacheBlock *block)
Definition: bcache.c:404
volatile UINT32 g_hitTimes[CONFIG_FS_FAT_BLOCK_NUMS]
Definition: bcache.c:58
INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector)
写块设备缓存
Definition: bcache.c:892
static UINT64 GetMinWriteNum(OsBcache *bc)
Definition: bcache.c:539
VOID LOS_SetSyncThreadInterval(UINT32 interval)
设置同步间隔,5秒
Definition: bcache.c:92
INT32 BcacheClearCache(OsBcache *bc)
Definition: bcache.c:706
static INT32 BcacheSyncBlock(OsBcache *bc, OsBcacheBlock *block)
Definition: bcache.c:348
UINT32 g_memSize
Definition: bcache.c:53
volatile UINT8 * g_memStart
Definition: bcache.c:56
VOID BlockCacheDeinit(OsBcache *bcache)
Definition: bcache.c:1122
INT32 OsSdSync(INT32 id)
Definition: bcache.c:956
static VOID ListMoveBlockToHead(OsBcache *bc, OsBcacheBlock *block)
删除红黑树块
Definition: bcache.c:178
INT32 LOS_SetSyncThreadPrio(UINT32 prio, const CHAR *name)
设置同步任务优先级,10
Definition: bcache.c:97
UINT32 g_syncThreadPrio
Definition: bcache.c:81
static OsBcacheBlock * GetBaseBlock(OsBcache *bc)
Definition: bcache.c:436
INT32 BlockCacheSync(OsBcache *bc)
块缓存同步
Definition: bcache.c:951
static VOID BlockInit(OsBcache *bc, OsBcacheBlock *block, UINT64 num)
Definition: bcache.c:623
volatile UINT32 g_dataSize
Definition: bcache.c:55
static INT32 BcacheInitCache(OsBcache *bc, UINT8 *memStart, UINT32 memSize, UINT32 blockSize)
块设备缓存初始化
Definition: bcache.c:716
INT32 BcacheGetDirtyRatio(INT32 id)
Definition: bcache.c:989
static OsBcacheBlock * AllocNewBlock(OsBcache *bc, BOOL read, UINT64 num)
Definition: bcache.c:554
VOID BcacheSyncThreadInit(OsBcache *bc, INT32 id)
块缓存同步任务初始化,开了个内核任务.
Definition: bcache.c:1037
static VOID BcacheAsyncPrereadThread(VOID *arg)
Definition: bcache.c:1134
INT32 LOS_GetDirtyRatioByName(const CHAR *name)
Definition: bcache.c:1017
static VOID WriteMergedBlocks(OsBcache *bc, OsBcacheBlock *begin, int blocks)
Definition: bcache.c:487
INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector, BOOL useRead)
读块设备缓存
Definition: bcache.c:824
static OsBcacheBlock * GetSlowBlock(OsBcache *bc, BOOL read)
Definition: bcache.c:453
static BOOL BlockAllDirty(const OsBcache *bc, OsBcacheBlock *block)
Definition: bcache.c:414
UINT32 g_dirtyRatio
Definition: bcache.c:82
static INT32 DrvBwrite(struct Vnode *priv, const UINT8 *buf, UINT32 len, UINT64 pos)
写块设备数据
Definition: bcache.c:789
static void NumListAdd(OsBcache *bc, OsBcacheBlock *block)
Definition: bcache.c:381
volatile UINT32 g_blockNum
Definition: bcache.c:54
static VOID FreeBlock(OsBcache *bc, OsBcacheBlock *block)
释放块
Definition: bcache.c:184
volatile UINT32 g_switchTimes[CONFIG_FS_FAT_BLOCK_NUMS]
Definition: bcache.c:57
static INT32 BcacheSync(OsBcache *bc)
Definition: bcache.c:599
VOID BcacheAnalyse(UINT32 level)
Definition: bcache.c:61
static INT32 BlockRead(OsBcache *bc, OsBcacheBlock *block, UINT8 *buf)
Definition: bcache.c:246
static VOID RbAddBlock(OsBcache *bc, OsBcacheBlock *block)
添加缓存块
Definition: bcache.c:152
UINT32 BcacheAsyncPrereadInit(OsBcache *bc)
Definition: bcache.c:1184
VOID BcacheSyncThreadDeinit(const OsBcache *bc)
Definition: bcache.c:1055
static INT32 BcacheGetBlock(OsBcache *bc, UINT64 num, BOOL readData, OsBcacheBlock **dblock)
Definition: bcache.c:635
UINT32 BcacheAsyncPrereadDeinit(OsBcache *bc)
Definition: bcache.c:1210
static INT32 BcacheGetFlag(OsBcache *bc, OsBcacheBlock *block)
Definition: bcache.c:266
VOID LOS_SetDirtyRatioThreshold(UINT32 dirtyRatio)
Definition: bcache.c:85
static void AddBlock(OsBcache *bc, OsBcacheBlock *block)
Definition: bcache.c:395
static INT32 FindFlagPos(const UINT32 *arr, UINT32 len, UINT32 *p1, UINT32 *p2)
Definition: bcache.c:207
static VOID RbDelBlock(OsBcache *bc, OsBcacheBlock *block)
删除红黑树块
Definition: bcache.c:173
static OsBcacheBlock * RbFindBlock(const OsBcache *bc, UINT64 num)
红黑树找块
Definition: bcache.c:138
static VOID BcacheSyncThread(UINT32 id)
Definition: bcache.c:1024
INT32 LOS_BcacheSyncByName(const CHAR *name)
Definition: bcache.c:983
static INT32 DrvBread(struct Vnode *priv, UINT8 *buf, UINT32 len, UINT64 pos)
读块设备数据
Definition: bcache.c:777
@ STAT_UNUSED
Definition: disk.h:171
@ STAT_INUSED
Definition: disk.h:172
UINT32 GetFatBlockNums(VOID)
Definition: disk.c:110
los_disk * get_disk(INT32 id)
Find disk driver.
Definition: disk.c:263
INT32 los_get_diskid_byname(const CHAR *diskName)
get the INUSED disk id.
Definition: disk.c:191
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
销毁指定的事件控制块
Definition: los_event.c:334
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
读取指定事件类型,超时时间为相对时间:单位为Tick
Definition: los_event.c:313
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
写指定的事件类型
Definition: los_event.c:318
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
初始化一个事件控制块
Definition: los_event.c:95
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a new node to a doubly linked list.
Definition: los_list.h:217
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
Delete a task.
Definition: los_task.c:968
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
设置指定任务的优先级
Definition: los_task.c:1071
struct tagTskInitParam TSK_INIT_PARAM_S
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
Definition: los_task.c:718
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
signed int INT32
Definition: los_typedef.h:60
long unsigned int UINT64
Definition: los_typedef.h:66
unsigned char UINT8
Definition: los_typedef.h:55
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
size_t BOOL
Definition: los_typedef.h:88
void * zalloc(size_t size)
Definition: malloc.c:91
void * memalign(size_t boundary, size_t size)
Definition: malloc.c:112
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
int pthread_mutex_lock(pthread_mutex_t *mutex)
互斥锁加锁操作
int pthread_mutex_destroy(pthread_mutex_t *mutex)
销毁互斥锁
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr)
初始化互斥锁。 如果 mutexAttr 为 NULL,则使用默认属性。
int pthread_mutex_unlock(pthread_mutex_t *mutex)
解锁互斥锁
struct pthread_mutex disk_mutex
Definition: disk.h:191
OsBcache * bcache
Definition: disk.h:183
UINT32 disk_status
Definition: disk.h:178
struct LOS_DL_LIST * pstPrev
Definition: los_list.h:83
struct LOS_DL_LIST * pstNext
Definition: los_list.h:84
BOOL used
Definition: bcache.h:74
LOS_DL_LIST numNode
Definition: bcache.h:65
BOOL readBuff
Definition: bcache.h:73
UINT32 flag[BCACHE_BLOCK_FLAGS]
Definition: bcache.h:68
BOOL readFlag
Definition: bcache.h:72
BOOL allDirty
Definition: bcache.h:75
LOS_DL_LIST listNode
Definition: bcache.h:64
UINT8 * data
Definition: bcache.h:70
UINT32 pgHit
Definition: bcache.h:69
struct rb_node rbNode
Definition: bcache.h:66
UINT64 num
Definition: bcache.h:67
BOOL modified
Definition: bcache.h:71
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
void * data
Definition: vnode.h:176
UINT32 modifiedBlock
Definition: bcache.h:113
LOS_DL_LIST freeListHead
Definition: bcache.h:106
OsBcacheBlock * wEnd
Definition: bcache.h:118
LOS_DL_LIST listHead
Definition: bcache.h:95
UINT32 nBlock
Definition: bcache.h:120
pthread_mutex_t bcacheMutex
Definition: bcache.h:111
BcachePrereadFun prereadFun
Definition: bcache.h:109
UINT8 * memStart
Definition: bcache.h:103
BcacheWriteFun bwriteFun
Definition: bcache.h:108
UINT32 sectorPerBlock
Definition: bcache.h:102
UINT32 prereadTaskId
Definition: bcache.h:104
VOID * priv
Definition: bcache.h:94
struct rb_root rbRoot
Definition: bcache.h:97
UINT8 * rwBuffer
Definition: bcache.h:110
UINT64 sumNum
Definition: bcache.h:119
LOS_DL_LIST numHead
Definition: bcache.h:96
UINT64 blockCount
Definition: bcache.h:100
UINT32 syncTaskId
Definition: bcache.h:115
UINT32 blockSizeLog2
Definition: bcache.h:99
BcacheReadFun breadFun
Definition: bcache.h:107
UINT64 curBlockNum
Definition: bcache.h:105
UINT32 sectorSize
Definition: bcache.h:101
UINT32 blockSize
Definition: bcache.h:98
EVENT_CB_S bcacheEvent
Definition: bcache.h:112
OsBcacheBlock * wStart
Definition: bcache.h:117
UINT16 usTaskPrio
Definition: los_task.h:505
UINTPTR auwArgs[4]
Definition: los_task.h:507
UINT32 uwStackSize
Definition: los_task.h:508
CHAR * pcName
Definition: los_task.h:509
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UINT32 uwResved
Definition: los_task.h:513
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
INT32 LOS_CopyToKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
将用户空间的数据拷贝到内核空间
Definition: user_copy.c:101
INT32 LOS_CopyFromKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
将内核数据拷贝到用户空间
Definition: user_copy.c:88