svn commit: r253533 - projects/nfsv4.1-server/sys/fs/nfs
Rick Macklem
rmacklem at FreeBSD.org
Sun Jul 21 21:10:56 UTC 2013
Author: rmacklem
Date: Sun Jul 21 21:10:53 2013
New Revision: 253533
URL: http://svnweb.freebsd.org/changeset/base/253533
Log:
Merge in the remaining changes for the NFSv4.1 server.
Modified:
projects/nfsv4.1-server/sys/fs/nfs/nfs.h
projects/nfsv4.1-server/sys/fs/nfs/nfs_commonport.c
projects/nfsv4.1-server/sys/fs/nfs/nfs_commonsubs.c
projects/nfsv4.1-server/sys/fs/nfs/nfs_var.h
projects/nfsv4.1-server/sys/fs/nfs/nfsdport.h
projects/nfsv4.1-server/sys/fs/nfs/nfsport.h
projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h
projects/nfsv4.1-server/sys/fs/nfs/nfsrvstate.h
Modified: projects/nfsv4.1-server/sys/fs/nfs/nfs.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfs.h Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfs.h Sun Jul 21 21:10:53 2013 (r253533)
@@ -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,7 @@ struct nfsreferral {
#define LCL_GSSINTEGRITY 0x00002000
#define LCL_GSSPRIVACY 0x00004000
#define LCL_ADMINREVOKED 0x00008000
+#define LCL_RECLAIMCOMPLETE 0x00010000
#define LCL_GSS LCL_KERBV /* Or of all mechs */
@@ -346,68 +351,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.
@@ -534,6 +591,8 @@ 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 */
};
#define nd_princlen nd_gssnamelen
@@ -567,6 +626,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: projects/nfsv4.1-server/sys/fs/nfs/nfs_commonport.c
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfs_commonport.c Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfs_commonport.c Sun Jul 21 21:10:53 2013 (r253533)
@@ -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: projects/nfsv4.1-server/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfs_commonsubs.c Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfs_commonsubs.c Sun Jul 21 21:10:53 2013 (r253533)
@@ -1732,6 +1732,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);
@@ -2463,6 +2480,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);
};
@@ -3647,6 +3670,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,
@@ -3655,7 +3681,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) {
@@ -3663,13 +3690,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++;
@@ -3680,12 +3712,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;
}
Modified: projects/nfsv4.1-server/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfs_var.h Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfs_var.h Sun Jul 21 21:10:53 2013 (r253533)
@@ -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,7 +289,7 @@ 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 nfsrv_descript *, struct nfsclsession *, int);
void nfsv4_freeslot(struct nfsclsession *, int);
@@ -321,6 +346,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);
@@ -630,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: projects/nfsv4.1-server/sys/fs/nfs/nfsdport.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfsdport.h Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfsdport.h Sun Jul 21 21:10:53 2013 (r253533)
@@ -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: projects/nfsv4.1-server/sys/fs/nfs/nfsport.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfsport.h Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfsport.h Sun Jul 21 21:10:53 2013 (r253533)
@@ -642,6 +642,8 @@ 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 NFSLOCKSESSION(s) mtx_lock(&((s)->mtx))
+#define NFSUNLOCKSESSION(s) mtx_unlock(&((s)->mtx))
/*
* Use these macros to initialize/free a mutex.
@@ -737,6 +739,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
@@ -762,6 +765,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: projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h Sun Jul 21 21:10:53 2013 (r253533)
@@ -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,6 +498,19 @@
#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.)
*/
@@ -805,6 +830,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 +908,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 +938,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 +1005,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 +1017,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 +1028,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 +1059,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 +1090,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 +1108,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 +1123,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 +1159,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 +1191,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 +1213,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 +1225,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 +1233,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: projects/nfsv4.1-server/sys/fs/nfs/nfsrvstate.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfsrvstate.h Sun Jul 21 20:45:23 2013 (r253532)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfsrvstate.h Sun Jul 21 21:10:53 2013 (r253533)
@@ -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,29 @@ struct nfsclient {
#define CLOPS_RENEWOP 0x0004
/*
+ * Structure for an NFSv4.1 session.
+ */
+struct nfsdsession {
+ 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;
+ uint32_t sess_cbmaxslots;
+ uint8_t sess_sessionid[NFSX_V4SESSIONID];
+};
+
+/*
* 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
More information about the svn-src-projects
mailing list