summaryrefslogtreecommitdiff
path: root/fs/ubifs/commit.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.com>2024-03-13 21:17:33 +0100
committerJiri Kosina <jkosina@suse.com>2024-03-13 21:17:33 +0100
commit2e21dee6a46a66e4c2ced778485e1044101edee4 (patch)
treeb9a9565cf9e3954ad316c343715b43b401c51074 /fs/ubifs/commit.c
parent9a5b1521e2d0d7ace70c6e5eed073babcec91409 (diff)
parent90184f90c9ac559062a04aca72e5d05730164de0 (diff)
Merge branch 'for-6.9/amd-sfh' into for-linus
- assorted fixes and optimizations for amd-sfh (Basavaraj Natikar) Signed-off-by: Jiri Kosina <jkosina@suse.com>
Diffstat (limited to 'fs/ubifs/commit.c')
-rw-r--r--fs/ubifs/commit.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index c4fc1047fc07..5b3a840098b0 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -70,18 +70,29 @@ static int nothing_to_commit(struct ubifs_info *c)
return 0;
/*
+ * Increasing @c->dirty_pn_cnt/@c->dirty_nn_cnt and marking
+ * nnodes/pnodes as dirty in run_gc() could race with following
+ * checking, which leads inconsistent states between @c->nroot
+ * and @c->dirty_pn_cnt/@c->dirty_nn_cnt, holding @c->lp_mutex
+ * to avoid that.
+ */
+ mutex_lock(&c->lp_mutex);
+ /*
* Even though the TNC is clean, the LPT tree may have dirty nodes. For
* example, this may happen if the budgeting subsystem invoked GC to
* make some free space, and the GC found an LEB with only dirty and
* free space. In this case GC would just change the lprops of this
* LEB (by turning all space into free space) and unmap it.
*/
- if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags))
+ if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags)) {
+ mutex_unlock(&c->lp_mutex);
return 0;
+ }
ubifs_assert(c, atomic_long_read(&c->dirty_zn_cnt) == 0);
ubifs_assert(c, c->dirty_pn_cnt == 0);
ubifs_assert(c, c->dirty_nn_cnt == 0);
+ mutex_unlock(&c->lp_mutex);
return 1;
}