diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-10-14 09:54:47 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-10-20 12:06:20 -0400 |
commit | 257391ded8b53acc97d509bde15a2272ab0d1544 (patch) | |
tree | 8d4a797898d75f67bd147ad531418f11d269bd12 /fs/bcachefs/fsck.c | |
parent | f37bb418d585ff9cc0a428d9ac1461b56a6848c6 (diff) |
bcachefs: Fix for leaking of reflinked extentsreflink_p_fix
When a reflink pointer points to only part of an indirect extent, and
then that indirect extent is fragmented (e.g. by copygc), if the reflink
pointer only points to one of the fragments we leak a reference.
Fix this by storing front/back pad values in reflink pointers - when
inserting reflink pointesr, we initialize them to cover the full range
of the indirect extents we reference.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/fsck.c')
-rw-r--r-- | fs/bcachefs/fsck.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index b43c31b95dff..c99e1514fd4f 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -2174,7 +2174,7 @@ static int fix_reflink_p_key(struct btree_trans *trans, struct btree_iter *iter) p = bkey_s_c_to_reflink_p(k); - if (!p.v->v2) + if (!p.v->front_pad && !p.v->back_pad) return 0; u = bch2_trans_kmalloc(trans, sizeof(*u)); @@ -2183,7 +2183,8 @@ static int fix_reflink_p_key(struct btree_trans *trans, struct btree_iter *iter) return ret; bkey_reassemble(&u->k_i, k); - u->v.v2 = 0; + u->v.front_pad = 0; + u->v.back_pad = 0; return bch2_trans_update(trans, iter, &u->k_i, 0); } |