aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2023-12-30 00:15:50 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2024-01-11 16:46:52 +0000
commit09c69decd208d3ccd4dd54ea67c14b48c012c58c (patch)
treebee28023de19e5f264a0079ad512993df9f4b0fd
parent384c72acb50d3fd5a3bd07f41d3755867865c0b6 (diff)
downloadsrc-09c69decd208d3ccd4dd54ea67c14b48c012c58c.tar.gz
src-09c69decd208d3ccd4dd54ea67c14b48c012c58c.zip
nfsclient: flush dirty pages of the vnode
PR: 276002 (cherry picked from commit 47ec00d9d6071bbb0ee5ed0bdca3c4a468334d9d)
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index f86ecd53ad4e..36ab5485d807 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -3705,6 +3705,7 @@ nfs_allocate(struct vop_allocate_args *ap)
{
struct vnode *vp = ap->a_vp;
struct thread *td = curthread;
+ vm_object_t obj;
struct nfsvattr nfsva;
struct nfsmount *nmp;
struct nfsnode *np;
@@ -3733,8 +3734,15 @@ nfs_allocate(struct vop_allocate_args *ap)
* Flush first to ensure that the allocate adds to the
* file's allocation on the server.
*/
- if (error == 0)
+ if (error == 0) {
+ obj = vp->v_object;
+ if (obj != NULL) {
+ VM_OBJECT_WLOCK(obj);
+ vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_WUNLOCK(obj);
+ }
error = ncl_flush(vp, MNT_WAIT, td, 1, 0);
+ }
if (error == 0)
error = nfsrpc_allocate(vp, *ap->a_offset, alen,
&nfsva, &attrflag, ap->a_cred, td);
@@ -3872,13 +3880,14 @@ nfs_copy_file_range(struct vop_copy_file_range_args *ap)
struct vnode *invp = ap->a_invp;
struct vnode *outvp = ap->a_outvp;
struct mount *mp;
+ vm_object_t invp_obj;
struct nfsvattr innfsva, outnfsva;
struct vattr va, *vap;
struct uio io;
struct nfsmount *nmp;
size_t len, len2;
ssize_t r;
- int error, inattrflag, outattrflag, ret, ret2;
+ int error, inattrflag, outattrflag, ret, ret2, invp_lock;
off_t inoff, outoff;
bool consecutive, must_commit, tryoutcred;
@@ -3891,6 +3900,9 @@ generic_copy:
return (ENOSYS);
}
+ invp_lock = LK_SHARED;
+relock:
+
/* Lock both vnodes, avoiding risk of deadlock. */
do {
mp = NULL;
@@ -3898,14 +3910,14 @@ generic_copy:
if (error == 0) {
error = vn_lock(outvp, LK_EXCLUSIVE);
if (error == 0) {
- error = vn_lock(invp, LK_SHARED | LK_NOWAIT);
+ error = vn_lock(invp, invp_lock | LK_NOWAIT);
if (error == 0)
break;
VOP_UNLOCK(outvp);
if (mp != NULL)
vn_finished_write(mp);
mp = NULL;
- error = vn_lock(invp, LK_SHARED);
+ error = vn_lock(invp, invp_lock);
if (error == 0)
VOP_UNLOCK(invp);
}
@@ -3953,8 +3965,23 @@ generic_copy:
* stable storage before the Copy RPC. This is done in case the
* server reboots during the Copy and needs to be redone.
*/
- if (error == 0)
+ if (error == 0) {
+ invp_obj = invp->v_object;
+ if (invp_obj != NULL && vm_object_mightbedirty(invp_obj)) {
+ if (invp_lock != LK_EXCLUSIVE) {
+ invp_lock = LK_EXCLUSIVE;
+ VOP_UNLOCK(invp);
+ VOP_UNLOCK(outvp);
+ if (mp != NULL)
+ vn_finished_write(mp);
+ goto relock;
+ }
+ VM_OBJECT_WLOCK(invp_obj);
+ vm_object_page_clean(invp_obj, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_WUNLOCK(invp_obj);
+ }
error = ncl_flush(invp, MNT_WAIT, curthread, 1, 0);
+ }
if (error == 0)
error = ncl_vinvalbuf(outvp, V_SAVE, curthread, 0);
@@ -4110,6 +4137,7 @@ static int
nfs_ioctl(struct vop_ioctl_args *ap)
{
struct vnode *vp = ap->a_vp;
+ vm_object_t obj;
struct nfsvattr nfsva;
struct nfsmount *nmp;
int attrflag, content, error, ret;
@@ -4127,7 +4155,7 @@ nfs_ioctl(struct vop_ioctl_args *ap)
return (ENOTTY);
}
- error = vn_lock(vp, LK_SHARED);
+ error = vn_lock(vp, LK_EXCLUSIVE);
if (error != 0)
return (EBADF);
@@ -4153,6 +4181,11 @@ nfs_ioctl(struct vop_ioctl_args *ap)
* server, the LayoutCommit will be done to ensure the file
* size is up to date on the Metadata Server.
*/
+
+ obj = vp->v_object;
+ VM_OBJECT_WLOCK(obj);
+ vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_WUNLOCK(obj);
error = ncl_flush(vp, MNT_WAIT, ap->a_td, 1, 0);
if (error == 0)
error = nfsrpc_seek(vp, (off_t *)ap->a_data, &eof,