diff options
author | Brian Behlendorf <[email protected]> | 2019-05-23 13:46:33 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2019-05-23 13:46:33 -0700 |
commit | bff2361aeb32a83c26e2992733864ca99cced257 (patch) | |
tree | ae45cdae978446595bbb160f20dae43ba9e79edb /module/zfs/dmu_zfetch.c | |
parent | e34c3ee2fcbb320525a110c1811c557bc60479ff (diff) |
Linux 5.2 compat: rw_tryupgrade()
Commit torvalds/linux@46ad0840b has removed the architecture specific
rwsem source and headers leaving only the generic version. As part
of this change the RWSEM_ACTIVE_READ_BIAS and RWSEM_ACTIVE_WRITE_BIAS
macros were moved to the private kernel/locking/rwsem.h header.
This results in a build failure because these macros were required
to implement the rw_tryupgrade() compatibility function.
In practice, this isn't a major problem because there are only a
few consumers of rw_tryupgrade() and because consumers of rw_tryupgrade
should be written to retry using rw_enter(RW_WRITER).
After auditing all of the callers only dmu_zfetch() was determined
not to perform a retry. It has been updated in this commit to
resolve this issue.
That said, the rw_tryupgrade() functionality should be considered
for possible removal in a future release due to the difficultly
in supporting the interface.
Reviewed-by: Tomohiro Kusumi <[email protected]>
Reviewed-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #8730
Diffstat (limited to 'module/zfs/dmu_zfetch.c')
-rw-r--r-- | module/zfs/dmu_zfetch.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/module/zfs/dmu_zfetch.c b/module/zfs/dmu_zfetch.c index 2133518ff..364e4d7aa 100644 --- a/module/zfs/dmu_zfetch.c +++ b/module/zfs/dmu_zfetch.c @@ -214,6 +214,7 @@ dmu_zfetch(zfetch_t *zf, uint64_t blkid, uint64_t nblks, boolean_t fetch_data) uint64_t end_of_access_blkid; end_of_access_blkid = blkid + nblks; spa_t *spa = zf->zf_dnode->dn_objset->os_spa; + krw_t rw = RW_READER; if (zfs_prefetch_disable) return; @@ -234,7 +235,8 @@ dmu_zfetch(zfetch_t *zf, uint64_t blkid, uint64_t nblks, boolean_t fetch_data) if (blkid == 0) return; - rw_enter(&zf->zf_rwlock, RW_READER); +retry: + rw_enter(&zf->zf_rwlock, rw); /* * Find matching prefetch stream. Depending on whether the accesses @@ -272,8 +274,13 @@ dmu_zfetch(zfetch_t *zf, uint64_t blkid, uint64_t nblks, boolean_t fetch_data) * a new stream for it. */ ZFETCHSTAT_BUMP(zfetchstat_misses); - if (rw_tryupgrade(&zf->zf_rwlock)) - dmu_zfetch_stream_create(zf, end_of_access_blkid); + if (rw == RW_READER && !rw_tryupgrade(&zf->zf_rwlock)) { + rw_exit(&zf->zf_rwlock); + rw = RW_WRITER; + goto retry; + } + + dmu_zfetch_stream_create(zf, end_of_access_blkid); rw_exit(&zf->zf_rwlock); return; } |