FreeBSD Bugzilla – Attachment 192534 Details for
Bug 226493
ESX NFSv4.1 client can't perform the BindConnectiontoSession operation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Add partial support for BindConnectiontoSession to the NFSv4.1 server
bindconn.patch (text/plain), 9.89 KB, created by
Rick Macklem
on 2018-04-15 18:31:52 UTC
(
hide
)
Description:
Add partial support for BindConnectiontoSession to the NFSv4.1 server
Filename:
MIME Type:
Creator:
Rick Macklem
Created:
2018-04-15 18:31:52 UTC
Size:
9.89 KB
patch
obsolete
>--- fs/nfs/nfsrvstate.h.orig 2017-04-11 19:42:26.000000000 -0400 >+++ fs/nfs/nfsrvstate.h 2018-04-01 23:19:35.199728000 -0400 >@@ -101,6 +101,7 @@ struct nfsclient { > u_char *lc_name; > struct nfssockreq lc_req; /* Callback info */ > u_int32_t lc_flags; /* LCL_ flag bits */ >+ u_int32_t lc_sesscnt; /* Count of sessions. */ > u_char lc_verf[NFSX_VERF]; /* client verifier */ > u_char lc_id[1]; /* Malloc'd correct size */ > }; >--- fs/nfs/nfs.h.orig 2017-09-20 12:40:20.548481000 -0400 >+++ fs/nfs/nfs.h 2018-04-01 23:19:35.211237000 -0400 >@@ -128,6 +128,9 @@ > #ifndef NFS_ACCESSCACHESIZE > #define NFS_ACCESSCACHESIZE 8 > #endif >+#ifndef NFSRV_MAXCLIENTSESS >+#define NFSRV_MAXCLIENTSESS 32 >+#endif > #define NFSV4_CBPORT 7745 /* Callback port for testing */ > > /* >--- fs/nfs/nfsproto.h.orig 2017-06-24 08:11:01.471700000 -0400 >+++ fs/nfs/nfsproto.h 2018-04-01 23:19:35.217960000 -0400 >@@ -614,6 +614,9 @@ > #define NFSV4CRSESS_CONNBACKCHAN 0x00000002 > #define NFSV4CRSESS_CONNRDMA 0x00000004 > >+/* Local flags for sess_crflags (never on wire). */ >+#define NFSV4CRSESS_DONEBINDCONN 0x80000000 >+ > /* Flags for Sequence */ > #define NFSV4SEQ_CBPATHDOWN 0x00000001 > #define NFSV4SEQ_CBGSSCONTEXPIRING 0x00000002 >@@ -650,6 +653,15 @@ > #define NFSFLAYUTIL_DENSE 0x1 > #define NFSFLAYUTIL_COMMIT_THRU_MDS 0x2 > >+/* Enum values for Bind Connection to Session. */ >+#define NFSCDFC4_FORE 0x1 >+#define NFSCDFC4_BACK 0x2 >+#define NFSCDFC4_FORE_OR_BOTH 0x3 >+#define NFSCDFC4_BACK_OR_BOTH 0x7 >+#define NFSCDFS4_FORE 0x1 >+#define NFSCDFS4_BACK 0x2 >+#define NFSCDFS4_BOTH 0x3 >+ > /* Conversion macros */ > #define vtonfsv2_mode(t,m) \ > txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \ >--- fs/nfs/nfs_var.h.orig 2017-09-28 09:05:36.348898000 -0400 >+++ fs/nfs/nfs_var.h 2018-04-01 23:19:35.220243000 -0400 >@@ -95,6 +95,7 @@ int nfsrv_getclient(nfsquad_t, int, stru > nfsquad_t, uint32_t, struct nfsrv_descript *, NFSPROC_T *); > int nfsrv_destroyclient(nfsquad_t, NFSPROC_T *); > int nfsrv_destroysession(struct nfsrv_descript *, uint8_t *); >+int nfsrv_bindconnsess(struct nfsrv_descript *, uint8_t *, int *); > int nfsrv_freestateid(struct nfsrv_descript *, nfsv4stateid_t *, NFSPROC_T *); > int nfsrv_adminrevoke(struct nfsd_clid *, NFSPROC_T *); > void nfsrv_dumpclients(struct nfsd_dumpclients *, int); >@@ -230,6 +231,8 @@ int nfsrvd_reclaimcomplete(struct nfsrv_ > vnode_t, NFSPROC_T *, struct nfsexstuff *); > int nfsrvd_destroyclientid(struct nfsrv_descript *, int, > vnode_t, NFSPROC_T *, struct nfsexstuff *); >+int nfsrvd_bindconnsess(struct nfsrv_descript *, int, >+ vnode_t, NFSPROC_T *, struct nfsexstuff *); > int nfsrvd_destroysession(struct nfsrv_descript *, int, > vnode_t, NFSPROC_T *, struct nfsexstuff *); > int nfsrvd_freestateid(struct nfsrv_descript *, int, >--- fs/nfs/nfs_commonsubs.c.orig 2017-09-28 09:04:42.776196000 -0400 >+++ fs/nfs/nfs_commonsubs.c 2018-04-01 23:19:35.223260000 -0400 >@@ -136,7 +136,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV41_ > { 0, 2, 1, 1, LK_EXCLUSIVE, 1, 0 }, /* Write */ > { 0, 0, 0, 0, LK_EXCLUSIVE, 1, 0 }, /* ReleaseLockOwner */ > { 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Backchannel Ctrl */ >- { 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Bind Conn to Sess */ >+ { 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 }, /* Bind Conn to Sess */ > { 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 }, /* Exchange ID */ > { 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 }, /* Create Session */ > { 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 }, /* Destroy Session */ >--- fs/nfsserver/nfs_nfsdstate.c.orig 2017-04-24 16:40:27.000000000 -0400 >+++ fs/nfsserver/nfs_nfsdstate.c 2018-04-03 20:42:15.991767000 -0400 >@@ -582,6 +582,11 @@ nfsrv_getclient(nfsquad_t clientid, int > error = NFSERR_STALECLIENTID; > else if (nfsrv_notsamecredname(nd, clp)) > error = NFSERR_CLIDINUSE; >+ else if ((nd->nd_flag & ND_NFSV41) != 0 && nsep != NULL && >+ clp->lc_sesscnt > NFSRV_MAXCLIENTSESS) >+{ printf("Too many sessions\n"); >+ error = NFSERR_RESOURCE; >+} > > if (!error) { > if ((clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_DONTCLEAN)) == >@@ -614,10 +619,11 @@ nfsrv_getclient(nfsquad_t clientid, int > if (nsep != NULL) { > /* Hold a reference on the xprt for a backchannel. */ > if ((nsep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) >- != 0 && clp->lc_req.nr_client == NULL) { >- clp->lc_req.nr_client = (struct __rpc_client *) >- clnt_bck_create(nd->nd_xprt->xp_socket, >- cbprogram, NFSV4_CBVERS); >+ != 0) { >+ if (clp->lc_req.nr_client == NULL) >+ clp->lc_req.nr_client = (struct __rpc_client *) >+ clnt_bck_create(nd->nd_xprt->xp_socket, >+ cbprogram, NFSV4_CBVERS); > if (clp->lc_req.nr_client != NULL) { > SVC_ACQUIRE(nd->nd_xprt); > nd->nd_xprt->xp_p2 = >@@ -638,6 +644,7 @@ nfsrv_getclient(nfsquad_t clientid, int > LIST_INSERT_HEAD(&shp->list, nsep, sess_hash); > LIST_INSERT_HEAD(&clp->lc_session, nsep, sess_list); > nsep->sess_clp = clp; >+ clp->lc_sesscnt++; > NFSUNLOCKSESSION(shp); > NFSUNLOCKSTATE(); > } >@@ -4248,7 +4255,8 @@ nfsrv_docallback(struct nfsclient *clp, > error = newnfs_request(nd, NULL, clp, &clp->lc_req, > NULL, NULL, cred, clp->lc_program, > clp->lc_req.nr_vers, NULL, 1, NULL, NULL); >- } >+ } else if ((nd->nd_flag & ND_NFSV41) != 0 && sep != NULL) >+ nfsrv_freesession(sep, NULL); > errout: > NFSFREECRED(cred); > >@@ -5833,7 +5841,10 @@ nfsrv_checksequence(struct nfsrv_descrip > * RPC, since this is the one being used. > */ > if (sep->sess_clp->lc_req.nr_client != NULL && >- (sep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) != 0) { >+ sep->sess_cbsess.nfsess_xprt != nd->nd_xprt && >+ (sep->sess_crflags & (NFSV4CRSESS_CONNBACKCHAN | >+ NFSV4CRSESS_DONEBINDCONN)) == NFSV4CRSESS_CONNBACKCHAN) { >+printf("implicit bind backchan\n"); > savxprt = sep->sess_cbsess.nfsess_xprt; > SVC_ACQUIRE(nd->nd_xprt); > nd->nd_xprt->xp_p2 = >@@ -5950,6 +5961,75 @@ nfsrv_destroysession(struct nfsrv_descri > } > > /* >+ * Bind a connection to a session. >+ * For now, only certain variants are supported, since the current session >+ * structure can only handle a single backchannel entry, which will be >+ * applied to all connections if it is set. >+ */ >+int >+nfsrv_bindconnsess(struct nfsrv_descript *nd, uint8_t *sessionid, int *foreaftp) >+{ >+ struct nfssessionhash *shp; >+ struct nfsdsession *sep; >+ struct nfsclient *clp; >+ SVCXPRT *savxprt; >+ int error; >+ >+ error = 0; >+ shp = NFSSESSIONHASH(sessionid); >+ NFSLOCKSESSION(shp); >+ sep = nfsrv_findsession(sessionid); >+ if (sep != NULL) { >+ clp = sep->sess_clp; >+ if (*foreaftp == NFSCDFC4_BACK || >+ *foreaftp == NFSCDFC4_BACK_OR_BOTH || >+ *foreaftp == NFSCDFC4_FORE_OR_BOTH) { >+ /* Try to set up a backchannel. */ >+ if (clp->lc_req.nr_client == NULL) >+{ printf("nfsrv_bindconnsess: clnt_bck_create\n"); >+ clp->lc_req.nr_client = (struct __rpc_client *) >+ clnt_bck_create(nd->nd_xprt->xp_socket, >+ sep->sess_cbprogram, NFSV4_CBVERS); >+} >+ if (clp->lc_req.nr_client != NULL) { >+ savxprt = sep->sess_cbsess.nfsess_xprt; >+ SVC_ACQUIRE(nd->nd_xprt); >+ nd->nd_xprt->xp_p2 = >+ clp->lc_req.nr_client->cl_private; >+ /* Disable idle timeout. */ >+ nd->nd_xprt->xp_idletimeout = 0; >+ sep->sess_cbsess.nfsess_xprt = nd->nd_xprt; >+ if (savxprt != NULL) >+ SVC_RELEASE(savxprt); >+ sep->sess_crflags |= (NFSV4CRSESS_CONNBACKCHAN | >+ NFSV4CRSESS_DONEBINDCONN); >+ if (*foreaftp == NFSCDFS4_BACK) >+ *foreaftp = NFSCDFS4_BACK; >+ else >+ *foreaftp = NFSCDFS4_BOTH; >+printf("nfsrv_bindconnsess: Added backchannel\n"); >+ } else if (*foreaftp != NFSCDFC4_BACK) { >+printf("nfsrv_bindconnsess: No backchannel\n"); >+ sep->sess_crflags &= ~NFSV4CRSESS_CONNBACKCHAN; >+ sep->sess_crflags |= NFSV4CRSESS_DONEBINDCONN; >+ *foreaftp = NFSCDFS4_FORE; >+ } else { >+ error = NFSERR_NOTSUPP; >+ printf("nfsrv_bindconnsess: Can't add " >+ "backchannel\n"); >+ } >+ } else { >+printf("nfsrv_bindconnsess: Set forechannel\n"); >+ sep->sess_crflags |= NFSV4CRSESS_DONEBINDCONN; >+ *foreaftp = NFSCDFS4_FORE; >+ } >+ } else >+ error = NFSERR_BADSESSION; >+ NFSUNLOCKSESSION(shp); >+ return (error); >+} >+ >+/* > * Free up a session structure. > */ > static int >@@ -5976,6 +6056,7 @@ nfsrv_freesession(struct nfsdsession *se > } > LIST_REMOVE(sep, sess_hash); > LIST_REMOVE(sep, sess_list); >+ sep->sess_clp->lc_sesscnt--; > } > NFSUNLOCKSESSION(shp); > NFSUNLOCKSTATE(); >--- fs/nfsserver/nfs_nfsdserv.c.orig 2017-09-23 11:41:31.701643000 -0400 >+++ fs/nfsserver/nfs_nfsdserv.c 2018-04-01 23:19:35.231291000 -0400 >@@ -4041,6 +4041,45 @@ nfsmout: > } > > /* >+ * nfsv4 bind connection to session service >+ */ >+APPLESTATIC int >+nfsrvd_bindconnsess(struct nfsrv_descript *nd, __unused int isdgram, >+ __unused vnode_t vp, NFSPROC_T *p, __unused struct nfsexstuff *exp) >+{ >+ uint32_t *tl; >+ uint8_t sessid[NFSX_V4SESSIONID]; >+ int error = 0, foreaft; >+ >+ if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) { >+ nd->nd_repstat = NFSERR_WRONGSEC; >+ goto nfsmout; >+ } >+ NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + 2 * NFSX_UNSIGNED); >+ NFSBCOPY(tl, sessid, NFSX_V4SESSIONID); >+ tl += (NFSX_V4SESSIONID / NFSX_UNSIGNED); >+ foreaft = fxdr_unsigned(int, *tl++); >+ if (*tl == newnfs_true) { >+ /* RDMA is not supported. */ >+ nd->nd_repstat = NFSERR_NOTSUPP; >+ goto nfsmout; >+ } >+ >+ nd->nd_repstat = nfsrv_bindconnsess(nd, sessid, &foreaft); >+ if (nd->nd_repstat == 0) { >+ NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 2 * >+ NFSX_UNSIGNED); >+ NFSBCOPY(sessid, tl, NFSX_V4SESSIONID); >+ tl += (NFSX_V4SESSIONID / NFSX_UNSIGNED); >+ *tl++ = txdr_unsigned(foreaft); >+ *tl = newnfs_false; >+ } >+nfsmout: >+ NFSEXITCODE2(error, nd); >+ return (error); >+} >+ >+/* > * nfsv4 destroy session service > */ > APPLESTATIC int >--- fs/nfsserver/nfs_nfsdsocket.c.orig 2017-04-11 19:42:27.000000000 -0400 >+++ fs/nfsserver/nfs_nfsdsocket.c 2018-04-01 23:19:35.233560000 -0400 >@@ -176,7 +176,7 @@ int (*nfsrv4_ops0[NFSV41_NOPS])(struct n > nfsrvd_write, > nfsrvd_releaselckown, > nfsrvd_notsupp, >- nfsrvd_notsupp, >+ nfsrvd_bindconnsess, > nfsrvd_exchangeid, > nfsrvd_createsession, > nfsrvd_destroysession,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 226493
:
191364
|
192534
|
192666