svn commit: r269398 - in stable/10/sys: conf fs/nfs fs/nfsclient fs/nfsserver modules/krpc rpc
Rick Macklem
rmacklem at FreeBSD.org
Fri Aug 1 21:10:44 UTC 2014
Author: rmacklem
Date: Fri Aug 1 21:10:41 2014
New Revision: 269398
URL: http://svnweb.freebsd.org/changeset/base/269398
Log:
MFC: r268115
Merge the NFSv4.1 server code in projects/nfsv4.1-server over
into head. The code is not believed to have any effect
on the semantics of non-NFSv4.1 server behaviour.
It is a rather large merge, but I am hoping that there will
not be any regressions for the NFS server.
Added:
stable/10/sys/rpc/clnt_bck.c
- copied unchanged from r268115, head/sys/rpc/clnt_bck.c
Modified:
stable/10/sys/conf/files
stable/10/sys/fs/nfs/nfs.h
stable/10/sys/fs/nfs/nfs_commonkrpc.c
stable/10/sys/fs/nfs/nfs_commonport.c
stable/10/sys/fs/nfs/nfs_commonsubs.c
stable/10/sys/fs/nfs/nfs_var.h
stable/10/sys/fs/nfs/nfsclstate.h
stable/10/sys/fs/nfs/nfsdport.h
stable/10/sys/fs/nfs/nfsport.h
stable/10/sys/fs/nfs/nfsproto.h
stable/10/sys/fs/nfs/nfsrvstate.h
stable/10/sys/fs/nfsclient/nfs_clstate.c
stable/10/sys/fs/nfsserver/nfs_nfsdcache.c
stable/10/sys/fs/nfsserver/nfs_nfsdkrpc.c
stable/10/sys/fs/nfsserver/nfs_nfsdport.c
stable/10/sys/fs/nfsserver/nfs_nfsdserv.c
stable/10/sys/fs/nfsserver/nfs_nfsdsocket.c
stable/10/sys/fs/nfsserver/nfs_nfsdstate.c
stable/10/sys/fs/nfsserver/nfs_nfsdsubs.c
stable/10/sys/modules/krpc/Makefile
stable/10/sys/rpc/krpc.h
stable/10/sys/rpc/svc.h
stable/10/sys/rpc/svc_vc.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/conf/files
==============================================================================
--- stable/10/sys/conf/files Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/conf/files Fri Aug 1 21:10:41 2014 (r269398)
@@ -3838,6 +3838,7 @@ pci/viapm.c optional viapm pci
rpc/auth_none.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
rpc/auth_unix.c optional krpc | nfslockd | nfsclient | nfscl | nfsd
rpc/authunix_prot.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
+rpc/clnt_bck.c optional krpc | nfslockd | nfsserver | nfscl | nfsd
rpc/clnt_dg.c optional krpc | nfslockd | nfsclient | nfscl | nfsd
rpc/clnt_rc.c optional krpc | nfslockd | nfsclient | nfscl | nfsd
rpc/clnt_vc.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
Modified: stable/10/sys/fs/nfs/nfs.h
==============================================================================
--- stable/10/sys/fs/nfs/nfs.h Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfs.h Fri Aug 1 21:10:41 2014 (r269398)
@@ -50,7 +50,8 @@
#define NFS_MAXREXMIT 100 /* Stop counting after this many */
#define NFSV4_CALLBACKTIMEO (2 * NFS_HZ) /* Timeout in ticks */
#define NFSV4_CALLBACKRETRY 5 /* Number of retries before failure */
-#define NFSV4_CBSLOTS 8 /* Number of slots for session */
+#define NFSV4_SLOTS 64 /* Number of slots, fore channel */
+#define NFSV4_CBSLOTS 8 /* Number of slots, back channel */
#define NFSV4_CBRETRYCNT 4 /* # of CBRecall retries upon err */
#define NFSV4_UPCALLTIMEO (15 * NFS_HZ) /* Timeout in ticks for upcalls */
/* to gssd or nfsuserd */
@@ -91,6 +92,9 @@
#ifndef NFSLOCKHASHSIZE
#define NFSLOCKHASHSIZE 20 /* Size of server nfslock hash table */
#endif
+#ifndef NFSSESSIONHASHSIZE
+#define NFSSESSIONHASHSIZE 20 /* Size of server session hash table */
+#endif
#define NFSSTATEHASHSIZE 10 /* Size of server stateid hash table */
#ifndef NFSUSERHASHSIZE
#define NFSUSERHASHSIZE 30 /* Size of user id hash table */
@@ -276,6 +280,8 @@ struct nfsreferral {
#define LCL_GSSINTEGRITY 0x00002000
#define LCL_GSSPRIVACY 0x00004000
#define LCL_ADMINREVOKED 0x00008000
+#define LCL_RECLAIMCOMPLETE 0x00010000
+#define LCL_NFSV41 0x00020000
#define LCL_GSS LCL_KERBV /* Or of all mechs */
@@ -318,6 +324,11 @@ struct nfsreferral {
#define NFSLCK_SETATTR 0x02000000
#define NFSLCK_DELEGPURGE 0x04000000
#define NFSLCK_DELEGRETURN 0x08000000
+#define NFSLCK_WANTWDELEG 0x10000000
+#define NFSLCK_WANTRDELEG 0x20000000
+#define NFSLCK_WANTNODELEG 0x40000000
+#define NFSLCK_WANTBITS \
+ (NFSLCK_WANTWDELEG | NFSLCK_WANTRDELEG | NFSLCK_WANTNODELEG)
/* And bits for nid_flag */
#define NFSID_INITIALIZE 0x0001
@@ -341,68 +352,120 @@ struct nfsreferral {
* THE MACROS MUST BE MANUALLY MODIFIED IF NFSATTRBIT_MAXWORDS CHANGES!!
* It is (NFSATTRBIT_MAX + 31) / 32.
*/
-#define NFSATTRBIT_MAXWORDS 2
+#define NFSATTRBIT_MAXWORDS 3
typedef struct {
u_int32_t bits[NFSATTRBIT_MAXWORDS];
} nfsattrbit_t;
-#define NFSZERO_ATTRBIT(b) do { (b)->bits[0] = 0; (b)->bits[1] = 0; } while (0)
-#define NFSSET_ATTRBIT(t, f) do { (t)->bits[0] = (f)->bits[0]; \
- (t)->bits[1] = (f)->bits[1]; } while (0)
+#define NFSZERO_ATTRBIT(b) do { \
+ (b)->bits[0] = 0; \
+ (b)->bits[1] = 0; \
+ (b)->bits[2] = 0; \
+} while (0)
+
+#define NFSSET_ATTRBIT(t, f) do { \
+ (t)->bits[0] = (f)->bits[0]; \
+ (t)->bits[1] = (f)->bits[1]; \
+ (t)->bits[2] = (f)->bits[2]; \
+} while (0)
+
#define NFSSETSUPP_ATTRBIT(b) do { \
(b)->bits[0] = NFSATTRBIT_SUPP0; \
- (b)->bits[1] = (NFSATTRBIT_SUPP1 | NFSATTRBIT_SUPPSETONLY); } while (0)
+ (b)->bits[1] = (NFSATTRBIT_SUPP1 | NFSATTRBIT_SUPPSETONLY); \
+ (b)->bits[2] = NFSATTRBIT_SUPP2; \
+} while (0)
+
#define NFSISSET_ATTRBIT(b, p) ((b)->bits[(p) / 32] & (1 << ((p) % 32)))
#define NFSSETBIT_ATTRBIT(b, p) ((b)->bits[(p) / 32] |= (1 << ((p) % 32)))
#define NFSCLRBIT_ATTRBIT(b, p) ((b)->bits[(p) / 32] &= ~(1 << ((p) % 32)))
+
#define NFSCLRALL_ATTRBIT(b, a) do { \
- (b)->bits[0] &= ~((a)->bits[0]); \
- (b)->bits[1] &= ~((a)->bits[1]); \
- } while (0)
+ (b)->bits[0] &= ~((a)->bits[0]); \
+ (b)->bits[1] &= ~((a)->bits[1]); \
+ (b)->bits[2] &= ~((a)->bits[2]); \
+} while (0)
+
#define NFSCLRNOT_ATTRBIT(b, a) do { \
- (b)->bits[0] &= ((a)->bits[0]); \
- (b)->bits[1] &= ((a)->bits[1]); \
- } while (0)
+ (b)->bits[0] &= ((a)->bits[0]); \
+ (b)->bits[1] &= ((a)->bits[1]); \
+ (b)->bits[2] &= ((a)->bits[2]); \
+} while (0)
+
#define NFSCLRNOTFILLABLE_ATTRBIT(b) do { \
- (b)->bits[0] &= NFSATTRBIT_SUPP0; \
- (b)->bits[1] &= NFSATTRBIT_SUPP1; } while (0)
+ (b)->bits[0] &= NFSATTRBIT_SUPP0; \
+ (b)->bits[1] &= NFSATTRBIT_SUPP1; \
+ (b)->bits[2] &= NFSATTRBIT_SUPP2; \
+} while (0)
+
#define NFSCLRNOTSETABLE_ATTRBIT(b) do { \
- (b)->bits[0] &= NFSATTRBIT_SETABLE0; \
- (b)->bits[1] &= NFSATTRBIT_SETABLE1; } while (0)
-#define NFSNONZERO_ATTRBIT(b) ((b)->bits[0] || (b)->bits[1])
-#define NFSEQUAL_ATTRBIT(b, p) \
- ((b)->bits[0] == (p)->bits[0] && (b)->bits[1] == (p)->bits[1])
+ (b)->bits[0] &= NFSATTRBIT_SETABLE0; \
+ (b)->bits[1] &= NFSATTRBIT_SETABLE1; \
+ (b)->bits[2] &= NFSATTRBIT_SETABLE2; \
+} while (0)
+
+#define NFSNONZERO_ATTRBIT(b) ((b)->bits[0] || (b)->bits[1] || (b)->bits[2])
+#define NFSEQUAL_ATTRBIT(b, p) ((b)->bits[0] == (p)->bits[0] && \
+ (b)->bits[1] == (p)->bits[1] && (b)->bits[2] == (p)->bits[2])
+
#define NFSGETATTR_ATTRBIT(b) do { \
- (b)->bits[0] = NFSATTRBIT_GETATTR0; \
- (b)->bits[1] = NFSATTRBIT_GETATTR1; } while (0)
+ (b)->bits[0] = NFSATTRBIT_GETATTR0; \
+ (b)->bits[1] = NFSATTRBIT_GETATTR1; \
+ (b)->bits[2] = NFSATTRBIT_GETATTR2; \
+} while (0)
+
#define NFSWCCATTR_ATTRBIT(b) do { \
- (b)->bits[0] = NFSATTRBIT_WCCATTR0; \
- (b)->bits[1] = NFSATTRBIT_WCCATTR1; } while (0)
+ (b)->bits[0] = NFSATTRBIT_WCCATTR0; \
+ (b)->bits[1] = NFSATTRBIT_WCCATTR1; \
+ (b)->bits[2] = NFSATTRBIT_WCCATTR2; \
+} while (0)
+
#define NFSWRITEGETATTR_ATTRBIT(b) do { \
- (b)->bits[0] = NFSATTRBIT_WRITEGETATTR0; \
- (b)->bits[1] = NFSATTRBIT_WRITEGETATTR1; } while (0)
+ (b)->bits[0] = NFSATTRBIT_WRITEGETATTR0; \
+ (b)->bits[1] = NFSATTRBIT_WRITEGETATTR1; \
+ (b)->bits[2] = NFSATTRBIT_WRITEGETATTR2; \
+} while (0)
+
#define NFSCBGETATTR_ATTRBIT(b, c) do { \
- (c)->bits[0] = ((b)->bits[0] & NFSATTRBIT_CBGETATTR0); \
- (c)->bits[1] = ((b)->bits[1] & NFSATTRBIT_CBGETATTR1); } while (0)
+ (c)->bits[0] = ((b)->bits[0] & NFSATTRBIT_CBGETATTR0); \
+ (c)->bits[1] = ((b)->bits[1] & NFSATTRBIT_CBGETATTR1); \
+ (c)->bits[2] = ((b)->bits[2] & NFSATTRBIT_CBGETATTR2); \
+} while (0)
+
#define NFSPATHCONF_GETATTRBIT(b) do { \
- (b)->bits[0] = NFSGETATTRBIT_PATHCONF0; \
- (b)->bits[1] = NFSGETATTRBIT_PATHCONF1; } while (0)
+ (b)->bits[0] = NFSGETATTRBIT_PATHCONF0; \
+ (b)->bits[1] = NFSGETATTRBIT_PATHCONF1; \
+ (b)->bits[2] = NFSGETATTRBIT_PATHCONF2; \
+} while (0)
+
#define NFSSTATFS_GETATTRBIT(b) do { \
- (b)->bits[0] = NFSGETATTRBIT_STATFS0; \
- (b)->bits[1] = NFSGETATTRBIT_STATFS1; } while (0)
+ (b)->bits[0] = NFSGETATTRBIT_STATFS0; \
+ (b)->bits[1] = NFSGETATTRBIT_STATFS1; \
+ (b)->bits[2] = NFSGETATTRBIT_STATFS2; \
+} while (0)
+
#define NFSISSETSTATFS_ATTRBIT(b) \
(((b)->bits[0] & NFSATTRBIT_STATFS0) || \
- ((b)->bits[1] & NFSATTRBIT_STATFS1))
+ ((b)->bits[1] & NFSATTRBIT_STATFS1) || \
+ ((b)->bits[2] & NFSATTRBIT_STATFS2))
+
#define NFSCLRSTATFS_ATTRBIT(b) do { \
- (b)->bits[0] &= ~NFSATTRBIT_STATFS0; \
- (b)->bits[1] &= ~NFSATTRBIT_STATFS1; } while (0)
+ (b)->bits[0] &= ~NFSATTRBIT_STATFS0; \
+ (b)->bits[1] &= ~NFSATTRBIT_STATFS1; \
+ (b)->bits[2] &= ~NFSATTRBIT_STATFS2; \
+} while (0)
+
#define NFSREADDIRPLUS_ATTRBIT(b) do { \
- (b)->bits[0] = NFSATTRBIT_READDIRPLUS0; \
- (b)->bits[1] = NFSATTRBIT_READDIRPLUS1; } while (0)
+ (b)->bits[0] = NFSATTRBIT_READDIRPLUS0; \
+ (b)->bits[1] = NFSATTRBIT_READDIRPLUS1; \
+ (b)->bits[2] = NFSATTRBIT_READDIRPLUS2; \
+} while (0)
+
#define NFSREFERRAL_ATTRBIT(b) do { \
- (b)->bits[0] = NFSATTRBIT_REFERRAL0; \
- (b)->bits[1] = NFSATTRBIT_REFERRAL1; } while (0)
+ (b)->bits[0] = NFSATTRBIT_REFERRAL0; \
+ (b)->bits[1] = NFSATTRBIT_REFERRAL1; \
+ (b)->bits[2] = NFSATTRBIT_REFERRAL2; \
+} while (0)
/*
* Store uid, gid creds that were used when the stateid was acquired.
@@ -529,6 +592,9 @@ struct nfsrv_descript {
int nd_gssnamelen; /* principal name length */
char *nd_gssname; /* principal name */
uint32_t *nd_slotseq; /* ptr to slot seq# in req */
+ uint8_t nd_sessionid[NFSX_V4SESSIONID]; /* Session id */
+ uint32_t nd_slotid; /* Slotid for this RPC */
+ SVCXPRT *nd_xprt; /* Server RPC handle */
};
#define nd_princlen nd_gssnamelen
@@ -562,6 +628,8 @@ struct nfsrv_descript {
#define ND_NFSCL 0x01000000
#define ND_NFSV41 0x02000000
#define ND_HASSEQUENCE 0x04000000
+#define ND_CACHETHIS 0x08000000
+#define ND_LASTOP 0x10000000
/*
* ND_GSS should be the "or" of all GSS type authentications.
Modified: stable/10/sys/fs/nfs/nfs_commonkrpc.c
==============================================================================
--- stable/10/sys/fs/nfs/nfs_commonkrpc.c Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfs_commonkrpc.c Fri Aug 1 21:10:41 2014 (r269398)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <rpc/rpc.h>
+#include <rpc/krpc.h>
#include <kgssapi/krb5/kcrypto.h>
@@ -739,8 +740,12 @@ tryagain:
}
nd->nd_mrep = NULL;
- stat = CLNT_CALL_MBUF(nrp->nr_client, &ext, procnum, nd->nd_mreq,
- &nd->nd_mrep, timo);
+ if (clp != NULL && sep != NULL)
+ stat = clnt_bck_call(nrp->nr_client, &ext, procnum,
+ nd->nd_mreq, &nd->nd_mrep, timo, sep->nfsess_xprt);
+ else
+ stat = CLNT_CALL_MBUF(nrp->nr_client, &ext, procnum,
+ nd->nd_mreq, &nd->nd_mrep, timo);
if (rep != NULL) {
/*
@@ -795,7 +800,8 @@ tryagain:
nd->nd_md = nd->nd_mrep;
nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t);
nd->nd_repstat = 0;
- if (nd->nd_procnum != NFSPROC_NULL) {
+ if (nd->nd_procnum != NFSPROC_NULL &&
+ nd->nd_procnum != NFSV4PROC_CBNULL) {
/* If sep == NULL, set it to the default in nmp. */
if (sep == NULL && nmp != NULL)
sep = NFSMNT_MDSSESSION(nmp);
@@ -827,11 +833,20 @@ tryagain:
/*
* If the first op is Sequence, free up the slot.
*/
- if (nmp != NULL && i == NFSV4OP_SEQUENCE && j != 0)
+ if ((nmp != NULL && i == NFSV4OP_SEQUENCE && j != 0) ||
+ (clp != NULL && i == NFSV4OP_CBSEQUENCE && j != 0))
NFSCL_DEBUG(1, "failed seq=%d\n", j);
- if (nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) {
- NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID +
- 5 * NFSX_UNSIGNED);
+ if ((nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) ||
+ (clp != NULL && i == NFSV4OP_CBSEQUENCE && j == 0)
+ ) {
+ if (i == NFSV4OP_SEQUENCE)
+ NFSM_DISSECT(tl, uint32_t *,
+ NFSX_V4SESSIONID +
+ 5 * NFSX_UNSIGNED);
+ else
+ NFSM_DISSECT(tl, uint32_t *,
+ NFSX_V4SESSIONID +
+ 4 * NFSX_UNSIGNED);
mtx_lock(&sep->nfsess_mtx);
tl += NFSX_V4SESSIONID / NFSX_UNSIGNED;
retseq = fxdr_unsigned(uint32_t, *tl++);
Modified: stable/10/sys/fs/nfs/nfs_commonport.c
==============================================================================
--- stable/10/sys/fs/nfs/nfs_commonport.c Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfs_commonport.c Fri Aug 1 21:10:41 2014 (r269398)
@@ -112,6 +112,7 @@ MALLOC_DEFINE(M_NEWNFSDEVINFO, "NFSCL de
MALLOC_DEFINE(M_NEWNFSSOCKREQ, "NFSCL sockreq", "NFS Sock Req");
MALLOC_DEFINE(M_NEWNFSCLDS, "NFSCL session", "NFSv4.1 Session");
MALLOC_DEFINE(M_NEWNFSLAYRECALL, "NFSCL layrecall", "NFSv4.1 Layout Recall");
+MALLOC_DEFINE(M_NEWNFSDSESSION, "NFSD session", "NFSD Session for a client");
/*
* Definition of mutex locks.
Modified: stable/10/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- stable/10/sys/fs/nfs/nfs_commonsubs.c Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfs_commonsubs.c Fri Aug 1 21:10:41 2014 (r269398)
@@ -1733,6 +1733,23 @@ nfsv4_loadattr(struct nfsrv_descript *nd
}
attrsum += NFSX_HYPER;
break;
+ case NFSATTRBIT_SUPPATTREXCLCREAT:
+ retnotsup = 0;
+ error = nfsrv_getattrbits(nd, &retattrbits,
+ &cnt, &retnotsup);
+ if (error)
+ goto nfsmout;
+ if (compare && !(*retcmpp)) {
+ NFSSETSUPP_ATTRBIT(&checkattrbits);
+ NFSCLRNOTSETABLE_ATTRBIT(&checkattrbits);
+ NFSCLRBIT_ATTRBIT(&checkattrbits,
+ NFSATTRBIT_TIMEACCESSSET);
+ if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits)
+ || retnotsup)
+ *retcmpp = NFSERR_NOTSAME;
+ }
+ attrsum += cnt;
+ break;
default:
printf("EEK! nfsv4_loadattr unknown attr=%d\n",
bitpos);
@@ -2469,6 +2486,12 @@ nfsv4_fillattr(struct nfsrv_descript *nd
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
+ case NFSATTRBIT_SUPPATTREXCLCREAT:
+ NFSSETSUPP_ATTRBIT(&attrbits);
+ NFSCLRNOTSETABLE_ATTRBIT(&attrbits);
+ NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESSSET);
+ retnum += nfsrv_putattrbit(nd, &attrbits);
+ break;
default:
printf("EEK! Bad V4 attribute bitpos=%d\n", bitpos);
};
@@ -3663,6 +3686,9 @@ nfsmout:
/*
* Handle an NFSv4.1 Sequence request for the session.
+ * If reply != NULL, use it to return the cached reply, as required.
+ * The client gets a cached reply via this call for callbacks, however the
+ * server gets a cached reply via the nfsv4_seqsess_cachereply() call.
*/
int
nfsv4_seqsession(uint32_t seqid, uint32_t slotid, uint32_t highslot,
@@ -3671,7 +3697,8 @@ nfsv4_seqsession(uint32_t seqid, uint32_
int error;
error = 0;
- *reply = NULL;
+ if (reply != NULL)
+ *reply = NULL;
if (slotid > maxslot)
return (NFSERR_BADSLOT);
if (seqid == slots[slotid].nfssl_seq) {
@@ -3679,13 +3706,18 @@ nfsv4_seqsession(uint32_t seqid, uint32_
if (slots[slotid].nfssl_inprog != 0)
error = NFSERR_DELAY;
else if (slots[slotid].nfssl_reply != NULL) {
- *reply = slots[slotid].nfssl_reply;
- slots[slotid].nfssl_reply = NULL;
+ if (reply != NULL) {
+ *reply = slots[slotid].nfssl_reply;
+ slots[slotid].nfssl_reply = NULL;
+ }
slots[slotid].nfssl_inprog = 1;
+ error = NFSERR_REPLYFROMCACHE;
} else
- error = NFSERR_SEQMISORDERED;
+ /* No reply cached, so just do it. */
+ slots[slotid].nfssl_inprog = 1;
} else if ((slots[slotid].nfssl_seq + 1) == seqid) {
- m_freem(slots[slotid].nfssl_reply);
+ if (slots[slotid].nfssl_reply != NULL)
+ m_freem(slots[slotid].nfssl_reply);
slots[slotid].nfssl_reply = NULL;
slots[slotid].nfssl_inprog = 1;
slots[slotid].nfssl_seq++;
@@ -3696,12 +3728,22 @@ nfsv4_seqsession(uint32_t seqid, uint32_
/*
* Cache this reply for the slot.
+ * Use the "rep" argument to return the cached reply if repstat is set to
+ * NFSERR_REPLYFROMCACHE. The client never sets repstat to this value.
*/
void
-nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, struct mbuf *rep)
+nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, int repstat,
+ struct mbuf **rep)
{
- slots[slotid].nfssl_reply = rep;
+ if (repstat == NFSERR_REPLYFROMCACHE) {
+ *rep = slots[slotid].nfssl_reply;
+ slots[slotid].nfssl_reply = NULL;
+ } else {
+ if (slots[slotid].nfssl_reply != NULL)
+ m_freem(slots[slotid].nfssl_reply);
+ slots[slotid].nfssl_reply = *rep;
+ }
slots[slotid].nfssl_inprog = 0;
}
@@ -3713,9 +3755,36 @@ nfsv4_setsequence(struct nfsmount *nmp,
struct nfsclsession *sep, int dont_replycache)
{
uint32_t *tl, slotseq = 0;
+ int error, maxslot, slotpos;
+ uint8_t sessionid[NFSX_V4SESSIONID];
+
+ error = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, &slotseq,
+ sessionid);
+ if (error != 0)
+ return;
+ KASSERT(maxslot >= 0, ("nfscl_setsequence neg maxslot"));
+
+ /* Build the Sequence arguments. */
+ NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 4 * NFSX_UNSIGNED);
+ bcopy(sessionid, tl, NFSX_V4SESSIONID);
+ tl += NFSX_V4SESSIONID / NFSX_UNSIGNED;
+ nd->nd_slotseq = tl;
+ *tl++ = txdr_unsigned(slotseq);
+ *tl++ = txdr_unsigned(slotpos);
+ *tl++ = txdr_unsigned(maxslot);
+ if (dont_replycache == 0)
+ *tl = newnfs_true;
+ else
+ *tl = newnfs_false;
+ nd->nd_flag |= ND_HASSEQUENCE;
+}
+
+int
+nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep,
+ int *slotposp, int *maxslotp, uint32_t *slotseqp, uint8_t *sessionid)
+{
int i, maxslot, slotpos;
uint64_t bitval;
- uint8_t sessionid[NFSX_V4SESSIONID];
/* Find an unused slot. */
slotpos = -1;
@@ -3728,7 +3797,7 @@ nfsv4_setsequence(struct nfsmount *nmp,
slotpos = i;
sep->nfsess_slots |= bitval;
sep->nfsess_slotseq[i]++;
- slotseq = sep->nfsess_slotseq[i];
+ *slotseqp = sep->nfsess_slotseq[i];
break;
}
bitval <<= 1;
@@ -3739,10 +3808,11 @@ nfsv4_setsequence(struct nfsmount *nmp,
* This RPC attempt will fail when it calls
* newnfs_request().
*/
- if ((nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)
+ if (nmp != NULL &&
+ (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)
!= 0) {
mtx_unlock(&sep->nfsess_mtx);
- return;
+ return (ESTALE);
}
/* Wake up once/sec, to check for a forced dismount. */
(void)mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx,
@@ -3758,21 +3828,9 @@ nfsv4_setsequence(struct nfsmount *nmp,
}
bcopy(sep->nfsess_sessionid, sessionid, NFSX_V4SESSIONID);
mtx_unlock(&sep->nfsess_mtx);
- KASSERT(maxslot >= 0, ("nfscl_setsequence neg maxslot"));
-
- /* Build the Sequence arguments. */
- NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 4 * NFSX_UNSIGNED);
- bcopy(sessionid, tl, NFSX_V4SESSIONID);
- tl += NFSX_V4SESSIONID / NFSX_UNSIGNED;
- nd->nd_slotseq = tl;
- *tl++ = txdr_unsigned(slotseq);
- *tl++ = txdr_unsigned(slotpos);
- *tl++ = txdr_unsigned(maxslot);
- if (dont_replycache == 0)
- *tl = newnfs_true;
- else
- *tl = newnfs_false;
- nd->nd_flag |= ND_HASSEQUENCE;
+ *slotposp = slotpos;
+ *maxslotp = maxslot;
+ return (0);
}
/*
Modified: stable/10/sys/fs/nfs/nfs_var.h
==============================================================================
--- stable/10/sys/fs/nfs/nfs_var.h Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfs_var.h Fri Aug 1 21:10:41 2014 (r269398)
@@ -61,6 +61,7 @@ union nethostaddr;
struct nfsstate;
struct nfslock;
struct nfsclient;
+struct nfsdsession;
struct nfslockconflict;
struct nfsd_idargs;
struct nfsd_clid;
@@ -90,8 +91,11 @@ NFS_READDIR_ARGS;
/* nfs_nfsdstate.c */
int nfsrv_setclient(struct nfsrv_descript *, struct nfsclient **,
nfsquad_t *, nfsquad_t *, NFSPROC_T *);
-int nfsrv_getclient(nfsquad_t, int, struct nfsclient **, nfsquad_t,
- struct nfsrv_descript *, NFSPROC_T *);
+int nfsrv_getclient(nfsquad_t, int, struct nfsclient **, struct nfsdsession *,
+ 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_freestateid(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 *);
@@ -105,8 +109,8 @@ int nfsrv_opencheck(nfsquad_t, nfsv4stat
vnode_t, struct nfsrv_descript *, NFSPROC_T *, int);
int nfsrv_openupdate(vnode_t, struct nfsstate *, nfsquad_t,
nfsv4stateid_t *, struct nfsrv_descript *, NFSPROC_T *);
-int nfsrv_delegupdate(nfsquad_t, nfsv4stateid_t *, vnode_t, int,
- struct ucred *, NFSPROC_T *);
+int nfsrv_delegupdate(struct nfsrv_descript *, nfsquad_t, nfsv4stateid_t *,
+ vnode_t, int, struct ucred *, NFSPROC_T *);
int nfsrv_releaselckown(struct nfsstate *, nfsquad_t, NFSPROC_T *);
void nfsrv_zapclient(struct nfsclient *, NFSPROC_T *);
int nfssvc_idname(struct nfsd_idargs *);
@@ -127,6 +131,10 @@ int nfsrv_checkgetattr(struct nfsrv_desc
int nfsrv_nfsuserdport(u_short, NFSPROC_T *);
void nfsrv_nfsuserddelport(void);
void nfsrv_throwawayallstate(NFSPROC_T *);
+int nfsrv_checksequence(struct nfsrv_descript *, uint32_t, uint32_t *,
+ uint32_t *, int, uint32_t *, NFSPROC_T *);
+int nfsrv_checkreclaimcomplete(struct nfsrv_descript *);
+void nfsrv_cache_session(uint8_t *, uint32_t, int, struct mbuf **);
/* nfs_nfsdserv.c */
int nfsrvd_access(struct nfsrv_descript *, int,
@@ -211,10 +219,27 @@ int nfsrvd_releaselckown(struct nfsrv_de
vnode_t, NFSPROC_T *, struct nfsexstuff *);
int nfsrvd_pathconf(struct nfsrv_descript *, int,
vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_exchangeid(struct nfsrv_descript *, int,
+ vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_createsession(struct nfsrv_descript *, int,
+ vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_sequence(struct nfsrv_descript *, int,
+ vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_reclaimcomplete(struct nfsrv_descript *, int,
+ vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_destroyclientid(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,
+ vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_notsupp(struct nfsrv_descript *, int,
+ vnode_t, NFSPROC_T *, struct nfsexstuff *);
/* nfs_nfsdsocket.c */
void nfsrvd_rephead(struct nfsrv_descript *);
-void nfsrvd_dorpc(struct nfsrv_descript *, int, NFSPROC_T *);
+void nfsrvd_dorpc(struct nfsrv_descript *, int, u_char *, int, u_int32_t,
+ NFSPROC_T *);
/* nfs_nfsdcache.c */
void nfsrvd_initcache(void);
@@ -264,9 +289,11 @@ int nfsv4_getipaddr(struct nfsrv_descrip
int *);
int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
struct mbuf **, uint16_t);
-void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, struct mbuf *);
+void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **);
void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
struct nfsclsession *, int);
+int nfsv4_sequencelookup(struct nfsmount *, struct nfsclsession *, int *,
+ int *, uint32_t *, uint8_t *);
void nfsv4_freeslot(struct nfsclsession *, int);
/* nfs_clcomsubs.c */
@@ -322,6 +349,8 @@ int nfsrv_parsename(struct nfsrv_descrip
NFSPATHLEN_T *);
void nfsd_init(void);
int nfsd_checkrootexp(struct nfsrv_descript *);
+void nfsd_getminorvers(struct nfsrv_descript *, u_char *, u_char **, int *,
+ u_int32_t *);
/* nfs_clvfsops.c */
void nfscl_retopts(struct nfsmount *, char *, size_t);
@@ -628,6 +657,7 @@ int nfsvno_advlock(vnode_t, int, u_int64
int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *);
int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *);
uint32_t nfsrv_hashfh(fhandle_t *);
+uint32_t nfsrv_hashsessionid(uint8_t *);
void nfsrv_backupstable(void);
/* nfs_commonkrpc.c */
Modified: stable/10/sys/fs/nfs/nfsclstate.h
==============================================================================
--- stable/10/sys/fs/nfs/nfsclstate.h Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfsclstate.h Fri Aug 1 21:10:41 2014 (r269398)
@@ -57,6 +57,7 @@ struct nfsclsession {
struct mtx nfsess_mtx;
struct nfsslot nfsess_cbslots[NFSV4_CBSLOTS];
nfsquad_t nfsess_clientid;
+ SVCXPRT *nfsess_xprt; /* For backchannel callback */
uint32_t nfsess_slotseq[64]; /* Max for 64bit nm_slots */
uint64_t nfsess_slots;
uint32_t nfsess_sequenceid;
Modified: stable/10/sys/fs/nfs/nfsdport.h
==============================================================================
--- stable/10/sys/fs/nfs/nfsdport.h Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfsdport.h Fri Aug 1 21:10:41 2014 (r269398)
@@ -115,3 +115,9 @@ struct nfsexstuff {
#define NFSRV_MINFH (sizeof (fhandle_t))
#define NFSRV_MAXFH (sizeof (fhandle_t))
+/* Use this macro for debug printfs. */
+#define NFSD_DEBUG(level, ...) do { \
+ if (nfsd_debuglevel >= (level)) \
+ printf(__VA_ARGS__); \
+ } while (0)
+
Modified: stable/10/sys/fs/nfs/nfsport.h
==============================================================================
--- stable/10/sys/fs/nfs/nfsport.h Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfsport.h Fri Aug 1 21:10:41 2014 (r269398)
@@ -637,6 +637,9 @@ void nfsrvd_rcv(struct socket *, void *,
#define NFSUNLOCKSOCKREQ(r) mtx_unlock(&((r)->nr_mtx))
#define NFSLOCKDS(d) mtx_lock(&((d)->nfsclds_mtx))
#define NFSUNLOCKDS(d) mtx_unlock(&((d)->nfsclds_mtx))
+#define NFSSESSIONMUTEXPTR(s) (&((s)->mtx))
+#define NFSLOCKSESSION(s) mtx_lock(&((s)->mtx))
+#define NFSUNLOCKSESSION(s) mtx_unlock(&((s)->mtx))
/*
* Use these macros to initialize/free a mutex.
@@ -732,6 +735,7 @@ MALLOC_DECLARE(M_NEWNFSDEVINFO);
MALLOC_DECLARE(M_NEWNFSSOCKREQ);
MALLOC_DECLARE(M_NEWNFSCLDS);
MALLOC_DECLARE(M_NEWNFSLAYRECALL);
+MALLOC_DECLARE(M_NEWNFSDSESSION);
#define M_NFSRVCACHE M_NEWNFSRVCACHE
#define M_NFSDCLIENT M_NEWNFSDCLIENT
#define M_NFSDSTATE M_NEWNFSDSTATE
@@ -757,6 +761,7 @@ MALLOC_DECLARE(M_NEWNFSLAYRECALL);
#define M_NFSSOCKREQ M_NEWNFSSOCKREQ
#define M_NFSCLDS M_NEWNFSCLDS
#define M_NFSLAYRECALL M_NEWNFSLAYRECALL
+#define M_NFSDSESSION M_NEWNFSDSESSION
#define NFSINT_SIGMASK(set) \
(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \
Modified: stable/10/sys/fs/nfs/nfsproto.h
==============================================================================
--- stable/10/sys/fs/nfs/nfsproto.h Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfsproto.h Fri Aug 1 21:10:41 2014 (r269398)
@@ -389,9 +389,13 @@
#define NFSV4OPEN_CLAIMPREVIOUS 1
#define NFSV4OPEN_CLAIMDELEGATECUR 2
#define NFSV4OPEN_CLAIMDELEGATEPREV 3
+#define NFSV4OPEN_CLAIMFH 4
+#define NFSV4OPEN_CLAIMDELEGATECURFH 5
+#define NFSV4OPEN_CLAIMDELEGATEPREVFH 6
#define NFSV4OPEN_DELEGATENONE 0
#define NFSV4OPEN_DELEGATEREAD 1
#define NFSV4OPEN_DELEGATEWRITE 2
+#define NFSV4OPEN_DELEGATENONEEXT 3
#define NFSV4OPEN_LIMITSIZE 1
#define NFSV4OPEN_LIMITBLOCKS 2
@@ -479,6 +483,14 @@
#define NFSV4OPEN_ACCESSREAD 0x00000001
#define NFSV4OPEN_ACCESSWRITE 0x00000002
#define NFSV4OPEN_ACCESSBOTH 0x00000003
+#define NFSV4OPEN_WANTDELEGMASK 0x0000ff00
+#define NFSV4OPEN_WANTREADDELEG 0x00000100
+#define NFSV4OPEN_WANTWRITEDELEG 0x00000200
+#define NFSV4OPEN_WANTANYDELEG 0x00000300
+#define NFSV4OPEN_WANTNODELEG 0x00000400
+#define NFSV4OPEN_WANTCANCEL 0x00000500
+#define NFSV4OPEN_WANTSIGNALDELEG 0x00010000
+#define NFSV4OPEN_WANTPUSHDELEG 0x00020000
#define NFSV4OPEN_DENYNONE 0x00000000
#define NFSV4OPEN_DENYREAD 0x00000001
@@ -486,16 +498,35 @@
#define NFSV4OPEN_DENYBOTH 0x00000003
/*
+ * Delegate_none_ext reply values.
+ */
+#define NFSV4OPEN_NOTWANTED 0
+#define NFSV4OPEN_CONTENTION 1
+#define NFSV4OPEN_RESOURCE 2
+#define NFSV4OPEN_NOTSUPPFTYPE 3
+#define NFSV4OPEN_NOTSUPPWRITEFTYPE 4
+#define NFSV4OPEN_NOTSUPPUPGRADE 5
+#define NFSV4OPEN_NOTSUPPDOWNGRADE 6
+#define NFSV4OPEN_CANCELLED 7
+#define NFSV4OPEN_ISDIR 8
+
+/*
* Open result flags
- * (The first two are in the spec. The rest are used internally.)
+ * (The first four are in the spec. The rest are used internally.)
*/
#define NFSV4OPEN_RESULTCONFIRM 0x00000002
#define NFSV4OPEN_LOCKTYPEPOSIX 0x00000004
+#define NFSV4OPEN_PRESERVEUNLINKED 0x00000008
+#define NFSV4OPEN_MAYNOTIFYLOCK 0x00000020
#define NFSV4OPEN_RFLAGS \
- (NFSV4OPEN_RESULTCONFIRM | NFSV4OPEN_LOCKTYPEPOSIX)
+ (NFSV4OPEN_RESULTCONFIRM | NFSV4OPEN_LOCKTYPEPOSIX | \
+ NFSV4OPEN_PRESERVEUNLINKED | NFSV4OPEN_MAYNOTIFYLOCK)
#define NFSV4OPEN_RECALL 0x00010000
#define NFSV4OPEN_READDELEGATE 0x00020000
#define NFSV4OPEN_WRITEDELEGATE 0x00040000
+#define NFSV4OPEN_WDRESOURCE 0x00080000
+#define NFSV4OPEN_WDCONTENTION 0x00100000
+#define NFSV4OPEN_WDNOTWANTED 0x00200000
/*
* NFS V4 File Handle types
@@ -805,6 +836,27 @@ struct nfsv3_sattr {
#define NFSATTRBIT_TIMEMODIFY 53
#define NFSATTRBIT_TIMEMODIFYSET 54
#define NFSATTRBIT_MOUNTEDONFILEID 55
+#define NFSATTRBIT_DIRNOTIFDELAY 56
+#define NFSATTRBIT_DIRENTNOTIFDELAY 57
+#define NFSATTRBIT_DACL 58
+#define NFSATTRBIT_SACL 59
+#define NFSATTRBIT_CHANGEPOLICY 60
+#define NFSATTRBIT_FSSTATUS 61
+#define NFSATTRBIT_FSLAYOUTTYPE 62
+#define NFSATTRBIT_LAYOUTHINT 63
+#define NFSATTRBIT_LAYOUTTYPE 64
+#define NFSATTRBIT_LAYOUTBLKSIZE 65
+#define NFSATTRBIT_LAYOUTALIGNMENT 66
+#define NFSATTRBIT_FSLOCATIONSINFO 67
+#define NFSATTRBIT_MDSTHRESHOLD 68
+#define NFSATTRBIT_RETENTIONGET 69
+#define NFSATTRBIT_RETENTIONSET 70
+#define NFSATTRBIT_RETENTEVTGET 71
+#define NFSATTRBIT_RETENTEVTSET 72
+#define NFSATTRBIT_RETENTIONHOLD 73
+#define NFSATTRBIT_MODESETMASKED 74
+#define NFSATTRBIT_SUPPATTREXCLCREAT 75
+#define NFSATTRBIT_FSCHARSETCAP 76
#define NFSATTRBM_SUPPORTEDATTRS 0x00000001
#define NFSATTRBM_TYPE 0x00000002
@@ -862,8 +914,29 @@ struct nfsv3_sattr {
#define NFSATTRBM_TIMEMODIFY 0x00200000
#define NFSATTRBM_TIMEMODIFYSET 0x00400000
#define NFSATTRBM_MOUNTEDONFILEID 0x00800000
+#define NFSATTRBM_DIRNOTIFDELAY 0x01000000
+#define NFSATTRBM_DIRENTNOTIFDELAY 0x02000000
+#define NFSATTRBM_DACL 0x04000000
+#define NFSATTRBM_SACL 0x08000000
+#define NFSATTRBM_CHANGEPOLICY 0x10000000
+#define NFSATTRBM_FSSTATUS 0x20000000
+#define NFSATTRBM_FSLAYOUTTYPE 0x40000000
+#define NFSATTRBM_LAYOUTHINT 0x80000000
+#define NFSATTRBM_LAYOUTTYPE 0x00000001
+#define NFSATTRBM_LAYOUTBLKSIZE 0x00000002
+#define NFSATTRBM_LAYOUTALIGNMENT 0x00000004
+#define NFSATTRBM_FSLOCATIONSINFO 0x00000008
+#define NFSATTRBM_MDSTHRESHOLD 0x00000010
+#define NFSATTRBM_RETENTIONGET 0x00000020
+#define NFSATTRBM_RETENTIONSET 0x00000040
+#define NFSATTRBM_RETENTEVTGET 0x00000080
+#define NFSATTRBM_RETENTEVTSET 0x00000100
+#define NFSATTRBM_RETENTIONHOLD 0x00000200
+#define NFSATTRBM_MODESETMASKED 0x00000400
+#define NFSATTRBM_SUPPATTREXCLCREAT 0x00000800
+#define NFSATTRBM_FSCHARSETCAP 0x00001000
-#define NFSATTRBIT_MAX 56
+#define NFSATTRBIT_MAX 77
/*
* Sets of attributes that are supported, by words in the bitmap.
@@ -871,6 +944,7 @@ struct nfsv3_sattr {
/*
* NFSATTRBIT_SUPPORTED - SUPP0 - bits 0<->31
* SUPP1 - bits 32<->63
+ * SUPP2 - bits 64<->95
*/
#define NFSATTRBIT_SUPP0 \
(NFSATTRBM_SUPPORTEDATTRS | \
@@ -937,6 +1011,8 @@ struct nfsv3_sattr {
#define NFSATTRBIT_SUPP1 NFSATTRBIT_S1
#endif
+#define NFSATTRBIT_SUPP2 NFSATTRBM_SUPPATTREXCLCREAT
+
/*
* NFSATTRBIT_SUPPSETONLY is the OR of NFSATTRBIT_TIMEACCESSSET and
* NFSATTRBIT_TIMEMODIFYSET.
@@ -947,6 +1023,7 @@ struct nfsv3_sattr {
/*
* NFSATTRBIT_SETABLE - SETABLE0 - bits 0<->31
* SETABLE1 - bits 32<->63
+ * SETABLE2 - bits 64<->95
*/
#define NFSATTRBIT_SETABLE0 \
(NFSATTRBM_SIZE | \
@@ -957,6 +1034,7 @@ struct nfsv3_sattr {
NFSATTRBM_OWNERGROUP | \
NFSATTRBM_TIMEACCESSSET | \
NFSATTRBM_TIMEMODIFYSET)
+#define NFSATTRBIT_SETABLE2 0
/*
* Set of attributes that the getattr vnode op needs.
@@ -987,6 +1065,11 @@ struct nfsv3_sattr {
NFSATTRBM_TIMEMODIFY)
/*
+ * NFSATTRBIT_GETATTR2 - bits 64<->95
+ */
+#define NFSATTRBIT_GETATTR2 0
+
+/*
* Subset of the above that the Write RPC gets.
* OR of the following bits.
* NFSATTRBIT_WRITEGETATTR0 - bits 0<->31
@@ -1013,6 +1096,11 @@ struct nfsv3_sattr {
NFSATTRBM_TIMEMODIFY)
/*
+ * NFSATTRBIT_WRITEGETATTR2 - bits 64<->95
+ */
+#define NFSATTRBIT_WRITEGETATTR2 0
+
+/*
* Set of attributes that the wccattr operation op needs.
* OR of the following bits.
* NFSATTRBIT_WCCATTR0 - bits 0<->31
@@ -1026,6 +1114,11 @@ struct nfsv3_sattr {
(NFSATTRBM_TIMEMODIFY)
/*
+ * NFSATTRBIT_WCCATTR2 - bits 64<->95
+ */
+#define NFSATTRBIT_WCCATTR2 0
+
+/*
* NFSATTRBIT_CBGETATTR0 - bits 0<->31
*/
#define NFSATTRBIT_CBGETATTR0 (NFSATTRBM_CHANGE | NFSATTRBM_SIZE)
@@ -1036,6 +1129,11 @@ struct nfsv3_sattr {
#define NFSATTRBIT_CBGETATTR1 0x0
/*
+ * NFSATTRBIT_CBGETATTR2 - bits 64<->95
+ */
+#define NFSATTRBIT_CBGETATTR2 0x0
+
+/*
* Sets of attributes that require a VFS_STATFS() call to get the
* values of.
* NFSATTRBIT_STATFS0 - bits 0<->31
@@ -1067,6 +1165,11 @@ struct nfsv3_sattr {
NFSATTRBM_TIMEDELTA)
/*
+ * NFSATTRBIT_STATFS2 - bits 64<->95
+ */
+#define NFSATTRBIT_STATFS2 0
+
+/*
* These are the bits that are needed by the nfs_statfs() call.
* (The regular getattr bits are or'd in so the vnode gets the correct
* type, etc.)
@@ -1094,6 +1197,11 @@ struct nfsv3_sattr {
NFSATTRBM_TIMEDELTA)
/*
+ * NFSGETATTRBIT_STATFS2 - bits 64<->95
+ */
+#define NFSGETATTRBIT_STATFS2 0
+
+/*
* Set of attributes for the equivalent of an nfsv3 pathconf rpc.
* NFSGETATTRBIT_PATHCONF0 - bits 0<->31
*/
@@ -1111,6 +1219,11 @@ struct nfsv3_sattr {
NFSATTRBM_NOTRUNC)
/*
+ * NFSGETATTRBIT_PATHCONF2 - bits 64<->95
+ */
+#define NFSGETATTRBIT_PATHCONF2 0
+
+/*
* Sets of attributes required by readdir and readdirplus.
* NFSATTRBIT_READDIRPLUS0 (NFSATTRBIT_GETATTR0 | NFSATTRBIT_FILEHANDLE |
* NFSATTRBIT_RDATTRERROR)
@@ -1118,6 +1231,7 @@ struct nfsv3_sattr {
#define NFSATTRBIT_READDIRPLUS0 (NFSATTRBIT_GETATTR0 | NFSATTRBM_FILEHANDLE | \
NFSATTRBM_RDATTRERROR)
#define NFSATTRBIT_READDIRPLUS1 NFSATTRBIT_GETATTR1
+#define NFSATTRBIT_READDIRPLUS2 0
/*
* Set of attributes supported by Referral vnodes.
@@ -1125,6 +1239,7 @@ struct nfsv3_sattr {
#define NFSATTRBIT_REFERRAL0 (NFSATTRBM_TYPE | NFSATTRBM_FSID | \
NFSATTRBM_RDATTRERROR | NFSATTRBM_FSLOCATIONS)
#define NFSATTRBIT_REFERRAL1 NFSATTRBM_MOUNTEDONFILEID
+#define NFSATTRBIT_REFERRAL2 0
/*
* Structure for data handled by the statfs rpc. Since some fields are
Modified: stable/10/sys/fs/nfs/nfsrvstate.h
==============================================================================
--- stable/10/sys/fs/nfs/nfsrvstate.h Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfs/nfsrvstate.h Fri Aug 1 21:10:41 2014 (r269398)
@@ -42,6 +42,8 @@ LIST_HEAD(nfsclienthashhead, nfsclient);
LIST_HEAD(nfsstatehead, nfsstate);
LIST_HEAD(nfslockhead, nfslock);
LIST_HEAD(nfslockhashhead, nfslockfile);
+LIST_HEAD(nfssessionhead, nfsdsession);
+LIST_HEAD(nfssessionhashhead, nfsdsession);
/*
* List head for nfsusrgrp.
@@ -64,6 +66,13 @@ TAILQ_HEAD(nfsuserlruhead, nfsusrgrp);
(&nfsgroupnamehash[((l)>=4?(*(p)+*((p)+1)+*((p)+2)+*((p)+3)):*(p)) \
% NFSGROUPHASHSIZE])
+struct nfssessionhash {
+ struct mtx mtx;
+ struct nfssessionhashhead list;
+};
+#define NFSSESSIONHASH(f) \
+ (&nfssessionhash[nfsrv_hashsessionid(f) % NFSSESSIONHASHSIZE])
+
/*
* Client server structure for V4. It is doubly linked into two lists.
* The first is a hash table based on the clientid and the second is a
@@ -76,6 +85,7 @@ struct nfsclient {
struct nfsstatehead lc_open; /* Open owner list */
struct nfsstatehead lc_deleg; /* Delegations */
struct nfsstatehead lc_olddeleg; /* and old delegations */
+ struct nfssessionhead lc_session; /* List of NFSv4.1 sessions */
time_t lc_expiry; /* Expiry time (sec) */
time_t lc_delegtime; /* Old deleg expiry (sec) */
nfsquad_t lc_clientid; /* 64 bit clientid */
@@ -101,6 +111,43 @@ struct nfsclient {
#define CLOPS_RENEWOP 0x0004
/*
+ * Structure for an NFSv4.1 session.
+ * Locking rules for this structure.
+ * To add/delete one of these structures from the lists, you must lock
+ * both: NFSLOCKSESSION(session hashhead) and NFSLOCKSTATE() in that order.
+ * To traverse the lists looking for one of these, you must hold one
+ * of these two locks.
+ * The exception is if the thread holds the exclusive root sleep lock.
+ * In this case, all other nfsd threads are blocked, so locking the
+ * mutexes isn't required.
+ * When manipulating sess_refcnt, NFSLOCKSTATE() must be locked.
+ * When manipulating the fields withinsess_cbsess except nfsess_xprt,
+ * sess_cbsess.nfsess_mtx must be locked.
+ * When manipulating sess_slots and sess_cbsess.nfsess_xprt,
+ * NFSLOCKSESSION(session hashhead) must be locked.
+ */
+struct nfsdsession {
+ uint64_t sess_refcnt; /* Reference count. */
+ LIST_ENTRY(nfsdsession) sess_hash; /* Hash list of sessions. */
+ LIST_ENTRY(nfsdsession) sess_list; /* List of client sessions. */
+ struct nfsslot sess_slots[NFSV4_SLOTS];
+ struct nfsclient *sess_clp; /* Associated clientid. */
+ uint32_t sess_crflags;
+ uint32_t sess_cbprogram;
+ uint32_t sess_maxreq;
+ uint32_t sess_maxresp;
+ uint32_t sess_maxrespcached;
+ uint32_t sess_maxops;
+ uint32_t sess_maxslots;
+ uint32_t sess_cbmaxreq;
+ uint32_t sess_cbmaxresp;
+ uint32_t sess_cbmaxrespcached;
+ uint32_t sess_cbmaxops;
+ uint8_t sess_sessionid[NFSX_V4SESSIONID];
+ struct nfsclsession sess_cbsess; /* Callback session. */
+};
+
+/*
* Nfs state structure. I couldn't resist overloading this one, since
* it makes cleanup, etc. simpler. These structures are used in four ways:
* - open_owner structures chained off of nfsclient
Modified: stable/10/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- stable/10/sys/fs/nfsclient/nfs_clstate.c Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfsclient/nfs_clstate.c Fri Aug 1 21:10:41 2014 (r269398)
@@ -3548,7 +3548,7 @@ out:
if (clp != NULL) {
nfsv4_seqsess_cacherep(slotid,
NFSMNT_MDSSESSION(clp->nfsc_nmp)->nfsess_cbslots,
- rep);
+ NFSERR_OK, &rep);
NFSUNLOCKCLSTATE();
} else {
NFSUNLOCKCLSTATE();
Modified: stable/10/sys/fs/nfsserver/nfs_nfsdcache.c
==============================================================================
--- stable/10/sys/fs/nfsserver/nfs_nfsdcache.c Fri Aug 1 21:00:18 2014 (r269397)
+++ stable/10/sys/fs/nfsserver/nfs_nfsdcache.c Fri Aug 1 21:10:41 2014 (r269398)
@@ -977,6 +977,9 @@ nfsrvd_refcache(struct nfsrvcache *rp)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable
mailing list