diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-11-17 22:03:15 +0100 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 23:09:46 +0200 |
commit | 42af0ad569edbfcd252e9abf0badd97b895c34be (patch) | |
tree | ae24fa72c52e7f8ed6797a98cae59fdae556f543 /fs/bcachefs/btree_update_interior.c | |
parent | bcachefs: Error message improvement (diff) | |
download | linux-42af0ad569edbfcd252e9abf0badd97b895c34be.tar.xz linux-42af0ad569edbfcd252e9abf0badd97b895c34be.zip |
bcachefs: Fix a race with b->write_type
b->write_type needs to be set atomically with setting the
btree_node_need_write flag, so move it into b->flags.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_update_interior.c')
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index ac3a5ef1b1af..03e016758af3 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -1257,6 +1257,7 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as, struct bch_fs *c = as->c; struct bkey_packed *k; struct printbuf buf = PRINTBUF; + unsigned long old, new, v; BUG_ON(insert->k.type == KEY_TYPE_btree_ptr_v2 && !btree_ptr_sectors_written(insert)); @@ -1294,8 +1295,15 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as, bch2_btree_bset_insert_key(trans, path, b, node_iter, insert); set_btree_node_dirty_acct(c, b); - set_btree_node_need_write(b); - b->write_type = BTREE_WRITE_interior; + + v = READ_ONCE(b->flags); + do { + old = new = v; + + new &= ~BTREE_WRITE_TYPE_MASK; + new |= BTREE_WRITE_interior; + new |= 1 << BTREE_NODE_need_write; + } while ((v = cmpxchg(&b->flags, old, new)) != old); printbuf_exit(&buf); } |