Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 May 2018 22:16:24 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r333508 - in head/sys/fs: nfs nfsserver
Message-ID:  <201805112216.w4BMGOV8003768@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Fri May 11 22:16:23 2018
New Revision: 333508
URL: https://svnweb.freebsd.org/changeset/base/333508

Log:
  Add support for the TestStateID operation to the NFSv4.1 server.
  
  The Linux client now uses the TestStateID operation, so this patch adds
  support for it to the NFSv4.1 server. The FreeBSD client never uses this
  operation, so it should not be affected.
  
  MFC after:	2 months

Modified:
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfsserver/nfs_nfsdserv.c
  head/sys/fs/nfsserver/nfs_nfsdsocket.c
  head/sys/fs/nfsserver/nfs_nfsdstate.c

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Fri May 11 21:56:01 2018	(r333507)
+++ head/sys/fs/nfs/nfs_var.h	Fri May 11 22:16:23 2018	(r333508)
@@ -98,6 +98,7 @@ int nfsrv_getclient(nfsquad_t, int, struct nfsclient *
 int nfsrv_destroyclient(nfsquad_t, NFSPROC_T *);
 int nfsrv_destroysession(struct nfsrv_descript *, uint8_t *);
 int nfsrv_freestateid(struct nfsrv_descript *, nfsv4stateid_t *, NFSPROC_T *);
+int nfsrv_teststateid(struct nfsrv_descript *, nfsv4stateid_t *, NFSPROC_T *);
 int nfsrv_adminrevoke(struct nfsd_clid *, NFSPROC_T *);
 void nfsrv_dumpclients(struct nfsd_dumpclients *, int);
 void nfsrv_dumplocks(vnode_t, struct nfsd_dumplocks *, int, NFSPROC_T *);
@@ -235,6 +236,8 @@ int nfsrvd_destroyclientid(struct nfsrv_descript *, in
 int nfsrvd_destroysession(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);
 int nfsrvd_freestateid(struct nfsrv_descript *, int,
+    vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_teststateid(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);
 int nfsrvd_notsupp(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);

Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c	Fri May 11 21:56:01 2018	(r333507)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c	Fri May 11 22:16:23 2018	(r333508)
@@ -4101,6 +4101,50 @@ nfsmout:
 }
 
 /*
+ * nfsv4 test stateid service
+ */
+APPLESTATIC int
+nfsrvd_teststateid(struct nfsrv_descript *nd, __unused int isdgram,
+    __unused vnode_t vp, NFSPROC_T *p, __unused struct nfsexstuff *exp)
+{
+	uint32_t *tl;
+	nfsv4stateid_t *stateidp = NULL, *tstateidp;
+	int cnt, error = 0, i, ret;
+
+	if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) {
+		nd->nd_repstat = NFSERR_WRONGSEC;
+		goto nfsmout;
+	}
+	NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+	cnt = fxdr_unsigned(int, *tl);
+	if (cnt <= 0 || cnt > 1024) {
+		nd->nd_repstat = NFSERR_BADXDR;
+		goto nfsmout;
+	}
+	stateidp = mallocarray(cnt, sizeof(nfsv4stateid_t), M_TEMP, M_WAITOK);
+	tstateidp = stateidp;
+	for (i = 0; i < cnt; i++) {
+		NFSM_DISSECT(tl, uint32_t *, NFSX_STATEID);
+		tstateidp->seqid = fxdr_unsigned(uint32_t, *tl++);
+		NFSBCOPY(tl, tstateidp->other, NFSX_STATEIDOTHER);
+		tstateidp++;
+	}
+	NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+	*tl = txdr_unsigned(cnt);
+	tstateidp = stateidp;
+	for (i = 0; i < cnt; i++) {
+		ret = nfsrv_teststateid(nd, tstateidp, p);
+		NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+		*tl = txdr_unsigned(ret);
+		tstateidp++;
+	}
+nfsmout:
+	free(stateidp, M_TEMP);
+	NFSEXITCODE2(error, nd);
+	return (error);
+}
+
+/*
  * nfsv4 service not supported
  */
 APPLESTATIC int

Modified: head/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdsocket.c	Fri May 11 21:56:01 2018	(r333507)
+++ head/sys/fs/nfsserver/nfs_nfsdsocket.c	Fri May 11 22:16:23 2018	(r333508)
@@ -192,7 +192,7 @@ int (*nfsrv4_ops0[NFSV41_NOPS])(struct nfsrv_descript 
 	nfsrvd_notsupp,
 	nfsrvd_sequence,
 	nfsrvd_notsupp,
-	nfsrvd_notsupp,
+	nfsrvd_teststateid,
 	nfsrvd_notsupp,
 	nfsrvd_destroyclientid,
 	nfsrvd_reclaimcomplete,

Modified: head/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdstate.c	Fri May 11 21:56:01 2018	(r333507)
+++ head/sys/fs/nfsserver/nfs_nfsdstate.c	Fri May 11 22:16:23 2018	(r333508)
@@ -6050,6 +6050,32 @@ nfsrv_freestateid(struct nfsrv_descript *nd, nfsv4stat
 }
 
 /*
+ * Test a stateid.
+ */
+int
+nfsrv_teststateid(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp,
+    NFSPROC_T *p)
+{
+	struct nfsclient *clp;
+	struct nfsstate *stp;
+	int error;
+
+	NFSLOCKSTATE();
+	/*
+	 * Look up the stateid
+	 */
+	error = nfsrv_getclient((nfsquad_t)((u_quad_t)0), CLOPS_RENEW, &clp,
+	    NULL, (nfsquad_t)((u_quad_t)0), 0, nd, p);
+	if (error == 0)
+		error = nfsrv_getstate(clp, stateidp, 0, &stp);
+	if (error == 0 && stateidp->seqid != 0 &&
+	    SEQ_LT(stateidp->seqid, stp->ls_stateid.seqid))
+		error = NFSERR_OLDSTATEID;
+	NFSUNLOCKSTATE();
+	return (error);
+}
+
+/*
  * Generate the xdr for an NFSv4.1 CBSequence Operation.
  */
 static int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805112216.w4BMGOV8003768>