shithub: lwext4

Download patch

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,