mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 03:37:45 +03:00
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 <mahrens@delphix.com> Signed-off-by: Tom Caputi <tcaputi@datto.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #7219 Closes #8000
This commit is contained in:
+4
-4
@@ -3081,8 +3081,8 @@ arc_share_buf(arc_buf_hdr_t *hdr, arc_buf_t *buf)
|
||||
* refcount ownership to the hdr since it always owns
|
||||
* the refcount whenever an arc_buf_t is shared.
|
||||
*/
|
||||
zfs_refcount_transfer_ownership(&hdr->b_l1hdr.b_state->arcs_size,
|
||||
buf, hdr);
|
||||
zfs_refcount_transfer_ownership_many(&hdr->b_l1hdr.b_state->arcs_size,
|
||||
arc_hdr_size(hdr), buf, hdr);
|
||||
hdr->b_l1hdr.b_pabd = abd_get_from_buf(buf->b_data, arc_buf_size(buf));
|
||||
abd_take_ownership_of_buf(hdr->b_l1hdr.b_pabd,
|
||||
HDR_ISTYPE_METADATA(hdr));
|
||||
@@ -3110,8 +3110,8 @@ arc_unshare_buf(arc_buf_hdr_t *hdr, arc_buf_t *buf)
|
||||
* We are no longer sharing this buffer so we need
|
||||
* to transfer its ownership to the rightful owner.
|
||||
*/
|
||||
zfs_refcount_transfer_ownership(&hdr->b_l1hdr.b_state->arcs_size,
|
||||
hdr, buf);
|
||||
zfs_refcount_transfer_ownership_many(&hdr->b_l1hdr.b_state->arcs_size,
|
||||
arc_hdr_size(hdr), hdr, buf);
|
||||
arc_hdr_clear_flags(hdr, ARC_FLAG_SHARED_DATA);
|
||||
abd_release_ownership_of_buf(hdr->b_l1hdr.b_pabd);
|
||||
abd_put(hdr->b_l1hdr.b_pabd);
|
||||
|
||||
Reference in New Issue
Block a user