Page MenuHomeFreeBSD

D42603.id130520.diff
No OneTemporary

D42603.id130520.diff

diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
@@ -6321,9 +6321,7 @@
bad_write_fallback:
if (mp != NULL)
vn_finished_write(mp);
- error = vn_generic_copy_file_range(ap->a_invp, ap->a_inoffp,
- ap->a_outvp, ap->a_outoffp, ap->a_lenp, ap->a_flags,
- ap->a_incred, ap->a_outcred, ap->a_fsizetd);
+ error = ENOSYS;
return (error);
}
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -861,6 +861,7 @@
pid_t pid;
int err;
+ err = ENOSYS;
if (mp == NULL || mp != vnode_mount(outvp))
goto fallback;
@@ -943,13 +944,9 @@
VOP_UNLOCK(invp);
VOP_UNLOCK(outvp);
- if (err == ENOSYS) {
+ if (err == ENOSYS)
fsess_set_notimpl(mp, FUSE_COPY_FILE_RANGE);
fallback:
- err = vn_generic_copy_file_range(ap->a_invp, ap->a_inoffp,
- ap->a_outvp, ap->a_outoffp, ap->a_lenp, ap->a_flags,
- ap->a_incred, ap->a_outcred, ap->a_fsizetd);
- }
/*
* No need to call vn_rlimit_fsizex_res before return, since the uio is
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -3888,9 +3888,7 @@
*/
if (invp == outvp || invp->v_mount != outvp->v_mount) {
generic_copy:
- return (vn_generic_copy_file_range(invp, ap->a_inoffp,
- outvp, ap->a_outoffp, ap->a_lenp, ap->a_flags,
- ap->a_incred, ap->a_outcred, ap->a_fsizetd));
+ return (ENOSYS);
}
/* Lock both vnodes, avoiding risk of deadlock. */
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -1131,6 +1131,23 @@
return (res);
}
+static int
+null_getlowvnode(struct vop_getlowvnode_args *ap)
+{
+ struct vnode *vp, *vpl;
+
+ vp = ap->a_vp;
+ if (vn_lock(vp, LK_SHARED) != 0)
+ return (EBADF);
+
+ vpl = NULLVPTOLOWERVP(vp);
+ vhold(vpl);
+ VOP_UNLOCK(vp);
+ VOP_GETLOWVNODE(vpl, ap->a_vplp, ap->a_flags);
+ vdrop(vpl);
+ return (0);
+}
+
/*
* Global vfs data structures
*/
@@ -1143,6 +1160,7 @@
.vop_bmap = VOP_EOPNOTSUPP,
.vop_stat = null_stat,
.vop_getattr = null_getattr,
+ .vop_getlowvnode = null_getlowvnode,
.vop_getwritemount = null_getwritemount,
.vop_inactive = null_inactive,
.vop_need_inactive = null_need_inactive,
@@ -1163,5 +1181,6 @@
.vop_vptofh = null_vptofh,
.vop_add_writecount = null_add_writecount,
.vop_vput_pair = null_vput_pair,
+ .vop_copy_file_range = VOP_PANIC,
};
VFS_VOP_VECTOR_REGISTER(null_vnodeops);
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -85,6 +85,7 @@
static int vop_stdread_pgcache(struct vop_read_pgcache_args *ap);
static int vop_stdstat(struct vop_stat_args *ap);
static int vop_stdvput_pair(struct vop_vput_pair_args *ap);
+static int vop_stdgetlowvnode(struct vop_getlowvnode_args *ap);
/*
* This vnode table stores what we want to do if the filesystem doesn't
@@ -115,6 +116,7 @@
.vop_fsync = VOP_NULL,
.vop_stat = vop_stdstat,
.vop_fdatasync = vop_stdfdatasync,
+ .vop_getlowvnode = vop_stdgetlowvnode,
.vop_getpages = vop_stdgetpages,
.vop_getpages_async = vop_stdgetpages_async,
.vop_getwritemount = vop_stdgetwritemount,
@@ -1610,3 +1612,11 @@
vput(vp);
return (0);
}
+
+static int
+vop_stdgetlowvnode(struct vop_getlowvnode_args *ap)
+{
+ vref(ap->a_vp);
+ *ap->a_vplp = ap->a_vp;
+ return (0);
+}
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3072,10 +3072,12 @@
struct ucred *outcred, struct thread *fsize_td)
{
struct mount *inmp, *outmp;
+ struct vnode *invpl, *outvpl;
int error;
size_t len;
uint64_t uval;
+ invpl = outvpl = NULL;
len = *lenp;
*lenp = 0; /* For error returns. */
error = 0;
@@ -3101,17 +3103,22 @@
if (len == 0)
goto out;
- inmp = invp->v_mount;
- outmp = outvp->v_mount;
- if (inmp == NULL || outmp == NULL) {
- error = EBADF;
+ error = VOP_GETLOWVNODE(invp, &invpl, FREAD);
+ if (error != 0)
goto out;
- }
+ error = VOP_GETLOWVNODE(outvp, &outvpl, FWRITE);
+ if (error != 0)
+ goto out1;
+
+ inmp = invpl->v_mount;
+ outmp = outvpl->v_mount;
+ if (inmp == NULL || outmp == NULL)
+ goto out2;
for (;;) {
error = vfs_busy(inmp, 0);
if (error != 0)
- goto out;
+ goto out2;
if (inmp == outmp)
break;
error = vfs_busy(outmp, MBF_NOWAIT);
@@ -3122,7 +3129,7 @@
vfs_unbusy(outmp);
continue;
}
- goto out;
+ goto out2;
}
break;
}
@@ -3133,16 +3140,23 @@
* which can handle copies across multiple file system types.
*/
*lenp = len;
- if (inmp == outmp || strcmp(inmp->mnt_vfc->vfc_name,
- outmp->mnt_vfc->vfc_name) == 0)
- error = VOP_COPY_FILE_RANGE(invp, inoffp, outvp, outoffp,
+ if (inmp == outmp || inmp->mnt_vfc == outmp->mnt_vfc)
+ error = VOP_COPY_FILE_RANGE(invpl, inoffp, outvpl, outoffp,
lenp, flags, incred, outcred, fsize_td);
else
- error = vn_generic_copy_file_range(invp, inoffp, outvp,
+ error = ENOSYS;
+ if (error == ENOSYS)
+ error = vn_generic_copy_file_range(invpl, inoffp, outvpl,
outoffp, lenp, flags, incred, outcred, fsize_td);
vfs_unbusy(outmp);
if (inmp != outmp)
vfs_unbusy(inmp);
+out2:
+ if (outvpl != NULL)
+ vrele(outvpl);
+out1:
+ if (invpl != NULL)
+ vrele(invpl);
out:
return (error);
}
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -471,6 +471,13 @@
OUT struct mount **mpp;
};
+%% getwritevnode vp = = =
+
+vop_getlowvnode {
+ IN struct vnode *vp;
+ OUT struct vnode **vplp;
+ IN int flags;
+};
%% print vp - - -

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 9, 4:42 PM (9 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15733480
Default Alt Text
D42603.id130520.diff (5 KB)

Event Timeline