51 #include <sys/signal.h>
52 #include <sys/list.h>
53 #include <sys/zone.h>
54
55 #include <netsmb/smb.h>
56 #include <netsmb/smb_conn.h>
57 #include <netsmb/smb_subr.h>
58
59 #include <smbfs/smbfs.h>
60 #include <smbfs/smbfs_node.h>
61 #include <smbfs/smbfs_subr.h>
62
63 #include <vm/hat.h>
64 #include <vm/as.h>
65 #include <vm/page.h>
66 #include <vm/pvn.h>
67 #include <vm/seg.h>
68 #include <vm/seg_map.h>
69 #include <vm/seg_vn.h>
70
71 static int smbfs_getattr_cache(vnode_t *, struct smbfattr *);
72 static int smbfattr_to_vattr(vnode_t *, struct smbfattr *,
73 struct vattr *);
74
75 /*
76 * The following code provide zone support in order to perform an action
77 * for each smbfs mount in a zone. This is also where we would add
78 * per-zone globals and kernel threads for the smbfs module (since
79 * they must be terminated by the shutdown callback).
80 */
81
82 struct smi_globals {
83 kmutex_t smg_lock; /* lock protecting smg_list */
84 list_t smg_list; /* list of SMBFS mounts in zone */
85 boolean_t smg_destructor_called;
86 };
87 typedef struct smi_globals smi_globals_t;
88
89 static zone_key_t smi_list_key;
90
91 /*
92 * Attributes caching:
93 *
424 */
425 mask = AT_ALL;
426 if (vap->va_mask & (AT_UID | AT_GID)) {
427 if (smi->smi_flags & SMI_ACL)
428 (void) smbfs_acl_getids(vp, cr);
429 /* else leave as set in make_smbnode */
430 } else {
431 mask &= ~(AT_UID | AT_GID);
432 }
433
434 /*
435 * If we've got cached attributes, just use them;
436 * otherwise go to the server to get attributes,
437 * which will update the cache in the process.
438 */
439 error = smbfs_getattr_cache(vp, &fa);
440 if (error)
441 error = smbfs_getattr_otw(vp, &fa, cr);
442 if (error)
443 return (error);
444
445 /*
446 * Re. client's view of the file size, see:
447 * smbfs_attrcache_fa, smbfs_getattr_otw
448 */
449
450 error = smbfattr_to_vattr(vp, &fa, vap);
451 vap->va_mask = mask;
452
453 return (error);
454 }
455
456
457 /*
458 * Convert SMB over the wire attributes to vnode form.
459 * Returns 0 for success, error if failed (overflow, etc).
460 * From NFS: nattr_to_vattr()
461 */
462 int
463 smbfattr_to_vattr(vnode_t *vp, struct smbfattr *fa, struct vattr *vap)
464 {
465 struct smbnode *np = VTOSMB(vp);
466
467 /* Set va_mask in caller */
468
469 /*
470 * Take type, mode, uid, gid from the smbfs node,
471 * which has have been updated by _getattr_otw.
472 */
473 vap->va_type = vp->v_type;
474 vap->va_mode = np->n_mode;
475
476 vap->va_uid = np->n_uid;
477 vap->va_gid = np->n_gid;
478
479 vap->va_fsid = vp->v_vfsp->vfs_dev;
480 vap->va_nodeid = np->n_ino;
481 vap->va_nlink = 1;
482
483 /*
484 * Difference from NFS here: We cache attributes as
485 * reported by the server, so r_attr.fa_size is the
486 * server's idea of the file size. This is called
487 * for getattr, so we want to return the client's
488 * idea of the file size. NFS deals with that in
489 * nfsgetattr(), the equivalent of our caller.
490 */
491 vap->va_size = np->r_size;
492
493 /*
494 * Times. Note, already converted from NT to
495 * Unix form (in the unmarshalling code).
496 */
497 vap->va_atime = fa->fa_atime;
498 vap->va_mtime = fa->fa_mtime;
499 vap->va_ctime = fa->fa_ctime;
500
501 /*
502 * rdev, blksize, seq are made up.
503 * va_nblocks is 512 byte blocks.
504 */
505 vap->va_rdev = vp->v_rdev;
506 vap->va_blksize = MAXBSIZE;
507 vap->va_nblocks = (fsblkcnt64_t)btod(np->r_attr.fa_allocsz);
508 vap->va_seq = 0;
509
510 return (0);
511 }
512
513
514 /*
515 * SMB Client initialization and cleanup.
516 * Much of it is per-zone now.
517 */
518
519
520 /* ARGSUSED */
521 static void *
522 smbfs_zone_init(zoneid_t zoneid)
523 {
524 smi_globals_t *smg;
525
526 smg = kmem_alloc(sizeof (*smg), KM_SLEEP);
527 mutex_init(&smg->smg_lock, NULL, MUTEX_DEFAULT, NULL);
528 list_create(&smg->smg_list, sizeof (smbmntinfo_t),
529 offsetof(smbmntinfo_t, smi_zone_node));
530 smg->smg_destructor_called = B_FALSE;
531 return (smg);
532 }
533
|
51 #include <sys/signal.h>
52 #include <sys/list.h>
53 #include <sys/zone.h>
54
55 #include <netsmb/smb.h>
56 #include <netsmb/smb_conn.h>
57 #include <netsmb/smb_subr.h>
58
59 #include <smbfs/smbfs.h>
60 #include <smbfs/smbfs_node.h>
61 #include <smbfs/smbfs_subr.h>
62
63 #include <vm/hat.h>
64 #include <vm/as.h>
65 #include <vm/page.h>
66 #include <vm/pvn.h>
67 #include <vm/seg.h>
68 #include <vm/seg_map.h>
69 #include <vm/seg_vn.h>
70
71 static int smbfs_getattr_cache(vnode_t *, smbfattr_t *);
72 static void smbfattr_to_vattr(vnode_t *, smbfattr_t *, vattr_t *);
73 static void smbfattr_to_xvattr(vnode_t *, smbfattr_t *, vattr_t *);
74
75 /*
76 * The following code provide zone support in order to perform an action
77 * for each smbfs mount in a zone. This is also where we would add
78 * per-zone globals and kernel threads for the smbfs module (since
79 * they must be terminated by the shutdown callback).
80 */
81
82 struct smi_globals {
83 kmutex_t smg_lock; /* lock protecting smg_list */
84 list_t smg_list; /* list of SMBFS mounts in zone */
85 boolean_t smg_destructor_called;
86 };
87 typedef struct smi_globals smi_globals_t;
88
89 static zone_key_t smi_list_key;
90
91 /*
92 * Attributes caching:
93 *
424 */
425 mask = AT_ALL;
426 if (vap->va_mask & (AT_UID | AT_GID)) {
427 if (smi->smi_flags & SMI_ACL)
428 (void) smbfs_acl_getids(vp, cr);
429 /* else leave as set in make_smbnode */
430 } else {
431 mask &= ~(AT_UID | AT_GID);
432 }
433
434 /*
435 * If we've got cached attributes, just use them;
436 * otherwise go to the server to get attributes,
437 * which will update the cache in the process.
438 */
439 error = smbfs_getattr_cache(vp, &fa);
440 if (error)
441 error = smbfs_getattr_otw(vp, &fa, cr);
442 if (error)
443 return (error);
444 vap->va_mask |= mask;
445
446 /*
447 * Re. client's view of the file size, see:
448 * smbfs_attrcache_fa, smbfs_getattr_otw
449 */
450 smbfattr_to_vattr(vp, &fa, vap);
451 if (vap->va_mask & AT_XVATTR)
452 smbfattr_to_xvattr(vp, &fa, vap);
453
454 return (0);
455 }
456
457
458 /*
459 * Convert SMB over the wire attributes to vnode form.
460 * Returns 0 for success, error if failed (overflow, etc).
461 * From NFS: nattr_to_vattr()
462 */
463 void
464 smbfattr_to_vattr(vnode_t *vp, struct smbfattr *fa, struct vattr *vap)
465 {
466 struct smbnode *np = VTOSMB(vp);
467
468 /*
469 * Take type, mode, uid, gid from the smbfs node,
470 * which has have been updated by _getattr_otw.
471 */
472 vap->va_type = vp->v_type;
473 vap->va_mode = np->n_mode;
474
475 vap->va_uid = np->n_uid;
476 vap->va_gid = np->n_gid;
477
478 vap->va_fsid = vp->v_vfsp->vfs_dev;
479 vap->va_nodeid = np->n_ino;
480 vap->va_nlink = 1;
481
482 /*
483 * Difference from NFS here: We cache attributes as
484 * reported by the server, so r_attr.fa_size is the
485 * server's idea of the file size. This is called
486 * for getattr, so we want to return the client's
487 * idea of the file size. NFS deals with that in
488 * nfsgetattr(), the equivalent of our caller.
489 */
490 vap->va_size = np->r_size;
491
492 /*
493 * Times. Note, already converted from NT to
494 * Unix form (in the unmarshalling code).
495 */
496 vap->va_atime = fa->fa_atime;
497 vap->va_mtime = fa->fa_mtime;
498 vap->va_ctime = fa->fa_ctime;
499
500 /*
501 * rdev, blksize, seq are made up.
502 * va_nblocks is 512 byte blocks.
503 */
504 vap->va_rdev = vp->v_rdev;
505 vap->va_blksize = MAXBSIZE;
506 vap->va_nblocks = (fsblkcnt64_t)btod(np->r_attr.fa_allocsz);
507 vap->va_seq = 0;
508 }
509
510 /*
511 * smbfattr_to_xvattr: like smbfattr_to_vattr but for
512 * Extensible system attributes (PSARC 2007/315)
513 */
514 static void
515 smbfattr_to_xvattr(vnode_t *vp, struct smbfattr *fa, struct vattr *vap)
516 {
517 struct smbnode *np = VTOSMB(vp);
518 xvattr_t *xvap = (xvattr_t *)vap; /* *vap may be xvattr_t */
519 xoptattr_t *xoap = NULL;
520
521 if ((xoap = xva_getxoptattr(xvap)) == NULL)
522 return;
523
524 if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
525 xoap->xoa_createtime = fa->fa_createtime;
526 XVA_SET_RTN(xvap, XAT_CREATETIME);
527 }
528
529 if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) {
530 xoap->xoa_archive =
531 ((fa->fa_attr & SMB_FA_ARCHIVE) != 0);
532 XVA_SET_RTN(xvap, XAT_ARCHIVE);
533 }
534
535 if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) {
536 xoap->xoa_system =
537 ((fa->fa_attr & SMB_FA_SYSTEM) != 0);
538 XVA_SET_RTN(xvap, XAT_SYSTEM);
539 }
540
541 if (XVA_ISSET_REQ(xvap, XAT_READONLY)) {
542 xoap->xoa_readonly =
543 ((fa->fa_attr & SMB_FA_RDONLY) != 0);
544 XVA_SET_RTN(xvap, XAT_READONLY);
545 }
546
547 if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) {
548 xoap->xoa_hidden =
549 ((fa->fa_attr & SMB_FA_HIDDEN) != 0);
550 XVA_SET_RTN(xvap, XAT_HIDDEN);
551 }
552 }
553
554 /*
555 * SMB Client initialization and cleanup.
556 * Much of it is per-zone now.
557 */
558
559
560 /* ARGSUSED */
561 static void *
562 smbfs_zone_init(zoneid_t zoneid)
563 {
564 smi_globals_t *smg;
565
566 smg = kmem_alloc(sizeof (*smg), KM_SLEEP);
567 mutex_init(&smg->smg_lock, NULL, MUTEX_DEFAULT, NULL);
568 list_create(&smg->smg_list, sizeof (smbmntinfo_t),
569 offsetof(smbmntinfo_t, smi_zone_node));
570 smg->smg_destructor_called = B_FALSE;
571 return (smg);
572 }
573
|