diff options
| author | ngkaho1234 <ngkaho1234@gmail.com> | 2015-11-07 17:35:15 +0000 |
|---|---|---|
| committer | gkostka <kostka.grzegorz@gmail.com> | 2015-11-08 14:49:48 +0100 |
| commit | 23644a4048b147390df8bef84b1e9cf4dbea2b8e (patch) | |
| tree | 66e2d02fb42fdd58150ed2eca5089d023d185806 | |
| parent | 754d2885b461161dee8d49eb0e0a50269ba634a0 (diff) | |
Reworks on buffer management
1. ext4_bcache: use flags arrayinstead of dirty boolean array.
2. ext4_blockdev: ext4_block_get_noread added.
| -rw-r--r-- | lwext4/ext4_bcache.c | 4 | ||||
| -rw-r--r-- | lwext4/ext4_bcache.h | 23 | ||||
| -rw-r--r-- | lwext4/ext4_blockdev.c | 41 | ||||
| -rw-r--r-- | lwext4/ext4_blockdev.h | 8 |
4 files changed, 62 insertions, 14 deletions
diff --git a/lwext4/ext4_bcache.c b/lwext4/ext4_bcache.c index daec9bc..165cd8a 100644 --- a/lwext4/ext4_bcache.c +++ b/lwext4/ext4_bcache.c @@ -115,6 +115,7 @@ int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b, /*Set valid cache data and id*/ b->data = bc->data + i * bc->itemsize; b->cache_id = i; + b->uptodate = ext4_bcache_test_flag(bc, i, BC_UPTODATE); return EOK; } @@ -154,6 +155,8 @@ int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b, /*Set valid cache data and id*/ b->data = bc->data + cache_id * bc->itemsize; b->cache_id = cache_id; + ext4_bcache_clear_flag(bc, cache_id, BC_UPTODATE); + b->uptodate = false; /*Statistics*/ bc->ref_blocks++; @@ -199,6 +202,7 @@ int ext4_bcache_free(struct ext4_bcache *bc, struct ext4_block *b, b->lb_id = 0; b->data = 0; b->cache_id = 0; + b->uptodate = false; return EOK; } diff --git a/lwext4/ext4_bcache.h b/lwext4/ext4_bcache.h index ce1ffc7..bf9505b 100644 --- a/lwext4/ext4_bcache.h +++ b/lwext4/ext4_bcache.h @@ -42,10 +42,13 @@ #include <stdint.h> #include <stdbool.h> -#define EXT4_BLOCK_ZERO() {.dirty = 0, .lb_id = 0, .cache_id = 0, .data = 0} +#define EXT4_BLOCK_ZERO() {.uptodate = 0, .dirty = 0, .lb_id = 0, .cache_id = 0, .data = 0} /**@brief Single block descriptor*/ struct ext4_block { + /**@brief Uptodate flag*/ + bool uptodate; + /**@brief Dirty flag*/ bool dirty; @@ -83,8 +86,8 @@ struct ext4_bcache { /**@brief Logical block table*/ uint64_t lba[CONFIG_BLOCK_DEV_CACHE_SIZE]; - /**@brief Dirty mark*/ - bool dirty[CONFIG_BLOCK_DEV_CACHE_SIZE]; + /**@brief Flags*/ + int flags[CONFIG_BLOCK_DEV_CACHE_SIZE]; /**@brief Cache data buffers*/ uint8_t *data; @@ -96,6 +99,20 @@ struct ext4_bcache { uint32_t max_ref_blocks; }; +enum bcache_state_bits { + BC_UPTODATE, + BC_DIRTY +}; + +#define ext4_bcache_set_flag(bc, id, b) \ + (bc)->flags[id] |= 1 << (b) + +#define ext4_bcache_clear_flag(bc, id, b) \ + (bc)->flags[id] &= ~(1 << (b)) + +#define ext4_bcache_test_flag(bc, id, b) \ + (((bc)->flags[id] & (1 << (b))) >> (b)) + /**@brief Static initializer of block cache structure.*/ #define EXT4_BCACHE_STATIC_INSTANCE(__name, __cnt, __itemsize) \ static uint8_t __name##_data[(__cnt) * (__itemsize)]; \ diff --git a/lwext4/ext4_blockdev.c b/lwext4/ext4_blockdev.c index 57e8f89..f266618 100644 --- a/lwext4/ext4_blockdev.c +++ b/lwext4/ext4_blockdev.c @@ -85,11 +85,9 @@ int ext4_block_fini(struct ext4_blockdev *bdev) return bdev->close(bdev); } -int ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b, - uint64_t lba) +int ext4_block_get_noread(struct ext4_blockdev *bdev, struct ext4_block *b, + uint64_t lba) { - uint64_t pba; - uint32_t pb_cnt; uint32_t i; bool is_new; int r; @@ -149,14 +147,26 @@ int ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b, if (r != EOK) return r; - if (!is_new) { + if (!b->data) + return ENOMEM; + + return EOK; +} + +int ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b, + uint64_t lba) +{ + uint64_t pba; + uint32_t pb_cnt; + int r = ext4_block_get_noread(bdev, b, lba); + if (r != EOK) + return r; + + if (b->uptodate) { /*Block is in cache. Read from physical device is not required*/ return EOK; } - if (!b->data) - return ENOMEM; - pba = (lba * bdev->lg_bsize) / bdev->ph_bsize; pb_cnt = bdev->lg_bsize / bdev->ph_bsize; @@ -168,6 +178,8 @@ int ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b, return r; } + ext4_bcache_set_flag(bdev->bc, b->cache_id, BC_UPTODATE); + b->uptodate = true; bdev->bread_ctr++; return EOK; } @@ -183,11 +195,17 @@ int ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b) if (!(bdev->flags & EXT4_BDEV_INITIALIZED)) return EIO; + /*Buffer is not marked dirty and is stale*/ + if (!b->uptodate && !b->dirty) + ext4_bcache_clear_flag(bdev->bc, b->cache_id, BC_UPTODATE); + /*No need to write.*/ - if (!b->dirty && !bdev->bc->dirty[b->cache_id]) { + if (!b->dirty && + !ext4_bcache_test_flag(bdev->bc, b->cache_id, BC_DIRTY)) { ext4_bcache_free(bdev->bc, b, 0); return EOK; } + ext4_bcache_set_flag(bdev->bc, b->cache_id, BC_UPTODATE); /*Free cache delay mode*/ if (bdev->cache_write_back) { @@ -197,7 +215,7 @@ int ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b) } if (bdev->bc->refctr[b->cache_id] > 1) { - bdev->bc->dirty[b->cache_id] = true; + ext4_bcache_set_flag(bdev->bc, b->cache_id, BC_DIRTY); return ext4_bcache_free(bdev->bc, b, 0); } @@ -205,9 +223,10 @@ int ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b) pb_cnt = bdev->lg_bsize / bdev->ph_bsize; r = bdev->bwrite(bdev, b->data, pba, pb_cnt); - bdev->bc->dirty[b->cache_id] = false; + ext4_bcache_clear_flag(bdev->bc, b->cache_id, BC_DIRTY); if (r != EOK) { b->dirty = false; + ext4_bcache_clear_flag(bdev->bc, b->cache_id, BC_UPTODATE); ext4_bcache_free(bdev->bc, b, 0); return r; } diff --git a/lwext4/ext4_blockdev.h b/lwext4/ext4_blockdev.h index a525219..39514a4 100644 --- a/lwext4/ext4_blockdev.h +++ b/lwext4/ext4_blockdev.h @@ -141,6 +141,14 @@ int ext4_block_fini(struct ext4_blockdev *bdev); * @return standard error code*/ void ext4_block_set_lb_size(struct ext4_blockdev *bdev, uint64_t lb_bsize); +/**@brief Block get function (through cache, don't read). + * @param bdev block device descriptor + * @param b block descriptor + * @param lba logical block address + * @return standard error code*/ +int ext4_block_get_noread(struct ext4_blockdev *bdev, struct ext4_block *b, + uint64_t lba); + /**@brief Block get function (through cache). * @param bdev block device descriptor * @param b block descriptor |
