This allows flushers to skip actual writes directly.
Signed-off-by: Gao Xiang <[email protected]>
---
lib/cache.c | 13 +++++++------
lib/inode.c | 32 +++++++++++++++++++-------------
lib/liberofs_cache.h | 2 +-
3 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/lib/cache.c b/lib/cache.c
index f23dbb06264a..4c7c3863275b 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -10,7 +10,8 @@
#include "erofs/print.h"
#include "liberofs_cache.h"
-static int erofs_bh_flush_drop_directly(struct erofs_buffer_head *bh)
+static int erofs_bh_flush_drop_directly(struct erofs_buffer_head *bh,
+ bool abort)
{
return erofs_bh_flush_generic_end(bh);
}
@@ -19,7 +20,7 @@ const struct erofs_bhops erofs_drop_directly_bhops = {
.flush = erofs_bh_flush_drop_directly,
};
-static int erofs_bh_flush_skip_write(struct erofs_buffer_head *bh)
+static int erofs_bh_flush_skip_write(struct erofs_buffer_head *bh, bool abort)
{
return -EBUSY;
}
@@ -449,7 +450,7 @@ static void erofs_bfree(struct erofs_buffer_block *bb)
}
static int __erofs_bflush(struct erofs_bufmgr *bmgr,
- struct erofs_buffer_block *bb, bool forget)
+ struct erofs_buffer_block *bb, bool abort)
{
struct erofs_sb_info *sbi = bmgr->sbi;
const unsigned int blksiz = erofs_blksiz(sbi);
@@ -470,7 +471,7 @@ static int __erofs_bflush(struct erofs_bufmgr *bmgr,
list_for_each_entry_safe(bh, nbh, &p->buffers.list, list) {
if (bh->op == &erofs_skip_write_bhops) {
- if (!forget) {
+ if (!abort) {
skip = true;
continue;
}
@@ -478,8 +479,8 @@ static int __erofs_bflush(struct erofs_bufmgr *bmgr,
}
/* flush and remove bh */
- ret = bh->op->flush(bh);
- if (__erofs_unlikely(ret == -EBUSY && !forget)) {
+ ret = bh->op->flush(bh, abort);
+ if (__erofs_unlikely(ret == -EBUSY && !abort)) {
skip = true;
continue;
}
diff --git a/lib/inode.c b/lib/inode.c
index e3ee79a04a04..7d20fbdda6e6 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -897,20 +897,23 @@ int erofs_iflush(struct erofs_inode *inode)
if (ret != inode->extent_isize)
return ret < 0 ? ret : -EIO;
}
- if (bh) {
- inode->bh = NULL;
- erofs_iput(inode);
- return erofs_bh_flush_generic_end(bh);
- }
return 0;
}
-static int erofs_bh_flush_write_inode(struct erofs_buffer_head *bh)
+static int erofs_bh_flush_write_inode(struct erofs_buffer_head *bh, bool abort)
{
struct erofs_inode *inode = bh->fsprivate;
+ int ret;
DBG_BUGON(inode->bh != bh);
- return erofs_iflush(inode);
+ if (!abort) {
+ ret = erofs_iflush(inode);
+ if (ret)
+ return ret;
+ }
+ inode->bh = NULL;
+ erofs_iput(inode);
+ return erofs_bh_flush_generic_end(bh);
}
static struct erofs_bhops erofs_write_inode_bhops = {
@@ -1050,7 +1053,7 @@ noinline:
return 0;
}
-static int erofs_bh_flush_write_inline(struct erofs_buffer_head *bh)
+static int erofs_bh_flush_write_inline(struct erofs_buffer_head *bh, bool
abort)
{
struct erofs_inode *const inode = bh->fsprivate;
struct erofs_sb_info *sbi = inode->sbi;
@@ -1059,11 +1062,14 @@ static int erofs_bh_flush_write_inline(struct
erofs_buffer_head *bh)
const erofs_off_t off = erofs_btell(bh, false);
int ret;
- ret = erofs_io_pwrite(ibmgr->vf, inode->idata, off, inode->idata_size);
- if (ret < 0)
- return ret;
- if (ret != inode->idata_size)
- return -EIO;
+ if (!abort) {
+ ret = erofs_io_pwrite(ibmgr->vf, inode->idata, off,
+ inode->idata_size);
+ if (ret < 0)
+ return ret;
+ if (ret != inode->idata_size)
+ return -EIO;
+ }
free(inode->idata);
inode->idata = NULL;
diff --git a/lib/liberofs_cache.h b/lib/liberofs_cache.h
index 215b320da0fd..baac609fb49f 100644
--- a/lib/liberofs_cache.h
+++ b/lib/liberofs_cache.h
@@ -30,7 +30,7 @@ struct erofs_buffer_block;
#define DEVT 5
struct erofs_bhops {
- int (*flush)(struct erofs_buffer_head *bh);
+ int (*flush)(struct erofs_buffer_head *bh, bool abort);
};
struct erofs_buffer_head {
--
2.43.5