|
Jiri Slaby |
1f0641 |
From: Zhihao Cheng <chengzhihao1@huawei.com>
|
|
Jiri Slaby |
1f0641 |
Date: Fri, 18 Nov 2022 17:02:35 +0800
|
|
Jiri Slaby |
1f0641 |
Subject: [PATCH] ubifs: Re-statistic cleaned znode count if commit failed
|
|
Jiri Slaby |
1f0641 |
References: bsc#1012628
|
|
Jiri Slaby |
1f0641 |
Patch-mainline: 6.2.5
|
|
Jiri Slaby |
1f0641 |
Git-commit: 944e096aa24071d3fe22822f6249d3ae309e39ea
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
[ Upstream commit 944e096aa24071d3fe22822f6249d3ae309e39ea ]
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
Dirty znodes will be written on flash in committing process with
|
|
Jiri Slaby |
1f0641 |
following states:
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
process A | znode state
|
|
Jiri Slaby |
1f0641 |
------------------------------------------------------
|
|
Jiri Slaby |
1f0641 |
do_commit | DIRTY_ZNODE
|
|
Jiri Slaby |
1f0641 |
ubifs_tnc_start_commit | DIRTY_ZNODE
|
|
Jiri Slaby |
1f0641 |
get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE
|
|
Jiri Slaby |
1f0641 |
layout_commit | DIRTY_ZNODE | COW_ZNODE
|
|
Jiri Slaby |
1f0641 |
fill_gap | 0
|
|
Jiri Slaby |
1f0641 |
write master | 0 or OBSOLETE_ZNODE
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
process B | znode state
|
|
Jiri Slaby |
1f0641 |
------------------------------------------------------
|
|
Jiri Slaby |
1f0641 |
do_commit | DIRTY_ZNODE[1]
|
|
Jiri Slaby |
1f0641 |
ubifs_tnc_start_commit | DIRTY_ZNODE
|
|
Jiri Slaby |
1f0641 |
get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE
|
|
Jiri Slaby |
1f0641 |
ubifs_tnc_end_commit | DIRTY_ZNODE | COW_ZNODE
|
|
Jiri Slaby |
1f0641 |
write_index | 0
|
|
Jiri Slaby |
1f0641 |
write master | 0 or OBSOLETE_ZNODE[2] or
|
|
Jiri Slaby |
1f0641 |
| DIRTY_ZNODE[3]
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
[1] znode is dirtied without concurrent committing process
|
|
Jiri Slaby |
1f0641 |
[2] znode is copied up (re-dirtied by other process) before cleaned
|
|
Jiri Slaby |
1f0641 |
up in committing process
|
|
Jiri Slaby |
1f0641 |
[3] znode is re-dirtied after cleaned up in committing process
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
Currently, the clean znode count is updated in free_obsolete_znodes(),
|
|
Jiri Slaby |
1f0641 |
which is called only in normal path. If do_commit failed, clean znode
|
|
Jiri Slaby |
1f0641 |
count won't be updated, which triggers a failure ubifs assertion[4] in
|
|
Jiri Slaby |
1f0641 |
ubifs_tnc_close():
|
|
Jiri Slaby |
1f0641 |
ubifs_assert_failed [ubifs]: UBIFS assert failed: freed == n
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
[4] Commit 380347e9ca7682 ("UBIFS: Add an assertion for clean_zn_cnt").
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
Fix it by re-statisticing cleaned znode count in tnc_destroy_cnext().
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
Fetch a reproducer in [Link].
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216704
|
|
Jiri Slaby |
1f0641 |
Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
|
|
Jiri Slaby |
1f0641 |
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
|
|
Jiri Slaby |
1f0641 |
Signed-off-by: Richard Weinberger <richard@nod.at>
|
|
Jiri Slaby |
1f0641 |
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Jiri Slaby |
1f0641 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
1f0641 |
---
|
|
Jiri Slaby |
1f0641 |
fs/ubifs/tnc.c | 15 +++++++++++++++
|
|
Jiri Slaby |
1f0641 |
1 file changed, 15 insertions(+)
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
|
|
Jiri Slaby |
1f0641 |
index 488f3da7..2df56bbc 100644
|
|
Jiri Slaby |
1f0641 |
--- a/fs/ubifs/tnc.c
|
|
Jiri Slaby |
1f0641 |
+++ b/fs/ubifs/tnc.c
|
|
Jiri Slaby |
1f0641 |
@@ -3053,6 +3053,21 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
|
|
Jiri Slaby |
1f0641 |
cnext = cnext->cnext;
|
|
Jiri Slaby |
1f0641 |
if (ubifs_zn_obsolete(znode))
|
|
Jiri Slaby |
1f0641 |
kfree(znode);
|
|
Jiri Slaby |
1f0641 |
+ else if (!ubifs_zn_cow(znode)) {
|
|
Jiri Slaby |
1f0641 |
+ /*
|
|
Jiri Slaby |
1f0641 |
+ * Don't forget to update clean znode count after
|
|
Jiri Slaby |
1f0641 |
+ * committing failed, because ubifs will check this
|
|
Jiri Slaby |
1f0641 |
+ * count while closing tnc. Non-obsolete znode could
|
|
Jiri Slaby |
1f0641 |
+ * be re-dirtied during committing process, so dirty
|
|
Jiri Slaby |
1f0641 |
+ * flag is untrustable. The flag 'COW_ZNODE' is set
|
|
Jiri Slaby |
1f0641 |
+ * for each dirty znode before committing, and it is
|
|
Jiri Slaby |
1f0641 |
+ * cleared as long as the znode become clean, so we
|
|
Jiri Slaby |
1f0641 |
+ * can statistic clean znode count according to this
|
|
Jiri Slaby |
1f0641 |
+ * flag.
|
|
Jiri Slaby |
1f0641 |
+ */
|
|
Jiri Slaby |
1f0641 |
+ atomic_long_inc(&c->clean_zn_cnt);
|
|
Jiri Slaby |
1f0641 |
+ atomic_long_inc(&ubifs_clean_zn_cnt);
|
|
Jiri Slaby |
1f0641 |
+ }
|
|
Jiri Slaby |
1f0641 |
} while (cnext && cnext != c->cnext);
|
|
Jiri Slaby |
1f0641 |
}
|
|
Jiri Slaby |
1f0641 |
|
|
Jiri Slaby |
1f0641 |
--
|
|
Jiri Slaby |
1f0641 |
2.35.3
|
|
Jiri Slaby |
1f0641 |
|