summaryrefslogtreecommitdiffstats
path: root/module/zfs/dmu_zfetch.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2019-05-23 13:46:33 -0700
committerGitHub <[email protected]>2019-05-23 13:46:33 -0700
commitbff2361aeb32a83c26e2992733864ca99cced257 (patch)
treeae45cdae978446595bbb160f20dae43ba9e79edb /module/zfs/dmu_zfetch.c
parente34c3ee2fcbb320525a110c1811c557bc60479ff (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.c13
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;
}