aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2024-01-01 22:22:44 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2024-01-11 16:46:53 +0000
commitcbf323cf503b69516ef19542c4630c0d42d74b05 (patch)
tree8f4c5d564407705bc78f7fcb2e4812c7e2f5c766
parent9e951d6b4b708fad9993aca0a1cede1c74d735e0 (diff)
downloadsrc-cbf323cf503b69516ef19542c4630c0d42d74b05.tar.gz
src-cbf323cf503b69516ef19542c4630c0d42d74b05.zip
nfsclient: limit situations when we do unlocked read-ahead by nfsiod
(cherry picked from commit 70dc6b2ce314a0f32755005ad02802fca7ed186e)
-rw-r--r--sys/fs/nfsclient/nfs_clbio.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
index 63e97f405198..7b9b68782d53 100644
--- a/sys/fs/nfsclient/nfs_clbio.c
+++ b/sys/fs/nfsclient/nfs_clbio.c
@@ -484,9 +484,14 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
on = uio->uio_offset - (lbn * biosize);
/*
- * Start the read ahead(s), as required.
+ * Start the read ahead(s), as required. Do not do
+ * read-ahead if there are writeable mappings, since
+ * unlocked read by nfsiod could obliterate changes
+ * done by userspace.
*/
- if (nmp->nm_readahead > 0) {
+ if (nmp->nm_readahead > 0 &&
+ !vm_object_mightbedirty(vp->v_object) &&
+ vp->v_object->un_pager.vnp.writemappings == 0) {
for (nra = 0; nra < nmp->nm_readahead && nra < seqcount &&
(off_t)(lbn + 1 + nra) * biosize < nsize; nra++) {
rabn = lbn + 1 + nra;
@@ -674,6 +679,8 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
*/
NFSLOCKNODE(np);
if (nmp->nm_readahead > 0 &&
+ !vm_object_mightbedirty(vp->v_object) &&
+ vp->v_object->un_pager.vnp.writemappings == 0 &&
(bp->b_flags & B_INVAL) == 0 &&
(np->n_direofoffset == 0 ||
(lbn + 1) * NFS_DIRBLKSIZ < np->n_direofoffset) &&