2 * Copyright (c) 2000-2001, Boris Popov
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Boris Popov.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $Id: smbfs_node.h,v 1.31.52.1 2005/05/27 02:35:28 lindak Exp $
36 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
37 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
38 * Use is subject to license terms.
41 #ifndef _FS_SMBFS_NODE_H_
42 #define _FS_SMBFS_NODE_H_
45 * Much code copied into here from Sun NFS.
46 * Compare with nfs_clnt.h
51 #include <netsmb/smb_subr.h>
58 * Cache whole directories (not yet)
60 typedef struct rddir_cache
{
61 lloff_t _cookie
; /* cookie used to find this cache entry */
62 lloff_t _ncookie
; /* cookie used to find the next cache entry */
63 char *entries
; /* buffer containing dirent entries */
64 int eof
; /* EOF reached after this request */
65 int entlen
; /* size of dirent entries in buf */
66 int buflen
; /* size of the buffer used to store entries */
67 int flags
; /* control flags, see below */
68 kcondvar_t cv
; /* cv for blocking */
69 int error
; /* error from RPC operation */
71 uint_t count
; /* reference count */
72 avl_node_t tree
; /* AVL tree links */
75 #define smbfs_cookie _cookie._p._l
76 #define smbfs_ncookie _ncookie._p._l
77 #define smbfs3_cookie _cookie._f
78 #define smbfs3_ncookie _ncookie._f
80 #define RDDIR 0x1 /* readdir operation in progress */
81 #define RDDIRWAIT 0x2 /* waiting on readdir in progress */
82 #define RDDIRREQ 0x4 /* a new readdir is required */
83 #define RDDIRCACHED 0x8 /* entry is in the cache */
85 #define HAVE_RDDIR_CACHE(rp) (avl_numnodes(&(rp)->r_dir) > 0)
88 * A homegrown reader/writer lock implementation. It addresses
89 * two requirements not addressed by the system primitives. They
90 * are that the `enter" operation is optionally interruptible and
91 * that that they can be re`enter'ed by writers without deadlock.
93 typedef struct smbfs_rwlock
{
102 * The format of the smbfs node header, which contains the
103 * fields used to link nodes in the AVL tree, and those
104 * fields needed by the AVL node comparison functions.
105 * It's a separate struct so we can call avl_find with
106 * this relatively small struct as a stack local.
108 * The AVL tree is mntinfo.smi_hash_avl,
109 * and its lock is mntinfo.smi_hash_lk.
111 typedef struct smbfs_node_hdr
{
113 * Our linkage in the node cache AVL tree.
115 avl_node_t hdr_avl_node
;
118 * Identity of this node: The full path name,
119 * in server form, relative to the share root.
126 * Below is the SMBFS-specific representation of a "node".
127 * This struct is a mixture of Sun NFS and Darwin code.
128 * Fields starting with "r_" came from NFS struct "rnode"
129 * and fields starting with "n_" came from Darwin, or
130 * were added during the Solaris port. We have avoided
131 * renaming fields so we would not cause excessive
132 * changes in the code using this struct.
134 * Now using an AVL tree instead of hash lists, but kept the
135 * "hash" in some member names and functions to reduce churn.
136 * One AVL tree per mount replaces the global hash buckets.
138 * Notes carried over from the NFS code:
140 * The smbnode is the "inode" for remote files. It contains all the
141 * information necessary to handle remote file on the client side.
143 * Note on file sizes: we keep two file sizes in the smbnode: the size
144 * according to the client (r_size) and the size according to the server
145 * (r_attr.fa_size). They can differ because we modify r_size during a
146 * write system call (smbfs_rdwr), before the write request goes over the
147 * wire (before the file is actually modified on the server). If an OTW
148 * request occurs before the cached data is written to the server the file
149 * size returned from the server (r_attr.fa_size) may not match r_size.
150 * r_size is the one we use, in general. r_attr.fa_size is only used to
151 * determine whether or not our cached data is valid.
153 * Each smbnode has 3 locks associated with it (not including the smbnode
154 * "hash" AVL tree and free list locks):
156 * r_rwlock: Serializes smbfs_write and smbfs_setattr requests
157 * and allows smbfs_read requests to proceed in parallel.
158 * Serializes reads/updates to directories.
160 * r_lkserlock: Serializes lock requests with map, write, and
161 * readahead operations.
163 * r_statelock: Protects all fields in the smbnode except for
164 * those listed below. This lock is intented
165 * to be held for relatively short periods of
166 * time (not accross entire putpage operations,
169 * The following members are protected by the mutex smbfreelist_lock:
173 * The following members are protected by the AVL tree rwlock:
174 * r_avl_node (r__hdr.hdr_avl_node)
176 * Note: r_modaddr is only accessed when the r_statelock mutex is held.
177 * Its value is also controlled via r_rwlock. It is assumed that
178 * there will be only 1 writer active at a time, so it safe to
179 * set r_modaddr and release r_statelock as long as the r_rwlock
180 * writer lock is held.
182 * 64-bit offsets: the code formerly assumed that atomic reads of
183 * r_size were safe and reliable; on 32-bit architectures, this is
184 * not true since an intervening bus cycle from another processor
185 * could update half of the size field. The r_statelock must now
186 * be held whenever any kind of access of r_size is made.
189 * r_rwlock > r_lkserlock > r_statelock
192 typedef struct smbnode
{
193 /* Our linkage in the node cache AVL tree (see above). */
194 smbfs_node_hdr_t r__hdr
;
196 /* short-hand names for r__hdr members */
197 #define r_avl_node r__hdr.hdr_avl_node
198 #define n_rpath r__hdr.hdr_n_rpath
199 #define n_rplen r__hdr.hdr_n_rplen
201 smbmntinfo_t
*n_mount
; /* VFS data */
202 vnode_t
*r_vnode
; /* associated vnode */
205 * Linkage in smbfreelist, for reclaiming nodes.
206 * Lock for the free list is: smbfreelist_lock
208 struct smbnode
*r_freef
; /* free list forward pointer */
209 struct smbnode
*r_freeb
; /* free list back pointer */
211 smbfs_rwlock_t r_rwlock
; /* serialize write/setattr requests */
212 smbfs_rwlock_t r_lkserlock
; /* serialize lock with other ops */
213 kmutex_t r_statelock
; /* protect (most) smbnode fields */
216 * File handle, directory search handle,
217 * and reference counts for them, etc.
218 * Lock for these is: r_lkserlock
221 struct smbfs_fctx
*n_dirseq
; /* ff context */
222 int n_dirofs
; /* last ff offset */
224 uint16_t n_fid
; /* file handle */
225 enum vtype n_ovtype
; /* vnode type opened */
226 uint32_t n_rights
; /* granted rights */
227 int n_vcgenid
; /* gereration no. (reconnect) */
232 cred_t
*r_cred
; /* current credentials */
233 uoff_t r_nextr
; /* next read offset (read-ahead) */
234 long r_mapcnt
; /* count of mmapped pages */
235 uint_t r_inmap
; /* to serialize read/write and mmap */
236 uint_t r_count
; /* # of refs not reflect in v_count */
237 uint_t r_awcount
; /* # of outstanding async write */
238 uint_t r_gcount
; /* getattrs waiting to flush pages */
239 uint_t r_flags
; /* flags, see below */
240 uint32_t n_flag
; /* N--- flags below */
241 uint_t r_error
; /* async write error */
242 kcondvar_t r_cv
; /* condvar for blocked threads */
243 avl_tree_t r_dir
; /* cache of readdir responses */
244 rddir_cache
*r_direof
; /* pointer to the EOF entry */
245 uoff_t r_modaddr
; /* address for page in writenp */
246 kthread_t
*r_serial
; /* id of purging thread */
247 list_t r_indelmap
; /* list of delmap callers */
250 * Attributes: local, and as last seen on the server.
251 * See notes above re: r_size vs r_attr.fa_size, etc.
253 smbfattr_t r_attr
; /* attributes from the server */
254 hrtime_t r_attrtime
; /* time attributes become invalid */
255 hrtime_t r_mtime
; /* client time file last modified */
256 len_t r_size
; /* client's view of file size */
259 * Security attributes.
261 vsecattr_t r_secattr
;
265 * Other attributes, not carried in smbfattr_t
274 * Flag bits in: smbnode_t .n_flag
276 #define NFLUSHINPROG 0x00001
277 #define NFLUSHWANT 0x00002 /* they should gone ... */
278 #define NMODIFIED 0x00004 /* bogus, until async IO implemented */
279 #define NREFPARENT 0x00010 /* node holds parent from recycling */
280 #define NGOTIDS 0x00020
281 #define NRDIRSERIAL 0x00080 /* serialize readdir operation */
282 #define NISMAPPED 0x00800
283 #define NFLUSHWIRE 0x01000
284 #define NATTRCHANGED 0x02000 /* kill cached attributes at close */
285 #define NALLOC 0x04000 /* being created */
286 #define NWALLOC 0x08000 /* awaiting creation */
287 #define N_XATTR 0x10000 /* extended attribute (dir or file) */
290 * Flag bits in: smbnode_t .r_flags
292 #define RREADDIRPLUS 0x1 /* issue a READDIRPLUS instead of READDIR */
293 #define RDIRTY 0x2 /* dirty pages from write operation */
294 #define RSTALE 0x4 /* file handle is stale */
295 #define RMODINPROGRESS 0x8 /* page modification happening */
296 #define RTRUNCATE 0x10 /* truncating, don't commit */
297 #define RHAVEVERF 0x20 /* have a write verifier to compare against */
298 #define RCOMMIT 0x40 /* commit in progress */
299 #define RCOMMITWAIT 0x80 /* someone is waiting to do a commit */
300 #define RHASHED 0x100 /* smbnode is in the "hash" AVL tree */
301 #define ROUTOFSPACE 0x200 /* an out of space error has happened */
302 #define RDIRECTIO 0x400 /* bypass the buffer cache */
303 #define RLOOKUP 0x800 /* a lookup has been performed */
304 #define RWRITEATTR 0x1000 /* attributes came from WRITE */
305 #define RINDNLCPURGE 0x2000 /* in the process of purging DNLC references */
306 #define RDELMAPLIST 0x4000 /* delmap callers tracking for as callback */
309 * Convert between vnode and smbnode
311 #define VTOSMB(vp) ((smbnode_t *)((vp)->v_data))
312 #define SMBTOV(np) ((np)->r_vnode)
315 * A macro to compute the separator that should be used for
316 * names under some directory. See smbfs_fullpath().
318 #define SMBFS_DNP_SEP(dnp) \
319 (((dnp->n_flag & N_XATTR) == 0 && dnp->n_rplen > 1) ? '\\' : '\0')
325 #endif /* _FS_SMBFS_NODE_H_ */