svn commit: r350884 - in projects/nfsv42/sys/fs: nfs nfsclient nfsserver

Rick Macklem rmacklem at FreeBSD.org
Mon Aug 12 05:25:42 UTC 2019


Author: rmacklem
Date: Mon Aug 12 05:25:40 2019
New Revision: 350884
URL: https://svnweb.freebsd.org/changeset/base/350884

Log:
  Add support for the Seek operation to the NFSv4.2 client and server.

Modified:
  projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c
  projects/nfsv42/sys/fs/nfs/nfs_var.h
  projects/nfsv42/sys/fs/nfs/nfsport.h
  projects/nfsv42/sys/fs/nfs/nfsproto.h
  projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c
  projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c

Modified: projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c	Mon Aug 12 05:25:40 2019	(r350884)
@@ -177,7 +177,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = {
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Offload Cancel */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Offload Status */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Read Plus */
-	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Seek */
+	{ 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 */
 };
@@ -206,7 +206,7 @@ static struct nfsrv_lughash	*nfsgroupnamehash;
  */
 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
 
 /* local functions */
 static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep);
@@ -283,6 +283,7 @@ static struct {
 	{ NFSV4OP_IOADVISE, 1, "Advise", 6, },
 	{ NFSV4OP_ALLOCATE, 2, "Allocate", 8, },
 	{ NFSV4OP_SAVEFH, 5, "Copy", 4, },
+	{ NFSV4OP_SEEK, 2, "Seek", 4, },
 };
 
 /*
@@ -291,7 +292,7 @@ static struct {
 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, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
 /*

Modified: projects/nfsv42/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfs_var.h	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfs/nfs_var.h	Mon Aug 12 05:25:40 2019	(r350884)
@@ -281,6 +281,8 @@ int nfsrvd_allocate(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_seek(struct nfsrv_descript *, int,
+    vnode_t, struct nfsexstuff *);
 int nfsrvd_notsupp(struct nfsrv_descript *, int,
     vnode_t, struct nfsexstuff *);
 
@@ -540,6 +542,8 @@ int nfsrpc_allocate(vnode_t, off_t, off_t, struct nfsv
 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_seek(vnode_t, off_t *, bool *, int, struct ucred *,
+    struct nfsvattr *, int *);
 
 /* nfs_clstate.c */
 int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int,

Modified: projects/nfsv42/sys/fs/nfs/nfsport.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfsport.h	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfs/nfsport.h	Mon Aug 12 05:25:40 2019	(r350884)
@@ -397,11 +397,12 @@
 #define	NFSPROC_IOADVISE	56
 #define	NFSPROC_ALLOCATE	57
 #define	NFSPROC_COPY		58
+#define	NFSPROC_SEEK		59
 
 /*
  * Must be defined as one higher than the last NFSv4.2 Proc# above.
  */
-#define	NFSV42_NPROCS		59
+#define	NFSV42_NPROCS		60
 
 #endif	/* NFS_V3NPROCS */
 
@@ -430,7 +431,7 @@ struct nfsstatsv1 {
 	uint64_t	readlink_bios;
 	uint64_t	biocache_readdirs;
 	uint64_t	readdir_bios;
-	uint64_t	rpccnt[NFSV42_NPROCS + 10];
+	uint64_t	rpccnt[NFSV42_NPROCS + 9];
 	uint64_t	rpcretries;
 	uint64_t	srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS];
 	uint64_t	srvrpc_errs;

Modified: projects/nfsv42/sys/fs/nfs/nfsproto.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfsproto.h	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfs/nfsproto.h	Mon Aug 12 05:25:40 2019	(r350884)
@@ -381,11 +381,12 @@
 #define	NFSPROC_IOADVISE	56
 #define	NFSPROC_ALLOCATE	57
 #define	NFSPROC_COPY		58
+#define	NFSPROC_SEEK		59
 
 /*
  * Must be defined as one higher than the last NFSv4.2 Proc# above.
  */
-#define	NFSV42_NPROCS		59
+#define	NFSV42_NPROCS		60
 
 #endif	/* NFS_V3NPROCS */
 
@@ -1477,5 +1478,9 @@ typedef struct nfsv4stateid nfsv4stateid_t;
 #define	NFSV4LAYOUTRET_FILE	1
 #define	NFSV4LAYOUTRET_FSID	2
 #define	NFSV4LAYOUTRET_ALL	3
+
+/* Seek Contents. */
+#define	NFSV4CONTENT_DATA	0
+#define	NFSV4CONTENT_HOLE	1
 
 #endif	/* _NFS_NFSPROTO_H_ */

Modified: projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c	Mon Aug 12 05:25:40 2019	(r350884)
@@ -216,6 +216,8 @@ static int nfsrpc_layoutgetres(struct nfsmount *, vnod
 static int nfsrpc_copyrpc(vnode_t, off_t, vnode_t, off_t, size_t *,
     nfsv4stateid_t *, nfsv4stateid_t *, struct nfsvattr *, int *,
     struct nfsvattr *, int *, bool, int *, struct ucred *, NFSPROC_T *);
+static int nfsrpc_seekrpc(vnode_t, off_t *, nfsv4stateid_t *, bool *,
+    int, struct nfsvattr *, int *, struct ucred *);
 
 int nfs_pnfsio(task_fn_t *, void *);
 
@@ -8139,6 +8141,100 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outv
 	}
 	if (error == 0)
 		error = nd->nd_repstat;
+nfsmout:
+	mbuf_freem(nd->nd_mrep);
+	return (error);
+}
+
+/*
+ * Seek operation.
+ */
+APPLESTATIC int
+nfsrpc_seek(vnode_t vp, off_t *offp, bool *eofp, int content,
+    struct ucred *cred, struct nfsvattr *nap, int *attrflagp)
+{
+	int error, expireret = 0, retrycnt;
+	u_int32_t clidrev = 0;
+	struct nfsmount *nmp = VFSTONFS(vnode_mount(vp));
+	struct nfsnode *np = VTONFS(vp);
+	struct nfsfh *nfhp = NULL;
+	nfsv4stateid_t stateid;
+	void *lckp;
+
+	if (nmp->nm_clp != NULL)
+		clidrev = nmp->nm_clp->nfsc_clientidrev;
+	nfhp = np->n_fhp;
+	retrycnt = 0;
+	do {
+		lckp = NULL;
+		nfscl_getstateid(vp, nfhp->nfh_fh, nfhp->nfh_len,
+		    NFSV4OPEN_ACCESSREAD, 0, cred, curthread, &stateid, &lckp);
+		error = nfsrpc_seekrpc(vp, offp, &stateid, eofp, content,
+		    nap, attrflagp, cred);
+		if (error == NFSERR_STALESTATEID)
+			nfscl_initiate_recovery(nmp->nm_clp);
+		if (lckp != NULL)
+			nfscl_lockderef(lckp);
+		if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
+		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
+		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
+			(void) nfs_catnap(PZERO, error, "nfs_seek");
+		} else if ((error == NFSERR_EXPIRED ||
+		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev,
+			    curthread);
+		}
+		retrycnt++;
+	} while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
+	    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
+	    error == NFSERR_BADSESSION ||
+	    (error == NFSERR_OLDSTATEID && retrycnt < 20) ||
+	    ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) &&
+	     expireret == 0 && clidrev != 0 && retrycnt < 4) ||
+	    (error == NFSERR_OPENMODE && retrycnt < 4));
+	if (error && retrycnt >= 4)
+		error = EIO;
+	return (error);
+}
+
+/*
+ * The seek RPC.
+ */
+static int
+nfsrpc_seekrpc(vnode_t vp, off_t *offp, nfsv4stateid_t *stateidp, bool *eofp,
+    int content, struct nfsvattr *nap, int *attrflagp, struct ucred *cred)
+{
+	uint32_t *tl;
+	int error;
+	struct nfsrv_descript nfsd;
+	struct nfsrv_descript *nd = &nfsd;
+	nfsattrbit_t attrbits;
+
+	*attrflagp = 0;
+	NFSCL_REQSTART(nd, NFSPROC_SEEK, vp);
+	nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID);
+	NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED);
+	txdr_hyper(*offp, tl); tl += 2;
+	*tl++ = txdr_unsigned(content);
+	*tl = txdr_unsigned(NFSV4OP_GETATTR);
+	NFSGETATTR_ATTRBIT(&attrbits);
+	nfsrv_putattrbit(nd, &attrbits);
+	error = nfscl_request(nd, vp, curthread, cred, NULL);
+	if (error != 0)
+		return (error);
+	if (nd->nd_repstat == 0) {
+		NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_UNSIGNED + NFSX_HYPER);
+		if (*tl++ == newnfs_true)
+			*eofp = true;
+		else
+			*eofp = false;
+		*offp = fxdr_hyper(tl);
+		/* Just skip over Getattr op status. */
+		error = nfsm_loadattr(nd, nap);
+		if (error == 0)
+			*attrflagp = 1;
+	}
+	error = nd->nd_repstat;
 nfsmout:
 	mbuf_freem(nd->nd_mrep);
 	return (error);

Modified: projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Mon Aug 12 05:25:40 2019	(r350884)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mount.h>
 #include <sys/bio.h>
 #include <sys/buf.h>
+#include <sys/filio.h>
 #include <sys/jail.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
@@ -145,6 +146,7 @@ static vop_setacl_t nfs_setacl;
 static vop_advise_t nfs_advise;
 static vop_allocate_t nfs_allocate;
 static vop_copy_file_range_t nfs_copy_file_range;
+static vop_ioctl_t nfs_ioctl;
 
 /*
  * Global vfs data structures for nfs
@@ -185,6 +187,7 @@ static struct vop_vector newnfs_vnodeops_nosig = {
 	.vop_advise =		nfs_advise,
 	.vop_allocate =		nfs_allocate,
 	.vop_copy_file_range =	nfs_copy_file_range,
+	.vop_ioctl =		nfs_ioctl,
 };
 
 static int
@@ -3678,6 +3681,67 @@ nfs_copy_file_range(struct vop_copy_file_range_args *a
 
 	if (error != 0)
 		error = nfscl_maperr(curthread, error, (uid_t)0, (gid_t)0);
+	return (error);
+}
+
+/*
+ * nfs ioctl call
+ */
+static int
+nfs_ioctl(struct vop_ioctl_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct nfsvattr nfsva;
+	struct nfsmount *nmp;
+	int attrflag, content, error, ret;
+	bool eof;
+
+	if (vp->v_type != VREG)
+		return (ENOTTY);
+	nmp = VFSTONFS(vp->v_mount);
+	if (!NFSHASNFSV4(nmp) || nmp->nm_minorvers < NFSV42_MINORVERSION) {
+#ifdef notyet
+		error = vop_stdioctl(ap);
+#else
+		error = ENOTTY;
+#endif
+		return (error);
+	}
+
+	error = vn_lock(vp, LK_SHARED);
+	if (error != 0)
+		return (EBADF);
+
+	/* Do the actual NFSv4.2 RPC. */
+	switch (ap->a_command) {
+	case FIOSEEKDATA:
+		content = NFSV4CONTENT_DATA;
+		break;
+	case FIOSEEKHOLE:
+		content = NFSV4CONTENT_HOLE;
+		break;
+	default:
+		return (ENOTTY);
+	}
+	attrflag = 0;
+	if (*((off_t *)ap->a_data) >= VTONFS(vp)->n_size)
+		error = ENXIO;
+	else {
+		error = nfsrpc_seek(vp, (off_t *)ap->a_data, &eof, content,
+		    ap->a_cred, &nfsva, &attrflag);
+		/* If at eof for FIOSEEKDATA, return ENXIO. */
+		if (eof && error == 0 && content == NFSV4CONTENT_DATA)
+			error = ENXIO;
+	}
+	if (attrflag != 0) {
+		ret = nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
+		if (error == 0 && ret != 0)
+			error = ret;
+	}
+	NFSVOPUNLOCK(vp, 0);
+
+	if (error != 0)
+		error = ENXIO;
 	return (error);
 }
 

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Mon Aug 12 05:25:40 2019	(r350884)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 
 #ifndef APPLEKEXT
 #include <fs/nfs/nfsport.h>
+#include <sys/filio.h>
 
 /* Global vars */
 extern u_int32_t newnfs_false, newnfs_true;
@@ -5190,7 +5191,7 @@ nfsmout:
  * nfs copy service
  */
 APPLESTATIC int
-nfsrvd_copy_file_range(struct nfsrv_descript *nd, int isdgram,
+nfsrvd_copy_file_range(struct nfsrv_descript *nd, __unused int isdgram,
     vnode_t vp, vnode_t tovp, struct nfsexstuff *exp, struct nfsexstuff *toexp)
 {
 	uint32_t *tl;
@@ -5226,7 +5227,7 @@ nfsrvd_copy_file_range(struct nfsrv_descript *nd, int 
 	instp->ls_ownerlen = 0;
 	instp->ls_op = NULL;
 	instp->ls_uid = nd->nd_cred->cr_uid;
-	instp->ls_stateid.seqid = fxdr_unsigned(u_int32_t, *tl++);
+	instp->ls_stateid.seqid = fxdr_unsigned(uint32_t, *tl++);
 	clientid.lval[0] = instp->ls_stateid.other[0] = *tl++;
 	clientid.lval[1] = instp->ls_stateid.other[1] = *tl++;
 	if ((nd->nd_flag & ND_IMPLIEDCLID) != 0)
@@ -5237,7 +5238,7 @@ nfsrvd_copy_file_range(struct nfsrv_descript *nd, int 
 	outstp->ls_ownerlen = 0;
 	outstp->ls_op = NULL;
 	outstp->ls_uid = nd->nd_cred->cr_uid;
-	outstp->ls_stateid.seqid = fxdr_unsigned(u_int32_t, *tl++);
+	outstp->ls_stateid.seqid = fxdr_unsigned(uint32_t, *tl++);
 	outstp->ls_stateid.other[0] = *tl++;
 	outstp->ls_stateid.other[1] = *tl++;
 	outstp->ls_stateid.other[2] = *tl++;
@@ -5398,6 +5399,98 @@ out:
 nfsmout:
 	vput(vp);
 	vrele(tovp);
+	NFSEXITCODE2(error, nd);
+	return (error);
+}
+
+/*
+ * nfs seek service
+ */
+APPLESTATIC int
+nfsrvd_seek(struct nfsrv_descript *nd, __unused int isdgram,
+    vnode_t vp, struct nfsexstuff *exp)
+{
+	uint32_t *tl;
+	struct nfsvattr at;
+	int content, error = 0;
+	off_t off;
+	u_long cmd;
+	nfsattrbit_t attrbits;
+
+	if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) {
+		nd->nd_repstat = NFSERR_WRONGSEC;
+		goto nfsmout;
+	}
+	if (nfsrv_devidcnt > 0) {
+		nd->nd_repstat = NFSERR_NOTSUPP;
+		goto nfsmout;
+	}
+	NFSM_DISSECT(tl, uint32_t *, NFSX_STATEID + NFSX_HYPER + NFSX_UNSIGNED);
+	/* Ignore the stateid for now. */
+	tl += (NFSX_STATEID / NFSX_UNSIGNED);
+	off = fxdr_hyper(tl); tl += 2;
+	content = fxdr_unsigned(int, *tl);
+	if (content == NFSV4CONTENT_DATA)
+		cmd = FIOSEEKDATA;
+	else if (content == NFSV4CONTENT_HOLE)
+		cmd = FIOSEEKHOLE;
+	else
+		nd->nd_repstat = NFSERR_BADXDR;
+	if (nd->nd_repstat == 0 && (nd->nd_flag & ND_DSSERVER) != 0)
+		nd->nd_repstat = NFSERR_NOTSUPP;
+	if (nd->nd_repstat == 0 && vnode_vtype(vp) == VDIR)
+		nd->nd_repstat = NFSERR_ISDIR;
+	if (nd->nd_repstat == 0 && vnode_vtype(vp) != VREG)
+		nd->nd_repstat = NFSERR_WRONGTYPE;
+	if (nd->nd_repstat == 0 && off < 0)
+		nd->nd_repstat = NFSERR_NXIO;
+	if (nd->nd_repstat == 0) {
+		/* Check permissions for the input file. */
+		NFSZERO_ATTRBIT(&attrbits);
+		NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNER);
+		NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE);
+		nd->nd_repstat = nfsvno_getattr(vp, &at, nd, curthread, 1,
+		    &attrbits);
+	}
+	if (nd->nd_repstat == 0 && off > at.na_size)
+		nd->nd_repstat = NFSERR_NXIO;
+	if (nd->nd_repstat == 0 && (at.na_uid != nd->nd_cred->cr_uid ||
+	     NFSVNO_EXSTRICTACCESS(exp)))
+		nd->nd_repstat = nfsvno_accchk(vp, VREAD, nd->nd_cred, exp,
+		    curthread, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED,
+		    NULL);
+	if (nd->nd_repstat != 0)
+		goto nfsmout;
+
+	if (off < at.na_size) {
+		NFSVOPUNLOCK(vp, 0);
+		nd->nd_repstat = VOP_IOCTL(vp, cmd, &off, 0, nd->nd_cred,
+		    curthread);
+		vrele(vp);
+		if (nd->nd_repstat == ENOTTY || nd->nd_repstat == ENXIO) {
+			/*
+			 * For FIOSEEKHOLE, find the "virtual hole" at EOF.
+			 * For FIOSEEKDATA, just return the offset in the
+			 * request unless the error is ENXIO.
+			 */
+			if (cmd == FIOSEEKHOLE || error == ENXIO)
+				off = at.na_size;
+			nd->nd_repstat = 0;
+		}
+	} else
+		vput(vp);
+	if (nd->nd_repstat == 0) {
+		NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED + NFSX_HYPER);
+		if (off == at.na_size)
+			*tl++ = newnfs_true;
+		else
+			*tl++ = newnfs_false;
+		txdr_hyper(off, tl);
+	}
+	NFSEXITCODE2(error, nd);
+	return (error);
+nfsmout:
+	vput(vp);
 	NFSEXITCODE2(error, nd);
 	return (error);
 }

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c	Mon Aug 12 03:03:56 2019	(r350883)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c	Mon Aug 12 05:25:40 2019	(r350884)
@@ -206,7 +206,7 @@ int (*nfsrv4_ops0[NFSV42_NOPS])(struct nfsrv_descript 
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
-	nfsrvd_notsupp,
+	nfsrvd_seek,
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
 };


More information about the svn-src-projects mailing list