Print this page
*** NO COMMENTS ***
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_client.c
+++ new/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_client.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 *
25 25 * Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
26 26 * All rights reserved.
27 27 */
28 28
29 29 #include <sys/param.h>
30 30 #include <sys/systm.h>
31 31 #include <sys/thread.h>
32 32 #include <sys/t_lock.h>
33 33 #include <sys/time.h>
34 34 #include <sys/vnode.h>
35 35 #include <sys/vfs.h>
36 36 #include <sys/errno.h>
37 37 #include <sys/buf.h>
38 38 #include <sys/stat.h>
39 39 #include <sys/cred.h>
40 40 #include <sys/kmem.h>
41 41 #include <sys/debug.h>
42 42 #include <sys/vmsystm.h>
43 43 #include <sys/flock.h>
44 44 #include <sys/share.h>
45 45 #include <sys/cmn_err.h>
46 46 #include <sys/tiuser.h>
47 47 #include <sys/sysmacros.h>
48 48 #include <sys/callb.h>
49 49 #include <sys/acl.h>
50 50 #include <sys/kstat.h>
51 51 #include <sys/signal.h>
52 52 #include <sys/list.h>
53 53 #include <sys/zone.h>
54 54
55 55 #include <netsmb/smb.h>
56 56 #include <netsmb/smb_conn.h>
57 57 #include <netsmb/smb_subr.h>
58 58
59 59 #include <smbfs/smbfs.h>
60 60 #include <smbfs/smbfs_node.h>
61 61 #include <smbfs/smbfs_subr.h>
62 62
63 63 #include <vm/hat.h>
64 64 #include <vm/as.h>
65 65 #include <vm/page.h>
66 66 #include <vm/pvn.h>
67 67 #include <vm/seg.h>
68 68 #include <vm/seg_map.h>
69 69 #include <vm/seg_vn.h>
70 70
71 71 static int smbfs_getattr_cache(vnode_t *, struct smbfattr *);
72 72 static int smbfattr_to_vattr(vnode_t *, struct smbfattr *,
73 73 struct vattr *);
74 74
75 75 /*
76 76 * The following code provide zone support in order to perform an action
77 77 * for each smbfs mount in a zone. This is also where we would add
78 78 * per-zone globals and kernel threads for the smbfs module (since
79 79 * they must be terminated by the shutdown callback).
80 80 */
81 81
82 82 struct smi_globals {
83 83 kmutex_t smg_lock; /* lock protecting smg_list */
84 84 list_t smg_list; /* list of SMBFS mounts in zone */
85 85 boolean_t smg_destructor_called;
86 86 };
87 87 typedef struct smi_globals smi_globals_t;
88 88
89 89 static zone_key_t smi_list_key;
90 90
91 91 /*
92 92 * Attributes caching:
93 93 *
94 94 * Attributes are cached in the smbnode in struct vattr form.
95 95 * There is a time associated with the cached attributes (r_attrtime)
96 96 * which tells whether the attributes are valid. The time is initialized
97 97 * to the difference between current time and the modify time of the vnode
98 98 * when new attributes are cached. This allows the attributes for
99 99 * files that have changed recently to be timed out sooner than for files
100 100 * that have not changed for a long time. There are minimum and maximum
101 101 * timeout values that can be set per mount point.
102 102 */
103 103
104 104 /*
105 105 * Validate caches by checking cached attributes. If they have timed out
106 106 * get the attributes from the server and compare mtimes. If mtimes are
107 107 * different purge all caches for this vnode.
108 108 */
109 109 int
110 110 smbfs_validate_caches(
111 111 struct vnode *vp,
112 112 cred_t *cr)
113 113 {
114 114 struct vattr va;
115 115
116 116 va.va_mask = AT_SIZE;
↓ open down ↓ |
116 lines elided |
↑ open up ↑ |
117 117 return (smbfsgetattr(vp, &va, cr));
118 118 }
119 119
120 120 /*
121 121 * Purge all of the various data caches.
122 122 */
123 123 /*ARGSUSED*/
124 124 void
125 125 smbfs_purge_caches(struct vnode *vp)
126 126 {
127 -#if 0 /* not yet: mmap support */
128 127 /*
129 128 * NFS: Purge the DNLC for this vp,
130 129 * Clear any readdir state bits,
131 130 * the readlink response cache, ...
132 131 */
133 132 smbnode_t *np = VTOSMB(vp);
134 133
135 134 /*
136 135 * Flush the page cache.
137 136 */
138 137 if (vn_has_cached_data(vp)) {
139 - (void) VOP_PUTPAGE(vp, (u_offset_t)0, 0, B_INVAL, cr, NULL);
138 + (void) VOP_PUTPAGE(vp, (u_offset_t) 0, 0, B_INVAL, np->r_cred, NULL);
140 139 }
141 -#endif /* not yet */
142 140 }
143 141
144 142 /*
145 143 * Check the attribute cache to see if the new attributes match
146 144 * those cached. If they do, the various `data' caches are
147 145 * considered to be good. Otherwise, purge the cached data.
148 146 */
149 147 void
150 148 smbfs_cache_check(
151 149 struct vnode *vp,
152 150 struct smbfattr *fap)
153 151 {
154 152 smbnode_t *np;
155 153 int purge_data = 0;
156 154 int purge_acl = 0;
157 155
158 156 np = VTOSMB(vp);
159 157 mutex_enter(&np->r_statelock);
160 158
161 159 /*
162 160 * Compare with NFS macro: CACHE_VALID
163 161 * If the mtime or size has changed,
164 162 * purge cached data.
165 163 */
166 164 if (np->r_attr.fa_mtime.tv_sec != fap->fa_mtime.tv_sec ||
167 165 np->r_attr.fa_mtime.tv_nsec != fap->fa_mtime.tv_nsec)
168 166 purge_data = 1;
169 167 if (np->r_attr.fa_size != fap->fa_size)
170 168 purge_data = 1;
171 169
172 170 if (np->r_attr.fa_ctime.tv_sec != fap->fa_ctime.tv_sec ||
173 171 np->r_attr.fa_ctime.tv_nsec != fap->fa_ctime.tv_nsec)
174 172 purge_acl = 1;
175 173
176 174 if (purge_acl) {
177 175 /* just invalidate r_secattr (XXX: OK?) */
178 176 np->r_sectime = gethrtime();
179 177 }
180 178
181 179 mutex_exit(&np->r_statelock);
182 180
183 181 if (purge_data)
184 182 smbfs_purge_caches(vp);
185 183 }
186 184
187 185 /*
188 186 * Set attributes cache for given vnode using vnode attributes.
189 187 * From NFS: nfs_attrcache_va
190 188 */
191 189 #if 0 /* not yet (not sure if we need this) */
192 190 void
193 191 smbfs_attrcache_va(vnode_t *vp, struct vattr *vap)
194 192 {
195 193 smbfattr_t fa;
196 194 smbnode_t *np;
197 195
198 196 vattr_to_fattr(vp, vap, &fa);
199 197 smbfs_attrcache_fa(vp, &fa);
200 198 }
201 199 #endif /* not yet */
202 200
203 201 /*
204 202 * Set attributes cache for given vnode using SMB fattr
205 203 * and update the attribute cache timeout.
206 204 *
207 205 * From NFS: nfs_attrcache, nfs_attrcache_va
208 206 */
209 207 void
210 208 smbfs_attrcache_fa(vnode_t *vp, struct smbfattr *fap)
211 209 {
212 210 smbnode_t *np;
213 211 smbmntinfo_t *smi;
214 212 hrtime_t delta, now;
215 213 u_offset_t newsize;
216 214 vtype_t vtype, oldvt;
217 215 mode_t mode;
218 216
219 217 np = VTOSMB(vp);
220 218 smi = VTOSMI(vp);
221 219
222 220 /*
223 221 * We allow v_type to change, so set that here
224 222 * (and the mode, which depends on the type).
225 223 */
226 224 if (fap->fa_attr & SMB_FA_DIR) {
227 225 vtype = VDIR;
228 226 mode = smi->smi_dmode;
229 227 } else {
230 228 vtype = VREG;
231 229 mode = smi->smi_fmode;
232 230 }
233 231
234 232 mutex_enter(&np->r_statelock);
235 233 now = gethrtime();
236 234
237 235 /*
238 236 * Delta is the number of nanoseconds that we will
239 237 * cache the attributes of the file. It is based on
240 238 * the number of nanoseconds since the last time that
241 239 * we detected a change. The assumption is that files
242 240 * that changed recently are likely to change again.
243 241 * There is a minimum and a maximum for regular files
244 242 * and for directories which is enforced though.
245 243 *
246 244 * Using the time since last change was detected
247 245 * eliminates direct comparison or calculation
248 246 * using mixed client and server times. SMBFS
249 247 * does not make any assumptions regarding the
250 248 * client and server clocks being synchronized.
251 249 */
252 250 if (fap->fa_mtime.tv_sec != np->r_attr.fa_mtime.tv_sec ||
253 251 fap->fa_mtime.tv_nsec != np->r_attr.fa_mtime.tv_nsec ||
254 252 fap->fa_size != np->r_attr.fa_size)
255 253 np->r_mtime = now;
256 254
257 255 if ((smi->smi_flags & SMI_NOAC) || (vp->v_flag & VNOCACHE))
258 256 delta = 0;
259 257 else {
260 258 delta = now - np->r_mtime;
261 259 if (vtype == VDIR) {
262 260 if (delta < smi->smi_acdirmin)
263 261 delta = smi->smi_acdirmin;
264 262 else if (delta > smi->smi_acdirmax)
265 263 delta = smi->smi_acdirmax;
266 264 } else {
267 265 if (delta < smi->smi_acregmin)
268 266 delta = smi->smi_acregmin;
269 267 else if (delta > smi->smi_acregmax)
270 268 delta = smi->smi_acregmax;
271 269 }
272 270 }
273 271
274 272 np->r_attrtime = now + delta;
275 273 np->r_attr = *fap;
276 274 np->n_mode = mode;
277 275 oldvt = vp->v_type;
278 276 vp->v_type = vtype;
279 277
280 278 /*
281 279 * Shall we update r_size? (local notion of size)
282 280 *
283 281 * The real criteria for updating r_size should be:
284 282 * if the file has grown on the server, or if
285 283 * the client has not modified the file.
286 284 *
↓ open down ↓ |
135 lines elided |
↑ open up ↑ |
287 285 * Also deal with the fact that SMB presents
288 286 * directories as having size=0. Doing that
289 287 * here and leaving fa_size as returned OtW
290 288 * avoids fixing the size lots of places.
291 289 */
292 290 newsize = fap->fa_size;
293 291 if (vtype == VDIR && newsize < DEV_BSIZE)
294 292 newsize = DEV_BSIZE;
295 293
296 294 if (np->r_size != newsize) {
297 -#if 0 /* not yet: mmap support */
298 - if (!vn_has_cached_data(vp) || ...)
299 - /* XXX: See NFS page cache code. */
300 -#endif /* not yet */
301 - /* OK to set the size. */
302 - np->r_size = newsize;
295 + if (!vn_has_cached_data(vp)
296 + || (!(np->r_flags & RDIRTY)&& np->r_count == 0)) {
297 + /* OK to set the size. */
298 + np->r_size = newsize;
299 + }
303 300 }
304 301
305 302 /* NFS: np->r_flags &= ~RWRITEATTR; */
306 303 np->n_flag &= ~NATTRCHANGED;
307 304
308 305 mutex_exit(&np->r_statelock);
309 306
310 307 if (oldvt != vtype) {
311 308 SMBVDEBUG("vtype change %d to %d\n", oldvt, vtype);
312 309 }
313 310 }
314 311
315 312 /*
316 313 * Fill in attribute from the cache.
317 314 *
318 315 * If valid, copy to *fap and return zero,
319 316 * otherwise return an error.
320 317 *
321 318 * From NFS: nfs_getattr_cache()
322 319 */
323 320 int
324 321 smbfs_getattr_cache(vnode_t *vp, struct smbfattr *fap)
325 322 {
326 323 smbnode_t *np;
327 324 int error;
328 325
329 326 np = VTOSMB(vp);
330 327
331 328 mutex_enter(&np->r_statelock);
332 329 if (gethrtime() >= np->r_attrtime) {
333 330 /* cache expired */
334 331 error = ENOENT;
335 332 } else {
336 333 /* cache is valid */
337 334 *fap = np->r_attr;
338 335 error = 0;
339 336 }
340 337 mutex_exit(&np->r_statelock);
341 338
342 339 return (error);
343 340 }
344 341
345 342 /*
346 343 * Get attributes over-the-wire and update attributes cache
347 344 * if no error occurred in the over-the-wire operation.
348 345 * Return 0 if successful, otherwise error.
349 346 * From NFS: nfs_getattr_otw
350 347 */
351 348 int
352 349 smbfs_getattr_otw(vnode_t *vp, struct smbfattr *fap, cred_t *cr)
353 350 {
354 351 struct smbnode *np;
355 352 struct smb_cred scred;
356 353 int error;
357 354
358 355 np = VTOSMB(vp);
359 356
360 357 /*
361 358 * NFS uses the ACL rpc here (if smi_flags & SMI_ACL)
362 359 * With SMB, getting the ACL is a significantly more
363 360 * expensive operation, so we do that only when asked
364 361 * for the uid/gid. See smbfsgetattr().
365 362 */
366 363
367 364 /* Shared lock for (possible) n_fid use. */
368 365 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
369 366 return (EINTR);
370 367 smb_credinit(&scred, cr);
371 368
372 369 bzero(fap, sizeof (*fap));
373 370 error = smbfs_smb_getfattr(np, fap, &scred);
374 371
375 372 smb_credrele(&scred);
376 373 smbfs_rw_exit(&np->r_lkserlock);
377 374
378 375 if (error) {
379 376 /* NFS had: PURGE_STALE_FH(error, vp, cr) */
380 377 smbfs_attrcache_remove(np);
381 378 if (error == ENOENT || error == ENOTDIR) {
382 379 /*
383 380 * Getattr failed because the object was
384 381 * removed or renamed by another client.
385 382 * Remove any cached attributes under it.
386 383 */
387 384 smbfs_attrcache_prune(np);
388 385 }
389 386 return (error);
390 387 }
391 388
392 389 /*
393 390 * NFS: smbfs_cache_fattr(vap, fa, vap, t, cr);
394 391 * which did: fattr_to_vattr, nfs_attr_cache.
395 392 * We cache the fattr form, so just do the
396 393 * cache check and store the attributes.
397 394 */
398 395 smbfs_cache_check(vp, fap);
399 396 smbfs_attrcache_fa(vp, fap);
400 397
401 398 return (0);
402 399 }
403 400
404 401 /*
405 402 * Return either cached or remote attributes. If get remote attr
406 403 * use them to check and invalidate caches, then cache the new attributes.
407 404 *
408 405 * From NFS: nfsgetattr()
409 406 */
410 407 int
411 408 smbfsgetattr(vnode_t *vp, struct vattr *vap, cred_t *cr)
412 409 {
413 410 struct smbfattr fa;
414 411 smbmntinfo_t *smi;
415 412 uint_t mask;
416 413 int error;
417 414
418 415 smi = VTOSMI(vp);
419 416
420 417 ASSERT(curproc->p_zone == smi->smi_zone_ref.zref_zone);
421 418
422 419 /*
423 420 * If asked for UID or GID, update n_uid, n_gid.
424 421 */
425 422 mask = AT_ALL;
426 423 if (vap->va_mask & (AT_UID | AT_GID)) {
427 424 if (smi->smi_flags & SMI_ACL)
428 425 (void) smbfs_acl_getids(vp, cr);
429 426 /* else leave as set in make_smbnode */
430 427 } else {
431 428 mask &= ~(AT_UID | AT_GID);
432 429 }
433 430
434 431 /*
435 432 * If we've got cached attributes, just use them;
436 433 * otherwise go to the server to get attributes,
437 434 * which will update the cache in the process.
438 435 */
439 436 error = smbfs_getattr_cache(vp, &fa);
440 437 if (error)
441 438 error = smbfs_getattr_otw(vp, &fa, cr);
442 439 if (error)
443 440 return (error);
444 441
445 442 /*
446 443 * Re. client's view of the file size, see:
447 444 * smbfs_attrcache_fa, smbfs_getattr_otw
448 445 */
449 446
450 447 error = smbfattr_to_vattr(vp, &fa, vap);
451 448 vap->va_mask = mask;
452 449
453 450 return (error);
454 451 }
455 452
456 453
457 454 /*
458 455 * Convert SMB over the wire attributes to vnode form.
459 456 * Returns 0 for success, error if failed (overflow, etc).
460 457 * From NFS: nattr_to_vattr()
461 458 */
462 459 int
463 460 smbfattr_to_vattr(vnode_t *vp, struct smbfattr *fa, struct vattr *vap)
464 461 {
465 462 struct smbnode *np = VTOSMB(vp);
466 463
467 464 /* Set va_mask in caller */
468 465
469 466 /*
470 467 * Take type, mode, uid, gid from the smbfs node,
471 468 * which has have been updated by _getattr_otw.
472 469 */
473 470 vap->va_type = vp->v_type;
474 471 vap->va_mode = np->n_mode;
475 472
476 473 vap->va_uid = np->n_uid;
477 474 vap->va_gid = np->n_gid;
478 475
479 476 vap->va_fsid = vp->v_vfsp->vfs_dev;
480 477 vap->va_nodeid = np->n_ino;
481 478 vap->va_nlink = 1;
482 479
483 480 /*
484 481 * Difference from NFS here: We cache attributes as
485 482 * reported by the server, so r_attr.fa_size is the
486 483 * server's idea of the file size. This is called
487 484 * for getattr, so we want to return the client's
488 485 * idea of the file size. NFS deals with that in
489 486 * nfsgetattr(), the equivalent of our caller.
490 487 */
491 488 vap->va_size = np->r_size;
492 489
493 490 /*
494 491 * Times. Note, already converted from NT to
495 492 * Unix form (in the unmarshalling code).
496 493 */
497 494 vap->va_atime = fa->fa_atime;
498 495 vap->va_mtime = fa->fa_mtime;
499 496 vap->va_ctime = fa->fa_ctime;
500 497
501 498 /*
502 499 * rdev, blksize, seq are made up.
503 500 * va_nblocks is 512 byte blocks.
504 501 */
505 502 vap->va_rdev = vp->v_rdev;
506 503 vap->va_blksize = MAXBSIZE;
507 504 vap->va_nblocks = (fsblkcnt64_t)btod(np->r_attr.fa_allocsz);
508 505 vap->va_seq = 0;
509 506
510 507 return (0);
511 508 }
512 509
513 510
514 511 /*
515 512 * SMB Client initialization and cleanup.
516 513 * Much of it is per-zone now.
517 514 */
518 515
519 516
520 517 /* ARGSUSED */
521 518 static void *
522 519 smbfs_zone_init(zoneid_t zoneid)
523 520 {
524 521 smi_globals_t *smg;
525 522
526 523 smg = kmem_alloc(sizeof (*smg), KM_SLEEP);
527 524 mutex_init(&smg->smg_lock, NULL, MUTEX_DEFAULT, NULL);
528 525 list_create(&smg->smg_list, sizeof (smbmntinfo_t),
529 526 offsetof(smbmntinfo_t, smi_zone_node));
530 527 smg->smg_destructor_called = B_FALSE;
531 528 return (smg);
532 529 }
533 530
534 531 /*
535 532 * Callback routine to tell all SMBFS mounts in the zone to stop creating new
536 533 * threads. Existing threads should exit.
537 534 */
538 535 /* ARGSUSED */
539 536 static void
540 537 smbfs_zone_shutdown(zoneid_t zoneid, void *data)
541 538 {
542 539 smi_globals_t *smg = data;
543 540 smbmntinfo_t *smi;
544 541
545 542 ASSERT(smg != NULL);
546 543 again:
547 544 mutex_enter(&smg->smg_lock);
548 545 for (smi = list_head(&smg->smg_list); smi != NULL;
549 546 smi = list_next(&smg->smg_list, smi)) {
550 547
551 548 /*
552 549 * If we've done the shutdown work for this FS, skip.
553 550 * Once we go off the end of the list, we're done.
554 551 */
555 552 if (smi->smi_flags & SMI_DEAD)
556 553 continue;
557 554
558 555 /*
559 556 * We will do work, so not done. Get a hold on the FS.
560 557 */
561 558 VFS_HOLD(smi->smi_vfsp);
562 559
563 560 mutex_enter(&smi->smi_lock);
564 561 smi->smi_flags |= SMI_DEAD;
565 562 mutex_exit(&smi->smi_lock);
566 563
567 564 /*
568 565 * Drop lock and release FS, which may change list, then repeat.
569 566 * We're done when every mi has been done or the list is empty.
570 567 */
571 568 mutex_exit(&smg->smg_lock);
572 569 VFS_RELE(smi->smi_vfsp);
573 570 goto again;
574 571 }
575 572 mutex_exit(&smg->smg_lock);
576 573 }
577 574
578 575 static void
579 576 smbfs_zone_free_globals(smi_globals_t *smg)
580 577 {
581 578 list_destroy(&smg->smg_list); /* makes sure the list is empty */
582 579 mutex_destroy(&smg->smg_lock);
583 580 kmem_free(smg, sizeof (*smg));
584 581
585 582 }
586 583
587 584 /* ARGSUSED */
588 585 static void
589 586 smbfs_zone_destroy(zoneid_t zoneid, void *data)
590 587 {
591 588 smi_globals_t *smg = data;
592 589
593 590 ASSERT(smg != NULL);
594 591 mutex_enter(&smg->smg_lock);
595 592 if (list_head(&smg->smg_list) != NULL) {
596 593 /* Still waiting for VFS_FREEVFS() */
597 594 smg->smg_destructor_called = B_TRUE;
598 595 mutex_exit(&smg->smg_lock);
599 596 return;
600 597 }
601 598 smbfs_zone_free_globals(smg);
602 599 }
603 600
604 601 /*
605 602 * Add an SMBFS mount to the per-zone list of SMBFS mounts.
606 603 */
607 604 void
608 605 smbfs_zonelist_add(smbmntinfo_t *smi)
609 606 {
610 607 smi_globals_t *smg;
611 608
612 609 smg = zone_getspecific(smi_list_key, smi->smi_zone_ref.zref_zone);
613 610 mutex_enter(&smg->smg_lock);
614 611 list_insert_head(&smg->smg_list, smi);
615 612 mutex_exit(&smg->smg_lock);
616 613 }
617 614
618 615 /*
619 616 * Remove an SMBFS mount from the per-zone list of SMBFS mounts.
620 617 */
621 618 void
622 619 smbfs_zonelist_remove(smbmntinfo_t *smi)
623 620 {
624 621 smi_globals_t *smg;
625 622
626 623 smg = zone_getspecific(smi_list_key, smi->smi_zone_ref.zref_zone);
627 624 mutex_enter(&smg->smg_lock);
628 625 list_remove(&smg->smg_list, smi);
629 626 /*
630 627 * We can be called asynchronously by VFS_FREEVFS() after the zone
631 628 * shutdown/destroy callbacks have executed; if so, clean up the zone's
632 629 * smi_globals.
633 630 */
634 631 if (list_head(&smg->smg_list) == NULL &&
635 632 smg->smg_destructor_called == B_TRUE) {
636 633 smbfs_zone_free_globals(smg);
637 634 return;
638 635 }
639 636 mutex_exit(&smg->smg_lock);
640 637 }
641 638
642 639 #ifdef lint
643 640 #define NEED_SMBFS_CALLBACKS 1
644 641 #endif
645 642
646 643 #ifdef NEED_SMBFS_CALLBACKS
647 644 /*
648 645 * Call-back hooks for netsmb, in case we want them.
649 646 * Apple's VFS wants them. We may not need them.
650 647 */
651 648 /*ARGSUSED*/
652 649 static void smbfs_dead(smb_share_t *ssp)
653 650 {
654 651 /*
655 652 * Walk the mount list, finding all mounts
656 653 * using this share...
657 654 */
658 655 }
659 656
660 657 /*ARGSUSED*/
661 658 static void smbfs_cb_nop(smb_share_t *ss)
662 659 {
663 660 /* no-op */
664 661 }
665 662
666 663 smb_fscb_t smbfs_cb = {
667 664 .fscb_disconn = smbfs_dead,
668 665 .fscb_connect = smbfs_cb_nop,
669 666 .fscb_down = smbfs_cb_nop,
670 667 .fscb_up = smbfs_cb_nop };
671 668
672 669 #endif /* NEED_SMBFS_CALLBACKS */
673 670
674 671 /*
675 672 * SMBFS Client initialization routine. This routine should only be called
676 673 * once. It performs the following tasks:
677 674 * - Initalize all global locks
678 675 * - Call sub-initialization routines (localize access to variables)
679 676 */
680 677 int
681 678 smbfs_clntinit(void)
682 679 {
683 680
684 681 zone_key_create(&smi_list_key, smbfs_zone_init, smbfs_zone_shutdown,
685 682 smbfs_zone_destroy);
686 683 #ifdef NEED_SMBFS_CALLBACKS
687 684 (void) smb_fscb_set(&smbfs_cb);
688 685 #endif /* NEED_SMBFS_CALLBACKS */
689 686 return (0);
690 687 }
691 688
692 689 /*
693 690 * This routine is called when the modunload is called. This will cleanup
694 691 * the previously allocated/initialized nodes.
695 692 */
696 693 void
697 694 smbfs_clntfini(void)
698 695 {
699 696 #ifdef NEED_SMBFS_CALLBACKS
700 697 (void) smb_fscb_set(NULL);
701 698 #endif /* NEED_SMBFS_CALLBACKS */
702 699 (void) zone_key_delete(smi_list_key);
703 700 }
↓ open down ↓ |
391 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX