Correct refcount_add in dmu_zfetch
refcount_add_many(foo,N) is not the same as for (i=0; i < N; i++) { refcount_add(foo); } Unfortunately, this is only actually true with debug kernels and reference_tracking_enable=1. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rich Ercolani <rincebrain@gmail.com> Closes #12589 Closes #12602
This commit is contained in:
parent
2d02bba23d
commit
9d1407e8f2
|
@ -72,6 +72,14 @@ int zfs_refcount_is_zero(zfs_refcount_t *);
|
|||
int64_t zfs_refcount_count(zfs_refcount_t *);
|
||||
int64_t zfs_refcount_add(zfs_refcount_t *, const void *);
|
||||
int64_t zfs_refcount_remove(zfs_refcount_t *, const void *);
|
||||
/*
|
||||
* Note that (add|remove)_many add/remove one reference with "number" N,
|
||||
* _not_ make N references with "number" 1, which is what vanilla
|
||||
* zfs_refcount_(add|remove) would do if called N times.
|
||||
*
|
||||
* Attempting to remove a reference with number N when none exists is a
|
||||
* panic on debug kernels with reference_tracking enabled.
|
||||
*/
|
||||
int64_t zfs_refcount_add_many(zfs_refcount_t *, uint64_t, const void *);
|
||||
int64_t zfs_refcount_remove_many(zfs_refcount_t *, uint64_t, const void *);
|
||||
void zfs_refcount_transfer(zfs_refcount_t *, zfs_refcount_t *);
|
||||
|
|
|
@ -488,7 +488,8 @@ dmu_zfetch_run(zstream_t *zs, boolean_t missed, boolean_t have_lock)
|
|||
issued = pf_end - pf_start + ipf_end - ipf_start;
|
||||
if (issued > 1) {
|
||||
/* More references on top of taken in dmu_zfetch_prepare(). */
|
||||
zfs_refcount_add_many(&zs->zs_refs, issued - 1, NULL);
|
||||
for (int i = 0; i < issued - 1; i++)
|
||||
zfs_refcount_add(&zs->zs_refs, NULL);
|
||||
} else if (issued == 0) {
|
||||
/* Some other thread has done our work, so drop the ref. */
|
||||
if (zfs_refcount_remove(&zs->zs_refs, NULL) == 0)
|
||||
|
|
Loading…
Reference in New Issue