diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2012-12-08 22:52:39 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2012-12-08 22:52:39 +0000 |
commit | c82d89183db93c8a4a4a1db712fa5464d28ff9a3 (patch) | |
tree | 1d0d5926e781fef2471af6865dd51ab8fbdb8620 /sys/fs/nfs/nfsclstate.h | |
parent | 98601953890f2c4381eda07f2914bfc1f8b114ec (diff) | |
download | FreeBSD-src-c82d89183db93c8a4a4a1db712fa5464d28ff9a3.zip FreeBSD-src-c82d89183db93c8a4a4a1db712fa5464d28ff9a3.tar.gz |
Move the NFSv4.1 client patches over from projects/nfsv4.1-client
to head. I don't think the NFS client behaviour will change unless
the new "minorversion=1" mount option is used. It includes basic
NFSv4.1 support plus support for pNFS using the Files Layout only.
All problems detecting during an NFSv4.1 Bakeathon testing event
in June 2012 have been resolved in this code and it has been tested
against the NFSv4.1 server available to me.
Although not reviewed, I believe that kib@ has looked at it.
Diffstat (limited to 'sys/fs/nfs/nfsclstate.h')
-rw-r--r-- | sys/fs/nfs/nfsclstate.h | 208 |
1 files changed, 196 insertions, 12 deletions
diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h index 868e7cf..aa2bfee 100644 --- a/sys/fs/nfs/nfsclstate.h +++ b/sys/fs/nfs/nfsclstate.h @@ -40,26 +40,75 @@ LIST_HEAD(nfsclhead, nfsclclient); LIST_HEAD(nfsclownerhead, nfsclowner); TAILQ_HEAD(nfscldeleghead, nfscldeleg); LIST_HEAD(nfscldeleghash, nfscldeleg); +TAILQ_HEAD(nfscllayouthead, nfscllayout); +LIST_HEAD(nfscllayouthash, nfscllayout); +LIST_HEAD(nfsclflayouthead, nfsclflayout); +LIST_HEAD(nfscldevinfohead, nfscldevinfo); +LIST_HEAD(nfsclrecalllayouthead, nfsclrecalllayout); #define NFSCLDELEGHASHSIZE 256 -#define NFSCLDELEGHASH(c, f, l) \ +#define NFSCLDELEGHASH(c, f, l) \ (&((c)->nfsc_deleghash[ncl_hash((f), (l)) % NFSCLDELEGHASHSIZE])) +#define NFSCLLAYOUTHASHSIZE 256 +#define NFSCLLAYOUTHASH(c, f, l) \ + (&((c)->nfsc_layouthash[ncl_hash((f), (l)) % NFSCLLAYOUTHASHSIZE])) + +/* Structure for NFSv4.1 session stuff. */ +struct nfsclsession { + struct mtx nfsess_mtx; + struct nfsslot nfsess_cbslots[NFSV4_CBSLOTS]; + nfsquad_t nfsess_clientid; + uint32_t nfsess_slotseq[64]; /* Max for 64bit nm_slots */ + uint64_t nfsess_slots; + uint32_t nfsess_sequenceid; + uint32_t nfsess_maxcache; /* Max size for cached reply. */ + uint16_t nfsess_foreslots; + uint16_t nfsess_backslots; + uint8_t nfsess_sessionid[NFSX_V4SESSIONID]; +}; + +/* + * This structure holds the session, clientid and related information + * needed for an NFSv4.1 Meta Data Server (MDS) or Data Server (DS). + * It is malloc'd to the correct length. + */ +struct nfsclds { + TAILQ_ENTRY(nfsclds) nfsclds_list; + struct nfsclsession nfsclds_sess; + struct mtx nfsclds_mtx; + struct nfssockreq *nfsclds_sockp; + time_t nfsclds_expire; + uint16_t nfsclds_flags; + uint16_t nfsclds_servownlen; + uint8_t nfsclds_verf[NFSX_VERF]; + uint8_t nfsclds_serverown[0]; +}; + +/* + * Flags for nfsclds_flags. + */ +#define NFSCLDS_HASWRITEVERF 0x0001 +#define NFSCLDS_MDS 0x0002 +#define NFSCLDS_DS 0x0004 struct nfsclclient { LIST_ENTRY(nfsclclient) nfsc_list; struct nfsclownerhead nfsc_owner; struct nfscldeleghead nfsc_deleg; struct nfscldeleghash nfsc_deleghash[NFSCLDELEGHASHSIZE]; - struct nfsv4lock nfsc_lock; - struct proc *nfsc_renewthread; - struct nfsmount *nfsc_nmp; - nfsquad_t nfsc_clientid; - time_t nfsc_expire; - u_int32_t nfsc_clientidrev; - u_int32_t nfsc_renew; - u_int32_t nfsc_cbident; - u_int16_t nfsc_flags; - u_int16_t nfsc_idlen; - u_int8_t nfsc_id[1]; /* Malloc'd to correct length */ + struct nfscllayouthead nfsc_layout; + struct nfscllayouthash nfsc_layouthash[NFSCLLAYOUTHASHSIZE]; + struct nfscldevinfohead nfsc_devinfo; + struct nfsv4lock nfsc_lock; + struct proc *nfsc_renewthread; + struct nfsmount *nfsc_nmp; + time_t nfsc_expire; + u_int32_t nfsc_clientidrev; + u_int32_t nfsc_rev; + u_int32_t nfsc_renew; + u_int32_t nfsc_cbident; + u_int16_t nfsc_flags; + u_int16_t nfsc_idlen; + u_int8_t nfsc_id[1]; /* Malloc'd to correct length */ }; /* @@ -176,6 +225,141 @@ struct nfscllockownerfh { }; /* + * MALLOC'd to the correct length to accommodate the file handle. + */ +struct nfscllayout { + TAILQ_ENTRY(nfscllayout) nfsly_list; + LIST_ENTRY(nfscllayout) nfsly_hash; + nfsv4stateid_t nfsly_stateid; + struct nfsv4lock nfsly_lock; + uint64_t nfsly_filesid[2]; + uint64_t nfsly_lastbyte; + struct nfsclflayouthead nfsly_flayread; + struct nfsclflayouthead nfsly_flayrw; + struct nfsclrecalllayouthead nfsly_recall; + time_t nfsly_timestamp; + struct nfsclclient *nfsly_clp; + uint16_t nfsly_flags; + uint16_t nfsly_fhlen; + uint8_t nfsly_fh[1]; +}; + +/* + * Flags for nfsly_flags. + */ +#define NFSLY_FILES 0x0001 +#define NFSLY_BLOCK 0x0002 +#define NFSLY_OBJECT 0x0004 +#define NFSLY_RECALL 0x0008 +#define NFSLY_RECALLFILE 0x0010 +#define NFSLY_RECALLFSID 0x0020 +#define NFSLY_RECALLALL 0x0040 +#define NFSLY_RETONCLOSE 0x0080 +#define NFSLY_WRITTEN 0x0100 /* Has been used to write to a DS. */ + +/* + * MALLOC'd to the correct length to accommodate the file handle list. + * These hang off of nfsly_flayread and nfsly_flayrw, sorted in increasing + * offset order. + * The nfsly_flayread list holds the ones with iomode == NFSLAYOUTIOMODE_READ, + * whereas the nfsly_flayrw holds the ones with iomode == NFSLAYOUTIOMODE_RW. + */ +struct nfsclflayout { + LIST_ENTRY(nfsclflayout) nfsfl_list; + uint8_t nfsfl_dev[NFSX_V4DEVICEID]; + uint64_t nfsfl_off; + uint64_t nfsfl_end; + uint64_t nfsfl_patoff; + struct nfscldevinfo *nfsfl_devp; + uint32_t nfsfl_iomode; + uint32_t nfsfl_util; + uint32_t nfsfl_stripe1; + uint16_t nfsfl_flags; + uint16_t nfsfl_fhcnt; + struct nfsfh *nfsfl_fh[1]; /* FH list for DS */ +}; + +/* + * Flags for nfsfl_flags. + */ +#define NFSFL_RECALL 0x0001 /* File layout has been recalled */ + +/* + * Structure that is used to store a LAYOUTRECALL. + */ +struct nfsclrecalllayout { + LIST_ENTRY(nfsclrecalllayout) nfsrecly_list; + uint64_t nfsrecly_off; + uint64_t nfsrecly_len; + int nfsrecly_recalltype; + uint32_t nfsrecly_iomode; + uint32_t nfsrecly_stateseqid; +}; + +/* + * Stores the NFSv4.1 Device Info. Malloc'd to the correct length to + * store the list of network connections and list of indices. + * nfsdi_data[] is allocated the following way: + * - nfsdi_addrcnt * struct nfsclds + * - stripe indices, each stored as one byte, since there can be many + * of them. (This implies a limit of 256 on nfsdi_addrcnt, since the + * indices select which address.) + */ +struct nfscldevinfo { + LIST_ENTRY(nfscldevinfo) nfsdi_list; + uint8_t nfsdi_deviceid[NFSX_V4DEVICEID]; + struct nfsclclient *nfsdi_clp; + uint32_t nfsdi_refcnt; + uint32_t nfsdi_layoutrefs; + uint16_t nfsdi_stripecnt; + uint16_t nfsdi_addrcnt; + struct nfsclds *nfsdi_data[0]; +}; + +/* These inline functions return values from nfsdi_data[]. */ +/* + * Return a pointer to the address at "pos". + */ +static __inline struct nfsclds ** +nfsfldi_addr(struct nfscldevinfo *ndi, int pos) +{ + + if (pos >= ndi->nfsdi_addrcnt) + return (NULL); + return (&ndi->nfsdi_data[pos]); +} + +/* + * Return the Nth ("pos") stripe index. + */ +static __inline int +nfsfldi_stripeindex(struct nfscldevinfo *ndi, int pos) +{ + uint8_t *valp; + + if (pos >= ndi->nfsdi_stripecnt) + return (-1); + valp = (uint8_t *)&ndi->nfsdi_data[ndi->nfsdi_addrcnt]; + valp += pos; + return ((int)*valp); +} + +/* + * Set the Nth ("pos") stripe index to "val". + */ +static __inline void +nfsfldi_setstripeindex(struct nfscldevinfo *ndi, int pos, uint8_t val) +{ + uint8_t *valp; + + if (pos >= ndi->nfsdi_stripecnt) + return; + valp = (uint8_t *)&ndi->nfsdi_data[ndi->nfsdi_addrcnt]; + valp += pos; + *valp = val; +} + +/* * Macro for incrementing the seqid#. */ #define NFSCL_INCRSEQID(s, n) do { \ |