diff options
Diffstat (limited to 'usr/src/cmd')
-rw-r--r-- | usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/smbclnt/mount/mntopts.h | 110 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/smbclnt/mount/mount.c | 400 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/smbfs/smbfs.c | 176 |
4 files changed, 284 insertions, 404 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c b/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c index 1285251898..afce3a64fd 100644 --- a/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c +++ b/usr/src/cmd/fs.d/smbclnt/lsacl/lsacl.c @@ -61,7 +61,7 @@ main(int argc, char **argv) uid_t uid; gid_t gid; int error, fd; - i_ntsd_t *sd; + struct i_ntsd *sd; progname = argv[0]; diff --git a/usr/src/cmd/fs.d/smbclnt/mount/mntopts.h b/usr/src/cmd/fs.d/smbclnt/mount/mntopts.h deleted file mode 100644 index 6b908f3c7f..0000000000 --- a/usr/src/cmd/fs.d/smbclnt/mount/mntopts.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)mntopts.h 8.7 (Berkeley) 3/29/95 - * $Id: mntopts.h,v 1.4 2004/03/19 01:49:47 lindak Exp $ - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _CIFS_MNTOPTS_H -#define _CIFS_MNTOPTS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/vfs.h> -#ifdef UNPORTED -/* In solaris this is defined in proto/root_i386/usr/include/sys/vfs.h */ -struct mntopt { - const char *m_option; /* option name */ - int m_inverse; /* if a negative option, e.g. "dev" */ - int m_flag; /* bit to set, e.g. MNT_RDONLY */ - int m_altloc; /* 1 => set bit in altflags */ -}; -#endif /* UNPORTED */ - -/* User-visible MNT_ flags. */ -#define MOPT_ASYNC { "async", 0, MNT_ASYNC, 0 } -#define MOPT_NODEV { "dev", 1, MNT_NODEV, 0 } -#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 } -#define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 } -#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 } -#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 } -#define MOPT_UNION { "union", 0, MNT_UNION, 0 } -#define MOPT_USERQUOTA { "userquota", 0, 0, 0 } -#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 } -#define MOPT_BROWSE { "browse", 1, MNT_DONTBROWSE, 0 } -#define MOPT_AUTOMOUNTED { "automounted", 0, MNT_AUTOMOUNTED, 0 } - -/* Control flags. */ -#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 } -#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 } -#define MOPT_RO { "ro", 0, MNT_RDONLY, 0 } -#define MOPT_RW { "rw", 1, MNT_RDONLY, 0 } - -/* This is parsed by mount(1m), but is ignored by specific mount_*(1m)s. */ -#define MOPT_AUTO { "auto", 0, 0, 0 } - -#define MOPT_FSTAB_COMPAT \ - MOPT_RO, \ - MOPT_RW, \ - MOPT_AUTO - -/* Standard options which all mounts can understand. */ -#define MOPT_STDOPTS \ - MOPT_USERQUOTA, \ - MOPT_GROUPQUOTA, \ - MOPT_FSTAB_COMPAT, \ - MOPT_NODEV, \ - MOPT_NOEXEC, \ - MOPT_NOSUID, \ - MOPT_RDONLY, \ - MOPT_UNION, \ - MOPT_BROWSE, \ - MOPT_AUTOMOUNTED - -void getmntopts(const char *, const mntopt_t *, int *, int *); - -extern int getmnt_silent; - -#ifdef __cplusplus -} -#endif - -#endif /* _CIFS_MNTOPTS_H */ diff --git a/usr/src/cmd/fs.d/smbclnt/mount/mount.c b/usr/src/cmd/fs.d/smbclnt/mount/mount.c index 9068d093b6..5b2cac4ee7 100644 --- a/usr/src/cmd/fs.d/smbclnt/mount/mount.c +++ b/usr/src/cmd/fs.d/smbclnt/mount/mount.c @@ -47,7 +47,6 @@ #include <stdlib.h> #include <errno.h> #include <err.h> -#include <sysexits.h> #include <libintl.h> #include <locale.h> #include <libscf.h> @@ -59,93 +58,110 @@ #include <sys/mntent.h> #include <sys/mnttab.h> -/* This needs to know ctx->ct_dev_fd, etc. */ -#include <netsmb/smb_lib.h> - #include <sys/fs/smbfs_mount.h> -#include "mntopts.h" +/* This needs to know ctx->ct_dev_fd, etc. */ +#include <netsmb/smb_lib.h> extern char *optarg; extern int optind; static char mount_point[MAXPATHLEN + 1]; static void usage(void); -static int setsubopt(smb_ctx_t *, struct smbfs_args *, int, char *); - -/* smbfs options */ -#define MNTOPT_DOMAIN "domain" -#define MNTOPT_USER "user" -#define MNTOPT_DIRPERMS "dirperms" -#define MNTOPT_FILEPERMS "fileperms" -#define MNTOPT_GID "gid" -#define MNTOPT_UID "uid" -#define MNTOPT_NOPROMPT "noprompt" - -#define OPT_DOMAIN 1 -#define OPT_USER 2 -#define OPT_DIRPERMS 3 -#define OPT_FILEPERMS 4 -#define OPT_GID 5 -#define OPT_UID 6 -#define OPT_NOPROMPT 7 - -/* generic VFS options */ -#define OPT_RO 10 -#define OPT_RW 11 -#define OPT_SUID 12 -#define OPT_NOSUID 13 -#define OPT_DEVICES 14 -#define OPT_NODEVICES 15 -#define OPT_SETUID 16 -#define OPT_NOSETUID 17 -#define OPT_EXEC 18 -#define OPT_NOEXEC 19 - -struct smbfsopts { - char *name; - int index; -}; - -struct smbfsopts opts[] = { - {MNTOPT_DOMAIN, OPT_DOMAIN}, - {MNTOPT_USER, OPT_USER}, - {MNTOPT_DIRPERMS, OPT_DIRPERMS}, - {MNTOPT_FILEPERMS, OPT_FILEPERMS}, - {MNTOPT_GID, OPT_GID}, - {MNTOPT_UID, OPT_UID}, - {MNTOPT_NOPROMPT, OPT_NOPROMPT}, - {MNTOPT_RO, OPT_RO}, - {MNTOPT_RW, OPT_RW}, - {MNTOPT_SUID, OPT_SUID}, - {MNTOPT_NOSUID, OPT_NOSUID}, - {MNTOPT_DEVICES, OPT_DEVICES}, - {MNTOPT_NODEVICES, OPT_NODEVICES}, - {MNTOPT_SETUID, OPT_SETUID}, - {MNTOPT_NOSETUID, OPT_NOSETUID}, - {MNTOPT_EXEC, OPT_EXEC}, - {MNTOPT_NOEXEC, OPT_NOEXEC}, - {NULL, 0} +static int setsubopt(smb_ctx_t *, struct smbfs_args *, char *); + +const char * const optlist[] = { + + /* Generic VFS options. */ +#define OPT_RO 0 + MNTOPT_RO, +#define OPT_RW 1 + MNTOPT_RW, +#define OPT_SUID 2 + MNTOPT_SUID, +#define OPT_NOSUID 3 + MNTOPT_NOSUID, +#define OPT_DEVICES 4 + MNTOPT_DEVICES, +#define OPT_NODEVICES 5 + MNTOPT_NODEVICES, +#define OPT_SETUID 6 + MNTOPT_SETUID, +#define OPT_NOSETUID 7 + MNTOPT_NOSETUID, +#define OPT_EXEC 8 + MNTOPT_EXEC, +#define OPT_NOEXEC 9 + MNTOPT_NOEXEC, +#define OPT_XATTR 10 + MNTOPT_XATTR, +#define OPT_NOXATTR 11 + MNTOPT_NOXATTR, + + /* Sort of generic (from NFS) */ +#define OPT_NOAC 12 + MNTOPT_NOAC, +#define OPT_ACTIMEO 13 + MNTOPT_ACTIMEO, +#define OPT_ACREGMIN 14 + MNTOPT_ACREGMIN, +#define OPT_ACREGMAX 15 + MNTOPT_ACREGMAX, +#define OPT_ACDIRMIN 16 + MNTOPT_ACDIRMIN, +#define OPT_ACDIRMAX 17 + MNTOPT_ACDIRMAX, + + /* smbfs-specifis options */ +#define OPT_DOMAIN 18 + "domain", +#define OPT_USER 19 + "user", +#define OPT_UID 20 + "uid", +#define OPT_GID 21 + "gid", +#define OPT_DIRPERMS 22 + "dirperms", +#define OPT_FILEPERMS 23 + "fileperms", +#define OPT_NOPROMPT 24 + "noprompt", + + NULL }; static int Oflg = 0; /* Overlay mounts */ static int qflg = 0; /* quiet - don't print warnings on bad options */ -static int ro = 0; /* read-only mount */ static int noprompt = 0; /* don't prompt for password */ -#define RET_ERR 33 +/* Note: smbfs uses _both_ kinds of options. */ +static int mntflags = MS_DATA | MS_OPTIONSTR; + +#define EX_OK 0 /* normal */ +#define EX_OPT 1 /* bad options, usage, etc */ +#define EX_MNT 2 /* mount point problems, etc */ +#define RET_ERR 3 /* later errors */ + #define SERVICE "svc:/network/smb/client:default" struct smbfs_args mdata; struct mnttab mnt; -char optbuf[MAX_MNTOPT_STR]; + +/* + * Initialize this with "rw" just to have something there, + * so we don't have to decide whether to add a comma when + * we strcat another option. Note the "rw" may be changed + * to an "ro" by option processing. + */ +char optbuf[MAX_MNTOPT_STR] = "rw"; int main(int argc, char *argv[]) { struct smb_ctx *ctx = NULL; struct stat st; - int opt, error, err2, mntflags; + int opt, error, err2; static char *fstype = MNTTYPE_SMBFS; char *env, *state; @@ -188,13 +204,11 @@ main(int argc, char *argv[]) exit(RET_ERR); mnt.mnt_mntopts = optbuf; - mntflags = MS_DATA; bzero(&mdata, sizeof (mdata)); mdata.version = SMBFS_VERSION; /* smbfs mount version */ mdata.uid = (uid_t)-1; mdata.gid = (gid_t)-1; - mdata.caseopt = SMB_CS_NONE; error = smb_ctx_alloc(&ctx); if (error) @@ -209,11 +223,11 @@ main(int argc, char *argv[]) error = smb_ctx_parseunc(ctx, argv[argc - 2], SMBL_SHARE, SMBL_SHARE, USE_DISKDEV, NULL); if (error) - exit(RET_ERR); + exit(EX_OPT); error = smb_ctx_readrc(ctx); if (error) - exit(RET_ERR); + exit(EX_OPT); while ((opt = getopt(argc, argv, "ro:Oq")) != -1) { switch (opt) { @@ -226,19 +240,13 @@ main(int argc, char *argv[]) break; case 'r': - ro++; + mntflags |= MS_RDONLY; break; case 'o': { - char *nextopt, *comma, *equals, *sopt, *soptval; - int i, ret; - - if (strlen(optarg) >= MAX_MNTOPT_STR) { - if (!qflg) - warnx(gettext( - "option string too long")); - exit(RET_ERR); - } + char *nextopt, *comma, *sopt; + int ret; + for (sopt = optarg; sopt != NULL; sopt = nextopt) { comma = strchr(sopt, ','); if (comma) { @@ -246,33 +254,10 @@ main(int argc, char *argv[]) *comma = '\0'; } else nextopt = NULL; - equals = strchr(sopt, '='); - if (equals) { - soptval = equals + 1; - *equals = '\0'; - } else - soptval = NULL; - for (i = 0; opts[i].name != NULL; i++) { - if (strcmp(sopt, opts[i].name) == 0) - break; - } - if (opts[i].name == NULL) { - if (equals) - *equals = '='; - if (!qflg) - errx(RET_ERR, gettext( - "Bad option '%s'"), sopt); - if (comma) - *comma = ','; - continue; - } - ret = setsubopt(ctx, &mdata, - opts[i].index, soptval); + ret = setsubopt(ctx, &mdata, sopt); if (ret != 0) - exit(RET_ERR); - if (equals) - *equals = '='; - (void) strcat(mnt.mnt_mntopts, sopt); + exit(EX_OPT); + /* undo changes to optarg */ if (comma) *comma = ','; } @@ -288,12 +273,10 @@ main(int argc, char *argv[]) if (Oflg) mntflags |= MS_OVERLAY; - if (ro) { + if (mntflags & MS_RDONLY) { char *p; - - mntflags |= MS_RDONLY; /* convert "rw"->"ro" */ - if (p = strstr(mnt.mnt_mntopts, "rw")) { + if (p = strstr(optbuf, "rw")) { if (*(p+2) == ',' || *(p+2) == '\0') *(p+1) = 'o'; } @@ -307,11 +290,11 @@ main(int argc, char *argv[]) realpath(argv[optind+1], mount_point); if (stat(mount_point, &st) == -1) - err(EX_OSERR, gettext("could not find mount point %s"), + err(EX_MNT, gettext("could not find mount point %s"), mount_point); if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR; - err(EX_OSERR, gettext("can't mount on %s"), mount_point); + err(EX_MNT, gettext("can't mount on %s"), mount_point); } /* @@ -379,40 +362,57 @@ again: mntflags, fstype, &mdata, sizeof (mdata), mnt.mnt_mntopts, MAX_MNTOPT_STR) < 0) { if (errno != ENOENT) { - err(EX_OSERR, gettext("mount_smbfs: %s"), + err(EX_MNT, gettext("mount_smbfs: %s"), mnt.mnt_mountp); } else { struct stat sb; if (stat(mnt.mnt_mountp, &sb) < 0 && errno == ENOENT) - err(EX_OSERR, gettext("mount_smbfs: %s"), + err(EX_MNT, gettext("mount_smbfs: %s"), mnt.mnt_mountp); else - err(EX_OSERR, gettext("mount_smbfs: %s"), + err(EX_MNT, gettext("mount_smbfs: %s"), mnt.mnt_special); } } smb_ctx_free(ctx); - if (error) { - smb_error(gettext("mount error: %s"), error, mount_point); - exit(RET_ERR); - } return (0); } +#define bad(val) (val == NULL || !isdigit(*val)) + int -setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, int index, char *optarg) +setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, char *subopt) { + char *equals, *optarg; struct passwd *pwd; struct group *grp; - long l; - int err = 0; - char *next; + long val; + int rc = EX_OK; + int index; + char *p; + + equals = strchr(subopt, '='); + if (equals) { + *equals = '\0'; + optarg = equals + 1; + } else + optarg = NULL; + + for (index = 0; optlist[index] != NULL; index++) { + if (strcmp(subopt, optlist[index]) == 0) + break; + } + + /* + * Note: if the option was unknown, index will + * point to the NULL at the end of optlist[], + * and we'll take the switch default. + */ switch (index) { - case OPT_RO: - case OPT_RW: + case OPT_SUID: case OPT_NOSUID: case OPT_DEVICES: @@ -421,15 +421,106 @@ setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, int index, char *optarg) case OPT_NOSETUID: case OPT_EXEC: case OPT_NOEXEC: - /* We don't have to handle generic options here */ - return (0); + case OPT_XATTR: + case OPT_NOXATTR: + /* + * These options are handled via the + * generic option string mechanism. + * None of these take an optarg. + */ + if (optarg != NULL) + goto badval; + (void) strlcat(optbuf, ",", sizeof (optbuf)); + if (strlcat(optbuf, subopt, sizeof (optbuf)) >= + sizeof (optbuf)) { + if (!qflg) + warnx(gettext("option string too long")); + rc = EX_OPT; + } + break; + + /* + * OPT_RO, OPT_RW, are actually generic too, + * but we use the mntflags for these, and + * then update the options string later. + */ + case OPT_RO: + mntflags |= MS_RDONLY; + break; + case OPT_RW: + mntflags &= ~MS_RDONLY; + break; + + /* + * NFS-derived options for attribute cache + * handling (disable, set min/max timeouts) + */ + case OPT_NOAC: + mdatap->flags |= SMBFS_MF_NOAC; + break; + + case OPT_ACTIMEO: + errno = 0; + val = strtol(optarg, &p, 10); + if (errno || *p != 0) + goto badval; + mdatap->acdirmin = mdatap->acregmin = val; + mdatap->acdirmax = mdatap->acregmax = val; + mdatap->flags |= SMBFS_MF_ACDIRMAX; + mdatap->flags |= SMBFS_MF_ACREGMAX; + mdatap->flags |= SMBFS_MF_ACDIRMIN; + mdatap->flags |= SMBFS_MF_ACREGMIN; + break; + + case OPT_ACREGMIN: + errno = 0; + val = strtol(optarg, &p, 10); + if (errno || *p != 0) + goto badval; + mdatap->acregmin = val; + mdatap->flags |= SMBFS_MF_ACREGMIN; + break; + + case OPT_ACREGMAX: + errno = 0; + val = strtol(optarg, &p, 10); + if (errno || *p != 0) + goto badval; + mdatap->acregmax = val; + mdatap->flags |= SMBFS_MF_ACREGMAX; + break; + + case OPT_ACDIRMIN: + errno = 0; + val = strtol(optarg, &p, 10); + if (errno || *p != 0) + goto badval; + mdatap->acdirmin = val; + mdatap->flags |= SMBFS_MF_ACDIRMIN; + break; + + case OPT_ACDIRMAX: + errno = 0; + val = strtol(optarg, &p, 10); + if (errno || *p != 0) + goto badval; + mdatap->acdirmax = val; + mdatap->flags |= SMBFS_MF_ACDIRMAX; + break; + /* + * SMBFS-specific options. Some of these + * don't go through the mount system call, + * but just set libsmbfs options. + */ case OPT_DOMAIN: - err = smb_ctx_setdomain(ctx, optarg, B_TRUE); + if (smb_ctx_setdomain(ctx, optarg, B_TRUE) != 0) + rc = EX_OPT; break; case OPT_USER: - err = smb_ctx_setuser(ctx, optarg, B_TRUE); + if (smb_ctx_setuser(ctx, optarg, B_TRUE) != 0) + rc = EX_OPT; break; case OPT_UID: @@ -438,49 +529,62 @@ setsubopt(smb_ctx_t *ctx, struct smbfs_args *mdatap, int index, char *optarg) if (pwd == NULL) { if (!qflg) warnx(gettext("unknown user '%s'"), optarg); - err = -1; + rc = EX_OPT; } else { mdatap->uid = pwd->pw_uid; } break; + case OPT_GID: grp = isdigit(optarg[0]) ? getgrgid(atoi(optarg)) : getgrnam(optarg); if (grp == NULL) { if (!qflg) warnx(gettext("unknown group '%s'"), optarg); - err = -1; + rc = EX_OPT; } else { mdatap->gid = grp->gr_gid; } break; + case OPT_DIRPERMS: errno = 0; - l = strtol(optarg, &next, 8); - if (errno || *next != 0) { - if (!qflg) - warnx(gettext( - "invalid value for directory mode")); - err = -1; - } else { - mdatap->dir_mode = l; - } + val = strtol(optarg, &p, 8); + if (errno || *p != 0) + goto badval; + mdatap->dir_mode = val; break; + case OPT_FILEPERMS: errno = 0; - l = strtol(optarg, &next, 8); - if (errno || *next != 0) { - if (!qflg) - warnx(gettext("invalid value for file mode")); - err = -1; - } else { - mdatap->file_mode = l; - } + val = strtol(optarg, &p, 8); + if (errno || *p != 0) + goto badval; + mdatap->file_mode = val; break; + case OPT_NOPROMPT: noprompt++; + break; + + default: + if (!qflg) + warnx(gettext("unknown option %s"), subopt); + rc = EX_OPT; + break; + + badval: + if (!qflg) + warnx(gettext("invalid value for %s"), subopt); + rc = EX_OPT; + break; } - return (err); + + /* Undo changes made to subopt */ + if (equals) + *equals = '='; + + return (rc); } static void @@ -490,5 +594,5 @@ usage(void) gettext("usage: mount -F smbfs [-Orq] [-o option[,option]]" " //[workgroup;][user[:password]@]server[/share] path")); - exit(EX_USAGE); + exit(EX_OPT); } diff --git a/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c b/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c index 11aeb9f081..4841a41cd8 100644 --- a/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c +++ b/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c @@ -20,13 +20,10 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/mdb_modapi.h> #include <sys/types.h> #include <sys/refstr_impl.h> @@ -176,138 +173,29 @@ smbfs_vfs_help(void) } /* - * Walker for the smbnode hash table. - */ - -typedef struct smbnode_walk_data { - rhashq_t *smbtab; /* (our copy of) the smbtable */ - int tabsize; /* size of table */ - int nextidx; /* next bucket index */ - uintptr_t buckptr; /* target addr of current bucket */ - uintptr_t nodeptr; /* target addr of current smbnode */ - smbnode_t node; /* scratch space for _step */ -} smbnode_walk_data_t; - -int -smbnode_walk_init(mdb_walk_state_t *wsp) -{ - size_t tabsz_bytes; - int tabsize; - uintptr_t smbtab; - smbnode_walk_data_t *smbw; - - if (wsp->walk_addr != NULL) { - mdb_warn("smbnode only supports global walks\n"); - return (WALK_ERR); - } - - if (mdb_readvar(&tabsize, "smbtablesize") == -1) { - mdb_warn("failed to read `smbtablesize'\n"); - return (WALK_ERR); - } - - if (tabsize == 0) { - return (WALK_DONE); - } - - if (mdb_readvar(&smbtab, "smbtable") == -1) { - mdb_warn("failed to read `smbtable'\n"); - return (WALK_ERR); - } - - smbw = mdb_alloc(sizeof (*smbw), UM_SLEEP | UM_GC); - - tabsz_bytes = tabsize * sizeof (rhashq_t); - smbw->smbtab = mdb_alloc(tabsz_bytes, UM_SLEEP | UM_GC); - if (mdb_vread(smbw->smbtab, tabsz_bytes, smbtab) != tabsz_bytes) { - mdb_warn("failed to read in smbtable from %p", smbtab); - return (WALK_ERR); - } - smbw->tabsize = tabsize; - smbw->nextidx = 1; - smbw->buckptr = smbtab; - smbw->nodeptr = (uintptr_t)smbw->smbtab[0].r_hashf; - wsp->walk_data = smbw; - - return (WALK_NEXT); -} - -int -smbnode_walk_step(mdb_walk_state_t *wsp) -{ - smbnode_walk_data_t *smbw = wsp->walk_data; - int status; - -next_bucket: - while (smbw->nodeptr == smbw->buckptr && - smbw->nextidx < smbw->tabsize) { - - /* Skip an empty bucket */ - rhashq_t *h = &smbw->smbtab[smbw->nextidx]; - smbw->nodeptr = (uintptr_t)h->r_hashf; - smbw->nextidx++; - smbw->buckptr += sizeof (rhashq_t); - } - - if (smbw->nodeptr == smbw->buckptr) - return (WALK_DONE); - - if (mdb_vread(&smbw->node, sizeof (smbw->node), - smbw->nodeptr) != sizeof (smbw->node)) { - mdb_warn("failed to read smbnode at %p in bucket %p\n", - smbw->nodeptr, smbw->buckptr); - /* Proceed with next bucket. */ - smbw->nodeptr = smbw->buckptr; - goto next_bucket; - } - - status = wsp->walk_callback(smbw->nodeptr, - &smbw->node, wsp->walk_cbdata); - - /* Move to next node in this bucket */ - smbw->nodeptr = (uintptr_t)smbw->node.r_hashf; - - return (status); -} - -/*ARGSUSED*/ -void -smbnode_walk_fini(mdb_walk_state_t *wsp) -{ - /* UM_GC takes care of it all. */ -} - -/* * Dcmd (and callback function) to print a summary of - * all smbnodes in the node hash table. + * all smbnodes in the node "hash" (cache) AVL tree. */ -typedef struct smbnode_cbdata { +typedef struct smbfs_node_cbdata { int flags; int printed_header; - uintptr_t smi; /* optional filtering by VFS */ - /* TODO: only nodes with a given [-h]ash */ - vnode_t vn; /* scratch space for smbnode_cb */ -} smbnode_cbdata_t; + vnode_t vn; +} smbfs_node_cbdata_t; int -smbnode_cb(uintptr_t addr, const void *data, void *arg) +smbfs_node_cb(uintptr_t addr, const void *data, void *arg) { const smbnode_t *np = data; - smbnode_cbdata_t *cbd = arg; - - /* Optional filtering by mount point. */ - if (cbd->smi && cbd->smi != (uintptr_t)np->n_mount) { - return (WALK_NEXT); - } + smbfs_node_cbdata_t *cbd = arg; if (cbd->printed_header == 0) { cbd->printed_header = 1; - mdb_printf("// smbnode vnode rpath\n"); + mdb_printf("// vnode smbnode rpath\n"); } - mdb_printf(" %-p", addr); /* smbnode */ mdb_printf(" %-p", (uintptr_t)np->r_vnode); + mdb_printf(" %-p", addr); /* smbnode */ print_str((uintptr_t)np->n_rpath); mdb_printf("\n"); @@ -320,9 +208,8 @@ smbnode_cb(uintptr_t addr, const void *data, void *arg) (uintptr_t)np->r_vnode); } else { /* Interesting parts of vnode_t */ - mdb_printf("v_type: %d v_path:", - cbd->vn.v_type); - print_str((uintptr_t)cbd->vn.v_path); + mdb_printf("v_type=%d v_count=%d", + cbd->vn.v_type, cbd->vn.v_count); mdb_printf("\n"); } mdb_dec_indent(2); @@ -332,55 +219,54 @@ smbnode_cb(uintptr_t addr, const void *data, void *arg) } int -smbnode_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +smbfs_node_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { - smbnode_cbdata_t *cbd; - smbnode_t *np; + smbfs_node_cbdata_t *cbd; cbd = mdb_zalloc(sizeof (*cbd), UM_SLEEP | UM_GC); if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, OPT_VERBOSE, &cbd->flags, - 'm', MDB_OPT_UINTPTR, &cbd->smi, NULL) != argc) { + NULL) != argc) { return (DCMD_USAGE); } if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk("smbnode", smbnode_cb, cbd) - == -1) { - mdb_warn("cannot walk smbnodes"); - return (DCMD_ERR); - } - return (DCMD_OK); + mdb_warn("expect an smbmntinfo_t addr"); + return (DCMD_USAGE); } + addr += OFFSETOF(smbmntinfo_t, smi_hash_avl); - np = mdb_alloc(sizeof (*np), UM_SLEEP | UM_GC); - SMBFS_OBJ_FETCH(addr, smbnode_t, np, DCMD_ERR); - smbnode_cb(addr, np, cbd); + if (mdb_pwalk("genunix`avl", smbfs_node_cb, cbd, addr) == -1) { + mdb_warn("cannot walk smbfs nodes"); + return (DCMD_ERR); + } return (DCMD_OK); } void -smbnode_help(void) +smbfs_node_help(void) { mdb_printf("Options:\n" - " -m mntinfo only show smbnodes belonging to mntinfo\n" " -v be verbose when displaying smbnodes\n"); } static const mdb_dcmd_t dcmds[] = { - { "smbfs_vfs", "?[-v]", + { + "smbfs_vfs", "?[-v]", "show smbfs-mounted vfs structs", - smbfs_vfs_dcmd, smbfs_vfs_help }, - { "smbnode", "?[-v] [-m mntinfo]", - "show smbnodes", smbnode_dcmd, smbnode_help }, + smbfs_vfs_dcmd, smbfs_vfs_help + }, + { + "smbfs_node", "?[-v]", + "given an smbmntinfo_t, list smbnodes", + smbfs_node_dcmd, smbfs_node_help + }, {NULL} }; static const mdb_walker_t walkers[] = { - { "smbnode", "walk smbnode hash table", - smbnode_walk_init, smbnode_walk_step, smbnode_walk_fini }, {NULL} }; |