diff options
author | Brian Behlendorf <[email protected]> | 2018-10-08 14:58:21 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-10-09 10:05:48 -0700 |
commit | d7e4b30a672c1d7eb77dbbe2cdcf14cac102839a (patch) | |
tree | e9d61baf611a5479fd047b7170b67ea57dd2abf7 /include | |
parent | 4cbde2ecbf7c6478bac106fadd6a23f53d538262 (diff) |
Add zfs_refcount_transfer_ownership_many()
When debugging is enabled and a zfs_refcount_t contains multiple holders
using the same key, but different ref_counts, the wrong reference_t may
be transferred. Add a zfs_refcount_transfer_ownership_many() function,
like the existing zfs_refcount_*_many() functions, to match and transfer
the correct refcount_t;
This issue may occur when using encryption with refcount debugging
enabled. An arc_buf_hdr_t can have references for both the
hdr->b_l1hdr.b_pabd and hdr->b_crypt_hdr.b_rabd both of which use
the hdr as the reference holder. When unsharing the buffer the
p_abd should be transferred.
This issue does not impact production builds because refcount holders
are not tracked.
Reviewed-by: Matthew Ahrens <[email protected]>
Signed-off-by: Tom Caputi <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #7219
Closes #8000
Diffstat (limited to 'include')
-rw-r--r-- | include/sys/refcount.h | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/include/sys/refcount.h b/include/sys/refcount.h index 0059a245e..e982faeba 100644 --- a/include/sys/refcount.h +++ b/include/sys/refcount.h @@ -76,6 +76,8 @@ int64_t zfs_refcount_add_many(zfs_refcount_t *, uint64_t, void *); int64_t zfs_refcount_remove_many(zfs_refcount_t *, uint64_t, void *); void zfs_refcount_transfer(zfs_refcount_t *, zfs_refcount_t *); void zfs_refcount_transfer_ownership(zfs_refcount_t *, void *, void *); +void zfs_refcount_transfer_ownership_many(zfs_refcount_t *, uint64_t, + void *, void *); boolean_t zfs_refcount_held(zfs_refcount_t *, void *); boolean_t zfs_refcount_not_held(zfs_refcount_t *, void *); @@ -106,8 +108,9 @@ typedef struct refcount { atomic_add_64(&(src)->rc_count, -__tmp); \ atomic_add_64(&(dst)->rc_count, __tmp); \ } -#define zfs_refcount_transfer_ownership(rc, current_holder, new_holder) (void)0 -#define zfs_refcount_held(rc, holder) ((rc)->rc_count > 0) +#define zfs_refcount_transfer_ownership(rc, ch, nh) ((void)0) +#define zfs_refcount_transfer_ownership_many(rc, nr, ch, nh) ((void)0) +#define zfs_refcount_held(rc, holder) ((rc)->rc_count > 0) #define zfs_refcount_not_held(rc, holder) (B_TRUE) #define zfs_refcount_init() |