* [PATCH] f2fs: detach remaining IPU bio on error in f2fs_inplace_write_data()
@ 2026-10-12 9:51 Seongjae Jeong
0 siblings, 0 replies; only message in thread
From: Seongjae Jeong @ 2026-10-12 9:51 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: linux-f2fs-devel, linux-kernel, Seongjae Jeong
add_bio_entry() adds an IPU bio to bio_list and takes an additional
reference. However, the drop_bio path in f2fs_inplace_write_data()
only calls bio_endio() and clears *(fio->bio), without removing
the bio_entry from bio_list or releasing the additional reference.
This leaves a completed bio on the bio_list, allowing a later
submission path to submit it again.
Add a helper to detach the bio_entry from bio_list and release the
caller's reference regardless of whether the entry is found.
Call this helper in the drop_bio path and call bio_endio() only if
the helper successfully removes the entry. If another path has already
removed the entry for submission, leave completion to that path.
Fixes: 955772787667 ("f2fs: drop inplace IO if fs status is abnormal")
Signed-off-by: Seongjae Jeong <jsjlee1020@gmail.com>
---
fs/f2fs/data.c | 41 +++++++++++++++++++++++++++++++++++++++++
fs/f2fs/f2fs.h | 1 +
fs/f2fs/segment.c | 6 ++++--
3 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 6d4ba5e77906..ca8fce5ad778 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -989,6 +989,47 @@ static int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio,
return ret;
}
+bool f2fs_detach_bio_entry(struct f2fs_sb_info *sbi, struct bio *bio)
+{
+ enum temp_type temp;
+ bool found = false;
+
+ for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
+ struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
+ struct list_head *head = &io->bio_list;
+ struct bio_entry *be;
+
+ if (list_empty(head))
+ continue;
+
+ f2fs_down_read(&io->bio_list_lock);
+ list_for_each_entry(be, head, list) {
+ found = (bio == be->bio);
+ if (found)
+ break;
+ }
+ f2fs_up_read(&io->bio_list_lock);
+
+ if (!found)
+ continue;
+
+ found = false;
+
+ f2fs_down_write(&io->bio_list_lock);
+ list_for_each_entry(be, head, list) {
+ found = (bio == be->bio);
+ if (found) {
+ del_bio_entry(be);
+ break;
+ }
+ }
+ f2fs_up_write(&io->bio_list_lock);
+ }
+
+ bio_put(bio);
+ return found;
+}
+
void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
struct bio **bio, struct folio *folio)
{
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 089a62c054ea..63da4c2a9553 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4357,6 +4357,7 @@ void f2fs_destroy_bioset(void);
bool f2fs_is_cp_guaranteed(const struct folio *folio);
int f2fs_init_bio_entry_cache(void);
void f2fs_destroy_bio_entry_cache(void);
+bool f2fs_detach_bio_entry(struct f2fs_sb_info *sbi, struct bio *bio);
void f2fs_submit_read_bio(struct f2fs_sb_info *sbi, struct bio *bio,
enum page_type type);
int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 794e0d99fc7c..6bd60746d140 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -4300,8 +4300,10 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
if (fio->bio && *(fio->bio)) {
struct bio *bio = *(fio->bio);
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ if (f2fs_detach_bio_entry(sbi, bio)) {
+ bio->bi_status = BLK_STS_IOERR;
+ bio_endio(bio);
+ }
*(fio->bio) = NULL;
}
return err;
--
2.53.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-12 9:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 9:51 [PATCH] f2fs: detach remaining IPU bio on error in f2fs_inplace_write_data() Seongjae Jeong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®