diff options
Diffstat (limited to 'sys/fs/nfs')
-rw-r--r-- | sys/fs/nfs/nfs_commonkrpc.c | 1 | ||||
-rw-r--r-- | sys/fs/nfs/nfs_commonsubs.c | 45 | ||||
-rw-r--r-- | sys/fs/nfs/nfs_var.h | 17 | ||||
-rw-r--r-- | sys/fs/nfs/nfsport.h | 7 | ||||
-rw-r--r-- | sys/fs/nfs/nfsproto.h | 13 |
5 files changed, 65 insertions, 18 deletions
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 0ae3b94bef89..1e4e8506790f 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -239,6 +239,7 @@ static bool nfscl_use_gss[NFSV42_NPROCS] = { true, true, true, + true, }; /* diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 67e33193ecec..7f5b29ca2085 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -187,7 +187,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = { { 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Read Plus */ { 0, 1, 0, 0, LK_SHARED, 1, 0 }, /* Seek */ { 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Write Same */ - { 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Clone */ + { 2, 1, 1, 0, LK_SHARED, 1, 0 }, /* Clone */ { 0, 1, 0, 0, LK_SHARED, 1, 1 }, /* Getxattr */ { 0, 1, 1, 1, LK_EXCLUSIVE, 1, 1 }, /* Setxattr */ { 0, 1, 0, 0, LK_SHARED, 1, 1 }, /* Listxattrs */ @@ -219,7 +219,7 @@ NFSD_VNET_DEFINE_STATIC(u_char *, nfsrv_dnsname) = NULL; static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }; + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }; /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); @@ -310,6 +310,7 @@ static struct { { NFSV4OP_LAYOUTERROR, 1, "LayoutError", 11, }, { NFSV4OP_VERIFY, 3, "AppendWrite", 11, }, { NFSV4OP_OPENATTR, 3, "OpenAttr", 8, }, + { NFSV4OP_SAVEFH, 5, "Clone", 5, }, }; /* @@ -319,7 +320,7 @@ static int nfs_bigrequest[NFSV42_NPROCS] = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0 + 0, 1, 0, 0 }; /* @@ -648,7 +649,7 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap, NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE); (void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0, &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL, - false, false, false); + false, false, false, 0); break; } } @@ -1302,7 +1303,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsv3_pathconf *pc, struct statfs *sbp, struct nfsstatfs *sfp, struct nfsfsinfo *fsp, NFSACL_T *aclp, int compare, int *retcmpp, u_int32_t *leasep, u_int32_t *rderrp, bool *has_namedattrp, - NFSPROC_T *p, struct ucred *cred) + uint32_t *clone_blksizep, NFSPROC_T *p, struct ucred *cred) { u_int32_t *tl; int i = 0, j, k, l = 0, m, bitpos, attrsum = 0; @@ -1437,6 +1438,13 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, NFSCLRBIT_ATTRBIT(&checkattrbits, NFSATTRBIT_SYSTEM); } + /* Some filesystems do not support block cloning */ + if (vp == NULL || VOP_PATHCONF(vp, + _PC_CLONE_BLKSIZE, &has_pathconf) != 0) + has_pathconf = 0; + if (has_pathconf == 0) + NFSCLRBIT_ATTRBIT(&checkattrbits, + NFSATTRBIT_CLONEBLKSIZE); if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits) || retnotsup) *retcmpp = NFSERR_NOTSAME; @@ -2374,6 +2382,23 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, if (compare && !(*retcmpp) && i != nfs_srvmaxio) *retcmpp = NFSERR_NOTSAME; break; + case NFSATTRBIT_CLONEBLKSIZE: + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + if (compare) { + if (!(*retcmpp)) { + if (vp == NULL || VOP_PATHCONF(vp, + _PC_CLONE_BLKSIZE, &has_pathconf) + != 0) + has_pathconf = 0; + if (has_pathconf != + fxdr_unsigned(uint32_t, *tl)) + *retcmpp = NFSERR_NOTSAME; + } + } else if (clone_blksizep != NULL) { + *clone_blksizep = fxdr_unsigned(uint32_t, *tl); + } + attrsum += NFSX_UNSIGNED; + break; case NFSATTRBIT_CHANGEATTRTYPE: NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); if (compare) { @@ -2648,7 +2673,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram, int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno, struct statfs *pnfssf, bool xattrsupp, bool has_hiddensystem, - bool has_namedattr) + bool has_namedattr, uint32_t clone_blksize) { int bitpos, retnum = 0; u_int32_t *tl; @@ -2771,6 +2796,9 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN); NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM); } + if (clone_blksize == 0) + NFSCLRBIT_ATTRBIT(&attrbits, + NFSATTRBIT_CLONEBLKSIZE); retnum += nfsrv_putattrbit(nd, &attrbits); break; case NFSATTRBIT_TYPE: @@ -3249,6 +3277,11 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, } retnum += NFSX_UNSIGNED; break; + case NFSATTRBIT_CLONEBLKSIZE: + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(clone_blksize); + retnum += NFSX_UNSIGNED; + break; default: printf("EEK! Bad V4 attribute bitpos=%d\n", bitpos); } diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 54f60a753c50..61083ecf2d66 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -286,6 +286,8 @@ int nfsrvd_deallocate(struct nfsrv_descript *, int, vnode_t, struct nfsexstuff *); int nfsrvd_copy_file_range(struct nfsrv_descript *, int, vnode_t, vnode_t, struct nfsexstuff *, struct nfsexstuff *); +int nfsrvd_clone(struct nfsrv_descript *, int, + vnode_t, vnode_t, struct nfsexstuff *, struct nfsexstuff *); int nfsrvd_seek(struct nfsrv_descript *, int, vnode_t, struct nfsexstuff *); int nfsrvd_getxattr(struct nfsrv_descript *, int, @@ -341,7 +343,8 @@ int nfsv4_loadattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, struct nfsfh **, fhandle_t *, int, struct nfsv3_pathconf *, struct statfs *, struct nfsstatfs *, struct nfsfsinfo *, NFSACL_T *, - int, int *, u_int32_t *, u_int32_t *, bool *, NFSPROC_T *, struct ucred *); + int, int *, u_int32_t *, u_int32_t *, bool *, uint32_t *, NFSPROC_T *, + struct ucred *); int nfsv4_lock(struct nfsv4lock *, int, int *, struct mtx *, struct mount *); void nfsv4_unlock(struct nfsv4lock *, int); void nfsv4_relref(struct nfsv4lock *); @@ -397,7 +400,7 @@ void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int, int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *, struct vattr *, fhandle_t *, int, nfsattrbit_t *, struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, struct statfs *, bool, bool, - bool); + bool, uint32_t); void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *); struct mbuf *nfsrv_adj(struct mbuf *, int, int); void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *); @@ -517,10 +520,10 @@ int nfsrpc_lock(struct nfsrv_descript *, struct nfsmount *, vnode_t, u_int8_t *, int, struct nfscllockowner *, int, int, u_int64_t, u_int64_t, short, struct ucred *, NFSPROC_T *, int); int nfsrpc_statfs(vnode_t, struct nfsstatfs *, struct nfsfsinfo *, uint32_t *, - struct ucred *, NFSPROC_T *, struct nfsvattr *, int *); + uint32_t *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *); int nfsrpc_fsinfo(vnode_t, struct nfsfsinfo *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *); -int nfsrpc_pathconf(vnode_t, struct nfsv3_pathconf *, bool *, +int nfsrpc_pathconf(vnode_t, struct nfsv3_pathconf *, bool *, uint32_t *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *); int nfsrpc_renew(struct nfsclclient *, struct nfsclds *, struct ucred *, NFSPROC_T *); @@ -562,6 +565,8 @@ int nfsrpc_deallocate(vnode_t, off_t, off_t, struct nfsvattr *, int *, int nfsrpc_copy_file_range(vnode_t, off_t *, vnode_t, off_t *, size_t *, unsigned int, int *, struct nfsvattr *, int *, struct nfsvattr *, struct ucred *, bool, bool *); +int nfsrpc_clone(vnode_t, off_t *, vnode_t, off_t *, size_t *, bool, + int *, struct nfsvattr *, int *, struct nfsvattr *, struct ucred *); int nfsrpc_seek(vnode_t, off_t *, bool *, int, struct ucred *, struct nfsvattr *, int *); int nfsrpc_getextattr(vnode_t, const char *, struct uio *, ssize_t *, @@ -668,7 +673,7 @@ int nfscl_nget(mount_t, vnode_t, struct nfsfh *, NFSPROC_T *nfscl_getparent(NFSPROC_T *); void nfscl_start_renewthread(struct nfsclclient *); void nfscl_loadsbinfo(struct nfsmount *, struct nfsstatfs *, void *); -void nfscl_loadfsinfo (struct nfsmount *, struct nfsfsinfo *); +void nfscl_loadfsinfo(struct nfsmount *, struct nfsfsinfo *, uint32_t); void nfscl_delegreturn(struct nfscldeleg *, int, struct nfsmount *, struct ucred *, NFSPROC_T *); void nfsrvd_cbinit(int); @@ -737,7 +742,7 @@ int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct nfsrv_descript *, int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *, struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, bool, bool, - bool); + bool, uint32_t); int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, NFSACL_T *, NFSPROC_T *); int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index c30b46261df0..bd6107187966 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -442,10 +442,13 @@ /* Do a NFSv4 Openattr. */ #define NFSPROC_OPENATTR 70 +/* Do a NFSv4.2 Clone. */ +#define NFSPROC_CLONE 71 + /* * Must be defined as one higher than the last NFSv4.2 Proc# above. */ -#define NFSV42_NPROCS 71 +#define NFSV42_NPROCS 72 /* Value of NFSV42_NPROCS for old nfsstats structure. (Always 69) */ #define NFSV42_OLDNPROCS 69 @@ -477,7 +480,7 @@ struct nfsstatsv1 { uint64_t readlink_bios; uint64_t biocache_readdirs; uint64_t readdir_bios; - uint64_t rpccnt[NFSV42_NPROCS + 9]; + uint64_t rpccnt[NFSV42_NPROCS + 8]; uint64_t rpcretries; uint64_t srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15]; uint64_t srvlayouts; diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index cb5a80e8df73..d628108bdc1a 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -411,10 +411,13 @@ /* Do a NFSv4 Openattr. */ #define NFSPROC_OPENATTR 70 +/* Do a NFSv4.2 Clone. */ +#define NFSPROC_CLONE 71 + /* * Must be defined as one higher than the last NFSv4.2 Proc# above. */ -#define NFSV42_NPROCS 71 +#define NFSV42_NPROCS 72 /* Value of NFSV42_NPROCS for old nfsstats structure. (Always 69) */ #define NFSV42_OLDNPROCS 69 @@ -1194,6 +1197,7 @@ struct nfsv3_sattr { NFSATTRBM_LAYOUTBLKSIZE | \ NFSATTRBM_LAYOUTALIGNMENT | \ NFSATTRBM_SUPPATTREXCLCREAT | \ + NFSATTRBM_CLONEBLKSIZE | \ NFSATTRBM_CHANGEATTRTYPE | \ NFSATTRBM_XATTRSUPPORT) @@ -1242,7 +1246,8 @@ struct nfsv3_sattr { * NFSATTRBIT_NFSV42 - Attributes only supported by NFSv4.2. */ #define NFSATTRBIT_NFSV42_2 \ - (NFSATTRBM_CHANGEATTRTYPE | \ + (NFSATTRBM_CLONEBLKSIZE | \ + NFSATTRBM_CHANGEATTRTYPE | \ NFSATTRBM_XATTRSUPPORT | \ NFSATTRBM_MODEUMASK) @@ -1415,7 +1420,7 @@ struct nfsv3_sattr { /* * NFSGETATTRBIT_STATFS2 - bits 64<->95 */ -#define NFSGETATTRBIT_STATFS2 0 +#define NFSGETATTRBIT_STATFS2 (NFSATTRBM_CLONEBLKSIZE) /* * Set of attributes for the equivalent of an nfsv3 pathconf rpc. @@ -1438,7 +1443,7 @@ struct nfsv3_sattr { /* * NFSGETATTRBIT_PATHCONF2 - bits 64<->95 */ -#define NFSGETATTRBIT_PATHCONF2 0 +#define NFSGETATTRBIT_PATHCONF2 (NFSATTRBM_CLONEBLKSIZE) /* * Sets of attributes required by readdir and readdirplus. |