1191783Srmacklem/*- 2191783Srmacklem * Copyright (c) 2009 Rick Macklem, University of Guelph 3191783Srmacklem * All rights reserved. 4191783Srmacklem * 5191783Srmacklem * Redistribution and use in source and binary forms, with or without 6191783Srmacklem * modification, are permitted provided that the following conditions 7191783Srmacklem * are met: 8191783Srmacklem * 1. Redistributions of source code must retain the above copyright 9191783Srmacklem * notice, this list of conditions and the following disclaimer. 10191783Srmacklem * 2. Redistributions in binary form must reproduce the above copyright 11191783Srmacklem * notice, this list of conditions and the following disclaimer in the 12191783Srmacklem * documentation and/or other materials provided with the distribution. 13191783Srmacklem * 14191783Srmacklem * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15191783Srmacklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16191783Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17191783Srmacklem * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18191783Srmacklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19191783Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20191783Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22191783Srmacklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23191783Srmacklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24191783Srmacklem * SUCH DAMAGE. 25191783Srmacklem * 26191783Srmacklem * $FreeBSD: releng/10.2/sys/fs/nfs/nfsclstate.h 269398 2014-08-01 21:10:41Z rmacklem $ 27191783Srmacklem */ 28191783Srmacklem 29191783Srmacklem#ifndef _NFS_NFSCLSTATE_H_ 30191783Srmacklem#define _NFS_NFSCLSTATE_H_ 31191783Srmacklem 32191783Srmacklem/* 33191783Srmacklem * Definitions for NFS V4 client state handling. 34191783Srmacklem */ 35191783SrmacklemLIST_HEAD(nfsclopenhead, nfsclopen); 36191783SrmacklemLIST_HEAD(nfscllockownerhead, nfscllockowner); 37228217SrmacklemSLIST_HEAD(nfscllockownerfhhead, nfscllockownerfh); 38191783SrmacklemLIST_HEAD(nfscllockhead, nfscllock); 39191783SrmacklemLIST_HEAD(nfsclhead, nfsclclient); 40191783SrmacklemLIST_HEAD(nfsclownerhead, nfsclowner); 41191783SrmacklemTAILQ_HEAD(nfscldeleghead, nfscldeleg); 42191783SrmacklemLIST_HEAD(nfscldeleghash, nfscldeleg); 43244042SrmacklemTAILQ_HEAD(nfscllayouthead, nfscllayout); 44244042SrmacklemLIST_HEAD(nfscllayouthash, nfscllayout); 45244042SrmacklemLIST_HEAD(nfsclflayouthead, nfsclflayout); 46244042SrmacklemLIST_HEAD(nfscldevinfohead, nfscldevinfo); 47244042SrmacklemLIST_HEAD(nfsclrecalllayouthead, nfsclrecalllayout); 48191783Srmacklem#define NFSCLDELEGHASHSIZE 256 49244042Srmacklem#define NFSCLDELEGHASH(c, f, l) \ 50191783Srmacklem (&((c)->nfsc_deleghash[ncl_hash((f), (l)) % NFSCLDELEGHASHSIZE])) 51244042Srmacklem#define NFSCLLAYOUTHASHSIZE 256 52244042Srmacklem#define NFSCLLAYOUTHASH(c, f, l) \ 53244042Srmacklem (&((c)->nfsc_layouthash[ncl_hash((f), (l)) % NFSCLLAYOUTHASHSIZE])) 54191783Srmacklem 55244042Srmacklem/* Structure for NFSv4.1 session stuff. */ 56244042Srmacklemstruct nfsclsession { 57244042Srmacklem struct mtx nfsess_mtx; 58244042Srmacklem struct nfsslot nfsess_cbslots[NFSV4_CBSLOTS]; 59244042Srmacklem nfsquad_t nfsess_clientid; 60269398Srmacklem SVCXPRT *nfsess_xprt; /* For backchannel callback */ 61244042Srmacklem uint32_t nfsess_slotseq[64]; /* Max for 64bit nm_slots */ 62244042Srmacklem uint64_t nfsess_slots; 63244042Srmacklem uint32_t nfsess_sequenceid; 64244042Srmacklem uint32_t nfsess_maxcache; /* Max size for cached reply. */ 65244042Srmacklem uint16_t nfsess_foreslots; 66244042Srmacklem uint16_t nfsess_backslots; 67244042Srmacklem uint8_t nfsess_sessionid[NFSX_V4SESSIONID]; 68244042Srmacklem}; 69244042Srmacklem 70244042Srmacklem/* 71244042Srmacklem * This structure holds the session, clientid and related information 72244042Srmacklem * needed for an NFSv4.1 Meta Data Server (MDS) or Data Server (DS). 73244042Srmacklem * It is malloc'd to the correct length. 74244042Srmacklem */ 75244042Srmacklemstruct nfsclds { 76244042Srmacklem TAILQ_ENTRY(nfsclds) nfsclds_list; 77244042Srmacklem struct nfsclsession nfsclds_sess; 78244042Srmacklem struct mtx nfsclds_mtx; 79244042Srmacklem struct nfssockreq *nfsclds_sockp; 80244042Srmacklem time_t nfsclds_expire; 81244042Srmacklem uint16_t nfsclds_flags; 82244042Srmacklem uint16_t nfsclds_servownlen; 83244042Srmacklem uint8_t nfsclds_verf[NFSX_VERF]; 84244042Srmacklem uint8_t nfsclds_serverown[0]; 85244042Srmacklem}; 86244042Srmacklem 87244042Srmacklem/* 88244042Srmacklem * Flags for nfsclds_flags. 89244042Srmacklem */ 90244042Srmacklem#define NFSCLDS_HASWRITEVERF 0x0001 91244042Srmacklem#define NFSCLDS_MDS 0x0002 92244042Srmacklem#define NFSCLDS_DS 0x0004 93244042Srmacklem 94191783Srmacklemstruct nfsclclient { 95191783Srmacklem LIST_ENTRY(nfsclclient) nfsc_list; 96191783Srmacklem struct nfsclownerhead nfsc_owner; 97191783Srmacklem struct nfscldeleghead nfsc_deleg; 98191783Srmacklem struct nfscldeleghash nfsc_deleghash[NFSCLDELEGHASHSIZE]; 99244042Srmacklem struct nfscllayouthead nfsc_layout; 100244042Srmacklem struct nfscllayouthash nfsc_layouthash[NFSCLLAYOUTHASHSIZE]; 101244042Srmacklem struct nfscldevinfohead nfsc_devinfo; 102244042Srmacklem struct nfsv4lock nfsc_lock; 103244042Srmacklem struct proc *nfsc_renewthread; 104244042Srmacklem struct nfsmount *nfsc_nmp; 105244042Srmacklem time_t nfsc_expire; 106244042Srmacklem u_int32_t nfsc_clientidrev; 107244042Srmacklem u_int32_t nfsc_rev; 108244042Srmacklem u_int32_t nfsc_renew; 109244042Srmacklem u_int32_t nfsc_cbident; 110244042Srmacklem u_int16_t nfsc_flags; 111244042Srmacklem u_int16_t nfsc_idlen; 112244042Srmacklem u_int8_t nfsc_id[1]; /* Malloc'd to correct length */ 113191783Srmacklem}; 114191783Srmacklem 115191783Srmacklem/* 116191783Srmacklem * Bits for nfsc_flags. 117191783Srmacklem */ 118191783Srmacklem#define NFSCLFLAGS_INITED 0x0001 119191783Srmacklem#define NFSCLFLAGS_HASCLIENTID 0x0002 120191783Srmacklem#define NFSCLFLAGS_RECOVER 0x0004 121191783Srmacklem#define NFSCLFLAGS_UMOUNT 0x0008 122191783Srmacklem#define NFSCLFLAGS_HASTHREAD 0x0010 123191783Srmacklem#define NFSCLFLAGS_AFINET6 0x0020 124191783Srmacklem#define NFSCLFLAGS_EXPIREIT 0x0040 125191783Srmacklem#define NFSCLFLAGS_FIRSTDELEG 0x0080 126191783Srmacklem#define NFSCLFLAGS_GOTDELEG 0x0100 127206818Srmacklem#define NFSCLFLAGS_RECVRINPROG 0x0200 128191783Srmacklem 129191783Srmacklemstruct nfsclowner { 130191783Srmacklem LIST_ENTRY(nfsclowner) nfsow_list; 131191783Srmacklem struct nfsclopenhead nfsow_open; 132191783Srmacklem struct nfsclclient *nfsow_clp; 133191783Srmacklem u_int32_t nfsow_seqid; 134191783Srmacklem u_int32_t nfsow_defunct; 135191783Srmacklem struct nfsv4lock nfsow_rwlock; 136191783Srmacklem u_int8_t nfsow_owner[NFSV4CL_LOCKNAMELEN]; 137191783Srmacklem}; 138191783Srmacklem 139191783Srmacklem/* 140191783Srmacklem * MALLOC'd to the correct length to accommodate the file handle. 141191783Srmacklem */ 142191783Srmacklemstruct nfscldeleg { 143191783Srmacklem TAILQ_ENTRY(nfscldeleg) nfsdl_list; 144191783Srmacklem LIST_ENTRY(nfscldeleg) nfsdl_hash; 145191783Srmacklem struct nfsclownerhead nfsdl_owner; /* locally issued state */ 146191783Srmacklem struct nfscllockownerhead nfsdl_lock; 147191783Srmacklem nfsv4stateid_t nfsdl_stateid; 148191783Srmacklem struct acl_entry nfsdl_ace; /* Delegation ace */ 149191783Srmacklem struct nfsclclient *nfsdl_clp; 150191783Srmacklem struct nfsv4lock nfsdl_rwlock; /* for active I/O ops */ 151191783Srmacklem struct nfscred nfsdl_cred; /* Cred. used for Open */ 152191783Srmacklem time_t nfsdl_timestamp; /* used for stale cleanup */ 153191783Srmacklem u_int64_t nfsdl_sizelimit; /* Limit for file growth */ 154191783Srmacklem u_int64_t nfsdl_size; /* saved copy of file size */ 155191783Srmacklem u_int64_t nfsdl_change; /* and change attribute */ 156191783Srmacklem struct timespec nfsdl_modtime; /* local modify time */ 157191783Srmacklem u_int16_t nfsdl_fhlen; 158191783Srmacklem u_int8_t nfsdl_flags; 159191783Srmacklem u_int8_t nfsdl_fh[1]; /* must be last */ 160191783Srmacklem}; 161191783Srmacklem 162191783Srmacklem/* 163191783Srmacklem * nfsdl_flags bits. 164191783Srmacklem */ 165191783Srmacklem#define NFSCLDL_READ 0x01 166191783Srmacklem#define NFSCLDL_WRITE 0x02 167191783Srmacklem#define NFSCLDL_RECALL 0x04 168191783Srmacklem#define NFSCLDL_NEEDRECLAIM 0x08 169191783Srmacklem#define NFSCLDL_ZAPPED 0x10 170191783Srmacklem#define NFSCLDL_MODTIMESET 0x20 171214406Srmacklem#define NFSCLDL_DELEGRET 0x40 172191783Srmacklem 173191783Srmacklem/* 174191783Srmacklem * MALLOC'd to the correct length to accommodate the file handle. 175191783Srmacklem */ 176191783Srmacklemstruct nfsclopen { 177191783Srmacklem LIST_ENTRY(nfsclopen) nfso_list; 178191783Srmacklem struct nfscllockownerhead nfso_lock; 179191783Srmacklem nfsv4stateid_t nfso_stateid; 180191783Srmacklem struct nfsclowner *nfso_own; 181191783Srmacklem struct nfscred nfso_cred; /* Cred. used for Open */ 182191783Srmacklem u_int32_t nfso_mode; 183191783Srmacklem u_int32_t nfso_opencnt; 184191783Srmacklem u_int16_t nfso_fhlen; 185191783Srmacklem u_int8_t nfso_posixlock; /* 1 for POSIX type locking */ 186191783Srmacklem u_int8_t nfso_fh[1]; /* must be last */ 187191783Srmacklem}; 188191783Srmacklem 189191783Srmacklem/* 190191783Srmacklem * Return values for nfscl_open(). NFSCLOPEN_OK must == 0. 191191783Srmacklem */ 192191783Srmacklem#define NFSCLOPEN_OK 0 193191783Srmacklem#define NFSCLOPEN_DOOPEN 1 194191783Srmacklem#define NFSCLOPEN_DOOPENDOWNGRADE 2 195206688Srmacklem#define NFSCLOPEN_SETCRED 3 196191783Srmacklem 197191783Srmacklemstruct nfscllockowner { 198191783Srmacklem LIST_ENTRY(nfscllockowner) nfsl_list; 199191783Srmacklem struct nfscllockhead nfsl_lock; 200191783Srmacklem struct nfsclopen *nfsl_open; 201191783Srmacklem NFSPROC_T *nfsl_inprog; 202191783Srmacklem nfsv4stateid_t nfsl_stateid; 203228217Srmacklem int nfsl_lockflags; 204191783Srmacklem u_int32_t nfsl_seqid; 205191783Srmacklem struct nfsv4lock nfsl_rwlock; 206191783Srmacklem u_int8_t nfsl_owner[NFSV4CL_LOCKNAMELEN]; 207191783Srmacklem u_int8_t nfsl_openowner[NFSV4CL_LOCKNAMELEN]; 208191783Srmacklem}; 209191783Srmacklem 210191783Srmacklem/* 211191783Srmacklem * Byte range entry for the above lock owner. 212191783Srmacklem */ 213191783Srmacklemstruct nfscllock { 214191783Srmacklem LIST_ENTRY(nfscllock) nfslo_list; 215191783Srmacklem u_int64_t nfslo_first; 216191783Srmacklem u_int64_t nfslo_end; 217191783Srmacklem short nfslo_type; 218191783Srmacklem}; 219191783Srmacklem 220228217Srmacklem/* This structure is used to collect a list of lockowners to free up. */ 221228217Srmacklemstruct nfscllockownerfh { 222228217Srmacklem SLIST_ENTRY(nfscllockownerfh) nfslfh_list; 223228217Srmacklem struct nfscllockownerhead nfslfh_lock; 224228217Srmacklem int nfslfh_len; 225228217Srmacklem uint8_t nfslfh_fh[NFSX_V4FHMAX]; 226228217Srmacklem}; 227228217Srmacklem 228191783Srmacklem/* 229244042Srmacklem * MALLOC'd to the correct length to accommodate the file handle. 230244042Srmacklem */ 231244042Srmacklemstruct nfscllayout { 232244042Srmacklem TAILQ_ENTRY(nfscllayout) nfsly_list; 233244042Srmacklem LIST_ENTRY(nfscllayout) nfsly_hash; 234244042Srmacklem nfsv4stateid_t nfsly_stateid; 235244042Srmacklem struct nfsv4lock nfsly_lock; 236244042Srmacklem uint64_t nfsly_filesid[2]; 237244042Srmacklem uint64_t nfsly_lastbyte; 238244042Srmacklem struct nfsclflayouthead nfsly_flayread; 239244042Srmacklem struct nfsclflayouthead nfsly_flayrw; 240244042Srmacklem struct nfsclrecalllayouthead nfsly_recall; 241244042Srmacklem time_t nfsly_timestamp; 242244042Srmacklem struct nfsclclient *nfsly_clp; 243244042Srmacklem uint16_t nfsly_flags; 244244042Srmacklem uint16_t nfsly_fhlen; 245244042Srmacklem uint8_t nfsly_fh[1]; 246244042Srmacklem}; 247244042Srmacklem 248244042Srmacklem/* 249244042Srmacklem * Flags for nfsly_flags. 250244042Srmacklem */ 251244042Srmacklem#define NFSLY_FILES 0x0001 252244042Srmacklem#define NFSLY_BLOCK 0x0002 253244042Srmacklem#define NFSLY_OBJECT 0x0004 254244042Srmacklem#define NFSLY_RECALL 0x0008 255244042Srmacklem#define NFSLY_RECALLFILE 0x0010 256244042Srmacklem#define NFSLY_RECALLFSID 0x0020 257244042Srmacklem#define NFSLY_RECALLALL 0x0040 258244042Srmacklem#define NFSLY_RETONCLOSE 0x0080 259244042Srmacklem#define NFSLY_WRITTEN 0x0100 /* Has been used to write to a DS. */ 260244042Srmacklem 261244042Srmacklem/* 262244042Srmacklem * MALLOC'd to the correct length to accommodate the file handle list. 263244042Srmacklem * These hang off of nfsly_flayread and nfsly_flayrw, sorted in increasing 264244042Srmacklem * offset order. 265244042Srmacklem * The nfsly_flayread list holds the ones with iomode == NFSLAYOUTIOMODE_READ, 266244042Srmacklem * whereas the nfsly_flayrw holds the ones with iomode == NFSLAYOUTIOMODE_RW. 267244042Srmacklem */ 268244042Srmacklemstruct nfsclflayout { 269244042Srmacklem LIST_ENTRY(nfsclflayout) nfsfl_list; 270244042Srmacklem uint8_t nfsfl_dev[NFSX_V4DEVICEID]; 271244042Srmacklem uint64_t nfsfl_off; 272244042Srmacklem uint64_t nfsfl_end; 273244042Srmacklem uint64_t nfsfl_patoff; 274244042Srmacklem struct nfscldevinfo *nfsfl_devp; 275244042Srmacklem uint32_t nfsfl_iomode; 276244042Srmacklem uint32_t nfsfl_util; 277244042Srmacklem uint32_t nfsfl_stripe1; 278244042Srmacklem uint16_t nfsfl_flags; 279244042Srmacklem uint16_t nfsfl_fhcnt; 280244042Srmacklem struct nfsfh *nfsfl_fh[1]; /* FH list for DS */ 281244042Srmacklem}; 282244042Srmacklem 283244042Srmacklem/* 284244042Srmacklem * Flags for nfsfl_flags. 285244042Srmacklem */ 286244042Srmacklem#define NFSFL_RECALL 0x0001 /* File layout has been recalled */ 287244042Srmacklem 288244042Srmacklem/* 289244042Srmacklem * Structure that is used to store a LAYOUTRECALL. 290244042Srmacklem */ 291244042Srmacklemstruct nfsclrecalllayout { 292244042Srmacklem LIST_ENTRY(nfsclrecalllayout) nfsrecly_list; 293244042Srmacklem uint64_t nfsrecly_off; 294244042Srmacklem uint64_t nfsrecly_len; 295244042Srmacklem int nfsrecly_recalltype; 296244042Srmacklem uint32_t nfsrecly_iomode; 297244042Srmacklem uint32_t nfsrecly_stateseqid; 298244042Srmacklem}; 299244042Srmacklem 300244042Srmacklem/* 301244042Srmacklem * Stores the NFSv4.1 Device Info. Malloc'd to the correct length to 302244042Srmacklem * store the list of network connections and list of indices. 303244042Srmacklem * nfsdi_data[] is allocated the following way: 304244042Srmacklem * - nfsdi_addrcnt * struct nfsclds 305244042Srmacklem * - stripe indices, each stored as one byte, since there can be many 306244042Srmacklem * of them. (This implies a limit of 256 on nfsdi_addrcnt, since the 307244042Srmacklem * indices select which address.) 308244042Srmacklem */ 309244042Srmacklemstruct nfscldevinfo { 310244042Srmacklem LIST_ENTRY(nfscldevinfo) nfsdi_list; 311244042Srmacklem uint8_t nfsdi_deviceid[NFSX_V4DEVICEID]; 312244042Srmacklem struct nfsclclient *nfsdi_clp; 313244042Srmacklem uint32_t nfsdi_refcnt; 314244042Srmacklem uint32_t nfsdi_layoutrefs; 315244042Srmacklem uint16_t nfsdi_stripecnt; 316244042Srmacklem uint16_t nfsdi_addrcnt; 317244042Srmacklem struct nfsclds *nfsdi_data[0]; 318244042Srmacklem}; 319244042Srmacklem 320244042Srmacklem/* These inline functions return values from nfsdi_data[]. */ 321244042Srmacklem/* 322244042Srmacklem * Return a pointer to the address at "pos". 323244042Srmacklem */ 324244042Srmacklemstatic __inline struct nfsclds ** 325244042Srmacklemnfsfldi_addr(struct nfscldevinfo *ndi, int pos) 326244042Srmacklem{ 327244042Srmacklem 328244042Srmacklem if (pos >= ndi->nfsdi_addrcnt) 329244042Srmacklem return (NULL); 330244042Srmacklem return (&ndi->nfsdi_data[pos]); 331244042Srmacklem} 332244042Srmacklem 333244042Srmacklem/* 334244042Srmacklem * Return the Nth ("pos") stripe index. 335244042Srmacklem */ 336244042Srmacklemstatic __inline int 337244042Srmacklemnfsfldi_stripeindex(struct nfscldevinfo *ndi, int pos) 338244042Srmacklem{ 339244042Srmacklem uint8_t *valp; 340244042Srmacklem 341244042Srmacklem if (pos >= ndi->nfsdi_stripecnt) 342244042Srmacklem return (-1); 343244042Srmacklem valp = (uint8_t *)&ndi->nfsdi_data[ndi->nfsdi_addrcnt]; 344244042Srmacklem valp += pos; 345244042Srmacklem return ((int)*valp); 346244042Srmacklem} 347244042Srmacklem 348244042Srmacklem/* 349244042Srmacklem * Set the Nth ("pos") stripe index to "val". 350244042Srmacklem */ 351244042Srmacklemstatic __inline void 352244042Srmacklemnfsfldi_setstripeindex(struct nfscldevinfo *ndi, int pos, uint8_t val) 353244042Srmacklem{ 354244042Srmacklem uint8_t *valp; 355244042Srmacklem 356244042Srmacklem if (pos >= ndi->nfsdi_stripecnt) 357244042Srmacklem return; 358244042Srmacklem valp = (uint8_t *)&ndi->nfsdi_data[ndi->nfsdi_addrcnt]; 359244042Srmacklem valp += pos; 360244042Srmacklem *valp = val; 361244042Srmacklem} 362244042Srmacklem 363244042Srmacklem/* 364191783Srmacklem * Macro for incrementing the seqid#. 365191783Srmacklem */ 366191783Srmacklem#define NFSCL_INCRSEQID(s, n) do { \ 367191783Srmacklem if (((n)->nd_flag & ND_INCRSEQID)) \ 368191783Srmacklem (s)++; \ 369191783Srmacklem } while (0) 370191783Srmacklem 371191783Srmacklem#endif /* _NFS_NFSCLSTATE_H_ */ 372