ref: ee889f7d84ffbde7acefd23d4b7b7c7a2268242d
parent: fe2cde8c8128fff855522a84a8f2864e6ed69686
author: ngkaho1234 <ngkaho1234@gmail.com>
date: Thu Jan 21 18:53:41 EST 2016
ext4_bcache: do not allow cache shaking when callback is invoked.
--- a/lwext4/ext4_bcache.h
+++ b/lwext4/ext4_bcache.h
@@ -135,6 +135,9 @@
/**@brief The blockdev binded to this block cache*/
struct ext4_blockdev *bdev;
+ /**@brief The cache should not be shaked */
+ bool dont_shake;
+
/**@brief A tree holding all bufs*/
RB_HEAD(ext4_buf_lba, ext4_buf) lba_root;
--- a/lwext4/ext4_blockdev.c
+++ b/lwext4/ext4_blockdev.c
@@ -144,10 +144,12 @@
if (ext4_bcache_test_flag(buf, BC_DIRTY) &&
ext4_bcache_test_flag(buf, BC_UPTODATE)) {
r = ext4_blocks_set_direct(bdev, buf->data, buf->lba, 1);
-
if (r) {
- if (buf->end_write)
+ if (buf->end_write) {
+ bc->dont_shake = true;
buf->end_write(bc, buf, r, buf->end_write_arg);
+ bc->dont_shake = false;
+ }
return r;
}
@@ -154,9 +156,11 @@
ext4_bcache_remove_dirty_node(bc, buf);
ext4_bcache_clear_flag(buf, BC_DIRTY);
- if (buf->end_write)
+ if (buf->end_write) {
+ bc->dont_shake = true;
buf->end_write(bc, buf, r, buf->end_write_arg);
-
+ bc->dont_shake = false;
+ }
}
return EOK;
}
@@ -176,7 +180,11 @@
int ext4_block_cache_shake(struct ext4_blockdev *bdev)
{
+ int r = EOK;
struct ext4_buf *buf;
+ if (bdev->bc->dont_shake)
+ return EOK;
+
while (!RB_EMPTY(&bdev->bc->lru_root) &&
ext4_bcache_is_full(bdev->bc)) {
@@ -183,15 +191,15 @@
buf = ext4_buf_lowest_lru(bdev->bc);
ext4_assert(buf);
if (ext4_bcache_test_flag(buf, BC_DIRTY)) {
- int r = ext4_block_flush_buf(bdev, buf);
+ r = ext4_block_flush_buf(bdev, buf);
if (r != EOK)
- return r;
+ break;
}
ext4_bcache_drop_buf(bdev->bc, buf);
}
- return EOK;
+ return r;
}
int ext4_block_get_noread(struct ext4_blockdev *bdev, struct ext4_block *b,