diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-10-14 09:54:47 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:14 -0400 |
commit | 6d76aefea1902a11c47e20fec5495d30a39891f3 (patch) | |
tree | 3492b62e7853384faad5e0b97a4c5f7c60f7d945 /fs/bcachefs/reflink.c | |
parent | bfe88863cf3063204fc49a04307fa6635554d6e3 (diff) | |
download | lwn-6d76aefea1902a11c47e20fec5495d30a39891f3.tar.gz lwn-6d76aefea1902a11c47e20fec5495d30a39891f3.zip |
bcachefs: Fix for leaking of reflinked extents
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/reflink.c')
-rw-r--r-- | fs/bcachefs/reflink.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c index 9bcf4216a286..2827d0ef1019 100644 --- a/fs/bcachefs/reflink.c +++ b/fs/bcachefs/reflink.c @@ -32,6 +32,10 @@ const char *bch2_reflink_p_invalid(const struct bch_fs *c, struct bkey_s_c k) if (bkey_val_bytes(p.k) != sizeof(*p.v)) return "incorrect value size"; + if (c->sb.version >= bcachefs_metadata_version_reflink_p_fix && + le64_to_cpu(p.v->idx) < le32_to_cpu(p.v->front_pad)) + return "idx < front_pad"; + return NULL; } |