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; |