Skip to content

Commit

Permalink
dmu_zfetch: don't leak unreferenced stream when zfetch is freed
Browse files Browse the repository at this point in the history
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 openzfs#11052
  • Loading branch information
mattmacy authored and Ryan Moeller committed May 25, 2021
1 parent 745625a commit c8ef1ff
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions module/zfs/dmu_zfetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit c8ef1ff

Please sign in to comment.