View | Details | Raw Unified | Return to bug 276002 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/fs/nfsclient/nfs_clvnops.c (-5 / +24 lines)
Lines 3872-3884 nfs_copy_file_range(struct vop_copy_file_range_args *ap) Link Here
3872
	struct vnode *invp = ap->a_invp;
3872
	struct vnode *invp = ap->a_invp;
3873
	struct vnode *outvp = ap->a_outvp;
3873
	struct vnode *outvp = ap->a_outvp;
3874
	struct mount *mp;
3874
	struct mount *mp;
3875
	vm_object_t invp_obj;
3875
	struct nfsvattr innfsva, outnfsva;
3876
	struct nfsvattr innfsva, outnfsva;
3876
	struct vattr va, *vap;
3877
	struct vattr va, *vap;
3877
	struct uio io;
3878
	struct uio io;
3878
	struct nfsmount *nmp;
3879
	struct nfsmount *nmp;
3879
	size_t len, len2;
3880
	size_t len, len2;
3880
	ssize_t r;
3881
	ssize_t r;
3881
	int error, inattrflag, outattrflag, ret, ret2;
3882
	int error, inattrflag, outattrflag, ret, ret2, invp_lock;
3882
	off_t inoff, outoff;
3883
	off_t inoff, outoff;
3883
	bool consecutive, must_commit, tryoutcred;
3884
	bool consecutive, must_commit, tryoutcred;
3884
3885
Lines 3891-3896 nfs_copy_file_range(struct vop_copy_file_range_args *ap) Link Here
3891
		return (ENOSYS);
3892
		return (ENOSYS);
3892
	}
3893
	}
3893
3894
3895
	invp_lock = LK_SHARED;
3896
relock:
3897
3894
	/* Lock both vnodes, avoiding risk of deadlock. */
3898
	/* Lock both vnodes, avoiding risk of deadlock. */
3895
	do {
3899
	do {
3896
		mp = NULL;
3900
		mp = NULL;
Lines 3898-3911 nfs_copy_file_range(struct vop_copy_file_range_args *ap) Link Here
3898
		if (error == 0) {
3902
		if (error == 0) {
3899
			error = vn_lock(outvp, LK_EXCLUSIVE);
3903
			error = vn_lock(outvp, LK_EXCLUSIVE);
3900
			if (error == 0) {
3904
			if (error == 0) {
3901
				error = vn_lock(invp, LK_SHARED | LK_NOWAIT);
3905
				error = vn_lock(invp, invp_lock | LK_NOWAIT);
3902
				if (error == 0)
3906
				if (error == 0)
3903
					break;
3907
					break;
3904
				VOP_UNLOCK(outvp);
3908
				VOP_UNLOCK(outvp);
3905
				if (mp != NULL)
3909
				if (mp != NULL)
3906
					vn_finished_write(mp);
3910
					vn_finished_write(mp);
3907
				mp = NULL;
3911
				mp = NULL;
3908
				error = vn_lock(invp, LK_SHARED);
3912
				error = vn_lock(invp, invp_lock);
3909
				if (error == 0)
3913
				if (error == 0)
3910
					VOP_UNLOCK(invp);
3914
					VOP_UNLOCK(invp);
3911
			}
3915
			}
Lines 3953-3962 nfs_copy_file_range(struct vop_copy_file_range_args *ap) Link Here
3953
	 * stable storage before the Copy RPC.  This is done in case the
3957
	 * stable storage before the Copy RPC.  This is done in case the
3954
	 * server reboots during the Copy and needs to be redone.
3958
	 * server reboots during the Copy and needs to be redone.
3955
	 */
3959
	 */
3956
	if (error == 0)
3960
	if (error == 0) {
3961
		invp_obj = invp->v_object;
3962
		if (invp_obj != NULL && vm_object_mightbedirty(invp_obj)) {
3963
			if (invp_lock != LK_EXCLUSIVE) {
3964
				invp_lock = LK_EXCLUSIVE;
3965
				VOP_UNLOCK(invp);
3966
				VOP_UNLOCK(outvp);
3967
				if (mp != NULL)
3968
					vn_finished_write(mp);
3969
				goto relock;
3970
			}
3971
			VM_OBJECT_WLOCK(invp_obj);
3972
			vm_object_page_clean(invp_obj, 0, 0, OBJPC_SYNC);
3973
			VM_OBJECT_WUNLOCK(invp_obj);
3974
		}
3957
		error = ncl_flush(invp, MNT_WAIT, curthread, 1, 0);
3975
		error = ncl_flush(invp, MNT_WAIT, curthread, 1, 0);
3976
	}
3958
	if (error == 0)
3977
	if (error == 0)
3959
		error = ncl_flush(outvp, MNT_WAIT, curthread, 1, 0);
3978
		error = ncl_vinvalbuf(outvp, V_SAVE, curthread, 0);
3960
3979
3961
	/* Do the actual NFSv4.2 RPC. */
3980
	/* Do the actual NFSv4.2 RPC. */
3962
	ret = ret2 = 0;
3981
	ret = ret2 = 0;

Return to bug 276002