svn commit: r338812 - in projects/nfsv42/sys/fs: nfs nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Wed Sep 19 22:39:42 UTC 2018
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;
More information about the svn-src-projects
mailing list