\r
int ext4_bcache_init_dynamic(struct ext4_bcache *bc, uint32_t cnt, uint32_t itemsize)\r
{\r
- ext4_assert(bc && cnt && itemsize);\r
+ ext4_assert(bc && cnt && itemsize);\r
\r
- bc->lru_ctr= 0;\r
+ bc->lru_ctr= 0;\r
\r
- bc->refctr = 0;\r
- bc->lru_id = 0;\r
- bc->free_delay = 0;\r
- bc->lba = 0;\r
- bc->data = 0;\r
+ bc->refctr = 0;\r
+ bc->lru_id = 0;\r
+ bc->free_delay = 0;\r
+ bc->lba = 0;\r
+ bc->data = 0;\r
\r
- bc->refctr = malloc(cnt * sizeof(uint32_t));\r
- if(!bc->refctr)\r
- goto error;\r
+ bc->refctr = malloc(cnt * sizeof(uint32_t));\r
+ if(!bc->refctr)\r
+ goto error;\r
\r
- bc->lru_id = malloc(cnt * sizeof(uint32_t));\r
- if(!bc->lru_id)\r
- goto error;\r
+ bc->lru_id = malloc(cnt * sizeof(uint32_t));\r
+ if(!bc->lru_id)\r
+ goto error;\r
\r
- bc->free_delay = malloc(cnt * sizeof(uint8_t));\r
- if(!bc->free_delay)\r
- goto error;\r
+ bc->free_delay = malloc(cnt * sizeof(uint8_t));\r
+ if(!bc->free_delay)\r
+ goto error;\r
\r
- bc->lba = malloc(cnt * sizeof(uint64_t));\r
- if(!bc->lba)\r
- goto error;\r
+ bc->lba = malloc(cnt * sizeof(uint64_t));\r
+ if(!bc->lba)\r
+ goto error;\r
\r
- bc->data = malloc(cnt * itemsize);\r
- if(!bc->data)\r
- goto error;\r
+ bc->data = malloc(cnt * itemsize);\r
+ if(!bc->data)\r
+ goto error;\r
\r
- memset(bc->refctr, 0, cnt * sizeof(uint32_t));\r
- memset(bc->lru_id, 0, cnt * sizeof(uint32_t));\r
- memset(bc->free_delay, 0, cnt * sizeof(uint8_t));\r
- memset(bc->lba, 0, cnt * sizeof(uint64_t));\r
+ memset(bc->refctr, 0, cnt * sizeof(uint32_t));\r
+ memset(bc->lru_id, 0, cnt * sizeof(uint32_t));\r
+ memset(bc->free_delay, 0, cnt * sizeof(uint8_t));\r
+ memset(bc->lba, 0, cnt * sizeof(uint64_t));\r
\r
- bc->cnt = cnt;\r
- bc->itemsize = itemsize;\r
- bc->ref_blocks = 0;\r
- bc->max_ref_blocks = 0;\r
+ bc->cnt = cnt;\r
+ bc->itemsize = itemsize;\r
+ bc->ref_blocks = 0;\r
+ bc->max_ref_blocks = 0;\r
\r
- return EOK;\r
+ return EOK;\r
\r
- error:\r
+ error:\r
\r
- if(bc->refctr)\r
- free(bc->refctr);\r
+ if(bc->refctr)\r
+ free(bc->refctr);\r
\r
- if(bc->lru_id)\r
- free(bc->lru_id);\r
+ if(bc->lru_id)\r
+ free(bc->lru_id);\r
\r
- if(bc->free_delay)\r
- free(bc->free_delay);\r
+ if(bc->free_delay)\r
+ free(bc->free_delay);\r
\r
- if(bc->lba)\r
- free(bc->lba);\r
+ if(bc->lba)\r
+ free(bc->lba);\r
\r
- if(bc->data)\r
- free(bc->data);\r
+ if(bc->data)\r
+ free(bc->data);\r
\r
- return ENOMEM;\r
+ return ENOMEM;\r
}\r
\r
int ext4_bcache_fini_dynamic(struct ext4_bcache *bc)\r
{\r
- if(bc->refctr)\r
- free(bc->refctr);\r
+ if(bc->refctr)\r
+ free(bc->refctr);\r
\r
- if(bc->lru_id)\r
- free(bc->lru_id);\r
+ if(bc->lru_id)\r
+ free(bc->lru_id);\r
\r
- if(bc->free_delay)\r
- free(bc->free_delay);\r
+ if(bc->free_delay)\r
+ free(bc->free_delay);\r
\r
- if(bc->lba)\r
- free(bc->lba);\r
+ if(bc->lba)\r
+ free(bc->lba);\r
\r
- if(bc->data)\r
- free(bc->data);\r
+ if(bc->data)\r
+ free(bc->data);\r
\r
- bc->lru_ctr= 0;\r
+ bc->lru_ctr= 0;\r
\r
- bc->refctr = 0;\r
- bc->lru_id = 0;\r
- bc->free_delay = 0;\r
- bc->lba = 0;\r
- bc->data = 0;\r
+ bc->refctr = 0;\r
+ bc->lru_id = 0;\r
+ bc->free_delay = 0;\r
+ bc->lba = 0;\r
+ bc->data = 0;\r
\r
- return EOK;\r
+ return EOK;\r
}\r
\r
\r
int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b, bool *is_new)\r
{\r
- uint32_t i;\r
- ext4_assert(bc && b && is_new);\r
+ uint32_t i;\r
+ ext4_assert(bc && b && is_new);\r
\r
- /*Check if valid.*/\r
- ext4_assert(b->lb_id);\r
- if(!b->lb_id){\r
- ext4_assert(b->lb_id);\r
- }\r
+ /*Check if valid.*/\r
+ ext4_assert(b->lb_id);\r
+ if(!b->lb_id){\r
+ ext4_assert(b->lb_id);\r
+ }\r
\r
- uint32_t cache_id = bc->cnt;\r
- uint32_t alloc_id;\r
+ uint32_t cache_id = bc->cnt;\r
+ uint32_t alloc_id;\r
\r
- *is_new = false;\r
+ *is_new = false;\r
\r
- /*Find in free blocks (Last Recently Used).*/\r
- for (i = 0; i < bc->cnt; ++i) {\r
+ /*Find in free blocks (Last Recently Used).*/\r
+ for (i = 0; i < bc->cnt; ++i) {\r
\r
- /*Check if block is already in cache*/\r
- if(b->lb_id == bc->lba[i]){\r
+ /*Check if block is already in cache*/\r
+ if(b->lb_id == bc->lba[i]){\r
\r
- if(!bc->refctr[i] && !bc->free_delay[i])\r
- bc->ref_blocks++;\r
+ if(!bc->refctr[i] && !bc->free_delay[i])\r
+ bc->ref_blocks++;\r
\r
- /*Update reference counter*/\r
- bc->refctr[i]++;\r
+ /*Update reference counter*/\r
+ bc->refctr[i]++;\r
\r
- /*Update usage marker*/\r
- bc->lru_id[i] = ++bc->lru_ctr;\r
+ /*Update usage marker*/\r
+ bc->lru_id[i] = ++bc->lru_ctr;\r
\r
- /*Set valid cache data*/\r
- b->data = bc->data + i * bc->itemsize;\r
+ /*Set valid cache data*/\r
+ b->data = bc->data + i * bc->itemsize;\r
\r
- return EOK;\r
- }\r
+ return EOK;\r
+ }\r
\r
- /*Best fit calculations.*/\r
- if(bc->refctr[i])\r
- continue;\r
+ /*Best fit calculations.*/\r
+ if(bc->refctr[i])\r
+ continue;\r
\r
- if(bc->free_delay[i])\r
- continue;\r
+ if(bc->free_delay[i])\r
+ continue;\r
\r
- /*Block is unreferenced, but it may exist block with\r
- * lower usage marker*/\r
+ /*Block is unreferenced, but it may exist block with\r
+ * lower usage marker*/\r
\r
- /*First find.*/\r
- if(cache_id == bc->cnt){\r
- cache_id = i;\r
- alloc_id = bc->lru_id[i];\r
- continue;\r
- }\r
+ /*First find.*/\r
+ if(cache_id == bc->cnt){\r
+ cache_id = i;\r
+ alloc_id = bc->lru_id[i];\r
+ continue;\r
+ }\r
\r
- /*Next find*/\r
- if(alloc_id <= bc->lru_id[i])\r
- continue;\r
+ /*Next find*/\r
+ if(alloc_id <= bc->lru_id[i])\r
+ continue;\r
\r
- /*This block has lower alloc id marker*/\r
- cache_id = i;\r
- alloc_id = bc->lru_id[i];\r
- }\r
+ /*This block has lower alloc id marker*/\r
+ cache_id = i;\r
+ alloc_id = bc->lru_id[i];\r
+ }\r
\r
\r
- if(cache_id != bc->cnt){\r
- /*There was unreferenced block*/\r
- bc->lba[cache_id] = b->lb_id;\r
- bc->refctr[cache_id] = 1;\r
- bc->lru_id[cache_id] = ++bc->lru_ctr;\r
+ if(cache_id != bc->cnt){\r
+ /*There was unreferenced block*/\r
+ bc->lba[cache_id] = b->lb_id;\r
+ bc->refctr[cache_id] = 1;\r
+ bc->lru_id[cache_id] = ++bc->lru_ctr;\r
\r
- /*Set valid cache data*/\r
- b->data = bc->data + cache_id * bc->itemsize;\r
+ /*Set valid cache data*/\r
+ b->data = bc->data + cache_id * bc->itemsize;\r
\r
- /*Statistics*/\r
- bc->ref_blocks++;\r
- if(bc->ref_blocks > bc->max_ref_blocks)\r
- bc->max_ref_blocks = bc->ref_blocks;\r
+ /*Statistics*/\r
+ bc->ref_blocks++;\r
+ if(bc->ref_blocks > bc->max_ref_blocks)\r
+ bc->max_ref_blocks = bc->ref_blocks;\r
\r
\r
- /*Block needs to be read.*/\r
- *is_new = true;\r
+ /*Block needs to be read.*/\r
+ *is_new = true;\r
\r
- return EOK;\r
- }\r
+ return EOK;\r
+ }\r
\r
- ext4_dprintf(EXT4_DEBUG_BCACHE, "ext4_bcache_alloc: FAIL, unable to alloc block cache!\n");\r
- return ENOMEM;\r
+ ext4_dprintf(EXT4_DEBUG_BCACHE, "ext4_bcache_alloc: FAIL, unable to alloc block cache!\n");\r
+ return ENOMEM;\r
}\r
\r
int ext4_bcache_free (struct ext4_bcache *bc, struct ext4_block *b, uint8_t free_delay)\r
{\r
- uint32_t i;\r
+ uint32_t i;\r
\r
- ext4_assert(bc && b);\r
+ ext4_assert(bc && b);\r
\r
- /*Check if valid.*/\r
- ext4_assert(b->lb_id);\r
+ /*Check if valid.*/\r
+ ext4_assert(b->lb_id);\r
\r
- /*Block should be in cache.*/\r
- for (i = 0; i < bc->cnt; ++i) {\r
+ /*Block should be in cache.*/\r
+ for (i = 0; i < bc->cnt; ++i) {\r
\r
- if(bc->lba[i] != b->lb_id)\r
- continue;\r
+ if(bc->lba[i] != b->lb_id)\r
+ continue;\r
\r
- /*Check if someone don't try free unreferenced block cache.*/\r
- ext4_assert(bc->refctr[i]);\r
+ /*Check if someone don't try free unreferenced block cache.*/\r
+ ext4_assert(bc->refctr[i]);\r
\r
- /*Just decrease reference counter*/\r
- if(bc->refctr[i])\r
- bc->refctr[i]--;\r
+ /*Just decrease reference counter*/\r
+ if(bc->refctr[i])\r
+ bc->refctr[i]--;\r
\r
\r
- if(free_delay)\r
- bc->free_delay[i] = free_delay;\r
+ if(free_delay)\r
+ bc->free_delay[i] = free_delay;\r
\r
- /*Update statistics*/\r
- if(!bc->refctr[i] && !bc->free_delay[i])\r
- bc->ref_blocks--;\r
+ /*Update statistics*/\r
+ if(!bc->refctr[i] && !bc->free_delay[i])\r
+ bc->ref_blocks--;\r
\r
- b->lb_id = 0;\r
- b->data = 0;\r
+ b->lb_id = 0;\r
+ b->data = 0;\r
\r
- return EOK;\r
- }\r
+ return EOK;\r
+ }\r
\r
- ext4_dprintf(EXT4_DEBUG_BCACHE, "ext4_bcache_free: FAIL, block should be in cache memory !\n");\r
- return EFAULT;\r
+ ext4_dprintf(EXT4_DEBUG_BCACHE, "ext4_bcache_free: FAIL, block should be in cache memory !\n");\r
+ return EFAULT;\r
}\r
\r
bool ext4_bcache_is_full(struct ext4_bcache *bc)\r
{\r
- return (bc->cnt == bc->ref_blocks);\r
+ return (bc->cnt == bc->ref_blocks);\r
}\r
\r
/**\r