From 024440663d17c66dbf813d0fa92a475da01b9093 Mon Sep 17 00:00:00 2001 From: wanggang26 Date: Sat, 29 Jul 2023 10:37:17 +0800 Subject: [PATCH] bch: fix sector buffer invalidation issue --- drivers/bch/bch.h | 2 +- drivers/bch/bchdev_driver.c | 4 ++-- drivers/bch/bchlib_cache.c | 13 ++++++++----- drivers/bch/bchlib_teardown.c | 5 ++--- drivers/bch/bchlib_write.c | 3 ++- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/bch/bch.h b/drivers/bch/bch.h index e60184316a..c3e802d9ec 100644 --- a/drivers/bch/bch.h +++ b/drivers/bch/bch.h @@ -81,7 +81,7 @@ EXTERN const struct file_operations g_bch_fops; * Public Function Prototypes ****************************************************************************/ -EXTERN int bchlib_flushsector(FAR struct bchlib_s *bch); +EXTERN int bchlib_flushsector(FAR struct bchlib_s *bch, bool discard); EXTERN int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector); #undef EXTERN diff --git a/drivers/bch/bchdev_driver.c b/drivers/bch/bchdev_driver.c index 98e730b84c..0439130abf 100644 --- a/drivers/bch/bchdev_driver.c +++ b/drivers/bch/bchdev_driver.c @@ -168,7 +168,7 @@ static int bch_close(FAR struct file *filep) /* Flush any dirty pages remaining in the cache */ - bchlib_flushsector(bch); + bchlib_flushsector(bch, false); /* Decrement the reference count (I don't use bchlib_decref() because I * want the entire close operation to be atomic wrt other driver @@ -424,7 +424,7 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { /* Flush any dirty pages remaining in the cache */ - ret = bchlib_flushsector(bch); + ret = bchlib_flushsector(bch, false); } break; diff --git a/drivers/bch/bchlib_cache.c b/drivers/bch/bchlib_cache.c index 8001137b1f..cce8224229 100644 --- a/drivers/bch/bchlib_cache.c +++ b/drivers/bch/bchlib_cache.c @@ -103,7 +103,7 @@ static int bch_cypher(FAR struct bchlib_s *bch, int encrypt) * ****************************************************************************/ -int bchlib_flushsector(FAR struct bchlib_s *bch) +int bchlib_flushsector(FAR struct bchlib_s *bch, bool discard) { FAR struct inode *inode; ssize_t ret = OK; @@ -144,6 +144,11 @@ int bchlib_flushsector(FAR struct bchlib_s *bch) bch->dirty = false; } + if (discard) + { + bch->sector = (size_t)-1; + } + return (int)ret; } @@ -151,7 +156,7 @@ int bchlib_flushsector(FAR struct bchlib_s *bch) * Name: bchlib_readsector * * Description: - * Flush the current contents of the sector buffer (if dirty) + * Read the current sector contents into buffer * * Assumptions: * Caller must assume mutual exclusion @@ -167,15 +172,13 @@ int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector) { inode = bch->inode; - ret = bchlib_flushsector(bch); + ret = bchlib_flushsector(bch, true); if (ret < 0) { ferr("Flush failed: %zd\n", ret); return (int)ret; } - bch->sector = (size_t)-1; - ret = inode->u.i_bops->read(inode, bch->buffer, sector, 1); if (ret < 0) { diff --git a/drivers/bch/bchlib_teardown.c b/drivers/bch/bchlib_teardown.c index f85b96beef..89f9f4a20e 100644 --- a/drivers/bch/bchlib_teardown.c +++ b/drivers/bch/bchlib_teardown.c @@ -43,8 +43,7 @@ * Name: bchlib_teardown * * Description: - * Setup so that the block driver referenced by 'blkdev' can be accessed - * similar to a character device. + * Close the block driver and free resources * ****************************************************************************/ @@ -63,7 +62,7 @@ int bchlib_teardown(FAR void *handle) /* Flush any pending data to the block driver */ - bchlib_flushsector(bch); + bchlib_flushsector(bch, false); /* Close the block driver */ diff --git a/drivers/bch/bchlib_write.c b/drivers/bch/bchlib_write.c index dd74adcfa3..c63715c67c 100644 --- a/drivers/bch/bchlib_write.c +++ b/drivers/bch/bchlib_write.c @@ -133,7 +133,8 @@ ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, /* Flush the dirty sector to keep the sector sequence */ - ret = bchlib_flushsector(bch); + ret = bchlib_flushsector(bch, sector <= bch->sector && + bch->sector < (sector + nsectors)); if (ret < 0) { ferr("ERROR: Flush failed: %d\n", ret);