16007Sthurlow /* 26007Sthurlow * Copyright (c) 2000-2001, Boris Popov 36007Sthurlow * All rights reserved. 46007Sthurlow * 56007Sthurlow * Redistribution and use in source and binary forms, with or without 66007Sthurlow * modification, are permitted provided that the following conditions 76007Sthurlow * are met: 86007Sthurlow * 1. Redistributions of source code must retain the above copyright 96007Sthurlow * notice, this list of conditions and the following disclaimer. 106007Sthurlow * 2. Redistributions in binary form must reproduce the above copyright 116007Sthurlow * notice, this list of conditions and the following disclaimer in the 126007Sthurlow * documentation and/or other materials provided with the distribution. 136007Sthurlow * 3. All advertising materials mentioning features or use of this software 146007Sthurlow * must display the following acknowledgement: 156007Sthurlow * This product includes software developed by Boris Popov. 166007Sthurlow * 4. Neither the name of the author nor the names of any co-contributors 176007Sthurlow * may be used to endorse or promote products derived from this software 186007Sthurlow * without specific prior written permission. 196007Sthurlow * 206007Sthurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 216007Sthurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 226007Sthurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 236007Sthurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 246007Sthurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 256007Sthurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 266007Sthurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 276007Sthurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 286007Sthurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 296007Sthurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 306007Sthurlow * SUCH DAMAGE. 316007Sthurlow * 326007Sthurlow * $Id: smbfs_node.h,v 1.31.52.1 2005/05/27 02:35:28 lindak Exp $ 336007Sthurlow */ 346007Sthurlow 356007Sthurlow /* 36*11564SGordon.Ross@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 376007Sthurlow * Use is subject to license terms. 386007Sthurlow */ 396007Sthurlow 406007Sthurlow #ifndef _FS_SMBFS_NODE_H_ 416007Sthurlow #define _FS_SMBFS_NODE_H_ 426007Sthurlow 436007Sthurlow /* 446007Sthurlow * Much code copied into here from Sun NFS. 4511332SGordon.Ross@Sun.COM * Compare with nfs_clnt.h 466007Sthurlow */ 476007Sthurlow 486007Sthurlow #include <sys/avl.h> 496007Sthurlow #include <sys/list.h> 506007Sthurlow 516007Sthurlow #ifdef __cplusplus 526007Sthurlow extern "C" { 536007Sthurlow #endif 546007Sthurlow 5511332SGordon.Ross@Sun.COM /* 5611332SGordon.Ross@Sun.COM * These are the attributes we can get from the server via 5711332SGordon.Ross@Sun.COM * SMB commands such as TRANS2_QUERY_FILE_INFORMATION 5811332SGordon.Ross@Sun.COM * with info level SMB_QFILEINFO_ALL_INFO, and directory 5911332SGordon.Ross@Sun.COM * FindFirst/FindNext info. levels FIND_DIRECTORY_INFO 6011332SGordon.Ross@Sun.COM * and FIND_BOTH_DIRECTORY_INFO, etc. 6111332SGordon.Ross@Sun.COM * 6211332SGordon.Ross@Sun.COM * Values in this struct are always native endian, 6311332SGordon.Ross@Sun.COM * and times are converted converted to Unix form. 6411332SGordon.Ross@Sun.COM * Note: zero in any of the times means "unknown". 6511332SGordon.Ross@Sun.COM * 6611332SGordon.Ross@Sun.COM * XXX: Later, move this to nsmb 6711332SGordon.Ross@Sun.COM */ 6811332SGordon.Ross@Sun.COM typedef struct smbfattr { 6911332SGordon.Ross@Sun.COM timespec_t fa_createtime; /* Note, != ctime */ 7011332SGordon.Ross@Sun.COM timespec_t fa_atime; /* these 3 are like unix */ 7111332SGordon.Ross@Sun.COM timespec_t fa_mtime; 7211332SGordon.Ross@Sun.COM timespec_t fa_ctime; 7311332SGordon.Ross@Sun.COM u_offset_t fa_size; /* EOF position */ 7411332SGordon.Ross@Sun.COM u_offset_t fa_allocsz; /* Allocated size. */ 7511332SGordon.Ross@Sun.COM uint32_t fa_attr; /* Ext. file (DOS) attr */ 7611332SGordon.Ross@Sun.COM } smbfattr_t; 7711332SGordon.Ross@Sun.COM 7811332SGordon.Ross@Sun.COM /* 7911332SGordon.Ross@Sun.COM * Cache whole directories (not yet) 8011332SGordon.Ross@Sun.COM */ 816007Sthurlow typedef struct rddir_cache { 826007Sthurlow lloff_t _cookie; /* cookie used to find this cache entry */ 836007Sthurlow lloff_t _ncookie; /* cookie used to find the next cache entry */ 846007Sthurlow char *entries; /* buffer containing dirent entries */ 856007Sthurlow int eof; /* EOF reached after this request */ 866007Sthurlow int entlen; /* size of dirent entries in buf */ 876007Sthurlow int buflen; /* size of the buffer used to store entries */ 886007Sthurlow int flags; /* control flags, see below */ 896007Sthurlow kcondvar_t cv; /* cv for blocking */ 906007Sthurlow int error; /* error from RPC operation */ 916007Sthurlow kmutex_t lock; 926007Sthurlow uint_t count; /* reference count */ 936007Sthurlow avl_node_t tree; /* AVL tree links */ 946007Sthurlow } rddir_cache; 956007Sthurlow 966007Sthurlow #define smbfs_cookie _cookie._p._l 976007Sthurlow #define smbfs_ncookie _ncookie._p._l 986007Sthurlow #define smbfs3_cookie _cookie._f 996007Sthurlow #define smbfs3_ncookie _ncookie._f 1006007Sthurlow 1016007Sthurlow #define RDDIR 0x1 /* readdir operation in progress */ 1026007Sthurlow #define RDDIRWAIT 0x2 /* waiting on readdir in progress */ 1036007Sthurlow #define RDDIRREQ 0x4 /* a new readdir is required */ 1046007Sthurlow #define RDDIRCACHED 0x8 /* entry is in the cache */ 1056007Sthurlow 1066007Sthurlow #define HAVE_RDDIR_CACHE(rp) (avl_numnodes(&(rp)->r_dir) > 0) 1076007Sthurlow 1086007Sthurlow /* 1096007Sthurlow * A homegrown reader/writer lock implementation. It addresses 1106007Sthurlow * two requirements not addressed by the system primitives. They 1116007Sthurlow * are that the `enter" operation is optionally interruptible and 1126007Sthurlow * that that they can be re`enter'ed by writers without deadlock. 1136007Sthurlow */ 1146007Sthurlow typedef struct smbfs_rwlock { 1156007Sthurlow int count; 1166007Sthurlow int waiters; 1176007Sthurlow kthread_t *owner; 1186007Sthurlow kmutex_t lock; 1196007Sthurlow kcondvar_t cv; 1206007Sthurlow } smbfs_rwlock_t; 1216007Sthurlow 1226007Sthurlow /* 12311332SGordon.Ross@Sun.COM * The format of the smbfs node header, which contains the 12411332SGordon.Ross@Sun.COM * fields used to link nodes in the AVL tree, and those 12511332SGordon.Ross@Sun.COM * fields needed by the AVL node comparison functions. 12611332SGordon.Ross@Sun.COM * It's a separate struct so we can call avl_find with 12711332SGordon.Ross@Sun.COM * this relatively small struct as a stack local. 12811332SGordon.Ross@Sun.COM * 12911332SGordon.Ross@Sun.COM * The AVL tree is mntinfo.smi_hash_avl, 13011332SGordon.Ross@Sun.COM * and its lock is mntinfo.smi_hash_lk. 1316007Sthurlow */ 13211332SGordon.Ross@Sun.COM typedef struct smbfs_node_hdr { 13311332SGordon.Ross@Sun.COM /* 13411332SGordon.Ross@Sun.COM * Our linkage in the node cache AVL tree. 13511332SGordon.Ross@Sun.COM */ 13611332SGordon.Ross@Sun.COM avl_node_t hdr_avl_node; 13711332SGordon.Ross@Sun.COM 13811332SGordon.Ross@Sun.COM /* 13911332SGordon.Ross@Sun.COM * Identity of this node: The full path name, 14011332SGordon.Ross@Sun.COM * in server form, relative to the share root. 14111332SGordon.Ross@Sun.COM */ 14211332SGordon.Ross@Sun.COM char *hdr_n_rpath; 14311332SGordon.Ross@Sun.COM int hdr_n_rplen; 14411332SGordon.Ross@Sun.COM } smbfs_node_hdr_t; 1456007Sthurlow 1466007Sthurlow /* 14711332SGordon.Ross@Sun.COM * Below is the SMBFS-specific representation of a "node". 14811332SGordon.Ross@Sun.COM * This struct is a mixture of Sun NFS and Darwin code. 14911332SGordon.Ross@Sun.COM * Fields starting with "r_" came from NFS struct "rnode" 15011332SGordon.Ross@Sun.COM * and fields starting with "n_" came from Darwin, or 15111332SGordon.Ross@Sun.COM * were added during the Solaris port. We have avoided 15211332SGordon.Ross@Sun.COM * renaming fields so we would not cause excessive 15311332SGordon.Ross@Sun.COM * changes in the code using this struct. 15411332SGordon.Ross@Sun.COM * 15511332SGordon.Ross@Sun.COM * Now using an AVL tree instead of hash lists, but kept the 15611332SGordon.Ross@Sun.COM * "hash" in some member names and functions to reduce churn. 15711332SGordon.Ross@Sun.COM * One AVL tree per mount replaces the global hash buckets. 15811332SGordon.Ross@Sun.COM * 15911332SGordon.Ross@Sun.COM * Notes carried over from the NFS code: 1606007Sthurlow * 1616007Sthurlow * The smbnode is the "inode" for remote files. It contains all the 1626007Sthurlow * information necessary to handle remote file on the client side. 1636007Sthurlow * 1646007Sthurlow * Note on file sizes: we keep two file sizes in the smbnode: the size 1656007Sthurlow * according to the client (r_size) and the size according to the server 16611332SGordon.Ross@Sun.COM * (r_attr.fa_size). They can differ because we modify r_size during a 1676007Sthurlow * write system call (smbfs_rdwr), before the write request goes over the 1686007Sthurlow * wire (before the file is actually modified on the server). If an OTW 1696007Sthurlow * request occurs before the cached data is written to the server the file 17011332SGordon.Ross@Sun.COM * size returned from the server (r_attr.fa_size) may not match r_size. 17111332SGordon.Ross@Sun.COM * r_size is the one we use, in general. r_attr.fa_size is only used to 1726007Sthurlow * determine whether or not our cached data is valid. 1736007Sthurlow * 1746007Sthurlow * Each smbnode has 3 locks associated with it (not including the smbnode 17511332SGordon.Ross@Sun.COM * "hash" AVL tree and free list locks): 1766007Sthurlow * 1776007Sthurlow * r_rwlock: Serializes smbfs_write and smbfs_setattr requests 1786007Sthurlow * and allows smbfs_read requests to proceed in parallel. 1796007Sthurlow * Serializes reads/updates to directories. 1806007Sthurlow * 1816007Sthurlow * r_lkserlock: Serializes lock requests with map, write, and 1826007Sthurlow * readahead operations. 1836007Sthurlow * 1846007Sthurlow * r_statelock: Protects all fields in the smbnode except for 1856007Sthurlow * those listed below. This lock is intented 1866007Sthurlow * to be held for relatively short periods of 1876007Sthurlow * time (not accross entire putpage operations, 1886007Sthurlow * for example). 1896007Sthurlow * 19011332SGordon.Ross@Sun.COM * The following members are protected by the mutex smbfreelist_lock: 1916007Sthurlow * r_freef 1926007Sthurlow * r_freeb 1936007Sthurlow * 19411332SGordon.Ross@Sun.COM * The following members are protected by the AVL tree rwlock: 19511332SGordon.Ross@Sun.COM * r_avl_node (r__hdr.hdr_avl_node) 1966007Sthurlow * 1976007Sthurlow * Note: r_modaddr is only accessed when the r_statelock mutex is held. 1986007Sthurlow * Its value is also controlled via r_rwlock. It is assumed that 1996007Sthurlow * there will be only 1 writer active at a time, so it safe to 2006007Sthurlow * set r_modaddr and release r_statelock as long as the r_rwlock 2016007Sthurlow * writer lock is held. 2026007Sthurlow * 2036007Sthurlow * 64-bit offsets: the code formerly assumed that atomic reads of 2046007Sthurlow * r_size were safe and reliable; on 32-bit architectures, this is 2056007Sthurlow * not true since an intervening bus cycle from another processor 2066007Sthurlow * could update half of the size field. The r_statelock must now 2076007Sthurlow * be held whenever any kind of access of r_size is made. 2086007Sthurlow * 2096007Sthurlow * Lock ordering: 2106007Sthurlow * r_rwlock > r_lkserlock > r_statelock 2116007Sthurlow */ 21211332SGordon.Ross@Sun.COM 21311332SGordon.Ross@Sun.COM typedef struct smbnode { 21411332SGordon.Ross@Sun.COM /* Our linkage in the node cache AVL tree (see above). */ 21511332SGordon.Ross@Sun.COM smbfs_node_hdr_t r__hdr; 21611332SGordon.Ross@Sun.COM 21711332SGordon.Ross@Sun.COM /* short-hand names for r__hdr members */ 21811332SGordon.Ross@Sun.COM #define r_avl_node r__hdr.hdr_avl_node 21911332SGordon.Ross@Sun.COM #define n_rpath r__hdr.hdr_n_rpath 22011332SGordon.Ross@Sun.COM #define n_rplen r__hdr.hdr_n_rplen 22111332SGordon.Ross@Sun.COM 22211332SGordon.Ross@Sun.COM smbmntinfo_t *n_mount; /* VFS data */ 22311332SGordon.Ross@Sun.COM vnode_t *r_vnode; /* associated vnode */ 22411332SGordon.Ross@Sun.COM 22511332SGordon.Ross@Sun.COM /* 22611332SGordon.Ross@Sun.COM * Linkage in smbfreelist, for reclaiming nodes. 22711332SGordon.Ross@Sun.COM * Lock for the free list is: smbfreelist_lock 22811332SGordon.Ross@Sun.COM */ 22911332SGordon.Ross@Sun.COM struct smbnode *r_freef; /* free list forward pointer */ 23011332SGordon.Ross@Sun.COM struct smbnode *r_freeb; /* free list back pointer */ 23111332SGordon.Ross@Sun.COM 23211332SGordon.Ross@Sun.COM smbfs_rwlock_t r_rwlock; /* serialize write/setattr requests */ 23311332SGordon.Ross@Sun.COM smbfs_rwlock_t r_lkserlock; /* serialize lock with other ops */ 23411332SGordon.Ross@Sun.COM kmutex_t r_statelock; /* protect (most) smbnode fields */ 23511332SGordon.Ross@Sun.COM 23611332SGordon.Ross@Sun.COM /* 23711332SGordon.Ross@Sun.COM * File handle, directory search handle, 23811332SGordon.Ross@Sun.COM * and reference counts for them, etc. 23911332SGordon.Ross@Sun.COM * Lock for these is: r_lkserlock 24011332SGordon.Ross@Sun.COM */ 24111332SGordon.Ross@Sun.COM int n_dirrefs; 24211332SGordon.Ross@Sun.COM struct smbfs_fctx *n_dirseq; /* ff context */ 24311332SGordon.Ross@Sun.COM int n_dirofs; /* last ff offset */ 24411332SGordon.Ross@Sun.COM int n_fidrefs; 24511332SGordon.Ross@Sun.COM uint16_t n_fid; /* file handle */ 24611332SGordon.Ross@Sun.COM enum vtype n_ovtype; /* vnode type opened */ 24711332SGordon.Ross@Sun.COM uint32_t n_rights; /* granted rights */ 24811332SGordon.Ross@Sun.COM int n_vcgenid; /* gereration no. (reconnect) */ 2496007Sthurlow 25011332SGordon.Ross@Sun.COM /* 25111332SGordon.Ross@Sun.COM * Misc. bookkeeping 25211332SGordon.Ross@Sun.COM */ 25311332SGordon.Ross@Sun.COM cred_t *r_cred; /* current credentials */ 25411332SGordon.Ross@Sun.COM u_offset_t r_nextr; /* next read offset (read-ahead) */ 25511332SGordon.Ross@Sun.COM long r_mapcnt; /* count of mmapped pages */ 25611332SGordon.Ross@Sun.COM uint_t r_count; /* # of refs not reflect in v_count */ 25711332SGordon.Ross@Sun.COM uint_t r_awcount; /* # of outstanding async write */ 25811332SGordon.Ross@Sun.COM uint_t r_gcount; /* getattrs waiting to flush pages */ 25911332SGordon.Ross@Sun.COM uint_t r_flags; /* flags, see below */ 26011332SGordon.Ross@Sun.COM uint32_t n_flag; /* NXXX flags below */ 26111332SGordon.Ross@Sun.COM uint_t r_error; /* async write error */ 26211332SGordon.Ross@Sun.COM kcondvar_t r_cv; /* condvar for blocked threads */ 26311332SGordon.Ross@Sun.COM avl_tree_t r_dir; /* cache of readdir responses */ 26411332SGordon.Ross@Sun.COM rddir_cache *r_direof; /* pointer to the EOF entry */ 26511332SGordon.Ross@Sun.COM kthread_t *r_serial; /* id of purging thread */ 26611332SGordon.Ross@Sun.COM list_t r_indelmap; /* list of delmap callers */ 26711332SGordon.Ross@Sun.COM 26811332SGordon.Ross@Sun.COM /* 26911332SGordon.Ross@Sun.COM * Attributes: local, and as last seen on the server. 27011332SGordon.Ross@Sun.COM * See notes above re: r_size vs r_attr.fa_size, etc. 27111332SGordon.Ross@Sun.COM */ 27211332SGordon.Ross@Sun.COM smbfattr_t r_attr; /* attributes from the server */ 27311332SGordon.Ross@Sun.COM hrtime_t r_attrtime; /* time attributes become invalid */ 27411332SGordon.Ross@Sun.COM hrtime_t r_mtime; /* client time file last modified */ 27511332SGordon.Ross@Sun.COM len_t r_size; /* client's view of file size */ 27611332SGordon.Ross@Sun.COM 27711332SGordon.Ross@Sun.COM /* 278*11564SGordon.Ross@Sun.COM * Security attributes. 279*11564SGordon.Ross@Sun.COM */ 280*11564SGordon.Ross@Sun.COM vsecattr_t r_secattr; 281*11564SGordon.Ross@Sun.COM hrtime_t r_sectime; 282*11564SGordon.Ross@Sun.COM 283*11564SGordon.Ross@Sun.COM /* 28411332SGordon.Ross@Sun.COM * Other attributes, not carried in smbfattr_t 28511332SGordon.Ross@Sun.COM */ 28611332SGordon.Ross@Sun.COM u_longlong_t n_ino; 28711332SGordon.Ross@Sun.COM uid_t n_uid; 28811332SGordon.Ross@Sun.COM gid_t n_gid; 28911332SGordon.Ross@Sun.COM mode_t n_mode; 29011332SGordon.Ross@Sun.COM } smbnode_t; 29111332SGordon.Ross@Sun.COM 29211332SGordon.Ross@Sun.COM /* 29311332SGordon.Ross@Sun.COM * Flag bits in: smbnode_t .n_flag 29411332SGordon.Ross@Sun.COM */ 2956007Sthurlow #define NFLUSHINPROG 0x00001 2966007Sthurlow #define NFLUSHWANT 0x00002 /* they should gone ... */ 2976007Sthurlow #define NMODIFIED 0x00004 /* bogus, until async IO implemented */ 2986007Sthurlow #define NREFPARENT 0x00010 /* node holds parent from recycling */ 2996007Sthurlow #define NGOTIDS 0x00020 3006007Sthurlow #define NRDIRSERIAL 0x00080 /* serialize readdir operation */ 3016007Sthurlow #define NISMAPPED 0x00800 3026007Sthurlow #define NFLUSHWIRE 0x01000 30311332SGordon.Ross@Sun.COM #define NATTRCHANGED 0x02000 /* kill cached attributes at close */ 3046007Sthurlow #define NALLOC 0x04000 /* being created */ 3056007Sthurlow #define NWALLOC 0x08000 /* awaiting creation */ 3067040Sgwr #define N_XATTR 0x10000 /* extended attribute (dir or file) */ 3076007Sthurlow 3086007Sthurlow /* 30911332SGordon.Ross@Sun.COM * Flag bits in: smbnode_t .r_flags 3106007Sthurlow */ 3116007Sthurlow #define RREADDIRPLUS 0x1 /* issue a READDIRPLUS instead of READDIR */ 3126007Sthurlow #define RDIRTY 0x2 /* dirty pages from write operation */ 3136007Sthurlow #define RSTALE 0x4 /* file handle is stale */ 3146007Sthurlow #define RMODINPROGRESS 0x8 /* page modification happening */ 3156007Sthurlow #define RTRUNCATE 0x10 /* truncating, don't commit */ 3166007Sthurlow #define RHAVEVERF 0x20 /* have a write verifier to compare against */ 3176007Sthurlow #define RCOMMIT 0x40 /* commit in progress */ 3186007Sthurlow #define RCOMMITWAIT 0x80 /* someone is waiting to do a commit */ 31911332SGordon.Ross@Sun.COM #define RHASHED 0x100 /* smbnode is in the "hash" AVL tree */ 3206007Sthurlow #define ROUTOFSPACE 0x200 /* an out of space error has happened */ 3216007Sthurlow #define RDIRECTIO 0x400 /* bypass the buffer cache */ 3226007Sthurlow #define RLOOKUP 0x800 /* a lookup has been performed */ 3236007Sthurlow #define RWRITEATTR 0x1000 /* attributes came from WRITE */ 3246007Sthurlow #define RINDNLCPURGE 0x2000 /* in the process of purging DNLC references */ 3256007Sthurlow #define RDELMAPLIST 0x4000 /* delmap callers tracking for as callback */ 3266007Sthurlow 3276007Sthurlow /* 3286007Sthurlow * Convert between vnode and smbnode 3296007Sthurlow */ 3306007Sthurlow #define VTOSMB(vp) ((smbnode_t *)((vp)->v_data)) 3316007Sthurlow #define SMBTOV(np) ((np)->r_vnode) 3326007Sthurlow 3336007Sthurlow /* 33411332SGordon.Ross@Sun.COM * A macro to compute the separator that should be used for 33511332SGordon.Ross@Sun.COM * names under some directory. See smbfs_fullpath(). 3366007Sthurlow */ 33711332SGordon.Ross@Sun.COM #define SMBFS_DNP_SEP(dnp) \ 33811332SGordon.Ross@Sun.COM (((dnp->n_flag & N_XATTR) == 0 && dnp->n_rplen > 1) ? '\\' : '\0') 3396007Sthurlow 3406007Sthurlow #ifdef __cplusplus 3416007Sthurlow } 3426007Sthurlow #endif 3436007Sthurlow 3446007Sthurlow #endif /* _FS_SMBFS_NODE_H_ */ 345