Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Sep 2018 22:39:40 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r338812 - in projects/nfsv42/sys/fs: nfs nfsserver
Message-ID:  <201809192239.w8JMdeag047800@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Wed Sep 19 22:39:40 2018
New Revision: 338812
URL: https://svnweb.freebsd.org/changeset/base/338812

Log:
  Add the Layout Error operation to the NFSv4.2. server.

Modified:
  projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c
  projects/nfsv42/sys/fs/nfs/nfs_var.h
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdstate.c

Modified: projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c	Wed Sep 19 21:18:44 2018	(r338811)
+++ projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c	Wed Sep 19 22:39:40 2018	(r338812)
@@ -171,7 +171,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = {
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Copy Notify */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Deallocate */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* IO Advise */
-	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Layout Error */
+	{ 0, 1, 0, 1, LK_EXCLUSIVE, 1, 0 },		/* Layout Error */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Layout Stats */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Offload Cancel */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Offload Status */

Modified: projects/nfsv42/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfs_var.h	Wed Sep 19 21:18:44 2018	(r338811)
+++ projects/nfsv42/sys/fs/nfs/nfs_var.h	Wed Sep 19 22:39:40 2018	(r338812)
@@ -161,6 +161,7 @@ void nfsrv_freealllayoutsanddevids(void);
 void nfsrv_freefilelayouts(fhandle_t *);
 int nfsrv_deldsserver(int, char *, NFSPROC_T *);
 struct nfsdevice *nfsrv_deldsnmp(int, struct nfsmount *, NFSPROC_T *);
+int nfsrv_delds(char *, NFSPROC_T *);
 int nfsrv_createdevids(struct nfsd_nfsd_args *, NFSPROC_T *);
 int nfsrv_checkdsattr(struct nfsrv_descript *, vnode_t, NFSPROC_T *);
 int nfsrv_copymr(vnode_t, vnode_t, vnode_t, struct nfsdevice *,
@@ -275,6 +276,8 @@ int nfsrvd_getdevinfo(struct nfsrv_descript *, int,
 int nfsrvd_layoutcommit(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);
 int nfsrvd_layoutreturn(struct nfsrv_descript *, int,
+    vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_layouterror(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);
 int nfsrvd_teststateid(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Wed Sep 19 21:18:44 2018	(r338811)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Wed Sep 19 22:39:40 2018	(r338812)
@@ -4654,6 +4654,72 @@ nfsmout:
 }
 
 /*
+ * nfsv4 layout error service
+ */
+APPLESTATIC int
+nfsrvd_layouterror(struct nfsrv_descript *nd, __unused int isdgram,
+    vnode_t vp, NFSPROC_T *p, struct nfsexstuff *exp)
+{
+	uint32_t *tl;
+	nfsv4stateid_t stateid;
+	int cnt, error = 0, i, opnum, stat;
+	char devid[NFSX_V4DEVICEID];
+	uint64_t offset, len;
+
+	if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) {
+		nd->nd_repstat = NFSERR_WRONGSEC;
+		goto nfsmout;
+	}
+	NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_HYPER + NFSX_STATEID +
+	    NFSX_UNSIGNED);
+	offset = fxdr_hyper(tl); tl += 2;
+	len = fxdr_hyper(tl); tl += 2;
+	stateid.seqid = fxdr_unsigned(uint32_t, *tl++);
+	NFSBCOPY(tl, stateid.other, NFSX_STATEIDOTHER);
+	tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED);
+	cnt = fxdr_unsigned(int, *tl);
+	NFSD_DEBUG(4, "layouterror off=%ju len=%ju cnt=%d\n", (uintmax_t)offset,
+	    (uintmax_t)len, cnt);
+	/*
+	 * For the special stateid of other all 0s and seqid == 1, set
+	 * the stateid to the current stateid, if it is set.
+	 */
+	if (stateid.seqid == 1 && stateid.other[0] == 0 &&
+	    stateid.other[1] == 0 && stateid.other[2] == 0) {
+		if ((nd->nd_flag & ND_CURSTATEID) != 0) {
+			stateid = nd->nd_curstateid;
+			stateid.seqid = 0;
+		} else {
+			nd->nd_repstat = NFSERR_BADSTATEID;
+			goto nfsmout;
+		}
+	}
+
+	/*
+	 * Ignore offset, len and stateid for now.
+	 */
+	for (i = 0; i < cnt; i++) {
+		NFSM_DISSECT(tl, uint32_t *, NFSX_V4DEVICEID + 2 *
+		    NFSX_UNSIGNED);
+		NFSBCOPY(tl, devid, NFSX_V4DEVICEID);
+		tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED);
+		stat = fxdr_unsigned(int, *tl++);
+		opnum = fxdr_unsigned(int, *tl);
+		NFSD_DEBUG(4, "nfsrvd_layouterr op=%d stat=%d\n", opnum, stat);
+		/*
+		 * Except for NFSERR_ACCES and NFSERR_STALE errors,
+		 * disable the mirror.
+		 */
+		if (stat != NFSERR_ACCES && stat != NFSERR_STALE)
+			nfsrv_delds(devid, p);
+	}
+nfsmout:
+	vput(vp);
+	NFSEXITCODE2(error, nd);
+	return (error);
+}
+
+/*
  * nfsv4 getdeviceinfo service
  */
 APPLESTATIC int

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c	Wed Sep 19 21:18:44 2018	(r338811)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c	Wed Sep 19 22:39:40 2018	(r338812)
@@ -203,7 +203,7 @@ int (*nfsrv4_ops0[NFSV42_NOPS])(struct nfsrv_descript 
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
-	nfsrvd_notsupp,
+	nfsrvd_layouterror,
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdstate.c	Wed Sep 19 21:18:44 2018	(r338811)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdstate.c	Wed Sep 19 22:39:40 2018	(r338812)
@@ -213,7 +213,6 @@ static void nfsrv_freealllayouts(void);
 static void nfsrv_freedevid(struct nfsdevice *ds);
 static int nfsrv_setdsserver(char *dspathp, char *mdspathp, NFSPROC_T *p,
     struct nfsdevice **dsp);
-static int nfsrv_delds(char *devid, NFSPROC_T *p);
 static void nfsrv_deleteds(struct nfsdevice *fndds);
 static void nfsrv_allocdevid(struct nfsdevice *ds, char *addr, char *dnshost);
 static void nfsrv_freealldevids(void);
@@ -7575,7 +7574,7 @@ nfsrv_deldsnmp(int op, struct nfsmount *nmp, NFSPROC_T
  * point.
  * Also, returns an error instead of the nfsdevice found.
  */
-static int
+APPLESTATIC int
 nfsrv_delds(char *devid, NFSPROC_T *p)
 {
 	struct nfsdevice *ds, *fndds;



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