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.c,v 1.54.52.1 2005/05/27 02:35:28 lindak Exp $
36 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
37 * Use is subject to license terms.
40 #include <sys/param.h>
41 #include <sys/systm.h>
45 #include <sys/vnode.h>
48 #include <sys/atomic.h>
49 #include <sys/cmn_err.h>
50 #include <sys/sysmacros.h>
51 #include <sys/bitmap.h>
53 #include <netsmb/smb_osdep.h>
55 #include <netsmb/smb.h>
56 #include <netsmb/smb_conn.h>
57 #include <netsmb/smb_subr.h>
59 #include <smbfs/smbfs.h>
60 #include <smbfs/smbfs_node.h>
61 #include <smbfs/smbfs_subr.h>
64 * Lack of inode numbers leads us to the problem of generating them.
65 * Partially this problem can be solved by having a dir/file cache
66 * with inode numbers generated from the incremented by one counter.
67 * However this way will require too much kernel memory, gives all
68 * sorts of locking and consistency problems, not to mentinon counter
69 * overflows. So, I'm decided to use a hash function to generate
70 * pseudo random (and [often?] unique) inode numbers.
73 /* Magic constants for name hashing. */
74 #define FNV_32_PRIME ((uint32_t)0x01000193UL)
75 #define FNV1_32_INIT ((uint32_t)33554467UL)
77 static inline uint32_t
78 smbfs_hash(uint32_t ival
, const char *name
, int nmlen
)
82 for (v
= ival
; nmlen
; name
++, nmlen
--) {
90 * Compute the hash of the full (remote) path name
91 * using the three parts supplied separately.
94 smbfs_gethash(const char *rpath
, int rplen
)
98 v
= smbfs_hash(FNV1_32_INIT
, rpath
, rplen
);
103 * Like smbfs_gethash, but optimized a little by
104 * starting with the directory hash.
107 smbfs_getino(struct smbnode
*dnp
, const char *name
, int nmlen
)
112 /* Start with directory hash */
113 ino
= (uint32_t)dnp
->n_ino
;
115 /* separator (maybe) */
116 sep
= SMBFS_DNP_SEP(dnp
);
118 ino
= smbfs_hash(ino
, &sep
, 1);
120 /* Now hash this component. */
121 ino
= smbfs_hash(ino
, name
, nmlen
);
127 * Allocate and copy a string of passed length.
128 * The passed length does NOT include the null.
131 smbfs_name_alloc(const char *name
, int nmlen
)
135 cp
= kmem_alloc(nmlen
+ 1, KM_SLEEP
);
136 bcopy(name
, cp
, nmlen
);
143 * Free string from smbfs_name_alloc(). Again,
144 * the passed length does NOT include the null.
147 smbfs_name_free(const char *name
, int nmlen
)
149 kmem_free((char *)name
, nmlen
+ 1);
155 * Find or create a node under some directory node.
158 smbfs_nget(vnode_t
*dvp
, const char *name
, int nmlen
,
159 struct smbfattr
*fap
, vnode_t
**vpp
)
161 struct smbnode
*dnp
= VTOSMB(dvp
);
169 /* Don't expect "" or "." or ".." here anymore. */
170 if (nmlen
== 0 || (nmlen
== 1 && name
[0] == '.') ||
171 (nmlen
== 2 && name
[0] == '.' && name
[1] == '.')) {
174 sep
= SMBFS_DNP_SEP(dnp
);
176 /* Find or create the node. */
177 np
= smbfs_node_findcreate(dnp
->n_mount
,
178 dnp
->n_rpath
, dnp
->n_rplen
,
179 name
, nmlen
, sep
, fap
);
182 * We should have np now, because we passed
183 * fap != NULL to smbfs_node_findcreate.
189 * Files in an XATTR dir are also XATTR.
191 if (dnp
->n_flag
& N_XATTR
) {
192 mutex_enter(&np
->r_statelock
);
193 np
->n_flag
|= N_XATTR
;
194 mutex_exit(&np
->r_statelock
);
197 /* BSD symlink hack removed (smb_symmagic) */
205 * Update the local notion of the mtime of some directory.
206 * See comments re. r_mtime in smbfs_node.h
209 smbfs_attr_touchdir(struct smbnode
*dnp
)
212 mutex_enter(&dnp
->r_statelock
);
215 * Now that we keep the client's notion of mtime
216 * separately from the server, this is easy.
218 dnp
->r_mtime
= gethrtime();
221 * Invalidate the cache, so that we go to the wire
222 * to check that the server doesn't have a better
223 * timestamp next time we care.
225 smbfs_attrcache_rm_locked(dnp
);
226 mutex_exit(&dnp
->r_statelock
);
230 smbfs_attrcache_remove(struct smbnode
*np
)
232 mutex_enter(&np
->r_statelock
);
233 /* smbfs_attrcache_rm_locked(np); */
234 np
->r_attrtime
= gethrtime();
235 mutex_exit(&np
->r_statelock
);
238 /* See smbfs_node.h */
239 #undef smbfs_attrcache_rm_locked
241 smbfs_attrcache_rm_locked(struct smbnode
*np
)
243 ASSERT(MUTEX_HELD(&np
->r_statelock
));
244 np
->r_attrtime
= gethrtime();