diff options
author | Matthew Macy <[email protected]> | 2020-10-13 21:03:36 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2020-10-13 21:03:36 -0700 |
commit | 57dc5d42b185d2983717580b7fb58bfe423cd834 (patch) | |
tree | a0cd46563a64aed94762df41848892671609c750 /module | |
parent | 6ba2e72b7899771f588dc4557624c186be2c2176 (diff) |
dmu_zfetch: don't leak unreferenced stream when zfetch is freed
Currently streams are only freed when:
- They have no referencing zfetch and and their I/O references
go to zero.
- They are more than 2s old and a new I/O request comes in on
the same zfetch.
This means that we will leak unreferenced streams when their zfetch
structure is freed.
This change checks the reference count on a stream at zfetch free
time. If it is zero we free it immediately. If it has remaining
references we allow the prefetch callback to free it at I/O
completion time.
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Adam Moss <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Matt Macy <[email protected]>
Closes #11052
Diffstat (limited to 'module')
-rw-r--r-- | module/zfs/dmu_zfetch.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/module/zfs/dmu_zfetch.c b/module/zfs/dmu_zfetch.c index fa43fe4fc..5d061fe38 100644 --- a/module/zfs/dmu_zfetch.c +++ b/module/zfs/dmu_zfetch.c @@ -161,8 +161,12 @@ dmu_zfetch_fini(zfetch_t *zf) zstream_t *zs; mutex_enter(&zf->zf_lock); - while ((zs = list_head(&zf->zf_stream)) != NULL) - dmu_zfetch_stream_orphan(zf, zs); + while ((zs = list_head(&zf->zf_stream)) != NULL) { + if (zfs_refcount_count(&zs->zs_blocks) != 0) + dmu_zfetch_stream_orphan(zf, zs); + else + dmu_zfetch_stream_remove(zf, zs); + } mutex_exit(&zf->zf_lock); list_destroy(&zf->zf_stream); mutex_destroy(&zf->zf_lock); |