Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109446713
D29475.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D29475.diff
View Options
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -218,7 +218,7 @@
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,
- 1, 0, 0, 1 };
+ 1, 0, 0, 1, 0 };
/* local functions */
static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep);
@@ -301,6 +301,7 @@
{ NFSV4OP_SETXATTR, 2, "Setxattr", 8, },
{ NFSV4OP_REMOVEXATTR, 2, "Rmxattr", 7, },
{ NFSV4OP_LISTXATTRS, 2, "Listxattr", 9, },
+ { NFSV4OP_BINDCONNTOSESS, 1, "BindConSess", 11, },
};
/*
@@ -309,7 +310,7 @@
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, 1, 0, 0
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
};
/*
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -561,6 +561,7 @@
struct nfsvattr *, int *, struct ucred *, NFSPROC_T *);
int nfsrpc_rmextattr(vnode_t, const char *, struct nfsvattr *, int *,
struct ucred *, NFSPROC_T *);
+void nfsrpc_bindconnsess(CLIENT *, void *, struct ucred *);
/* nfs_clstate.c */
int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int,
diff --git a/sys/fs/nfs/nfscl.h b/sys/fs/nfs/nfscl.h
--- a/sys/fs/nfs/nfscl.h
+++ b/sys/fs/nfs/nfscl.h
@@ -81,4 +81,9 @@
printf(__VA_ARGS__); \
} while (0)
+struct nfscl_reconarg {
+ int minorvers;
+ uint8_t sessionid[NFSX_V4SESSIONID];
+};
+
#endif /* _NFS_NFSCL_H */
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -412,10 +412,13 @@
#define NFSPROC_RMEXTATTR 63
#define NFSPROC_LISTEXTATTR 64
+/* BindConnectionToSession, done by the krpc for a new connection. */
+#define NFSPROC_BINDCONNTOSESS 65
+
/*
* Must be defined as one higher than the last NFSv4.2 Proc# above.
*/
-#define NFSV42_NPROCS 65
+#define NFSV42_NPROCS 66
#endif /* NFS_V3NPROCS */
@@ -444,7 +447,7 @@
uint64_t readlink_bios;
uint64_t biocache_readdirs;
uint64_t readdir_bios;
- uint64_t rpccnt[NFSV42_NPROCS + 15];
+ uint64_t rpccnt[NFSV42_NPROCS + 14];
uint64_t rpcretries;
uint64_t srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15];
uint64_t reserved_0;
@@ -509,7 +512,7 @@
uint64_t readlink_bios;
uint64_t biocache_readdirs;
uint64_t readdir_bios;
- uint64_t rpccnt[NFSV42_NPROCS + 4];
+ uint64_t rpccnt[NFSV42_NPROCS + 3];
uint64_t rpcretries;
uint64_t srvrpccnt[NFSV42_PURENOPS + NFSV4OP_FAKENOPS];
uint64_t reserved_0;
diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h
--- a/sys/fs/nfs/nfsproto.h
+++ b/sys/fs/nfs/nfsproto.h
@@ -394,10 +394,13 @@
#define NFSPROC_RMEXTATTR 63
#define NFSPROC_LISTEXTATTR 64
+/* BindConnectionToSession, done by the krpc for a new connection. */
+#define NFSPROC_BINDCONNTOSESS 65
+
/*
* Must be defined as one higher than the last NFSv4.2 Proc# above.
*/
-#define NFSV42_NPROCS 65
+#define NFSV42_NPROCS 66
#endif /* NFS_V3NPROCS */
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -946,6 +946,8 @@
struct nfsclds *dsp, *odsp;
struct in6_addr a6;
struct nfsclsession *tsep;
+ struct rpc_reconupcall recon;
+ struct nfscl_reconarg *rcp;
if (nfsboottime.tv_sec == 0)
NFSSETBOOTTIME(nfsboottime);
@@ -1019,6 +1021,23 @@
NFSCL_DEBUG(1, "aft createsess=%d\n", error);
}
if (error == 0) {
+ /*
+ * If the session supports a backchannel, set up
+ * the BindConnectionToSession call in the krpc
+ * so that it is done on a reconnection.
+ */
+ if (nfscl_enablecallb != 0 && nfs_numnfscbd > 0) {
+ rcp = mem_alloc(sizeof(*rcp));
+ rcp->minorvers = nmp->nm_minorvers;
+ memcpy(rcp->sessionid,
+ dsp->nfsclds_sess.nfsess_sessionid,
+ NFSX_V4SESSIONID);
+ recon.call = nfsrpc_bindconnsess;
+ recon.arg = rcp;
+ CLNT_CONTROL(nmp->nm_client, CLSET_RECONUPCALL,
+ &recon);
+ }
+
NFSLOCKMNT(nmp);
/*
* The old sessions cannot be safely free'd
@@ -8709,3 +8728,74 @@
m->m_next = NULL;
return (m2);
}
+
+/*
+ * Do the NFSv4.1 Bind Connection to Session.
+ * Called from the reconnect layer of the krpc (sys/rpc/clnt_rc.c).
+ */
+void
+nfsrpc_bindconnsess(CLIENT *cl, void *arg, struct ucred *cr)
+{
+ struct nfscl_reconarg *rcp = (struct nfscl_reconarg *)arg;
+ uint32_t res, *tl;
+ struct nfsrv_descript nfsd;
+ struct nfsrv_descript *nd = &nfsd;
+ struct rpc_callextra ext;
+ struct timeval utimeout;
+ enum clnt_stat stat;
+ int error;
+
+ nfscl_reqstart(nd, NFSPROC_BINDCONNTOSESS, NULL, NULL, 0, NULL, NULL,
+ NFS_VER4, rcp->minorvers);
+ NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 2 * NFSX_UNSIGNED);
+ memcpy(tl, rcp->sessionid, NFSX_V4SESSIONID);
+ tl += NFSX_V4SESSIONID / NFSX_UNSIGNED;
+ *tl++ = txdr_unsigned(NFSCDFC4_FORE_OR_BOTH);
+ *tl = newnfs_false;
+
+ memset(&ext, 0, sizeof(ext));
+ utimeout.tv_sec = 30;
+ utimeout.tv_usec = 0;
+ ext.rc_auth = authunix_create(cr);
+ nd->nd_mrep = NULL;
+ stat = CLNT_CALL_MBUF(cl, &ext, NFSV4PROC_COMPOUND, nd->nd_mreq,
+ &nd->nd_mrep, utimeout);
+ AUTH_DESTROY(ext.rc_auth);
+ if (stat != RPC_SUCCESS) {
+ printf("nfsrpc_bindconnsess: call failed stat=%d\n", stat);
+ return;
+ }
+ if (nd->nd_mrep == NULL) {
+ printf("nfsrpc_bindconnsess: no reply args\n");
+ return;
+ }
+ error = 0;
+ newnfs_realign(&nd->nd_mrep, M_WAITOK);
+ nd->nd_md = nd->nd_mrep;
+ nd->nd_dpos = mtod(nd->nd_md, char *);
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ nd->nd_repstat = fxdr_unsigned(uint32_t, *tl++);
+ if (nd->nd_repstat == NFSERR_OK) {
+ res = fxdr_unsigned(uint32_t, *tl);
+ if (res > 0 && (error = nfsm_advance(nd, NFSM_RNDUP(res),
+ -1)) != 0)
+ goto nfsmout;
+ NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID +
+ 4 * NFSX_UNSIGNED);
+ tl += 3;
+ if (!NFSBCMP(tl, rcp->sessionid, NFSX_V4SESSIONID)) {
+ tl += NFSX_V4SESSIONID / NFSX_UNSIGNED;
+ res = fxdr_unsigned(uint32_t, *tl);
+ if (res != NFSCDFS4_BOTH)
+ printf("nfsrpc_bindconnsess: did not "
+ "return FS4_BOTH\n");
+ } else
+ printf("nfsrpc_bindconnsess: not same "
+ "sessionid\n");
+ } else if (nd->nd_repstat != NFSERR_BADSESSION)
+ printf("nfsrpc_bindconnsess: returned %d\n", nd->nd_repstat);
+nfsmout:
+ if (error != 0)
+ printf("nfsrpc_bindconnsess: reply bad xdr\n");
+ m_freem(nd->nd_mrep);
+}
diff --git a/sys/rpc/clnt.h b/sys/rpc/clnt.h
--- a/sys/rpc/clnt.h
+++ b/sys/rpc/clnt.h
@@ -360,6 +360,12 @@
#define CLSET_TLS 30 /* set TLS for socket */
#define CLSET_BLOCKRCV 31 /* Temporarily block reception */
#define CLSET_TLSCERTNAME 32 /* TLS certificate file name */
+/* Structure used as the argument for CLSET_RECONUPCALL. */
+struct rpc_reconupcall {
+ void (*call)(CLIENT *, void *, struct ucred *);
+ void *arg;
+};
+#define CLSET_RECONUPCALL 33 /* Reconnect upcall */
#endif
diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c
--- a/sys/rpc/clnt_rc.c
+++ b/sys/rpc/clnt_rc.c
@@ -111,6 +111,8 @@
rc->rc_client = NULL;
rc->rc_tls = false;
rc->rc_tlscertname = NULL;
+ rc->rc_reconcall = NULL;
+ rc->rc_reconarg = NULL;
cl->cl_refs = 1;
cl->cl_ops = &clnt_reconnect_ops;
@@ -213,6 +215,9 @@
goto out;
}
}
+ if (newclient != NULL && rc->rc_reconcall != NULL)
+ (*rc->rc_reconcall)(newclient, rc->rc_reconarg,
+ rc->rc_ucred);
}
td->td_ucred = oldcred;
@@ -408,6 +413,7 @@
struct rc_data *rc = (struct rc_data *)cl->cl_private;
SVCXPRT *xprt;
size_t slen;
+ struct rpc_reconupcall *upcp;
if (info == NULL) {
return (FALSE);
@@ -513,6 +519,12 @@
strlcpy(rc->rc_tlscertname, info, slen);
break;
+ case CLSET_RECONUPCALL:
+ upcp = (struct rpc_reconupcall *)info;
+ rc->rc_reconcall = upcp->call;
+ rc->rc_reconarg = upcp->arg;
+ break;
+
default:
return (FALSE);
}
@@ -555,12 +567,15 @@
CLNT_DESTROY(rc->rc_client);
if (rc->rc_backchannel) {
xprt = (SVCXPRT *)rc->rc_backchannel;
+ KASSERT(xprt->xp_socket == NULL,
+ ("clnt_reconnect_destroy: xp_socket not NULL"));
xprt_unregister(xprt);
SVC_RELEASE(xprt);
}
crfree(rc->rc_ucred);
mtx_destroy(&rc->rc_lock);
mem_free(rc->rc_tlscertname, 0); /* 0 ok, since arg. ignored. */
+ mem_free(rc->rc_reconarg, 0);
mem_free(rc, sizeof(*rc));
mem_free(cl, sizeof (CLIENT));
}
diff --git a/sys/rpc/krpc.h b/sys/rpc/krpc.h
--- a/sys/rpc/krpc.h
+++ b/sys/rpc/krpc.h
@@ -81,6 +81,9 @@
void *rc_backchannel;
bool rc_tls; /* Enable TLS on connection */
char *rc_tlscertname;
+ void (*rc_reconcall)(CLIENT *, void *,
+ struct ucred *); /* reconection upcall */
+ void *rc_reconarg; /* upcall arg */
};
/* Bits for ct_rcvstate. */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 6, 4:30 AM (21 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16486994
Default Alt Text
D29475.diff (8 KB)
Attached To
Mode
D29475: add support for BindConnectionToSession to the NFSv4.1/4.2 client
Attached
Detach File
Event Timeline
Log In to Comment