summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorth199096 <none@none>2007-10-22 15:49:36 -0700
committerth199096 <none@none>2007-10-22 15:49:36 -0700
commitb9238976491622ad75a67ab0c12edf99e36212b9 (patch)
tree9b05921ffcef7973ffdbbb12b4e5b867fdaf70c1
parent90c85bf889e3af34323084f00e344a82f120b409 (diff)
downloadillumos-gate-b9238976491622ad75a67ab0c12edf99e36212b9.tar.gz
PSARC 2007/416 NFSv4 Mirror-mounts
PSARC 2007/563 Add _AT_TRIGGER to fstatat(2) 5035401 allow clients to cross server filesystem boundaries if the fs is visible 6613892 nftw(3C) has potential security issues
-rw-r--r--usr/src/cmd/fs.d/autofs/autod_nfs.c8
-rw-r--r--usr/src/cmd/fs.d/nfs/lib/nfs_subr.c51
-rw-r--r--usr/src/cmd/fs.d/nfs/mount/mount.c643
-rw-r--r--usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c141
-rw-r--r--usr/src/cmd/rexd/Makefile10
-rw-r--r--usr/src/cmd/rexd/mount_nfs.c242
-rw-r--r--usr/src/lib/libc/port/gen/nftw.c136
-rw-r--r--usr/src/uts/common/Makefile.files2
-rw-r--r--usr/src/uts/common/fs/autofs/auto_vnops.c87
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_client.c277
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_client_secinfo.c99
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_recovery.c215
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_rnode.c129
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c2448
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_subr.c104
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_vfsops.c471
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_vnops.c1228
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_sys.c13
-rw-r--r--usr/src/uts/common/fs/vfs.c2
-rw-r--r--usr/src/uts/common/nfs/mount.h13
-rw-r--r--usr/src/uts/common/nfs/nfs4.h3
-rw-r--r--usr/src/uts/common/nfs/nfs4_clnt.h169
-rw-r--r--usr/src/uts/common/nfs/nfssys.h5
-rw-r--r--usr/src/uts/common/nfs/rnode4.h23
-rw-r--r--usr/src/uts/common/rpc/sec/sec_clnt.c79
-rw-r--r--usr/src/uts/common/sys/fcntl.h3
-rw-r--r--usr/src/uts/common/sys/vnode.h1
-rw-r--r--usr/src/uts/common/syscall/stat.c22
-rw-r--r--usr/src/uts/common/syscall/umount.c123
-rw-r--r--usr/src/uts/intel/nfs/Makefile4
-rw-r--r--usr/src/uts/sparc/nfs/Makefile5
31 files changed, 4819 insertions, 1937 deletions
diff --git a/usr/src/cmd/fs.d/autofs/autod_nfs.c b/usr/src/cmd/fs.d/autofs/autod_nfs.c
index d750376974..903f3b8f18 100644
--- a/usr/src/cmd/fs.d/autofs/autod_nfs.c
+++ b/usr/src/cmd/fs.d/autofs/autod_nfs.c
@@ -85,6 +85,8 @@
#include <tsol/label.h>
#include <zone.h>
+extern void set_nfsv4_ephemeral_mount_to(void);
+
extern char *nfs_get_qop_name();
extern AUTH *nfs_create_ah();
extern enum snego_stat nfs_sec_nego();
@@ -2378,6 +2380,12 @@ try_mnt_slash:
}
/*
+ * About to do a nfs mount, make sure the mount_to is set for
+ * potential ephemeral mounts with NFSv4.
+ */
+ set_nfsv4_ephemeral_mount_to();
+
+ /*
* If no action list pointer then do the mount, otherwise
* build the actions list pointer with the mount information.
* so the mount can be done in the kernel.
diff --git a/usr/src/cmd/fs.d/nfs/lib/nfs_subr.c b/usr/src/cmd/fs.d/nfs/lib/nfs_subr.c
index b78d4e124f..0dbdbbe6a3 100644
--- a/usr/src/cmd/fs.d/nfs/lib/nfs_subr.c
+++ b/usr/src/cmd/fs.d/nfs/lib/nfs_subr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,10 +19,8 @@
* CDDL HEADER END
*/
/*
- * nfs_subr.c
- *
- * Copyright (c) 1996 Sun Microsystems Inc
- * All Rights Reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -35,6 +32,11 @@
#include <sys/utsname.h>
#include <nfs/nfs.h>
#include "nfs_subr.h"
+#include <errno.h>
+#include <deflt.h>
+
+#include <nfs/nfssys.h>
+extern int _nfssys(enum nfssys_op, void *);
/*
* This function is added to detect compatibility problem with SunOS4.x.
@@ -75,8 +77,8 @@ remote_lock(char *fshost, caddr_t fh)
return (0);
rpc_stat = clnt_call(cl, NLM_GRANTED,
- xdr_nlm_testargs, (caddr_t)&rlm_args,
- xdr_nlm_res, (caddr_t)&rlm_res, timeout);
+ xdr_nlm_testargs, (caddr_t)&rlm_args,
+ xdr_nlm_res, (caddr_t)&rlm_res, timeout);
clnt_destroy(cl);
return (rpc_stat == RPC_CANTDECODEARGS);
@@ -242,3 +244,34 @@ convert_special(char **specialp, char *host, char *oldpath, char *newpath,
free(url);
return (0);
}
+
+/*
+ * Solaris autofs configuration file location
+ */
+#define AUTOFSADMIN "/etc/default/autofs"
+#define AUTOFS_MOUNT_TIMEOUT 600 /* default min time mount will */
+
+void
+set_nfsv4_ephemeral_mount_to(void)
+{
+ char *defval;
+
+ uint_t mount_to = AUTOFS_MOUNT_TIMEOUT;
+
+ /*
+ * Get the value from /etc/default/autofs
+ */
+ if ((defopen(AUTOFSADMIN)) == 0) {
+ if ((defval = defread("AUTOMOUNT_TIMEOUT=")) != NULL) {
+ errno = 0;
+ mount_to = strtoul(defval, (char **)NULL, 10);
+ if (errno != 0)
+ mount_to = AUTOFS_MOUNT_TIMEOUT;
+ }
+
+ /* close defaults file */
+ defopen(NULL);
+ }
+
+ (void) _nfssys(NFS4_EPHEMERAL_MOUNT_TO, &mount_to);
+}
diff --git a/usr/src/cmd/fs.d/nfs/mount/mount.c b/usr/src/cmd/fs.d/nfs/mount/mount.c
index a6bba0b601..318ee6ae8c 100644
--- a/usr/src/cmd/fs.d/nfs/mount/mount.c
+++ b/usr/src/cmd/fs.d/nfs/mount/mount.c
@@ -82,6 +82,9 @@
#include "webnfs.h"
#include <rpcsvc/nfs4_prot.h>
+#include <nfs/nfssys.h>
+extern int _nfssys(enum nfssys_op, void *);
+
#ifndef NFS_VERSMAX
#define NFS_VERSMAX 4
#endif
@@ -176,6 +179,8 @@ static int sec_opt = 0; /* any security option ? */
static bool_t snego_done;
static void sigusr1(int);
+extern void set_nfsv4_ephemeral_mount_to(void);
+
/*
* list of support services needed
*/
@@ -320,13 +325,13 @@ main(int argc, char *argv[])
*/
read_default();
if (vers_min_default > vers_max_default ||
- vers_min_default < NFS_VERSMIN ||
- vers_max_default > NFS_VERSMAX) {
+ vers_min_default < NFS_VERSMIN ||
+ vers_max_default > NFS_VERSMAX) {
pr_err("%s %s\n%s %s\n",
- gettext("Incorrect configuration of client\'s"),
- NFSADMIN,
- gettext("NFS_CLIENT_VERSMIN or NFS_CLIENT_VERSMAX"),
- gettext("is either out of range or overlaps."));
+ gettext("Incorrect configuration of client\'s"),
+ NFSADMIN,
+ gettext("NFS_CLIENT_VERSMIN or NFS_CLIENT_VERSMAX"),
+ gettext("is either out of range or overlaps."));
}
SET_ERR_RET(&retry_error, ERR_PROTO_NONE, 0);
@@ -482,7 +487,7 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
cb = strchr(host, ']');
if (cb == NULL) {
pr_err(gettext(
- "illegal nfs url syntax\n"));
+ "illegal nfs url syntax\n"));
last_error = RET_ERR;
goto out;
} else {
@@ -491,7 +496,7 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
cb++;
if (*cb == ':')
port = htons((ushort_t)
- atoi(cb+1));
+ atoi(cb+1));
}
} else {
sport = strchr(host, ':');
@@ -534,14 +539,14 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
if (replicated && !(mntflags & MS_RDONLY)) {
pr_err(gettext(
- "replicated mounts must be read-only\n"));
+ "replicated mounts must be read-only\n"));
last_error = RET_ERR;
goto out;
}
if (replicated && (argp->flags & NFSMNT_SOFT)) {
pr_err(gettext(
- "replicated mounts must not be soft\n"));
+ "replicated mounts must not be soft\n"));
last_error = RET_ERR;
goto out;
}
@@ -557,7 +562,7 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
*/
if ((use_pubfh == TRUE) || (url == TRUE)) {
r = get_fh_via_pub(argp, host, path, url, use_pubfh,
- &vers, &nconf, port);
+ &vers, &nconf, port);
if (r != RET_OK) {
/*
@@ -597,7 +602,7 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
loud_on_mnt_err = TRUE;
r = get_fh(argp, host, path, &vers,
- loud_on_mnt_err, &nconf, port);
+ loud_on_mnt_err, &nconf, port);
if (r != RET_OK) {
@@ -622,7 +627,7 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
strcat(newpath, path);
r = get_fh(argp, host, newpath, &vers,
- TRUE, &nconf, port);
+ TRUE, &nconf, port);
if (r == RET_OK)
path = newpath;
@@ -669,7 +674,7 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
host, path);
(void) fprintf(stderr, gettext(
" contact admin to install server change\n"));
- argp->flags |= NFSMNT_LLOCK;
+ argp->flags |= NFSMNT_LLOCK;
}
if (self_check(host))
@@ -684,8 +689,8 @@ mount_nfs(struct mnttab *mntp, int ro, err_ret_t *retry_error)
if (!(argp->flags & NFSMNT_KNCONF)) {
nconf = NULL;
if (r = getaddr_nfs(argp, host, &nconf,
- FALSE, path, port, retry_error,
- TRUE)) {
+ FALSE, path, port, retry_error,
+ TRUE)) {
last_error = r;
goto out;
}
@@ -760,19 +765,25 @@ cont:
if (!qflg)
saveopts = strdup(mntp->mnt_mntopts);
+ /*
+ * And make sure that we have the ephemeral mount_to
+ * set for this zone.
+ */
+ set_nfsv4_ephemeral_mount_to();
+
if (mount(mntp->mnt_special, mntp->mnt_mountp, mntflags, fstype, args,
- sizeof (*args), mntp->mnt_mntopts, MAX_MNTOPT_STR) < 0) {
+ sizeof (*args), mntp->mnt_mntopts, MAX_MNTOPT_STR) < 0) {
if (errno != ENOENT) {
pr_err(gettext("mount: %s: %s\n"),
- mntp->mnt_mountp, strerror(errno));
+ mntp->mnt_mountp, strerror(errno));
} else {
struct stat sb;
if (stat(mntp->mnt_mountp, &sb) < 0 && errno == ENOENT)
pr_err(gettext("mount: %s: %s\n"),
- mntp->mnt_mountp, strerror(ENOENT));
+ mntp->mnt_mountp, strerror(ENOENT));
else
pr_err("%s: %s\n", mntp->mnt_special,
- strerror(ENOENT));
+ strerror(ENOENT));
}
last_error = RET_ERR;
@@ -1027,9 +1038,9 @@ set_args(int *mntflags, struct nfs_args *args, char *fshost, struct mnttab *mnt)
case OPT_SECURE:
if (nfs_getseconfig_byname("dh", &nfs_sec)) {
- pr_err(gettext("can not get \"dh\" from %s\n"),
- NFSSEC_CONF);
- goto badopt;
+ pr_err(gettext("can not get \"dh\" from %s\n"),
+ NFSSEC_CONF);
+ goto badopt;
}
sec_opt++;
break;
@@ -1070,7 +1081,7 @@ set_args(int *mntflags, struct nfs_args *args, char *fshost, struct mnttab *mnt)
if (bad(val))
goto badopt;
args->acdirmin = args->acregmin = args->acdirmax
- = args->acregmax = atoi(val);
+ = args->acregmax = atoi(val);
break;
case OPT_ACREGMIN:
args->flags |= NFSMNT_ACREGMIN;
@@ -1130,12 +1141,15 @@ set_args(int *mntflags, struct nfs_args *args, char *fshost, struct mnttab *mnt)
(void) strncpy(nfs_proto, val, strlen(val)+1);
break;
+
case OPT_NOPRINT:
args->flags |= NFSMNT_NOPRINT;
break;
+
case OPT_LARGEFILES:
largefiles = 1;
break;
+
case OPT_NOLARGEFILES:
pr_err(gettext("NFS can't support \"nolargefiles\"\n"));
free(optstr);
@@ -1143,9 +1157,9 @@ set_args(int *mntflags, struct nfs_args *args, char *fshost, struct mnttab *mnt)
case OPT_SEC:
if (nfs_getseconfig_byname(val, &nfs_sec)) {
- pr_err(gettext("can not get \"%s\" from %s\n"),
- val, NFSSEC_CONF);
- return (RET_ERR);
+ pr_err(gettext("can not get \"%s\" from %s\n"),
+ val, NFSSEC_CONF);
+ return (RET_ERR);
}
sec_opt++;
break;
@@ -1244,18 +1258,18 @@ make_secure(struct nfs_args *args, char *hostname, struct netconfig *nconf,
*/
if (!snego_done && !sec_opt) {
/*
- * Get default security mode.
- * AUTH_UNIX has been the default choice for a long time.
- * The better NFS security service becomes, the better chance
- * we will set stronger security service as the default NFS
- * security mode.
- *
+ * Get default security mode.
+ * AUTH_UNIX has been the default choice for a long time.
+ * The better NFS security service becomes, the better chance
+ * we will set stronger security service as the default NFS
+ * security mode.
*/
- if (nfs_getseconfig_default(&nfs_sec)) {
- pr_err(gettext("error getting default security entry\n"));
- return (-1);
- }
- args->flags |= NFSMNT_SECDEFAULT;
+ if (nfs_getseconfig_default(&nfs_sec)) {
+ pr_err(gettext("error getting default"
+ " security entry\n"));
+ return (-1);
+ }
+ args->flags |= NFSMNT_SECDEFAULT;
}
/*
@@ -1280,10 +1294,9 @@ make_secure(struct nfs_args *args, char *hostname, struct netconfig *nconf,
* If using the public fh or nfsv4, we will not contact the
* remote RPCBINDer, since it is possibly behind a firewall.
*/
- if (use_pubfh == FALSE && vers != NFS_V4) {
+ if (use_pubfh == FALSE && vers != NFS_V4)
syncaddr = get_the_addr(hostname, RPCBPROG, RPCBVERS,
- nconf, 0, NULL, NULL, FALSE, NULL, NULL);
- }
+ nconf, 0, NULL, NULL, FALSE, NULL, NULL);
if (syncaddr != NULL) {
/* for flags in sec_data */
@@ -1298,9 +1311,9 @@ make_secure(struct nfs_args *args, char *hostname, struct netconfig *nconf,
error = netdir_getbyname(nconf, &hs, &retaddrs);
if (error != ND_OK && (nfs_sec.sc_rpcnum == AUTH_DH)) {
- pr_err(gettext("%s: secure: no time service\n"),
- hostname);
- return (-1);
+ pr_err(gettext("%s: secure: no time service\n"),
+ hostname);
+ return (-1);
}
if (error == ND_OK)
@@ -1312,15 +1325,15 @@ make_secure(struct nfs_args *args, char *hostname, struct netconfig *nconf,
* and netname data.
*/
if (vers == NFS_V4 && syncaddr &&
- host2netname(netname, hostname, NULL)) {
- args->syncaddr = malloc(sizeof (struct netbuf));
- args->syncaddr->buf = malloc(syncaddr->len);
- (void) memcpy(args->syncaddr->buf, syncaddr->buf,
- syncaddr->len);
- args->syncaddr->len = syncaddr->len;
- args->syncaddr->maxlen = syncaddr->maxlen;
- args->netname = strdup(netname);
- args->flags |= NFSMNT_SECURE;
+ host2netname(netname, hostname, NULL)) {
+ args->syncaddr = malloc(sizeof (struct netbuf));
+ args->syncaddr->buf = malloc(syncaddr->len);
+ (void) memcpy(args->syncaddr->buf,
+ syncaddr->buf, syncaddr->len);
+ args->syncaddr->len = syncaddr->len;
+ args->syncaddr->maxlen = syncaddr->maxlen;
+ args->netname = strdup(netname);
+ args->flags |= NFSMNT_SECURE;
}
}
}
@@ -1332,7 +1345,7 @@ make_secure(struct nfs_args *args, char *hostname, struct netconfig *nconf,
* extended data structure.
*/
if (!(secdata = nfs_clnt_secdata(&nfs_sec, hostname, args->knconf,
- syncaddr, flags))) {
+ syncaddr, flags))) {
pr_err(gettext("errors constructing security related data\n"));
if (flags & AUTH_F_RPCTIMESYNC) {
free(syncaddr->buf);
@@ -1382,11 +1395,11 @@ get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
return (NULL);
if ((fd = t_open(nconf->nc_device, O_RDWR, tinfo)) == -1)
- goto done;
+ goto done;
/* LINTED pointer alignment */
if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR))
- == NULL)
+ == NULL)
goto done;
/*
@@ -1402,7 +1415,7 @@ get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
/* NFS where vers==4 does not support UDP */
if (vers == NFS_V4 &&
strncasecmp(nconf->nc_proto, NC_UDP,
- strlen(NC_UDP)) == 0) {
+ strlen(NC_UDP)) == 0) {
SET_ERR_RET(error, ERR_PROTO_UNSUPP, 0);
goto done;
}
@@ -1425,7 +1438,7 @@ get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
goto done;
}
memcpy(tbind->addr.buf, retaddrs->n_addrs->buf,
- retaddrs->n_addrs->len);
+ retaddrs->n_addrs->len);
tbind->addr.len = retaddrs->n_addrs->len;
netdir_free((void *)retaddrs, ND_ADDRLIST);
(void) netdir_options(nconf, ND_SET_RESERVEDPORT, fd, NULL);
@@ -1441,10 +1454,10 @@ get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
/* LINTED pointer alignment */
if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
((struct sockaddr_in *)tbind->addr.buf)->sin_port
- = port;
+ = port;
else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
((struct sockaddr_in6 *)tbind->addr.buf)->sin6_port
- = port;
+ = port;
}
@@ -1476,139 +1489,145 @@ get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
(void) clnt_control(cl, CLSET_TIMEOUT, (char *)&tv);
if ((get_pubfh == TRUE) && (vers != NFS_V4)) {
- enum snego_stat sec;
+ enum snego_stat sec;
- if (!snego_done) {
- /*
- * negotiate sec flavor.
- */
- snego.cnt = 0;
- if ((sec = nfs_sec_nego(vers, cl, fspath, &snego)) ==
- SNEGO_SUCCESS) {
- int jj;
-
- /*
- * check if server supports the one
- * specified in the sec= option.
- */
- if (sec_opt) {
- for (jj = 0; jj < snego.cnt; jj++) {
- if (snego.array[jj] == nfs_sec.sc_nfsnum) {
- snego_done = TRUE;
- break;
- }
- }
- }
+ if (!snego_done) {
+ /*
+ * negotiate sec flavor.
+ */
+ snego.cnt = 0;
+ if ((sec = nfs_sec_nego(vers, cl, fspath, &snego)) ==
+ SNEGO_SUCCESS) {
+ int jj;
- /*
- * find a common sec flavor
- */
- if (!snego_done) {
- if (sec_opt) {
- pr_err(gettext(
- "Server does not support the security"
- " flavor specified.\n"));
- }
- for (jj = 0; jj < snego.cnt; jj++) {
- if (!nfs_getseconfig_bynumber(snego.array[jj],
- &nfs_sec)) {
- snego_done = TRUE;
+ /*
+ * check if server supports the one
+ * specified in the sec= option.
+ */
if (sec_opt) {
- pr_err(gettext(
- "Security flavor %d was negotiated and"
- " will be used.\n"),
- nfs_sec.sc_nfsnum);
+ for (jj = 0; jj < snego.cnt; jj++) {
+ if (snego.array[jj] ==
+ nfs_sec.sc_nfsnum) {
+ snego_done = TRUE;
+ break;
+ }
+ }
}
- break;
- }
- }
- }
- if (!snego_done)
- return (NULL);
- /*
- * Now that the flavor has been
- * negotiated, get the fh.
- *
- * First, create an auth handle using the negotiated
- * sec flavor in the next lookup to
- * fetch the filehandle.
- */
- new_ah = nfs_create_ah(cl, hostname, &nfs_sec);
- if (new_ah == NULL)
- goto done;
- cl->cl_auth = new_ah;
- } else if (sec == SNEGO_ARRAY_TOO_SMALL || sec ==
- SNEGO_FAILURE) {
- goto done;
- }
- /*
- * Note that if sec == SNEGO_DEF_VALID
- * default sec flavor is acceptable.
- * Use it to get the filehandle.
- */
- }
+ /*
+ * find a common sec flavor
+ */
+ if (!snego_done) {
+ if (sec_opt) {
+ pr_err(gettext(
+ "Server does not support"
+ " the security flavor"
+ " specified.\n"));
+ }
- if (vers == NFS_VERSION) {
- wnl_diropargs arg;
- wnl_diropres *res;
+ for (jj = 0; jj < snego.cnt; jj++) {
+ if (!nfs_getseconfig_bynumber(
+ snego.array[jj],
+ &nfs_sec)) {
+ snego_done = TRUE;
+#define EMSG80SUX "Security flavor %d was negotiated and will be used.\n"
+ if (sec_opt)
+ pr_err(gettext(
+ EMSG80SUX),
+ nfs_sec.
+ sc_nfsnum);
+ break;
+ }
+ }
+ }
- memset((char *)&arg.dir, 0, sizeof (wnl_fh));
- arg.name = fspath;
- res = wnlproc_lookup_2(&arg, cl);
+ if (!snego_done)
+ return (NULL);
- if (res == NULL || res->status != NFS_OK)
- goto done;
- *fhp = malloc(sizeof (wnl_fh));
+ /*
+ * Now that the flavor has been
+ * negotiated, get the fh.
+ *
+ * First, create an auth handle using the
+ * negotiated sec flavor in the next lookup to
+ * fetch the filehandle.
+ */
+ new_ah = nfs_create_ah(cl, hostname, &nfs_sec);
+ if (new_ah == NULL)
+ goto done;
+ cl->cl_auth = new_ah;
+ } else if (sec == SNEGO_ARRAY_TOO_SMALL || sec ==
+ SNEGO_FAILURE) {
+ goto done;
+ }
- if (*fhp == NULL) {
- pr_err(gettext("no memory\n"));
- goto done;
+ /*
+ * Note that if sec == SNEGO_DEF_VALID
+ * default sec flavor is acceptable.
+ * Use it to get the filehandle.
+ */
}
- memcpy((char *)*fhp,
- (char *)&res->wnl_diropres_u.wnl_diropres.file,
- sizeof (wnl_fh));
- } else {
- WNL_LOOKUP3args arg;
- WNL_LOOKUP3res *res;
- nfs_fh3 *fh3p;
+ if (vers == NFS_VERSION) {
+ wnl_diropargs arg;
+ wnl_diropres *res;
- memset((char *)&arg.what.dir, 0, sizeof (wnl_fh3));
- arg.what.name = fspath;
- res = wnlproc3_lookup_3(&arg, cl);
+ memset((char *)&arg.dir, 0, sizeof (wnl_fh));
+ arg.name = fspath;
+ res = wnlproc_lookup_2(&arg, cl);
- if (res == NULL || res->status != NFS3_OK)
- goto done;
+ if (res == NULL || res->status != NFS_OK)
+ goto done;
+ *fhp = malloc(sizeof (wnl_fh));
- fh3p = (nfs_fh3 *)malloc(sizeof (*fh3p));
+ if (*fhp == NULL) {
+ pr_err(gettext("no memory\n"));
+ goto done;
+ }
- if (fh3p == NULL) {
- pr_err(gettext("no memory\n"));
- CLNT_FREERES(cl, xdr_WNL_LOOKUP3res, (char *)res);
- goto done;
- }
+ memcpy((char *)*fhp,
+ (char *)&res->wnl_diropres_u.wnl_diropres.file,
+ sizeof (wnl_fh));
+ } else {
+ WNL_LOOKUP3args arg;
+ WNL_LOOKUP3res *res;
+ nfs_fh3 *fh3p;
- fh3p->fh3_length =
- res->WNL_LOOKUP3res_u.res_ok.object.data.data_len;
- memcpy(fh3p->fh3_u.data,
- res->WNL_LOOKUP3res_u.res_ok.object.data.data_val,
- fh3p->fh3_length);
+ memset((char *)&arg.what.dir, 0, sizeof (wnl_fh3));
+ arg.what.name = fspath;
+ res = wnlproc3_lookup_3(&arg, cl);
- *fhp = (caddr_t)fh3p;
+ if (res == NULL || res->status != NFS3_OK)
+ goto done;
- CLNT_FREERES(cl, xdr_WNL_LOOKUP3res, (char *)res);
- }
+ fh3p = (nfs_fh3 *)malloc(sizeof (*fh3p));
+
+ if (fh3p == NULL) {
+ pr_err(gettext("no memory\n"));
+ CLNT_FREERES(cl, xdr_WNL_LOOKUP3res,
+ (char *)res);
+ goto done;
+ }
+
+ fh3p->fh3_length =
+ res->WNL_LOOKUP3res_u.res_ok.object.data.data_len;
+ memcpy(fh3p->fh3_u.data,
+ res->WNL_LOOKUP3res_u.res_ok.object.data.data_val,
+ fh3p->fh3_length);
+
+ *fhp = (caddr_t)fh3p;
+ CLNT_FREERES(cl, xdr_WNL_LOOKUP3res, (char *)res);
+ }
} else {
void *res;
struct rpc_err r_err;
if (vers == NFS_VERSION)
- res = wnlproc_null_2(NULL, cl);
+ res = wnlproc_null_2(NULL, cl);
else if (vers == NFS_V3)
- res = wnlproc3_null_3(NULL, cl);
+ res = wnlproc3_null_3(NULL, cl);
else
- res = wnlproc4_null_4(NULL, cl);
+ res = wnlproc4_null_4(NULL, cl);
if (res == NULL) {
clnt_geterr(cl, &r_err);
@@ -1645,14 +1664,14 @@ get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
done:
if (cl) {
- if (ah != NULL) {
- if (new_ah != NULL)
- AUTH_DESTROY(ah);
- AUTH_DESTROY(cl->cl_auth);
- cl->cl_auth = NULL;
- }
- clnt_destroy(cl);
- cl = NULL;
+ if (ah != NULL) {
+ if (new_ah != NULL)
+ AUTH_DESTROY(ah);
+ AUTH_DESTROY(cl->cl_auth);
+ cl->cl_auth = NULL;
+ }
+ clnt_destroy(cl);
+ cl = NULL;
}
if (tbind) {
t_free((char *)tbind, T_BIND);
@@ -1663,6 +1682,34 @@ done:
return (nb);
}
+static int
+check_nconf(struct netconfig *nconf, int nthtry, int *valid_proto)
+{
+ int try_test = 0;
+ int valid_family;
+ char *proto = NULL;
+
+
+ if (nthtry == FIRST_TRY) {
+ try_test = ((nconf->nc_semantics == NC_TPI_COTS_ORD) ||
+ (nconf->nc_semantics == NC_TPI_COTS));
+ proto = NC_TCP;
+ } else if (nthtry == SECOND_TRY) {
+ try_test = (nconf->nc_semantics == NC_TPI_CLTS);
+ proto = NC_UDP;
+ }
+
+ if (proto &&
+ (strcmp(nconf->nc_protofmly, NC_INET) == 0 ||
+ strcmp(nconf->nc_protofmly, NC_INET6) == 0) &&
+ (strcmp(nconf->nc_proto, proto) == 0))
+ *valid_proto = TRUE;
+ else
+ *valid_proto = FALSE;
+
+ return (try_test);
+}
+
/*
* Get a network address on "hostname" for program "prog"
* with version "vers". If the port number is specified (non zero)
@@ -1704,7 +1751,7 @@ get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp,
if (nconfp && *nconfp)
return (get_the_addr(hostname, prog, vers, *nconfp, port,
- tinfo, fhp, get_pubfh, fspath, error));
+ tinfo, fhp, get_pubfh, fspath, error));
/*
* No nconf passed in.
*
@@ -1739,17 +1786,15 @@ get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp,
SET_ERR_RET(error, ERR_PROTO_UNSUPP, 0);
if ((port != 0) &&
- ((strcmp(nconf->nc_protofmly, NC_INET) == 0 ||
- strcmp(nconf->nc_protofmly, NC_INET6) == 0) &&
- (strcmp(nconf->nc_proto, NC_TCP) != 0 &&
- strcmp(nconf->nc_proto, NC_UDP) != 0)))
-
+ ((strcmp(nconf->nc_protofmly, NC_INET) == 0 ||
+ strcmp(nconf->nc_protofmly, NC_INET6) == 0) &&
+ (strcmp(nconf->nc_proto, NC_TCP) != 0 &&
+ strcmp(nconf->nc_proto, NC_UDP) != 0))) {
continue;
-
- else {
+ } else {
nb = get_the_addr(hostname, prog,
- vers, nconf, port, tinfo,
- fhp, get_pubfh, fspath, error);
+ vers, nconf, port, tinfo,
+ fhp, get_pubfh, fspath, error);
if (nb != NULL)
break;
@@ -1758,12 +1803,12 @@ get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp,
if (error) {
if (error->error_type == ERR_NOHOST)
SET_ERR_RET(&errsave_nohost,
- error->error_type,
- error->error_value);
+ error->error_type,
+ error->error_value);
if (error->error_type == ERR_RPCERROR)
SET_ERR_RET(&errsave_rpcerr,
- error->error_type,
- error->error_value);
+ error->error_type,
+ error->error_value);
}
/*
* continue with same protocol
@@ -1777,51 +1822,24 @@ get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp,
goto done;
if ((nb = get_the_addr(hostname, prog, vers, nconf, port,
- tinfo, fhp, get_pubfh, fspath, error)) == NULL)
+ tinfo, fhp, get_pubfh, fspath, error)) == NULL)
goto done;
-
-
} else {
retry:
SET_ERR_RET(error, ERR_NETPATH, 0);
while (nconf = getnetpath(nc)) {
SET_ERR_RET(error, ERR_PROTO_NONE, 0);
- if (nconf->nc_flag & NC_VISIBLE) {
- if (nthtry == FIRST_TRY) {
- if ((nconf->nc_semantics ==
- NC_TPI_COTS_ORD) ||
- (nconf->nc_semantics ==
- NC_TPI_COTS)) {
- if (port == 0)
- break;
+ if (nconf->nc_flag & NC_VISIBLE) {
+ int valid_proto;
- if ((strcmp(nconf->nc_protofmly,
- NC_INET) == 0 ||
- strcmp(nconf->
- nc_protofmly,
- NC_INET6) == 0) &&
- (strcmp(nconf->nc_proto,
- NC_TCP) == 0))
+ if (check_nconf(nconf,
+ nthtry, &valid_proto)) {
+ if (port == 0)
+ break;
- break;
- }
- }
- if (nthtry == SECOND_TRY) {
- if (nconf->nc_semantics ==
- NC_TPI_CLTS) {
- if (port == 0)
- break;
- if ((strcmp(nconf->nc_protofmly,
- NC_INET) == 0 ||
- strcmp(nconf->
- nc_protofmly, NC_INET6)
- == 0) &&
- (strcmp(
- nconf->nc_proto,
- NC_UDP) == 0))
- break;
- }
+ if (valid_proto == TRUE)
+ break;
}
}
} /* while */
@@ -1835,18 +1853,18 @@ retry:
goto done;
} else {
if ((nb = get_the_addr(hostname, prog, vers, nconf,
- port, tinfo, fhp, get_pubfh, fspath, error))
- == NULL) {
+ port, tinfo, fhp, get_pubfh, fspath, error))
+ == NULL) {
/* nb is NULL - deal with errors */
if (error) {
if (error->error_type == ERR_NOHOST)
SET_ERR_RET(&errsave_nohost,
- error->error_type,
- error->error_value);
+ error->error_type,
+ error->error_value);
if (error->error_type == ERR_RPCERROR)
SET_ERR_RET(&errsave_rpcerr,
- error->error_type,
- error->error_value);
+ error->error_type,
+ error->error_value);
}
/*
* Continue the same search path in the
@@ -1880,11 +1898,11 @@ done:
*/
if (errsave_nohost.error_type != ERR_PROTO_NONE)
SET_ERR_RET(error, errsave_nohost.error_type,
- errsave_nohost.error_value);
+ errsave_nohost.error_value);
if (errsave_rpcerr.error_type != ERR_PROTO_NONE)
SET_ERR_RET(error, errsave_rpcerr.error_type,
- errsave_rpcerr.error_value);
+ errsave_rpcerr.error_value);
}
return (nb);
@@ -1913,9 +1931,8 @@ get_fh_via_pub(struct nfs_args *args, char *fshost, char *fspath, bool_t url,
if (url == FALSE) {
path = malloc(strlen(fspath) + 2);
if (path == NULL) {
- if (loud == TRUE) {
+ if (loud == TRUE)
pr_err(gettext("no memory\n"));
- }
return (RET_ERR);
}
@@ -1932,7 +1949,7 @@ get_fh_via_pub(struct nfs_args *args, char *fshost, char *fspath, bool_t url,
* getaddr_nfs will also fill in the fh for us.
*/
r = getaddr_nfs(args, fshost, nconfp,
- TRUE, path, port, NULL, FALSE);
+ TRUE, path, port, NULL, FALSE);
if (r == RET_OK) {
/*
@@ -1959,13 +1976,12 @@ get_fh_via_pub(struct nfs_args *args, char *fshost, char *fspath, bool_t url,
}
}
- if (fspath != path) {
+ if (fspath != path)
free(path);
- }
if (loud == TRUE) {
pr_err(gettext("Could not use public filehandle in request to"
- " server %s\n"), fshost);
+ " server %s\n"), fshost);
}
return (r);
@@ -2041,9 +2057,8 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
/* Let's hope for the best */
nfsvers_to_use = NFS_V4;
- retval =
- getaddr_nfs(args, fshost, nconfp, FALSE,
- fspath, port, &error, vers_min == NFS_V4);
+ retval = getaddr_nfs(args, fshost, nconfp, FALSE,
+ fspath, port, &error, vers_min == NFS_V4);
if (retval == RET_OK) {
*versp = nfsvers_to_use = NFS_V4;
@@ -2060,9 +2075,8 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
vers_to_try--;
/* If no more versions to try, let the user know. */
- if (vers_to_try < vers_min) {
+ if (vers_to_try < vers_min)
return (retval);
- }
/*
* If we are here, there are more versions to try but
@@ -2076,7 +2090,7 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
}
while ((cl = clnt_create_vers(fshost, MOUNTPROG, &outvers,
- vers_min, vers_to_try, "datagram_v")) == NULL) {
+ vers_min, vers_to_try, "datagram_v")) == NULL) {
if (rpc_createerr.cf_stat == RPC_UNKNOWNHOST) {
pr_err(gettext("%s: %s\n"), fshost,
clnt_spcreateerror(""));
@@ -2087,7 +2101,7 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
* We don't want to downgrade version on lost packets
*/
if ((rpc_createerr.cf_stat == RPC_TIMEDOUT) ||
- (rpc_createerr.cf_stat == RPC_PMAPFAILURE)) {
+ (rpc_createerr.cf_stat == RPC_PMAPFAILURE)) {
pr_err(gettext("%s: %s\n"), fshost,
clnt_spcreateerror(""));
return (RET_RETRY);
@@ -2148,7 +2162,7 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
case MOUNTVERS_POSIX:
*versp = nfsvers_to_use = NFS_VERSION;
rpc_stat = clnt_call(cl, MOUNTPROC_MNT, xdr_dirpath,
- (caddr_t)&fspath, xdr_fhstatus, (caddr_t)&fhs, timeout);
+ (caddr_t)&fspath, xdr_fhstatus, (caddr_t)&fhs, timeout);
if (rpc_stat != RPC_SUCCESS) {
pr_err(gettext("%s:%s: server not responding %s\n"),
fshost, fspath, clnt_sperror(cl, ""));
@@ -2158,13 +2172,14 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
if ((errno = fhs.fhs_status) != MNT_OK) {
if (loud_on_mnt_err) {
- if (errno == EACCES) {
- pr_err(gettext("%s:%s: access denied\n"),
- fshost, fspath);
- } else {
- pr_err(gettext("%s:%s: %s\n"), fshost, fspath,
- strerror(errno));
- }
+ if (errno == EACCES) {
+ pr_err(gettext(
+ "%s:%s: access denied\n"),
+ fshost, fspath);
+ } else {
+ pr_err(gettext("%s:%s: %s\n"), fshost,
+ fspath, strerror(errno));
+ }
}
clnt_destroy(cl);
return (RET_MNTERR);
@@ -2175,11 +2190,11 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
return (RET_ERR);
}
memcpy((caddr_t)args->fh, (caddr_t)&fhs.fhstatus_u.fhs_fhandle,
- sizeof (fhs.fhstatus_u.fhs_fhandle));
+ sizeof (fhs.fhstatus_u.fhs_fhandle));
if (!errno && posix) {
rpc_stat = clnt_call(cl, MOUNTPROC_PATHCONF,
- xdr_dirpath, (caddr_t)&fspath, xdr_ppathcnf,
- (caddr_t)&p, timeout);
+ xdr_dirpath, (caddr_t)&fspath, xdr_ppathcnf,
+ (caddr_t)&p, timeout);
if (rpc_stat != RPC_SUCCESS) {
pr_err(gettext(
"%s:%s: server not responding %s\n"),
@@ -2205,15 +2220,15 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
return (RET_ERR);
}
memcpy((caddr_t)args->pathconf, (caddr_t)&p,
- sizeof (p));
+ sizeof (p));
}
break;
case MOUNTVERS3:
*versp = nfsvers_to_use = NFS_V3;
rpc_stat = clnt_call(cl, MOUNTPROC_MNT, xdr_dirpath,
- (caddr_t)&fspath,
- xdr_mountres3, (caddr_t)&mountres3, timeout);
+ (caddr_t)&fspath, xdr_mountres3, (caddr_t)&mountres3,
+ timeout);
if (rpc_stat != RPC_SUCCESS) {
pr_err(gettext("%s:%s: server not responding %s\n"),
fshost, fspath, clnt_sperror(cl, ""));
@@ -2226,25 +2241,26 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
* codes map into E* errors.
*/
if ((errno = mountres3.fhs_status) != MNT_OK) {
- if (loud_on_mnt_err) {
- switch (errno) {
- case MNT3ERR_NAMETOOLONG:
- msg = "path name is too long";
- break;
- case MNT3ERR_NOTSUPP:
- msg = "operation not supported";
- break;
- case MNT3ERR_SERVERFAULT:
- msg = "server fault";
- break;
- default:
- msg = strerror(errno);
- break;
+ if (loud_on_mnt_err) {
+ switch (errno) {
+ case MNT3ERR_NAMETOOLONG:
+ msg = "path name is too long";
+ break;
+ case MNT3ERR_NOTSUPP:
+ msg = "operation not supported";
+ break;
+ case MNT3ERR_SERVERFAULT:
+ msg = "server fault";
+ break;
+ default:
+ msg = strerror(errno);
+ break;
+ }
+ pr_err(gettext("%s:%s: %s\n"), fshost,
+ fspath, msg);
}
- pr_err(gettext("%s:%s: %s\n"), fshost, fspath, msg);
- }
- clnt_destroy(cl);
- return (RET_MNTERR);
+ clnt_destroy(cl);
+ return (RET_MNTERR);
}
fh3p = (nfs_fh3 *)malloc(sizeof (*fh3p));
@@ -2253,10 +2269,10 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
return (RET_ERR);
}
fh3p->fh3_length =
- mountres3.mountres3_u.mountinfo.fhandle.fhandle3_len;
+ mountres3.mountres3_u.mountinfo.fhandle.fhandle3_len;
(void) memcpy(fh3p->fh3_u.data,
- mountres3.mountres3_u.mountinfo.fhandle.fhandle3_val,
- fh3p->fh3_length);
+ mountres3.mountres3_u.mountinfo.fhandle.fhandle3_val,
+ fh3p->fh3_length);
args->fh = (caddr_t)fh3p;
fstype = MNTTYPE_NFS3;
@@ -2274,30 +2290,33 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
*
*/
auths =
- mountres3.mountres3_u.mountinfo.auth_flavors.auth_flavors_val;
+ mountres3.mountres3_u.mountinfo.auth_flavors
+ .auth_flavors_val;
count =
- mountres3.mountres3_u.mountinfo.auth_flavors.auth_flavors_len;
+ mountres3.mountres3_u.mountinfo.auth_flavors
+ .auth_flavors_len;
if (sec_opt) {
for (i = 0; i < count; i++) {
if (auths[i] == nfs_sec.sc_nfsnum)
- break;
+ break;
}
- if (i >= count) {
+ if (i >= count)
goto autherr;
- }
} else {
- if (count > 0) {
- for (i = 0; i < count; i++) {
- if (!nfs_getseconfig_bynumber(auths[i], &nfs_sec)) {
- sec_opt++;
+ if (count < 0)
break;
- }
- }
- if (i >= count) {
- goto autherr;
+
+ for (i = 0; i < count; i++) {
+ if (!nfs_getseconfig_bynumber(auths[i],
+ &nfs_sec)) {
+ sec_opt++;
+ break;
+ }
}
- }
+
+ if (i >= count)
+ goto autherr;
}
break;
default:
@@ -2312,8 +2331,8 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp,
autherr:
pr_err(gettext(
- "security mode does not match the server exporting %s:%s\n"),
- fshost, fspath);
+ "security mode does not match the server exporting %s:%s\n"),
+ fshost, fspath);
clnt_destroy(cl);
return (RET_ERR);
}
@@ -2388,19 +2407,19 @@ getaddr_nfs(struct nfs_args *args, char *fshost, struct netconfig **nconfp,
/* no error print at this time */
break;
pr_err(gettext("%s NFS service not"
- " available %s\n"), fshost,
+ " available %s\n"), fshost,
clnt_sperrno(addr_error.error_value));
printed = 1;
break;
case ERR_NETPATH:
pr_err(gettext("%s: Error in NETPATH.\n"),
- fshost);
+ fshost);
printed = 1;
break;
case ERR_PROTO_INVALID:
pr_err(gettext("%s: NFS service does not"
- " recognize protocol: %s.\n"), fshost,
- nfs_proto);
+ " recognize protocol: %s.\n"), fshost,
+ nfs_proto);
printed = 1;
break;
case ERR_PROTO_UNSUPP:
@@ -2423,8 +2442,8 @@ getaddr_nfs(struct nfs_args *args, char *fshost, struct netconfig **nconfp,
* and retry below.
*/
pr_err(gettext("%s: NFS service does"
- " not support protocol: %s.\n"),
- fshost, nfs_proto);
+ " not support protocol: %s.\n"),
+ fshost, nfs_proto);
}
break;
case ERR_NOHOST:
@@ -2434,20 +2453,20 @@ getaddr_nfs(struct nfs_args *args, char *fshost, struct netconfig **nconfp,
default:
/* case ERR_PROTO_NONE falls through */
pr_err(gettext("%s: NFS service not responding"
- "\n"), fshost);
+ "\n"), fshost);
printed = 1;
break;
}
}
SET_ERR_RET(error,
- addr_error.error_type, addr_error.error_value);
+ addr_error.error_type, addr_error.error_value);
if (addr_error.error_type == ERR_PROTO_NONE)
return (RET_RETRY);
else if (addr_error.error_type == ERR_RPCERROR &&
- ! IS_UNRECOVERABLE_RPC(addr_error.error_value)) {
+ !IS_UNRECOVERABLE_RPC(addr_error.error_value)) {
return (RET_RETRY);
} else if (nfsvers == 0 && addr_error.error_type ==
- ERR_PROTO_UNSUPP && nfsvers_to_use != NFS_VERSMIN) {
+ ERR_PROTO_UNSUPP && nfsvers_to_use != NFS_VERSMIN) {
/*
* If no version is specified, and the error is due
* to an unsupported transport, then decrement the
@@ -2520,10 +2539,10 @@ retry(struct mnttab *mntp, int ro)
break;
if (count > 0) {
- (void) sleep(delay);
- delay *= 2;
- if (delay > 120)
- delay = 120;
+ (void) sleep(delay);
+ delay *= 2;
+ if (delay > 120)
+ delay = 120;
}
}
diff --git a/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c b/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
index 5680d59174..e97dc9cbff 100644
--- a/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
+++ b/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
@@ -116,6 +116,13 @@ static int count; /* number of iterations the stat is printed */
#define MAX_COLUMNS 80
#define MAX_PATHS 50 /* max paths that can be taken by -m */
+/*
+ * MI4_MIRRORMOUNT is canonically defined in nfs4_clnt.h, but we cannot
+ * include that file here.
+ */
+#define MI4_MIRRORMOUNT 0x4000
+#define NFS_V4 4
+
static int req_width(kstat_t *, int);
static int stat_width(kstat_t *, int);
static char *path [MAX_PATHS] = {NULL}; /* array to store the multiple paths */
@@ -157,7 +164,7 @@ main(int argc, char *argv[])
int vflag = 0; /* version specified, 0 specifies all */
int zflag = 0; /* zero stats after printing */
char *split_line = "*******************************************"
- "*************************************";
+ "*************************************";
interval = 0;
count = 0;
@@ -226,7 +233,8 @@ main(int argc, char *argv[])
} else if (mflag) {
if (cflag || rflag || sflag || zflag || nflag || aflag || vflag)
- fail(0, "The -m flag may not be used with any other flags");
+ fail(0,
+ "The -m flag may not be used with any other flags");
for (j = 0; (argc - optind > 0) && (j < (MAX_PATHS - 1)); j++) {
path[j] = argv[optind];
@@ -238,8 +246,7 @@ main(int argc, char *argv[])
path[j] = NULL;
if (argc - optind > 0)
fprintf(stderr, "Only the first 50 paths "
- "will be searched for\n");
-
+ "will be searched for\n");
}
setup();
@@ -270,8 +277,8 @@ main(int argc, char *argv[])
(rpc_clts_client_kstat == NULL ||
nfs_client_kstat == NULL)) {
fprintf(stderr,
- "nfsstat: kernel is not configured with"
- " the client nfs and rpc code.\n");
+ "nfsstat: kernel is not configured with"
+ " the client nfs and rpc code.\n");
}
if (cflag || (!sflag && !cflag)) {
if (rflag || (!rflag && !nflag && !aflag))
@@ -537,7 +544,7 @@ req_width(kstat_t *req, int field_width)
else
per = 0;
(void) sprintf(fixlen, "%" PRIu64 " %d%%",
- knp[i].value.ui64, per);
+ knp[i].value.ui64, per);
len = strlen(fixlen) + 1;
if (field_width < len)
field_width = len;
@@ -577,15 +584,12 @@ cr_print(int zflag)
return;
stat_print("\nClient rpc:\nConnection oriented:",
- rpc_cots_client_kstat,
- &old_rpc_cots_client_kstat.kst, field_width,
- zflag);
+ rpc_cots_client_kstat,
+ &old_rpc_cots_client_kstat.kst, field_width, zflag);
stat_print("Connectionless:", rpc_clts_client_kstat,
- &old_rpc_clts_client_kstat.kst, field_width,
- zflag);
+ &old_rpc_clts_client_kstat.kst, field_width, zflag);
stat_print("RDMA based:", rpc_rdma_client_kstat,
- &old_rpc_rdma_client_kstat.kst, field_width,
- zflag);
+ &old_rpc_rdma_client_kstat.kst, field_width, zflag);
}
static void
@@ -598,14 +602,11 @@ sr_print(int zflag)
return;
stat_print("\nServer rpc:\nConnection oriented:", rpc_cots_server_kstat,
- &old_rpc_cots_server_kstat.kst, field_width,
- zflag);
+ &old_rpc_cots_server_kstat.kst, field_width, zflag);
stat_print("Connectionless:", rpc_clts_server_kstat,
- &old_rpc_clts_server_kstat.kst, field_width,
- zflag);
+ &old_rpc_clts_server_kstat.kst, field_width, zflag);
stat_print("RDMA based:", rpc_rdma_server_kstat,
- &old_rpc_rdma_server_kstat.kst, field_width,
- zflag);
+ &old_rpc_rdma_server_kstat.kst, field_width, zflag);
}
static void
@@ -620,37 +621,35 @@ cn_print(int zflag, int vflag)
if (vflag == 0) {
kstat_sum(nfs_client_kstat, nfs4_client_kstat, ksum_kstat);
stat_print("\nClient nfs:", ksum_kstat, &old_ksum_kstat.kst,
- field_width, zflag);
+ field_width, zflag);
}
if (vflag == 2 || vflag == 3) {
stat_print("\nClient nfs:", nfs_client_kstat,
- &old_nfs_client_kstat.kst,
- field_width, zflag);
+ &old_nfs_client_kstat.kst, field_width, zflag);
}
if (vflag == 4) {
stat_print("\nClient nfs:", nfs4_client_kstat,
- &old_nfs4_client_kstat.kst,
- field_width, zflag);
+ &old_nfs4_client_kstat.kst, field_width, zflag);
}
if (vflag == 2 || vflag == 0) {
field_width = getstats_rfsreq(2);
req_print(rfsreqcnt_v2_kstat, &old_rfsreqcnt_v2_kstat.kst,
- 2, field_width, zflag);
+ 2, field_width, zflag);
}
if (vflag == 3 || vflag == 0) {
field_width = getstats_rfsreq(3);
req_print(rfsreqcnt_v3_kstat, &old_rfsreqcnt_v3_kstat.kst, 3,
- field_width, zflag);
+ field_width, zflag);
}
if (vflag == 4 || vflag == 0) {
field_width = getstats_rfsreq(4);
req_print_v4(rfsreqcnt_v4_kstat, &old_rfsreqcnt_v4_kstat.kst,
- field_width, zflag);
+ field_width, zflag);
}
}
@@ -665,39 +664,35 @@ sn_print(int zflag, int vflag)
if (vflag == 2 || vflag == 0) {
stat_print("\nServer NFSv2:", nfs_server_v2_kstat,
- &old_nfs_server_v2_kstat.kst,
- field_width, zflag);
+ &old_nfs_server_v2_kstat.kst, field_width, zflag);
}
if (vflag == 3 || vflag == 0) {
stat_print("\nServer NFSv3:", nfs_server_v3_kstat,
- &old_nfs_server_v3_kstat.kst,
- field_width, zflag);
+ &old_nfs_server_v3_kstat.kst, field_width, zflag);
}
if (vflag == 4 || vflag == 0) {
stat_print("\nServer NFSv4:", nfs_server_v4_kstat,
- &old_nfs_server_v4_kstat.kst,
- field_width, zflag);
+ &old_nfs_server_v4_kstat.kst, field_width, zflag);
}
if (vflag == 2 || vflag == 0) {
field_width = getstats_rfsproc(2);
req_print(rfsproccnt_v2_kstat, &old_rfsproccnt_v2_kstat.kst,
- 2, field_width, zflag);
+ 2, field_width, zflag);
}
if (vflag == 3 || vflag == 0) {
field_width = getstats_rfsproc(3);
req_print(rfsproccnt_v3_kstat, &old_rfsproccnt_v3_kstat.kst,
- 3, field_width, zflag);
-
+ 3, field_width, zflag);
}
if (vflag == 4 || vflag == 0) {
field_width = getstats_rfsproc(4);
req_print_v4(rfsproccnt_v4_kstat, &old_rfsproccnt_v4_kstat.kst,
- field_width, zflag);
+ field_width, zflag);
}
}
@@ -714,12 +709,12 @@ ca_print(int zflag, int vflag)
if (vflag == 2 || vflag == 0) {
req_print(aclreqcnt_v2_kstat, &old_aclreqcnt_v2_kstat.kst, 2,
- field_width, zflag);
+ field_width, zflag);
}
if (vflag == 3 || vflag == 0) {
req_print(aclreqcnt_v3_kstat, &old_aclreqcnt_v3_kstat.kst,
- 3, field_width, zflag);
+ 3, field_width, zflag);
}
}
@@ -736,12 +731,12 @@ sa_print(int zflag, int vflag)
if (vflag == 2 || vflag == 0) {
req_print(aclproccnt_v2_kstat, &old_aclproccnt_v2_kstat.kst,
- 2, field_width, zflag);
+ 2, field_width, zflag);
}
if (vflag == 3 || vflag == 0) {
req_print(aclproccnt_v3_kstat, &old_aclproccnt_v3_kstat.kst,
- 3, field_width, zflag);
+ 3, field_width, zflag);
}
}
@@ -749,7 +744,7 @@ sa_print(int zflag, int vflag)
static void
req_print(kstat_t *req, kstat_t *req_old, int ver, int field_width,
- int zflag)
+ int zflag)
{
int i, j, nreq, per, ncolumns;
uint64_t tot, old_tot;
@@ -803,9 +798,9 @@ req_print(kstat_t *req, kstat_t *req_old, int ver, int field_width,
else
per = 0;
(void) sprintf(fixlen, "%" PRIu64 " %d%% ",
- ((interval && knp_old != NULL) ?
- (knp[j].value.ui64 - knp_old[j].value.ui64)
- : knp[j].value.ui64), per);
+ ((interval && knp_old != NULL) ?
+ (knp[j].value.ui64 - knp_old[j].value.ui64)
+ : knp[j].value.ui64), per);
printf("%-*s", field_width, fixlen);
}
if (zflag) {
@@ -889,9 +884,9 @@ req_print_v4(kstat_t *req, kstat_t *req_old, int field_width, int zflag)
else
per = 0;
(void) sprintf(fixlen, "%" PRIu64 " %d%% ",
- ((interval && kptr_old != NULL) ?
- (knp[j].value.ui64 - kptr_old[j].value.ui64)
- : knp[j].value.ui64), per);
+ ((interval && kptr_old != NULL) ?
+ (knp[j].value.ui64 - kptr_old[j].value.ui64)
+ : knp[j].value.ui64), per);
printf("%-*s", field_width, fixlen);
}
printf("\n");
@@ -912,9 +907,9 @@ req_print_v4(kstat_t *req, kstat_t *req_old, int field_width, int zflag)
else
per = 0;
(void) sprintf(fixlen, "%" PRIu64 " %d%% ",
- ((interval && kptr_old != NULL) ?
- (knp[j].value.ui64 - kptr_old[j].value.ui64)
- : knp[j].value.ui64), per);
+ ((interval && kptr_old != NULL) ?
+ (knp[j].value.ui64 - kptr_old[j].value.ui64)
+ : knp[j].value.ui64), per);
printf("%-*s", field_width, fixlen);
}
printf("\n");
@@ -931,7 +926,7 @@ req_print_v4(kstat_t *req, kstat_t *req_old, int field_width, int zflag)
static void
stat_print(const char *title_string, kstat_t *req, kstat_t *req_old,
- int field_width, int zflag)
+ int field_width, int zflag)
{
int i, j, nreq, ncolumns;
char fixlen[128];
@@ -961,9 +956,9 @@ stat_print(const char *title_string, kstat_t *req, kstat_t *req_old,
/* prints out the stat numbers */
for (j = i; j < MIN(i + ncolumns, nreq); j++) {
(void) sprintf(fixlen, "%" PRIu64 " ",
- (interval && knp_old != NULL) ?
- (knp[j].value.ui64 - knp_old[j].value.ui64)
- : knp[j].value.ui64);
+ (interval && knp_old != NULL) ?
+ (knp[j].value.ui64 - knp_old[j].value.ui64)
+ : knp[j].value.ui64);
printf("%-*s", field_width, fixlen);
}
printf("\n");
@@ -1050,7 +1045,7 @@ mi_print(void)
* Check to see here if user gave a path(s) to
* only show the mount point they wanted
* Iterate through the list of paths the user gave and see
- * if any of them match the our current nfs mount
+ * if any of them match our current nfs mount
*/
if (path[0] != NULL) {
found = 0;
@@ -1081,7 +1076,7 @@ mi_print(void)
* So save the mount point now
*/
if ((mrp->ig_path = malloc(
- strlen(m.mnt_mountp) + 1)) == 0) {
+ strlen(m.mnt_mountp) + 1)) == 0) {
fprintf(stderr, "nfsstat: not enough memory\n");
exit(1);
}
@@ -1122,7 +1117,7 @@ mi_print(void)
if (strcmp(mrp->ig_path, m.mnt_special) == 0) {
mrp->ig_path = 0;
(void) strcpy(mrp->my_dir,
- m.mnt_mountp);
+ m.mnt_mountp);
}
}
}
@@ -1221,13 +1216,18 @@ mi_print(void)
if (mik.mik_flags & MI_ACL)
printf(",acl");
+ if (mik.mik_vers >= NFS_V4) {
+ if (mik.mik_flags & MI4_MIRRORMOUNT)
+ printf(",mirrormount");
+ }
+
printf(",rsize=%d,wsize=%d,retrans=%d,timeo=%d",
- mik.mik_curread, mik.mik_curwrite, mik.mik_retrans,
- mik.mik_timeo);
+ mik.mik_curread, mik.mik_curwrite, mik.mik_retrans,
+ mik.mik_timeo);
printf("\n");
printf(" Attr cache: acregmin=%d,acregmax=%d"
- ",acdirmin=%d,acdirmax=%d\n", mik.mik_acregmin,
- mik.mik_acregmax, mik.mik_acdirmin, mik.mik_acdirmax);
+ ",acdirmin=%d,acdirmax=%d\n", mik.mik_acregmin,
+ mik.mik_acregmax, mik.mik_acdirmin, mik.mik_acdirmax);
if (transport_flag) {
printf(" Transport: proto=rdma, plugin=%s\n",
@@ -1243,13 +1243,13 @@ mi_print(void)
j = (i == NFS_CALLTYPES ? i - 1 : i);
if (mik.mik_timers[j].srtt ||
mik.mik_timers[j].rtxcur) {
- printf(
- " %s: srtt=%d (%dms), dev=%d (%dms), cur=%u (%ums)\n",
- timer_name[i],
- srtt_to_ms(mik.mik_timers[i].srtt),
- dev_to_ms(mik.mik_timers[i].deviate),
- mik.mik_timers[i].rtxcur,
- mik.mik_timers[i].rtxcur * 20);
+ printf(" %s: srtt=%d (%dms), "
+ "dev=%d (%dms), cur=%u (%ums)\n",
+ timer_name[i],
+ srtt_to_ms(mik.mik_timers[i].srtt),
+ dev_to_ms(mik.mik_timers[i].deviate),
+ mik.mik_timers[i].rtxcur,
+ mik.mik_timers[i].rtxcur * 20);
}
}
@@ -1297,7 +1297,6 @@ ignore(char *opts)
void
usage(void)
{
-
fprintf(stderr, "Usage: nfsstat [-cnrsza [-v version] "
"[interval [count]]\n");
fprintf(stderr, "Usage: nfsstat -m [pathname..]\n");
diff --git a/usr/src/cmd/rexd/Makefile b/usr/src/cmd/rexd/Makefile
index a60d269936..5817b4add5 100644
--- a/usr/src/cmd/rexd/Makefile
+++ b/usr/src/cmd/rexd/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -40,7 +40,8 @@ ROOTMANIFESTDIR= $(ROOTSVCNETWORKRPC)
SRCS= $(PROG:%=%.c)
#OBJS= errprintf.o mount_nfs.o rex_xdr.o unix_login.o mntent.o
-OBJS= errprintf.o mount_nfs.o rex.o unix_login.o mntent.o
+TYPEOBJS= nfs_subr.o
+OBJS= errprintf.o mount_nfs.o rex.o unix_login.o mntent.o $(TYPEOBJS)
REXDOBJS= rpc.rexd.o errprintf.o mount_nfs.o rex.o unix_login.o mntent.o
ONOBJS= on.o sharetab.o where.o rex.o mntent.o
#WHEREOBJS= sharetab.o where.o where_main.o mntent.o
@@ -58,6 +59,8 @@ CPPFLAGS = -I. $(CPPFLAGS.master)
LDLIBS += -lsocket -lnsl
rpc.rexd := LDLIBS += -lrpcsvc -lbsm -lpam
+TYPESRCS= ../nfs/lib/nfs_subr.c
+
# install rule
# don't re-install directories created by Targetdirs
#$(ROOTREXD)/%: %
@@ -113,3 +116,6 @@ rpc.rexd.o: rex.h
unix_login.o: rex.h
rex.o: rex.h
+
+nfs_subr.o: ../fs.d/nfs/lib/nfs_subr.c
+ $(COMPILE.c) ../fs.d/nfs/lib/nfs_subr.c
diff --git a/usr/src/cmd/rexd/mount_nfs.c b/usr/src/cmd/rexd/mount_nfs.c
index 3a276b7afc..8f94b04d72 100644
--- a/usr/src/cmd/rexd/mount_nfs.c
+++ b/usr/src/cmd/rexd/mount_nfs.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -18,10 +17,12 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- *
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -32,32 +33,34 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#define NFSCLIENT
-#include <sys/types.h>
-#include <memory.h>
-#include <netconfig.h>
-#include <netdb.h>
-#include <netdir.h>
-#include <netinet/in.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <syslog.h>
-
-#include <rpc/rpc.h>
-#include <rpc/clnt_soc.h>
-#include <rpc/pmap_prot.h>
-#include <nfs/nfs.h>
-#include <nfs/mount.h>
-#include <rpcsvc/mount.h>
-#include <errno.h>
-#include <sys/mntent.h>
-#include <sys/mnttab.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
+#include <sys/types.h>
+#include <memory.h>
+#include <netconfig.h>
+#include <netdb.h>
+#include <netdir.h>
+#include <netinet/in.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#include <rpc/rpc.h>
+#include <rpc/clnt_soc.h>
+#include <rpc/pmap_prot.h>
+#include <nfs/nfs.h>
+#include <nfs/mount.h>
+#include <rpcsvc/mount.h>
+#include <errno.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include <sys/mount.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <deflt.h>
static struct knetconfig *get_knconf(struct netconfig *nconf);
static int bindudp_resvport(CLIENT *client);
@@ -68,6 +71,8 @@ static void netbuf_free(struct netbuf *nb);
static struct netbuf *get_addr(char *hostname, int prog, int vers,
struct netconfig **nconfp);
+extern void set_nfsv4_ephemeral_mount_to(void);
+
#define TIME_MAX 16
extern int Debug;
@@ -91,10 +96,7 @@ void free_knconf(struct knetconfig *);
* The "error" string returns the error message.
*/
int
-mount_nfs(fsname, dir, error)
- char *fsname;
- char *dir;
- char *error;
+mount_nfs(char *fsname, char *dir, char *error)
{
struct sockaddr_in sin;
struct hostent *hp;
@@ -156,7 +158,7 @@ mount_nfs(fsname, dir, error)
*/
if ((hp = gethostbyname(host)) == NULL) {
errprintf(error, "mount %s: %s not in hosts database\n",
- fsname, host);
+ fsname, host);
return (1);
}
@@ -171,11 +173,11 @@ mount_nfs(fsname, dir, error)
fprintf(stderr, "h_aliases %s\n\t", "<none>");
if (hp->h_addrtype == AF_INET)
fprintf(stderr,
- "h_addrtype AF_INET\n\th_adth_length %u\n\t",
- hp->h_length);
+ "h_addrtype AF_INET\n\th_adth_length %u\n\t",
+ hp->h_length);
else
fprintf(stderr, "h_addrtype %u\n\th_adth_length %u\n\t",
- hp->h_addrtype, hp->h_length);
+ hp->h_addrtype, hp->h_length);
if (hp->h_addr_list[0] && *hp->h_addr_list[0])
fprintf(stderr, "h_addr_list <apparent list>\n");
else
@@ -196,19 +198,19 @@ mount_nfs(fsname, dir, error)
printf("clnt_create for mountproc (%d)\n", errno);
client = clnt_create_vers(host, MOUNTPROG, &vers, MOUNTVERS, vers,
- "udp");
+ "udp");
if (client == NULL) {
errprintf(error, "%s %s\n", host,
- clnt_spcreateerror("mount server not responding"));
+ clnt_spcreateerror("mount server not responding"));
return (1);
}
if (Debug)
printf("call bindudp_resvport for mountproc (%d)\n", errno);
- if (bindudp_resvport(client) < 0) {
+ if (bindudp_resvport(client) < 0) {
errprintf(error, "mount %s:%s: %s\n", host, path,
- "Couldn't bind to reserved port");
+ "Couldn't bind to reserved port");
if (Debug)
printf("could not bind to reserved port\n");
clnt_destroy(client);
@@ -219,7 +221,7 @@ mount_nfs(fsname, dir, error)
auth_destroy(client->cl_auth);
if ((client->cl_auth = authsys_create_default()) == NULL) {
errprintf(error, "mount %s:%s: %s\n", host, path,
- "Couldn't create authsys structure");
+ "Couldn't create authsys structure");
if (Debug)
printf("could not create authsys structure\n");
clnt_destroy(client);
@@ -234,7 +236,7 @@ mount_nfs(fsname, dir, error)
*/
/* set mount args */
- memset(&args, 0, sizeof(args));
+ memset(&args, 0, sizeof (args));
/* Get fhandle of remote path from server's mountd */
@@ -245,14 +247,16 @@ mount_nfs(fsname, dir, error)
case MOUNTVERS:
case MOUNTVERS_POSIX:
rpc_stat = clnt_call(client, MOUNTPROC_MNT,
- xdr_dirpath, (caddr_t)&path,
- xdr_fhstatus, (caddr_t)&fhs, timeout);
+ xdr_dirpath, (caddr_t)&path,
+ xdr_fhstatus, (caddr_t)&fhs, timeout);
if (rpc_stat != RPC_SUCCESS) {
- /* Given the way "clnt_sperror" works, the "%s" */
- /* following the "not responding" is correct. */
+ /*
+ * Given the way "clnt_sperror" works, the "%s"
+ * following the "not responding" is correct.
+ */
errprintf(error, "mount server %s not responding %s\n",
- host, clnt_sperror(client, ""));
+ host, clnt_sperror(client, ""));
clnt_destroy(client);
return (1);
}
@@ -262,11 +266,11 @@ mount_nfs(fsname, dir, error)
if ((errno = fhs.fhs_status) != MNT_OK) {
if (errno == EACCES) {
errprintf(error,
- "rexd mount: not in EXPORT list for %s\n",
- fsname);
+ "rexd mount: not in EXPORT list for %s\n",
+ fsname);
} else {
errprintf(error, "rexd mount: error %d %s\n",
- errno, strerror(errno));
+ errno, strerror(errno));
}
return (1);
}
@@ -277,14 +281,16 @@ mount_nfs(fsname, dir, error)
case MOUNTVERS3:
memset((char *)&res3, '\0', sizeof (res3));
rpc_stat = clnt_call(client, MOUNTPROC_MNT,
- xdr_dirpath, (char *)&path,
- xdr_mountres3, (char *)&res3, timeout);
+ xdr_dirpath, (char *)&path,
+ xdr_mountres3, (char *)&res3, timeout);
if (rpc_stat != RPC_SUCCESS) {
- /* Given the way "clnt_sperror" works, the "%s" */
- /* following the "not responding" is correct. */
+ /*
+ * Given the way "clnt_sperror" works, the "%s"
+ * following the "not responding" is correct.
+ */
errprintf(error, "mount server %s not responding %s\n",
- host, clnt_sperror(client, ""));
+ host, clnt_sperror(client, ""));
clnt_destroy(client);
return (1);
}
@@ -294,11 +300,11 @@ mount_nfs(fsname, dir, error)
if ((errno = res3.fhs_status) != MNT_OK) {
if (errno == EACCES) {
errprintf(error,
- "rexd mount: not in EXPORT list for %s\n",
- fsname);
+ "rexd mount: not in EXPORT list for %s\n",
+ fsname);
} else {
errprintf(error, "rexd mount: error %d %s\n",
- errno, strerror(errno));
+ errno, strerror(errno));
}
return (1);
}
@@ -322,7 +328,7 @@ mount_nfs(fsname, dir, error)
break;
default:
errprintf(error, "rexd mount: unknown MOUNT version %ld\n",
- vers);
+ vers);
return (1);
}
@@ -353,12 +359,18 @@ mount_nfs(fsname, dir, error)
flags = MS_NOSUID | MS_DATA;
+ /*
+ * And make sure that we have the ephemeral mount_to
+ * set for this zone.
+ */
+ set_nfsv4_ephemeral_mount_to();
+
/* Provide the mounted resource name when mounting. */
- if (mount(fsname, dir, flags, fstype, &args, sizeof(args)) < 0) {
+ if (mount(fsname, dir, flags, fstype, &args, sizeof (args)) < 0) {
netbuf_free(args.addr);
free_knconf(args.knconf);
errprintf(error, "unable to mount %s on %s: %s\n",
- fsname, dir, strerror(errno));
+ fsname, dir, strerror(errno));
return (1);
}
@@ -397,8 +409,7 @@ mount_nfs(fsname, dir, error)
* umount_nfs - unmount a file system when finished
*/
int
-umount_nfs(fsname, dir)
-char *fsname, *dir;
+umount_nfs(char *fsname, char *dir)
{
char *p;
char *hostname;
@@ -443,7 +454,7 @@ char *fsname, *dir;
}
if (bindudp_resvport(client) < 0) {
errprintf(NULL, "umount %s:%s:%s", hostname, p,
- "Could not bind to reserved port\n");
+ "Could not bind to reserved port\n");
clnt_destroy(client);
return (1);
}
@@ -456,8 +467,8 @@ char *fsname, *dir;
timeout.tv_usec = 0;
timeout.tv_sec = 25;
- rpc_stat = clnt_call(client, MOUNTPROC_UMNT, xdr_dirpath, (caddr_t) &p,
- xdr_void, (char *)NULL, timeout);
+ rpc_stat = clnt_call(client, MOUNTPROC_UMNT, xdr_dirpath, (caddr_t)&p,
+ xdr_void, (char *)NULL, timeout);
clnt_destroy(client);
@@ -470,12 +481,8 @@ char *fsname, *dir;
return (0);
}
-
-
-
static struct mnttab *
-dupmnttab(mnt)
-struct mnttab *mnt;
+dupmnttab(struct mnttab *mnt)
{
struct mnttab *new;
void freemnttab();
@@ -502,7 +509,8 @@ struct mnttab *mnt;
return (new);
- alloc_failed:
+alloc_failed:
+
errprintf(NULL, "dupmnttab: memory allocation failed\n");
freemnttab(new);
return (NULL);
@@ -514,8 +522,7 @@ struct mnttab *mnt;
* Free a single mnttab structure
*/
static void
-freemnttab(mnt)
-struct mnttab *mnt;
+freemnttab(struct mnttab *mnt)
{
if (mnt) {
if (mnt->mnt_special)
@@ -545,8 +552,7 @@ struct mntlist {
* Free a list of mnttab structures
*/
static void
-freemntlist(mntl)
-struct mntlist *mntl;
+freemntlist(struct mntlist *mntl)
{
struct mntlist *mntl_tmp;
@@ -568,25 +574,20 @@ struct mntlist *mntl;
* Returns NULL on errors.
*/
char *
-parsefs(fullname, error)
-char *fullname;
-char *error;
+parsefs(char *fullname, char *error)
{
- char *dir,
- *subdir;
+ char *dir, *subdir;
struct exportnode *ex = NULL;
int err;
int bestlen = 0;
- int len,
- dirlen;
+ int len, dirlen;
if (Debug && errno)
printf("parsefs of %s entered with errno %d %s\n",
- fullname, errno, strerror(errno));
+ fullname, errno, strerror(errno));
dir = strchr(fullname, ':');
if (dir == NULL) {
-
errprintf(error, "No host name in %s\n", fullname);
return (NULL);
}
@@ -596,20 +597,18 @@ char *error;
printf("parsefs before rpc_call: ERRNO:%d\n", errno);
if (err = rpc_call(fullname, MOUNTPROG, MOUNTVERS, MOUNTPROC_EXPORT,
- xdr_void, 0, xdr_exports, (char *)&ex, "udp")) {
+ xdr_void, 0, xdr_exports, (char *)&ex, "udp")) {
if (err == (int)RPC_TIMEDOUT)
errprintf(error, "Host %s is not running mountd\n",
- fullname);
+ fullname);
else
errprintf(error, "RPC error %d with host %s (%s)\n",
- err, fullname, clnt_sperrno(err));
+ err, fullname, clnt_sperrno(err));
if (Debug && errno) {
printf("parsefs: mount call to %s returned %d %s\n",
- fullname,
- err,
- clnt_sperrno(err));
+ fullname, err, clnt_sperrno(err));
printf("with errno %d:\t%s\n", errno, strerror(errno));
}
return (NULL);
@@ -622,9 +621,7 @@ char *error;
if (Debug && errno) {
printf("parsefs: mount call to %s returned %d %s\n",
- fullname,
- err,
- clnt_sperrno(err));
+ fullname, err, clnt_sperrno(err));
printf("with errno %d:\t%s\n", errno, strerror(errno));
}
@@ -644,7 +641,7 @@ char *error;
if (bestlen == 0) {
errprintf(error, "%s not exported by %s\n",
- dir, fullname);
+ dir, fullname);
return (NULL);
}
@@ -659,7 +656,6 @@ char *error;
return (subdir);
}
-
/*
* Get the network address for the service identified by "prog"
* and "vers" on "hostname". The netconfig address is returned
@@ -667,13 +663,8 @@ char *error;
* If the hostname is the same as the last call, then the same
* transport is used as last time (same netconfig entry).
*/
-
-
static struct netbuf *
-get_addr(hostname, prog, vers, nconfp)
-char *hostname;
-int prog, vers;
-struct netconfig **nconfp;
+get_addr(char *hostname, int prog, int vers, struct netconfig **nconfp)
{
static char prevhost[MAXHOSTNAMELEN+1];
static struct netconfig *nconf;
@@ -712,12 +703,12 @@ struct netconfig **nconfp;
if (fd < 0)
goto done;
- tbind = (struct t_bind *) t_alloc(fd, T_BIND, T_ADDR);
+ tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR);
if (tbind == NULL)
goto done;
if (rpcb_getaddr(prog, vers, nconf, &tbind->addr, hostname) == 0) {
- t_free((char *) tbind, T_BIND);
+ t_free((char *)tbind, T_BIND);
tbind = NULL;
goto retry;
}
@@ -726,7 +717,7 @@ struct netconfig **nconfp;
/*
* Make a copy of the netbuf to return
*/
- nb = (struct netbuf *) malloc(sizeof (struct netbuf));
+ nb = (struct netbuf *)malloc(sizeof (struct netbuf));
if (nb == NULL) {
errprintf(NULL, "no memory");
goto done;
@@ -743,15 +734,14 @@ struct netconfig **nconfp;
done:
if (tbind)
- t_free((char *) tbind, T_BIND);
+ t_free((char *)tbind, T_BIND);
if (fd >= 0)
(void) t_close(fd);
return (nb);
}
static struct knetconfig *
-get_knconf(nconf)
-struct netconfig *nconf;
+get_knconf(struct netconfig *nconf)
{
struct stat stbuf;
struct knetconfig *k;
@@ -760,7 +750,7 @@ struct netconfig *nconf;
errprintf(NULL, "get_knconf: stat %s: %m", nconf->nc_device);
return (NULL);
}
- k = (struct knetconfig *) malloc(sizeof (*k));
+ k = (struct knetconfig *)malloc(sizeof (*k));
if (k == NULL)
goto nomem;
k->knc_semantics = nconf->nc_semantics;
@@ -781,8 +771,7 @@ nomem:
}
static void
-free_knconf(k)
-struct knetconfig *k;
+free_knconf(struct knetconfig *k)
{
if (k == NULL)
return;
@@ -794,8 +783,7 @@ struct knetconfig *k;
}
static void
-netbuf_free(nb)
-struct netbuf *nb;
+netbuf_free(struct netbuf *nb)
{
if (nb == NULL)
return;
@@ -806,9 +794,7 @@ struct netbuf *nb;
static enum clnt_stat
-pingnfs(hostname, versp)
-char *hostname;
-rpcvers_t *versp;
+pingnfs(char *hostname, rpcvers_t *versp)
{
CLIENT *cl;
enum clnt_stat clnt_stat;
@@ -828,10 +814,10 @@ rpcvers_t *versp;
/* ping the NFS nullproc on the server */
cl = clnt_create_vers(hostname, NFS_PROGRAM, versp, NFS_VERSMIN,
- NFS_VERSMAX, "udp");
+ NFS_VERSMAX, "udp");
if (cl == NULL) {
errprintf(NULL, "pingnfs: %s%s",
- hostname, clnt_spcreateerror(""));
+ hostname, clnt_spcreateerror(""));
if (Debug)
printf("clnt_create failed\n");
clnt_stat = RPC_TIMEDOUT;
@@ -850,13 +836,12 @@ rpcvers_t *versp;
if (Debug)
(void) printf("%s\n", clnt_stat == RPC_SUCCESS ?
- "OK" : "NO RESPONSE");
+ "OK" : "NO RESPONSE");
return (clnt_stat);
}
-static int bindudp_resvport(client)
-CLIENT *client;
+static int bindudp_resvport(CLIENT *client)
{
struct netconfig *udpnconf;
int clfd;
@@ -868,8 +853,9 @@ CLIENT *client;
return (-1);
}
- if (clnt_control(client, CLGET_FD, (char *) &clfd) == FALSE) {
- errprintf(NULL, "Could not get file dscriptor for client handle\n");
+ if (clnt_control(client, CLGET_FD, (char *)&clfd) == FALSE) {
+ errprintf(NULL,
+ "Could not get file dscriptor for client handle\n");
return (-1);
}
@@ -882,7 +868,7 @@ CLIENT *client;
}
}
- if ((udpnconf = getnetconfigent("udp")) == (struct netconfig *) NULL) {
+ if ((udpnconf = getnetconfigent("udp")) == (struct netconfig *)NULL) {
errprintf(NULL, "no netconfig information about \"udp\"\n");
return (-1);
}
@@ -892,7 +878,7 @@ CLIENT *client;
}
if ((rv = netdir_options(udpnconf, ND_SET_RESERVEDPORT, clfd,
- (char *) NULL)) == -1) {
+ (char *)NULL)) == -1) {
if (Debug) {
printf("netdir_options fails rv=%d\n", rv);
}
diff --git a/usr/src/lib/libc/port/gen/nftw.c b/usr/src/lib/libc/port/gen/nftw.c
index c048664f3b..f4247c2ed2 100644
--- a/usr/src/lib/libc/port/gen/nftw.c
+++ b/usr/src/lib/libc/port/gen/nftw.c
@@ -175,16 +175,17 @@ struct Var {
dev_t cur_mount;
struct FTW state;
int walklevel;
- int (*statf)(const char *, struct stat *, struct Save *);
- int (*savedstatf)(const char *, struct stat *, struct Save *);
+ int (*statf)(const char *, struct stat *, struct Save *, int flags);
+ int (*savedstatf)(const char *, struct stat *, struct Save *,
+ int flags);
DIR *(*opendirf)(const char *);
};
static int oldclose(struct Save *);
-static int cdlstat(const char *, struct stat *, struct Save *);
-static int cdstat(const char *, struct stat *, struct Save *);
-static int nocdlstat(const char *, struct stat *, struct Save *);
-static int nocdstat(const char *, struct stat *, struct Save *);
+static int cdlstat(const char *, struct stat *, struct Save *, int flags);
+static int cdstat(const char *, struct stat *, struct Save *, int flags);
+static int nocdlstat(const char *, struct stat *, struct Save *, int flags);
+static int nocdstat(const char *, struct stat *, struct Save *, int flags);
static DIR *cdopendir(const char *);
static DIR *nocdopendir(const char *);
static const char *get_unrooted(const char *);
@@ -234,8 +235,11 @@ walk(char *component,
/*
* Determine the type of the component.
+ *
+ * Note that if the component is a trigger mount, this
+ * will cause it to load.
*/
- if ((*vp->statf)(comp, &statb, last) >= 0) {
+ if ((*vp->statf)(comp, &statb, last, _AT_TRIGGER) >= 0) {
if ((statb.st_mode & S_IFMT) == S_IFDIR) {
type = FTW_D;
if (depth <= 1)
@@ -256,17 +260,6 @@ walk(char *component,
goto fail;
}
}
- if (statb.st_fstype[0] == 'a' &&
- strcmp(statb.st_fstype, "autofs") == 0) {
- /*
- * this dir is on autofs
- */
- if (fstat(this.fd->dd_fd, &statb) < 0) {
- (void) closedir(this.fd);
- type = FTW_NS;
- goto fail;
- }
- }
} else if ((statb.st_mode & S_IFMT) == S_IFLNK) {
type = FTW_SL;
} else {
@@ -293,10 +286,10 @@ walk(char *component,
* link.
*/
if (((vp->statf == cdstat) &&
- (cdlstat(comp, &statb, last) >= 0) &&
+ (cdlstat(comp, &statb, last, 0) >= 0) &&
((statb.st_mode & S_IFMT) == S_IFLNK)) ||
((vp->statf == nocdstat) &&
- (nocdlstat(comp, &statb, last) >= 0) &&
+ (nocdlstat(comp, &statb, last, 0) >= 0) &&
((statb.st_mode & S_IFMT) == S_IFLNK))) {
/*
@@ -492,7 +485,7 @@ quit:
}
} else {
if ((cdval = chdir("..")) >= 0) {
- if ((*vp->statf)(".", &statb, last) < 0 ||
+ if ((*vp->statf)(".", &statb, last, 0) < 0 ||
statb.st_ino != last->inode ||
statb.st_dev != last->dev)
cdval = -1;
@@ -502,18 +495,20 @@ quit:
if (chdir(vp->fullpath) < 0) {
rc = -1;
} else {
- /* Security check */
- if ((vp->curflags & FTW_PHYS) &&
- ((*vp->statf)(".", &statb, last) < 0 ||
- statb.st_ino != last->inode ||
- statb.st_dev != last->dev)) {
- errno = EAGAIN;
- rc = -1;
- }
+ /* Security check */
+ if ((vp->curflags & FTW_PHYS) &&
+ ((*vp->statf)(".", &statb,
+ last, 0) < 0 ||
+ statb.st_ino != last->inode ||
+ statb.st_dev != last->dev)) {
+ errno = EAGAIN;
+ rc = -1;
+ }
}
}
}
}
+
if (this.fd)
(void) closedir(this.fd);
if (val > rc)
@@ -610,7 +605,7 @@ _nftw(const char *path,
* save the current mount point.
*/
if (flags & FTW_MOUNT) {
- if ((*var.statf)(savepath, &statb, NULL) >= 0)
+ if ((*var.statf)(savepath, &statb, NULL, 0) >= 0)
var.cur_mount = statb.st_dev;
else
goto done;
@@ -641,8 +636,9 @@ done:
*/
/*ARGSUSED1*/
static int
-cdstat(const char *path, struct stat *statp, struct Save *lp) {
- return (stat(path, statp));
+cdstat(const char *path, struct stat *statp, struct Save *lp, int flags)
+{
+ return (fstatat(AT_FDCWD, path, statp, flags));
}
/*
@@ -650,44 +646,56 @@ cdstat(const char *path, struct stat *statp, struct Save *lp) {
*/
/*ARGSUSED1*/
static int
-cdlstat(const char *path, struct stat *statp, struct Save *lp)
+cdlstat(const char *path, struct stat *statp, struct Save *lp, int flags)
{
- return (lstat(path, statp));
+ return (fstatat(AT_FDCWD, path, statp,
+ flags | AT_SYMLINK_NOFOLLOW));
}
/*
* Get stat info on path when FTW_CHDIR is not set.
*/
static int
-nocdstat(const char *path, struct stat *statp, struct Save *lp)
+nocdstat(const char *path, struct stat *statp, struct Save *lp, int flags)
{
- const char *unrootp;
+ int fd;
+ const char *basepath;
if (lp && lp->fd) {
/* get basename of path */
- unrootp = get_unrooted(path);
- return (fstatat(lp->fd->dd_fd, unrootp, statp, 0));
+ basepath = get_unrooted(path);
+
+ fd = lp->fd->dd_fd;
} else {
- return (stat(path, statp));
+ basepath = path;
+
+ fd = AT_FDCWD;
}
+
+ return (fstatat(fd, basepath, statp, flags));
}
/*
* Get lstat info on path when FTW_CHDIR is not set.
*/
static int
-nocdlstat(const char *path, struct stat *statp, struct Save *lp)
+nocdlstat(const char *path, struct stat *statp, struct Save *lp, int flags)
{
- const char *unrootp;
+ int fd;
+ const char *basepath;
if (lp && lp->fd) {
/* get basename of path */
- unrootp = get_unrooted(path);
- return (fstatat(lp->fd->dd_fd, unrootp, statp,
- AT_SYMLINK_NOFOLLOW));
+ basepath = get_unrooted(path);
+
+ fd = lp->fd->dd_fd;
} else {
- return (lstat(path, statp));
+ basepath = path;
+
+ fd = AT_FDCWD;
}
+
+ return (fstatat(fd, basepath, statp, flags | AT_SYMLINK_NOFOLLOW));
}
/*
@@ -716,23 +724,23 @@ nocdopendir(const char *path)
return (NULL);
}
if ((token = strtok_r(dirp, "/", &ptr)) != NULL) {
- if ((fd = openat(AT_FDCWD, dirp, O_RDONLY)) < 0) {
- (void) free(dirp);
- errno = ENAMETOOLONG;
- return (NULL);
- }
- while ((token = strtok_r(NULL, "/", &ptr)) != NULL) {
- if ((cfd = openat(fd, token, O_RDONLY)) < 0) {
- (void) close(fd);
- (void) free(dirp);
- errno = ENAMETOOLONG;
- return (NULL);
+ if ((fd = openat(AT_FDCWD, dirp, O_RDONLY)) < 0) {
+ (void) free(dirp);
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ while ((token = strtok_r(NULL, "/", &ptr)) != NULL) {
+ if ((cfd = openat(fd, token, O_RDONLY)) < 0) {
+ (void) close(fd);
+ (void) free(dirp);
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ (void) close(fd);
+ fd = cfd;
}
- (void) close(fd);
- fd = cfd;
- }
- (void) free(dirp);
- return (fdopendir(fd));
+ (void) free(dirp);
+ return (fdopendir(fd));
}
(void) free(dirp);
errno = ENAMETOOLONG;
@@ -740,7 +748,11 @@ nocdopendir(const char *path)
return (fdd);
}
-/* return pointer basename of path, which may contain trailing slashes */
+/*
+ * return pointer basename of path, which may contain trailing slashes
+ *
+ * We do this when we do not chdir() on the input.
+ */
static const char *
get_unrooted(const char *path)
{
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 21071a1742..ba15278285 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -869,7 +869,7 @@ NFS_OBJS += nfs_client.o nfs_common.o nfs_dump.o \
nfs4_acache.o nfs4_common.o nfs4_client_state.o \
nfs4_callback.o nfs4_recovery.o nfs4_client_secinfo.o \
nfs4_client_debug.o nfs_stats.o \
- nfs4_acl.o
+ nfs4_acl.o nfs4_stub_vnops.o
NFSSRV_OBJS += nfs_server.o nfs_srv.o nfs3_srv.o \
nfs_acl_srv.o nfs_auth.o nfs_auth_xdr.o \
diff --git a/usr/src/uts/common/fs/autofs/auto_vnops.c b/usr/src/uts/common/fs/autofs/auto_vnops.c
index dec18bd6e1..5ffcf57d83 100644
--- a/usr/src/uts/common/fs/autofs/auto_vnops.c
+++ b/usr/src/uts/common/fs/autofs/auto_vnops.c
@@ -158,17 +158,35 @@ auto_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cred)
AUTOFS_DPRINT((4, "auto_getattr vp %p\n", (void *)vp));
- /*
- * Recursive auto_getattr/mount; go to the vfsp == NULL
- * case.
- */
- if (vn_vfswlock_held(vp))
- goto defattr;
+ if (flags & ATTR_TRIGGER) {
+ /*
+ * Pre-trigger the mount
+ */
+ error = auto_trigger_mount(vp, cred, &newvp);
+ if (error)
+ return (error);
- if (error = vn_vfsrlock_wait(vp))
- return (error);
+ if (newvp == NULL)
+ goto defattr;
+
+ if (error = vn_vfsrlock_wait(vp))
+ return (error);
+
+ vfsp = newvp->v_vfsp;
+ } else {
+ /*
+ * Recursive auto_getattr/mount; go to the vfsp == NULL
+ * case.
+ */
+ if (vn_vfswlock_held(vp))
+ goto defattr;
+
+ if (error = vn_vfsrlock_wait(vp))
+ return (error);
+
+ vfsp = vn_mountedvfs(vp);
+ }
- vfsp = vn_mountedvfs(vp);
if (vfsp != NULL) {
/*
* Node is mounted on.
@@ -299,7 +317,7 @@ auto_access(vnode_t *vp, int mode, int flags, cred_t *cred)
mode &= ~(fnp->fn_mode << shift);
if (mode != 0)
error = secpolicy_vnode_access(cred, vp, fnp->fn_uid,
- mode);
+ mode);
}
done:
@@ -602,9 +620,9 @@ top:
break;
default:
auto_log(dfnp->fn_globals->fng_verbose,
- dfnp->fn_globals->fng_zoneid, CE_WARN,
- "auto_lookup: unknown "
- "operation %d", operation);
+ dfnp->fn_globals->fng_zoneid, CE_WARN,
+ "auto_lookup: unknown operation %d",
+ operation);
}
AUTOFS_DPRINT((5, "auto_lookup: name=%s *vpp=%p return=%d\n",
@@ -914,13 +932,13 @@ again:
rda.uid = crgetuid(cred);
error = auto_calldaemon(fngp->fng_zoneid,
- AUTOFS_READDIR,
- xdr_autofs_rddirargs,
- &rda,
- xdr_autofs_rddirres,
- (void *)&rd,
- sizeof (autofs_rddirres),
- TRUE);
+ AUTOFS_READDIR,
+ xdr_autofs_rddirargs,
+ &rda,
+ xdr_autofs_rddirres,
+ (void *)&rd,
+ sizeof (autofs_rddirres),
+ TRUE);
/*
* reacquire previously dropped lock
@@ -954,7 +972,7 @@ again:
do {
this_reclen = cdp->d_reclen;
if (auto_search(fnp, cdp->d_name,
- NULL, cred)) {
+ NULL, cred)) {
/*
* entry not found in kernel list,
* include it in readdir output.
@@ -966,7 +984,7 @@ again:
*/
if (cdp != odp)
bcopy(cdp, odp,
- (size_t)this_reclen);
+ (size_t)this_reclen);
odp = nextdp(odp);
outcount += this_reclen;
} else {
@@ -982,7 +1000,7 @@ again:
}
count += this_reclen;
cdp = (struct dirent64 *)
- ((char *)cdp + this_reclen);
+ ((char *)cdp + this_reclen);
} while (count < rd.rd_rddir.rddir_size);
if (outcount)
@@ -1029,7 +1047,7 @@ again:
/* use strncpy(9f) to zero out uninitialized bytes */
(void) strncpy(dp->d_name, ".",
- DIRENT64_NAMELEN(this_reclen));
+ DIRENT64_NAMELEN(this_reclen));
outcount += dp->d_reclen;
dp = nextdp(dp);
@@ -1045,7 +1063,7 @@ again:
/* use strncpy(9f) to zero out uninitialized bytes */
(void) strncpy(dp->d_name, "..",
- DIRENT64_NAMELEN(this_reclen));
+ DIRENT64_NAMELEN(this_reclen));
outcount += dp->d_reclen;
dp = nextdp(dp);
}
@@ -1056,7 +1074,7 @@ again:
nfnp = cfnp->fn_next;
offset = cfnp->fn_offset;
if ((offset >= uiop->uio_offset) &&
- (!(cfnp->fn_flags & MF_LOOKUP))) {
+ (!(cfnp->fn_flags & MF_LOOKUP))) {
int reclen;
/*
@@ -1088,7 +1106,7 @@ again:
/* use strncpy(9f) to zero out uninitialized bytes */
(void) strncpy(dp->d_name, cfnp->fn_name,
- DIRENT64_NAMELEN(reclen));
+ DIRENT64_NAMELEN(reclen));
outcount += dp->d_reclen;
dp = nextdp(dp);
}
@@ -1097,6 +1115,7 @@ again:
if (outcount)
error = uiomove(outbuf, outcount, UIO_READ, uiop);
+
if (!error) {
if (reached_max) {
/*
@@ -1109,12 +1128,12 @@ again:
if (outcount == 0)
error = EINVAL;
} else if (autofs_nobrowse ||
- auto_nobrowse_option(fnip->fi_opts) ||
- (fnip->fi_flags & MF_DIRECT) ||
- (fnp->fn_trigger != NULL) ||
- (((vp->v_flag & VROOT) == 0) &&
- ((fntovn(fnp->fn_parent))->v_flag & VROOT) &&
- (fnp->fn_dirents == NULL))) {
+ auto_nobrowse_option(fnip->fi_opts) ||
+ (fnip->fi_flags & MF_DIRECT) ||
+ (fnp->fn_trigger != NULL) ||
+ (((vp->v_flag & VROOT) == 0) &&
+ ((fntovn(fnp->fn_parent))->v_flag & VROOT) &&
+ (fnp->fn_dirents == NULL))) {
/*
* done reading directory entries
*/
@@ -1132,7 +1151,7 @@ again:
done:
kmem_free(outbuf, alloc_count);
AUTOFS_DPRINT((5, "auto_readdir vp=%p offset=%lld eof=%d\n",
- (void *)vp, uiop->uio_loffset, myeof));
+ (void *)vp, uiop->uio_loffset, myeof));
return (error);
}
diff --git a/usr/src/uts/common/fs/nfs/nfs4_client.c b/usr/src/uts/common/fs/nfs/nfs4_client.c
index 2aa86b9594..85f68c5123 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_client.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_client.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -322,14 +322,14 @@ nfs4_purge_caches(vnode_t *vp, int purge_dnlc, cred_t *cr, int asyncpg)
mutex_exit(&rp->r_statelock);
args = kmem_alloc(sizeof (pgflush_t),
- KM_SLEEP);
+ KM_SLEEP);
args->vp = vp;
VN_HOLD(args->vp);
args->cr = cr;
crhold(args->cr);
(void) zthread_create(NULL, 0,
- nfs4_pgflush_thread, args, 0,
- minclsyspri);
+ nfs4_pgflush_thread, args, 0,
+ minclsyspri);
}
}
}
@@ -444,8 +444,8 @@ nfs4_attrcache_noinval(vnode_t *vp, nfs4_ga_res_t *garp, hrtime_t t)
void
nfs4_attr_cache(vnode_t *vp, nfs4_ga_res_t *garp,
- hrtime_t t, cred_t *cr, int async,
- change_info4 *cinfo)
+ hrtime_t t, cred_t *cr, int async,
+ change_info4 *cinfo)
{
rnode4_t *rp;
int mtime_changed;
@@ -738,7 +738,7 @@ nfs4_attrcache_va(vnode_t *vp, nfs4_ga_res_t *garp, int set_cache_timeout)
if (garp->n4g_mon_fid_valid) {
rp->r_mntd_fid = garp->n4g_mon_fid;
- if (rp->r_flags & R4SRVSTUB)
+ if (RP_ISSTUB(rp))
rp->r_attr.va_nodeid = rp->r_mntd_fid;
}
@@ -791,8 +791,9 @@ nfs4_getattr_otw(vnode_t *vp, nfs4_ga_res_t *garp, cred_t *cr, int get_acl)
(void) save_mnt_secinfo(mi->mi_curr_serv);
recov_retry:
+
if ((e.error = nfs4_start_fop(mi, vp, NULL, OH_GETATTR,
- &recov_state, NULL))) {
+ &recov_state, NULL))) {
(void) check_mnt_secinfo(mi->mi_curr_serv, vp);
return (e.error);
}
@@ -805,7 +806,7 @@ recov_retry:
if (nfs4_start_recovery(&e, VTOMI4(vp), vp, NULL, NULL,
NULL, OP_GETATTR, NULL) == FALSE) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_GETATTR,
- &recov_state, 1);
+ &recov_state, 1);
goto recov_retry;
}
}
@@ -837,7 +838,7 @@ recov_retry:
*/
void
nfs4_getattr_otw_norecovery(vnode_t *vp, nfs4_ga_res_t *garp,
- nfs4_error_t *ep, cred_t *cr, int get_acl)
+ nfs4_error_t *ep, cred_t *cr, int get_acl)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -906,35 +907,28 @@ nfs4getattr(vnode_t *vp, vattr_t *vap, cred_t *cr)
/*
* If we've got cached attributes, we're done, otherwise go
* to the server to get attributes, which will update the cache
- * in the process.
+ * in the process. Either way, use the cached attributes for
+ * the caller's vattr_t.
+ *
+ * Note that we ignore the gar set by the OTW call: the attr caching
+ * code may make adjustments when storing to the rnode, and we want
+ * to see those changes here.
*/
rp = VTOR4(vp);
+ error = 0;
mutex_enter(&rp->r_statelock);
- mutex_enter(&rp->r_statev4_lock);
- if (ATTRCACHE4_VALID(vp)) {
- mutex_exit(&rp->r_statev4_lock);
- /*
- * Cached attributes are valid
- * Return the client's view of file size
- */
- *vap = rp->r_attr;
- vap->va_size = rp->r_size;
+ if (!ATTRCACHE4_VALID(vp)) {
mutex_exit(&rp->r_statelock);
-
- ASSERT(nfs4_consistent_type(vp));
-
- return (0);
+ error = nfs4_getattr_otw(vp, &gar, cr, 0);
+ mutex_enter(&rp->r_statelock);
}
- mutex_exit(&rp->r_statev4_lock);
- mutex_exit(&rp->r_statelock);
- error = nfs4_getattr_otw(vp, &gar, cr, 0);
if (!error)
- *vap = gar.n4g_va;
+ *vap = rp->r_attr;
/* Return the client's view of file size */
- mutex_enter(&rp->r_statelock);
vap->va_size = rp->r_size;
+
mutex_exit(&rp->r_statelock);
ASSERT(nfs4_consistent_type(vp));
@@ -944,7 +938,7 @@ nfs4getattr(vnode_t *vp, vattr_t *vap, cred_t *cr)
int
nfs4_attr_otw(vnode_t *vp, nfs4_tag_type_t tag_type,
- nfs4_ga_res_t *garp, bitmap4 reqbitmap, cred_t *cr)
+ nfs4_ga_res_t *garp, bitmap4 reqbitmap, cred_t *cr)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -989,7 +983,7 @@ recov_retry:
needrecov = nfs4_needs_recovery(&e, FALSE, vp->v_vfsp);
if (!needrecov && e.error) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_GETATTR, &recov_state,
- needrecov);
+ needrecov);
return (e.error);
}
@@ -1000,9 +994,9 @@ recov_retry:
"nfs4_attr_otw: initiating recovery\n"));
abort = nfs4_start_recovery(&e, VTOMI4(vp), vp, NULL, NULL,
- NULL, OP_GETATTR, NULL);
+ NULL, OP_GETATTR, NULL);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_GETATTR, &recov_state,
- needrecov);
+ needrecov);
if (!e.error) {
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
e.error = geterrno4(res.status);
@@ -1017,17 +1011,17 @@ recov_retry:
} else {
gerp = garp->n4g_ext_res;
bcopy(&res.array[1].nfs_resop4_u.opgetattr.ga_res,
- garp, sizeof (nfs4_ga_res_t));
+ garp, sizeof (nfs4_ga_res_t));
garp->n4g_ext_res = gerp;
if (garp->n4g_ext_res &&
res.array[1].nfs_resop4_u.opgetattr.ga_res.n4g_ext_res)
bcopy(res.array[1].nfs_resop4_u.opgetattr.
- ga_res.n4g_ext_res,
- garp->n4g_ext_res, sizeof (nfs4_ga_ext_res_t));
+ ga_res.n4g_ext_res,
+ garp->n4g_ext_res, sizeof (nfs4_ga_ext_res_t));
}
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_GETATTR, &recov_state,
- needrecov);
+ needrecov);
return (e.error);
}
@@ -1090,7 +1084,7 @@ nfs4_async_manager(vfs_t *vfsp)
mi = VFTOMI4(vfsp);
CALLB_CPR_INIT(&cprinfo, &mi->mi_async_lock, callb_generic_cpr,
- "nfs4_async_manager");
+ "nfs4_async_manager");
mutex_enter(&mi->mi_async_lock);
/*
@@ -1210,8 +1204,8 @@ nfs4_async_manager_stop(vfs_t *vfsp)
int
nfs4_async_readahead(vnode_t *vp, u_offset_t blkoff, caddr_t addr,
- struct seg *seg, cred_t *cr, void (*readahead)(vnode_t *,
- u_offset_t, caddr_t, struct seg *, cred_t *))
+ struct seg *seg, cred_t *cr, void (*readahead)(vnode_t *,
+ u_offset_t, caddr_t, struct seg *, cred_t *))
{
rnode4_t *rp;
mntinfo4_t *mi;
@@ -1407,7 +1401,7 @@ nfs4_async_start(struct vfs *vfsp)
if (*mi->mi_async_curr == NULL ||
--mi->mi_async_clusters[args->a_io] == 0) {
mi->mi_async_clusters[args->a_io] =
- mi->mi_async_init_clusters;
+ mi->mi_async_init_clusters;
mi->mi_async_curr++;
if (mi->mi_async_curr ==
&mi->mi_async_reqs[NFS4_ASYNC_TYPES])
@@ -1427,26 +1421,25 @@ nfs4_async_start(struct vfs *vfsp)
*/
if (args->a_io == NFS4_READ_AHEAD && mi->mi_max_threads > 0) {
(*args->a_nfs4_readahead)(args->a_vp,
- args->a_nfs4_blkoff,
- args->a_nfs4_addr, args->a_nfs4_seg,
- args->a_cred);
+ args->a_nfs4_blkoff, args->a_nfs4_addr,
+ args->a_nfs4_seg, args->a_cred);
} else if (args->a_io == NFS4_PUTAPAGE) {
(void) (*args->a_nfs4_putapage)(args->a_vp,
- args->a_nfs4_pp, args->a_nfs4_off,
- args->a_nfs4_len, args->a_nfs4_flags,
- args->a_cred);
+ args->a_nfs4_pp, args->a_nfs4_off,
+ args->a_nfs4_len, args->a_nfs4_flags,
+ args->a_cred);
} else if (args->a_io == NFS4_PAGEIO) {
(void) (*args->a_nfs4_pageio)(args->a_vp,
- args->a_nfs4_pp, args->a_nfs4_off,
- args->a_nfs4_len, args->a_nfs4_flags,
- args->a_cred);
+ args->a_nfs4_pp, args->a_nfs4_off,
+ args->a_nfs4_len, args->a_nfs4_flags,
+ args->a_cred);
} else if (args->a_io == NFS4_READDIR) {
(void) ((*args->a_nfs4_readdir)(args->a_vp,
- args->a_nfs4_rdc, args->a_cred));
+ args->a_nfs4_rdc, args->a_cred));
} else if (args->a_io == NFS4_COMMIT) {
(*args->a_nfs4_commit)(args->a_vp, args->a_nfs4_plist,
- args->a_nfs4_offset, args->a_nfs4_count,
- args->a_cred);
+ args->a_nfs4_offset, args->a_nfs4_count,
+ args->a_cred);
} else if (args->a_io == NFS4_INACTIVE) {
nfs4_inactive_otw(args->a_vp, args->a_cred);
}
@@ -1476,7 +1469,7 @@ nfs4_inactive_thread(mntinfo4_t *mi)
vfs_t *vfsp = mi->mi_vfsp;
CALLB_CPR_INIT(&cprinfo, &mi->mi_async_lock, callb_generic_cpr,
- "nfs4_inactive_thread");
+ "nfs4_inactive_thread");
for (;;) {
mutex_enter(&mi->mi_async_lock);
@@ -1625,8 +1618,8 @@ interrupted:
int
nfs4_async_putapage(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
- int flags, cred_t *cr, int (*putapage)(vnode_t *, page_t *,
- u_offset_t, size_t, int, cred_t *))
+ int flags, cred_t *cr, int (*putapage)(vnode_t *, page_t *,
+ u_offset_t, size_t, int, cred_t *))
{
rnode4_t *rp;
mntinfo4_t *mi;
@@ -1748,8 +1741,8 @@ noasync:
int
nfs4_async_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
- int flags, cred_t *cr, int (*pageio)(vnode_t *, page_t *, u_offset_t,
- size_t, int, cred_t *))
+ int flags, cred_t *cr, int (*pageio)(vnode_t *, page_t *, u_offset_t,
+ size_t, int, cred_t *))
{
rnode4_t *rp;
mntinfo4_t *mi;
@@ -1879,7 +1872,7 @@ noasync:
void
nfs4_async_readdir(vnode_t *vp, rddir4_cache *rdc, cred_t *cr,
- int (*readdir)(vnode_t *, rddir4_cache *, cred_t *))
+ int (*readdir)(vnode_t *, rddir4_cache *, cred_t *))
{
rnode4_t *rp;
mntinfo4_t *mi;
@@ -1966,8 +1959,8 @@ noasync:
void
nfs4_async_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
- cred_t *cr, void (*commit)(vnode_t *, page_t *, offset3, count3,
- cred_t *))
+ cred_t *cr, void (*commit)(vnode_t *, page_t *, offset3, count3,
+ cred_t *))
{
rnode4_t *rp;
mntinfo4_t *mi;
@@ -2133,7 +2126,7 @@ nfs4_async_inactive(vnode_t *vp, cred_t *cr)
*/
if (rp->r_deleg_type != OPEN_DELEGATE_NONE) {
(void) nfs_rw_enter_sig(&mi->mi_recovlock, RW_READER,
- FALSE);
+ FALSE);
(void) nfs4delegreturn(rp, NFS4_DR_DISCARD);
nfs_rw_exit(&mi->mi_recovlock);
}
@@ -2231,8 +2224,8 @@ writerp4(rnode4_t *rp, caddr_t base, int tcount, struct uio *uio, int pgcreated)
* created and mapped at base.
*/
pagecreate = pgcreated ||
- ((offset & PAGEOFFSET) == 0 &&
- (n == PAGESIZE || ((offset + n) >= rp->r_size)));
+ ((offset & PAGEOFFSET) == 0 &&
+ (n == PAGESIZE || ((offset + n) >= rp->r_size)));
mutex_exit(&rp->r_statelock);
@@ -2251,7 +2244,7 @@ writerp4(rnode4_t *rp, caddr_t base, int tcount, struct uio *uio, int pgcreated)
*/
if (pgcreated == 0)
(void) segmap_pagecreate(segkmap, base,
- (uint_t)n, 1);
+ (uint_t)n, 1);
saved_base = base;
saved_n = n;
}
@@ -2279,7 +2272,7 @@ writerp4(rnode4_t *rp, caddr_t base, int tcount, struct uio *uio, int pgcreated)
* with zeros.
*/
error = vpm_data_copy(vp, offset, n, uio,
- !pagecreate, NULL, 0, S_WRITE);
+ !pagecreate, NULL, 0, S_WRITE);
} else {
error = uiomove(base, n, UIO_WRITE, uio);
}
@@ -2329,8 +2322,8 @@ writerp4(rnode4_t *rp, caddr_t base, int tcount, struct uio *uio, int pgcreated)
* segmap_pagecreate().
*/
sm_error = segmap_fault(kas.a_hat, segkmap,
- saved_base, saved_n,
- F_SOFTUNLOCK, S_WRITE);
+ saved_base, saved_n,
+ F_SOFTUNLOCK, S_WRITE);
if (error == 0)
error = sm_error;
}
@@ -2408,7 +2401,7 @@ nfs4_putpages(vnode_t *vp, u_offset_t off, size_t len, int flags, cred_t *cr)
* the dirty pages.
*/
error = pvn_vplist_dirty(vp, off, rp->r_putapage,
- flags, cr);
+ flags, cr);
/*
* If an error occured and the file was marked as dirty
@@ -2491,7 +2484,7 @@ nfs4_invalidate_pages(vnode_t *vp, u_offset_t off, cred_t *cr)
rp->r_truncaddr = off;
mutex_exit(&rp->r_statelock);
(void) pvn_vplist_dirty(vp, off, rp->r_putapage,
- B_INVAL | B_TRUNC, cr);
+ B_INVAL | B_TRUNC, cr);
mutex_enter(&rp->r_statelock);
rp->r_flags &= ~R4TRUNCATE;
cv_broadcast(&rp->r_cv);
@@ -2532,8 +2525,8 @@ nfs4_mnt_kstat_update(kstat_t *ksp, int rw)
* sv_currsec is NULL if no security negotiation takes place.
*/
mik->mik_secmod = mi->mi_curr_serv->sv_currsec ?
- mi->mi_curr_serv->sv_currsec->secmod :
- mi->mi_curr_serv->sv_secdata->secmod;
+ mi->mi_curr_serv->sv_currsec->secmod :
+ mi->mi_curr_serv->sv_secdata->secmod;
mik->mik_curread = (uint32_t)mi->mi_curread;
mik->mik_curwrite = (uint32_t)mi->mi_curwrite;
mik->mik_retrans = mi->mi_retrans;
@@ -2666,7 +2659,7 @@ nfs4_safemap(const vnode_t *vp)
ASSERT(nfs_rw_lock_held(&rp->r_lkserlock, RW_WRITER));
NFS4_DEBUG(nfs4_client_map_debug, (CE_NOTE, "nfs4_safemap: "
- "vp = %p", (void *)vp));
+ "vp = %p", (void *)vp));
/*
* Review all the locks for the vnode, both ones that have been
@@ -2701,7 +2694,7 @@ nfs4_safemap(const vnode_t *vp)
}
NFS4_DEBUG(nfs4_client_map_debug, (CE_NOTE, "nfs4_safemap: %s",
- safe ? "safe" : "unsafe"));
+ safe ? "safe" : "unsafe"));
return (safe);
}
@@ -3157,7 +3150,7 @@ nfs4_renew_lease_thread(nfs4_server_t *sp)
kmutex_t cpr_lock;
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: acting on sp 0x%p", (void*)sp));
+ "nfs4_renew_lease_thread: acting on sp 0x%p", (void*)sp));
mutex_init(&cpr_lock, NULL, MUTEX_DEFAULT, NULL);
CALLB_CPR_INIT(&cpr_info, &cpr_lock, callb_generic_cpr, "nfsv4Lease");
@@ -3169,34 +3162,34 @@ nfs4_renew_lease_thread(nfs4_server_t *sp)
for (;;) {
if (!sp->state_ref_count ||
- sp->lease_valid != NFS4_LEASE_VALID) {
+ sp->lease_valid != NFS4_LEASE_VALID) {
kip_secs = MAX((sp->s_lease_time >> 1) -
- (3 * sp->propagation_delay.tv_sec), 1);
+ (3 * sp->propagation_delay.tv_sec), 1);
tick_delay = SEC_TO_TICK(kip_secs);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: no renew : thread "
- "wait %ld secs", kip_secs));
+ "nfs4_renew_lease_thread: no renew : thread "
+ "wait %ld secs", kip_secs));
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: no renew : "
- "state_ref_count %d, lease_valid %d",
- sp->state_ref_count, sp->lease_valid));
+ "nfs4_renew_lease_thread: no renew : "
+ "state_ref_count %d, lease_valid %d",
+ sp->state_ref_count, sp->lease_valid));
mutex_enter(&cpr_lock);
CALLB_CPR_SAFE_BEGIN(&cpr_info);
mutex_exit(&cpr_lock);
time_left = cv_timedwait(&sp->cv_thread_exit,
- &sp->s_lock, tick_delay + lbolt);
+ &sp->s_lock, tick_delay + lbolt);
mutex_enter(&cpr_lock);
CALLB_CPR_SAFE_END(&cpr_info, &cpr_lock);
mutex_exit(&cpr_lock);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: no renew: "
- "time left %ld", time_left));
+ "nfs4_renew_lease_thread: no renew: "
+ "time left %ld", time_left));
if (sp->s_thread_exit == NFS4_THREAD_EXIT)
goto die;
@@ -3206,43 +3199,43 @@ nfs4_renew_lease_thread(nfs4_server_t *sp)
tmp_last_renewal_time = sp->last_renewal_time;
tmp_time = gethrestime_sec() - sp->last_renewal_time +
- (3 * sp->propagation_delay.tv_sec);
+ (3 * sp->propagation_delay.tv_sec);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: tmp_time %ld, "
- "sp->last_renewal_time %ld", tmp_time,
- sp->last_renewal_time));
+ "nfs4_renew_lease_thread: tmp_time %ld, "
+ "sp->last_renewal_time %ld", tmp_time,
+ sp->last_renewal_time));
kip_secs = MAX((sp->s_lease_time >> 1) - tmp_time, 1);
tick_delay = SEC_TO_TICK(kip_secs);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: valid lease: sleep for %ld "
- "secs", kip_secs));
+ "nfs4_renew_lease_thread: valid lease: sleep for %ld "
+ "secs", kip_secs));
mutex_enter(&cpr_lock);
CALLB_CPR_SAFE_BEGIN(&cpr_info);
mutex_exit(&cpr_lock);
time_left = cv_timedwait(&sp->cv_thread_exit, &sp->s_lock,
- tick_delay + lbolt);
+ tick_delay + lbolt);
mutex_enter(&cpr_lock);
CALLB_CPR_SAFE_END(&cpr_info, &cpr_lock);
mutex_exit(&cpr_lock);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: valid lease: time left %ld :"
- "sp last_renewal_time %ld, nfs4_client_resumed %ld, "
- "tmp_last_renewal_time %ld", time_left,
- sp->last_renewal_time, nfs4_client_resumed,
- tmp_last_renewal_time));
+ "nfs4_renew_lease_thread: valid lease: time left %ld :"
+ "sp last_renewal_time %ld, nfs4_client_resumed %ld, "
+ "tmp_last_renewal_time %ld", time_left,
+ sp->last_renewal_time, nfs4_client_resumed,
+ tmp_last_renewal_time));
if (sp->s_thread_exit == NFS4_THREAD_EXIT)
goto die;
if (tmp_last_renewal_time == sp->last_renewal_time ||
- (nfs4_client_resumed != 0 &&
- nfs4_client_resumed > sp->last_renewal_time)) {
+ (nfs4_client_resumed != 0 &&
+ nfs4_client_resumed > sp->last_renewal_time)) {
/*
* Issue RENEW op since we haven't renewed the lease
* since we slept.
@@ -3268,20 +3261,20 @@ nfs4_renew_lease_thread(nfs4_server_t *sp)
* we waited for a reply for our RENEW call.
*/
if (tmp_last_renewal_time ==
- sp->last_renewal_time) {
+ sp->last_renewal_time) {
/* no implicit renew came */
sp->last_renewal_time = tmp_now_time;
} else {
NFS4_DEBUG(nfs4_client_lease_debug,
- (CE_NOTE, "renew_thread: did "
- "implicit renewal before reply "
- "from server for RENEW"));
+ (CE_NOTE, "renew_thread: did "
+ "implicit renewal before reply "
+ "from server for RENEW"));
}
} else {
/* figure out error */
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "renew_thread: nfs4renew returned error"
- " %d", error));
+ "renew_thread: nfs4renew returned error"
+ " %d", error));
}
}
@@ -3289,14 +3282,14 @@ nfs4_renew_lease_thread(nfs4_server_t *sp)
die:
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: thread exiting"));
+ "nfs4_renew_lease_thread: thread exiting"));
while (sp->s_otw_call_count != 0) {
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: waiting for outstanding "
- "otw calls to finish for sp 0x%p, current "
- "s_otw_call_count %d", (void *)sp,
- sp->s_otw_call_count));
+ "nfs4_renew_lease_thread: waiting for outstanding "
+ "otw calls to finish for sp 0x%p, current "
+ "s_otw_call_count %d", (void *)sp,
+ sp->s_otw_call_count));
mutex_enter(&cpr_lock);
CALLB_CPR_SAFE_BEGIN(&cpr_info);
mutex_exit(&cpr_lock);
@@ -3317,7 +3310,7 @@ done:
mutex_destroy(&cpr_lock);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_renew_lease_thread: renew thread exit officially"));
+ "nfs4_renew_lease_thread: renew thread exit officially"));
zthread_exit();
/* NOT REACHED */
@@ -3401,26 +3394,26 @@ recov_retry:
"nfs4renew: %s call, sp 0x%p", needrecov ? "recov" : "first",
(void*)sp));
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE, "before: %ld s %ld ns ",
- prop_time.tv_sec, prop_time.tv_nsec));
+ prop_time.tv_sec, prop_time.tv_nsec));
DTRACE_PROBE2(nfs4__renew__start, nfs4_server_t *, sp,
- mntinfo4_t *, mi);
+ mntinfo4_t *, mi);
rfs4call(mi, &args, &res, cr, &doqueue, 0, &e);
crfree(cr);
DTRACE_PROBE2(nfs4__renew__end, nfs4_server_t *, sp,
- mntinfo4_t *, mi);
+ mntinfo4_t *, mi);
gethrestime(&after_time);
mutex_enter(&sp->s_lock);
sp->propagation_delay.tv_sec =
- MAX(1, after_time.tv_sec - prop_time.tv_sec);
+ MAX(1, after_time.tv_sec - prop_time.tv_sec);
mutex_exit(&sp->s_lock);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE, "after : %ld s %ld ns ",
- after_time.tv_sec, after_time.tv_nsec));
+ after_time.tv_sec, after_time.tv_nsec));
if (e.error == 0 && res.status == NFS4ERR_CB_PATH_DOWN) {
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
@@ -3455,7 +3448,7 @@ recov_retry:
VFS_RELE(mi->mi_vfsp);
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
mutex_enter(&sp->s_lock);
goto recov_retry;
}
@@ -3511,8 +3504,8 @@ nfs4_inc_state_ref_count_nolock(nfs4_server_t *sp, mntinfo4_t *mi)
sp->state_ref_count++;
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_inc_state_ref_count: state_ref_count now %d",
- sp->state_ref_count));
+ "nfs4_inc_state_ref_count: state_ref_count now %d",
+ sp->state_ref_count));
if (sp->lease_valid == NFS4_LEASE_UNINITIALIZED)
sp->lease_valid = NFS4_LEASE_VALID;
@@ -3556,20 +3549,20 @@ nfs4_dec_state_ref_count_nolock(nfs4_server_t *sp, mntinfo4_t *mi)
sp->state_ref_count--;
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_dec_state_ref_count: state ref count now %d",
- sp->state_ref_count));
+ "nfs4_dec_state_ref_count: state ref count now %d",
+ sp->state_ref_count));
mi->mi_open_files--;
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_dec_state_ref_count: mi open files %d, v4 flags 0x%x",
- mi->mi_open_files, mi->mi_flags));
+ "nfs4_dec_state_ref_count: mi open files %d, v4 flags 0x%x",
+ mi->mi_open_files, mi->mi_flags));
/* We don't have to hold the mi_lock to test mi_flags */
if (mi->mi_open_files == 0 &&
(mi->mi_flags & MI4_REMOVE_ON_LAST_CLOSE)) {
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_dec_state_ref_count: remove mntinfo4 %p since "
- "we have closed the last open file", (void*)mi));
+ "nfs4_dec_state_ref_count: remove mntinfo4 %p since "
+ "we have closed the last open file", (void*)mi));
nfs4_remove_mi_from_server(mi, sp);
}
}
@@ -3623,7 +3616,7 @@ void
sfh4_createtab(avl_tree_t *tab)
{
avl_create(tab, sfh4cmp, sizeof (nfs4_sharedfh_t),
- offsetof(nfs4_sharedfh_t, sfh_tree));
+ offsetof(nfs4_sharedfh_t, sfh_tree));
}
/*
@@ -3657,7 +3650,7 @@ sfh4_put(const nfs_fh4 *fh, mntinfo4_t *mi, nfs4_sharedfh_t *key)
nsfh->sfh_flags = SFH4_IN_TREE;
nsfh->sfh_mi = mi;
NFS4_DEBUG(nfs4_sharedfh_debug, (CE_NOTE, "sfh4_get: new object (%p)",
- (void *)nsfh));
+ (void *)nsfh));
(void) nfs_rw_enter_sig(&mi->mi_fh_lock, RW_WRITER, 0);
sfh = avl_find(&mi->mi_filehandles, key, &where);
@@ -3716,8 +3709,8 @@ sfh4_get(const nfs_fh4 *fh, mntinfo4_t *mi)
mutex_enter(&sfh->sfh_lock);
sfh->sfh_refcnt++;
NFS4_DEBUG(nfs4_sharedfh_debug, (CE_NOTE,
- "sfh4_get: found existing %p, new refcnt=%d",
- (void *)sfh, sfh->sfh_refcnt));
+ "sfh4_get: found existing %p, new refcnt=%d",
+ (void *)sfh, sfh->sfh_refcnt));
mutex_exit(&sfh->sfh_lock);
nfs_rw_exit(&mi->mi_fh_lock);
return (sfh);
@@ -3739,8 +3732,8 @@ sfh4_hold(nfs4_sharedfh_t *sfh)
mutex_enter(&sfh->sfh_lock);
sfh->sfh_refcnt++;
NFS4_DEBUG(nfs4_sharedfh_debug,
- (CE_NOTE, "sfh4_hold %p, new refcnt=%d",
- (void *)sfh, sfh->sfh_refcnt));
+ (CE_NOTE, "sfh4_hold %p, new refcnt=%d",
+ (void *)sfh, sfh->sfh_refcnt));
mutex_exit(&sfh->sfh_lock);
}
@@ -3786,7 +3779,7 @@ sfh4_rele(nfs4_sharedfh_t **sfhpp)
}
NFS4_DEBUG(nfs4_sharedfh_debug, (CE_NOTE,
- "sfh4_rele %p, last ref", (void *)sfh));
+ "sfh4_rele %p, last ref", (void *)sfh));
if (sfh->sfh_flags & SFH4_IN_TREE) {
avl_remove(&mi->mi_filehandles, sfh);
sfh->sfh_flags &= ~SFH4_IN_TREE;
@@ -3966,8 +3959,8 @@ fn_get(nfs4_fname_t *parent, char *name)
avl_create(&fnp->fn_children, fncmp, sizeof (nfs4_fname_t),
offsetof(nfs4_fname_t, fn_tree));
NFS4_DEBUG(nfs4_fname_debug, (CE_NOTE,
- "fn_get %p:%s, a new nfs4_fname_t!",
- (void *)fnp, fnp->fn_name));
+ "fn_get %p:%s, a new nfs4_fname_t!",
+ (void *)fnp, fnp->fn_name));
if (parent != NULL) {
avl_insert(&parent->fn_children, fnp, where);
mutex_exit(&parent->fn_lock);
@@ -3981,8 +3974,8 @@ fn_hold(nfs4_fname_t *fnp)
{
atomic_add_32(&fnp->fn_refcnt, 1);
NFS4_DEBUG(nfs4_fname_debug, (CE_NOTE,
- "fn_hold %p:%s, new refcnt=%d",
- (void *)fnp, fnp->fn_name, fnp->fn_refcnt));
+ "fn_hold %p:%s, new refcnt=%d",
+ (void *)fnp, fnp->fn_name, fnp->fn_refcnt));
}
/*
@@ -4008,8 +4001,8 @@ recur:
newref = atomic_add_32_nv(&fnp->fn_refcnt, -1);
if (newref > 0) {
NFS4_DEBUG(nfs4_fname_debug, (CE_NOTE,
- "fn_rele %p:%s, new refcnt=%d",
- (void *)fnp, fnp->fn_name, fnp->fn_refcnt));
+ "fn_rele %p:%s, new refcnt=%d",
+ (void *)fnp, fnp->fn_name, fnp->fn_refcnt));
if (parent != NULL)
mutex_exit(&parent->fn_lock);
mutex_exit(&fnp->fn_lock);
@@ -4017,8 +4010,8 @@ recur:
}
NFS4_DEBUG(nfs4_fname_debug, (CE_NOTE,
- "fn_rele %p:%s, last reference, deleting...",
- (void *)fnp, fnp->fn_name));
+ "fn_rele %p:%s, last reference, deleting...",
+ (void *)fnp, fnp->fn_name));
if (parent != NULL) {
avl_remove(&parent->fn_children, fnp);
mutex_exit(&parent->fn_lock);
@@ -4242,8 +4235,8 @@ nfs4_consistent_type(vnode_t *vp)
if (nfs4_vtype_debug && vp->v_type != VNON &&
rp->r_attr.va_type != VNON && vp->v_type != rp->r_attr.va_type) {
cmn_err(CE_PANIC, "vnode %p type mismatch; v_type=%d, "
- "rnode attr type=%d", (void *)vp, vp->v_type,
- rp->r_attr.va_type);
+ "rnode attr type=%d", (void *)vp, vp->v_type,
+ rp->r_attr.va_type);
}
return (1);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_client_secinfo.c b/usr/src/uts/common/fs/nfs/nfs4_client_secinfo.c
index dbdb8f9354..3546a88ea9 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_client_secinfo.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_client_secinfo.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -92,8 +92,8 @@ nfs4_secinfo_init(void)
secinfo_support = kmem_alloc(sizeof (SECINFO4res), KM_SLEEP);
secinfo_support->SECINFO4resok_len = SECINFO_SUPPORT_COUNT;
val = kmem_alloc(
- secinfo_support->SECINFO4resok_len * sizeof (secinfo4),
- KM_SLEEP);
+ secinfo_support->SECINFO4resok_len * sizeof (secinfo4),
+ KM_SLEEP);
val[0].flavor = AUTH_SYS;
val[0].flavor_info.oid.sec_oid4_len = 0;
@@ -136,7 +136,7 @@ nfs4_secinfo_fini(void)
{
kmem_free(secinfo_support->SECINFO4resok_val,
- secinfo_support->SECINFO4resok_len * sizeof (secinfo4));
+ secinfo_support->SECINFO4resok_len * sizeof (secinfo4));
kmem_free(secinfo_support, sizeof (SECINFO4res));
}
@@ -158,7 +158,7 @@ secinfo2nfsflavor(sec_oid4 *mech_oid, rpc_gss_svc_t service)
{
/* Is this kerberos_v5? */
if (bcmp(mech_oid->sec_oid4_val, krb5_oid.sec_oid4_val,
- krb5_oid.sec_oid4_len) != 0) {
+ krb5_oid.sec_oid4_len) != 0) {
return (0);
}
@@ -229,7 +229,7 @@ secinfo_create(servinfo4_t *svp, SECINFO4res *sec_info, char *servname)
data->qop = (uint_t)info->qop;
data->mechanism.length = info->oid.sec_oid4_len;
data->mechanism.elements =
- kmem_alloc(info->oid.sec_oid4_len, KM_SLEEP);
+ kmem_alloc(info->oid.sec_oid4_len, KM_SLEEP);
bcopy(info->oid.sec_oid4_val,
data->mechanism.elements, info->oid.sec_oid4_len);
data->uname[0] = 'n'; data->uname[1] = 'f';
@@ -238,7 +238,7 @@ secinfo_create(servinfo4_t *svp, SECINFO4res *sec_info, char *servname)
sdata[scnt].data = (caddr_t)data;
sdata[scnt].secmod =
- secinfo2nfsflavor(&info->oid, info->service);
+ secinfo2nfsflavor(&info->oid, info->service);
scnt++;
break;
case AUTH_DH:
@@ -280,32 +280,35 @@ secinfo_free(sv_secinfo_t *secinfo)
return;
for (i = 0; i < secinfo->count; i++) {
- if (secinfo->sdata[i].rpcflavor == RPCSEC_GSS) {
- gss_clntdata_t *data = (gss_clntdata_t *)
- secinfo->sdata[i].data;
+ if (secinfo->sdata[i].rpcflavor == RPCSEC_GSS) {
+ gss_clntdata_t *data = (gss_clntdata_t *)
+ secinfo->sdata[i].data;
- /*
- * An auth handle may already cached in rpcsec_gss module
- * per this secdata. Purge the cache entry before freeing
- * up this secdata. Can't use sec_clnt_freeinfo since
- * the allocation of secinfo is different from sec_data.
- */
- (void) rpc_gss_secpurge((void *)&secinfo->sdata[i]);
+ /*
+ * An auth handle may already cached in rpcsec_gss
+ * module per this secdata. Purge the cache entry
+ * before freeing up this secdata. Can't use
+ * sec_clnt_freeinfo since the allocation of secinfo
+ * is different from sec_data.
+ */
+ (void) rpc_gss_secpurge((void *)&secinfo->sdata[i]);
- kmem_free(data->mechanism.elements, data->mechanism.length);
- kmem_free(data, sizeof (gss_clntdata_t));
- }
+ kmem_free(data->mechanism.elements,
+ data->mechanism.length);
+ kmem_free(data, sizeof (gss_clntdata_t));
+ }
- if (secinfo->sdata[i].rpcflavor == AUTH_DH) {
+ if (secinfo->sdata[i].rpcflavor == AUTH_DH) {
- secinfo->sdata[i].data = NULL; /* release ref to sv_dhsec */
+ /* release ref to sv_dhsec */
+ secinfo->sdata[i].data = NULL;
- /*
- * No need to purge the auth_dh cache entry (e.g. call
- * purge_authtab()) since the AUTH_DH data used here
- * are always the same.
- */
- }
+ /*
+ * No need to purge the auth_dh cache entry (e.g. call
+ * purge_authtab()) since the AUTH_DH data used here
+ * are always the same.
+ */
+ }
}
kmem_free(secinfo->sdata, sizeof (sec_data_t) * secinfo->count);
kmem_free(secinfo, sizeof (sv_secinfo_t));
@@ -329,7 +332,7 @@ secinfo_check(servinfo4_t *svp)
if (svp->sv_secinfo->index < svp->sv_secinfo->count) {
svp->sv_flags |= SV4_TRYSECINFO;
svp->sv_currsec =
- &svp->sv_secinfo->sdata[svp->sv_secinfo->index];
+ &svp->sv_secinfo->sdata[svp->sv_secinfo->index];
nfs_rw_exit(&svp->sv_lock);
return (TRUE);
} else {
@@ -371,7 +374,7 @@ secinfo_update(servinfo4_t *svp, SECINFO4res *sec_info)
svp->sv_secinfo->index = 0;
svp->sv_flags |= SV4_TRYSECINFO;
svp->sv_currsec =
- &svp->sv_secinfo->sdata[svp->sv_secinfo->index];
+ &svp->sv_secinfo->sdata[svp->sv_secinfo->index];
} else {
svp->sv_flags &= ~SV4_TRYSECINFO;
svp->sv_currsec = NULL;
@@ -391,7 +394,6 @@ secinfo_update(servinfo4_t *svp, SECINFO4res *sec_info)
void
save_mnt_secinfo(servinfo4_t *svp)
{
-
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_WRITER, 0);
if (svp->sv_currsec) {
svp->sv_savesec = svp->sv_currsec;
@@ -418,9 +420,9 @@ check_mnt_secinfo(servinfo4_t *svp, vnode_t *vp)
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_WRITER, 0);
- is_restore = (vp == NULL || (VTOR4(vp)->r_flags & R4SRVSTUB)) &&
- svp->sv_save_secinfo &&
- (svp->sv_secinfo != svp->sv_save_secinfo);
+ is_restore = (vp == NULL || (RP_ISSTUB(VTOR4(vp)))) &&
+ svp->sv_save_secinfo &&
+ (svp->sv_secinfo != svp->sv_save_secinfo);
if (is_restore) {
secinfo_free(svp->sv_secinfo);
@@ -435,7 +437,7 @@ check_mnt_secinfo(servinfo4_t *svp, vnode_t *vp)
}
} else {
if (svp->sv_save_secinfo &&
- svp->sv_save_secinfo != svp->sv_secinfo)
+ svp->sv_save_secinfo != svp->sv_secinfo)
secinfo_free(svp->sv_save_secinfo);
}
@@ -666,9 +668,9 @@ retry:
num_argops = args.array_len;
argop[num_argops - 1].argop = OP_SECINFO;
argop[num_argops - 1].nfs_argop4_u.opsecinfo.name.utf8string_len =
- comp.utf8string_len;
+ comp.utf8string_len;
argop[num_argops - 1].nfs_argop4_u.opsecinfo.name.utf8string_val =
- comp.utf8string_val;
+ comp.utf8string_val;
doqueue = 1;
@@ -701,7 +703,7 @@ retry:
ncomp = tcomp;
nfs4args_lookup_free(argop, num_argops);
kmem_free(argop,
- lookuparg.arglen * sizeof (nfs_argop4));
+ lookuparg.arglen * sizeof (nfs_argop4));
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
kmem_free(tmp_path, path_len + 1);
@@ -730,22 +732,24 @@ retry:
/* If not in a recovery thread, bail out */
if (!isrecov) {
+ if (!e.error) {
+ e.error = geterrno4(res.status);
+ (void) xdr_free(xdr_COMPOUND4res_clnt,
+ (caddr_t)&res);
+ }
- if (!e.error) {
- e.error = geterrno4(res.status);
- (void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
- }
- nfs4args_lookup_free(argop, num_argops);
- kmem_free(argop, lookuparg.arglen * sizeof (nfs_argop4));
- kmem_free(tmp_path, path_len + 1);
- return (e.error);
+ nfs4args_lookup_free(argop, num_argops);
+ kmem_free(argop,
+ lookuparg.arglen * sizeof (nfs_argop4));
+ kmem_free(tmp_path, path_len + 1);
+ return (e.error);
}
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
"nfs4secinfo_otw: recovery in a recovery thread\n"));
abort = nfs4_start_recovery(&e, mi, NULL,
- NULL, NULL, NULL, OP_SECINFO, NULL);
+ NULL, NULL, NULL, OP_SECINFO, NULL);
if (!e.error) {
e.error = geterrno4(res.status);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
@@ -838,7 +842,6 @@ retry:
int
nfs4_secinfo_path(mntinfo4_t *mi, cred_t *cr, int isrecov)
{
-
int error = 0;
int ncomp;
servinfo4_t *svp = mi->mi_curr_serv;
diff --git a/usr/src/uts/common/fs/nfs/nfs4_recovery.c b/usr/src/uts/common/fs/nfs/nfs4_recovery.c
index 0cfdf4827a..32df45d5f8 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_recovery.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_recovery.c
@@ -148,7 +148,6 @@ static void free_milist(mntinfo4_t **, int);
static mntinfo4_t **make_milist(nfs4_server_t *, int *);
static int nfs4_check_recov_err(vnode_t *, nfs4_op_hint_t,
nfs4_recov_state_t *, int, char *);
-static int nfs4_check_srvstub(vnode_t *vp, rnode4_t *rp, nfs4_op_hint_t op);
static char *nfs4_getsrvnames(mntinfo4_t *, size_t *);
static void nfs4_recov_fh_fail(vnode_t *, int, nfsstat4);
static void nfs4_recov_thread(recov_info_t *);
@@ -242,7 +241,7 @@ nfs4_needs_recovery(nfs4_error_t *ep, bool_t stateful, vfs_t *vfsp)
case NFS4ERR_MOVED:
zcmn_err(VFTOMI4(vfsp)->mi_zone->zone_id,
CE_WARN, "!Can't yet recover from NFS status %d",
- ep->stat);
+ ep->stat);
break;
#endif
}
@@ -282,8 +281,8 @@ nfs4_enqueue_lost_rqst(recov_info_t *recovp, mntinfo4_t *mi)
ASSERT(lrp != NULL && lrp->lr_op != 0);
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE,
- "nfs4_enqueue_lost_rqst %p, op %d",
- (void *)lrp, lrp->lr_op));
+ "nfs4_enqueue_lost_rqst %p, op %d",
+ (void *)lrp, lrp->lr_op));
mutex_enter(&mi->mi_lock);
mi->mi_recovflags |= MI4R_LOST_STATE;
@@ -295,7 +294,7 @@ nfs4_enqueue_lost_rqst(recov_info_t *recovp, mntinfo4_t *mi)
mutex_exit(&mi->mi_lock);
nfs4_queue_event(RE_LOST_STATE, mi, NULL, lrp->lr_op, lrp->lr_vp,
- lrp->lr_dvp, 0, NULL, 0, TAG_NONE, TAG_NONE, 0, 0);
+ lrp->lr_dvp, 0, NULL, 0, TAG_NONE, TAG_NONE, 0, 0);
}
/*
@@ -361,7 +360,7 @@ nfs4_start_recovery(nfs4_error_t *ep, mntinfo4_t *mi, vnode_t *vp1,
if (abort) {
mutex_exit(&mi->mi_lock);
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "nfs4_start_recovery: fs unmounted"));
+ "nfs4_start_recovery: fs unmounted"));
return (TRUE);
}
}
@@ -371,8 +370,7 @@ nfs4_start_recovery(nfs4_error_t *ep, mntinfo4_t *mi, vnode_t *vp1,
recovp = kmem_alloc(sizeof (recov_info_t), KM_SLEEP);
recovp->rc_orig_errors = *ep;
sp = find_nfs4_server(mi);
- errs_to_action(recovp, sp, mi, sid, lost_rqstp,
- gone, op, bsep);
+ errs_to_action(recovp, sp, mi, sid, lost_rqstp, gone, op, bsep);
if (sp != NULL)
mutex_exit(&sp->s_lock);
start_recovery(recovp, mi, vp1, vp2, sp);
@@ -388,7 +386,7 @@ nfs4_start_recovery(nfs4_error_t *ep, mntinfo4_t *mi, vnode_t *vp1,
*/
static void
start_recovery_action(nfs4_recov_t what, bool_t reboot, mntinfo4_t *mi,
- vnode_t *vp1, vnode_t *vp2)
+ vnode_t *vp1, vnode_t *vp2)
{
recov_info_t *recovp;
@@ -406,11 +404,11 @@ start_recovery_action(nfs4_recov_t what, bool_t reboot, mntinfo4_t *mi,
static void
start_recovery(recov_info_t *recovp, mntinfo4_t *mi,
- vnode_t *vp1, vnode_t *vp2, nfs4_server_t *sp)
+ vnode_t *vp1, vnode_t *vp2, nfs4_server_t *sp)
{
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "start_recovery: mi %p, what %s", (void*)mi,
- nfs4_recov_action_to_str(recovp->rc_action)));
+ "start_recovery: mi %p, what %s", (void*)mi,
+ nfs4_recov_action_to_str(recovp->rc_action)));
/*
* Bump the reference on the vfs so that we can pass it to the
@@ -598,7 +596,7 @@ again:
mi->mi_flags |= MI4_RECOV_ACTIV;
mutex_exit(&mi->mi_lock);
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "start_recovery: starting new thread for mi %p", (void*)mi));
+ "start_recovery: starting new thread for mi %p", (void*)mi));
recovp->rc_mi = mi;
recovp->rc_vp1 = vp1;
@@ -613,7 +611,7 @@ again:
}
(void) zthread_create(NULL, 0, nfs4_recov_thread, recovp, 0,
- minclsyspri);
+ minclsyspri);
return;
/* not reached by thread creating call */
@@ -633,39 +631,8 @@ out_no_thread:
}
static int
-nfs4_check_srvstub(vnode_t *vp, rnode4_t *rp, nfs4_op_hint_t op)
-{
- int err = 0;
-
- /*
- * If tuneable does not allow client to cross srv mountpoints and
- * object is a stub, then check check op hint and return EACCES for
- * any hint other than access, rddir, getattr, lookup.
- */
- if (rp->r_flags & R4SRVSTUB && op != OH_ACCESS && op != OH_GETACL &&
- op != OH_GETATTR && op != OH_READDIR && op != OH_LOOKUP) {
- err = EACCES;
-#ifdef DEBUG
- NFS4_DEBUG(nfs4_srvmnt_debug, (CE_NOTE,
- "nfs4_check_srvstub: op=%d err=%d rp=%p vp=%p\n"
- "va_nod=%llx r_mntd_fid=%llx\n"
- "sv_fsid=(%llx:%llx) r_srv_fsid=(%llx:%llx)",
- op, err, (void *)rp, (void *)vp,
- (u_longlong_t)rp->r_attr.va_nodeid,
- (u_longlong_t)rp->r_mntd_fid,
- (u_longlong_t)rp->r_server->sv_fsid.major,
- (u_longlong_t)rp->r_server->sv_fsid.minor,
- (u_longlong_t)rp->r_srv_fsid.major,
- (u_longlong_t)rp->r_srv_fsid.minor));
-#endif
- }
-
- return (err);
-}
-
-static int
nfs4_check_recov_err(vnode_t *vp, nfs4_op_hint_t op,
- nfs4_recov_state_t *rsp, int retry_err_cnt, char *str)
+ nfs4_recov_state_t *rsp, int retry_err_cnt, char *str)
{
rnode4_t *rp;
int error = 0;
@@ -682,14 +649,10 @@ nfs4_check_recov_err(vnode_t *vp, nfs4_op_hint_t op,
* If there was a recovery error, then allow op hints "exempt" from
* recov errors to retry (currently 3 times). Either r_error or
* EIO is returned for non-exempt op hints.
- *
- * Error heirarchy:
- * a) check for R4ERECOVERR
- * b) check for R4SRVSTUB (only if R4RECOVERR is not set).
*/
if (rp->r_flags & R4RECOVERR) {
if (exempt && rsp->rs_num_retry_despite_err <=
- nfs4_max_recov_error_retry) {
+ nfs4_max_recov_error_retry) {
/*
* Check to make sure that we haven't already inc'd
@@ -702,8 +665,8 @@ nfs4_check_recov_err(vnode_t *vp, nfs4_op_hint_t op,
rsp->rs_num_retry_despite_err++;
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "nfs4_start_fop: %s %p DEAD, cnt=%d", str,
- (void *)vp, rsp->rs_num_retry_despite_err));
+ "nfs4_start_fop: %s %p DEAD, cnt=%d", str,
+ (void *)vp, rsp->rs_num_retry_despite_err));
} else {
error = (rp->r_error ? rp->r_error : EIO);
/*
@@ -718,21 +681,17 @@ nfs4_check_recov_err(vnode_t *vp, nfs4_op_hint_t op,
*/
if (error == ESTALE && vp->v_type != VREG) {
rp->r_flags &=
- ~(R4RECOVERR|R4RECOVERRP|R4STALE);
+ ~(R4RECOVERR|R4RECOVERRP|R4STALE);
rp->r_error = 0;
error = ESTALE;
}
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "nfs4_start_fop: %s %p DEAD, cnt=%d error=%d",
- str, (void *)vp,
- rsp->rs_num_retry_despite_err, error));
+ "nfs4_start_fop: %s %p DEAD, cnt=%d error=%d",
+ str, (void *)vp,
+ rsp->rs_num_retry_despite_err, error));
}
- } else {
- error = nfs4_check_srvstub(vp, rp, op);
- NFS4_DEBUG(nfs4_client_recov_stub_debug, (CE_NOTE,
- "nfs4_start_fop: %s %p SRVSTUB, error=%d", str,
- (void *)vp, error));
}
+
mutex_exit(&rp->r_statelock);
return (error);
}
@@ -765,7 +724,7 @@ nfs4_check_recov_err(vnode_t *vp, nfs4_op_hint_t op,
int
nfs4_start_fop(mntinfo4_t *mi, vnode_t *vp1, vnode_t *vp2, nfs4_op_hint_t op,
- nfs4_recov_state_t *rsp, bool_t *startrecovp)
+ nfs4_recov_state_t *rsp, bool_t *startrecovp)
{
int error = 0, rerr_cnt;
nfs4_server_t *sp = NULL;
@@ -782,7 +741,7 @@ nfs4_start_fop(mntinfo4_t *mi, vnode_t *vp1, vnode_t *vp2, nfs4_op_hint_t op,
#ifdef DEBUG
if ((fop_caller = tsd_get(nfs4_tsd_key)) != NULL) {
cmn_err(CE_PANIC, "Missing nfs4_end_fop: last caller %p",
- fop_caller);
+ fop_caller);
}
(void) tsd_set(nfs4_tsd_key, caller());
#endif
@@ -863,13 +822,13 @@ get_sp:
if (sp != NULL) {
if (nfs_rw_enter_sig(&sp->s_recovlock, RW_READER,
- mi->mi_flags & MI4_INT)) {
+ mi->mi_flags & MI4_INT)) {
error = EINTR;
goto out;
}
}
if (nfs_rw_enter_sig(&mi->mi_recovlock, RW_READER,
- mi->mi_flags & MI4_INT)) {
+ mi->mi_flags & MI4_INT)) {
if (sp != NULL)
nfs_rw_exit(&sp->s_recovlock);
error = EINTR;
@@ -921,8 +880,8 @@ get_sp:
*/
if (NFS4_VOLATILE_FH(mi) && op != OH_MOUNT) {
if (nfs_rw_enter_sig(&mi->mi_rename_lock,
- op == OH_VFH_RENAME ? RW_WRITER : RW_READER,
- mi->mi_flags & MI4_INT)) {
+ op == OH_VFH_RENAME ? RW_WRITER : RW_READER,
+ mi->mi_flags & MI4_INT)) {
nfs_rw_exit(&mi->mi_recovlock);
if (sp != NULL)
nfs_rw_exit(&sp->s_recovlock);
@@ -985,7 +944,7 @@ out:
*/
int
nfs4_start_op(mntinfo4_t *mi, vnode_t *vp1, vnode_t *vp2,
- nfs4_recov_state_t *rsp)
+ nfs4_recov_state_t *rsp)
{
ASSERT(rsp->rs_num_retry_despite_err == 0);
rsp->rs_num_retry_despite_err = 0;
@@ -1002,7 +961,7 @@ nfs4_start_op(mntinfo4_t *mi, vnode_t *vp1, vnode_t *vp2,
void
nfs4_end_fop(mntinfo4_t *mi, vnode_t *vp1, vnode_t *vp2, nfs4_op_hint_t op,
- nfs4_recov_state_t *rsp, bool_t needs_recov)
+ nfs4_recov_state_t *rsp, bool_t needs_recov)
{
nfs4_server_t *sp = rsp->rs_sp;
rnode4_t *rp = NULL;
@@ -1057,7 +1016,7 @@ nfs4_end_fop(mntinfo4_t *mi, vnode_t *vp1, vnode_t *vp2, nfs4_op_hint_t op,
void
nfs4_end_op(mntinfo4_t *mi, vnode_t *vp1, vnode_t *vp2,
- nfs4_recov_state_t *rsp, bool_t needrecov)
+ nfs4_recov_state_t *rsp, bool_t needrecov)
{
nfs4_end_fop(mi, vp1, vp2, OH_OTHER, rsp, needrecov);
}
@@ -1110,12 +1069,12 @@ wait_for_recovery(mntinfo4_t *mi, nfs4_op_hint_t op_hint)
if (mi->mi_flags & MI4_RECOV_FAIL) {
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "wait_for_recovery: fail since RECOV FAIL"));
+ "wait_for_recovery: fail since RECOV FAIL"));
error = mi->mi_error;
} else if ((mi->mi_vfsp->vfs_flag & VFS_UNMOUNTED) &&
!OH_IS_STATE_RELE(op_hint)) {
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "wait_for_recovery: forced unmount"));
+ "wait_for_recovery: forced unmount"));
error = EIO;
}
@@ -1279,12 +1238,12 @@ nfs4_recov_thread(recov_info_t *recovp)
NFS4_DEBUG(nfs4_client_recov_debug &&
mi->mi_vfsp->vfs_flag & VFS_UNMOUNTED, (CE_NOTE,
- "nfs4_recov_thread: file system has been "
- "unmounted"));
+ "nfs4_recov_thread: file system has been "
+ "unmounted"));
NFS4_DEBUG(nfs4_client_recov_debug &&
zone_status_get(curproc->p_zone) >=
ZONE_IS_SHUTTING_DOWN, (CE_NOTE,
- "nfs4_recov_thread: zone shutting down"));
+ "nfs4_recov_thread: zone shutting down"));
/*
* If the server has lost its state for us and
* the filesystem is unmounted, then the filesystem
@@ -1325,8 +1284,8 @@ nfs4_recov_thread(recov_info_t *recovp)
}
if (!activesrv) {
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "no active fs for server %p",
- (void *)sp));
+ "no active fs for server %p",
+ (void *)sp));
mutex_enter(&mi->mi_lock);
mi->mi_flags |= MI4_RECOV_FAIL;
mi->mi_error = recovp->rc_error;
@@ -1392,9 +1351,9 @@ nfs4_recov_thread(recov_info_t *recovp)
!(mi->mi_flags & MI4_RECOV_FAIL)) {
mutex_exit(&mi->mi_lock);
(void) nfs_rw_enter_sig(&mi->mi_recovlock,
- RW_WRITER, 0);
+ RW_WRITER, 0);
error = nfs4_secinfo_recov(recovp->rc_mi,
- recovp->rc_vp1, recovp->rc_vp2);
+ recovp->rc_vp1, recovp->rc_vp2);
/*
* If error, nothing more can be done, stop
* the recovery.
@@ -1420,7 +1379,7 @@ nfs4_recov_thread(recov_info_t *recovp)
!(mi->mi_flags & MI4_RECOV_FAIL)) {
mutex_exit(&mi->mi_lock);
(void) nfs_rw_enter_sig(&mi->mi_recovlock,
- RW_WRITER, 0);
+ RW_WRITER, 0);
recov_bad_seqid(recovp);
nfs_rw_exit(&mi->mi_recovlock);
} else
@@ -1449,7 +1408,7 @@ nfs4_recov_thread(recov_info_t *recovp)
!(mi->mi_flags & MI4_RECOV_FAIL)) {
mutex_exit(&mi->mi_lock);
(void) nfs_rw_enter_sig(&mi->mi_recovlock,
- RW_WRITER, 0);
+ RW_WRITER, 0);
nfs4_resend_lost_rqsts(recovp, sp);
if (list_head(&mi->mi_lost_state) == NULL) {
/* done */
@@ -1571,7 +1530,7 @@ recov_done(mntinfo4_t *mi, recov_info_t *recovp)
ASSERT(MUTEX_HELD(&mi->mi_lock));
nfs4_queue_event(RE_END, mi, NULL, 0, recovp->rc_vp1,
- recovp->rc_vp2, 0, NULL, 0, TAG_NONE, TAG_NONE, 0, 0);
+ recovp->rc_vp2, 0, NULL, 0, TAG_NONE, TAG_NONE, 0, 0);
mi->mi_recovthread = NULL;
mi->mi_flags &= ~MI4_RECOV_ACTIV;
mi->mi_recovflags &= ~MI4R_SRV_REBOOT;
@@ -1857,9 +1816,9 @@ recov_clientid(recov_info_t *recovp, nfs4_server_t *sp)
tmi = milist[i];
if (tmi != mi) {
(void) nfs_rw_enter_sig(&tmi->mi_recovlock,
- RW_READER, 0);
+ RW_READER, 0);
start_recovery_action(NR_OPENFILES, TRUE, tmi,
- NULL, NULL);
+ NULL, NULL);
nfs_rw_exit(&tmi->mi_recovlock);
}
}
@@ -1981,7 +1940,7 @@ recov_filehandle(nfs4_recov_t action, mntinfo4_t *mi, vnode_t *vp)
needrecov = FALSE;
if (needrecov) {
(void) nfs4_start_recovery(&e, mi, vp,
- NULL, NULL, NULL, OP_LOOKUP, NULL);
+ NULL, NULL, NULL, OP_LOOKUP, NULL);
} else if (e.error != EINTR &&
!NFS4_FRC_UNMT_ERR(e.error, mi->mi_vfsp) &&
(e.error != 0 || e.stat != NFS4_OK)) {
@@ -2056,7 +2015,7 @@ recov_stale(mntinfo4_t *mi, vnode_t *vp)
needrecov = nfs4_needs_recovery(&e, FALSE, vp->v_vfsp);
if (needrecov && (e.error != 0 || e.stat != NFS4ERR_STALE)) {
(void) nfs4_start_recovery(&e, mi, vp,
- NULL, NULL, NULL, OP_GETATTR, NULL);
+ NULL, NULL, NULL, OP_GETATTR, NULL);
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
"recov_stale: error=%d, stat=%d seen on rp %s",
e.error, e.stat, rnode4info(rp)));
@@ -2105,8 +2064,8 @@ recov_stale(mntinfo4_t *mi, vnode_t *vp)
needrecov = nfs4_needs_recovery(&e, FALSE, vp->v_vfsp);
if (needrecov) {
(void) nfs4_start_recovery(&e,
- mi, rootvp, NULL, NULL, NULL,
- OP_GETATTR, NULL);
+ mi, rootvp, NULL, NULL, NULL,
+ OP_GETATTR, NULL);
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
"recov_stale: error=%d, stat=%d seen "
"on rp %s", e.error, e.stat,
@@ -2315,7 +2274,7 @@ relock_file(vnode_t *vp, mntinfo4_t *mi, nfs4_error_t *ep,
*/
static void
reclaim_one_lock(vnode_t *vp, flock64_t *flk, nfs4_error_t *ep,
- int *did_reclaimp)
+ int *did_reclaimp)
{
cred_t *cr;
rnode4_t *rp = VTOR4(vp);
@@ -2340,10 +2299,10 @@ reclaim_one_lock(vnode_t *vp, flock64_t *flk, nfs4_error_t *ep,
mutex_exit(&rp->r_statelock);
nfs4frlock(NFS4_LCK_CTYPE_RECLAIM, vp, F_SETLK, flk,
- FREAD|FWRITE, 0, cr, ep, NULL, did_reclaimp);
+ FREAD|FWRITE, 0, cr, ep, NULL, did_reclaimp);
if (ep->error == 0 && ep->stat == NFS4ERR_FHEXPIRED)
start_recovery_action(NR_FHEXPIRED, TRUE, VTOMI4(vp),
- vp, NULL);
+ vp, NULL);
} while (ep->error == 0 && ep->stat == NFS4ERR_FHEXPIRED);
crfree(cr);
@@ -2417,7 +2376,7 @@ nfs4_free_lost_rqst(nfs4_lost_rqst_t *lrp, nfs4_server_t *sp)
int have_sync_lock;
NFS4_DEBUG(nfs4_lost_rqst_debug,
- (CE_NOTE, "nfs4_free_lost_rqst:"));
+ (CE_NOTE, "nfs4_free_lost_rqst:"));
switch (lrp->lr_op) {
case OP_OPEN:
@@ -2524,7 +2483,7 @@ recov_openfiles(recov_info_t *recovp, nfs4_server_t *sp)
if ((sp->s_flags & (N4S_CB_PINGED | N4S_CB_WAITER)) == 0) {
sp->s_flags |= N4S_CB_WAITER;
(void) cv_timedwait(&sp->wait_cb_null, &sp->s_lock,
- (lbolt+drv_usectohz(N4S_CB_PAUSE_TIME)));
+ (lbolt + drv_usectohz(N4S_CB_PAUSE_TIME)));
}
mutex_exit(&sp->s_lock);
@@ -2535,7 +2494,7 @@ recov_openfiles(recov_info_t *recovp, nfs4_server_t *sp)
nfs4_remap_root(mi, &e, 0);
if (nfs4_needs_recovery(&e, FALSE, mi->mi_vfsp)) {
(void) nfs4_start_recovery(&e, mi, NULL,
- NULL, NULL, NULL, OP_LOOKUP, NULL);
+ NULL, NULL, NULL, OP_LOOKUP, NULL);
}
}
@@ -2568,7 +2527,7 @@ recov_openfiles(recov_info_t *recovp, nfs4_server_t *sp)
if (remap) {
nfs4_remap_file(mi, rep->re_vp,
- NFS4_REMAP_CKATTRS, &e);
+ NFS4_REMAP_CKATTRS, &e);
}
if (e.error == ENOENT || e.stat == NFS4ERR_NOENT) {
/*
@@ -2581,7 +2540,7 @@ recov_openfiles(recov_info_t *recovp, nfs4_server_t *sp)
* problem.
*/
nfs4_fail_recov(rep->re_vp,
- fail_msg, e.error, e.stat);
+ fail_msg, e.error, e.stat);
/*
* We've already handled the error so clear it.
*/
@@ -2597,15 +2556,15 @@ recov_openfiles(recov_info_t *recovp, nfs4_server_t *sp)
for (j = 0; j < rep->re_numosp; j++) {
nfs4_reopen(rep->re_vp, rep->re_osp[j],
- &e, claim, FALSE, TRUE);
+ &e, claim, FALSE, TRUE);
if (e.error != 0 || e.stat != NFS4_OK)
break;
}
if (nfs4_needs_recovery(&e, TRUE,
mi->mi_vfsp)) {
(void) nfs4_start_recovery(&e, mi,
- rep->re_vp, NULL, NULL, NULL,
- OP_OPEN, NULL);
+ rep->re_vp, NULL, NULL, NULL,
+ OP_OPEN, NULL);
break;
}
}
@@ -2618,8 +2577,8 @@ recov_openfiles(recov_info_t *recovp, nfs4_server_t *sp)
if (nfs4_needs_recovery(&e, TRUE, mi->mi_vfsp))
(void) nfs4_start_recovery(&e, mi,
- rep->re_vp, NULL, NULL, NULL, OP_LOCK,
- NULL);
+ rep->re_vp, NULL, NULL, NULL, OP_LOCK,
+ NULL);
if (e.error != 0 || e.stat != NFS4_OK)
break;
}
@@ -2632,9 +2591,9 @@ recov_openfiles(recov_info_t *recovp, nfs4_server_t *sp)
if (remap) {
nfs4_error_t ignore;
nfs4_check_remap(mi, recovp->rc_vp1, NFS4_REMAP_CKATTRS,
- &ignore);
+ &ignore);
nfs4_check_remap(mi, recovp->rc_vp2, NFS4_REMAP_CKATTRS,
- &ignore);
+ &ignore);
}
}
@@ -2707,8 +2666,8 @@ nfs4_resend_lost_rqsts(recov_info_t *recovp, nfs4_server_t *sp)
delay(SEC_TO_TICK(nfs4err_delay_time));
} else {
(void) nfs4_start_recovery(&n4e,
- mi, lrp->lr_dvp, lrp->lr_vp, NULL, NULL,
- lrp->lr_op, NULL);
+ mi, lrp->lr_dvp, lrp->lr_vp, NULL, NULL,
+ lrp->lr_op, NULL);
}
return;
}
@@ -2729,7 +2688,7 @@ nfs4_resend_lost_rqsts(recov_info_t *recovp, nfs4_server_t *sp)
static void
resend_one_op(nfs4_lost_rqst_t *lrp, nfs4_error_t *ep,
- mntinfo4_t *mi, nfs4_server_t *sp)
+ mntinfo4_t *mi, nfs4_server_t *sp)
{
vnode_t *vp;
nfs4_open_stream_t *osp;
@@ -2751,8 +2710,8 @@ resend_one_op(nfs4_lost_rqst_t *lrp, nfs4_error_t *ep,
ASSERT(lrp->lr_osp != NULL);
mutex_enter(&lrp->lr_osp->os_sync_lock);
nfs4_open_downgrade(lrp->lr_dg_acc, lrp->lr_dg_deny,
- lrp->lr_oop, lrp->lr_osp, vp, lrp->lr_cr, lrp,
- ep, NULL, NULL);
+ lrp->lr_oop, lrp->lr_osp, vp, lrp->lr_cr, lrp,
+ ep, NULL, NULL);
mutex_exit(&lrp->lr_osp->os_sync_lock);
nfs4_end_open_seqid_sync(lrp->lr_oop);
break;
@@ -2767,7 +2726,7 @@ resend_one_op(nfs4_lost_rqst_t *lrp, nfs4_error_t *ep,
acc_bits |= OPEN4_SHARE_ACCESS_WRITE;
mutex_exit(&osp->os_sync_lock);
nfs4close_one(vp, osp, cr, acc_bits, lrp, ep,
- CLOSE_RESEND, 0, 0, 0);
+ CLOSE_RESEND, 0, 0, 0);
break;
case OP_LOCK:
case OP_LOCKU:
@@ -2779,7 +2738,7 @@ resend_one_op(nfs4_lost_rqst_t *lrp, nfs4_error_t *ep,
default:
#ifdef DEBUG
cmn_err(CE_PANIC, "resend_one_op: unexpected op: %d",
- lrp->lr_op);
+ lrp->lr_op);
#endif
nfs4_queue_event(RE_LOST_STATE_BAD_OP, mi, NULL,
lrp->lr_op, lrp->lr_vp, lrp->lr_dvp, NFS4_OK, NULL, 0,
@@ -2841,12 +2800,12 @@ done:
static void
close_after_open_resend(vnode_t *vp, cred_t *cr, uint32_t acc_bits,
- nfs4_error_t *ep)
+ nfs4_error_t *ep)
{
for (;;) {
nfs4close_one(vp, NULL, cr, acc_bits, NULL, ep,
- CLOSE_AFTER_RESEND, 0, 0, 0);
+ CLOSE_AFTER_RESEND, 0, 0, 0);
if (ep->error == 0 && ep->stat == NFS4_OK)
break; /* success; done */
if (ep->error != 0 || ep->stat != NFS4ERR_FHEXPIRED)
@@ -2876,7 +2835,7 @@ resend_lock(nfs4_lost_rqst_t *lrp, nfs4_error_t *ep)
lrp->lr_ctype == NFS4_LCK_CTYPE_RESEND);
nfs4frlock(lrp->lr_ctype, vp, F_SETLK,
- lrp->lr_flk, FREAD|FWRITE, 0, lrp->lr_cr, ep, lrp, NULL);
+ lrp->lr_flk, FREAD|FWRITE, 0, lrp->lr_cr, ep, lrp, NULL);
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE, "resend_lock: "
"nfs4frlock for vp %p returned error %d, stat %d",
@@ -3010,7 +2969,7 @@ flush_reinstate(nfs4_lost_rqst_t *lrp)
ASSERT(lrp->lr_vp == vp);
ASSERT(lrp->lr_flk->l_pid == pid);
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE,
- "remove reinstantiation %p", (void *)lrp));
+ "remove reinstantiation %p", (void *)lrp));
list_remove(&mi->mi_lost_state, lrp);
nfs4_free_lost_rqst(lrp, NULL);
}
@@ -3029,7 +2988,7 @@ flush_reinstate(nfs4_lost_rqst_t *lrp)
static void
nfs4_save_lost_rqst(nfs4_lost_rqst_t *lost_rqstp, recov_info_t *recovp,
- nfs4_recov_t *action, mntinfo4_t *mi)
+ nfs4_recov_t *action, mntinfo4_t *mi)
{
nfs4_lost_rqst_t *destp;
@@ -3077,7 +3036,7 @@ nfs4_save_lost_rqst(nfs4_lost_rqst_t *lost_rqstp, recov_info_t *recovp,
} else {
#ifdef DEBUG
cmn_err(CE_PANIC, "nfs4_save_lost_rqst: bad op %d",
- lost_rqstp->lr_op);
+ lost_rqstp->lr_op);
#endif
nfs4_queue_event(RE_LOST_STATE_BAD_OP, mi, NULL,
lost_rqstp->lr_op, lost_rqstp->lr_vp, lost_rqstp->lr_dvp,
@@ -3124,9 +3083,9 @@ nfs4_save_lost_rqst(nfs4_lost_rqst_t *lost_rqstp, recov_info_t *recovp,
void
errs_to_action(recov_info_t *recovp,
- nfs4_server_t *sp, mntinfo4_t *mi, stateid4 *sidp,
- nfs4_lost_rqst_t *lost_rqstp, int unmounted, nfs_opnum4 op,
- nfs4_bseqid_entry_t *bsep)
+ nfs4_server_t *sp, mntinfo4_t *mi, stateid4 *sidp,
+ nfs4_lost_rqst_t *lost_rqstp, int unmounted, nfs_opnum4 op,
+ nfs4_bseqid_entry_t *bsep)
{
nfs4_recov_t action = NR_UNUSED;
bool_t reboot = FALSE;
@@ -3139,7 +3098,7 @@ errs_to_action(recov_info_t *recovp,
recovp->rc_bseqid_rqst = NULL;
try_f = nfs4_try_failover(&recovp->rc_orig_errors) &&
- FAILOVER_MOUNT4(mi);
+ FAILOVER_MOUNT4(mi);
/*
* We start recovery for EINTR only in the lost lock
@@ -3209,9 +3168,9 @@ errs_to_action(recov_info_t *recovp,
action = NR_CLIENTID;
DTRACE_PROBE4(nfs4__expired,
- nfs4_server_t *, sp,
- mntinfo4_t *, mi,
- stateid4 *, sidp, int, op);
+ nfs4_server_t *, sp,
+ mntinfo4_t *, mi,
+ stateid4 *, sidp, int, op);
break;
case NFS4ERR_STALE_CLIENTID:
@@ -3250,7 +3209,7 @@ errs_to_action(recov_info_t *recovp,
recovp->rc_srv_reboot = reboot;
recovp->rc_action = action;
nfs4_queue_fact(RF_ERR, mi, stat, action, op, reboot, NULL, error,
- NULL);
+ NULL);
}
/*
@@ -3378,9 +3337,9 @@ recov_throttle(recov_info_t *recovp, vnode_t *vp)
mutex_enter(&rp->r_statelock);
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "recov_throttle: now: (%d, %ld), last: (%d, %ld)",
- recovp->rc_action, curtime,
- rp->r_recov_act, rp->r_last_recov));
+ "recov_throttle: now: (%d, %ld), last: (%d, %ld)",
+ recovp->rc_action, curtime,
+ rp->r_recov_act, rp->r_last_recov));
if (recovp->rc_action == rp->r_recov_act &&
rp->r_last_recov + recov_err_delay > curtime) {
time_to_wait = rp->r_last_recov + recov_err_delay - curtime;
diff --git a/usr/src/uts/common/fs/nfs/nfs4_rnode.c b/usr/src/uts/common/fs/nfs/nfs4_rnode.c
index 6b67ec086d..35d48fd750 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_rnode.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_rnode.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -147,6 +147,7 @@ static void nfs4_reclaim(void *);
static int isrootfh(nfs4_sharedfh_t *, rnode4_t *);
static void uninit_rnode4(rnode4_t *);
static void destroy_rnode4(rnode4_t *);
+static void r4_stub_set(rnode4_t *, nfs4_stub_type_t);
#ifdef DEBUG
static int r4_check_for_dups = 0; /* Flag to enable dup rnode detection. */
@@ -303,7 +304,7 @@ badrootfh_check(nfs4_sharedfh_t *fh, nfs4_fname_t *nm, mntinfo4_t *mi,
ASSERT(strcmp(s, "..") != 0);
if ((s[0] == '.' && s[1] == '\0') && fh &&
- !SFH4_SAME(mi->mi_rootfh, fh)) {
+ !SFH4_SAME(mi->mi_rootfh, fh)) {
#ifdef DEBUG
nfs4_fhandle_t fhandle;
@@ -316,13 +317,13 @@ badrootfh_check(nfs4_sharedfh_t *fh, nfs4_fname_t *nm, mntinfo4_t *mi,
/* print the bad fh */
fhandle.fh_len = fh->sfh_fh.nfs_fh4_len;
bcopy(fh->sfh_fh.nfs_fh4_val, fhandle.fh_buf,
- fhandle.fh_len);
+ fhandle.fh_len);
nfs4_printfhandle(&fhandle);
/* print mi_rootfh */
fhandle.fh_len = mi->mi_rootfh->sfh_fh.nfs_fh4_len;
bcopy(mi->mi_rootfh->sfh_fh.nfs_fh4_val, fhandle.fh_buf,
- fhandle.fh_len);
+ fhandle.fh_len);
nfs4_printfhandle(&fhandle);
#endif
/* use mi_rootfh instead; fh will be rele by the caller */
@@ -338,6 +339,7 @@ void
r4_do_attrcache(vnode_t *vp, nfs4_ga_res_t *garp, int newnode,
hrtime_t t, cred_t *cr, int index)
{
+ int is_stub;
vattr_t *attr;
/*
* Don't add to attrcache if time overflow, but
@@ -354,9 +356,9 @@ r4_do_attrcache(vnode_t *vp, nfs4_ga_res_t *garp, int newnode,
if (vp->v_type != attr->va_type &&
vp->v_type != VNON && attr->va_type != VNON) {
zcmn_err(VTOMI4(vp)->mi_zone->zone_id, CE_WARN,
- "makenfs4node: type (%d) doesn't "
- "match type of found node at %p (%d)",
- attr->va_type, (void *)vp, vp->v_type);
+ "makenfs4node: type (%d) doesn't "
+ "match type of found node at %p (%d)",
+ attr->va_type, (void *)vp, vp->v_type);
}
#endif
nfs4_attr_cache(vp, garp, t, cr, TRUE, NULL);
@@ -368,39 +370,47 @@ r4_do_attrcache(vnode_t *vp, nfs4_ga_res_t *garp, int newnode,
/*
* Turn this object into a "stub" object if we
- * crossed an underlying server fs boundary. To
- * make this check, during mount we save the
+ * crossed an underlying server fs boundary.
+ * To make this check, during mount we save the
* fsid of the server object being mounted.
* Here we compare this object's server fsid
* with the fsid we saved at mount. If they
* are different, we crossed server fs boundary.
*
- * The stub flag is set (or not) at rnode
+ * The stub type is set (or not) at rnode
* creation time and it never changes for life
- * of rnode.
+ * of the rnode.
*
- * We don't bother with taking r_state_lock
- * to set R4SRVSTUB flag because this is a new
- * rnode and we're holding rtable lock. No other
- * thread could have obtained access to this
- * rnode.
+ * The stub type is also set during RO failover,
+ * nfs4_remap_file().
+ *
+ * This stub will be for a mirror-mount.
+ *
+ * We don't bother with taking r_state_lock to
+ * set the stub type because this is a new rnode
+ * and we're holding the hash bucket r_lock RW_WRITER.
+ * No other thread could have obtained access
+ * to this rnode.
*/
+ is_stub = 0;
if (garp->n4g_fsid_valid) {
- rp->r_srv_fsid = garp->n4g_fsid;
+ fattr4_fsid ga_fsid = garp->n4g_fsid;
+ servinfo4_t *svp = rp->r_server;
- if (vp->v_type == VDIR) {
- servinfo4_t *svp = rp->r_server;
+ rp->r_srv_fsid = ga_fsid;
- (void) nfs_rw_enter_sig(&svp->sv_lock,
- RW_READER, 0);
- if (!FATTR4_FSID_EQ(&garp->n4g_fsid,
- &svp->sv_fsid)) {
- rp->r_flags |= R4SRVSTUB;
- }
- nfs_rw_exit(&svp->sv_lock);
- }
+ (void) nfs_rw_enter_sig(&svp->sv_lock,
+ RW_READER, 0);
+ if (!FATTR4_FSID_EQ(&ga_fsid, &svp->sv_fsid))
+ is_stub = 1;
+ nfs_rw_exit(&svp->sv_lock);
}
+ if (is_stub)
+ r4_stub_mirrormount(rp);
+ else
+ r4_stub_none(rp);
+
/* Can not cache partial attr */
if (attr->va_mask == AT_ALL)
nfs4_attrcache_noinval(vp, garp, t);
@@ -427,8 +437,8 @@ r4_do_attrcache(vnode_t *vp, nfs4_ga_res_t *garp, int newnode,
vnode_t *
makenfs4node_by_fh(nfs4_sharedfh_t *sfh, nfs4_sharedfh_t *psfh,
- nfs4_fname_t **npp, nfs4_ga_res_t *garp,
- mntinfo4_t *mi, cred_t *cr, hrtime_t t)
+ nfs4_fname_t **npp, nfs4_ga_res_t *garp,
+ mntinfo4_t *mi, cred_t *cr, hrtime_t t)
{
vfs_t *vfsp = mi->mi_vfsp;
int newnode = 0;
@@ -480,7 +490,7 @@ makenfs4node_by_fh(nfs4_sharedfh_t *sfh, nfs4_sharedfh_t *psfh,
*/
vnode_t *
makenfs4node(nfs4_sharedfh_t *fh, nfs4_ga_res_t *garp, struct vfs *vfsp,
- hrtime_t t, cred_t *cr, vnode_t *dvp, nfs4_fname_t *nm)
+ hrtime_t t, cred_t *cr, vnode_t *dvp, nfs4_fname_t *nm)
{
vnode_t *vp;
int newnode;
@@ -775,7 +785,7 @@ rp4_addfree(rnode4_t *rp, cred_t *cr)
*/
if (rp->r_deleg_type != OPEN_DELEGATE_NONE) {
(void) nfs4delegreturn(rp,
- NFS4_DR_FORCE|NFS4_DR_PUSH|NFS4_DR_REOPEN);
+ NFS4_DR_FORCE|NFS4_DR_PUSH|NFS4_DR_REOPEN);
}
r4inactive(rp, cr);
@@ -838,7 +848,7 @@ again:
if (rp->r_deleg_type != OPEN_DELEGATE_NONE) {
rw_exit(&rp->r_hashq->r_lock);
(void) nfs4delegreturn(rp,
- NFS4_DR_FORCE|NFS4_DR_PUSH|NFS4_DR_REOPEN);
+ NFS4_DR_FORCE|NFS4_DR_PUSH|NFS4_DR_REOPEN);
goto again;
}
@@ -986,7 +996,6 @@ rp4_rmhash_locked(rnode4_t *rp)
void
rp4_rmhash(rnode4_t *rp)
{
-
rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
rp4_rmhash_locked(rp);
rw_exit(&rp->r_hashq->r_lock);
@@ -1102,7 +1111,7 @@ check_rtable4(struct vfs *vfsp)
if (rp->r_freef == NULL) {
busy = "not on free list";
} else if (nfs4_has_pages(vp) &&
- (rp->r_flags & R4DIRTY)) {
+ (rp->r_flags & R4DIRTY)) {
busy = "dirty pages";
} else if (rp->r_count > 0) {
busy = "r_count > 0";
@@ -1131,7 +1140,7 @@ check_rtable4(struct vfs *vfsp)
/*
* Destroy inactive vnodes from the hash queues which
* belong to this vfs. All of the vnodes should be inactive.
- * It is essential that we destory all rnodes in case of
+ * It is essential that we destroy all rnodes in case of
* forced unmount as well as in normal unmount case.
*/
@@ -1539,7 +1548,6 @@ nfs4_rnode_reclaim(void)
static void
nfs4_reclaim(void *cdrarg)
{
-
#ifdef DEBUG
clstat4_debug.reclaim.value.ui64++;
#endif
@@ -1679,14 +1687,14 @@ r4mkopenlist(mntinfo4_t *mi)
* Add a new open instance to the list
*/
rep = kmem_zalloc(sizeof (*reopenlist),
- KM_SLEEP);
+ KM_SLEEP);
rep->re_next = reopenlist;
reopenlist = rep;
rep->re_vp = vp;
rep->re_osp = kmem_zalloc(
- numosp * sizeof (*(rep->re_osp)),
- KM_SLEEP);
+ numosp * sizeof (*(rep->re_osp)),
+ KM_SLEEP);
rep->re_numosp = numosp;
j = 0;
@@ -1724,7 +1732,7 @@ r4mkopenlist(mntinfo4_t *mi)
*/
if (numosp > 0)
rp->r_deleg_needs_recovery =
- rp->r_deleg_type;
+ rp->r_deleg_type;
}
/* Save the delegation type for use outside the lock */
dtype = rp->r_deleg_type;
@@ -1758,7 +1766,7 @@ r4releopenlist(nfs4_opinst_t *reopenp)
next = rep->re_next;
for (i = 0; i < rep->re_numosp; i++)
- open_stream_rele(rep->re_osp[i], VTOR4(rep->re_vp));
+ open_stream_rele(rep->re_osp[i], VTOR4(rep->re_vp));
VN_RELE(rep->re_vp);
kmem_free(rep->re_osp,
@@ -1840,6 +1848,45 @@ isrootfh(nfs4_sharedfh_t *fh, rnode4_t *rp)
return (isroot);
}
+/*
+ * The r4_stub_* routines assume that the rnode is newly activated, and
+ * that the caller either holds the hash bucket r_lock for this rnode as
+ * RW_WRITER, or holds r_statelock.
+ */
+static void
+r4_stub_set(rnode4_t *rp, nfs4_stub_type_t type)
+{
+ vnode_t *vp = RTOV4(rp);
+ krwlock_t *hash_lock = &rp->r_hashq->r_lock;
+
+ ASSERT(RW_WRITE_HELD(hash_lock) || MUTEX_HELD(&rp->r_statelock));
+
+ rp->r_stub_type = type;
+
+ /*
+ * Safely switch this vnode to the trigger vnodeops.
+ *
+ * Currently, we don't ever switch a trigger vnode back to using
+ * "regular" v4 vnodeops. NFS4_STUB_NONE is only used to note that
+ * a new v4 object is not a trigger, and it will already have the
+ * correct v4 vnodeops by default. So, no "else" case required here.
+ */
+ if (type != NFS4_STUB_NONE)
+ vn_setops(vp, nfs4_trigger_vnodeops);
+}
+
+void
+r4_stub_mirrormount(rnode4_t *rp)
+{
+ r4_stub_set(rp, NFS4_STUB_MIRRORMOUNT);
+}
+
+void
+r4_stub_none(rnode4_t *rp)
+{
+ r4_stub_set(rp, NFS4_STUB_NONE);
+}
+
#ifdef DEBUG
/*
diff --git a/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c
new file mode 100644
index 0000000000..e0b9ce1800
--- /dev/null
+++ b/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c
@@ -0,0 +1,2448 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Support for ephemeral mounts, e.g. mirror-mounts. These mounts are
+ * triggered from a "stub" rnode via a special set of vnodeops.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/cred.h>
+#include <sys/time.h>
+#include <sys/vnode.h>
+#include <sys/vfs.h>
+#include <sys/vfs_opreg.h>
+#include <sys/file.h>
+#include <sys/filio.h>
+#include <sys/uio.h>
+#include <sys/buf.h>
+#include <sys/mman.h>
+#include <sys/pathname.h>
+#include <sys/dirent.h>
+#include <sys/debug.h>
+#include <sys/vmsystm.h>
+#include <sys/fcntl.h>
+#include <sys/flock.h>
+#include <sys/swap.h>
+#include <sys/errno.h>
+#include <sys/strsubr.h>
+#include <sys/sysmacros.h>
+#include <sys/kmem.h>
+#include <sys/mount.h>
+#include <sys/cmn_err.h>
+#include <sys/pathconf.h>
+#include <sys/utsname.h>
+#include <sys/dnlc.h>
+#include <sys/acl.h>
+#include <sys/systeminfo.h>
+#include <sys/policy.h>
+#include <sys/sdt.h>
+#include <sys/list.h>
+#include <sys/stat.h>
+#include <sys/mntent.h>
+
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+
+#include <nfs/nfs.h>
+#include <nfs/nfs_clnt.h>
+#include <nfs/nfs_acl.h>
+#include <nfs/lm.h>
+#include <nfs/nfs4.h>
+#include <nfs/nfs4_kprot.h>
+#include <nfs/rnode4.h>
+#include <nfs/nfs4_clnt.h>
+
+#include <vm/hat.h>
+#include <vm/as.h>
+#include <vm/page.h>
+#include <vm/pvn.h>
+#include <vm/seg.h>
+#include <vm/seg_map.h>
+#include <vm/seg_kpm.h>
+#include <vm/seg_vn.h>
+
+#include <fs/fs_subr.h>
+
+#include <sys/ddi.h>
+#include <sys/int_fmtio.h>
+
+#include <util/string.h>
+
+/*
+ * The automatic unmounter thread stuff!
+ */
+static int nfs4_trigger_thread_timer = 20; /* in seconds */
+
+/*
+ * Just a default....
+ */
+static uint_t nfs4_trigger_mount_to = 240;
+
+typedef struct nfs4_trigger_globals {
+ kmutex_t ntg_forest_lock;
+ uint_t ntg_mount_to;
+ int ntg_thread_started;
+ nfs4_ephemeral_tree_t *ntg_forest;
+} nfs4_trigger_globals_t;
+
+kmutex_t nfs4_ephemeral_thread_lock;
+
+zone_key_t nfs4_ephemeral_key = ZONE_KEY_UNINITIALIZED;
+
+static void nfs4_ephemeral_start_harvester(nfs4_trigger_globals_t *);
+
+/*
+ * Used for ephemeral mounts; contains data either duplicated from
+ * servinfo4_t, or hand-crafted, depending on type of ephemeral mount.
+ *
+ * It's intended that this structure is used solely for ephemeral
+ * mount-type specific data, for passing this data to
+ * nfs4_trigger_nargs_create().
+ */
+typedef struct ephemeral_servinfo {
+ char *esi_hostname;
+ char *esi_netname;
+ char *esi_path;
+ int esi_path_len;
+ int esi_mount_flags;
+ struct netbuf *esi_addr;
+ struct netbuf *esi_syncaddr;
+ struct knetconfig *esi_knconf;
+} ephemeral_servinfo_t;
+
+/*
+ * Collect together the mount-type specific and generic data args.
+ */
+typedef struct domount_args {
+ ephemeral_servinfo_t *dma_esi;
+ char *dma_hostlist; /* comma-sep. for RO failover */
+ struct nfs_args *dma_nargs;
+} domount_args_t;
+
+
+/*
+ * The vnode ops functions for a trigger stub vnode
+ */
+static int nfs4_trigger_open(vnode_t **, int, cred_t *);
+static int nfs4_trigger_getattr(vnode_t *, struct vattr *, int, cred_t *);
+static int nfs4_trigger_setattr(vnode_t *, struct vattr *, int, cred_t *,
+ caller_context_t *);
+static int nfs4_trigger_access(vnode_t *, int, int, cred_t *);
+static int nfs4_trigger_readlink(vnode_t *, struct uio *, cred_t *);
+static int nfs4_trigger_lookup(vnode_t *, char *, vnode_t **,
+ struct pathname *, int, vnode_t *, cred_t *);
+static int nfs4_trigger_create(vnode_t *, char *, struct vattr *,
+ enum vcexcl, int, vnode_t **, cred_t *, int);
+static int nfs4_trigger_remove(vnode_t *, char *, cred_t *);
+static int nfs4_trigger_link(vnode_t *, vnode_t *, char *, cred_t *);
+static int nfs4_trigger_rename(vnode_t *, char *, vnode_t *, char *,
+ cred_t *);
+static int nfs4_trigger_mkdir(vnode_t *, char *, struct vattr *,
+ vnode_t **, cred_t *);
+static int nfs4_trigger_rmdir(vnode_t *, char *, vnode_t *, cred_t *);
+static int nfs4_trigger_symlink(vnode_t *, char *, struct vattr *, char *,
+ cred_t *);
+static int nfs4_trigger_cmp(vnode_t *, vnode_t *);
+
+/*
+ * Regular NFSv4 vnodeops that we need to reference directly
+ */
+extern int nfs4_getattr(vnode_t *, struct vattr *, int, cred_t *);
+extern void nfs4_inactive(vnode_t *, cred_t *);
+extern int nfs4_rwlock(vnode_t *, int, caller_context_t *);
+extern void nfs4_rwunlock(vnode_t *, int, caller_context_t *);
+extern int nfs4_lookup(vnode_t *, char *, vnode_t **,
+ struct pathname *, int, vnode_t *, cred_t *);
+extern int nfs4_pathconf(vnode_t *, int, ulong_t *, cred_t *);
+extern int nfs4_getsecattr(vnode_t *, vsecattr_t *, int, cred_t *);
+extern int nfs4_fid(vnode_t *, fid_t *);
+extern int nfs4_realvp(vnode_t *, vnode_t **);
+
+static int nfs4_trigger_mount(vnode_t *, vnode_t **);
+static int nfs4_trigger_domount(vnode_t *, domount_args_t *, vfs_t **,
+ cred_t *);
+static domount_args_t *nfs4_trigger_domount_args_create(vnode_t *);
+static void nfs4_trigger_domount_args_destroy(domount_args_t *dma,
+ vnode_t *vp);
+static ephemeral_servinfo_t *nfs4_trigger_esi_create(vnode_t *, servinfo4_t *);
+static void nfs4_trigger_esi_destroy(ephemeral_servinfo_t *, vnode_t *);
+static ephemeral_servinfo_t *nfs4_trigger_esi_create_mirrormount(vnode_t *,
+ servinfo4_t *);
+static struct nfs_args *nfs4_trigger_nargs_create(mntinfo4_t *, servinfo4_t *,
+ ephemeral_servinfo_t *);
+static void nfs4_trigger_nargs_destroy(struct nfs_args *);
+static char *nfs4_trigger_create_mntopts(vfs_t *);
+static void nfs4_trigger_destroy_mntopts(char *);
+static int nfs4_trigger_add_mntopt(char *, char *, vfs_t *);
+static enum clnt_stat nfs4_trigger_ping_server(servinfo4_t *, int);
+
+extern int umount2_engine(vfs_t *, int, cred_t *, int);
+
+
+vnodeops_t *nfs4_trigger_vnodeops;
+
+/*
+ * These are the vnodeops that we must define for stub vnodes.
+ *
+ *
+ * Many of the VOPs defined for NFSv4 do not need to be defined here,
+ * for various reasons. This will result in the VFS default function being
+ * used:
+ *
+ * - These VOPs require a previous VOP_OPEN to have occurred. That will have
+ * lost the reference to the stub vnode, meaning these should not be called:
+ * close, read, write, ioctl, readdir, seek.
+ *
+ * - These VOPs are meaningless for vnodes without data pages. Since the
+ * stub vnode is of type VDIR, these should not be called:
+ * space, getpage, putpage, map, addmap, delmap, pageio, fsync.
+ *
+ * - These VOPs are otherwise not applicable, and should not be called:
+ * dump, setsecattr.
+ *
+ *
+ * These VOPs we do not want to define, but nor do we want the VFS default
+ * action. Instead, we specify the VFS error function, with fs_error(), but
+ * note that fs_error() is not actually called. Instead it results in the
+ * use of the error function defined for the particular VOP, in vn_ops_table[]:
+ *
+ * - frlock, dispose, shrlock.
+ *
+ *
+ * These VOPs we define to use the corresponding regular NFSv4 vnodeop.
+ * NOTE: if any of these ops involve an OTW call with the stub FH, then
+ * that call must be wrapped with save_mnt_secinfo()/check_mnt_secinfo()
+ * to protect the security data in the servinfo4_t for the "parent"
+ * filesystem that contains the stub.
+ *
+ * - These VOPs should not trigger a mount, so that "ls -l" does not:
+ * pathconf, getsecattr.
+ *
+ * - These VOPs would not make sense to trigger:
+ * inactive, rwlock, rwunlock, fid, realvp.
+ */
+const fs_operation_def_t nfs4_trigger_vnodeops_template[] = {
+ VOPNAME_OPEN, { .vop_open = nfs4_trigger_open },
+ VOPNAME_GETATTR, { .vop_getattr = nfs4_trigger_getattr },
+ VOPNAME_SETATTR, { .vop_setattr = nfs4_trigger_setattr },
+ VOPNAME_ACCESS, { .vop_access = nfs4_trigger_access },
+ VOPNAME_LOOKUP, { .vop_lookup = nfs4_trigger_lookup },
+ VOPNAME_CREATE, { .vop_create = nfs4_trigger_create },
+ VOPNAME_REMOVE, { .vop_remove = nfs4_trigger_remove },
+ VOPNAME_LINK, { .vop_link = nfs4_trigger_link },
+ VOPNAME_RENAME, { .vop_rename = nfs4_trigger_rename },
+ VOPNAME_MKDIR, { .vop_mkdir = nfs4_trigger_mkdir },
+ VOPNAME_RMDIR, { .vop_rmdir = nfs4_trigger_rmdir },
+ VOPNAME_SYMLINK, { .vop_symlink = nfs4_trigger_symlink },
+ VOPNAME_READLINK, { .vop_readlink = nfs4_trigger_readlink },
+ VOPNAME_INACTIVE, { .vop_inactive = nfs4_inactive },
+ VOPNAME_FID, { .vop_fid = nfs4_fid },
+ VOPNAME_RWLOCK, { .vop_rwlock = nfs4_rwlock },
+ VOPNAME_RWUNLOCK, { .vop_rwunlock = nfs4_rwunlock },
+ VOPNAME_REALVP, { .vop_realvp = nfs4_realvp },
+ VOPNAME_GETSECATTR, { .vop_getsecattr = nfs4_getsecattr },
+ VOPNAME_PATHCONF, { .vop_pathconf = nfs4_pathconf },
+ VOPNAME_FRLOCK, { .error = fs_error },
+ VOPNAME_DISPOSE, { .error = fs_error },
+ VOPNAME_SHRLOCK, { .error = fs_error },
+ VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support },
+ NULL, NULL
+};
+
+/*
+ * Trigger ops for stub vnodes; for mirror mounts, etc.
+ *
+ * The general idea is that a "triggering" op will first call
+ * nfs4_trigger_mount(), which will find out whether a mount has already
+ * been triggered.
+ *
+ * If it has, then nfs4_trigger_mount() sets newvp to the root vnode
+ * of the covering vfs.
+ *
+ * If a mount has not yet been triggered, nfs4_trigger_mount() will do so,
+ * and again set newvp, as above.
+ *
+ * The triggering op may then re-issue the VOP by calling it on newvp.
+ *
+ * Note that some ops may perform custom action, and may or may not need
+ * to trigger a mount.
+ *
+ * Some ops need to call the regular NFSv4 vnodeop for a stub vnode. We
+ * obviously can't do this with VOP_<whatever>, since it's a stub vnode
+ * and that would just recurse. Instead, we call the v4 op directly,
+ * by name. This is OK, since we know that the vnode is for NFSv4,
+ * otherwise it couldn't be a stub.
+ *
+ */
+
+static int
+nfs4_trigger_open(vnode_t **vpp, int flag, cred_t *cr)
+{
+ int error;
+ vnode_t *newvp;
+
+ error = nfs4_trigger_mount(*vpp, &newvp);
+ if (error)
+ return (error);
+
+ /* Release the stub vnode, as we're losing the reference to it */
+ VN_RELE(*vpp);
+
+ /* Give the caller the root vnode of the newly-mounted fs */
+ *vpp = newvp;
+
+ /* return with VN_HELD(newvp) */
+ return (VOP_OPEN(vpp, flag, cr));
+}
+
+/*
+ * For the majority of cases, nfs4_trigger_getattr() will not trigger
+ * a mount. However, if ATTR_TRIGGER is set, we are being informed
+ * that we need to force the mount before we attempt to determine
+ * the attributes. The intent is an atomic operation for security
+ * testing.
+ */
+static int
+nfs4_trigger_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
+{
+ int error;
+
+ if (flags & ATTR_TRIGGER) {
+ vnode_t *newvp;
+
+ error = nfs4_trigger_mount(vp, &newvp);
+ if (error)
+ return (error);
+
+ error = VOP_GETATTR(newvp, vap, flags, cr);
+ VN_RELE(newvp);
+ } else {
+ error = nfs4_getattr(vp, vap, flags, cr);
+ }
+
+ return (error);
+}
+
+static int
+nfs4_trigger_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
+ caller_context_t *ct)
+{
+ int error;
+ vnode_t *newvp;
+
+ error = nfs4_trigger_mount(vp, &newvp);
+ if (error)
+ return (error);
+
+ error = VOP_SETATTR(newvp, vap, flags, cr, ct);
+ VN_RELE(newvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_access(vnode_t *vp, int mode, int flags, cred_t *cr)
+{
+ int error;
+ vnode_t *newvp;
+
+ error = nfs4_trigger_mount(vp, &newvp);
+ if (error)
+ return (error);
+
+ error = VOP_ACCESS(newvp, mode, flags, cr);
+ VN_RELE(newvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
+ int flags, vnode_t *rdir, cred_t *cr)
+{
+ int error;
+ vnode_t *newdvp;
+ rnode4_t *drp = VTOR4(dvp);
+
+ ASSERT(RP_ISSTUB(drp));
+
+ /* for now, we only support mirror-mounts */
+ ASSERT(RP_ISSTUB_MIRRORMOUNT(drp));
+
+ /*
+ * It's not legal to lookup ".." for an fs root, so we mustn't pass
+ * that up. Instead, pass onto the regular op, regardless of whether
+ * we've triggered a mount.
+ */
+ if (strcmp(nm, "..") == 0)
+ return (nfs4_lookup(dvp, nm, vpp, pnp, flags, rdir, cr));
+
+ error = nfs4_trigger_mount(dvp, &newdvp);
+ if (error)
+ return (error);
+
+ error = VOP_LOOKUP(newdvp, nm, vpp, pnp, flags, rdir, cr);
+ VN_RELE(newdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_create(vnode_t *dvp, char *nm, struct vattr *va,
+ enum vcexcl exclusive, int mode, vnode_t **vpp, cred_t *cr,
+ int flags)
+{
+ int error;
+ vnode_t *newdvp;
+
+ error = nfs4_trigger_mount(dvp, &newdvp);
+ if (error)
+ return (error);
+
+ error = VOP_CREATE(newdvp, nm, va, exclusive, mode, vpp, cr, flags);
+ VN_RELE(newdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_remove(vnode_t *dvp, char *nm, cred_t *cr)
+{
+ int error;
+ vnode_t *newdvp;
+
+ error = nfs4_trigger_mount(dvp, &newdvp);
+ if (error)
+ return (error);
+
+ error = VOP_REMOVE(newdvp, nm, cr);
+ VN_RELE(newdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr)
+{
+ int error;
+ vnode_t *newtdvp;
+
+ error = nfs4_trigger_mount(tdvp, &newtdvp);
+ if (error)
+ return (error);
+
+ /*
+ * We don't check whether svp is a stub. Let the NFSv4 code
+ * detect that error, and return accordingly.
+ */
+ error = VOP_LINK(newtdvp, svp, tnm, cr);
+ VN_RELE(newtdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
+ cred_t *cr)
+{
+ int error;
+ vnode_t *newsdvp;
+ rnode4_t *tdrp = VTOR4(tdvp);
+
+ /*
+ * We know that sdvp is a stub, otherwise we would not be here.
+ *
+ * If tdvp is also be a stub, there are two possibilities: it
+ * is either the same stub as sdvp [i.e. VN_CMP(sdvp, tdvp)]
+ * or it is a different stub [!VN_CMP(sdvp, tdvp)].
+ *
+ * In the former case, just trigger sdvp, and treat tdvp as
+ * though it were not a stub.
+ *
+ * In the latter case, it might be a different stub for the
+ * same server fs as sdvp, or for a different server fs.
+ * Regardless, from the client perspective this would still
+ * be a cross-filesystem rename, and should not be allowed,
+ * so return EXDEV, without triggering either mount.
+ */
+ if (RP_ISSTUB(tdrp) && !VN_CMP(sdvp, tdvp))
+ return (EXDEV);
+
+ error = nfs4_trigger_mount(sdvp, &newsdvp);
+ if (error)
+ return (error);
+
+ error = VOP_RENAME(newsdvp, snm, tdvp, tnm, cr);
+
+ VN_RELE(newsdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp,
+ cred_t *cr)
+{
+ int error;
+ vnode_t *newdvp;
+
+ error = nfs4_trigger_mount(dvp, &newdvp);
+ if (error)
+ return (error);
+
+ error = VOP_MKDIR(newdvp, nm, va, vpp, cr);
+ VN_RELE(newdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr)
+{
+ int error;
+ vnode_t *newdvp;
+
+ error = nfs4_trigger_mount(dvp, &newdvp);
+ if (error)
+ return (error);
+
+ error = VOP_RMDIR(newdvp, nm, cdir, cr);
+ VN_RELE(newdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm,
+ cred_t *cr)
+{
+ int error;
+ vnode_t *newdvp;
+
+ error = nfs4_trigger_mount(dvp, &newdvp);
+ if (error)
+ return (error);
+
+ error = VOP_SYMLINK(newdvp, lnm, tva, tnm, cr);
+ VN_RELE(newdvp);
+
+ return (error);
+}
+
+static int
+nfs4_trigger_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr)
+{
+ int error;
+ vnode_t *newvp;
+
+ error = nfs4_trigger_mount(vp, &newvp);
+ if (error)
+ return (error);
+
+ error = VOP_READLINK(newvp, uiop, cr);
+ VN_RELE(newvp);
+
+ return (error);
+}
+
+/* end of trigger vnode ops */
+
+
+/*
+ * Mount upon a trigger vnode; for mirror-mounts, etc.
+ *
+ * The mount may have already occurred, via another thread. If not,
+ * assemble the location information - which may require fetching - and
+ * perform the mount.
+ *
+ * Sets newvp to be the root of the fs that is now covering vp. Note
+ * that we return with VN_HELD(*newvp).
+ *
+ * The caller is responsible for passing the VOP onto the covering fs.
+ */
+static int
+nfs4_trigger_mount(vnode_t *vp, vnode_t **newvpp)
+{
+ int error;
+ vfs_t *vfsp;
+ rnode4_t *rp = VTOR4(vp);
+ mntinfo4_t *mi = VTOMI4(vp);
+ domount_args_t *dma;
+
+ nfs4_ephemeral_tree_t *net;
+
+ bool_t must_unlock = FALSE;
+ bool_t is_building = FALSE;
+
+ cred_t *zcred;
+
+ nfs4_trigger_globals_t *ntg;
+
+ zone_t *zone = curproc->p_zone;
+
+ ASSERT(RP_ISSTUB(rp));
+
+ /* for now, we only support mirror-mounts */
+ ASSERT(RP_ISSTUB_MIRRORMOUNT(rp));
+
+ *newvpp = NULL;
+
+ /*
+ * Has the mount already occurred?
+ */
+ error = vn_vfsrlock_wait(vp);
+ if (error)
+ goto done;
+ vfsp = vn_mountedvfs(vp);
+ if (vfsp != NULL) {
+ /* the mount has already occurred */
+ error = VFS_ROOT(vfsp, newvpp);
+ if (!error) {
+ /* need to update the reference time */
+ mutex_enter(&mi->mi_lock);
+ if (mi->mi_ephemeral)
+ mi->mi_ephemeral->ne_ref_time =
+ gethrestime_sec();
+ mutex_exit(&mi->mi_lock);
+ }
+
+ vn_vfsunlock(vp);
+ goto done;
+ }
+ vn_vfsunlock(vp);
+
+ ntg = zone_getspecific(nfs4_ephemeral_key, zone);
+ ASSERT(ntg != NULL);
+
+ mutex_enter(&mi->mi_lock);
+
+ /*
+ * We need to lock down the ephemeral tree.
+ */
+ if (mi->mi_ephemeral_tree == NULL) {
+ net = kmem_zalloc(sizeof (*net), KM_SLEEP);
+ mutex_init(&net->net_tree_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&net->net_cnt_lock, NULL, MUTEX_DEFAULT, NULL);
+ net->net_refcnt = 1;
+ net->net_status = NFS4_EPHEMERAL_TREE_BUILDING;
+ is_building = TRUE;
+
+ /*
+ * We need to add it to the zone specific list for
+ * automatic unmounting and harvesting of deadwood.
+ */
+ mutex_enter(&ntg->ntg_forest_lock);
+ if (ntg->ntg_forest != NULL)
+ net->net_next = ntg->ntg_forest;
+ ntg->ntg_forest = net;
+ mutex_exit(&ntg->ntg_forest_lock);
+
+ /*
+ * No lock order confusion with mi_lock because no
+ * other node could have grabbed net_tree_lock.
+ */
+ mutex_enter(&net->net_tree_lock);
+ mi->mi_ephemeral_tree = net;
+ net->net_mount = mi;
+ mutex_exit(&mi->mi_lock);
+ } else {
+ net = mi->mi_ephemeral_tree;
+ mutex_exit(&mi->mi_lock);
+
+ mutex_enter(&net->net_cnt_lock);
+ net->net_refcnt++;
+ mutex_exit(&net->net_cnt_lock);
+
+ /*
+ * Note that we do not do any checks to
+ * see if the parent has been nuked.
+ * We count on the vfs layer having protected
+ * us from feet shooters.
+ */
+ mutex_enter(&net->net_tree_lock);
+ }
+
+ mutex_enter(&net->net_cnt_lock);
+ net->net_status |= NFS4_EPHEMERAL_TREE_MOUNTING;
+ mutex_exit(&net->net_cnt_lock);
+
+ must_unlock = TRUE;
+
+ dma = nfs4_trigger_domount_args_create(vp);
+ if (dma == NULL) {
+ error = EINVAL;
+ goto done;
+ }
+
+ /*
+ * Need to be root for this call to make mount work.
+ * Note that since we define mirror mounts to work
+ * for any user, we allow the mount to proceed. And
+ * we realize that the server will perform security
+ * checks to make sure that the client is allowed
+ * access. Finally, once the mount takes place,
+ * directory permissions will ensure that the
+ * content is secure.
+ */
+ zcred = zone_get_kcred(getzoneid());
+ ASSERT(zcred != NULL);
+
+ error = nfs4_trigger_domount(vp, dma, &vfsp, zcred);
+ nfs4_trigger_domount_args_destroy(dma, vp);
+
+ crfree(zcred);
+
+ if (!error)
+ error = VFS_ROOT(vfsp, newvpp);
+done:
+ if (must_unlock) {
+ mutex_enter(&net->net_cnt_lock);
+ net->net_status &= ~NFS4_EPHEMERAL_TREE_MOUNTING;
+ if (is_building)
+ net->net_status &= ~NFS4_EPHEMERAL_TREE_BUILDING;
+ net->net_refcnt--;
+ mutex_exit(&net->net_cnt_lock);
+
+ mutex_exit(&net->net_tree_lock);
+ }
+
+ if (!error && (newvpp == NULL || *newvpp == NULL))
+ error = ENOSYS;
+
+ return (error);
+}
+
+/*
+ * Collect together both the generic & mount-type specific args.
+ */
+static domount_args_t *
+nfs4_trigger_domount_args_create(vnode_t *vp)
+{
+ int nointr;
+ char *hostlist;
+ servinfo4_t *svp;
+ struct nfs_args *nargs, *nargs_head;
+ enum clnt_stat status;
+ ephemeral_servinfo_t *esi, *esi_first;
+ domount_args_t *dma;
+ mntinfo4_t *mi = VTOMI4(vp);
+
+ nointr = !(mi->mi_flags & MI4_INT);
+ hostlist = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
+
+ svp = mi->mi_curr_serv;
+ /* check if the current server is responding */
+ status = nfs4_trigger_ping_server(svp, nointr);
+ if (status == RPC_SUCCESS) {
+ esi_first = nfs4_trigger_esi_create(vp, svp);
+ if (esi_first == NULL) {
+ kmem_free(hostlist, MAXPATHLEN);
+ return (NULL);
+ }
+
+ (void) strlcpy(hostlist, esi_first->esi_hostname, MAXPATHLEN);
+
+ nargs_head = nfs4_trigger_nargs_create(mi, svp, esi_first);
+ } else {
+ /* current server did not respond */
+ esi_first = NULL;
+ nargs_head = NULL;
+ }
+ nargs = nargs_head;
+
+ /*
+ * NFS RO failover.
+ *
+ * If we have multiple servinfo4 structures, linked via sv_next,
+ * we must create one nfs_args for each, linking the nfs_args via
+ * nfs_ext_u.nfs_extB.next.
+ *
+ * We need to build a corresponding esi for each, too, but that is
+ * used solely for building nfs_args, and may be immediately
+ * discarded, as domount() requires the info from just one esi,
+ * but all the nfs_args.
+ *
+ * Currently, the NFS mount code will hang if not all servers
+ * requested are available. To avoid that, we need to ping each
+ * server, here, and remove it from the list if it is not
+ * responding. This has the side-effect of that server then
+ * being permanently unavailable for this failover mount, even if
+ * it recovers. That's unfortunate, but the best we can do until
+ * the mount code path is fixed.
+ */
+
+ /*
+ * If the current server was down, loop indefinitely until we find
+ * at least one responsive server.
+ */
+ do {
+ /* no locking needed for sv_next; it is only set at fs mount */
+ for (svp = mi->mi_servers; svp != NULL; svp = svp->sv_next) {
+ struct nfs_args *next;
+
+ /*
+ * nargs_head: the head of the nfs_args list
+ * nargs: the current tail of the list
+ * next: the newly-created element to be added
+ */
+
+ /*
+ * We've already tried the current server, above;
+ * if it was responding, we have already included it
+ * and it may now be ignored.
+ *
+ * Otherwise, try it again, since it may now have
+ * recovered.
+ */
+ if (svp == mi->mi_curr_serv && esi_first != NULL)
+ continue;
+
+ (void) nfs_rw_enter_sig(&svp->sv_lock, RW_READER, 0);
+ if (svp->sv_flags & SV4_NOTINUSE) {
+ nfs_rw_exit(&svp->sv_lock);
+ continue;
+ }
+ nfs_rw_exit(&svp->sv_lock);
+
+ /* check if the server is responding */
+ status = nfs4_trigger_ping_server(svp, nointr);
+ /* if the server did not respond, ignore it */
+ if (status != RPC_SUCCESS)
+ continue;
+
+ esi = nfs4_trigger_esi_create(vp, svp);
+ if (esi == NULL)
+ continue;
+
+ /*
+ * If the original current server (mi_curr_serv)
+ * was down when when we first tried it,
+ * (i.e. esi_first == NULL),
+ * we select this new server (svp) to be the server
+ * that we will actually contact (esi_first).
+ *
+ * Note that it's possible that mi_curr_serv == svp,
+ * if that mi_curr_serv was down but has now recovered.
+ */
+ next = nfs4_trigger_nargs_create(mi, svp, esi);
+ if (esi_first == NULL) {
+ ASSERT(nargs == NULL);
+ ASSERT(nargs_head == NULL);
+ nargs_head = next;
+ esi_first = esi;
+ (void) strlcpy(hostlist,
+ esi_first->esi_hostname, MAXPATHLEN);
+ } else {
+ ASSERT(nargs_head != NULL);
+ nargs->nfs_ext_u.nfs_extB.next = next;
+ (void) strlcat(hostlist, ",", MAXPATHLEN);
+ (void) strlcat(hostlist, esi->esi_hostname,
+ MAXPATHLEN);
+ /* esi was only needed for hostname & nargs */
+ nfs4_trigger_esi_destroy(esi, vp);
+ }
+
+ nargs = next;
+ }
+
+ /* if we've had no response at all, wait a second */
+ if (esi_first == NULL)
+ delay(drv_usectohz(1000000));
+
+ } while (esi_first == NULL);
+ ASSERT(nargs_head != NULL);
+
+ dma = kmem_zalloc(sizeof (domount_args_t), KM_SLEEP);
+ dma->dma_esi = esi_first;
+ dma->dma_hostlist = hostlist;
+ dma->dma_nargs = nargs_head;
+
+ return (dma);
+}
+
+static void
+nfs4_trigger_domount_args_destroy(domount_args_t *dma, vnode_t *vp)
+{
+ if (dma != NULL) {
+ if (dma->dma_esi != NULL && vp != NULL)
+ nfs4_trigger_esi_destroy(dma->dma_esi, vp);
+
+ if (dma->dma_hostlist != NULL)
+ kmem_free(dma->dma_hostlist, MAXPATHLEN);
+
+ if (dma->dma_nargs != NULL) {
+ struct nfs_args *nargs = dma->dma_nargs;
+
+ do {
+ struct nfs_args *next =
+ nargs->nfs_ext_u.nfs_extB.next;
+
+ nfs4_trigger_nargs_destroy(nargs);
+ nargs = next;
+ } while (nargs != NULL);
+ }
+
+ kmem_free(dma, sizeof (domount_args_t));
+ }
+}
+
+/*
+ * The ephemeral_servinfo_t struct contains basic information we will need to
+ * perform the mount. Whilst the structure is generic across different
+ * types of ephemeral mount, the way we gather its contents differs.
+ */
+static ephemeral_servinfo_t *
+nfs4_trigger_esi_create(vnode_t *vp, servinfo4_t *svp)
+{
+ ephemeral_servinfo_t *esi;
+ rnode4_t *rp = VTOR4(vp);
+
+ ASSERT(RP_ISSTUB(rp));
+
+ /* Call the ephemeral type-specific routine */
+ if (RP_ISSTUB_MIRRORMOUNT(rp))
+ esi = nfs4_trigger_esi_create_mirrormount(vp, svp);
+ else
+ esi = NULL;
+
+ /* for now, we only support mirror-mounts */
+ ASSERT(esi != NULL);
+
+ return (esi);
+}
+
+static void
+nfs4_trigger_esi_destroy(ephemeral_servinfo_t *esi, vnode_t *vp)
+{
+ rnode4_t *rp = VTOR4(vp);
+
+ ASSERT(RP_ISSTUB(rp));
+
+ /* for now, we only support mirror-mounts */
+ ASSERT(RP_ISSTUB_MIRRORMOUNT(rp));
+
+ /* Currently, no need for an ephemeral type-specific routine */
+
+ /*
+ * The contents of ephemeral_servinfo_t goes into nfs_args,
+ * and will be handled by nfs4_trigger_nargs_destroy().
+ * We need only free the structure itself.
+ */
+ if (esi != NULL)
+ kmem_free(esi, sizeof (ephemeral_servinfo_t));
+}
+
+/*
+ * Some of this may turn out to be common with other ephemeral types,
+ * in which case it should be moved to nfs4_trigger_esi_create(), or a
+ * common function called.
+ */
+static ephemeral_servinfo_t *
+nfs4_trigger_esi_create_mirrormount(vnode_t *vp, servinfo4_t *svp)
+{
+ char *stubpath;
+ struct knetconfig *sikncp, *svkncp;
+ struct netbuf *bufp;
+ ephemeral_servinfo_t *esi;
+
+ esi = kmem_zalloc(sizeof (ephemeral_servinfo_t), KM_SLEEP);
+
+ /* initially set to be our type of ephemeral mount; may be added to */
+ esi->esi_mount_flags = NFSMNT_MIRRORMOUNT;
+
+ /*
+ * We're copying info from the stub rnode's servinfo4, but
+ * we must create new copies, not pointers, since this information
+ * is to be associated with the new mount, which will be
+ * unmounted (and its structures freed) separately
+ */
+
+ /*
+ * Sizes passed to kmem_[z]alloc here must match those freed
+ * in nfs4_free_args()
+ */
+
+ /*
+ * We hold sv_lock across kmem_zalloc() calls that may sleep, but this
+ * is difficult to avoid: as we need to read svp to calculate the
+ * sizes to be allocated.
+ */
+ (void) nfs_rw_enter_sig(&svp->sv_lock, RW_READER, 0);
+
+ esi->esi_hostname = kmem_zalloc(strlen(svp->sv_hostname) + 1, KM_SLEEP);
+ (void) strcat(esi->esi_hostname, svp->sv_hostname);
+
+ esi->esi_addr = kmem_zalloc(sizeof (struct netbuf), KM_SLEEP);
+ bufp = esi->esi_addr;
+ bufp->len = svp->sv_addr.len;
+ bufp->maxlen = svp->sv_addr.maxlen;
+ bufp->buf = kmem_zalloc(bufp->len, KM_SLEEP);
+ bcopy(svp->sv_addr.buf, bufp->buf, bufp->len);
+
+ esi->esi_knconf = kmem_zalloc(sizeof (*esi->esi_knconf), KM_SLEEP);
+ sikncp = esi->esi_knconf;
+ svkncp = svp->sv_knconf;
+ sikncp->knc_semantics = svkncp->knc_semantics;
+ sikncp->knc_protofmly = (caddr_t)kmem_zalloc(KNC_STRSIZE, KM_SLEEP);
+ (void) strcat((char *)sikncp->knc_protofmly,
+ (char *)svkncp->knc_protofmly);
+ sikncp->knc_proto = (caddr_t)kmem_zalloc(KNC_STRSIZE, KM_SLEEP);
+ (void) strcat((char *)sikncp->knc_proto, (char *)svkncp->knc_proto);
+ sikncp->knc_rdev = svkncp->knc_rdev;
+
+ /*
+ * Used when AUTH_DH is negotiated.
+ *
+ * This is ephemeral mount-type specific, since it contains the
+ * server's time-sync syncaddr.
+ */
+ if (svp->sv_dhsec) {
+ struct netbuf *bufp;
+ sec_data_t *sdata;
+ dh_k4_clntdata_t *data;
+
+ sdata = svp->sv_dhsec;
+ data = (dh_k4_clntdata_t *)sdata->data;
+ ASSERT(sdata->rpcflavor == AUTH_DH);
+
+ bufp = kmem_zalloc(sizeof (struct netbuf), KM_SLEEP);
+ bufp->len = data->syncaddr.len;
+ bufp->maxlen = data->syncaddr.maxlen;
+ bufp->buf = kmem_zalloc(bufp->len, KM_SLEEP);
+ bcopy(data->syncaddr.buf, bufp->buf, bufp->len);
+ esi->esi_syncaddr = bufp;
+
+ if (data->netname != NULL) {
+ int nmlen = data->netnamelen;
+
+ /*
+ * We need to copy from a dh_k4_clntdata_t
+ * netname/netnamelen pair to a NUL-terminated
+ * netname string suitable for putting in nfs_args,
+ * where the latter has no netnamelen field.
+ */
+ esi->esi_netname = kmem_zalloc(nmlen + 1, KM_SLEEP);
+ bcopy(data->netname, esi->esi_netname, nmlen);
+ }
+ } else {
+ esi->esi_syncaddr = NULL;
+ esi->esi_netname = NULL;
+ }
+
+ stubpath = fn_path(VTOSV(vp)->sv_name);
+ /* step over initial '.', to avoid e.g. sv_path: "/tank./ws" */
+ ASSERT(*stubpath == '.');
+ stubpath += 1;
+
+ /* for nfs_args->fh */
+ esi->esi_path_len = strlen(svp->sv_path) + strlen(stubpath) + 1;
+ esi->esi_path = kmem_zalloc(esi->esi_path_len, KM_SLEEP);
+ (void) strcat(esi->esi_path, svp->sv_path);
+ (void) strcat(esi->esi_path, stubpath);
+
+ stubpath -= 1;
+ /* stubpath allocated by fn_path() */
+ kmem_free(stubpath, strlen(stubpath) + 1);
+
+ nfs_rw_exit(&svp->sv_lock);
+
+ return (esi);
+}
+
+/*
+ * Assemble the args, and call the generic VFS mount function to
+ * finally perform the ephemeral mount.
+ */
+static int
+nfs4_trigger_domount(vnode_t *stubvp, domount_args_t *dma, vfs_t **vfsp,
+ cred_t *cr)
+{
+ struct mounta *uap;
+ char *mntpt, *orig_path, *path;
+ const char *orig_mntpt;
+ int retval;
+ int mntpt_len;
+ int spec_len;
+ zone_t *zone = curproc->p_zone;
+ bool_t has_leading_slash;
+
+ vfs_t *stubvfsp = stubvp->v_vfsp;
+ ephemeral_servinfo_t *esi = dma->dma_esi;
+ struct nfs_args *nargs = dma->dma_nargs;
+
+ /* first, construct the mount point for the ephemeral mount */
+ orig_path = path = fn_path(VTOSV(stubvp)->sv_name);
+ orig_mntpt = (char *)refstr_value(stubvfsp->vfs_mntpt);
+
+ if (*orig_path == '.')
+ orig_path++;
+
+ /*
+ * Get rid of zone's root path
+ */
+ if (zone != global_zone) {
+ /*
+ * -1 for trailing '/' and -1 for EOS.
+ */
+ if (strncmp(zone->zone_rootpath, orig_mntpt,
+ zone->zone_rootpathlen - 1) == 0) {
+ orig_mntpt += (zone->zone_rootpathlen - 2);
+ }
+ }
+
+ mntpt_len = strlen(orig_mntpt) + strlen(orig_path);
+ mntpt = kmem_zalloc(mntpt_len + 1, KM_SLEEP);
+ (void) strcat(mntpt, orig_mntpt);
+ (void) strcat(mntpt, orig_path);
+
+ kmem_free(path, strlen(path) + 1);
+ path = esi->esi_path;
+ if (*path == '.')
+ path++;
+ if (path[0] == '/' && path[1] == '/')
+ path++;
+ has_leading_slash = (*path == '/');
+
+ spec_len = strlen(dma->dma_hostlist);
+ spec_len += strlen(path);
+
+ /* We are going to have to add this in */
+ if (!has_leading_slash)
+ spec_len++;
+
+ /* We need to get the ':' for dma_hostlist:esi_path */
+ spec_len++;
+
+ uap = kmem_zalloc(sizeof (struct mounta), KM_SLEEP);
+ uap->spec = kmem_zalloc(spec_len + 1, KM_SLEEP);
+ (void) snprintf(uap->spec, spec_len + 1, "%s:%s%s", dma->dma_hostlist,
+ has_leading_slash ? "" : "/", path);
+
+ uap->dir = mntpt;
+
+ uap->flags = MS_SYSSPACE | MS_DATA;
+ /* fstype-independent mount options not covered elsewhere */
+ /* copy parent's mount(1M) "-m" flag */
+ if (stubvfsp->vfs_flag & VFS_NOMNTTAB)
+ uap->flags |= MS_NOMNTTAB;
+
+ uap->fstype = MNTTYPE_NFS4;
+ uap->dataptr = (char *)nargs;
+ /* not needed for MS_SYSSPACE */
+ uap->datalen = 0;
+
+ /* use optptr to pass in extra mount options */
+ uap->flags |= MS_OPTIONSTR;
+ uap->optptr = nfs4_trigger_create_mntopts(stubvfsp);
+ if (uap->optptr == NULL) {
+ retval = EINVAL;
+ goto done;
+ }
+ /* domount() expects us to count the trailing NUL */
+ uap->optlen = strlen(uap->optptr) + 1;
+
+ retval = domount(NULL, uap, stubvp, cr, vfsp);
+ if (retval == 0)
+ VFS_RELE(*vfsp);
+done:
+ if (uap->optptr)
+ nfs4_trigger_destroy_mntopts(uap->optptr);
+
+ kmem_free(uap->spec, spec_len + 1);
+ kmem_free(uap, sizeof (struct mounta));
+ kmem_free(mntpt, mntpt_len + 1);
+
+ return (retval);
+}
+
+/*
+ * Build an nfs_args structure for passing to domount().
+ *
+ * Ephemeral mount-type specific data comes from the ephemeral_servinfo_t;
+ * generic data - common to all ephemeral mount types - is read directly
+ * from the parent mount's servinfo4_t and mntinfo4_t, via the stub vnode.
+ */
+static struct nfs_args *
+nfs4_trigger_nargs_create(mntinfo4_t *mi, servinfo4_t *svp,
+ ephemeral_servinfo_t *esi)
+{
+ sec_data_t *secdata;
+ struct nfs_args *nargs;
+
+ /* setup the nfs args */
+ nargs = kmem_zalloc(sizeof (struct nfs_args), KM_SLEEP);
+
+ (void) nfs_rw_enter_sig(&svp->sv_lock, RW_READER, 0);
+
+ nargs->addr = esi->esi_addr;
+
+ /* for AUTH_DH by negotiation */
+ if (esi->esi_syncaddr || esi->esi_netname) {
+ nargs->flags |= NFSMNT_SECURE;
+ nargs->syncaddr = esi->esi_syncaddr;
+ nargs->netname = esi->esi_netname;
+ }
+
+ nargs->flags |= NFSMNT_KNCONF;
+ nargs->knconf = esi->esi_knconf;
+ nargs->flags |= NFSMNT_HOSTNAME;
+ nargs->hostname = esi->esi_hostname;
+ nargs->fh = esi->esi_path;
+
+ /* general mount settings, all copied from parent mount */
+ mutex_enter(&mi->mi_lock);
+
+ if (!(mi->mi_flags & MI4_HARD))
+ nargs->flags |= NFSMNT_SOFT;
+
+ nargs->flags |= NFSMNT_WSIZE | NFSMNT_RSIZE | NFSMNT_TIMEO |
+ NFSMNT_RETRANS;
+ nargs->wsize = mi->mi_stsize;
+ nargs->rsize = mi->mi_tsize;
+ nargs->timeo = mi->mi_timeo;
+ nargs->retrans = mi->mi_retrans;
+
+ if (mi->mi_flags & MI4_INT)
+ nargs->flags |= NFSMNT_INT;
+ if (mi->mi_flags & MI4_NOAC)
+ nargs->flags |= NFSMNT_NOAC;
+
+ nargs->flags |= NFSMNT_ACREGMIN | NFSMNT_ACREGMAX | NFSMNT_ACDIRMIN |
+ NFSMNT_ACDIRMAX;
+ nargs->acregmin = HR2SEC(mi->mi_acregmin);
+ nargs->acregmax = HR2SEC(mi->mi_acregmax);
+ nargs->acdirmin = HR2SEC(mi->mi_acdirmin);
+ nargs->acdirmax = HR2SEC(mi->mi_acdirmax);
+
+ if (mi->mi_flags & MI4_NOCTO)
+ nargs->flags |= NFSMNT_NOCTO;
+ if (mi->mi_flags & MI4_GRPID)
+ nargs->flags |= NFSMNT_GRPID;
+ if (mi->mi_flags & MI4_LLOCK)
+ nargs->flags |= NFSMNT_LLOCK;
+ if (mi->mi_flags & MI4_NOPRINT)
+ nargs->flags |= NFSMNT_NOPRINT;
+ if (mi->mi_flags & MI4_DIRECTIO)
+ nargs->flags |= NFSMNT_DIRECTIO;
+ if (mi->mi_flags & MI4_PUBLIC)
+ nargs->flags |= NFSMNT_PUBLIC;
+
+ mutex_exit(&mi->mi_lock);
+
+ /* add any specific flags for this type of ephemeral mount */
+ nargs->flags |= esi->esi_mount_flags;
+
+ /*
+ * Security data & negotiation policy.
+ *
+ * We need to preserve the parent mount's preference for security
+ * negotiation, translating SV4_TRYSECDEFAULT -> NFSMNT_SECDEFAULT.
+ *
+ * If SV4_TRYSECDEFAULT is not set, that indicates that a specific
+ * security flavour was requested, with data in sv_secdata, and that
+ * no negotiation should occur. If this specified flavour fails, that's
+ * it. We will copy sv_secdata, and not set NFSMNT_SECDEFAULT.
+ *
+ * If SV4_TRYSECDEFAULT is set, then we start with a passed-in
+ * default flavour, in sv_secdata, but then negotiate a new flavour.
+ * Possible flavours are recorded in an array in sv_secinfo, with
+ * currently in-use flavour pointed to by sv_currsec.
+ *
+ * If sv_currsec is set, i.e. if negotiation has already occurred,
+ * we will copy sv_currsec. Otherwise, copy sv_secdata. Regardless,
+ * we will set NFSMNT_SECDEFAULT, to enable negotiation.
+ */
+ if (svp->sv_flags & SV4_TRYSECDEFAULT) {
+ /* enable negotiation for ephemeral mount */
+ nargs->flags |= NFSMNT_SECDEFAULT;
+
+ /*
+ * As a starting point for negotiation, copy parent
+ * mount's negotiated flavour (sv_currsec) if available,
+ * or its passed-in flavour (sv_secdata) if not.
+ */
+ if (svp->sv_currsec != NULL)
+ secdata = copy_sec_data(svp->sv_currsec);
+ else if (svp->sv_secdata != NULL)
+ secdata = copy_sec_data(svp->sv_secdata);
+ else
+ secdata = NULL;
+ } else {
+ /* do not enable negotiation; copy parent's passed-in flavour */
+ if (svp->sv_secdata != NULL)
+ secdata = copy_sec_data(svp->sv_secdata);
+ else
+ secdata = NULL;
+ }
+
+ nfs_rw_exit(&svp->sv_lock);
+
+ nargs->flags |= NFSMNT_NEWARGS;
+ nargs->nfs_args_ext = NFS_ARGS_EXTB;
+ nargs->nfs_ext_u.nfs_extB.secdata = secdata;
+
+ /* for NFS RO failover; caller will set if necessary */
+ nargs->nfs_ext_u.nfs_extB.next = NULL;
+
+ return (nargs);
+}
+
+static void
+nfs4_trigger_nargs_destroy(struct nfs_args *nargs)
+{
+ /*
+ * Either the mount failed, in which case the data is not needed, or
+ * nfs4_mount() has either taken copies of what it needs or,
+ * where it has merely copied the ptr, it has set *our* ptr to NULL,
+ * whereby nfs4_free_args() will ignore it.
+ */
+ nfs4_free_args(nargs);
+ kmem_free(nargs, sizeof (struct nfs_args));
+}
+
+/*
+ * When we finally get into the mounting, we need to add this
+ * node to the ephemeral tree.
+ *
+ * This is called from nfs4_mount().
+ */
+void
+nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp)
+{
+ mntinfo4_t *mi_parent;
+ nfs4_ephemeral_t *eph;
+ nfs4_ephemeral_tree_t *net;
+
+ nfs4_ephemeral_t *prior;
+ nfs4_ephemeral_t *child;
+
+ nfs4_ephemeral_t *peer;
+
+ nfs4_trigger_globals_t *ntg;
+ zone_t *zone = curproc->p_zone;
+
+ mi_parent = VTOMI4(mvp);
+
+ /*
+ * Get this before grabbing anything else!
+ */
+ ntg = zone_getspecific(nfs4_ephemeral_key, zone);
+ if (!ntg->ntg_thread_started) {
+ nfs4_ephemeral_start_harvester(ntg);
+ }
+
+ mutex_enter(&mi_parent->mi_lock);
+ mutex_enter(&mi->mi_lock);
+
+ /*
+ * We need to tack together the ephemeral mount
+ * with this new mntinfo.
+ */
+ eph = kmem_zalloc(sizeof (*eph), KM_SLEEP);
+ eph->ne_mount = mi;
+ eph->ne_ref_time = gethrestime_sec();
+
+ /*
+ * We need to tell the ephemeral mount when
+ * to time out.
+ */
+ eph->ne_mount_to = ntg->ntg_mount_to;
+
+ mi->mi_flags |= MI4_EPHEMERAL;
+ mi->mi_ephemeral = eph;
+
+ net = mi->mi_ephemeral_tree =
+ mi_parent->mi_ephemeral_tree;
+ ASSERT(net != NULL);
+
+ /*
+ * If the enclosing mntinfo4 is also ephemeral,
+ * then we need to point to its enclosing parent.
+ * Else the enclosing mntinfo4 is the enclosing parent.
+ *
+ * We also need to weave this ephemeral node
+ * into the tree.
+ */
+ if (mi_parent->mi_flags & MI4_EPHEMERAL) {
+ /*
+ * We need to decide if we are
+ * the root node of this branch
+ * or if we are a sibling of this
+ * branch.
+ */
+ prior = mi_parent->mi_ephemeral;
+ ASSERT(prior != NULL);
+ if (prior->ne_child == NULL) {
+ prior->ne_child = eph;
+ } else {
+ child = prior->ne_child;
+
+ prior->ne_child = eph;
+ eph->ne_peer = child;
+
+ child->ne_prior = eph;
+ }
+
+ eph->ne_prior = prior;
+ } else {
+ /*
+ * The parent mntinfo4 is the non-ephemeral
+ * root of the ephemeral tree. We
+ * need to decide if we are the root
+ * node of that tree or if we are a
+ * sibling of the root node.
+ *
+ * We are the root if there is no
+ * other node.
+ */
+ if (net->net_root == NULL) {
+ net->net_root = eph;
+ } else {
+ eph->ne_peer = peer = net->net_root;
+ ASSERT(peer != NULL);
+ net->net_root = eph;
+
+ peer->ne_prior = eph;
+ }
+
+ eph->ne_prior = NULL;
+ }
+
+ mutex_exit(&mi->mi_lock);
+ mutex_exit(&mi_parent->mi_lock);
+}
+
+/*
+ * Commit the changes to the ephemeral tree for removing this node.
+ */
+static void
+nfs4_ephemeral_umount_cleanup(nfs4_ephemeral_t *eph)
+{
+ nfs4_ephemeral_t *e = eph;
+ nfs4_ephemeral_t *peer;
+ nfs4_ephemeral_t *prior;
+
+ peer = eph->ne_peer;
+ prior = e->ne_prior;
+
+ /*
+ * If this branch root was not the
+ * tree root, then we need to fix back pointers.
+ */
+ if (prior) {
+ if (prior->ne_child == e) {
+ prior->ne_child = peer;
+ } else {
+ prior->ne_peer = peer;
+ }
+
+ if (peer)
+ peer->ne_prior = prior;
+ } else if (peer) {
+ peer->ne_mount->mi_ephemeral_tree->net_root = peer;
+ peer->ne_prior = NULL;
+ } else {
+ e->ne_mount->mi_ephemeral_tree->net_root = NULL;
+ }
+}
+
+/*
+ * We want to avoid recursion at all costs. So we need to
+ * unroll the tree. We do this by a depth first traversal to
+ * leaf nodes. We blast away the leaf and work our way back
+ * up and down the tree.
+ */
+static int
+nfs4_ephemeral_unmount_engine(nfs4_ephemeral_t *eph,
+ int isTreeRoot, int flag, cred_t *cr)
+{
+ nfs4_ephemeral_t *e = eph;
+ nfs4_ephemeral_t *prior;
+ mntinfo4_t *mi;
+ vfs_t *vfsp;
+ int error;
+
+ /*
+ * We use the loop while unrolling the ephemeral tree.
+ */
+ for (;;) {
+ /*
+ * First we walk down the child.
+ */
+ if (e->ne_child) {
+ prior = e;
+ e = e->ne_child;
+ continue;
+ }
+
+ /*
+ * If we are the root of the branch we are removing,
+ * we end it here. But if the branch is the root of
+ * the tree, we have to forge on. We do not consider
+ * the peer list for the root because while it may
+ * be okay to remove, it is both extra work and a
+ * potential for a false-positive error to stall the
+ * unmount attempt.
+ */
+ if (e == eph && isTreeRoot == FALSE)
+ return (0);
+
+ /*
+ * Next we walk down the peer list.
+ */
+ if (e->ne_peer) {
+ prior = e;
+ e = e->ne_peer;
+ continue;
+ }
+
+ /*
+ * We can only remove the node passed in by the
+ * caller if it is the root of the ephemeral tree.
+ * Otherwise, the caller will remove it.
+ */
+ if (e == eph && isTreeRoot == FALSE)
+ return (0);
+
+ /*
+ * Okay, we have a leaf node, time
+ * to prune it!
+ *
+ * Note that prior can only be NULL if
+ * and only if it is the root of the
+ * ephemeral tree.
+ */
+ prior = e->ne_prior;
+
+ mi = e->ne_mount;
+ mutex_enter(&mi->mi_lock);
+ vfsp = mi->mi_vfsp;
+
+ /*
+ * Cleared by umount2_engine.
+ */
+ VFS_HOLD(vfsp);
+
+ /*
+ * Inform nfs4_unmount to not recursively
+ * descend into this node's children when it
+ * gets processed.
+ */
+ mi->mi_flags |= MI4_EPHEMERAL_RECURSED;
+ mutex_exit(&mi->mi_lock);
+
+ error = umount2_engine(vfsp, flag, cr, FALSE);
+ if (error) {
+ /*
+ * We need to reenable nfs4_unmount's ability
+ * to recursively descend on this node.
+ */
+ mutex_enter(&mi->mi_lock);
+ mi->mi_flags &= ~MI4_EPHEMERAL_RECURSED;
+ mutex_exit(&mi->mi_lock);
+
+ return (error);
+ }
+
+ /*
+ * If we are the current node, we do not want to
+ * touch anything else. At this point, the only
+ * way the current node can have survived to here
+ * is if it is the root of the ephemeral tree and
+ * we are unmounting the enclosing mntinfo4.
+ */
+ if (e == eph) {
+ ASSERT(prior == NULL);
+ return (0);
+ }
+
+ /*
+ * Stitch up the prior node. Note that since
+ * we have handled the root of the tree, prior
+ * must be non-NULL.
+ */
+ ASSERT(prior != NULL);
+ if (prior->ne_child == e) {
+ prior->ne_child = NULL;
+ } else {
+ ASSERT(prior->ne_peer == e);
+
+ prior->ne_peer = NULL;
+ }
+
+ e = prior;
+ }
+
+ /* NOTREACHED */
+}
+
+/*
+ * Common code to safely release net_cnt_lock and net_tree_lock
+ */
+void
+nfs4_ephemeral_umount_unlock(bool_t *pmust_unlock,
+ nfs4_ephemeral_tree_t **pnet)
+{
+ nfs4_ephemeral_tree_t *net = *pnet;
+
+ if (*pmust_unlock) {
+ mutex_enter(&net->net_cnt_lock);
+ net->net_refcnt--;
+ net->net_status &= ~NFS4_EPHEMERAL_TREE_UMOUNTING;
+ mutex_exit(&net->net_cnt_lock);
+
+ mutex_exit(&net->net_tree_lock);
+
+ *pmust_unlock = FALSE;
+ }
+}
+
+/*
+ * While we may have removed any child or sibling nodes of this
+ * ephemeral node, we can not nuke it until we know that there
+ * were no actived vnodes on it. This will do that final
+ * work once we know it is not busy.
+ */
+void
+nfs4_ephemeral_umount_activate(mntinfo4_t *mi, bool_t *pmust_unlock,
+ nfs4_ephemeral_tree_t **pnet)
+{
+ /*
+ * Now we need to get rid of the ephemeral data if it exists.
+ */
+ mutex_enter(&mi->mi_lock);
+ if (mi->mi_ephemeral) {
+ /*
+ * If we are the root node of an ephemeral branch
+ * which is being removed, then we need to fixup
+ * pointers into and out of the node.
+ */
+ if (!(mi->mi_flags & MI4_EPHEMERAL_RECURSED))
+ nfs4_ephemeral_umount_cleanup(mi->mi_ephemeral);
+
+ ASSERT(mi->mi_ephemeral != NULL);
+
+ kmem_free(mi->mi_ephemeral, sizeof (*mi->mi_ephemeral));
+ mi->mi_ephemeral = NULL;
+ }
+ mutex_exit(&mi->mi_lock);
+
+ nfs4_ephemeral_umount_unlock(pmust_unlock, pnet);
+}
+
+/*
+ * Unmount an ephemeral node.
+ */
+int
+nfs4_ephemeral_umount(mntinfo4_t *mi, int flag, cred_t *cr,
+ bool_t *pmust_unlock, nfs4_ephemeral_tree_t **pnet)
+{
+ int error = 0;
+ nfs4_ephemeral_t *eph;
+ nfs4_ephemeral_tree_t *net;
+ int is_derooting = FALSE;
+ int is_recursed = FALSE;
+ int was_locked = FALSE;
+
+ /*
+ * The active vnodes on this file system may be ephemeral
+ * children. We need to check for and try to unmount them
+ * here. If any can not be unmounted, we are going
+ * to return EBUSY.
+ */
+ mutex_enter(&mi->mi_lock);
+
+ /*
+ * If an ephemeral tree, we need to check to see if
+ * the lock is already held. If it is, then we need
+ * to see if we are being called as a result of
+ * the recursive removal of some node of the tree or
+ * if we are another attempt to remove the tree.
+ *
+ * mi_flags & MI4_EPHEMERAL indicates an ephemeral
+ * node. mi_ephemeral being non-NULL also does this.
+ *
+ * mi_ephemeral_tree being non-NULL is sufficient
+ * to also indicate either it is an ephemeral node
+ * or the enclosing mntinfo4.
+ *
+ * Do we need MI4_EPHEMERAL? Yes, it is useful for
+ * when we delete the ephemeral node and need to
+ * differentiate from an ephemeral node and the
+ * enclosing root node.
+ */
+ *pnet = net = mi->mi_ephemeral_tree;
+ eph = mi->mi_ephemeral;
+ if (net) {
+ is_recursed = mi->mi_flags & MI4_EPHEMERAL_RECURSED;
+ is_derooting = (eph == NULL);
+ mutex_exit(&mi->mi_lock);
+
+ /*
+ * If this is not recursion, then we need to
+ * grab a ref count.
+ *
+ * But wait, we also do not want to do that
+ * if a harvester thread has already grabbed
+ * the lock.
+ */
+ if (!is_recursed) {
+ mutex_enter(&net->net_cnt_lock);
+ if (net->net_status &
+ NFS4_EPHEMERAL_TREE_LOCKED)
+ was_locked = TRUE;
+ else
+ net->net_refcnt++;
+ mutex_exit(&net->net_cnt_lock);
+ }
+
+ /*
+ * If we grab the lock, it means that no other
+ * operation is working on the tree. If we don't
+ * grab it, we need to decide if this is because
+ * we are a recursive call or a new operation.
+ *
+ * If we are a recursive call, we proceed without
+ * the lock.
+ *
+ * Else we have to wait until the lock becomes free.
+ */
+ if (was_locked == FALSE &&
+ !mutex_tryenter(&net->net_tree_lock)) {
+ if (!is_recursed) {
+ mutex_enter(&net->net_cnt_lock);
+ if (net->net_status &
+ (NFS4_EPHEMERAL_TREE_DEROOTING
+ | NFS4_EPHEMERAL_TREE_INVALID)) {
+ net->net_refcnt--;
+ mutex_exit(&net->net_cnt_lock);
+ goto is_busy;
+ }
+ mutex_exit(&net->net_cnt_lock);
+
+ /*
+ * We can't hold any other locks whilst
+ * we wait on this to free up.
+ */
+ mutex_enter(&net->net_tree_lock);
+
+ /*
+ * Note that while mi->mi_ephemeral
+ * may change and thus we have to
+ * update eph, it is the case that
+ * we have tied down net and
+ * do not care if mi->mi_ephemeral_tree
+ * has changed.
+ */
+ mutex_enter(&mi->mi_lock);
+ eph = mi->mi_ephemeral;
+ mutex_exit(&mi->mi_lock);
+
+ /*
+ * Okay, we need to see if either the
+ * tree got nuked or the current node
+ * got nuked. Both of which will cause
+ * an error.
+ *
+ * Note that a subsequent retry of the
+ * umount shall work.
+ */
+ mutex_enter(&net->net_cnt_lock);
+ if (net->net_status &
+ NFS4_EPHEMERAL_TREE_INVALID ||
+ (!is_derooting && eph == NULL)) {
+ net->net_refcnt--;
+ mutex_exit(&net->net_cnt_lock);
+ mutex_exit(&net->net_tree_lock);
+ goto is_busy;
+ }
+ mutex_exit(&net->net_cnt_lock);
+ *pmust_unlock = TRUE;
+ }
+ } else if (was_locked == FALSE) {
+ /*
+ * If we grab it right away, everything must
+ * be great!
+ */
+ *pmust_unlock = TRUE;
+ }
+
+ /*
+ * Only once we have grabbed the lock can we mark what we
+ * are planning on doing to the ephemeral tree.
+ */
+ if (*pmust_unlock) {
+ mutex_enter(&net->net_cnt_lock);
+ net->net_status |= NFS4_EPHEMERAL_TREE_UMOUNTING;
+
+ /*
+ * Check to see if we are nuking the root.
+ */
+ if (is_derooting)
+ net->net_status |=
+ NFS4_EPHEMERAL_TREE_DEROOTING;
+ mutex_exit(&net->net_cnt_lock);
+ }
+
+ if (!is_derooting) {
+ /*
+ * Only work on children if the caller has not already
+ * done so.
+ */
+ if (!is_recursed) {
+ ASSERT(eph != NULL);
+
+ error = nfs4_ephemeral_unmount_engine(eph,
+ FALSE, flag, cr);
+ if (error)
+ goto is_busy;
+ }
+ } else {
+ eph = net->net_root;
+
+ /*
+ * Only work if there is something there.
+ */
+ if (eph) {
+ error = nfs4_ephemeral_unmount_engine(eph, TRUE,
+ flag, cr);
+ if (error) {
+ mutex_enter(&net->net_cnt_lock);
+ net->net_status &=
+ ~NFS4_EPHEMERAL_TREE_DEROOTING;
+ mutex_exit(&net->net_cnt_lock);
+ goto is_busy;
+ }
+
+ /*
+ * Nothing else which goes wrong will
+ * invalidate the blowing away of the
+ * ephmeral tree.
+ */
+ net->net_root = NULL;
+ }
+
+ /*
+ * We have derooted and we have caused the tree to be
+ * invalid.
+ */
+ mutex_enter(&net->net_cnt_lock);
+ net->net_status &= ~NFS4_EPHEMERAL_TREE_DEROOTING;
+ net->net_status |= NFS4_EPHEMERAL_TREE_INVALID;
+ net->net_refcnt--;
+ mutex_exit(&net->net_cnt_lock);
+
+ /*
+ * At this point, the tree should no
+ * longer be associated with the
+ * mntinfo4. We need to pull it off
+ * there and let the harvester take
+ * care of it once the refcnt drops.
+ */
+ mutex_enter(&mi->mi_lock);
+ mi->mi_ephemeral_tree = NULL;
+ mutex_exit(&mi->mi_lock);
+ }
+ } else {
+ mutex_exit(&mi->mi_lock);
+ }
+
+ return (0);
+
+is_busy:
+
+ nfs4_ephemeral_umount_unlock(pmust_unlock, pnet);
+
+ return (error);
+}
+
+/*
+ * Do the umount and record any error in the parent.
+ */
+static void
+nfs4_ephemeral_record_umount(vfs_t *vfsp, int flag,
+ nfs4_ephemeral_t *e, nfs4_ephemeral_t *prior)
+{
+ int error;
+
+ error = umount2_engine(vfsp, flag, kcred, FALSE);
+ if (error) {
+ if (prior) {
+ if (prior->ne_child == e)
+ prior->ne_state |=
+ NFS4_EPHEMERAL_CHILD_ERROR;
+ else
+ prior->ne_state |=
+ NFS4_EPHEMERAL_PEER_ERROR;
+ }
+ }
+}
+
+/*
+ * For each tree in the forest (where the forest is in
+ * effect all of the ephemeral trees for this zone),
+ * scan to see if a node can be unmounted. Note that
+ * unlike nfs4_ephemeral_unmount_engine(), we do
+ * not process the current node before children or
+ * siblings. I.e., if a node can be unmounted, we
+ * do not recursively check to see if the nodes
+ * hanging off of it can also be unmounted.
+ *
+ * Instead, we delve down deep to try and remove the
+ * children first. Then, because we share code with
+ * nfs4_ephemeral_unmount_engine(), we will try
+ * them again. This could be a performance issue in
+ * the future.
+ *
+ * Also note that unlike nfs4_ephemeral_unmount_engine(),
+ * we do not halt on an error. We will not remove the
+ * current node, but we will keep on trying to remove
+ * the others.
+ *
+ * force indicates that we want the unmount to occur
+ * even if there is something blocking it.
+ *
+ * time_check indicates that we want to see if the
+ * mount has expired past mount_to or not. Typically
+ * we want to do this and only on a shutdown of the
+ * zone would we want to ignore the check.
+ */
+static void
+nfs4_ephemeral_harvest_forest(nfs4_trigger_globals_t *ntg,
+ bool_t force, bool_t time_check)
+{
+ nfs4_ephemeral_tree_t *net;
+ nfs4_ephemeral_tree_t *prev = NULL;
+ nfs4_ephemeral_tree_t *next;
+ nfs4_ephemeral_t *e;
+ nfs4_ephemeral_t *prior;
+ time_t now = gethrestime_sec();
+
+ nfs4_ephemeral_tree_t *harvest = NULL;
+
+ int flag;
+
+ mntinfo4_t *mi;
+ vfs_t *vfsp;
+
+ if (force)
+ flag = MS_FORCE;
+ else
+ flag = 0;
+
+ mutex_enter(&ntg->ntg_forest_lock);
+ for (net = ntg->ntg_forest; net != NULL; net = next) {
+ next = net->net_next;
+
+ mutex_enter(&net->net_cnt_lock);
+ net->net_refcnt++;
+ mutex_exit(&net->net_cnt_lock);
+
+ mutex_enter(&net->net_tree_lock);
+
+ /*
+ * Let the unmount code know that the
+ * tree is already locked!
+ */
+ mutex_enter(&net->net_cnt_lock);
+ net->net_status |= NFS4_EPHEMERAL_TREE_LOCKED;
+ mutex_exit(&net->net_cnt_lock);
+
+ /*
+ * If the intent is force all ephemeral nodes to
+ * be unmounted in this zone, we can short circuit a
+ * lot of tree traversal and simply zap the root node.
+ */
+ if (force) {
+ if (net->net_root) {
+ mi = net->net_root->ne_mount;
+ vfsp = mi->mi_vfsp;
+
+ /*
+ * Cleared by umount2_engine.
+ */
+ VFS_HOLD(vfsp);
+
+ (void) umount2_engine(vfsp, flag,
+ kcred, FALSE);
+
+ goto check_done;
+ }
+ }
+
+ e = net->net_root;
+ if (e)
+ e->ne_state = NFS4_EPHEMERAL_VISIT_CHILD;
+
+ while (e) {
+ if (e->ne_state == NFS4_EPHEMERAL_VISIT_CHILD) {
+ e->ne_state = NFS4_EPHEMERAL_VISIT_SIBLING;
+ if (e->ne_child) {
+ e = e->ne_child;
+ e->ne_state =
+ NFS4_EPHEMERAL_VISIT_CHILD;
+ }
+
+ continue;
+ } else if (e->ne_state ==
+ NFS4_EPHEMERAL_VISIT_SIBLING) {
+ e->ne_state = NFS4_EPHEMERAL_PROCESS_ME;
+ if (e->ne_peer) {
+ e = e->ne_peer;
+ e->ne_state =
+ NFS4_EPHEMERAL_VISIT_CHILD;
+ }
+
+ continue;
+ } else if (e->ne_state ==
+ NFS4_EPHEMERAL_CHILD_ERROR) {
+ prior = e->ne_prior;
+
+ /*
+ * If a child reported an error, do
+ * not bother trying to unmount.
+ *
+ * If your prior node is a parent,
+ * pass the error up such that they
+ * also do not try to unmount.
+ *
+ * However, if your prior is a sibling,
+ * let them try to unmount if they can.
+ */
+ if (prior) {
+ if (prior->ne_child == e)
+ prior->ne_state |=
+ NFS4_EPHEMERAL_CHILD_ERROR;
+ else
+ prior->ne_state |=
+ NFS4_EPHEMERAL_PEER_ERROR;
+ }
+
+ /*
+ * Clear the error and if needed, process peers.
+ *
+ * Once we mask out the error, we know whether
+ * or we have to process another node.
+ */
+ e->ne_state &= ~NFS4_EPHEMERAL_CHILD_ERROR;
+ if (e->ne_state == NFS4_EPHEMERAL_PROCESS_ME)
+ e = prior;
+
+ continue;
+ } else if (e->ne_state ==
+ NFS4_EPHEMERAL_PEER_ERROR) {
+ prior = e->ne_prior;
+
+ if (prior) {
+ if (prior->ne_child == e)
+ prior->ne_state =
+ NFS4_EPHEMERAL_CHILD_ERROR;
+ else
+ prior->ne_state =
+ NFS4_EPHEMERAL_PEER_ERROR;
+ }
+
+ /*
+ * Clear the error from this node and do the
+ * correct processing.
+ */
+ e->ne_state &= ~NFS4_EPHEMERAL_PEER_ERROR;
+ continue;
+ }
+
+ prior = e->ne_prior;
+ e->ne_state = NFS4_EPHEMERAL_OK;
+
+ /*
+ * It must be the case that we need to process
+ * this node.
+ */
+ if (!time_check ||
+ now - e->ne_ref_time > e->ne_mount_to) {
+ mi = e->ne_mount;
+ vfsp = mi->mi_vfsp;
+
+ /*
+ * Cleared by umount2_engine.
+ */
+ VFS_HOLD(vfsp);
+
+ /*
+ * Note that we effectively work down to the
+ * leaf nodes first, try to unmount them,
+ * then work our way back up into the leaf
+ * nodes.
+ *
+ * Also note that we deal with a lot of
+ * complexity by sharing the work with
+ * the manual unmount code.
+ */
+ nfs4_ephemeral_record_umount(vfsp, flag,
+ e, prior);
+ }
+
+ e = prior;
+ }
+
+check_done:
+
+ /*
+ * Are we done with this tree?
+ */
+ mutex_enter(&net->net_cnt_lock);
+ if (net->net_refcnt == 1 &&
+ net->net_status & NFS4_EPHEMERAL_TREE_INVALID) {
+ net->net_refcnt--;
+ net->net_status &= ~NFS4_EPHEMERAL_TREE_LOCKED;
+ mutex_exit(&net->net_cnt_lock);
+ mutex_exit(&net->net_tree_lock);
+
+ if (prev)
+ prev->net_next = net->net_next;
+ else
+ ntg->ntg_forest = net->net_next;
+
+ net->net_next = harvest;
+ harvest = net;
+ continue;
+ }
+
+ net->net_refcnt--;
+ net->net_status &= ~NFS4_EPHEMERAL_TREE_LOCKED;
+ mutex_exit(&net->net_cnt_lock);
+ mutex_exit(&net->net_tree_lock);
+
+ prev = net;
+ }
+ mutex_exit(&ntg->ntg_forest_lock);
+
+ for (net = harvest; net != NULL; net = next) {
+ next = net->net_next;
+
+ mutex_destroy(&net->net_tree_lock);
+ mutex_destroy(&net->net_cnt_lock);
+ kmem_free(net, sizeof (*net));
+ }
+}
+
+/*
+ * This is the thread which decides when the harvesting
+ * can proceed and when to kill it off for this zone.
+ */
+static void
+nfs4_ephemeral_harvester(nfs4_trigger_globals_t *ntg)
+{
+ clock_t timeleft;
+ zone_t *zone = curproc->p_zone;
+
+ for (;;) {
+ timeleft = zone_status_timedwait(zone, lbolt +
+ nfs4_trigger_thread_timer * hz, ZONE_IS_SHUTTING_DOWN);
+
+ /*
+ * zone is exiting...
+ */
+ if (timeleft != -1) {
+ ASSERT(zone_status_get(zone) >= ZONE_IS_SHUTTING_DOWN);
+ zthread_exit();
+ /* NOTREACHED */
+ }
+
+ /*
+ * Only bother scanning if there is potential
+ * work to be done.
+ */
+ if (ntg->ntg_forest == NULL)
+ continue;
+
+ /*
+ * Now scan the list and get rid of everything which
+ * is old.
+ */
+ nfs4_ephemeral_harvest_forest(ntg, FALSE, TRUE);
+ }
+
+ /* NOTREACHED */
+}
+
+/*
+ * The zone specific glue needed to start the unmount harvester.
+ *
+ * Note that we want to avoid holding the mutex as long as possible,
+ * hence the multiple checks.
+ *
+ * The caller should avoid us getting down here in the first
+ * place.
+ */
+static void
+nfs4_ephemeral_start_harvester(nfs4_trigger_globals_t *ntg)
+{
+ /*
+ * It got started before we got here...
+ */
+ if (ntg->ntg_thread_started)
+ return;
+
+ mutex_enter(&nfs4_ephemeral_thread_lock);
+
+ if (ntg->ntg_thread_started) {
+ mutex_exit(&nfs4_ephemeral_thread_lock);
+ return;
+ }
+
+ /*
+ * Start the unmounter harvester thread for this zone.
+ */
+ (void) zthread_create(NULL, 0, nfs4_ephemeral_harvester,
+ ntg, 0, minclsyspri);
+
+ ntg->ntg_thread_started = TRUE;
+ mutex_exit(&nfs4_ephemeral_thread_lock);
+}
+
+/*ARGSUSED*/
+static void *
+nfs4_ephemeral_zsd_create(zoneid_t zoneid)
+{
+ nfs4_trigger_globals_t *ntg;
+
+ ntg = kmem_zalloc(sizeof (*ntg), KM_SLEEP);
+ ntg->ntg_thread_started = FALSE;
+
+ /*
+ * This is the default....
+ */
+ ntg->ntg_mount_to = nfs4_trigger_thread_timer;
+
+ mutex_init(&ntg->ntg_forest_lock, NULL,
+ MUTEX_DEFAULT, NULL);
+
+ return (ntg);
+}
+
+/*
+ * Try a nice gentle walk down the forest and convince
+ * all of the trees to gracefully give it up.
+ */
+/*ARGSUSED*/
+static void
+nfs4_ephemeral_zsd_shutdown(zoneid_t zoneid, void *arg)
+{
+ nfs4_trigger_globals_t *ntg = arg;
+
+ if (!ntg)
+ return;
+
+ nfs4_ephemeral_harvest_forest(ntg, FALSE, FALSE);
+}
+
+/*
+ * Race along the forest and rip all of the trees out by
+ * their rootballs!
+ */
+/*ARGSUSED*/
+static void
+nfs4_ephemeral_zsd_destroy(zoneid_t zoneid, void *arg)
+{
+ nfs4_trigger_globals_t *ntg = arg;
+
+ if (!ntg)
+ return;
+
+ nfs4_ephemeral_harvest_forest(ntg, TRUE, FALSE);
+
+ mutex_destroy(&ntg->ntg_forest_lock);
+ kmem_free(ntg, sizeof (*ntg));
+}
+
+/*
+ * This is the zone independent cleanup needed for
+ * emphemeral mount processing.
+ */
+void
+nfs4_ephemeral_fini(void)
+{
+ (void) zone_key_delete(nfs4_ephemeral_key);
+ mutex_destroy(&nfs4_ephemeral_thread_lock);
+}
+
+/*
+ * This is the zone independent initialization needed for
+ * emphemeral mount processing.
+ */
+void
+nfs4_ephemeral_init(void)
+{
+ mutex_init(&nfs4_ephemeral_thread_lock, NULL, MUTEX_DEFAULT,
+ NULL);
+
+ zone_key_create(&nfs4_ephemeral_key, nfs4_ephemeral_zsd_create,
+ nfs4_ephemeral_zsd_shutdown, nfs4_ephemeral_zsd_destroy);
+}
+
+/*
+ * nfssys() calls this function to set the per-zone
+ * value of mount_to to drive when an ephemeral mount is
+ * timed out. Each mount will grab a copy of this value
+ * when mounted.
+ */
+void
+nfs4_ephemeral_set_mount_to(uint_t mount_to)
+{
+ nfs4_trigger_globals_t *ntg;
+ zone_t *zone = curproc->p_zone;
+
+ ntg = zone_getspecific(nfs4_ephemeral_key, zone);
+
+ ntg->ntg_mount_to = mount_to;
+}
+
+/*
+ * Walk the list of v4 mount options; if they are currently set in vfsp,
+ * append them to a new comma-separated mount option string, and return it.
+ *
+ * Caller should free by calling nfs4_trigger_destroy_mntopts().
+ */
+static char *
+nfs4_trigger_create_mntopts(vfs_t *vfsp)
+{
+ uint_t i;
+ char *mntopts;
+ struct vfssw *vswp;
+ mntopts_t *optproto;
+
+ mntopts = kmem_zalloc(MAX_MNTOPT_STR, KM_SLEEP);
+
+ /* get the list of applicable mount options for v4; locks *vswp */
+ vswp = vfs_getvfssw(MNTTYPE_NFS4);
+ optproto = &vswp->vsw_optproto;
+
+ for (i = 0; i < optproto->mo_count; i++) {
+ struct mntopt *mop = &optproto->mo_list[i];
+
+ if (mop->mo_flags & MO_EMPTY)
+ continue;
+
+ if (nfs4_trigger_add_mntopt(mntopts, mop->mo_name, vfsp)) {
+ kmem_free(mntopts, MAX_MNTOPT_STR);
+ vfs_unrefvfssw(vswp);
+ return (NULL);
+ }
+ }
+
+ vfs_unrefvfssw(vswp);
+
+ /*
+ * MNTOPT_XATTR is not in the v4 mount opt proto list,
+ * and it may only be passed via MS_OPTIONSTR, so we
+ * must handle it here.
+ *
+ * Ideally, it would be in the list, but NFS does not specify its
+ * own opt proto list, it uses instead the default one. Since
+ * not all filesystems support extended attrs, it would not be
+ * appropriate to add it there.
+ */
+ if (nfs4_trigger_add_mntopt(mntopts, MNTOPT_XATTR, vfsp) ||
+ nfs4_trigger_add_mntopt(mntopts, MNTOPT_NOXATTR, vfsp)) {
+ kmem_free(mntopts, MAX_MNTOPT_STR);
+ return (NULL);
+ }
+
+ return (mntopts);
+}
+
+static void
+nfs4_trigger_destroy_mntopts(char *mntopts)
+{
+ if (mntopts)
+ kmem_free(mntopts, MAX_MNTOPT_STR);
+}
+
+/*
+ * Check a single mount option (optname). Add to mntopts if it is set in VFS.
+ */
+static int
+nfs4_trigger_add_mntopt(char *mntopts, char *optname, vfs_t *vfsp)
+{
+ if (mntopts == NULL || optname == NULL || vfsp == NULL)
+ return (EINVAL);
+
+ if (vfs_optionisset(vfsp, optname, NULL)) {
+ size_t mntoptslen = strlen(mntopts);
+ size_t optnamelen = strlen(optname);
+
+ /* +1 for ',', +1 for NUL */
+ if (mntoptslen + optnamelen + 2 > MAX_MNTOPT_STR)
+ return (EOVERFLOW);
+
+ /* first or subsequent mount option? */
+ if (*mntopts != '\0')
+ (void) strcat(mntopts, ",");
+
+ (void) strcat(mntopts, optname);
+ }
+
+ return (0);
+}
+
+static enum clnt_stat
+nfs4_trigger_ping_server(servinfo4_t *svp, int nointr)
+{
+ int retries, error;
+ uint_t max_msgsize;
+ enum clnt_stat status;
+ CLIENT *cl;
+ struct timeval timeout;
+
+ /* as per recov_newserver() */
+ max_msgsize = 0;
+ retries = 1;
+ timeout.tv_sec = 2;
+ timeout.tv_usec = 0;
+
+ error = clnt_tli_kcreate(svp->sv_knconf, &svp->sv_addr, NFS_PROGRAM,
+ NFS_V4, max_msgsize, retries, CRED(), &cl);
+ if (error)
+ return (RPC_FAILED);
+
+ if (nointr)
+ cl->cl_nosignal = TRUE;
+ status = CLNT_CALL(cl, RFS_NULL, xdr_void, NULL, xdr_void, NULL,
+ timeout);
+ if (nointr)
+ cl->cl_nosignal = FALSE;
+
+ AUTH_DESTROY(cl->cl_auth);
+ CLNT_DESTROY(cl);
+
+ return (status);
+}
diff --git a/usr/src/uts/common/fs/nfs/nfs4_subr.c b/usr/src/uts/common/fs/nfs/nfs4_subr.c
index 2a6505ccf9..16ce81e270 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_subr.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_subr.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -433,7 +433,7 @@ nfs4_log_badowner(mntinfo4_t *mi, nfs_opnum4 op)
* Happens once per client <-> server pair.
*/
if (nfs_rw_enter_sig(&mi->mi_recovlock, RW_READER,
- mi->mi_flags & MI4_INT))
+ mi->mi_flags & MI4_INT))
return;
server = find_nfs4_server(mi);
@@ -470,8 +470,6 @@ nfs4_log_badowner(mntinfo4_t *mi, nfs_opnum4 op)
mutex_exit(&mi->mi_lock);
}
-
-
int
nfs4_time_ntov(nfstime4 *ntime, timestruc_t *vatime)
{
@@ -546,7 +544,7 @@ utf8_to_fn(utf8string *u8s, uint_t *lenp, char *s)
ASSERT(lenp != NULL);
if (u8s == NULL || u8s->utf8string_len <= 0 ||
- u8s->utf8string_val == NULL)
+ u8s->utf8string_val == NULL)
return (NULL);
/*
@@ -659,9 +657,9 @@ utf8_copy(utf8string *src, utf8string *dest)
if (src->utf8string_len > 0) {
dest->utf8string_val = kmem_alloc(src->utf8string_len,
- KM_SLEEP);
+ KM_SLEEP);
bcopy(src->utf8string_val, dest->utf8string_val,
- src->utf8string_len);
+ src->utf8string_len);
dest->utf8string_len = src->utf8string_len;
} else {
dest->utf8string_val = NULL;
@@ -778,10 +776,10 @@ authget(servinfo4_t *svp, CLIENT *ch_client, cred_t *cr)
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_WRITER, 0);
if ((svp->sv_flags & SV4_TRYSECINFO) && svp->sv_secinfo) {
for (i = svp->sv_secinfo->index; i < svp->sv_secinfo->count;
- i++) {
+ i++) {
if (!(error = sec_clnt_geth(ch_client,
- &svp->sv_secinfo->sdata[i],
- cr, &ch_client->cl_auth))) {
+ &svp->sv_secinfo->sdata[i],
+ cr, &ch_client->cl_auth))) {
svp->sv_currsec = &svp->sv_secinfo->sdata[i];
svp->sv_secinfo->index = i;
@@ -804,11 +802,11 @@ authget(servinfo4_t *svp, CLIENT *ch_client, cred_t *cr)
/* sv_currsec points to one of the entries in sv_secinfo */
if (svp->sv_currsec) {
error = sec_clnt_geth(ch_client, svp->sv_currsec, cr,
- &ch_client->cl_auth);
+ &ch_client->cl_auth);
} else {
/* If it's null, use sv_secdata. */
error = sec_clnt_geth(ch_client, svp->sv_secdata, cr,
- &ch_client->cl_auth);
+ &ch_client->cl_auth);
}
}
nfs_rw_exit(&svp->sv_lock);
@@ -854,7 +852,7 @@ top:
ch->ch_vers == ci->cl_vers &&
ch->ch_dev == svp->sv_knconf->knc_rdev &&
(strcmp(ch->ch_protofmly,
- svp->sv_knconf->knc_protofmly) == 0))
+ svp->sv_knconf->knc_protofmly) == 0))
break;
plistp = &ch->ch_next;
}
@@ -1126,7 +1124,7 @@ clreclaim4_zone(struct nfs4_clnt *nfscl, uint_t cl_holdtime)
cpl = ch->ch_list;
cpp = &ch->ch_list;
while (cpl != NULL &&
- cpl->ch_freed + cl_holdtime > gethrestime_sec()) {
+ cpl->ch_freed + cl_holdtime > gethrestime_sec()) {
cpp = &cpl->ch_list;
cpl = cpl->ch_list;
}
@@ -1279,9 +1277,9 @@ nfs4_rfscall(mntinfo4_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
tryagain = FALSE;
NFS4_DEBUG(nfs4_rfscall_debug, (CE_NOTE,
- "nfs4_rfscall: vfs_flag=0x%x, %s",
- mi->mi_vfsp->vfs_flag,
- is_recov ? "recov thread" : "not recov thread"));
+ "nfs4_rfscall: vfs_flag=0x%x, %s",
+ mi->mi_vfsp->vfs_flag,
+ is_recov ? "recov thread" : "not recov thread"));
/*
* It's possible while we're retrying the admin
@@ -1461,7 +1459,7 @@ nfs4_rfscall(mntinfo4_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
} while (tryagain);
DTRACE_PROBE2(nfs4__rfscall_debug, enum clnt_stat, status,
- int, rpcerr.re_errno);
+ int, rpcerr.re_errno);
if (status != RPC_SUCCESS) {
zoneid_t zoneid = mi->mi_zone->zone_id;
@@ -1563,7 +1561,7 @@ nfs4_rfscall(mntinfo4_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
*/
void
rfs4call(mntinfo4_t *mi, COMPOUND4args_clnt *argsp, COMPOUND4res_clnt *resp,
- cred_t *cr, int *doqueue, int flags, nfs4_error_t *ep)
+ cred_t *cr, int *doqueue, int flags, nfs4_error_t *ep)
{
int i, error;
enum clnt_stat rpc_status = NFS4_OK;
@@ -1584,9 +1582,9 @@ rfs4call(mntinfo4_t *mi, COMPOUND4args_clnt *argsp, COMPOUND4res_clnt *resp,
resp->decode_len = 0;
error = nfs4_rfscall(mi, NFSPROC4_COMPOUND,
- xdr_COMPOUND4args_clnt, (caddr_t)argsp,
- xdr_COMPOUND4res_clnt, (caddr_t)resp, cr,
- doqueue, &rpc_status, flags, nfscl);
+ xdr_COMPOUND4args_clnt, (caddr_t)argsp,
+ xdr_COMPOUND4res_clnt, (caddr_t)resp, cr,
+ doqueue, &rpc_status, flags, nfscl);
/* Return now if it was an RPC error */
if (error) {
@@ -1639,10 +1637,10 @@ nfs4rename_update(vnode_t *renvp, vnode_t *ndvp, nfs_fh4 *nfh4p, char *nnm)
static void
remap_lookup(nfs4_fname_t *fname, vnode_t *rootvp,
- int filetype, cred_t *cr,
- nfs_fh4 *fhp, nfs4_ga_res_t *garp, /* fh, attrs for object */
- nfs_fh4 *pfhp, nfs4_ga_res_t *pgarp, /* fh, attrs for parent */
- nfs4_error_t *ep)
+ int filetype, cred_t *cr,
+ nfs_fh4 *fhp, nfs4_ga_res_t *garp, /* fh, attrs for object */
+ nfs_fh4 *pfhp, nfs4_ga_res_t *pgarp, /* fh, attrs for parent */
+ nfs4_error_t *ep)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -1773,6 +1771,7 @@ exit:
void
nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int flags, nfs4_error_t *ep)
{
+ int is_stub;
rnode4_t *rp = VTOR4(vp);
vnode_t *rootvp = NULL;
vnode_t *dvp = NULL;
@@ -1811,7 +1810,7 @@ get_remap_cred:
* Puts a hold on the cred_otw and the new osp (if found).
*/
cred_otw = nfs4_get_otw_cred_by_osp(rp, cr, &osp,
- &first_time, &last_time);
+ &first_time, &last_time);
ASSERT(cred_otw != NULL);
if (rp->r_flags & R4ISXATTR) {
@@ -1830,7 +1829,7 @@ get_remap_cred:
again:
remap_lookup(rp->r_svnode.sv_name, rootvp, filetype, cred_otw,
- &newfh, &gar, &newpfh, &pgar, ep);
+ &newfh, &gar, &newpfh, &pgar, ep);
NFS4_DEBUG(nfs4_client_failover_debug, (CE_NOTE,
"nfs4_remap_file: remap_lookup returned %d/%d",
@@ -1909,8 +1908,8 @@ again:
mutex_enter(&rp->r_statelock);
if (flags & NFS4_REMAP_CKATTRS) {
if (vp->v_type != gar.n4g_va.va_type ||
- (vp->v_type != VDIR &&
- rp->r_size != gar.n4g_va.va_size)) {
+ (vp->v_type != VDIR &&
+ rp->r_size != gar.n4g_va.va_size)) {
NFS4_DEBUG(nfs4_client_failover_debug, (CE_NOTE,
"nfs4_remap_file: size %d vs. %d, type %d vs. %d",
(int)rp->r_size, (int)gar.n4g_va.va_size,
@@ -1926,21 +1925,32 @@ again:
ASSERT(gar.n4g_va.va_type != VNON);
rp->r_server = mi->mi_curr_serv;
+ /*
+ * Turn this object into a "stub" object if we
+ * crossed an underlying server fs boundary.
+ *
+ * This stub will be for a mirror-mount.
+ *
+ * See comment in r4_do_attrcache() for more details.
+ */
+ is_stub = 0;
if (gar.n4g_fsid_valid) {
(void) nfs_rw_enter_sig(&rp->r_server->sv_lock, RW_READER, 0);
rp->r_srv_fsid = gar.n4g_fsid;
- if (FATTR4_FSID_EQ(&gar.n4g_fsid, &rp->r_server->sv_fsid))
- rp->r_flags &= ~R4SRVSTUB;
- else
- rp->r_flags |= R4SRVSTUB;
+ if (!FATTR4_FSID_EQ(&gar.n4g_fsid, &rp->r_server->sv_fsid))
+ is_stub = 1;
nfs_rw_exit(&rp->r_server->sv_lock);
#ifdef DEBUG
} else {
NFS4_DEBUG(nfs4_client_failover_debug, (CE_NOTE,
- "remap_file: fsid attr not provided by server. rp=%p",
- (void *)rp));
+ "remap_file: fsid attr not provided by server. rp=%p",
+ (void *)rp));
#endif
}
+ if (is_stub)
+ r4_stub_mirrormount(rp);
+ else
+ r4_stub_none(rp);
mutex_exit(&rp->r_statelock);
nfs4_attrcache_noinval(vp, &gar, gethrtime()); /* force update */
sfh4_update(rp->r_fh, &newfh);
@@ -2232,7 +2242,7 @@ sv4_free(servinfo4_t *svp)
if (svp->sv_secdata)
sec_clnt_freeinfo(svp->sv_secdata);
if (svp->sv_save_secinfo &&
- svp->sv_save_secinfo != svp->sv_secinfo)
+ svp->sv_save_secinfo != svp->sv_secinfo)
secinfo_free(svp->sv_save_secinfo);
if (svp->sv_secinfo)
secinfo_free(svp->sv_secinfo);
@@ -2348,7 +2358,7 @@ rddir4_cache_create(rnode4_t *rp)
rp->r_dir = kmem_alloc(sizeof (avl_tree_t), KM_SLEEP);
avl_create(rp->r_dir, rddir4_cache_compar, sizeof (rddir4_cache_impl),
- offsetof(rddir4_cache_impl, tree));
+ offsetof(rddir4_cache_impl, tree));
}
/*
@@ -2544,14 +2554,14 @@ top:
rddir4_cache_rele(rp, rdc);
mutex_exit(&rp->r_statelock);
(void) nfs_rw_enter_sig(&rp->r_rwlock,
- RW_READER, FALSE);
+ RW_READER, FALSE);
mutex_enter(&rp->r_statelock);
return (NULL);
}
}
mutex_exit(&rp->r_statelock);
(void) nfs_rw_enter_sig(&rp->r_rwlock,
- RW_READER, FALSE);
+ RW_READER, FALSE);
mutex_enter(&rp->r_statelock);
}
@@ -2684,8 +2694,8 @@ cl4_snapshot(kstat_t *ksp, void *buf, int rw)
* add the check just for paranoia.
*/
if (INGLOBALZONE(curproc))
- bcopy((char *)buf + sizeof (clstat4_tmpl), &clstat4_debug,
- sizeof (clstat4_debug));
+ bcopy((char *)buf + sizeof (clstat4_tmpl),
+ &clstat4_debug, sizeof (clstat4_debug));
#endif
} else {
bcopy(ksp->ks_private, buf, sizeof (clstat4_tmpl));
@@ -2792,8 +2802,8 @@ nfs4_subr_init(void)
* Allocate and initialize the client handle cache
*/
chtab4_cache = kmem_cache_create("client_handle4_cache",
- sizeof (struct chtab), 0, NULL, NULL, clreclaim4, NULL,
- NULL, 0);
+ sizeof (struct chtab), 0, NULL, NULL, clreclaim4, NULL,
+ NULL, 0);
/*
* Initialize the list of per-zone client handles (and associated data).
@@ -3015,7 +3025,7 @@ try_failover(enum clnt_stat rpc_status)
err = ETIMEDOUT;
#ifdef DEBUG
cmn_err(CE_NOTE, "try_failover: unexpected rpc error %d",
- rpc_status);
+ rpc_status);
#endif
} else
err = try_failover_table[rpc_status].error;
@@ -3023,8 +3033,8 @@ try_failover(enum clnt_stat rpc_status)
done:
if (rpc_status)
NFS4_DEBUG(nfs4_client_failover_debug, (CE_NOTE,
- "nfs4_try_failover: %strying failover on error %d",
- err ? "" : "NOT ", rpc_status));
+ "nfs4_try_failover: %strying failover on error %d",
+ err ? "" : "NOT ", rpc_status));
return (err);
}
diff --git a/usr/src/uts/common/fs/nfs/nfs4_vfsops.c b/usr/src/uts/common/fs/nfs/nfs4_vfsops.c
index 4f6719117f..88281d7b67 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_vfsops.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_vfsops.c
@@ -84,12 +84,13 @@
*/
typedef struct {
- vfs_t *fm_vfsp;
- cred_t *fm_cr;
+ vfs_t *fm_vfsp;
+ int fm_flag;
+ cred_t *fm_cr;
} freemountargs_t;
-static void async_free_mount(vfs_t *, cred_t *);
-static void nfs4_free_mount(vfs_t *, cred_t *);
+static void async_free_mount(vfs_t *, int, cred_t *);
+static void nfs4_free_mount(vfs_t *, int, cred_t *);
static void nfs4_free_mount_thread(freemountargs_t *);
static int nfs4_chkdup_servinfo4(servinfo4_t *, servinfo4_t *);
@@ -135,7 +136,7 @@ static int nfs4_max_mount_retry = 2;
/*
* nfs4 vfs operations.
*/
-static int nfs4_mount(vfs_t *, vnode_t *, struct mounta *, cred_t *);
+int nfs4_mount(vfs_t *, vnode_t *, struct mounta *, cred_t *);
static int nfs4_unmount(vfs_t *, int, cred_t *);
static int nfs4_root(vfs_t *, vnode_t **);
static int nfs4_statvfs(vfs_t *, struct statvfs64 *);
@@ -158,6 +159,9 @@ static void nfs4setclientid_otw(mntinfo4_t *, servinfo4_t *, cred_t *,
static void destroy_nfs4_server(nfs4_server_t *);
static void remove_mi(nfs4_server_t *, mntinfo4_t *);
+extern void nfs4_ephemeral_init(void);
+extern void nfs4_ephemeral_fini(void);
+
/*
* Initialize the vfs structure
*/
@@ -188,28 +192,48 @@ nfs4init(int fstyp, char *name)
};
int error;
+ nfs4_vfsops = NULL;
+ nfs4_vnodeops = NULL;
+ nfs4_trigger_vnodeops = NULL;
+
error = vfs_setfsops(fstyp, nfs4_vfsops_template, &nfs4_vfsops);
if (error != 0) {
zcmn_err(GLOBAL_ZONEID, CE_WARN,
"nfs4init: bad vfs ops template");
- return (error);
+ goto out;
}
error = vn_make_ops(name, nfs4_vnodeops_template, &nfs4_vnodeops);
if (error != 0) {
- (void) vfs_freevfsops_by_type(fstyp);
zcmn_err(GLOBAL_ZONEID, CE_WARN,
"nfs4init: bad vnode ops template");
- return (error);
+ goto out;
}
- nfs4fstyp = fstyp;
+ error = vn_make_ops("nfs4_trigger", nfs4_trigger_vnodeops_template,
+ &nfs4_trigger_vnodeops);
+ if (error != 0) {
+ zcmn_err(GLOBAL_ZONEID, CE_WARN,
+ "nfs4init: bad trigger vnode ops template");
+ goto out;
+ }
+ nfs4fstyp = fstyp;
(void) nfs4_vfsinit();
-
(void) nfs4_init_dot_entries();
- return (0);
+out:
+ if (error) {
+ if (nfs4_trigger_vnodeops != NULL)
+ vn_freevnodeops(nfs4_trigger_vnodeops);
+
+ if (nfs4_vnodeops != NULL)
+ vn_freevnodeops(nfs4_vnodeops);
+
+ (void) vfs_freevfsops_by_type(fstyp);
+ }
+
+ return (error);
}
void
@@ -227,7 +251,7 @@ nfs4fini(void)
*
* sec_data can be freed by sec_clnt_freeinfo().
*/
-struct sec_data *
+static struct sec_data *
create_authdh_data(char *netname, int nlen, struct netbuf *syncaddr,
struct knetconfig *knconf) {
struct sec_data *secdata;
@@ -272,6 +296,74 @@ create_authdh_data(char *netname, int nlen, struct netbuf *syncaddr,
return (secdata);
}
+/*
+ * Returns (deep) copy of sec_data_t. Allocates all memory required; caller
+ * is responsible for freeing.
+ */
+sec_data_t *
+copy_sec_data(sec_data_t *fsecdata) {
+ sec_data_t *tsecdata;
+
+ if (fsecdata == NULL)
+ return (NULL);
+
+ if (fsecdata->rpcflavor == AUTH_DH) {
+ dh_k4_clntdata_t *fdata = (dh_k4_clntdata_t *)fsecdata->data;
+
+ if (fdata == NULL)
+ return (NULL);
+
+ tsecdata = (sec_data_t *)create_authdh_data(fdata->netname,
+ fdata->netnamelen, &fdata->syncaddr, fdata->knconf);
+
+ return (tsecdata);
+ }
+
+ tsecdata = kmem_zalloc(sizeof (sec_data_t), KM_SLEEP);
+
+ tsecdata->secmod = fsecdata->secmod;
+ tsecdata->rpcflavor = fsecdata->rpcflavor;
+ tsecdata->flags = fsecdata->flags;
+ tsecdata->uid = fsecdata->uid;
+
+ if (fsecdata->rpcflavor == RPCSEC_GSS) {
+ gss_clntdata_t *gcd = (gss_clntdata_t *)fsecdata->data;
+
+ tsecdata->data = (caddr_t)copy_sec_data_gss(gcd);
+ } else {
+ tsecdata->data = NULL;
+ }
+
+ return (tsecdata);
+}
+
+gss_clntdata_t *
+copy_sec_data_gss(gss_clntdata_t *fdata)
+{
+ gss_clntdata_t *tdata;
+
+ if (fdata == NULL)
+ return (NULL);
+
+ tdata = kmem_zalloc(sizeof (gss_clntdata_t), KM_SLEEP);
+
+ tdata->mechanism.length = fdata->mechanism.length;
+ tdata->mechanism.elements = kmem_zalloc(fdata->mechanism.length,
+ KM_SLEEP);
+ bcopy(fdata->mechanism.elements, tdata->mechanism.elements,
+ fdata->mechanism.length);
+
+ tdata->service = fdata->service;
+
+ (void) strcpy(tdata->uname, fdata->uname);
+ (void) strcpy(tdata->inst, fdata->inst);
+ (void) strcpy(tdata->realm, fdata->realm);
+
+ tdata->qop = fdata->qop;
+
+ return (tdata);
+}
+
static int
nfs4_chkdup_servinfo4(servinfo4_t *svp_head, servinfo4_t *svp)
{
@@ -293,9 +385,9 @@ nfs4_chkdup_servinfo4(servinfo4_t *svp_head, servinfo4_t *svp)
continue;
if (si->sv_addr.len == svp->sv_addr.len &&
strcmp(si->sv_knconf->knc_protofmly,
- svp->sv_knconf->knc_protofmly) == 0 &&
+ svp->sv_knconf->knc_protofmly) == 0 &&
bcmp(si->sv_addr.buf, svp->sv_addr.buf,
- si->sv_addr.len) == 0) {
+ si->sv_addr.len) == 0) {
/* it's a duplicate */
return (1);
}
@@ -310,7 +402,7 @@ nfs4_free_args(struct nfs_args *nargs)
if (nargs->knconf) {
if (nargs->knconf->knc_protofmly)
kmem_free(nargs->knconf->knc_protofmly,
- KNC_STRSIZE);
+ KNC_STRSIZE);
if (nargs->knconf->knc_proto)
kmem_free(nargs->knconf->knc_proto, KNC_STRSIZE);
kmem_free(nargs->knconf, sizeof (*nargs->knconf));
@@ -353,7 +445,7 @@ nfs4_free_args(struct nfs_args *nargs)
if (nargs->nfs_ext_u.nfs_extA.secdata) {
sec_clnt_freeinfo(
- nargs->nfs_ext_u.nfs_extA.secdata);
+ nargs->nfs_ext_u.nfs_extA.secdata);
nargs->nfs_ext_u.nfs_extA.secdata = NULL;
}
}
@@ -490,7 +582,7 @@ nfs4_copyin(char *data, int datalen, struct nfs_args *nargs)
*/
if (flags & NFSMNT_HOSTNAME) {
error = copyinstr(STRUCT_FGETP(args, hostname),
- netname, sizeof (netname), &hlen);
+ netname, sizeof (netname), &hlen);
if (error)
goto errout;
nargs->hostname = kmem_zalloc(hlen, KM_SLEEP);
@@ -512,7 +604,7 @@ nfs4_copyin(char *data, int datalen, struct nfs_args *nargs)
/* get syncaddr */
STRUCT_INIT(addr_tmp, get_udatamodel());
if (copyin(STRUCT_FGETP(args, syncaddr), STRUCT_BUF(addr_tmp),
- STRUCT_SIZE(addr_tmp))) {
+ STRUCT_SIZE(addr_tmp))) {
error = EINVAL;
goto errout;
}
@@ -531,7 +623,7 @@ nfs4_copyin(char *data, int datalen, struct nfs_args *nargs)
/* get server's netname */
if (copyinstr(STRUCT_FGETP(args, netname), netname,
- sizeof (netname), &nlen)) {
+ sizeof (netname), &nlen)) {
error = EFAULT;
goto errout;
}
@@ -548,7 +640,7 @@ nfs4_copyin(char *data, int datalen, struct nfs_args *nargs)
if (flags & NFSMNT_NEWARGS) {
nargs->nfs_args_ext = STRUCT_FGET(args, nfs_args_ext);
if (nargs->nfs_args_ext == NFS_ARGS_EXTA ||
- nargs->nfs_args_ext == NFS_ARGS_EXTB) {
+ nargs->nfs_args_ext == NFS_ARGS_EXTB) {
/*
* Indicating the application is using the new
* sec_data structure to pass in the security
@@ -558,7 +650,7 @@ nfs4_copyin(char *data, int datalen, struct nfs_args *nargs)
nfs_ext_u.nfs_extA.secdata) != NULL) {
error = sec_clnt_loadinfo(
(struct sec_data *)STRUCT_FGETP(args,
- nfs_ext_u.nfs_extA.secdata),
+ nfs_ext_u.nfs_extA.secdata),
&secdata, get_udatamodel());
}
nargs->nfs_ext_u.nfs_extA.secdata = secdata;
@@ -578,7 +670,7 @@ nfs4_copyin(char *data, int datalen, struct nfs_args *nargs)
*/
if (nargs->nfs_args_ext == NFS_ARGS_EXTB)
nargs->nfs_ext_u.nfs_extB.next =
- STRUCT_FGETP(args, nfs_ext_u.nfs_extB.next);
+ STRUCT_FGETP(args, nfs_ext_u.nfs_extB.next);
errout:
if (error)
@@ -592,7 +684,7 @@ errout:
* nfs mount vfsop
* Set up mount info record and attach it to vfs struct.
*/
-static int
+int
nfs4_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
{
char *data = uap->dataptr;
@@ -616,6 +708,7 @@ nfs4_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
return (EPERM);
if (mvp->v_type != VDIR)
return (ENOTDIR);
+
/*
* get arguments
*
@@ -640,7 +733,6 @@ more:
args = (struct nfs_args *)data;
}
-
flags = args->flags;
/*
@@ -664,15 +756,38 @@ more:
return (0);
}
+ /*
+ * For ephemeral mount trigger stub vnodes, we have two problems
+ * to solve: racing threads will likely fail the v_count check, and
+ * we want only one to proceed with the mount.
+ *
+ * For stubs, if the mount has already occurred (via a racing thread),
+ * just return success. If not, skip the v_count check and proceed.
+ * Note that we are already serialised at this point.
+ */
mutex_enter(&mvp->v_lock);
- if (!(uap->flags & MS_OVERLAY) &&
- (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
- mutex_exit(&mvp->v_lock);
- if (!(uap->flags & MS_SYSSPACE)) {
- nfs4_free_args(args);
- kmem_free(args, sizeof (*args));
+ if (vn_matchops(mvp, nfs4_trigger_vnodeops)) {
+ /* mntpt is a v4 stub vnode */
+ ASSERT(RP_ISSTUB(VTOR4(mvp)));
+ ASSERT(!(uap->flags & MS_OVERLAY));
+ ASSERT(!(mvp->v_flag & VROOT));
+ if (vn_mountedvfs(mvp) != NULL) {
+ /* ephemeral mount has already occurred */
+ ASSERT(uap->flags & MS_SYSSPACE);
+ mutex_exit(&mvp->v_lock);
+ return (0);
+ }
+ } else {
+ /* mntpt is a non-v4 or v4 non-stub vnode */
+ if (!(uap->flags & MS_OVERLAY) &&
+ (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
+ mutex_exit(&mvp->v_lock);
+ if (!(uap->flags & MS_SYSSPACE)) {
+ nfs4_free_args(args);
+ kmem_free(args, sizeof (*args));
+ }
+ return (EBUSY);
}
- return (EBUSY);
}
mutex_exit(&mvp->v_lock);
@@ -684,11 +799,10 @@ more:
/*
* A valid knetconfig structure is required.
*/
-
if (!(flags & NFSMNT_KNCONF) ||
- args->knconf == NULL || args->knconf->knc_protofmly == NULL ||
- args->knconf->knc_proto == NULL ||
- (strcmp(args->knconf->knc_proto, NC_UDP) == 0)) {
+ args->knconf == NULL || args->knconf->knc_protofmly == NULL ||
+ args->knconf->knc_proto == NULL ||
+ (strcmp(args->knconf->knc_proto, NC_UDP) == 0)) {
if (!(uap->flags & MS_SYSSPACE)) {
nfs4_free_args(args);
kmem_free(args, sizeof (*args));
@@ -697,7 +811,7 @@ more:
}
if ((strlen(args->knconf->knc_protofmly) >= KNC_STRSIZE) ||
- (strlen(args->knconf->knc_proto) >= KNC_STRSIZE)) {
+ (strlen(args->knconf->knc_proto) >= KNC_STRSIZE)) {
if (!(uap->flags & MS_SYSSPACE)) {
nfs4_free_args(args);
kmem_free(args, sizeof (*args));
@@ -705,7 +819,6 @@ more:
return (EINVAL);
}
-
/*
* Allocate a servinfo4 struct.
*/
@@ -723,11 +836,9 @@ more:
svp->sv_knconf = args->knconf;
args->knconf = NULL;
-
/*
* Get server address
*/
-
if (args->addr == NULL || args->addr->buf == NULL) {
error = EINVAL;
goto errout;
@@ -738,7 +849,6 @@ more:
svp->sv_addr.buf = args->addr->buf;
args->addr->buf = NULL;
-
/*
* Get the root fhandle
*/
@@ -756,7 +866,7 @@ more:
*/
if (flags & NFSMNT_HOSTNAME) {
if (args->hostname == NULL || (strlen(args->hostname) >
- MAXNETNAMELEN)) {
+ MAXNETNAMELEN)) {
error = EINVAL;
goto errout;
}
@@ -785,7 +895,7 @@ more:
addr_type = AF_INET6;
if (rdma_reachable(addr_type, &svp->sv_addr,
- &rdma_knconf) == 0) {
+ &rdma_knconf) == 0) {
/*
* If successful, hijack the orignal knconf and
* replace with the new one, depending on the flags.
@@ -811,12 +921,10 @@ more:
* Check if more servers are specified;
* Failover case, otherwise bail out of mount.
*/
- if (args->nfs_args_ext ==
- NFS_ARGS_EXTB &&
- args->nfs_ext_u.nfs_extB.next
- != NULL) {
+ if (args->nfs_args_ext == NFS_ARGS_EXTB &&
+ args->nfs_ext_u.nfs_extB.next != NULL) {
data = (char *)
- args->nfs_ext_u.nfs_extB.next;
+ args->nfs_ext_u.nfs_extB.next;
if (uap->flags & MS_RDONLY &&
!(flags & NFSMNT_SOFT)) {
if (svp_head->sv_next == NULL) {
@@ -873,8 +981,8 @@ more:
*/
if (args->flags & NFSMNT_SECURE) {
svp->sv_dhsec = create_authdh_data(args->netname,
- strlen(args->netname),
- args->syncaddr, svp->sv_knconf);
+ strlen(args->netname),
+ args->syncaddr, svp->sv_knconf);
}
/*
@@ -922,12 +1030,15 @@ more:
} else if (flags & NFSMNT_SECURE) {
/*
* NFSMNT_SECURE is deprecated but we keep it
- * to support the rouge user generated application
+ * to support the rogue user-generated application
* that may use this undocumented interface to do
- * AUTH_DH security.
+ * AUTH_DH security, e.g. our own rexd.
+ *
+ * Also note that NFSMNT_SECURE is used for passing
+ * AUTH_DH info to be used in negotiation.
*/
secdata = create_authdh_data(args->netname,
- strlen(args->netname), args->syncaddr, svp->sv_knconf);
+ strlen(args->netname), args->syncaddr, svp->sv_knconf);
} else {
secdata = kmem_alloc(sizeof (*secdata), KM_SLEEP);
@@ -1005,7 +1116,6 @@ more:
*/
proceed:
error = nfs4rootvp(&rtvp, vfsp, svp_head, flags, cr, mntzone);
-
if (error) {
/* if nfs4rootvp failed, it will free svp_head */
svp_head = NULL;
@@ -1019,6 +1129,7 @@ proceed:
*/
nfs4_error_zinit(&n4e);
nfs4setclientid(mi, cr, FALSE, &n4e);
+
error = n4e.error;
if (error)
@@ -1034,6 +1145,14 @@ proceed:
mutex_exit(&mi->mi_lock);
}
error = nfs4_setopts(rtvp, DATAMODEL_NATIVE, args);
+ if (error)
+ goto errout;
+
+ /*
+ * Time to tie in the mirror mount info at last!
+ */
+ if (flags & NFSMNT_EPHEMERAL)
+ nfs4_record_ephemeral_mount(mi, mvp);
errout:
if (error) {
@@ -1099,8 +1218,7 @@ errout:
*/
static int
getlinktext_otw(mntinfo4_t *mi, nfs_fh4 *fh, char **linktextp, cred_t *cr,
- int flags)
-
+ int flags)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -1151,14 +1269,14 @@ recov_retry:
if (needrecov && !recovery && num_retry-- > 0) {
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "getlinktext_otw: initiating recovery\n"));
+ "getlinktext_otw: initiating recovery\n"));
if (nfs4_start_recovery(&e, mi, NULL, NULL, NULL, NULL,
- OP_READLINK, NULL) == FALSE) {
- nfs4_end_op(mi, NULL, NULL, &recov_state, needrecov);
- if (!e.error)
- (void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ OP_READLINK, NULL) == FALSE) {
+ nfs4_end_op(mi, NULL, NULL, &recov_state, needrecov);
+ if (!e.error)
+ (void) xdr_free(xdr_COMPOUND4res_clnt,
+ (caddr_t)&res);
goto recov_retry;
}
}
@@ -1229,7 +1347,7 @@ pathname_skipslashdot(struct pathname *pnp)
*/
int
resolve_sympath(mntinfo4_t *mi, servinfo4_t *svp, int nth, nfs_fh4 *fh,
- cred_t *cr, int flags)
+ cred_t *cr, int flags)
{
char *oldpath;
char *symlink, *newpath;
@@ -1353,7 +1471,7 @@ out:
static void
nfs4getfh_otw(struct mntinfo4 *mi, servinfo4_t *svp, vtype_t *vtp,
- int flags, cred_t *cr, nfs4_error_t *ep)
+ int flags, cred_t *cr, nfs4_error_t *ep)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -1387,7 +1505,7 @@ recov_retry:
if (!recovery) {
ep->error = nfs4_start_fop(mi, NULL, NULL, OH_MOUNT,
- &recov_state, NULL);
+ &recov_state, NULL);
/*
* If recovery has been started and this request as
@@ -1472,10 +1590,10 @@ recov_retry:
if (recovery) {
nfs4args_lookup_free(argop, num_argops);
kmem_free(argop,
- lookuparg.arglen * sizeof (nfs_argop4));
+ lookuparg.arglen * sizeof (nfs_argop4));
if (!ep->error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
return;
}
@@ -1483,7 +1601,7 @@ recov_retry:
(CE_NOTE, "nfs4getfh_otw: initiating recovery\n"));
abort = nfs4_start_recovery(ep, mi, NULL,
- NULL, NULL, NULL, OP_GETFH, NULL);
+ NULL, NULL, NULL, OP_GETFH, NULL);
if (!ep->error) {
ep->error = geterrno4(res.status);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
@@ -1505,7 +1623,7 @@ recov_retry:
kmem_free(argop, lookuparg.arglen * sizeof (nfs_argop4));
if (!recovery)
nfs4_end_fop(mi, NULL, NULL, OH_MOUNT, &recov_state,
- needrecov);
+ needrecov);
return;
}
@@ -1515,7 +1633,7 @@ is_link_err:
if (res.status && res.status != NFS4ERR_SYMLINK) {
if (!recovery) {
nfs4_end_fop(mi, NULL, NULL, OH_MOUNT, &recov_state,
- needrecov);
+ needrecov);
}
nfs4args_lookup_free(argop, num_argops);
kmem_free(argop, lookuparg.arglen * sizeof (nfs_argop4));
@@ -1556,10 +1674,10 @@ is_link_err:
*/
if (!recovery)
nfs4_end_fop(mi, NULL, NULL, OH_MOUNT, &recov_state,
- needrecov);
+ needrecov);
ep->error = resolve_sympath(mi, svp, nthcomp, tmpfhp, cr,
- flags);
+ flags);
nfs4args_lookup_free(argop, num_argops);
kmem_free(argop, lookuparg.arglen * sizeof (nfs_argop4));
@@ -1595,24 +1713,24 @@ is_link_err:
if (garp->n4g_ext_res->n4g_maxread == 0)
mi->mi_tsize =
- MIN(MAXBSIZE, mi->mi_tsize);
+ MIN(MAXBSIZE, mi->mi_tsize);
else
mi->mi_tsize =
- MIN(garp->n4g_ext_res->n4g_maxread,
- mi->mi_tsize);
+ MIN(garp->n4g_ext_res->n4g_maxread,
+ mi->mi_tsize);
if (garp->n4g_ext_res->n4g_maxwrite == 0)
mi->mi_stsize =
- MIN(MAXBSIZE, mi->mi_stsize);
+ MIN(MAXBSIZE, mi->mi_stsize);
else
mi->mi_stsize =
- MIN(garp->n4g_ext_res->n4g_maxwrite,
- mi->mi_stsize);
+ MIN(garp->n4g_ext_res->n4g_maxwrite,
+ mi->mi_stsize);
if (garp->n4g_ext_res->n4g_maxfilesize != 0)
mi->mi_maxfilesize =
- MIN(garp->n4g_ext_res->n4g_maxfilesize,
- mi->mi_maxfilesize);
+ MIN(garp->n4g_ext_res->n4g_maxfilesize,
+ mi->mi_maxfilesize);
/*
* If the final component is a a symbolic link, resolve the symlink,
@@ -1639,10 +1757,10 @@ is_link_err:
*/
if (!recovery)
nfs4_end_fop(mi, NULL, NULL, OH_MOUNT, &recov_state,
- needrecov);
+ needrecov);
ep->error = resolve_sympath(mi, svp, nthcomp, resfhp, cr,
- flags);
+ flags);
nfs4args_lookup_free(argop, num_argops);
kmem_free(argop, lookuparg.arglen * sizeof (nfs_argop4));
@@ -1690,7 +1808,7 @@ is_link_err:
/* initialize fsid and supp_attrs for server fs */
svp->sv_fsid = garp->n4g_fsid;
svp->sv_supp_attrs =
- garp->n4g_ext_res->n4g_suppattrs | FATTR4_MANDATTR_MASK;
+ garp->n4g_ext_res->n4g_suppattrs | FATTR4_MANDATTR_MASK;
nfs_rw_exit(&svp->sv_lock);
@@ -1726,9 +1844,9 @@ nfs4_remap_root(mntinfo4_t *mi, nfs4_error_t *ep, int flags)
remap_retry:
svp = mi->mi_curr_serv;
getfh_flags =
- (flags & NFS4_REMAP_NEEDSOP) ? NFS4_GETFH_NEEDSOP : 0;
+ (flags & NFS4_REMAP_NEEDSOP) ? NFS4_GETFH_NEEDSOP : 0;
getfh_flags |=
- (mi->mi_flags & MI4_PUBLIC) ? NFS4_GETFH_PUBLIC : 0;
+ (mi->mi_flags & MI4_PUBLIC) ? NFS4_GETFH_PUBLIC : 0;
mutex_exit(&mi->mi_lock);
/*
@@ -1792,8 +1910,8 @@ remap_retry:
if (vtype != VNON && vtype != mi->mi_type) {
/* shouldn't happen */
zcmn_err(mi->mi_zone->zone_id, CE_WARN,
- "nfs4_remap_root: server root vnode type (%d) doesn't "
- "match mount info (%d)", vtype, mi->mi_type);
+ "nfs4_remap_root: server root vnode type (%d) doesn't "
+ "match mount info (%d)", vtype, mi->mi_type);
}
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_READER, 0);
@@ -1817,7 +1935,7 @@ remap_retry:
static int
nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
- int flags, cred_t *cr, zone_t *zone)
+ int flags, cred_t *cr, zone_t *zone)
{
vnode_t *rtvp = NULL;
mntinfo4_t *mi;
@@ -1862,6 +1980,8 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
mi->mi_flags |= MI4_INT;
if (flags & NFSMNT_PUBLIC)
mi->mi_flags |= MI4_PUBLIC;
+ if (flags & NFSMNT_MIRRORMOUNT)
+ mi->mi_flags |= MI4_MIRRORMOUNT;
mi->mi_retrans = NFS_RETRIES;
if (svp->sv_knconf->knc_semantics == NC_TPI_COTS_ORD ||
svp->sv_knconf->knc_semantics == NC_TPI_COTS)
@@ -2007,8 +2127,8 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
for (svp = svp_head; svp; svp = svp->sv_next) {
if (nfs4_chkdup_servinfo4(svp_head, svp)) {
nfs_cmn_err(error, CE_WARN,
- VERS_MSG "Host %s is a duplicate%s",
- svp->sv_hostname, droptext);
+ VERS_MSG "Host %s is a duplicate%s",
+ svp->sv_hostname, droptext);
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_WRITER, 0);
svp->sv_flags |= SV4_NOTINUSE;
nfs_rw_exit(&svp->sv_lock);
@@ -2050,7 +2170,7 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
if (orig_sv_pathlen != svp->sv_pathlen) {
kmem_free(svp->sv_path, svp->sv_pathlen);
svp->sv_path = kmem_alloc(orig_sv_pathlen,
- KM_SLEEP);
+ KM_SLEEP);
svp->sv_pathlen = orig_sv_pathlen;
}
bcopy(orig_sv_path, svp->sv_path, orig_sv_pathlen);
@@ -2061,8 +2181,8 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
error = e.error ? e.error : geterrno4(e.stat);
if (error) {
nfs_cmn_err(error, CE_WARN,
- VERS_MSG "initial call to %s failed%s: %m",
- svp->sv_hostname, droptext);
+ VERS_MSG "initial call to %s failed%s: %m",
+ svp->sv_hostname, droptext);
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_WRITER, 0);
svp->sv_flags |= SV4_NOTINUSE;
nfs_rw_exit(&svp->sv_lock);
@@ -2073,8 +2193,8 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
if (tmp_vtype == VBAD) {
zcmn_err(mi->mi_zone->zone_id, CE_WARN,
- VERS_MSG "%s returned a bad file type for "
- "root%s", svp->sv_hostname, droptext);
+ VERS_MSG "%s returned a bad file type for "
+ "root%s", svp->sv_hostname, droptext);
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_WRITER, 0);
svp->sv_flags |= SV4_NOTINUSE;
nfs_rw_exit(&svp->sv_lock);
@@ -2085,8 +2205,8 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
vtype = tmp_vtype;
} else if (vtype != tmp_vtype) {
zcmn_err(mi->mi_zone->zone_id, CE_WARN,
- VERS_MSG "%s returned a different file type "
- "for root%s", svp->sv_hostname, droptext);
+ VERS_MSG "%s returned a different file type "
+ "for root%s", svp->sv_hostname, droptext);
(void) nfs_rw_enter_sig(&svp->sv_lock, RW_WRITER, 0);
svp->sv_flags |= SV4_NOTINUSE;
nfs_rw_exit(&svp->sv_lock);
@@ -2134,7 +2254,7 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
MI4_HOLD(mi);
VFS_HOLD(vfsp); /* add reference for thread */
mi->mi_manager_thread = zthread_create(NULL, 0, nfs4_async_manager,
- vfsp, 0, minclsyspri);
+ vfsp, 0, minclsyspri);
ASSERT(mi->mi_manager_thread != NULL);
/*
@@ -2144,7 +2264,7 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
*/
MI4_HOLD(mi);
mi->mi_inactive_thread = zthread_create(NULL, 0, nfs4_inactive_thread,
- mi, 0, minclsyspri);
+ mi, 0, minclsyspri);
ASSERT(mi->mi_inactive_thread != NULL);
/* If we didn't get a type, get one now */
@@ -2173,6 +2293,7 @@ bad:
*/
if (lcr != NULL)
crfree(lcr);
+
if (rtvp != NULL) {
/*
* We need to release our reference to the root vnode and
@@ -2206,9 +2327,13 @@ bad:
static int
nfs4_unmount(vfs_t *vfsp, int flag, cred_t *cr)
{
- mntinfo4_t *mi;
- ushort_t omax;
- int removed;
+ mntinfo4_t *mi;
+ ushort_t omax;
+ int removed;
+
+ bool_t must_unlock = FALSE;
+
+ nfs4_ephemeral_tree_t *eph_tree;
if (secpolicy_fs_unmount(cr, vfsp) != 0)
return (EPERM);
@@ -2227,44 +2352,60 @@ nfs4_unmount(vfs_t *vfsp, int flag, cred_t *cr)
NFS4_DEBUG(nfs4_client_zone_debug, (CE_NOTE,
"nfs4_unmount x-zone forced unmount of vfs %p\n",
(void *)vfsp));
- nfs4_free_mount(vfsp, cr);
+ nfs4_free_mount(vfsp, flag, cr);
} else {
/*
* Free data structures asynchronously, to avoid
* blocking the current thread (for performance
* reasons only).
*/
- async_free_mount(vfsp, cr);
+ async_free_mount(vfsp, flag, cr);
}
+
return (0);
}
+
/*
* Wait until all asynchronous putpage operations on
* this file system are complete before flushing rnodes
* from the cache.
*/
omax = mi->mi_max_threads;
- if (nfs4_async_stop_sig(vfsp)) {
-
+ if (nfs4_async_stop_sig(vfsp))
return (EINTR);
- }
+
r4flush(vfsp, cr);
+
+ (void) nfs4_ephemeral_umount(mi, flag, cr,
+ &must_unlock, &eph_tree);
+
/*
* If there are any active vnodes on this file system,
- * then the file system is busy and can't be umounted.
+ * then the file system is busy and can't be unmounted.
*/
if (check_rtable4(vfsp)) {
+ nfs4_ephemeral_umount_unlock(&must_unlock, &eph_tree);
+
mutex_enter(&mi->mi_async_lock);
mi->mi_max_threads = omax;
mutex_exit(&mi->mi_async_lock);
+
return (EBUSY);
}
+
+ /*
+ * The unmount can't fail from now on, so record any
+ * ephemeral changes.
+ */
+ nfs4_ephemeral_umount_activate(mi, &must_unlock, &eph_tree);
+
/*
- * The unmount can't fail from now on, and there are no active
- * files that could require over-the-wire calls to the server,
- * so stop the async manager and the inactive thread.
+ * There are no active files that could require over-the-wire
+ * calls to the server, so stop the async manager and the
+ * inactive thread.
*/
nfs4_async_manager_stop(vfsp);
+
/*
* Destroy all rnodes belonging to this file system from the
* rnode hash queues and purge any resources allocated to
@@ -2370,7 +2511,7 @@ nfs4_statvfs(vfs_t *vfsp, struct statvfs64 *sbp)
error = nfs4_statfs_otw(vp, sbp, cr);
if (!error) {
(void) strncpy(sbp->f_basetype,
- vfssw[vfsp->vfs_fstype].vsw_name, FSTYPSZ);
+ vfssw[vfsp->vfs_fstype].vsw_name, FSTYPSZ);
sbp->f_flag = vf_to_stf(vfsp->vfs_flag);
} else {
nfs4_purge_stale_fh(error, vp, cr);
@@ -2609,12 +2750,14 @@ nfs4_vfsinit(void)
{
mutex_init(&nfs4_syncbusy, NULL, MUTEX_DEFAULT, NULL);
nfs4setclientid_init();
+ nfs4_ephemeral_init();
return (0);
}
void
nfs4_vfsfini(void)
{
+ nfs4_ephemeral_fini();
nfs4setclientid_fini();
mutex_destroy(&nfs4_syncbusy);
}
@@ -2799,7 +2942,7 @@ recov_retry:
np->s_cred = lcr;
mutex_exit(&np->s_lock);
nfs4setclientid_otw(mi, svp, lcr, np, n4ep,
- &retry_inuse);
+ &retry_inuse);
}
}
mutex_enter(&np->s_lock);
@@ -2819,7 +2962,7 @@ recov_retry:
*/
if (FAILOVER_MOUNT4(mi) && nfs4_try_failover(n4ep)) {
(void) nfs4_start_recovery(n4ep, mi, NULL,
- NULL, NULL, NULL, OP_SETCLIENTID, NULL);
+ NULL, NULL, NULL, OP_SETCLIENTID, NULL);
/*
* Don't retry here, just return and let
* recovery take over.
@@ -2827,23 +2970,23 @@ recov_retry:
if (recovery)
retry = FALSE;
} else if (nfs4_rpc_retry_error(n4ep->error) ||
- n4ep->stat == NFS4ERR_RESOURCE ||
- n4ep->stat == NFS4ERR_STALE_CLIENTID) {
+ n4ep->stat == NFS4ERR_RESOURCE ||
+ n4ep->stat == NFS4ERR_STALE_CLIENTID) {
- retry = TRUE;
- /*
- * Always retry if in recovery or once had
- * contact with the server (but now it's
- * overloaded).
- */
- if (recovery == TRUE ||
- n4ep->error == ETIMEDOUT ||
- n4ep->error == ECONNRESET)
- num_retries = 0;
- } else if (retry_inuse && n4ep->error == 0 &&
- n4ep->stat == NFS4ERR_CLID_INUSE) {
- retry = TRUE;
+ retry = TRUE;
+ /*
+ * Always retry if in recovery or once had
+ * contact with the server (but now it's
+ * overloaded).
+ */
+ if (recovery == TRUE ||
+ n4ep->error == ETIMEDOUT ||
+ n4ep->error == ECONNRESET)
num_retries = 0;
+ } else if (retry_inuse && n4ep->error == 0 &&
+ n4ep->stat == NFS4ERR_CLID_INUSE) {
+ retry = TRUE;
+ num_retries = 0;
}
} else {
/*
@@ -2893,7 +3036,7 @@ int nfs4setclientid_otw_debug = 0;
*/
static void
nfs4setclientid_otw(mntinfo4_t *mi, struct servinfo4 *svp, cred_t *cr,
- struct nfs4_server *np, nfs4_error_t *ep, int *retry_inusep)
+ struct nfs4_server *np, nfs4_error_t *ep, int *retry_inusep)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -2992,7 +3135,7 @@ nfs4setclientid_otw(mntinfo4_t *mi, struct servinfo4 *svp, cred_t *cr,
if (!(*retry_inusep)) {
clid_inuse = &res.array->nfs_resop4_u.
- opsetclientid.SETCLIENTID4res_u.client_using;
+ opsetclientid.SETCLIENTID4res_u.client_using;
zcmn_err(mi->mi_zone->zone_id, CE_NOTE,
"NFS4 mount (SETCLIENTID failed)."
@@ -3016,7 +3159,7 @@ nfs4setclientid_otw(mntinfo4_t *mi, struct servinfo4 *svp, cred_t *cr,
}
s_resok = &res.array[2].nfs_resop4_u.
- opsetclientid.SETCLIENTID4res_u.resok4;
+ opsetclientid.SETCLIENTID4res_u.resok4;
tmp_clientid = s_resok->clientid;
@@ -3055,23 +3198,23 @@ nfs4setclientid_otw(mntinfo4_t *mi, struct servinfo4 *svp, cred_t *cr,
gethrestime(&prop_time);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE, "nfs4setlientid_otw: "
- "start time: %ld sec %ld nsec", prop_time.tv_sec,
- prop_time.tv_nsec));
+ "start time: %ld sec %ld nsec", prop_time.tv_sec,
+ prop_time.tv_nsec));
rfs4call(mi, &args, &res, cr, &doqueue, 0, ep);
gethrestime(&after_time);
mutex_enter(&np->s_lock);
np->propagation_delay.tv_sec =
- MAX(1, after_time.tv_sec - prop_time.tv_sec);
+ MAX(1, after_time.tv_sec - prop_time.tv_sec);
mutex_exit(&np->s_lock);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE, "nfs4setlcientid_otw: "
- "finish time: %ld sec ", after_time.tv_sec));
+ "finish time: %ld sec ", after_time.tv_sec));
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE, "nfs4setclientid_otw: "
- "propagation delay set to %ld sec",
- np->propagation_delay.tv_sec));
+ "propagation delay set to %ld sec",
+ np->propagation_delay.tv_sec));
if (ep->error)
return;
@@ -3081,7 +3224,7 @@ nfs4setclientid_otw(mntinfo4_t *mi, struct servinfo4 *svp, cred_t *cr,
if (!(*retry_inusep)) {
clid_inuse = &res.array->nfs_resop4_u.
- opsetclientid.SETCLIENTID4res_u.client_using;
+ opsetclientid.SETCLIENTID4res_u.client_using;
zcmn_err(mi->mi_zone->zone_id, CE_NOTE,
"SETCLIENTID_CONFIRM failed. "
@@ -3114,7 +3257,7 @@ nfs4setclientid_otw(mntinfo4_t *mi, struct servinfo4 *svp, cred_t *cr,
np->s_refcnt++; /* pass reference to thread */
(void) zthread_create(NULL, 0, nfs4_renew_lease_thread, np, 0,
- minclsyspri);
+ minclsyspri);
}
mutex_exit(&np->s_lock);
@@ -3138,16 +3281,16 @@ nfs4_add_mi_to_server(nfs4_server_t *sp, mntinfo4_t *mi)
ASSERT(MUTEX_HELD(&sp->s_lock));
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_add_mi_to_server: add mi %p to sp %p",
- (void*)mi, (void*)sp));
+ "nfs4_add_mi_to_server: add mi %p to sp %p",
+ (void*)mi, (void*)sp));
for (tmi = sp->mntinfo4_list;
tmi != NULL;
tmi = tmi->mi_clientid_next) {
if (tmi == mi) {
NFS4_DEBUG(nfs4_client_lease_debug,
- (CE_NOTE,
- "nfs4_add_mi_to_server: mi in list"));
+ (CE_NOTE,
+ "nfs4_add_mi_to_server: mi in list"));
in_list = 1;
}
}
@@ -3160,7 +3303,7 @@ nfs4_add_mi_to_server(nfs4_server_t *sp, mntinfo4_t *mi)
VFS_HOLD(mi->mi_vfsp);
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE, "nfs4_add_mi_to_server: "
- "hold vfs %p for mi: %p", (void*)mi->mi_vfsp, (void*)mi));
+ "hold vfs %p for mi: %p", (void*)mi->mi_vfsp, (void*)mi));
if (!in_list) {
if (sp->mntinfo4_list)
@@ -3200,8 +3343,8 @@ static void
nfs4_remove_mi_from_server_nolock(mntinfo4_t *mi, nfs4_server_t *sp)
{
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_remove_mi_from_server_nolock: remove mi %p from sp %p",
- (void*)mi, (void*)sp));
+ "nfs4_remove_mi_from_server_nolock: remove mi %p from sp %p",
+ (void*)mi, (void*)sp));
ASSERT(sp != NULL);
ASSERT(MUTEX_HELD(&sp->s_lock));
@@ -3213,8 +3356,8 @@ nfs4_remove_mi_from_server_nolock(mntinfo4_t *mi, nfs4_server_t *sp)
*/
if (mi->mi_open_files > 0) {
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "nfs4_remove_mi_from_server_nolock: don't "
- "remove mi since it still has files open"));
+ "nfs4_remove_mi_from_server_nolock: don't "
+ "remove mi since it still has files open"));
mutex_enter(&mi->mi_lock);
mi->mi_flags |= MI4_REMOVE_ON_LAST_CLOSE;
@@ -3229,7 +3372,7 @@ nfs4_remove_mi_from_server_nolock(mntinfo4_t *mi, nfs4_server_t *sp)
if (sp->mntinfo4_list == NULL) {
/* last fs unmounted, kill the thread */
NFS4_DEBUG(nfs4_client_lease_debug, (CE_NOTE,
- "remove_mi_from_nfs4_server_nolock: kill the thread"));
+ "remove_mi_from_nfs4_server_nolock: kill the thread"));
nfs4_mark_srv_dead(sp);
}
}
@@ -3607,7 +3750,7 @@ servinfo4_to_nfs4_server(servinfo4_t *srv_p)
if (np->zoneid == zoneid &&
np->saddr.len == srv_p->sv_addr.len &&
bcmp(np->saddr.buf, srv_p->sv_addr.buf,
- np->saddr.len) == 0 &&
+ np->saddr.len) == 0 &&
np->s_thread_exit != NFS4_THREAD_EXIT) {
mutex_enter(&np->s_lock);
np->s_refcnt++;
@@ -3674,7 +3817,7 @@ find_nfs4_server_all(mntinfo4_t *mi, int all)
if (nfs4_server_t_debug) {
/* mi->mi_clientid is unprotected, ok for debug output */
dumpnfs4slist("find_nfs4_server", mi, mi->mi_clientid,
- mi->mi_curr_serv);
+ mi->mi_curr_serv);
}
#endif
for (np = nfs4_server_lst.forw; np != &nfs4_server_lst; np = np->forw) {
@@ -3781,13 +3924,14 @@ nfs4_server_vlock(nfs4_server_t *sp, int all)
*/
static void
-async_free_mount(vfs_t *vfsp, cred_t *cr)
+async_free_mount(vfs_t *vfsp, int flag, cred_t *cr)
{
freemountargs_t *args;
args = kmem_alloc(sizeof (freemountargs_t), KM_SLEEP);
args->fm_vfsp = vfsp;
VFS_HOLD(vfsp);
MI4_HOLD(VFTOMI4(vfsp));
+ args->fm_flag = flag;
args->fm_cr = cr;
crhold(cr);
(void) zthread_create(NULL, 0, nfs4_free_mount_thread, args, 0,
@@ -3798,7 +3942,7 @@ static void
nfs4_free_mount_thread(freemountargs_t *args)
{
mntinfo4_t *mi;
- nfs4_free_mount(args->fm_vfsp, args->fm_cr);
+ nfs4_free_mount(args->fm_vfsp, args->fm_flag, args->fm_cr);
mi = VFTOMI4(args->fm_vfsp);
crfree(args->fm_cr);
VFS_RELE(args->fm_vfsp);
@@ -3812,14 +3956,17 @@ nfs4_free_mount_thread(freemountargs_t *args)
* Thread to free the data structures for a given filesystem.
*/
static void
-nfs4_free_mount(vfs_t *vfsp, cred_t *cr)
+nfs4_free_mount(vfs_t *vfsp, int flag, cred_t *cr)
{
- mntinfo4_t *mi = VFTOMI4(vfsp);
- nfs4_server_t *sp;
- callb_cpr_t cpr_info;
- kmutex_t cpr_lock;
- boolean_t async_thread;
- int removed;
+ mntinfo4_t *mi = VFTOMI4(vfsp);
+ nfs4_server_t *sp;
+ callb_cpr_t cpr_info;
+ kmutex_t cpr_lock;
+ boolean_t async_thread;
+ int removed;
+
+ bool_t must_unlock = FALSE;
+ nfs4_ephemeral_tree_t *eph_tree;
/*
* We need to participate in the CPR framework if this is a kernel
@@ -3879,6 +4026,10 @@ nfs4_free_mount(vfs_t *vfsp, cred_t *cr)
}
mutex_exit(&mi->mi_lock);
+ (void) nfs4_ephemeral_umount(mi, flag, cr,
+ &must_unlock, &eph_tree);
+ nfs4_ephemeral_umount_activate(mi, &must_unlock, &eph_tree);
+
/*
* The original purge of the dnlc via 'dounmount'
* doesn't guarantee that another dnlc entry was not
diff --git a/usr/src/uts/common/fs/nfs/nfs4_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_vnops.c
index 897e8fac60..f788f16bef 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c
@@ -204,15 +204,11 @@ static int nfs4_read(vnode_t *, struct uio *, int, cred_t *,
static int nfs4_write(vnode_t *, struct uio *, int, cred_t *,
caller_context_t *);
static int nfs4_ioctl(vnode_t *, int, intptr_t, int, cred_t *, int *);
-static int nfs4_getattr(vnode_t *, struct vattr *, int, cred_t *);
static int nfs4_setattr(vnode_t *, struct vattr *, int, cred_t *,
caller_context_t *);
static int nfs4_access(vnode_t *, int, int, cred_t *);
static int nfs4_readlink(vnode_t *, struct uio *, cred_t *);
static int nfs4_fsync(vnode_t *, int, cred_t *);
-static void nfs4_inactive(vnode_t *, cred_t *);
-static int nfs4_lookup(vnode_t *, char *, vnode_t **,
- struct pathname *, int, vnode_t *, cred_t *);
static int nfs4_create(vnode_t *, char *, struct vattr *, enum vcexcl,
int, vnode_t **, cred_t *, int);
static int nfs4_remove(vnode_t *, char *, cred_t *);
@@ -224,9 +220,6 @@ static int nfs4_rmdir(vnode_t *, char *, vnode_t *, cred_t *);
static int nfs4_symlink(vnode_t *, char *, struct vattr *, char *,
cred_t *);
static int nfs4_readdir(vnode_t *, struct uio *, cred_t *, int *);
-static int nfs4_fid(vnode_t *, fid_t *);
-static int nfs4_rwlock(vnode_t *, int, caller_context_t *);
-static void nfs4_rwunlock(vnode_t *, int, caller_context_t *);
static int nfs4_seek(vnode_t *, offset_t, offset_t *);
static int nfs4_getpage(vnode_t *, offset_t, size_t, uint_t *,
page_t *[], size_t, struct seg *, caddr_t,
@@ -241,16 +234,28 @@ static int nfs4_frlock(vnode_t *, int, struct flock64 *, int, offset_t,
struct flk_callback *, cred_t *);
static int nfs4_space(vnode_t *, int, struct flock64 *, int, offset_t,
cred_t *, caller_context_t *);
-static int nfs4_realvp(vnode_t *, vnode_t **);
static int nfs4_delmap(vnode_t *, offset_t, struct as *, caddr_t,
size_t, uint_t, uint_t, uint_t, cred_t *);
-static int nfs4_pathconf(vnode_t *, int, ulong_t *, cred_t *);
static int nfs4_pageio(vnode_t *, page_t *, u_offset_t, size_t, int,
cred_t *);
static void nfs4_dispose(vnode_t *, page_t *, int, int, cred_t *);
static int nfs4_setsecattr(vnode_t *, vsecattr_t *, int, cred_t *);
-static int nfs4_getsecattr(vnode_t *, vsecattr_t *, int, cred_t *);
static int nfs4_shrlock(vnode_t *, int, struct shrlock *, int, cred_t *);
+/*
+ * These vnode ops are required to be called from outside this source file,
+ * e.g. by ephemeral mount stub vnode ops, and so may not be declared
+ * as static.
+ */
+int nfs4_getattr(vnode_t *, struct vattr *, int, cred_t *);
+void nfs4_inactive(vnode_t *, cred_t *);
+int nfs4_lookup(vnode_t *, char *, vnode_t **,
+ struct pathname *, int, vnode_t *, cred_t *);
+int nfs4_fid(vnode_t *, fid_t *);
+int nfs4_rwlock(vnode_t *, int, caller_context_t *);
+void nfs4_rwunlock(vnode_t *, int, caller_context_t *);
+int nfs4_realvp(vnode_t *, vnode_t **);
+int nfs4_pathconf(vnode_t *, int, ulong_t *, cred_t *);
+int nfs4_getsecattr(vnode_t *, vsecattr_t *, int, cred_t *);
/*
* Used for nfs4_commit_vp() to indicate if we should
@@ -297,7 +302,6 @@ int nfs4_client_map_debug = 0;
static int nfs4_pageio_debug = 0;
int nfs4_client_inactive_debug = 0;
int nfs4_client_recov_debug = 0;
-int nfs4_client_recov_stub_debug = 0;
int nfs4_client_failover_debug = 0;
int nfs4_client_call_debug = 0;
int nfs4_client_lookup_debug = 0;
@@ -416,13 +420,16 @@ const fs_operation_def_t nfs4_vnodeops_template[] = {
void
nfs4args_lookup_free(nfs_argop4 *argop, int arglen)
{
- int i;
+ int i;
for (i = 0; i < arglen; i++) {
- if (argop[i].argop == OP_LOOKUP)
- kmem_free(
- argop[i].nfs_argop4_u.oplookup.objname.utf8string_val,
- argop[i].nfs_argop4_u.oplookup.objname.utf8string_len);
+ if (argop[i].argop == OP_LOOKUP) {
+ kmem_free(
+ argop[i].nfs_argop4_u.oplookup.
+ objname.utf8string_val,
+ argop[i].nfs_argop4_u.oplookup.
+ objname.utf8string_len);
+ }
}
}
@@ -437,7 +444,7 @@ nfs4args_lock_free(nfs_argop4 *argop)
open_owner = &locker->locker4_u.open_owner;
if (open_owner->lock_owner.owner_val != NULL) {
kmem_free(open_owner->lock_owner.owner_val,
- open_owner->lock_owner.owner_len);
+ open_owner->lock_owner.owner_len);
}
}
}
@@ -454,8 +461,8 @@ nfs4args_lockt_free(nfs_argop4 *argop)
static void
nfs4args_setattr(nfs_argop4 *argop, vattr_t *vap, vsecattr_t *vsap, int flags,
- rnode4_t *rp, cred_t *cr, bitmap4 supp, int *error,
- nfs4_stateid_types_t *sid_types)
+ rnode4_t *rp, cred_t *cr, bitmap4 supp, int *error,
+ nfs4_stateid_types_t *sid_types)
{
fattr4 *attr = &argop->nfs_argop4_u.opsetattr.obj_attributes;
mntinfo4_t *mi;
@@ -476,8 +483,8 @@ nfs4args_setattr(nfs_argop4 *argop, vattr_t *vap, vsecattr_t *vsap, int flags,
mi = VTOMI4(RTOV4(rp));
argop->nfs_argop4_u.opsetattr.stateid =
- nfs4_get_stateid(cr, rp, curproc->p_pidp->pid_id, mi,
- OP_SETATTR, sid_types, FALSE);
+ nfs4_get_stateid(cr, rp, curproc->p_pidp->pid_id, mi,
+ OP_SETATTR, sid_types, FALSE);
} else {
bzero(&argop->nfs_argop4_u.opsetattr.stateid,
sizeof (stateid4));
@@ -496,7 +503,7 @@ nfs4args_setattr_free(nfs_argop4 *argop)
static int
nfs4args_verify(nfs_argop4 *argop, vattr_t *vap, enum nfs_opnum4 op,
- bitmap4 supp)
+ bitmap4 supp)
{
fattr4 *attr;
int error = 0;
@@ -536,7 +543,7 @@ nfs4args_verify_free(nfs_argop4 *argop)
static void
nfs4args_write(nfs_argop4 *argop, stable_how4 stable, rnode4_t *rp, cred_t *cr,
- WRITE4args **wargs_pp, nfs4_stateid_types_t *sid_tp)
+ WRITE4args **wargs_pp, nfs4_stateid_types_t *sid_tp)
{
WRITE4args *wargs = &argop->nfs_argop4_u.opwrite;
mntinfo4_t *mi = VTOMI4(RTOV4(rp));
@@ -544,7 +551,7 @@ nfs4args_write(nfs_argop4 *argop, stable_how4 stable, rnode4_t *rp, cred_t *cr,
argop->argop = OP_WRITE;
wargs->stable = stable;
wargs->stateid = nfs4_get_w_stateid(cr, rp, curproc->p_pidp->pid_id,
- mi, OP_WRITE, sid_tp);
+ mi, OP_WRITE, sid_tp);
wargs->mblk = NULL;
*wargs_pp = wargs;
}
@@ -554,7 +561,7 @@ nfs4args_copen_free(OPEN4cargs *open_args)
{
if (open_args->owner.owner_val) {
kmem_free(open_args->owner.owner_val,
- open_args->owner.owner_len);
+ open_args->owner.owner_len);
}
if ((open_args->opentype == OPEN4_CREATE) &&
(open_args->mode != EXCLUSIVE4)) {
@@ -645,7 +652,7 @@ nfs4_open(vnode_t **vpp, int flag, cred_t *cr)
flag |= FWRITE;
error = nfs4open_otw(dvp, fn, NULL, vpp, cr, 0, flag, 0,
- just_been_created);
+ just_been_created);
if (!error && !((*vpp)->v_flag & VROOT))
dnlc_update(dvp, fn, *vpp);
@@ -668,8 +675,8 @@ nfs4_open(vnode_t **vpp, int flag, cred_t *cr)
*/
static void
nfs4open_save_lost_rqst(int error, nfs4_lost_rqst_t *lost_rqstp,
- nfs4_open_owner_t *oop, cred_t *cr, vnode_t *vp,
- vnode_t *dvp, OPEN4cargs *open_args)
+ nfs4_open_owner_t *oop, cred_t *cr, vnode_t *vp,
+ vnode_t *dvp, OPEN4cargs *open_args)
{
vfs_t *vfsp;
char *srccfp;
@@ -677,15 +684,16 @@ nfs4open_save_lost_rqst(int error, nfs4_lost_rqst_t *lost_rqstp,
vfsp = (dvp ? dvp->v_vfsp : vp->v_vfsp);
if (error != ETIMEDOUT && error != EINTR &&
- !NFS4_FRC_UNMT_ERR(error, vfsp)) {
+ !NFS4_FRC_UNMT_ERR(error, vfsp)) {
lost_rqstp->lr_op = 0;
return;
}
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE,
- "nfs4open_save_lost_rqst: error %d", error));
+ "nfs4open_save_lost_rqst: error %d", error));
lost_rqstp->lr_op = OP_OPEN;
+
/*
* The vp (if it is not NULL) and dvp are held and rele'd via
* the recovery code. See nfs4_save_lost_rqst.
@@ -725,8 +733,8 @@ struct nfs4_excl_time {
*/
static int
nfs4open_otw(vnode_t *dvp, char *file_name, struct vattr *in_va,
- vnode_t **vpp, cred_t *cr, int create_flag, int open_flag,
- enum createmode4 createmode, int file_just_been_created)
+ vnode_t **vpp, cred_t *cr, int create_flag, int open_flag,
+ enum createmode4 createmode, int file_just_been_created)
{
rnode4_t *rp;
rnode4_t *drp = VTOR4(dvp);
@@ -825,8 +833,8 @@ nfs4open_otw(vnode_t *dvp, char *file_name, struct vattr *in_va,
argop = kmem_alloc(argoplist_size, KM_SLEEP);
NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE, "nfs4open_otw: "
- "open %s open flag 0x%x cred %p", file_name, open_flag,
- (void *)cr));
+ "open %s open flag 0x%x cred %p", file_name, open_flag,
+ (void *)cr));
ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
if (create_flag) {
@@ -940,12 +948,12 @@ recov_retry:
/* GUARDED4 or UNCHECKED4 */
v_error = vattr_to_fattr4(in_va, NULL, attr, 0, OP_OPEN,
- supp_attrs);
+ supp_attrs);
if (v_error) {
bzero(attr, sizeof (*attr));
nfs4args_copen_free(open_args);
nfs4_end_op(VTOMI4(dvp), dvp, vpi,
- &recov_state, FALSE);
+ &recov_state, FALSE);
if (ncr != NULL)
crfree(ncr);
kmem_free(argop, argoplist_size);
@@ -1005,7 +1013,7 @@ recov_retry:
/* Check to see if we need to do the OTW call */
if (!create_flag) {
if (!nfs4_is_otw_open_necessary(oop, open_flag, vpi,
- file_just_been_created, &e.error, acc, &recov_state)) {
+ file_just_been_created, &e.error, acc, &recov_state)) {
/*
* The OTW open is not necessary. Either
@@ -1152,13 +1160,13 @@ recov_retry:
if (!e.error && res.status == NFS4ERR_BAD_SEQID) {
bsep = nfs4_create_bseqid_entry(oop, NULL,
- vpi, 0, args.ctag, open_args->seqid);
+ vpi, 0, args.ctag, open_args->seqid);
num_bseqid_retry--;
}
abort = nfs4_start_recovery(&e, VTOMI4(dvp), dvp, vpi,
- NULL, lost_rqst.lr_op == OP_OPEN ?
- &lost_rqst : NULL, OP_OPEN, bsep);
+ NULL, lost_rqst.lr_op == OP_OPEN ?
+ &lost_rqst : NULL, OP_OPEN, bsep);
if (bsep)
kmem_free(bsep, sizeof (*bsep));
@@ -1324,7 +1332,7 @@ recov_retry:
}
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
nfs4_end_op(VTOMI4(dvp), dvp, vpi, &recov_state,
- needrecov);
+ needrecov);
open_owner_rele(oop);
VN_RELE(vp);
if (ncr != NULL)
@@ -1364,7 +1372,7 @@ recov_retry:
}
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
nfs4_end_op(VTOMI4(dvp), dvp, vpi, &recov_state,
- needrecov);
+ needrecov);
open_owner_rele(oop);
if (create_flag || fh_differs) {
/* rele the makenfs4node */
@@ -1488,9 +1496,9 @@ recov_retry:
nfs4_end_op(VTOMI4(dvp), dvp, vpi, &recov_state, needrecov);
if (createmode == EXCLUSIVE4 &&
- (in_va->va_mask & ~(AT_GID | AT_SIZE))) {
+ (in_va->va_mask & ~(AT_GID | AT_SIZE))) {
NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE, "nfs4open_otw:"
- " EXCLUSIVE4: sending a SETATTR"));
+ " EXCLUSIVE4: sending a SETATTR"));
/*
* If doing an exclusive create, then generate
* a SETATTR to set the initial attributes.
@@ -1527,8 +1535,8 @@ recov_retry:
*/
/* XXX will this take care of client state ? */
NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE,
- "nfs4open_otw: EXCLUSIVE4: error %d on SETATTR:"
- " remove file", e.error));
+ "nfs4open_otw: EXCLUSIVE4: error %d on SETATTR:"
+ " remove file", e.error));
VN_RELE(vp);
(void) nfs4_remove(dvp, file_name, cr);
/*
@@ -1560,14 +1568,14 @@ recov_retry:
dinfo.di_time_call = t;
dinfo.di_cred = cr;
dinfo.di_garp =
- &res.array[6].nfs_resop4_u.opgetattr.ga_res;
+ &res.array[6].nfs_resop4_u.opgetattr.ga_res;
dinfop = &dinfo;
} else {
dinfop = NULL;
}
nfs4_update_dircaches(&op_res->cinfo, dvp, vp, file_name,
- dinfop);
+ dinfop);
}
/*
@@ -1632,8 +1640,8 @@ skip_update_dircaches:
void
nfs4_reopen(vnode_t *vp, nfs4_open_stream_t *osp, nfs4_error_t *ep,
- open_claim_type4 claim, bool_t frc_use_claim_previous,
- bool_t is_recov)
+ open_claim_type4 claim, bool_t frc_use_claim_previous,
+ bool_t is_recov)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -1755,8 +1763,8 @@ top:
* use the mntinfo parentfh
*/
argop[0].nfs_argop4_u.opcputfh.sfh =
- (vp->v_flag & VROOT) ? mi->mi_srvparentfh :
- VTOSV(vp)->sv_dfh;
+ (vp->v_flag & VROOT) ? mi->mi_srvparentfh :
+ VTOSV(vp)->sv_dfh;
} else {
/* putfh fh to reopen */
argop[0].nfs_argop4_u.opcputfh.sfh = rp->r_fh;
@@ -1796,9 +1804,9 @@ top:
*/
mutex_enter(&rp->r_statev4_lock);
open_args->open_claim4_u.delegate_type =
- frc_use_claim_previous ?
- rp->r_deleg_type :
- rp->r_deleg_needs_recovery;
+ frc_use_claim_previous ?
+ rp->r_deleg_type :
+ rp->r_deleg_needs_recovery;
mutex_exit(&rp->r_statev4_lock);
} else if (claim == CLAIM_DELEGATE_CUR) {
@@ -1815,7 +1823,7 @@ top:
mutex_enter(&rp->r_statev4_lock);
open_args->open_claim4_u.delegate_cur_info.delegate_stateid =
- rp->r_deleg_stateid;
+ rp->r_deleg_stateid;
mutex_exit(&rp->r_statev4_lock);
open_args->open_claim4_u.delegate_cur_info.cfile = fn;
@@ -1824,9 +1832,9 @@ top:
open_args->owner.clientid = mi2clientid(mi);
open_args->owner.owner_len = sizeof (oop->oo_name);
open_args->owner.owner_val =
- kmem_alloc(open_args->owner.owner_len, KM_SLEEP);
+ kmem_alloc(open_args->owner.owner_len, KM_SLEEP);
bcopy(&oop->oo_name, open_args->owner.owner_val,
- open_args->owner.owner_len);
+ open_args->owner.owner_len);
open_args->share_access = 0;
open_args->share_deny = 0;
@@ -1868,11 +1876,11 @@ top:
(ep->error == EINTR || ep->error == ETIMEDOUT ||
NFS4_FRC_UNMT_ERR(ep->error, vp->v_vfsp))) {
nfs4open_save_lost_rqst(ep->error, &lost_rqst, oop,
- cred_otw, vp, NULL, open_args);
+ cred_otw, vp, NULL, open_args);
abort = nfs4_start_recovery(ep,
- VTOMI4(vp), vp, NULL, NULL,
- lost_rqst.lr_op == OP_OPEN ?
- &lost_rqst : NULL, OP_OPEN, NULL);
+ VTOMI4(vp), vp, NULL, NULL,
+ lost_rqst.lr_op == OP_OPEN ?
+ &lost_rqst : NULL, OP_OPEN, NULL);
nfs4args_copen_free(open_args);
goto bailout;
}
@@ -1907,11 +1915,11 @@ top:
break;
case NFS4ERR_BAD_SEQID:
bsep = nfs4_create_bseqid_entry(oop, NULL, vp, 0,
- args.ctag, open_args->seqid);
+ args.ctag, open_args->seqid);
abort = nfs4_start_recovery(ep, VTOMI4(vp), vp, NULL,
- NULL, lost_rqst.lr_op == OP_OPEN ? &lost_rqst :
- NULL, OP_OPEN, bsep);
+ NULL, lost_rqst.lr_op == OP_OPEN ? &lost_rqst :
+ NULL, OP_OPEN, bsep);
nfs4args_copen_free(open_args);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
@@ -1970,7 +1978,7 @@ top:
case NFS4ERR_FHEXPIRED:
/* recover filehandle and retry */
abort = nfs4_start_recovery(ep,
- mi, vp, NULL, NULL, NULL, OP_OPEN, NULL);
+ mi, vp, NULL, NULL, NULL, OP_OPEN, NULL);
nfs4args_copen_free(open_args);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
nfs4_end_open_seqid_sync(oop);
@@ -2067,11 +2075,11 @@ top:
* compare. So kill the file.
*/
failed_msg =
- "Couldn't reopen: file handle changed"
+ "Couldn't reopen: file handle changed"
" due to mismatched fids";
nfs4args_copen_free(open_args);
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
nfs_rw_exit(&mi->mi_fh_lock);
goto kill_file;
} else {
@@ -2107,8 +2115,8 @@ top:
bool_t retry_open = FALSE;
nfs4open_confirm(vp, &seqid, &op_res->stateid,
- cred_otw, is_recov, &retry_open,
- oop, FALSE, ep, NULL);
+ cred_otw, is_recov, &retry_open,
+ oop, FALSE, ep, NULL);
if (ep->error || ep->stat) {
nfs4args_copen_free(open_args);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
@@ -2192,7 +2200,7 @@ nfs4_open_non_reg_file(vnode_t **vpp, int flag, cred_t *cr)
*/
rp = VTOR4(*vpp);
if (VTOMI4(*vpp)->mi_flags & MI4_NOCTO ||
- (rp->r_dir == NULL && !nfs4_has_pages(*vpp)))
+ (rp->r_dir == NULL && !nfs4_has_pages(*vpp)))
return (0);
gar.n4g_va.va_mask = AT_ALL;
@@ -2321,8 +2329,8 @@ nfs4_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr)
static void
nfs4close_save_lost_rqst(int error, nfs4_lost_rqst_t *lost_rqstp,
- nfs4_open_owner_t *oop, nfs4_open_stream_t *osp, cred_t *cr,
- vnode_t *vp)
+ nfs4_open_owner_t *oop, nfs4_open_stream_t *osp, cred_t *cr,
+ vnode_t *vp)
{
if (error != ETIMEDOUT && error != EINTR &&
!NFS4_FRC_UNMT_ERR(error, vp->v_vfsp)) {
@@ -2331,7 +2339,7 @@ nfs4close_save_lost_rqst(int error, nfs4_lost_rqst_t *lost_rqstp,
}
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE,
- "nfs4close_save_lost_rqst: error %d", error));
+ "nfs4close_save_lost_rqst: error %d", error));
lost_rqstp->lr_op = OP_CLOSE;
/*
@@ -2365,8 +2373,8 @@ nfs4close_save_lost_rqst(int error, nfs4_lost_rqst_t *lost_rqstp,
*/
static void
nfs4close_otw(rnode4_t *rp, cred_t *cred_otw, nfs4_open_owner_t *oop,
- nfs4_open_stream_t *osp, int *recov, int *did_start_seqid_syncp,
- nfs4_close_type_t close_type, nfs4_error_t *ep, int *have_sync_lockp)
+ nfs4_open_stream_t *osp, int *recov, int *did_start_seqid_syncp,
+ nfs4_close_type_t close_type, nfs4_error_t *ep, int *have_sync_lockp)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -2454,15 +2462,15 @@ nfs4close_otw(rnode4_t *rp, cred_t *cred_otw, nfs4_open_owner_t *oop,
if (close_type != CLOSE_RESEND)
nfs4close_save_lost_rqst(ep->error, &lost_rqst, oop,
- osp, cred_otw, vp);
+ osp, cred_otw, vp);
if (!ep->error && res.status == NFS4ERR_BAD_SEQID)
bsep = nfs4_create_bseqid_entry(oop, NULL, vp,
- 0, args.ctag, close_args->seqid);
+ 0, args.ctag, close_args->seqid);
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "nfs4close_otw: initiating recovery. error %d "
- "res.status %d", ep->error, res.status));
+ "nfs4close_otw: initiating recovery. error %d "
+ "res.status %d", ep->error, res.status));
/*
* Drop the 'os_sync_lock' here so we don't hit
@@ -2472,9 +2480,9 @@ nfs4close_otw(rnode4_t *rp, cred_t *cred_otw, nfs4_open_owner_t *oop,
mutex_exit(&osp->os_sync_lock);
*have_sync_lockp = 0;
abort = nfs4_start_recovery(ep, VTOMI4(vp), vp, NULL, NULL,
- (close_type != CLOSE_RESEND &&
- lost_rqst.lr_op == OP_CLOSE) ? &lost_rqst : NULL,
- OP_CLOSE, bsep);
+ (close_type != CLOSE_RESEND &&
+ lost_rqst.lr_op == OP_CLOSE) ? &lost_rqst : NULL,
+ OP_CLOSE, bsep);
/* drop open seq sync, and let the calling function regrab it */
nfs4_end_open_seqid_sync(oop);
@@ -2529,11 +2537,11 @@ nfs4close_otw(rnode4_t *rp, cred_t *cred_otw, nfs4_open_owner_t *oop,
if (!ep->error)
nfs4_attr_cache(vp,
- &res.array[1].nfs_resop4_u.opgetattr.ga_res,
- t, cred_otw, TRUE, NULL);
+ &res.array[1].nfs_resop4_u.opgetattr.ga_res,
+ t, cred_otw, TRUE, NULL);
NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE, "nfs4close_otw:"
- " returning %d", ep->error));
+ " returning %d", ep->error));
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
}
@@ -2541,7 +2549,7 @@ nfs4close_otw(rnode4_t *rp, cred_t *cred_otw, nfs4_open_owner_t *oop,
/* ARGSUSED */
static int
nfs4_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
- caller_context_t *ct)
+ caller_context_t *ct)
{
rnode4_t *rp;
u_offset_t off;
@@ -2594,7 +2602,7 @@ nfs4_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
size_t resid = 0;
return (nfs4read(vp, NULL, uiop->uio_loffset,
- uiop->uio_resid, &resid, cr, FALSE, uiop));
+ uiop->uio_resid, &resid, cr, FALSE, uiop));
}
error = 0;
@@ -2620,11 +2628,10 @@ nfs4_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
* Copy data.
*/
error = vpm_data_copy(vp, off + on, n, uiop,
- 1, NULL, 0, S_READ);
-
+ 1, NULL, 0, S_READ);
} else {
base = segmap_getmapflt(segkmap, vp, off + on, n, 1,
- S_READ);
+ S_READ);
error = uiomove(base + on, n, UIO_READ, uiop);
}
@@ -2661,7 +2668,7 @@ nfs4_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
/* ARGSUSED */
static int
nfs4_write(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
- caller_context_t *ct)
+ caller_context_t *ct)
{
rlim64_t limit = uiop->uio_llimit;
rnode4_t *rp;
@@ -2798,7 +2805,7 @@ nfs4_fwrite:
error = uiomove(base, count, UIO_WRITE, uiop);
if (!error) {
error = nfs4write(vp, base, org_offset,
- count, cr, &stab_comm);
+ count, cr, &stab_comm);
if (!error) {
mutex_enter(&rp->r_statelock);
if (rp->r_size < uiop->uio_loffset)
@@ -2853,23 +2860,23 @@ nfs4_fwrite:
if (segmap_kpm) {
int pon = uiop->uio_loffset & PAGEOFFSET;
size_t pn = MIN(PAGESIZE - pon,
- uiop->uio_resid);
+ uiop->uio_resid);
int pagecreate;
mutex_enter(&rp->r_statelock);
pagecreate = (pon == 0) && (pn == PAGESIZE ||
- uiop->uio_loffset + pn >= rp->r_size);
+ uiop->uio_loffset + pn >= rp->r_size);
mutex_exit(&rp->r_statelock);
base = segmap_getmapflt(segkmap, vp, off + on,
- pn, !pagecreate, S_WRITE);
+ pn, !pagecreate, S_WRITE);
error = writerp4(rp, base + pon, n, uiop,
- pagecreate);
+ pagecreate);
} else {
base = segmap_getmapflt(segkmap, vp, off + on,
- n, 0, S_READ);
+ n, 0, S_READ);
error = writerp4(rp, base + on, n, uiop, 0);
}
}
@@ -2940,7 +2947,7 @@ bottom:
*/
static int
nfs4_rdwrlbn(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
- int flags, cred_t *cr)
+ int flags, cred_t *cr)
{
struct buf *bp;
int error;
@@ -3057,7 +3064,7 @@ nfs4rdwr_check_osid(vnode_t *vp, nfs4_error_t *ep, cred_t *cr)
*/
static int
nfs4write(vnode_t *vp, caddr_t base, u_offset_t offset, int count, cred_t *cr,
- stable_how4 *stab_comm)
+ stable_how4 *stab_comm)
{
mntinfo4_t *mi;
COMPOUND4args_clnt args;
@@ -3094,7 +3101,7 @@ recov_retry:
args.array = argop;
e.error = nfs4_start_fop(VTOMI4(vp), vp, NULL, OH_WRITE,
- &recov_state, NULL);
+ &recov_state, NULL);
if (e.error)
return (e.error);
@@ -3134,7 +3141,7 @@ recov_retry:
needrecov = nfs4_needs_recovery(&e, FALSE, mi->mi_vfsp);
if (e.error && !needrecov) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
return (e.error);
}
@@ -3152,28 +3159,28 @@ recov_retry:
sid_types.cur_sid_type != SPEC_SID) {
nfs4_save_stateid(&wargs->stateid, &sid_types);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
goto recov_retry;
} else if (e.error == 0 && res.status == NFS4ERR_BAD_STATEID &&
- sid_types.cur_sid_type == DEL_SID) {
+ sid_types.cur_sid_type == DEL_SID) {
nfs4_save_stateid(&wargs->stateid, &sid_types);
mutex_enter(&rp->r_statev4_lock);
rp->r_deleg_return_pending = TRUE;
mutex_exit(&rp->r_statev4_lock);
if (nfs4rdwr_check_osid(vp, &e, cr)) {
nfs4_end_fop(mi, vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
return (EIO);
}
nfs4_end_fop(mi, vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
/* hold needed for nfs4delegreturn_thread */
VN_HOLD(vp);
nfs4delegreturn_async(rp, (NFS4_DR_PUSH|NFS4_DR_REOPEN|
- NFS4_DR_DISCARD), FALSE);
+ NFS4_DR_DISCARD), FALSE);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
goto recov_retry;
}
@@ -3182,19 +3189,19 @@ recov_retry:
bool_t abort;
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "nfs4write: client got error %d, res.status %d"
- ", so start recovery", e.error, res.status));
+ "nfs4write: client got error %d, res.status %d"
+ ", so start recovery", e.error, res.status));
abort = nfs4_start_recovery(&e,
- VTOMI4(vp), vp, NULL, &wargs->stateid,
- NULL, OP_WRITE, NULL);
+ VTOMI4(vp), vp, NULL, &wargs->stateid,
+ NULL, OP_WRITE, NULL);
if (!e.error) {
e.error = geterrno4(res.status);
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
}
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
if (abort == FALSE)
goto recov_retry;
return (e.error);
@@ -3204,7 +3211,7 @@ recov_retry:
e.error = geterrno4(res.status);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
return (e.error);
}
@@ -3215,10 +3222,10 @@ recov_retry:
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
zcmn_err(getzoneid(), CE_WARN,
- "nfs4write: server wrote %u, requested was %u",
+ "nfs4write: server wrote %u, requested was %u",
(int)wres->count, tsize);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
return (EIO);
}
if (wres->committed == UNSTABLE4) {
@@ -3226,13 +3233,13 @@ recov_retry:
if (wargs->stable == DATA_SYNC4 ||
wargs->stable == FILE_SYNC4) {
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
zcmn_err(getzoneid(), CE_WARN,
- "nfs4write: server %s did not commit "
- "to stable storage",
- rp->r_server->sv_hostname);
+ "nfs4write: server %s did not commit "
+ "to stable storage",
+ rp->r_server->sv_hostname);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_WRITE,
- &recov_state, needrecov);
+ &recov_state, needrecov);
return (EIO);
}
}
@@ -3277,7 +3284,7 @@ recov_retry:
*/
static int
nfs4read(vnode_t *vp, caddr_t base, offset_t offset, int count,
- size_t *residp, cred_t *cr, bool_t async, struct uio *uiop)
+ size_t *residp, cred_t *cr, bool_t async, struct uio *uiop)
{
mntinfo4_t *mi;
COMPOUND4args_clnt args;
@@ -3312,7 +3319,7 @@ nfs4read(vnode_t *vp, caddr_t base, offset_t offset, int count,
recov_retry:
e.error = nfs4_start_fop(mi, vp, NULL, OH_READ,
- &recov_state, NULL);
+ &recov_state, NULL);
if (e.error)
return (e.error);
@@ -3324,7 +3331,7 @@ recov_retry:
argop[1].argop = OP_READ;
rargs = &argop[1].nfs_argop4_u.opread;
rargs->stateid = nfs4_get_stateid(cr, rp, curproc->p_pidp->pid_id, mi,
- OP_READ, &sid_types, async);
+ OP_READ, &sid_types, async);
do {
if (mi->mi_io_kstats) {
@@ -3373,7 +3380,7 @@ recov_retry:
needrecov = nfs4_needs_recovery(&e, FALSE, mi->mi_vfsp);
if (e.error != 0 && !needrecov) {
nfs4_end_fop(mi, vp, NULL, OH_READ,
- &recov_state, needrecov);
+ &recov_state, needrecov);
return (e.error);
}
@@ -3394,41 +3401,41 @@ recov_retry:
if (e.error == 0 && (res.status == NFS4ERR_OLD_STATEID ||
res.status == NFS4ERR_BAD_STATEID) && async) {
nfs4_end_fop(mi, vp, NULL, OH_READ,
- &recov_state, needrecov);
+ &recov_state, needrecov);
if (sid_types.cur_sid_type == SPEC_SID) {
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
return (EIO);
}
nfs4_save_stateid(&rargs->stateid, &sid_types);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
goto recov_retry;
} else if (e.error == 0 && res.status == NFS4ERR_OLD_STATEID &&
- !async && sid_types.cur_sid_type != SPEC_SID) {
+ !async && sid_types.cur_sid_type != SPEC_SID) {
nfs4_save_stateid(&rargs->stateid, &sid_types);
nfs4_end_fop(mi, vp, NULL, OH_READ,
- &recov_state, needrecov);
+ &recov_state, needrecov);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
goto recov_retry;
} else if (e.error == 0 && res.status == NFS4ERR_BAD_STATEID &&
- sid_types.cur_sid_type == DEL_SID) {
+ sid_types.cur_sid_type == DEL_SID) {
nfs4_save_stateid(&rargs->stateid, &sid_types);
mutex_enter(&rp->r_statev4_lock);
rp->r_deleg_return_pending = TRUE;
mutex_exit(&rp->r_statev4_lock);
if (nfs4rdwr_check_osid(vp, &e, cr)) {
nfs4_end_fop(mi, vp, NULL, OH_READ,
- &recov_state, needrecov);
+ &recov_state, needrecov);
(void) xdr_free(xdr_COMPOUND4res_clnt,
(caddr_t)&res);
return (EIO);
}
nfs4_end_fop(mi, vp, NULL, OH_READ,
- &recov_state, needrecov);
+ &recov_state, needrecov);
/* hold needed for nfs4delegreturn_thread */
VN_HOLD(vp);
nfs4delegreturn_async(rp, (NFS4_DR_PUSH|NFS4_DR_REOPEN|
- NFS4_DR_DISCARD), FALSE);
+ NFS4_DR_DISCARD), FALSE);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
goto recov_retry;
}
@@ -3439,10 +3446,10 @@ recov_retry:
"nfs4read: initiating recovery\n"));
abort = nfs4_start_recovery(&e,
- mi, vp, NULL, &rargs->stateid,
- NULL, OP_READ, NULL);
+ mi, vp, NULL, &rargs->stateid,
+ NULL, OP_READ, NULL);
nfs4_end_fop(mi, vp, NULL, OH_READ,
- &recov_state, needrecov);
+ &recov_state, needrecov);
/*
* Do not retry if we got OLD_STATEID using a special
* stateid. This avoids looping with a broken server.
@@ -3460,14 +3467,14 @@ recov_retry:
*/
nfs4_init_stateid_types(&sid_types);
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
goto recov_retry;
}
if (!e.error) {
e.error = geterrno4(res.status);
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
}
return (e.error);
}
@@ -3475,7 +3482,7 @@ recov_retry:
if (res.status) {
e.error = geterrno4(res.status);
nfs4_end_fop(mi, vp, NULL, OH_READ,
- &recov_state, needrecov);
+ &recov_state, needrecov);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
return (e.error);
}
@@ -3518,7 +3525,7 @@ nfs4_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
}
}
-static int
+int
nfs4_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
{
int error;
@@ -3567,11 +3574,11 @@ nfs4_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
rp->r_gcount++;
mutex_exit(&rp->r_statelock);
error =
- nfs4_putpage(vp, (u_offset_t)0,
- 0, 0, cr);
+ nfs4_putpage(vp, (u_offset_t)0,
+ 0, 0, cr);
mutex_enter(&rp->r_statelock);
if (error && (error == ENOSPC ||
- error == EDQUOT)) {
+ error == EDQUOT)) {
if (!rp->r_error)
rp->r_error = error;
}
@@ -3605,7 +3612,7 @@ nfs4_compare_modes(mode_t from_server, mode_t on_client)
/*ARGSUSED4*/
static int
nfs4_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
- caller_context_t *ct)
+ caller_context_t *ct)
{
if (vap->va_mask & AT_NOSET)
return (EINVAL);
@@ -3643,7 +3650,7 @@ nfs4_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
*/
static int
nfs4setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
- vsecattr_t *vsap)
+ vsecattr_t *vsap)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res, *resp = NULL;
@@ -3711,7 +3718,7 @@ nfs4setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
*/
mutex_enter(&rp->r_statev4_lock);
if (rp->r_deleg_type == OPEN_DELEGATE_NONE ||
- rp->r_deleg_return_pending) {
+ rp->r_deleg_return_pending) {
numops = 5;
ctime = rp->r_attr.va_ctime;
}
@@ -3759,13 +3766,13 @@ recov_retry:
nfs_rw_exit(&svp->sv_lock);
nfs4args_setattr(&argop[setattr_argop], vap, vsap, flags, rp, cr,
- supp_attrs, &e.error, &sid_types);
+ supp_attrs, &e.error, &sid_types);
stateid = argop[setattr_argop].nfs_argop4_u.opsetattr.stateid;
if (e.error) {
/* req time field(s) overflow - return immediately */
nfs4_end_op(VTOMI4(vp), vp, NULL, &recov_state, needrecov);
nfs4_fattr4_free(&argop[setattr_argop].nfs_argop4_u.
- opsetattr.obj_attributes);
+ opsetattr.obj_attributes);
return (e.error);
}
omode = rp->r_attr.va_mode;
@@ -3800,11 +3807,11 @@ recov_retry:
supp_attrs = svp->sv_supp_attrs;
nfs_rw_exit(&svp->sv_lock);
e.error = nfs4args_verify(&argop[verify_argop], &va,
- OP_VERIFY, supp_attrs);
+ OP_VERIFY, supp_attrs);
if (e.error) {
/* req time field(s) overflow - return */
nfs4_end_op(VTOMI4(vp), vp, NULL, &recov_state,
- needrecov);
+ needrecov);
break;
}
}
@@ -3867,10 +3874,10 @@ recov_retry:
sid_types.cur_sid_type != SPEC_SID &&
sid_types.cur_sid_type != NO_SID) {
nfs4_end_op(VTOMI4(vp), vp, NULL, &recov_state,
- needrecov);
+ needrecov);
nfs4_save_stateid(&stateid, &sid_types);
nfs4_fattr4_free(&argop[setattr_argop].nfs_argop4_u.
- opsetattr.obj_attributes);
+ opsetattr.obj_attributes);
if (verify_argop != -1) {
nfs4args_verify_free(&argop[verify_argop]);
verify_argop = -1;
@@ -3883,10 +3890,10 @@ recov_retry:
bool_t abort;
abort = nfs4_start_recovery(&e,
- VTOMI4(vp), vp, NULL, NULL, NULL,
- OP_SETATTR, NULL);
+ VTOMI4(vp), vp, NULL, NULL, NULL,
+ OP_SETATTR, NULL);
nfs4_end_op(VTOMI4(vp), vp, NULL, &recov_state,
- needrecov);
+ needrecov);
/*
* Do not retry if we failed with OLD_STATEID using
* a special stateid. This is done to avoid looping
@@ -3903,10 +3910,10 @@ recov_retry:
e.error = geterrno4(res.status);
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
}
nfs4_fattr4_free(&argop[setattr_argop].nfs_argop4_u.
- opsetattr.obj_attributes);
+ opsetattr.obj_attributes);
if (verify_argop != -1) {
nfs4args_verify_free(&argop[verify_argop]);
verify_argop = -1;
@@ -3978,7 +3985,7 @@ recov_retry:
}
if (!e.error) {
nfs4_fattr4_free(&argop[setattr_argop].nfs_argop4_u.
- opsetattr.obj_attributes);
+ opsetattr.obj_attributes);
if (verify_argop != -1) {
nfs4args_verify_free(&argop[verify_argop]);
verify_argop = -1;
@@ -3993,7 +4000,7 @@ recov_retry:
* If we are here, rfs4call has an irrecoverable error - return
*/
nfs4_fattr4_free(&argop[setattr_argop].nfs_argop4_u.
- opsetattr.obj_attributes);
+ opsetattr.obj_attributes);
if (verify_argop != -1) {
nfs4args_verify_free(&argop[verify_argop]);
verify_argop = -1;
@@ -4083,7 +4090,7 @@ recov_retry:
* Can free up request args and res
*/
nfs4_fattr4_free(&argop[setattr_argop].nfs_argop4_u.
- opsetattr.obj_attributes);
+ opsetattr.obj_attributes);
if (verify_argop != -1) {
nfs4args_verify_free(&argop[verify_argop]);
verify_argop = -1;
@@ -4183,13 +4190,12 @@ nfs4_access(vnode_t *vp, int mode, int flags, cred_t *cr)
}
rp = VTOR4(vp);
- if (vp->v_type == VDIR) {
+ if (vp->v_type == VDIR)
argacc = ACCESS4_READ | ACCESS4_DELETE | ACCESS4_MODIFY |
- ACCESS4_EXTEND | ACCESS4_LOOKUP;
- } else {
+ ACCESS4_EXTEND | ACCESS4_LOOKUP;
+ else
argacc = ACCESS4_READ | ACCESS4_MODIFY | ACCESS4_EXTEND |
- ACCESS4_EXECUTE;
- }
+ ACCESS4_EXECUTE;
recov_state.rs_flags = 0;
recov_state.rs_num_retry_despite_err = 0;
@@ -4241,7 +4247,7 @@ recov_retry:
args.array = argop;
if (e.error = nfs4_start_fop(mi, vp, NULL, OH_ACCESS,
- &recov_state, NULL)) {
+ &recov_state, NULL)) {
if (ncrfree != NULL)
crfree(ncrfree);
return (e.error);
@@ -4282,7 +4288,7 @@ recov_retry:
&recov_state, needrecov);
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
goto recov_retry;
}
}
@@ -4308,7 +4314,7 @@ recov_retry:
if (do_getattr) {
resop++; /* getattr res */
nfs4_attr_cache(vp, &resop->nfs_resop4_u.opgetattr.ga_res,
- t, cr, FALSE, NULL);
+ t, cr, FALSE, NULL);
}
if (!e.error) {
@@ -4333,7 +4339,7 @@ recov_retry:
/* XXX-LP */
if (ncr != NULL) {
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
cred = ncr;
ncr = NULL;
goto tryagain;
@@ -4436,7 +4442,7 @@ recov_retry:
NULL, OP_READLINK, NULL) == FALSE) {
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
nfs4_end_op(VTOMI4(vp), vp, NULL, &recov_state,
needrecov);
@@ -4535,7 +4541,7 @@ nfs4_fsync(vnode_t *vp, int syncflag, cred_t *cr)
* operation while it was open, it got renamed instead. Here we
* remove the renamed file.
*/
-static void
+void
nfs4_inactive(vnode_t *vp, cred_t *cr)
{
rnode4_t *rp;
@@ -4634,7 +4640,7 @@ nfs4_inactive_otw(vnode_t *vp, cred_t *cr)
#ifdef DEBUG
name = fn_name(VTOSV(vp)->sv_name);
NFS4_DEBUG(nfs4_client_inactive_debug, (CE_NOTE, "nfs4_inactive_otw: "
- "release vnode %s", name));
+ "release vnode %s", name));
kmem_free(name, MAXNAMELEN);
#endif
@@ -4656,8 +4662,8 @@ nfs4_inactive_otw(vnode_t *vp, cred_t *cr)
}
if (recov_failed) {
NFS4_DEBUG(nfs4_client_recov_debug,
- (CE_NOTE, "nfs4_inactive_otw: "
- "close failed (recovery failure)"));
+ (CE_NOTE, "nfs4_inactive_otw: "
+ "close failed (recovery failure)"));
}
}
}
@@ -4701,7 +4707,7 @@ redo:
* but we have to do this for correctness.
*/
if (nfs4_has_pages(vp) &&
- ((rp->r_flags & R4DIRTY) || rp->r_count > 0)) {
+ ((rp->r_flags & R4DIRTY) || rp->r_count > 0)) {
ASSERT(vp->v_type != VCHR);
e.error = nfs4_putpage(vp, (u_offset_t)0, 0, 0, cr);
if (e.error) {
@@ -4795,9 +4801,9 @@ recov_retry_remove:
NULL, NULL, OP_REMOVE, NULL) == FALSE) {
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
nfs4_end_op(VTOMI4(unldvp), unldvp, NULL,
- &recov_state, TRUE);
+ &recov_state, TRUE);
goto recov_retry_remove;
}
}
@@ -4819,9 +4825,9 @@ recov_retry_remove:
* Remote file system operations having to do with directory manipulation.
*/
/* ARGSUSED3 */
-static int
+int
nfs4_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
- int flags, vnode_t *rdir, cred_t *cr)
+ int flags, vnode_t *rdir, cred_t *cr)
{
int error;
vnode_t *vp, *avp = NULL;
@@ -5010,7 +5016,7 @@ nfs4lookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr, int skipdnlc)
* We hit on the dnlc
*/
if (*vpp != DNLC_NO_VNODE ||
- (dvp->v_vfsp->vfs_flag & VFS_RDONLY)) {
+ (dvp->v_vfsp->vfs_flag & VFS_RDONLY)) {
/*
* But our attrs may not be valid.
*/
@@ -5035,7 +5041,7 @@ nfs4lookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr, int skipdnlc)
*vpp = dnlc_lookup(dvp, nm);
if (*vpp == NULL)
return (nfs4lookupnew_otw(dvp,
- nm, vpp, cr));
+ nm, vpp, cr));
/*
* The access cache should almost always hit
@@ -5131,16 +5137,11 @@ nfs4lookupvalidate_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
args.ctag = TAG_LOOKUP_VPARENT;
} else {
/*
- * Do not allow crossing of server mount points. The
- * only visible entries in a SRVSTUB dir are . and ..
- * This code handles the non-.. case. We can't even get
- * this far if looking up ".".
+ * If dvp were a stub, it should have triggered and caused
+ * a mount for us to get this far.
*/
- if (VTOR4(dvp)->r_flags & R4SRVSTUB) {
- VN_RELE(*vpp);
- *vpp = NULL;
- return (ENOENT);
- }
+ ASSERT(!RP_ISSTUB(VTOR4(dvp)));
+
isdotdot = 0;
args.ctag = TAG_LOOKUP_VALID;
}
@@ -5156,7 +5157,7 @@ nfs4lookupvalidate_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
recov_retry:
e.error = nfs4_start_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, NULL);
+ &recov_state, NULL);
if (e.error) {
(void) check_mnt_secinfo(mi->mi_curr_serv, nvp);
VN_RELE(*vpp);
@@ -5191,7 +5192,7 @@ recov_retry:
/* 3. access directory */
argop[3].argop = OP_ACCESS;
argop[3].nfs_argop4_u.opaccess.access = ACCESS4_READ | ACCESS4_DELETE |
- ACCESS4_MODIFY | ACCESS4_EXTEND | ACCESS4_LOOKUP;
+ ACCESS4_MODIFY | ACCESS4_EXTEND | ACCESS4_LOOKUP;
/* 4. lookup name */
if (isdotdot) {
@@ -5224,13 +5225,12 @@ recov_retry:
* for (PUTFH, SECINFO "..") yet.
*/
if (!isdotdot && res.status == NFS4ERR_WRONGSEC) {
- if ((e.error = nfs4_secinfo_vnode_otw(dvp, nm, cr))) {
+ if ((e.error = nfs4_secinfo_vnode_otw(dvp, nm, cr)))
nfs4_end_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, FALSE);
- } else {
+ &recov_state, FALSE);
+ else
nfs4_end_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, TRUE);
- }
+ &recov_state, TRUE);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
kmem_free(argop, argoplist_size);
if (!e.error)
@@ -5244,7 +5244,7 @@ recov_retry:
if (nfs4_start_recovery(&e, mi, dvp, NULL, NULL, NULL,
OP_LOOKUP, NULL) == FALSE) {
nfs4_end_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, TRUE);
+ &recov_state, TRUE);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
kmem_free(argop, argoplist_size);
@@ -5267,7 +5267,7 @@ recov_retry:
*/
if (e.error == 0)
e.error = (res.status == NFS4ERR_MINOR_VERS_MISMATCH) ?
- ENOTSUP : EIO;
+ ENOTSUP : EIO;
VN_RELE(*vpp);
*vpp = NULL;
kmem_free(argop, argoplist_size);
@@ -5308,8 +5308,8 @@ recov_retry:
* Install new cached attributes for the directory
*/
nfs4_attr_cache(dvp,
- &res.array[2].nfs_resop4_u.opgetattr.ga_res,
- t, cr, FALSE, NULL);
+ &res.array[2].nfs_resop4_u.opgetattr.ga_res,
+ t, cr, FALSE, NULL);
if (res.array[3].nfs_resop4_u.opaccess.status != NFS4_OK) {
nfs4_purge_stale_fh(e.error, dvp, cr);
@@ -5324,8 +5324,8 @@ recov_retry:
* cache new directory access
*/
nfs4_access_cache(drp,
- args.array[3].nfs_argop4_u.opaccess.access,
- res.array[3].nfs_resop4_u.opaccess.access, cr);
+ args.array[3].nfs_argop4_u.opaccess.access,
+ res.array[3].nfs_resop4_u.opaccess.access, cr);
/*
* recheck VEXEC access
@@ -5422,7 +5422,7 @@ recov_retry:
nfs4_attr_cache(nvp, garp, t, cr, FALSE, NULL);
} else {
nvp = makenfs4node(sfhp, garp, dvp->v_vfsp, t, cr,
- dvp, fn_get(VTOSV(dvp)->sv_name, nm));
+ dvp, fn_get(VTOSV(dvp)->sv_name, nm));
/*
* If v_type == VNON, then garp was NULL because
* the last op in the compound failed and makenfs4node
@@ -5560,13 +5560,10 @@ nfs4lookupnew_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
args.ctag = TAG_LOOKUP_PARENT;
} else {
/*
- * Do not allow crossing of server mount points. The
- * only visible entries in a SRVSTUB dir are . and ..
- * This code handles the non-.. case. We can't even get
- * this far if looking up ".".
+ * If dvp were a stub, it should have triggered and caused
+ * a mount for us to get this far.
*/
- if (VTOR4(dvp)->r_flags & R4SRVSTUB)
- return (ENOENT);
+ ASSERT(!RP_ISSTUB(VTOR4(dvp)));
isdotdot = 0;
args.ctag = TAG_LOOKUP;
@@ -5583,7 +5580,7 @@ nfs4lookupnew_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
recov_retry:
e.error = nfs4_start_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, NULL);
+ &recov_state, NULL);
if (e.error) {
(void) check_mnt_secinfo(mi->mi_curr_serv, nvp);
return (e.error);
@@ -5638,7 +5635,7 @@ recov_retry:
/* 8. access directory */
argop[8].argop = OP_ACCESS;
argop[8].nfs_argop4_u.opaccess.access = ACCESS4_READ | ACCESS4_DELETE |
- ACCESS4_MODIFY | ACCESS4_EXTEND | ACCESS4_LOOKUP;
+ ACCESS4_MODIFY | ACCESS4_EXTEND | ACCESS4_LOOKUP;
doqueue = 1;
t = gethrtime();
@@ -5655,13 +5652,12 @@ recov_retry:
* for (PUTFH, SECINFO "..") yet.
*/
if (!isdotdot && res.status == NFS4ERR_WRONGSEC) {
- if ((e.error = nfs4_secinfo_vnode_otw(dvp, nm, cr))) {
+ if ((e.error = nfs4_secinfo_vnode_otw(dvp, nm, cr)))
nfs4_end_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, FALSE);
- } else {
+ &recov_state, FALSE);
+ else
nfs4_end_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, TRUE);
- }
+ &recov_state, TRUE);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
kmem_free(argop, argoplist_size);
if (!e.error)
@@ -5673,7 +5669,7 @@ recov_retry:
if (nfs4_start_recovery(&e, mi, dvp, NULL, NULL, NULL,
OP_LOOKUP, NULL) == FALSE) {
nfs4_end_fop(mi, dvp, NULL, OH_LOOKUP,
- &recov_state, TRUE);
+ &recov_state, TRUE);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
kmem_free(argop, argoplist_size);
@@ -5696,7 +5692,7 @@ recov_retry:
*/
if (e.error == 0)
e.error = (res.status == NFS4ERR_MINOR_VERS_MISMATCH) ?
- ENOTSUP : EIO;
+ ENOTSUP : EIO;
kmem_free(argop, argoplist_size);
(void) check_mnt_secinfo(mi->mi_curr_serv, nvp);
@@ -5709,7 +5705,7 @@ recov_retry:
* The PUTFH and SAVEFH may have failed.
*/
if ((res.array[0].nfs_resop4_u.opputfh.status != NFS4_OK) ||
- (res.array[1].nfs_resop4_u.opsavefh.status != NFS4_OK)) {
+ (res.array[1].nfs_resop4_u.opsavefh.status != NFS4_OK)) {
nfs4_purge_stale_fh(e.error, dvp, cr);
goto exit;
}
@@ -5723,9 +5719,8 @@ recov_retry:
/*
* The lookup failed, probably no entry
*/
- if (e.error == ENOENT && nfs4_lookup_neg_cache) {
+ if (e.error == ENOENT && nfs4_lookup_neg_cache)
dnlc_update(dvp, nm, DNLC_NO_VNODE);
- }
goto exit;
}
@@ -5788,8 +5783,8 @@ recov_retry:
goto exit;
}
nfs4_attr_cache(dvp,
- &res.array[7].nfs_resop4_u.opgetattr.ga_res,
- t, cr, FALSE, NULL);
+ &res.array[7].nfs_resop4_u.opgetattr.ga_res,
+ t, cr, FALSE, NULL);
if (res.array[8].nfs_resop4_u.opaccess.status != NFS4_OK) {
nfs4_purge_stale_fh(e.error, dvp, cr);
@@ -5803,8 +5798,8 @@ recov_retry:
* cache new directory access
*/
nfs4_access_cache(drp,
- args.array[8].nfs_argop4_u.opaccess.access,
- res.array[8].nfs_resop4_u.opaccess.access, cr);
+ args.array[8].nfs_argop4_u.opaccess.access,
+ res.array[8].nfs_resop4_u.opaccess.access, cr);
/*
* recheck VEXEC access
@@ -5887,7 +5882,7 @@ recov_retry:
nfs4_attr_cache(nvp, garp, t, cr, FALSE, NULL);
} else {
nvp = makenfs4node(sfhp, garp, dvp->v_vfsp, t, cr,
- dvp, fn_get(VTOSV(dvp)->sv_name, nm));
+ dvp, fn_get(VTOSV(dvp)->sv_name, nm));
}
sfh4_rele(&sfhp);
@@ -6038,15 +6033,15 @@ nfs4lookup_setup(char *nm, lookup4_param_t *lookupargp, int needgetfh)
* Find n = number of components - nm must be null terminated
* Skip "." components.
*/
- if (*nm != '\0') {
+ if (*nm != '\0')
for (n = 1, s = nm; *s != '\0'; s++) {
if ((*s == '/') && (*(s + 1) != '/') &&
- (*(s + 1) != '\0') &&
- !(*(s + 1) == '.' && (*(s + 2) == '/' ||
- *(s + 2) == '\0')))
+ (*(s + 1) != '\0') &&
+ !(*(s + 1) == '.' && (*(s + 2) == '/' ||
+ *(s + 2) == '\0')))
n++;
}
- } else
+ else
n = 0;
/*
@@ -6101,7 +6096,9 @@ nfs4lookup_setup(char *nm, lookup4_param_t *lookupargp, int needgetfh)
s++;
if (*s == '\0')
break;
- for (p = s; (*p != '/') && (*p != '\0'); p++);
+
+ for (p = s; (*p != '/') && (*p != '\0'); p++)
+ ;
c = *p;
*p = '\0';
@@ -6119,9 +6116,9 @@ nfs4lookup_setup(char *nm, lookup4_param_t *lookupargp, int needgetfh)
/* getattr */
argop->argop = OP_GETATTR;
argop->nfs_argop4_u.opgetattr.attr_request =
- lookupargp->ga_bits;
+ lookupargp->ga_bits;
argop->nfs_argop4_u.opgetattr.mi =
- lookupargp->mi;
+ lookupargp->mi;
argop++;
argcnt++;
@@ -6142,9 +6139,9 @@ nfs4lookup_setup(char *nm, lookup4_param_t *lookupargp, int needgetfh)
/* getattr */
argop->argop = OP_GETATTR;
argop->nfs_argop4_u.opgetattr.attr_request =
- lookupargp->ga_bits;
+ lookupargp->ga_bits;
argop->nfs_argop4_u.opgetattr.mi =
- lookupargp->mi;
+ lookupargp->mi;
argop++;
argcnt++;
*p = c;
@@ -6156,7 +6153,7 @@ nfs4lookup_setup(char *nm, lookup4_param_t *lookupargp, int needgetfh)
/* lookup */
argop->argop = OP_LOOKUP;
(void) str_to_utf8(s,
- &argop->nfs_argop4_u.oplookup.objname);
+ &argop->nfs_argop4_u.oplookup.objname);
}
lookup_idx = argcnt;
argop++;
@@ -6173,16 +6170,16 @@ nfs4lookup_setup(char *nm, lookup4_param_t *lookupargp, int needgetfh)
/* getattr */
argop->argop = OP_GETATTR;
argop->nfs_argop4_u.opgetattr.attr_request =
- lookupargp->ga_bits;
+ lookupargp->ga_bits;
argop->nfs_argop4_u.opgetattr.mi =
- lookupargp->mi;
+ lookupargp->mi;
argop++;
argcnt++;
}
}
if ((l4_getattrs != LKP4_NO_ATTRIBUTES) &&
- ((l4_getattrs != LKP4_ALL_ATTRIBUTES) || (lookup_idx < 0))) {
+ ((l4_getattrs != LKP4_ALL_ATTRIBUTES) || (lookup_idx < 0))) {
if (needgetfh) {
/* stick in a post-lookup getfh */
argop->argop = OP_GETFH;
@@ -6192,7 +6189,7 @@ nfs4lookup_setup(char *nm, lookup4_param_t *lookupargp, int needgetfh)
/* post-lookup getattr */
argop->argop = OP_GETATTR;
argop->nfs_argop4_u.opgetattr.attr_request =
- lookupargp->ga_bits;
+ lookupargp->ga_bits;
argop->nfs_argop4_u.opgetattr.mi = lookupargp->mi;
argcnt++;
}
@@ -6276,8 +6273,8 @@ recov_retry:
"nfs4openattr: initiating recovery\n"));
abort = nfs4_start_recovery(&e,
- VTOMI4(dvp), dvp, NULL, NULL, NULL,
- OP_OPENATTR, NULL);
+ VTOMI4(dvp), dvp, NULL, NULL, NULL,
+ OP_OPENATTR, NULL);
nfs4_end_op(VTOMI4(dvp), dvp, NULL, &recov_state, needrecov);
if (!e.error) {
e.error = geterrno4(res.status);
@@ -6317,7 +6314,7 @@ recov_retry:
if (e.error) {
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
nfs4_end_op(VTOMI4(dvp), dvp, NULL, &recov_state,
- needrecov);
+ needrecov);
return (e.error);
}
}
@@ -6339,8 +6336,8 @@ recov_retry:
sfhp = sfh4_get(&gf_res->object, VTOMI4(dvp));
vp = makenfs4node(sfhp, &res.array[3].nfs_resop4_u.opgetattr.ga_res,
- dvp->v_vfsp, t, cr, dvp,
- fn_get(VTOSV(dvp)->sv_name, XATTR_RPATH));
+ dvp->v_vfsp, t, cr, dvp,
+ fn_get(VTOSV(dvp)->sv_name, XATTR_RPATH));
sfh4_rele(&sfhp);
if (e.error)
@@ -6378,7 +6375,7 @@ recov_retry:
/* ARGSUSED */
static int
nfs4_create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
- int mode, vnode_t **vpp, cred_t *cr, int flags)
+ int mode, vnode_t **vpp, cred_t *cr, int flags)
{
int error;
vnode_t *vp = NULL;
@@ -6490,7 +6487,7 @@ top:
if (must_trunc) {
vattr.va_mask = AT_SIZE;
error = nfs4setattr(vp, &vattr, 0, cr,
- NULL);
+ NULL);
} else {
/*
* we know we have a regular file that already
@@ -6503,7 +6500,7 @@ top:
rp->r_count > 0 ||
rp->r_mapcnt > 0)) {
error = nfs4_putpage(vp,
- (offset_t)0, 0, 0, cr);
+ (offset_t)0, 0, 0, cr);
if (error && (error == ENOSPC ||
error == EDQUOT)) {
mutex_enter(
@@ -6516,7 +6513,7 @@ top:
}
}
vattr.va_mask = (AT_SIZE |
- AT_TYPE | AT_MODE);
+ AT_TYPE | AT_MODE);
vattr.va_type = VREG;
createmode = UNCHECKED4;
truncating = 1;
@@ -6584,7 +6581,7 @@ create_otw:
/* if create was successful, throw away the file's pages */
if (!error && (vattr.va_mask & AT_SIZE))
nfs4_invalidate_pages(vp, (vattr.va_size & PAGEMASK),
- cr);
+ cr);
/* release the lookup hold */
VN_RELE(vp);
vp = NULL;
@@ -6658,7 +6655,7 @@ create_otw:
*/
static int
call_nfs4_create_req(vnode_t *dvp, char *nm, void *data, struct vattr *va,
- vnode_t **vpp, cred_t *cr, nfs_ftype4 type)
+ vnode_t **vpp, cred_t *cr, nfs_ftype4 type)
{
int need_end_op = FALSE;
COMPOUND4args_clnt args;
@@ -6684,7 +6681,7 @@ call_nfs4_create_req(vnode_t *dvp, char *nm, void *data, struct vattr *va,
bitmap4 supp_attrs;
ASSERT(type == NF4DIR || type == NF4LNK || type == NF4BLK ||
- type == NF4CHR || type == NF4SOCK || type == NF4FIFO);
+ type == NF4CHR || type == NF4SOCK || type == NF4FIFO);
mi = VTOMI4(dvp);
@@ -6781,12 +6778,12 @@ recov_retry:
*/
ASSERT(data != NULL);
argop[idx_create].nfs_argop4_u.opccreate.ftype4_u.clinkdata =
- (char *)data;
+ (char *)data;
}
if (type == NF4BLK || type == NF4CHR) {
ASSERT(data != NULL);
argop[idx_create].nfs_argop4_u.opccreate.ftype4_u.devdata =
- *((specdata4 *)data);
+ *((specdata4 *)data);
}
crattr = &argop[idx_create].nfs_argop4_u.opccreate.createattrs;
@@ -6890,7 +6887,7 @@ recov_retry:
if (nfs4_start_recovery(&e, mi, dvp, NULL, NULL, NULL,
OP_CREATE, NULL) == FALSE) {
nfs4_end_op(mi, dvp, NULL, &recov_state,
- needrecov);
+ needrecov);
need_end_op = FALSE;
nfs4_fattr4_free(crattr);
if (setgid_flag) {
@@ -6957,7 +6954,7 @@ recov_retry:
* potential nfs4_start_op deadlock. See RFE 4777612.
*/
nfs4_end_op(mi, dvp, NULL, &recov_state,
- needrecov);
+ needrecov);
need_end_op = FALSE;
e.error = nfs4getattr(vp, &vattr, cr);
if (e.error) {
@@ -6970,9 +6967,9 @@ recov_retry:
e.error = 0;
} else {
*vpp = vp = makenfs4node(sfhp,
- &res.array[idx_fattr].nfs_resop4_u.opgetattr.ga_res,
- dvp->v_vfsp, t, cr,
- dvp, fn_get(VTOSV(dvp)->sv_name, nm));
+ &res.array[idx_fattr].nfs_resop4_u.opgetattr.ga_res,
+ dvp->v_vfsp, t, cr,
+ dvp, fn_get(VTOSV(dvp)->sv_name, nm));
}
/*
@@ -7010,7 +7007,7 @@ out:
/* ARGSUSED */
static int
nfs4mknod(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
- int mode, vnode_t **vpp, cred_t *cr)
+ int mode, vnode_t **vpp, cred_t *cr)
{
int error;
vnode_t *vp;
@@ -7249,9 +7246,9 @@ recov_retry:
NULL, NULL, NULL, OP_REMOVE, NULL) == FALSE) {
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
nfs4_end_op(VTOMI4(dvp), dvp, NULL, &recov_state,
- needrecov);
+ needrecov);
goto recov_retry;
}
}
@@ -7277,12 +7274,12 @@ recov_retry:
rm_res = &resop->nfs_resop4_u.opremove;
dinfo.di_garp =
- &res.array[2].nfs_resop4_u.opgetattr.ga_res;
+ &res.array[2].nfs_resop4_u.opgetattr.ga_res;
dinfo.di_cred = cr;
/* Update directory attr, readdir and dnlc caches */
nfs4_update_dircaches(&rm_res->cinfo, dvp, NULL, NULL,
- &dinfo);
+ &dinfo);
}
}
nfs_rw_exit(&drp->r_rwlock);
@@ -7418,21 +7415,21 @@ recov_retry:
bool_t abort;
abort = nfs4_start_recovery(&e, VTOMI4(svp), svp, tdvp,
- NULL, NULL, OP_LINK, NULL);
+ NULL, NULL, OP_LINK, NULL);
if (abort == FALSE) {
nfs4_end_op(VTOMI4(svp), svp, tdvp, &recov_state,
- needrecov);
+ needrecov);
kmem_free(argop, argoplist_size);
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
goto recov_retry;
} else {
if (e.error != 0) {
PURGE_ATTRCACHE4(tdvp);
PURGE_ATTRCACHE4(svp);
nfs4_end_op(VTOMI4(svp), svp, tdvp,
- &recov_state, needrecov);
+ &recov_state, needrecov);
goto out;
}
/* fall through for res.status case */
@@ -7482,11 +7479,10 @@ recov_retry:
*/
resop = &res.array[3]; /* link res */
ln_res = &resop->nfs_resop4_u.oplink;
- if (res.status == NFS4_OK) {
+ if (res.status == NFS4_OK)
e.error = nfs4_update_attrcache(res.status,
- &res.array[6].nfs_resop4_u.opgetattr.ga_res,
- t, svp, cr);
- }
+ &res.array[6].nfs_resop4_u.opgetattr.ga_res,
+ t, svp, cr);
/*
* Call makenfs4node to create the new shadow vp for tnm.
@@ -7495,7 +7491,7 @@ recov_retry:
* to create the new shadow vnode.
*/
nvp = makenfs4node(VTOR4(svp)->r_fh, NULL, tdvp->v_vfsp, t, cr,
- tdvp, fn_get(VTOSV(tdvp)->sv_name, tnm));
+ tdvp, fn_get(VTOSV(tdvp)->sv_name, tnm));
/* Update target cache attribute, readdir and dnlc caches */
dinfo.di_garp = &res.array[4].nfs_resop4_u.opgetattr.ga_res;
@@ -7570,11 +7566,11 @@ nfs4rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
ASSERT(nfs4_consistent_type(ndvp));
if (onm[0] == '.' && (onm[1] == '\0' ||
- (onm[1] == '.' && onm[2] == '\0')))
+ (onm[1] == '.' && onm[2] == '\0')))
return (EINVAL);
if (nnm[0] == '.' && (nnm[1] == '\0' ||
- (nnm[1] == '.' && nnm[2] == '\0')))
+ (nnm[1] == '.' && nnm[2] == '\0')))
return (EINVAL);
odrp = VTOR4(odvp);
@@ -7825,13 +7821,13 @@ link_call:
* that are open with that flag on. (XXX)
*/
mi = VTOMI4(odvp);
- if (NFS4_VOLATILE_FH(mi)) {
+ if (NFS4_VOLATILE_FH(mi))
error = nfs4rename_volatile_fh(odvp, onm, ovp, ndvp, nnm, cr,
- &stat);
- } else {
+ &stat);
+ else
error = nfs4rename_persistent_fh(odvp, onm, ovp, ndvp, nnm, cr,
- &stat);
- }
+ &stat);
+
ASSERT(nfs4_consistent_type(odvp));
ASSERT(nfs4_consistent_type(ndvp));
ASSERT(nfs4_consistent_type(ovp));
@@ -7975,7 +7971,7 @@ link_call:
*/
static int
nfs4rename_persistent_fh(vnode_t *odvp, char *onm, vnode_t *renvp,
- vnode_t *ndvp, char *nnm, cred_t *cr, nfsstat4 *statp)
+ vnode_t *ndvp, char *nnm, cred_t *cr, nfsstat4 *statp)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res, *resp = NULL;
@@ -8072,7 +8068,7 @@ recov_retry:
nfs4_end_op(mi, odvp, ndvp, &recov_state, needrecov);
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
goto recov_retry;
}
}
@@ -8112,7 +8108,7 @@ recov_retry:
dinfop = NULL;
nfs4_update_dircaches(&rn_res->target_cinfo,
- ndvp, NULL, NULL, dinfop);
+ ndvp, NULL, NULL, dinfop);
/*
* Update source attribute, readdir and dnlc caches
@@ -8125,11 +8121,11 @@ recov_retry:
opgetattr.ga_res);
nfs4_update_dircaches(&rn_res->source_cinfo,
- odvp, NULL, NULL, dinfop);
+ odvp, NULL, NULL, dinfop);
}
fn_move(VTOSV(renvp)->sv_name, VTOSV(ndvp)->sv_name,
- nnm);
+ nnm);
}
}
@@ -8163,7 +8159,7 @@ recov_retry:
*/
static int
nfs4rename_volatile_fh(vnode_t *odvp, char *onm, vnode_t *ovp,
- vnode_t *ndvp, char *nnm, cred_t *cr, nfsstat4 *statp)
+ vnode_t *ndvp, char *nnm, cred_t *cr, nfsstat4 *statp)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res, *resp = NULL;
@@ -8234,7 +8230,7 @@ recov_retry:
args.array = argop;
e.error = nfs4_start_fop(mi, odvp, ndvp, OH_VFH_RENAME,
- &recov_state, NULL);
+ &recov_state, NULL);
if (e.error) {
kmem_free(argop, argoplist_size);
mutex_enter(&orp->r_statelock);
@@ -8312,7 +8308,7 @@ recov_retry:
PURGE_ATTRCACHE4(ndvp);
if (!needrecov) {
nfs4_end_fop(mi, odvp, ndvp, OH_VFH_RENAME,
- &recov_state, needrecov);
+ &recov_state, needrecov);
goto out;
}
} else {
@@ -8323,14 +8319,14 @@ recov_retry:
bool_t abort;
abort = nfs4_start_recovery(&e, mi, odvp, ndvp, NULL, NULL,
- OP_RENAME, NULL);
+ OP_RENAME, NULL);
if (abort == FALSE) {
nfs4_end_fop(mi, odvp, ndvp, OH_VFH_RENAME,
- &recov_state, needrecov);
+ &recov_state, needrecov);
kmem_free(argop, argoplist_size);
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
mutex_enter(&orp->r_statelock);
orp->r_flags &= ~R4RECEXPFH;
cv_broadcast(&orp->r_cv);
@@ -8339,7 +8335,7 @@ recov_retry:
} else {
if (e.error != 0) {
nfs4_end_fop(mi, odvp, ndvp, OH_VFH_RENAME,
- &recov_state, needrecov);
+ &recov_state, needrecov);
goto out;
}
/* fall through for res.status case */
@@ -8367,7 +8363,7 @@ recov_retry:
if (e.error == ENOTEMPTY)
e.error = EEXIST;
nfs4_end_fop(mi, odvp, ndvp, OH_VFH_RENAME, &recov_state,
- needrecov);
+ needrecov);
goto out;
}
@@ -8377,7 +8373,7 @@ recov_retry:
if (res.status == NFS4_OK) {
/* Update target attribute, readdir and dnlc caches */
dinfo.di_garp =
- &res.array[6].nfs_resop4_u.opgetattr.ga_res;
+ &res.array[6].nfs_resop4_u.opgetattr.ga_res;
dinfo.di_cred = cr;
dinfo.di_time_call = t;
} else
@@ -8396,9 +8392,9 @@ recov_retry:
*/
if (dinfop)
dinfo.di_garp =
- &res.array[11].nfs_resop4_u.opgetattr.ga_res;
+ &res.array[11].nfs_resop4_u.opgetattr.ga_res;
nfs4_update_dircaches(&rn_res->source_cinfo, odvp, NULL, NULL,
- dinfop);
+ dinfop);
}
/*
@@ -8420,8 +8416,8 @@ recov_retry:
if (res.status == NFS4_OK) {
resop++; /* getattr res */
e.error = nfs4_update_attrcache(res.status,
- &resop->nfs_resop4_u.opgetattr.ga_res,
- t, ovp, cr);
+ &resop->nfs_resop4_u.opgetattr.ga_res,
+ t, ovp, cr);
}
out:
@@ -8599,7 +8595,7 @@ recov_retry:
NULL, OP_REMOVE, NULL) == FALSE) {
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
nfs4_end_op(VTOMI4(dvp), dvp, NULL, &recov_state,
needrecov);
@@ -8619,7 +8615,7 @@ recov_retry:
e.error = geterrno4(res.status);
PURGE_ATTRCACHE4(dvp);
nfs4_end_op(VTOMI4(dvp), dvp, NULL,
- &recov_state, needrecov);
+ &recov_state, needrecov);
need_end_op = FALSE;
nfs4_purge_stale_fh(e.error, dvp, cr);
/*
@@ -8637,7 +8633,7 @@ recov_retry:
if (res.status == NFS4_OK) {
resop = &res.array[2]; /* dir attrs */
dinfo.di_garp =
- &resop->nfs_resop4_u.opgetattr.ga_res;
+ &resop->nfs_resop4_u.opgetattr.ga_res;
dinfo.di_cred = cr;
dinfop = &dinfo;
} else
@@ -8645,7 +8641,7 @@ recov_retry:
/* Update dir attribute, readdir and dnlc caches */
nfs4_update_dircaches(&rm_res->cinfo, dvp, NULL, NULL,
- dinfop);
+ dinfop);
/* destroy rddir cache for dir that was removed */
if (VTOR4(vp)->r_dir != NULL)
@@ -8691,9 +8687,8 @@ nfs4_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm, cred_t *cr)
return (EOPNOTSUPP);
error = call_nfs4_create_req(dvp, lnm, tnm, tva, &vp, cr, NF4LNK);
- if (error) {
+ if (error)
return (error);
- }
ASSERT(nfs4_consistent_type(vp));
rp = VTOR4(vp);
@@ -8954,57 +8949,6 @@ do_nfs4readdir(vnode_t *vp, rddir4_cache *rdc, cred_t *cr)
return (error);
}
-static void
-nfs4readdir_stub(vnode_t *vp, rddir4_cache *rdc, cred_t *cr)
-{
- int stublength;
- dirent64_t *dp;
- u_longlong_t nodeid, pnodeid;
- vnode_t *dotdotvp = NULL;
- rnode4_t *rp = VTOR4(vp);
- nfs_cookie4 cookie = (nfs_cookie4)rdc->nfs4_cookie;
-
- rdc->error = 0;
- rdc->entries = 0;
- rdc->actlen = rdc->entlen = 0;
- rdc->eof = TRUE;
-
- /* Check for EOF case for readdir of stub */
- if (cookie != 0 && cookie != 1)
- return;
-
- nodeid = rp->r_attr.va_nodeid;
- if (vp->v_flag & VROOT) {
- pnodeid = nodeid; /* root of mount point */
- } else {
- if (rdc->error = nfs4_lookup(vp, "..", &dotdotvp, 0, 0, 0, cr))
- return;
- pnodeid = VTOR4(dotdotvp)->r_attr.va_nodeid;
- VN_RELE(dotdotvp);
- }
-
- stublength = DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2);
- rdc->entries = kmem_alloc(stublength, KM_SLEEP);
- rdc->entlen = rdc->buflen = stublength;
- rdc->eof = TRUE;
-
- dp = (dirent64_t *)rdc->entries;
-
- if (rdc->nfs4_cookie == (nfs_cookie4)0) {
- bcopy(nfs4_dot_entries, rdc->entries,
- DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2));
- dp->d_ino = nodeid;
- dp = (struct dirent64 *)(((char *)dp) + DIRENT64_RECLEN(1));
- dp->d_ino = pnodeid;
- rdc->actlen = DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2);
- } else { /* for ".." entry */
- bcopy(nfs4_dot_dot_entry, rdc->entries, DIRENT64_RECLEN(2));
- dp->d_ino = pnodeid;
- rdc->actlen = DIRENT64_RECLEN(2);
- }
- rdc->nfs4_ncookie = rdc->actlen;
-}
-
/*
* Read directory entries.
* There are some weird things to look out for here. The uio_loffset
@@ -9050,10 +8994,11 @@ nfs4readdir(vnode_t *vp, rddir4_cache *rdc, cred_t *cr)
ASSERT(rdc->flags & RDDIR);
ASSERT(rdc->entries == NULL);
- if (rp->r_flags & R4SRVSTUB) {
- nfs4readdir_stub(vp, rdc, cr);
- return;
- }
+ /*
+ * If rp were a stub, it should have triggered and caused
+ * a mount for us to get this far.
+ */
+ ASSERT(!RP_ISSTUB(rp));
num_ops = 2;
if (cookie == (nfs_cookie4)0 || cookie == (nfs_cookie4)1) {
@@ -9099,7 +9044,7 @@ recov_retry:
args.array_len = num_ops;
if (e.error = nfs4_start_fop(VTOMI4(vp), vp, NULL, OH_READDIR,
- &recov_state, NULL)) {
+ &recov_state, NULL)) {
/*
* If readdir a node that is a stub for a crossed mount point,
* keep the original secinfo flavor for the current file
@@ -9121,8 +9066,8 @@ recov_retry:
* Get all vattr attrs plus filehandle and rdattr_error
*/
rd_bitsval = NFS4_VATTR_MASK |
- FATTR4_RDATTR_ERROR_MASK |
- FATTR4_FILEHANDLE_MASK;
+ FATTR4_RDATTR_ERROR_MASK |
+ FATTR4_FILEHANDLE_MASK;
if (rp->r_flags & R4READDIRWATTR) {
mutex_enter(&rp->r_statelock);
@@ -9240,13 +9185,13 @@ recov_retry:
"nfs4readdir: initiating recovery.\n"));
abort = nfs4_start_recovery(&e, VTOMI4(vp), vp, NULL, NULL,
- NULL, OP_READDIR, NULL);
+ NULL, OP_READDIR, NULL);
if (abort == FALSE) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_READDIR,
- &recov_state, needrecov);
+ &recov_state, needrecov);
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
if (rdc->entries != NULL) {
kmem_free(rdc->entries, rdc->entlen);
rdc->entries = NULL;
@@ -9357,7 +9302,7 @@ recov_retry:
*/
if (garp->n4g_va.va_mask & AT_NODEID)
rd_res->dotdotp->d_ino =
- garp->n4g_va.va_nodeid;
+ garp->n4g_va.va_nodeid;
/*
@@ -9417,11 +9362,10 @@ nfs4_bio(struct buf *bp, stable_how4 *stab_comm, cred_t *cr, bool_t readahead)
* Puts a hold on the cred_otw and the new osp (if found).
*/
cred_otw = nfs4_get_otw_cred_by_osp(rp, cr, &osp,
- &first_time, &last_time);
+ &first_time, &last_time);
error = bp->b_error = nfs4read(bp->b_vp, bp->b_un.b_addr,
- offset, bp->b_bcount,
- &bp->b_resid, cred_otw,
- readahead, NULL);
+ offset, bp->b_bcount, &bp->b_resid, cred_otw,
+ readahead, NULL);
crfree(cred_otw);
if (!error) {
if (bp->b_resid) {
@@ -9449,14 +9393,14 @@ nfs4_bio(struct buf *bp, stable_how4 *stab_comm, cred_t *cr, bool_t readahead)
}
} else {
if (!(rp->r_flags & R4STALE)) {
- write_again:
+write_again:
/*
* Releases the osp, if it is provided.
* Puts a hold on the cred_otw and the new
* osp (if found).
*/
cred_otw = nfs4_get_otw_cred_by_osp(rp, cr, &osp,
- &first_time, &last_time);
+ &first_time, &last_time);
mutex_enter(&rp->r_statelock);
count = MIN(bp->b_bcount, rp->r_size - offset);
mutex_exit(&rp->r_statelock);
@@ -9538,14 +9482,14 @@ nfs4_bio(struct buf *bp, stable_how4 *stab_comm, cred_t *cr, bool_t readahead)
}
/* ARGSUSED */
-static int
+int
nfs4_fid(vnode_t *vp, fid_t *fidp)
{
return (EREMOTE);
}
/* ARGSUSED2 */
-static int
+int
nfs4_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
{
rnode4_t *rp = VTOR4(vp);
@@ -9568,7 +9512,7 @@ nfs4_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
}
/* ARGSUSED */
-static void
+void
nfs4_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
{
rnode4_t *rp = VTOR4(vp);
@@ -9601,8 +9545,8 @@ nfs4_seek(vnode_t *vp, offset_t ooff, offset_t *noffp)
*/
static int
nfs4_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
- page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
- enum seg_rw rw, cred_t *cr)
+ page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
+ enum seg_rw rw, cred_t *cr)
{
rnode4_t *rp;
int error;
@@ -9642,8 +9586,8 @@ retry:
*/
if (rw == S_CREATE) {
while ((mi->mi_max_threads != 0 &&
- rp->r_awcount > 2 * mi->mi_max_threads) ||
- rp->r_gcount > 0)
+ rp->r_awcount > 2 * mi->mi_max_threads) ||
+ rp->r_gcount > 0)
cv_wait(&rp->r_cv, &rp->r_statelock);
}
@@ -9667,14 +9611,14 @@ retry:
error = nfs4_getapage(vp, off, len, protp, pl, plsz,
seg, addr, rw, cr);
NFS4_DEBUG(nfs4_pageio_debug && error,
- (CE_NOTE, "getpage error %d; off=%lld, "
- "len=%lld", error, off, (u_longlong_t)len));
+ (CE_NOTE, "getpage error %d; off=%lld, "
+ "len=%lld", error, off, (u_longlong_t)len));
} else {
error = pvn_getpages(nfs4_getapage, vp, off, len, protp,
pl, plsz, seg, addr, rw, cr);
NFS4_DEBUG(nfs4_pageio_debug && error,
- (CE_NOTE, "getpages error %d; off=%lld, "
- "len=%lld", error, off, (u_longlong_t)len));
+ (CE_NOTE, "getpages error %d; off=%lld, "
+ "len=%lld", error, off, (u_longlong_t)len));
}
switch (error) {
@@ -9694,8 +9638,8 @@ retry:
/* ARGSUSED */
static int
nfs4_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp,
- page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
- enum seg_rw rw, cred_t *cr)
+ page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
+ enum seg_rw rw, cred_t *cr)
{
rnode4_t *rp;
uint_t bsize;
@@ -9760,8 +9704,8 @@ reread:
else if (blkoff == rp->r_nextr)
readahead = nfs4_nra;
else if (rp->r_nextr > blkoff &&
- ((ra_window = (rp->r_nextr - blkoff) / bsize)
- <= (nfs4_nra - 1)))
+ ((ra_window = (rp->r_nextr - blkoff) / bsize)
+ <= (nfs4_nra - 1)))
readahead = nfs4_nra - ra_window;
else
readahead = 0;
@@ -9833,7 +9777,7 @@ again:
} else
blksize = rp->r_size - blkoff;
} else if ((off == 0) ||
- (off != rp->r_nextr && !readahead_issued)) {
+ (off != rp->r_nextr && !readahead_issued)) {
blksize = PAGESIZE;
blkoff = off; /* block = page here */
} else
@@ -9963,7 +9907,7 @@ out:
static void
nfs4_readahead(vnode_t *vp, u_offset_t blkoff, caddr_t addr, struct seg *seg,
- cred_t *cr)
+ cred_t *cr)
{
int error;
page_t *pp;
@@ -10120,7 +10064,7 @@ nfs4_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr)
*/
int
nfs4_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
- int flags, cred_t *cr)
+ int flags, cred_t *cr)
{
u_offset_t io_off;
u_offset_t lbn_off;
@@ -10242,7 +10186,7 @@ nfs4_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
static int
nfs4_sync_putapage(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
- int flags, cred_t *cr)
+ int flags, cred_t *cr)
{
int error;
rnode4_t *rp;
@@ -10297,7 +10241,7 @@ nfs4_sync_putapage(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
pvn_write_done(pp, flags);
if (freemem < desfree)
(void) nfs4_commit_vp(vp, (u_offset_t)0, 0, cr,
- NFS4_WRITE_NOWAIT);
+ NFS4_WRITE_NOWAIT);
}
return (error);
@@ -10309,7 +10253,7 @@ int nfs4_force_open_before_mmap = 0;
static int
nfs4_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
- size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr)
+ size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr)
{
struct segvn_crargs vn_a;
int error = 0;
@@ -10526,7 +10470,7 @@ open_and_get_osp(vnode_t *map_vp, cred_t *cr, nfs4_open_stream_t **ospp)
VN_HOLD(map_vp);
error = nfs4open_otw(dvp, file_name, NULL, &open_vp, cr, 0, FREAD, 0,
- just_created);
+ just_created);
if (error) {
nfs_rw_exit(&drp->r_rwlock);
VN_RELE(dvp);
@@ -10551,7 +10495,7 @@ open_and_get_osp(vnode_t *map_vp, cred_t *cr, nfs4_open_stream_t **ospp)
* and let VOP_INACTIVE handle it.
*/
(void) nfs4close_one(open_vp, NULL, cr, FREAD, NULL, &e,
- CLOSE_NORM, 0, 0, 0);
+ CLOSE_NORM, 0, 0, 0);
VN_RELE(map_vp);
return (EIO);
}
@@ -10569,7 +10513,7 @@ open_and_get_osp(vnode_t *map_vp, cred_t *cr, nfs4_open_stream_t **ospp)
* and let VOP_INACTIVE handle it.
*/
(void) nfs4close_one(open_vp, NULL, cr, FREAD, NULL, &e,
- CLOSE_NORM, 0, 0, 0);
+ CLOSE_NORM, 0, 0, 0);
return (EIO);
}
osp = find_open_stream(oop, rp);
@@ -10585,7 +10529,7 @@ open_and_get_osp(vnode_t *map_vp, cred_t *cr, nfs4_open_stream_t **ospp)
/* ARGSUSED */
static int
nfs4_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
- size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr)
+ size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr)
{
rnode4_t *rp;
int error = 0;
@@ -10698,7 +10642,7 @@ nfs4_cmp(vnode_t *vp1, vnode_t *vp2)
static int
nfs4_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
- offset_t offset, struct flk_callback *flk_cbp, cred_t *cr)
+ offset_t offset, struct flk_callback *flk_cbp, cred_t *cr)
{
int rc;
u_offset_t start, end;
@@ -10784,21 +10728,22 @@ nfs4_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
if (cmd != F_GETLK) {
mutex_enter(&rp->r_statelock);
while (rp->r_count > 0) {
- if (intr) {
- klwp_t *lwp = ttolwp(curthread);
+ if (intr) {
+ klwp_t *lwp = ttolwp(curthread);
- if (lwp != NULL)
- lwp->lwp_nostop++;
- if (cv_wait_sig(&rp->r_cv, &rp->r_statelock) == 0) {
+ if (lwp != NULL)
+ lwp->lwp_nostop++;
+ if (cv_wait_sig(&rp->r_cv,
+ &rp->r_statelock) == 0) {
+ if (lwp != NULL)
+ lwp->lwp_nostop--;
+ rc = EINTR;
+ break;
+ }
if (lwp != NULL)
lwp->lwp_nostop--;
- rc = EINTR;
- break;
- }
- if (lwp != NULL)
- lwp->lwp_nostop--;
- } else
- cv_wait(&rp->r_cv, &rp->r_statelock);
+ } else
+ cv_wait(&rp->r_cv, &rp->r_statelock);
}
mutex_exit(&rp->r_statelock);
if (rc != 0)
@@ -10822,9 +10767,8 @@ nfs4_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
* Call the lock manager to do the real work of contacting
* the server and obtaining the lock.
*/
-
nfs4frlock(NFS4_LCK_CTYPE_NORM, vp, cmd, bfp, flag, offset,
- cr, &e, NULL, NULL);
+ cr, &e, NULL, NULL);
rc = e.error;
if (rc == 0)
@@ -10848,7 +10792,7 @@ done:
/* ARGSUSED */
static int
nfs4_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
- offset_t offset, cred_t *cr, caller_context_t *ct)
+ offset_t offset, cred_t *cr, caller_context_t *ct)
{
int error;
@@ -10875,7 +10819,7 @@ nfs4_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
}
/* ARGSUSED */
-static int
+int
nfs4_realvp(vnode_t *vp, vnode_t **vpp)
{
rnode4_t *rp;
@@ -10901,7 +10845,7 @@ nfs4_realvp(vnode_t *vp, vnode_t **vpp)
/* ARGSUSED */
static int
nfs4_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
- size_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr)
+ size_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr)
{
int caller_found;
int error;
@@ -11104,7 +11048,7 @@ nfs4_delmap_callback(struct as *as, void *arg, uint_t event)
if (e.error) {
e.stat = puterrno4(e.error);
nfs4_queue_fact(RF_DELMAP_CB_ERR, mi, e.stat, 0,
- OP_COMMIT, FALSE, NULL, 0, dmapp->vp);
+ OP_COMMIT, FALSE, NULL, 0, dmapp->vp);
dmapp->caller->error = e.error;
}
@@ -11167,7 +11111,7 @@ fattr4_maxfilesize_to_bits(uint64_t ll)
return (l);
}
-static int
+int
nfs4_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
{
int error;
@@ -11218,23 +11162,23 @@ nfs4_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
switch (cmd) {
case _PC_FILESIZEBITS:
*valp =
- rp->r_pathconf.pc4_filesizebits;
+ rp->r_pathconf.pc4_filesizebits;
break;
case _PC_LINK_MAX:
*valp =
- rp->r_pathconf.pc4_link_max;
+ rp->r_pathconf.pc4_link_max;
break;
case _PC_NAME_MAX:
*valp =
- rp->r_pathconf.pc4_name_max;
+ rp->r_pathconf.pc4_name_max;
break;
case _PC_CHOWN_RESTRICTED:
*valp =
- rp->r_pathconf.pc4_chown_restricted;
+ rp->r_pathconf.pc4_chown_restricted;
break;
case _PC_NO_TRUNC:
*valp =
- rp->r_pathconf.pc4_no_trunc;
+ rp->r_pathconf.pc4_no_trunc;
break;
default:
error = EINVAL;
@@ -11267,7 +11211,7 @@ nfs4_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
/* interpret the max filesize */
gar.n4g_ext_res->n4g_pc4.pc4_filesizebits =
- fattr4_maxfilesize_to_bits(gar.n4g_ext_res->n4g_maxfilesize);
+ fattr4_maxfilesize_to_bits(gar.n4g_ext_res->n4g_maxfilesize);
/* Store the attributes we just received */
nfs4_attr_cache(vp, &gar, t, cr, TRUE, NULL);
@@ -11304,7 +11248,7 @@ nfs4_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
*/
static int
nfs4_sync_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
- int flags, cred_t *cr)
+ int flags, cred_t *cr)
{
int error;
@@ -11320,7 +11264,7 @@ nfs4_sync_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
static int
nfs4_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
- int flags, cred_t *cr)
+ int flags, cred_t *cr)
{
int error;
rnode4_t *rp;
@@ -11590,7 +11534,7 @@ get_commit_cred:
* Puts a hold on the cred_otw and the new osp (if found).
*/
cred_otw = nfs4_get_otw_cred_by_osp(rp, cr, &osp,
- &first_time, &last_time);
+ &first_time, &last_time);
args.ctag = TAG_COMMIT;
recov_retry:
/*
@@ -11600,7 +11544,7 @@ recov_retry:
args.array = argop;
e.error = nfs4_start_fop(VTOMI4(vp), vp, NULL, OH_COMMIT,
- &recov_state, NULL);
+ &recov_state, NULL);
if (e.error) {
crfree(cred_otw);
if (osp != NULL)
@@ -11623,7 +11567,7 @@ recov_retry:
needrecov = nfs4_needs_recovery(&e, FALSE, mi->mi_vfsp);
if (!needrecov && e.error) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_COMMIT, &recov_state,
- needrecov);
+ needrecov);
crfree(cred_otw);
if (e.error == EACCES && last_time == FALSE)
goto get_commit_cred;
@@ -11636,15 +11580,15 @@ recov_retry:
if (nfs4_start_recovery(&e, VTOMI4(vp), vp, NULL, NULL,
NULL, OP_COMMIT, NULL) == FALSE) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_COMMIT,
- &recov_state, needrecov);
+ &recov_state, needrecov);
if (!e.error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
goto recov_retry;
}
if (e.error) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_COMMIT,
- &recov_state, needrecov);
+ &recov_state, needrecov);
crfree(cred_otw);
if (osp != NULL)
open_stream_rele(osp, rp);
@@ -11658,7 +11602,7 @@ recov_retry:
if (e.error == EACCES && last_time == FALSE) {
crfree(cred_otw);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_COMMIT,
- &recov_state, needrecov);
+ &recov_state, needrecov);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
goto get_commit_cred;
}
@@ -11691,7 +11635,7 @@ recov_retry:
mutex_exit(&rp->r_statelock);
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
nfs4_end_fop(VTOMI4(vp), vp, NULL, OH_COMMIT,
- &recov_state, needrecov);
+ &recov_state, needrecov);
crfree(cred_otw);
if (osp != NULL)
open_stream_rele(osp, rp);
@@ -11836,7 +11780,7 @@ nfs4_get_commit(vnode_t *vp)
(offset3)pp->p_offset + rp->r_commit.c_commlen;
rp->r_commit.c_commbase = (offset3)pp->p_offset;
} else if ((rp->r_commit.c_commbase + rp->r_commit.c_commlen)
- <= pp->p_offset) {
+ <= pp->p_offset) {
rp->r_commit.c_commlen = (offset3)pp->p_offset -
rp->r_commit.c_commbase + PAGESIZE;
}
@@ -11911,7 +11855,7 @@ nfs4_get_commit_range(vnode_t *vp, u_offset_t soff, size_t len)
rp->r_commit.c_commlen = PAGESIZE;
} else {
rp->r_commit.c_commlen = (offset3)pp->p_offset -
- rp->r_commit.c_commbase + PAGESIZE;
+ rp->r_commit.c_commbase + PAGESIZE;
}
page_add(&rp->r_commit.c_pages, pp);
}
@@ -11999,7 +11943,7 @@ top:
*/
static int
nfs4_commit_vp(vnode_t *vp, u_offset_t poff, size_t plen,
- cred_t *cr, int wait_on_writes)
+ cred_t *cr, int wait_on_writes)
{
rnode4_t *rp;
page_t *plist;
@@ -12077,7 +12021,7 @@ nfs4_commit_vp(vnode_t *vp, u_offset_t poff, size_t plen,
static int
nfs4_sync_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
- cred_t *cr)
+ cred_t *cr)
{
int error;
page_t *pp;
@@ -12115,7 +12059,7 @@ nfs4_sync_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
static void
do_nfs4_async_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
- cred_t *cr)
+ cred_t *cr)
{
(void) nfs4_sync_commit(vp, plist, offset, count, cr);
@@ -12137,10 +12081,10 @@ nfs4_setsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
/* if we have a delegation, return it */
if (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE)
(void) nfs4delegreturn(VTOR4(vp),
- NFS4_DR_REOPEN|NFS4_DR_PUSH);
+ NFS4_DR_REOPEN|NFS4_DR_PUSH);
error = nfs4_is_acl_mask_valid(vsecattr->vsa_mask,
- NFS4_ACL_SET);
+ NFS4_ACL_SET);
if (error) /* EINVAL */
return (error);
@@ -12169,7 +12113,7 @@ nfs4_setsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
return (ENOSYS);
}
-static int
+int
nfs4_getsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
{
int error;
@@ -12318,7 +12262,7 @@ nfs4_is_acl_mask_valid(uint_t acl_mask, nfs4_acl_op_t op)
*/
static int
nfs4_create_getsecattr_return(vsecattr_t *filled_vsap, vsecattr_t *vsap,
- uid_t uid, gid_t gid, int isdir)
+ uid_t uid, gid_t gid, int isdir)
{
int error = 0;
/* Save the mask since the translators modify it. */
@@ -12437,7 +12381,7 @@ nfs4_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr)
*/
static int
nfs4_update_attrcache(nfsstat4 status, nfs4_ga_res_t *garp,
- hrtime_t t, vnode_t *vp, cred_t *cr)
+ hrtime_t t, vnode_t *vp, cred_t *cr)
{
int error = 0;
@@ -12463,7 +12407,7 @@ nfs4_update_attrcache(nfsstat4 status, nfs4_ga_res_t *garp,
*/
static void
nfs4_update_dircaches(change_info4 *cinfo, vnode_t *dvp, vnode_t *vp, char *nm,
- dirattr_info_t *dinfo)
+ dirattr_info_t *dinfo)
{
rnode4_t *drp = VTOR4(dvp);
@@ -12489,13 +12433,13 @@ nfs4_update_dircaches(change_info4 *cinfo, vnode_t *dvp, vnode_t *vp, char *nm,
*/
mutex_exit(&VTOR4(vp)->r_statev4_lock);
NFS4_DEBUG(nfs4_client_state_debug,
- (CE_NOTE, "nfs4_update_dircaches: "
- "don't update dnlc: created_v4 flag"));
+ (CE_NOTE, "nfs4_update_dircaches: "
+ "don't update dnlc: created_v4 flag"));
}
}
nfs4_attr_cache(dvp, dinfo->di_garp, dinfo->di_time_call,
- dinfo->di_cred, FALSE, cinfo);
+ dinfo->di_cred, FALSE, cinfo);
return;
}
@@ -12530,8 +12474,8 @@ nfs4_update_dircaches(change_info4 *cinfo, vnode_t *dvp, vnode_t *vp, char *nm,
*/
mutex_exit(&VTOR4(vp)->r_statev4_lock);
NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE,
- "nfs4_update_dircaches: don't"
- " update dnlc: created_v4 flag"));
+ "nfs4_update_dircaches: don't"
+ " update dnlc: created_v4 flag"));
}
}
} else {
@@ -12560,8 +12504,8 @@ nfs4_update_dircaches(change_info4 *cinfo, vnode_t *dvp, vnode_t *vp, char *nm,
*/
void
nfs4open_confirm(vnode_t *vp, seqid4 *seqid, stateid4 *stateid, cred_t *cr,
- bool_t reopening_file, bool_t *retry_open, nfs4_open_owner_t *oop,
- bool_t resend, nfs4_error_t *ep, int *num_bseqid_retryp)
+ bool_t reopening_file, bool_t *retry_open, nfs4_open_owner_t *oop,
+ bool_t resend, nfs4_error_t *ep, int *num_bseqid_retryp)
{
COMPOUND4args_clnt args;
COMPOUND4res_clnt res;
@@ -12622,11 +12566,11 @@ recov_retry_confirm:
if (!ep->error && res.status == NFS4ERR_BAD_SEQID)
bsep = nfs4_create_bseqid_entry(oop, NULL,
- vp, 0, args.ctag,
- open_confirm_args->seqid);
+ vp, 0, args.ctag,
+ open_confirm_args->seqid);
abort = nfs4_start_recovery(ep, VTOMI4(vp), vp,
- NULL, NULL, NULL, OP_OPEN_CONFIRM, bsep);
+ NULL, NULL, NULL, OP_OPEN_CONFIRM, bsep);
if (bsep) {
kmem_free(bsep, sizeof (*bsep));
if (num_bseqid_retryp &&
@@ -12635,11 +12579,11 @@ recov_retry_confirm:
}
}
if ((ep->error == ETIMEDOUT ||
- res.status == NFS4ERR_RESOURCE) &&
- abort == FALSE && resend == FALSE) {
+ res.status == NFS4ERR_RESOURCE) &&
+ abort == FALSE && resend == FALSE) {
if (!ep->error)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)&res);
+ (caddr_t)&res);
delay(SEC_TO_TICK(confirm_retry_sec));
goto recov_retry_confirm;
@@ -12661,7 +12605,7 @@ recov_retry_confirm:
resop = &res.array[1]; /* open confirm res */
bcopy(&resop->nfs_resop4_u.opopen_confirm.open_stateid,
- stateid, sizeof (*stateid));
+ stateid, sizeof (*stateid));
(void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
}
@@ -12701,7 +12645,7 @@ nfs4_find_sysid(mntinfo4_t *mi)
* Switch from RDMA knconf to original mount knconf
*/
return (lm_get_sysid(ORIG_KNCONF(mi), &mi->mi_curr_serv->sv_addr,
- mi->mi_curr_serv->sv_hostname, NULL));
+ mi->mi_curr_serv->sv_hostname, NULL));
}
#ifdef DEBUG
@@ -12722,7 +12666,7 @@ nfs4frlock_get_call_type(nfs4_lock_call_type_t ctype)
return ("REINSTATE");
default:
cmn_err(CE_PANIC, "nfs4frlock_get_call_type: got illegal "
- "type %d", ctype);
+ "type %d", ctype);
return ("");
}
}
@@ -12762,7 +12706,7 @@ flk_to_locktype(int cmd, int l_type)
*/
static int
nfs4frlock_validate_args(int cmd, flock64_t *flk, int flag, vnode_t *vp,
- u_offset_t offset)
+ u_offset_t offset)
{
int error = 0;
@@ -12818,8 +12762,8 @@ nfs4frlock_get_sysid(struct lm_sysid **lspp, vnode_t *vp, flock64_t *flk)
*/
static void
nfs4frlock_pre_setup(clock_t *tick_delayp, nfs4_recov_state_t *recov_statep,
- flock64_t *flk, short *whencep, vnode_t *vp, cred_t *search_cr,
- cred_t **cred_otw)
+ flock64_t *flk, short *whencep, vnode_t *vp, cred_t *search_cr,
+ cred_t **cred_otw)
{
/*
* set tick_delay to the base delay time.
@@ -12850,9 +12794,9 @@ nfs4frlock_pre_setup(clock_t *tick_delayp, nfs4_recov_state_t *recov_statep,
*/
static void
nfs4frlock_call_init(COMPOUND4args_clnt *argsp, COMPOUND4args_clnt **argspp,
- nfs_argop4 **argopp, nfs4_op_hint_t *op_hintp, flock64_t *flk, int cmd,
- bool_t *retry, bool_t *did_start_fop, COMPOUND4res_clnt **respp,
- bool_t *skip_get_err, nfs4_lost_rqst_t *lost_rqstp)
+ nfs_argop4 **argopp, nfs4_op_hint_t *op_hintp, flock64_t *flk, int cmd,
+ bool_t *retry, bool_t *did_start_fop, COMPOUND4res_clnt **respp,
+ bool_t *skip_get_err, nfs4_lost_rqst_t *lost_rqstp)
{
int argoplist_size;
int num_ops = 2;
@@ -12887,8 +12831,8 @@ nfs4frlock_call_init(COMPOUND4args_clnt *argsp, COMPOUND4args_clnt **argspp,
*/
static int
nfs4frlock_start_call(nfs4_lock_call_type_t ctype, vnode_t *vp,
- nfs4_op_hint_t op_hint, nfs4_recov_state_t *recov_statep,
- bool_t *did_start_fop, bool_t *startrecovp)
+ nfs4_op_hint_t op_hint, nfs4_recov_state_t *recov_statep,
+ bool_t *did_start_fop, bool_t *startrecovp)
{
int error = 0;
rnode4_t *rp;
@@ -12897,7 +12841,7 @@ nfs4frlock_start_call(nfs4_lock_call_type_t ctype, vnode_t *vp,
if (ctype == NFS4_LCK_CTYPE_NORM) {
error = nfs4_start_fop(VTOMI4(vp), vp, NULL, op_hint,
- recov_statep, startrecovp);
+ recov_statep, startrecovp);
if (error)
return (error);
*did_start_fop = TRUE;
@@ -12927,15 +12871,15 @@ nfs4frlock_start_call(nfs4_lock_call_type_t ctype, vnode_t *vp,
*/
static void
nfs4frlock_setup_resend_lock_args(nfs4_lost_rqst_t *resend_rqstp,
- COMPOUND4args_clnt *argsp, nfs_argop4 *argop, nfs4_lock_owner_t **lopp,
- nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp,
- LOCK4args **lock_argsp, LOCKU4args **locku_argsp)
+ COMPOUND4args_clnt *argsp, nfs_argop4 *argop, nfs4_lock_owner_t **lopp,
+ nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp,
+ LOCK4args **lock_argsp, LOCKU4args **locku_argsp)
{
mntinfo4_t *mi = VTOMI4(resend_rqstp->lr_vp);
int error;
NFS4_DEBUG((nfs4_lost_rqst_debug || nfs4_client_lock_debug),
- (CE_NOTE,
+ (CE_NOTE,
"nfs4frlock_setup_resend_lock_args: have lost lock to resend"));
ASSERT(resend_rqstp != NULL);
ASSERT(resend_rqstp->lr_op == OP_LOCK ||
@@ -12966,13 +12910,13 @@ nfs4frlock_setup_resend_lock_args(nfs4_lost_rqst_t *resend_rqstp,
*lock_argsp = lock_args = &argop->nfs_argop4_u.oplock;
lock_args->locktype = resend_rqstp->lr_locktype;
lock_args->reclaim =
- (resend_rqstp->lr_ctype == NFS4_LCK_CTYPE_RECLAIM);
+ (resend_rqstp->lr_ctype == NFS4_LCK_CTYPE_RECLAIM);
lock_args->offset = resend_rqstp->lr_flk->l_start;
lock_args->length = resend_rqstp->lr_flk->l_len;
if (lock_args->length == 0)
lock_args->length = ~lock_args->length;
nfs4_setup_lock_args(*lopp, *oopp, *ospp,
- mi2clientid(mi), &lock_args->locker);
+ mi2clientid(mi), &lock_args->locker);
switch (resend_rqstp->lr_ctype) {
case NFS4_LCK_CTYPE_RESEND:
@@ -13023,8 +12967,8 @@ nfs4frlock_setup_resend_lock_args(nfs4_lost_rqst_t *resend_rqstp,
*/
static void
nfs4frlock_setup_lockt_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop,
- LOCKT4args **lockt_argsp, COMPOUND4args_clnt *argsp, flock64_t *flk,
- rnode4_t *rp)
+ LOCKT4args **lockt_argsp, COMPOUND4args_clnt *argsp, flock64_t *flk,
+ rnode4_t *rp)
{
LOCKT4args *lockt_args;
@@ -13102,7 +13046,7 @@ nfs4frlock_check_deleg(vnode_t *vp, nfs4_error_t *ep, cred_t *cr, int lt)
if (osp->os_failed_reopen) {
NFS4_DEBUG((nfs4_open_stream_debug ||
- nfs4_client_lock_debug), (CE_NOTE,
+ nfs4_client_lock_debug), (CE_NOTE,
"nfs4frlock_check_deleg: os_failed_reopen set "
"for osp %p, cr %p, rp %s", (void *)osp,
(void *)cr, rnode4info(rp)));
@@ -13124,9 +13068,9 @@ nfs4frlock_check_deleg(vnode_t *vp, nfs4_error_t *ep, cred_t *cr, int lt)
reopen_needed = osp->os_delegation ||
((lt == F_RDLCK &&
- !(osp->os_dc_openacc & OPEN4_SHARE_ACCESS_READ)) ||
+ !(osp->os_dc_openacc & OPEN4_SHARE_ACCESS_READ)) ||
(lt == F_WRLCK &&
- !(osp->os_dc_openacc & OPEN4_SHARE_ACCESS_WRITE)));
+ !(osp->os_dc_openacc & OPEN4_SHARE_ACCESS_WRITE)));
mutex_exit(&osp->os_sync_lock);
open_owner_rele(oop);
@@ -13169,10 +13113,10 @@ nfs4frlock_check_deleg(vnode_t *vp, nfs4_error_t *ep, cred_t *cr, int lt)
*/
static void
nfs4frlock_setup_locku_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop,
- LOCKU4args **locku_argsp, flock64_t *flk,
- nfs4_lock_owner_t **lopp, nfs4_error_t *ep, COMPOUND4args_clnt *argsp,
- vnode_t *vp, int flag, u_offset_t offset, cred_t *cr,
- bool_t *skip_get_err, bool_t *go_otwp)
+ LOCKU4args **locku_argsp, flock64_t *flk,
+ nfs4_lock_owner_t **lopp, nfs4_error_t *ep, COMPOUND4args_clnt *argsp,
+ vnode_t *vp, int flag, u_offset_t offset, cred_t *cr,
+ bool_t *skip_get_err, bool_t *go_otwp)
{
nfs4_lock_owner_t *lop = NULL;
LOCKU4args *locku_args;
@@ -13204,7 +13148,7 @@ nfs4frlock_setup_locku_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop,
locku_args->locktype = READ_LT;
pid = ctype == NFS4_LCK_CTYPE_NORM ? curproc->p_pidp->pid_id :
- flk->l_pid;
+ flk->l_pid;
/*
* Get the lock owner stateid. If no lock owner
@@ -13228,8 +13172,8 @@ nfs4frlock_setup_locku_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop,
* have no lock to undo OTW.
*/
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE,
- "nfs4frlock_setup_locku_args: LOCKU: no lock owner "
- "(%ld) so return success", (long)pid));
+ "nfs4frlock_setup_locku_args: LOCKU: no lock owner "
+ "(%ld) so return success", (long)pid));
if (ctype == NFS4_LCK_CTYPE_NORM)
flk->l_pid = curproc->p_pid;
@@ -13280,9 +13224,9 @@ nfs4frlock_setup_locku_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop,
*/
static void
nfs4frlock_setup_lock_args(nfs4_lock_call_type_t ctype, LOCK4args **lock_argsp,
- nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp,
- nfs4_lock_owner_t **lopp, nfs_argop4 *argop, COMPOUND4args_clnt *argsp,
- flock64_t *flk, int cmd, vnode_t *vp, cred_t *cr, nfs4_error_t *ep)
+ nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp,
+ nfs4_lock_owner_t **lopp, nfs_argop4 *argop, COMPOUND4args_clnt *argsp,
+ flock64_t *flk, int cmd, vnode_t *vp, cred_t *cr, nfs4_error_t *ep)
{
LOCK4args *lock_args;
nfs4_open_owner_t *oop = NULL;
@@ -13316,13 +13260,13 @@ nfs4frlock_setup_lock_args(nfs4_lock_call_type_t ctype, LOCK4args **lock_argsp,
*/
pid = ctype == NFS4_LCK_CTYPE_NORM ? curproc->p_pid : flk->l_pid;
ep->stat =
- nfs4_find_or_create_lock_owner(pid, rp, cr, &oop, &osp, &lop);
+ nfs4_find_or_create_lock_owner(pid, rp, cr, &oop, &osp, &lop);
if (ep->stat != NFS4_OK)
goto out;
nfs4_setup_lock_args(lop, oop, osp, mi2clientid(VTOMI4(vp)),
- &lock_args->locker);
+ &lock_args->locker);
lock_args->offset = flk->l_start;
lock_args->length = flk->l_len;
@@ -13343,9 +13287,9 @@ out:
*/
static void
nfs4frlock_save_lost_rqst(nfs4_lock_call_type_t ctype, int error,
- nfs_lock_type4 locktype, nfs4_open_owner_t *oop,
- nfs4_open_stream_t *osp, nfs4_lock_owner_t *lop, flock64_t *flk,
- nfs4_lost_rqst_t *lost_rqstp, cred_t *cr, vnode_t *vp)
+ nfs_lock_type4 locktype, nfs4_open_owner_t *oop,
+ nfs4_open_stream_t *osp, nfs4_lock_owner_t *lop, flock64_t *flk,
+ nfs4_lost_rqst_t *lost_rqstp, cred_t *cr, vnode_t *vp)
{
bool_t unlock = (flk->l_type == F_UNLCK);
@@ -13355,7 +13299,7 @@ nfs4frlock_save_lost_rqst(nfs4_lock_call_type_t ctype, int error,
if (error != 0 && !unlock) {
NFS4_DEBUG((nfs4_lost_rqst_debug ||
- nfs4_client_lock_debug), (CE_NOTE,
+ nfs4_client_lock_debug), (CE_NOTE,
"nfs4frlock_save_lost_rqst: set lo_pending_rqsts to 1 "
" for lop %p", (void *)lop));
ASSERT(lop != NULL);
@@ -13379,7 +13323,7 @@ nfs4frlock_save_lost_rqst(nfs4_lock_call_type_t ctype, int error,
if (error == ETIMEDOUT || error == EINTR ||
NFS4_FRC_UNMT_ERR(error, vp->v_vfsp)) {
NFS4_DEBUG((nfs4_lost_rqst_debug ||
- nfs4_client_lock_debug), (CE_NOTE,
+ nfs4_client_lock_debug), (CE_NOTE,
"nfs4frlock_save_lost_rqst: got a lost %s lock for "
"lop %p oop %p osp %p", unlock ? "LOCKU" : "LOCK",
(void *)lop, (void *)oop, (void *)osp));
@@ -13457,7 +13401,7 @@ nfs4frlock_check_access(vnode_t *vp, nfs4_op_hint_t op_hint,
if (*did_start_fop) {
nfs4_end_fop(VTOMI4(vp), vp, NULL, op_hint, recov_statep,
- needrecov);
+ needrecov);
*did_start_fop = FALSE;
}
ASSERT((*argspp)->array_len == 2);
@@ -13506,12 +13450,12 @@ nfs4frlock_check_access(vnode_t *vp, nfs4_op_hint_t op_hint,
*/
static bool_t
nfs4frlock_recovery(int needrecov, nfs4_error_t *ep,
- COMPOUND4args_clnt **argspp, COMPOUND4res_clnt **respp,
- LOCK4args *lock_args, LOCKU4args *locku_args,
- nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp,
- nfs4_lock_owner_t **lopp, rnode4_t *rp, vnode_t *vp,
- nfs4_recov_state_t *recov_statep, nfs4_op_hint_t op_hint,
- bool_t *did_start_fop, nfs4_lost_rqst_t *lost_rqstp, flock64_t *flk)
+ COMPOUND4args_clnt **argspp, COMPOUND4res_clnt **respp,
+ LOCK4args *lock_args, LOCKU4args *locku_args,
+ nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp,
+ nfs4_lock_owner_t **lopp, rnode4_t *rp, vnode_t *vp,
+ nfs4_recov_state_t *recov_statep, nfs4_op_hint_t op_hint,
+ bool_t *did_start_fop, nfs4_lost_rqst_t *lost_rqstp, flock64_t *flk)
{
nfs4_open_owner_t *oop = *oopp;
nfs4_open_stream_t *osp = *ospp;
@@ -13542,10 +13486,10 @@ nfs4frlock_recovery(int needrecov, nfs4_error_t *ep,
if (lock_args) {
if (lock_args->locker.new_lock_owner == TRUE)
seqid = lock_args->locker.locker4_u.
- open_owner.open_seqid;
+ open_owner.open_seqid;
else
seqid = lock_args->locker.locker4_u.
- lock_owner.lock_seqid;
+ lock_owner.lock_seqid;
} else if (locku_args) {
seqid = locku_args->seqid;
} else {
@@ -13553,13 +13497,13 @@ nfs4frlock_recovery(int needrecov, nfs4_error_t *ep,
}
bsep = nfs4_create_bseqid_entry(oop, lop, vp,
- flk->l_pid, (*argspp)->ctag, seqid);
+ flk->l_pid, (*argspp)->ctag, seqid);
}
abort = nfs4_start_recovery(ep, VTOMI4(vp), vp, NULL, NULL,
- (lost_rqstp && (lost_rqstp->lr_op == OP_LOCK ||
- lost_rqstp->lr_op == OP_LOCKU)) ? lost_rqstp :
- NULL, op, bsep);
+ (lost_rqstp && (lost_rqstp->lr_op == OP_LOCK ||
+ lost_rqstp->lr_op == OP_LOCKU)) ? lost_rqstp :
+ NULL, op, bsep);
if (bsep)
kmem_free(bsep, sizeof (*bsep));
@@ -13628,8 +13572,8 @@ nfs4frlock_recovery(int needrecov, nfs4_error_t *ep,
*/
static void
nfs4frlock_results_ok(nfs4_lock_call_type_t ctype, int cmd, flock64_t *flk,
- vnode_t *vp, int flag, u_offset_t offset,
- nfs4_lost_rqst_t *resend_rqstp)
+ vnode_t *vp, int flag, u_offset_t offset,
+ nfs4_lost_rqst_t *resend_rqstp)
{
ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
if ((cmd == F_SETLK || cmd == F_SETLKW) &&
@@ -13657,14 +13601,14 @@ nfs4frlock_results_ok(nfs4_lock_call_type_t ctype, int cmd, flock64_t *flk,
*/
static bool_t
nfs4frlock_results_denied(nfs4_lock_call_type_t ctype, LOCK4args *lock_args,
- LOCKT4args *lockt_args, nfs4_open_owner_t **oopp,
- nfs4_open_stream_t **ospp, nfs4_lock_owner_t **lopp, int cmd,
- vnode_t *vp, flock64_t *flk, nfs4_op_hint_t op_hint,
- nfs4_recov_state_t *recov_statep, int needrecov,
- COMPOUND4args_clnt **argspp, COMPOUND4res_clnt **respp,
- clock_t *tick_delayp, short *whencep, int *errorp,
- nfs_resop4 *resop, cred_t *cr, bool_t *did_start_fop,
- bool_t *skip_get_err)
+ LOCKT4args *lockt_args, nfs4_open_owner_t **oopp,
+ nfs4_open_stream_t **ospp, nfs4_lock_owner_t **lopp, int cmd,
+ vnode_t *vp, flock64_t *flk, nfs4_op_hint_t op_hint,
+ nfs4_recov_state_t *recov_statep, int needrecov,
+ COMPOUND4args_clnt **argspp, COMPOUND4res_clnt **respp,
+ clock_t *tick_delayp, short *whencep, int *errorp,
+ nfs_resop4 *resop, cred_t *cr, bool_t *did_start_fop,
+ bool_t *skip_get_err)
{
ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
@@ -13689,7 +13633,7 @@ nfs4frlock_results_denied(nfs4_lock_call_type_t ctype, LOCK4args *lock_args,
ASSERT(ctype == NFS4_LCK_CTYPE_NORM);
nfs4_end_fop(VTOMI4(vp), vp, NULL, op_hint,
- recov_statep, needrecov);
+ recov_statep, needrecov);
*did_start_fop = FALSE;
ASSERT((*argspp)->array_len == 2);
if (argop[1].argop == OP_LOCK)
@@ -13699,7 +13643,7 @@ nfs4frlock_results_denied(nfs4_lock_call_type_t ctype, LOCK4args *lock_args,
kmem_free(argop, 2 * sizeof (nfs_argop4));
if (*respp)
(void) xdr_free(xdr_COMPOUND4res_clnt,
- (caddr_t)*respp);
+ (caddr_t)*respp);
*argspp = NULL;
*respp = NULL;
nfs4_end_lock_seqid_sync(lop);
@@ -13721,13 +13665,13 @@ nfs4frlock_results_denied(nfs4_lock_call_type_t ctype, LOCK4args *lock_args,
if (intr) {
(void) nfs_rw_enter_sig(&rp->r_lkserlock,
- RW_WRITER, FALSE);
+ RW_WRITER, FALSE);
*errorp = EINTR;
return (FALSE);
}
(void) nfs_rw_enter_sig(&rp->r_lkserlock,
- RW_WRITER, FALSE);
+ RW_WRITER, FALSE);
/*
* Make sure we are still safe to lock with
@@ -13751,7 +13695,7 @@ nfs4frlock_results_denied(nfs4_lock_call_type_t ctype, LOCK4args *lock_args,
"nfs4frlock_results_denied: OP_LOCKT DENIED"));
denied_to_flk(&resop->nfs_resop4_u.oplockt.denied,
- flk, lockt_args);
+ flk, lockt_args);
/* according to NLM code */
*errorp = 0;
@@ -13812,9 +13756,9 @@ nfs4frlock_results_default(COMPOUND4res_clnt *resp, int *errorp)
*/
static void
nfs4frlock_update_state(LOCK4args *lock_args, LOCKU4args *locku_args,
- LOCKT4args *lockt_args, nfs_resop4 *resop, nfs4_lock_owner_t *lop,
- vnode_t *vp, flock64_t *flk, cred_t *cr,
- nfs4_lost_rqst_t *resend_rqstp)
+ LOCKT4args *lockt_args, nfs_resop4 *resop, nfs4_lock_owner_t *lop,
+ vnode_t *vp, flock64_t *flk, cred_t *cr,
+ nfs4_lost_rqst_t *resend_rqstp)
{
ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
@@ -13870,13 +13814,13 @@ nfs4frlock_update_state(LOCK4args *lock_args, LOCKU4args *locku_args,
*/
static void
nfs4frlock_final_cleanup(nfs4_lock_call_type_t ctype, COMPOUND4args_clnt *argsp,
- COMPOUND4res_clnt *resp, vnode_t *vp, nfs4_op_hint_t op_hint,
- nfs4_recov_state_t *recov_statep, int needrecov, nfs4_open_owner_t *oop,
- nfs4_open_stream_t *osp, nfs4_lock_owner_t *lop, flock64_t *flk,
- short whence, u_offset_t offset, struct lm_sysid *ls,
- int *errorp, LOCK4args *lock_args, LOCKU4args *locku_args,
- bool_t did_start_fop, bool_t skip_get_err,
- cred_t *cred_otw, cred_t *cred)
+ COMPOUND4res_clnt *resp, vnode_t *vp, nfs4_op_hint_t op_hint,
+ nfs4_recov_state_t *recov_statep, int needrecov, nfs4_open_owner_t *oop,
+ nfs4_open_stream_t *osp, nfs4_lock_owner_t *lop, flock64_t *flk,
+ short whence, u_offset_t offset, struct lm_sysid *ls,
+ int *errorp, LOCK4args *lock_args, LOCKU4args *locku_args,
+ bool_t did_start_fop, bool_t skip_get_err,
+ cred_t *cred_otw, cred_t *cred)
{
mntinfo4_t *mi = VTOMI4(vp);
rnode4_t *rp = VTOR4(vp);
@@ -13894,9 +13838,8 @@ nfs4frlock_final_cleanup(nfs4_lock_call_type_t ctype, COMPOUND4args_clnt *argsp,
*errorp = geterrno4(resp->status);
if (did_start_fop == TRUE)
nfs4_end_fop(mi, vp, NULL, op_hint, recov_statep,
- needrecov);
+ needrecov);
- if (!error && resp && resp->status == NFS4_OK) {
/*
* We've established a new lock on the server, so invalidate
* the pages associated with the vnode to get the most up to
@@ -13908,10 +13851,11 @@ nfs4frlock_final_cleanup(nfs4_lock_call_type_t ctype, COMPOUND4args_clnt *argsp,
* nfs4_start_fop. We flush the pages below after calling
* nfs4_end_fop above
*/
+ if (!error && resp && resp->status == NFS4_OK) {
int error;
error = VOP_PUTPAGE(vp, (u_offset_t)0,
- 0, B_INVAL, cred);
+ 0, B_INVAL, cred);
if (error && (error == ENOSPC || error == EDQUOT)) {
rnode4_t *rp = VTOR4(vp);
@@ -14010,8 +13954,8 @@ nfs4frlock_final_cleanup(nfs4_lock_call_type_t ctype, COMPOUND4args_clnt *argsp,
*/
void
nfs4frlock(nfs4_lock_call_type_t ctype, vnode_t *vp, int cmd, flock64_t *flk,
- int flag, u_offset_t offset, cred_t *cr, nfs4_error_t *ep,
- nfs4_lost_rqst_t *resend_rqstp, int *did_reclaimp)
+ int flag, u_offset_t offset, cred_t *cr, nfs4_error_t *ep,
+ nfs4_lost_rqst_t *resend_rqstp, int *did_reclaimp)
{
COMPOUND4args_clnt args, *argsp = NULL;
COMPOUND4res_clnt res, *resp = NULL;
@@ -14068,11 +14012,11 @@ nfs4frlock(nfs4_lock_call_type_t ctype, vnode_t *vp, int cmd, flock64_t *flk,
recov_retry:
nfs4frlock_call_init(&args, &argsp, &argop, &op_hint, flk, cmd,
- &retry, &did_start_fop, &resp, &skip_get_err, &lost_rqst);
+ &retry, &did_start_fop, &resp, &skip_get_err, &lost_rqst);
rp = VTOR4(vp);
ep->error = nfs4frlock_start_call(ctype, vp, op_hint, &recov_state,
- &did_start_fop, &recovonly);
+ &did_start_fop, &recovonly);
if (ep->error)
goto out;
@@ -14090,12 +14034,12 @@ recov_retry:
lop = find_lock_owner(rp, curproc->p_pid, LOWN_ANY);
if (lop != NULL) {
nfs4frlock_save_lost_rqst(ctype, ep->error, READ_LT,
- NULL, NULL, lop, flk, &lost_rqst, cr, vp);
+ NULL, NULL, lop, flk, &lost_rqst, cr, vp);
(void) nfs4_start_recovery(ep,
- VTOMI4(vp), vp, NULL, NULL,
- (lost_rqst.lr_op == OP_LOCK ||
- lost_rqst.lr_op == OP_LOCKU) ?
- &lost_rqst : NULL, OP_LOCKU, NULL);
+ VTOMI4(vp), vp, NULL, NULL,
+ (lost_rqst.lr_op == OP_LOCK ||
+ lost_rqst.lr_op == OP_LOCKU) ?
+ &lost_rqst : NULL, OP_LOCKU, NULL);
lock_owner_rele(lop);
lop = NULL;
}
@@ -14116,7 +14060,7 @@ recov_retry:
if (ctype == NFS4_LCK_CTYPE_RESEND ||
ctype == NFS4_LCK_CTYPE_REINSTATE) {
nfs4frlock_setup_resend_lock_args(resend_rqstp, argsp,
- &argop[1], &lop, &oop, &osp, &lock_args, &locku_args);
+ &argop[1], &lop, &oop, &osp, &lock_args, &locku_args);
} else {
bool_t go_otw = TRUE;
@@ -14126,20 +14070,20 @@ recov_retry:
case F_GETLK:
case F_O_GETLK:
nfs4frlock_setup_lockt_args(ctype, &argop[1],
- &lockt_args, argsp, flk, rp);
+ &lockt_args, argsp, flk, rp);
break;
case F_SETLKW:
case F_SETLK:
if (flk->l_type == F_UNLCK)
nfs4frlock_setup_locku_args(ctype,
- &argop[1], &locku_args, flk,
- &lop, ep, argsp,
- vp, flag, offset, cr,
- &skip_get_err, &go_otw);
+ &argop[1], &locku_args, flk,
+ &lop, ep, argsp,
+ vp, flag, offset, cr,
+ &skip_get_err, &go_otw);
else
nfs4frlock_setup_lock_args(ctype,
- &lock_args, &oop, &osp, &lop, &argop[1],
- argsp, flk, cmd, vp, cr, ep);
+ &lock_args, &oop, &osp, &lop, &argop[1],
+ argsp, flk, cmd, vp, cr, ep);
if (ep->error)
goto out;
@@ -14169,7 +14113,7 @@ recov_retry:
break;
default:
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE,
- "nfs4_frlock: invalid cmd %d", cmd));
+ "nfs4_frlock: invalid cmd %d", cmd));
ep->error = EINVAL;
goto out;
}
@@ -14264,13 +14208,13 @@ recov_retry:
}
nfs4frlock_save_lost_rqst(ctype, ep->error,
- flk_to_locktype(cmd, flk->l_type),
- oop, osp, lop, flk, &lost_rqst, cred_otw, vp);
+ flk_to_locktype(cmd, flk->l_type),
+ oop, osp, lop, flk, &lost_rqst, cred_otw, vp);
retry = nfs4frlock_recovery(needrecov, ep, &argsp,
- &resp, lock_args, locku_args, &oop, &osp, &lop,
- rp, vp, &recov_state, op_hint, &did_start_fop,
- cmd != F_GETLK ? &lost_rqst : NULL, flk);
+ &resp, lock_args, locku_args, &oop, &osp, &lop,
+ rp, vp, &recov_state, op_hint, &did_start_fop,
+ cmd != F_GETLK ? &lost_rqst : NULL, flk);
if (retry) {
ASSERT(oop == NULL);
@@ -14297,21 +14241,21 @@ recov_retry:
case NFS4_OK:
resop = &resp->array[1];
nfs4frlock_results_ok(ctype, cmd, flk, vp, flag, offset,
- resend_rqstp);
+ resend_rqstp);
/*
* Have a successful lock operation, now update state.
*/
nfs4frlock_update_state(lock_args, locku_args, lockt_args,
- resop, lop, vp, flk, cr, resend_rqstp);
+ resop, lop, vp, flk, cr, resend_rqstp);
break;
case NFS4ERR_DENIED:
resop = &resp->array[1];
retry = nfs4frlock_results_denied(ctype, lock_args, lockt_args,
- &oop, &osp, &lop, cmd, vp, flk, op_hint,
- &recov_state, needrecov, &argsp, &resp,
- &tick_delay, &whence, &ep->error, resop, cr,
- &did_start_fop, &skip_get_err);
+ &oop, &osp, &lop, cmd, vp, flk, op_hint,
+ &recov_state, needrecov, &argsp, &resp,
+ &tick_delay, &whence, &ep->error, resop, cr,
+ &did_start_fop, &skip_get_err);
if (retry) {
ASSERT(oop == NULL);
@@ -14351,9 +14295,9 @@ out:
* client recovery code.
*/
nfs4frlock_final_cleanup(ctype, argsp, resp, vp, op_hint, &recov_state,
- needrecov, oop, osp, lop, flk, whence, offset, ls, &ep->error,
- lock_args, locku_args, did_start_fop,
- skip_get_err, cred_otw, cr);
+ needrecov, oop, osp, lop, flk, whence, offset, ls, &ep->error,
+ lock_args, locku_args, did_start_fop,
+ skip_get_err, cred_otw, cr);
if (ep->error == EINTR && flk->l_type == F_UNLCK &&
(cmd == F_SETLK || cmd == F_SETLKW))
@@ -14377,9 +14321,9 @@ nfs4_safelock(vnode_t *vp, const struct flock64 *bfp, cred_t *cr)
ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
ASSERT(rp->r_mapcnt >= 0);
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE, "nfs4_safelock %s: "
- "(%"PRIx64", %"PRIx64"); mapcnt = %ld", bfp->l_type == F_WRLCK ?
- "write" : bfp->l_type == F_RDLCK ? "read" : "unlock",
- bfp->l_start, bfp->l_len, rp->r_mapcnt));
+ "(%"PRIx64", %"PRIx64"); mapcnt = %ld", bfp->l_type == F_WRLCK ?
+ "write" : bfp->l_type == F_RDLCK ? "read" : "unlock",
+ bfp->l_start, bfp->l_len, rp->r_mapcnt));
if (rp->r_mapcnt == 0)
return (1); /* always safe if not mapped */
@@ -14393,9 +14337,9 @@ nfs4_safelock(vnode_t *vp, const struct flock64 *bfp, cred_t *cr)
if (bfp->l_start != 0 || bfp->l_len != 0) {
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE, "nfs4_safelock: "
- "cannot lock a memory mapped file unless locking the "
- "entire file: start %"PRIx64", len %"PRIx64,
- bfp->l_start, bfp->l_len));
+ "cannot lock a memory mapped file unless locking the "
+ "entire file: start %"PRIx64", len %"PRIx64,
+ bfp->l_start, bfp->l_len));
return (0);
}
@@ -14404,12 +14348,12 @@ nfs4_safelock(vnode_t *vp, const struct flock64 *bfp, cred_t *cr)
error = VOP_GETATTR(vp, &va, 0, cr);
if (error != 0) {
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE, "nfs4_safelock: "
- "getattr error %d", error));
+ "getattr error %d", error));
return (0); /* treat errors conservatively */
}
if (MANDLOCK(vp, va.va_mode)) {
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE, "nfs4_safelock: "
- "cannot mandatory lock and mmap a file"));
+ "cannot mandatory lock and mmap a file"));
return (0);
}
@@ -14427,7 +14371,7 @@ nfs4_safelock(vnode_t *vp, const struct flock64 *bfp, cred_t *cr)
*/
void
nfs4_register_lock_locally(vnode_t *vp, struct flock64 *flk, int flag,
- u_offset_t offset)
+ u_offset_t offset)
{
int oldsysid;
int error;
@@ -14454,20 +14398,20 @@ nfs4_register_lock_locally(vnode_t *vp, struct flock64 *flk, int flag,
#ifdef DEBUG
if (error != 0) {
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE,
- "nfs4_register_lock_locally: could not register with"
- " local locking"));
+ "nfs4_register_lock_locally: could not register with"
+ " local locking"));
NFS4_DEBUG(nfs4_client_lock_debug, (CE_CONT,
- "error %d, vp 0x%p, pid %d, sysid 0x%x",
- error, (void *)vp, flk->l_pid, flk->l_sysid));
+ "error %d, vp 0x%p, pid %d, sysid 0x%x",
+ error, (void *)vp, flk->l_pid, flk->l_sysid));
NFS4_DEBUG(nfs4_client_lock_debug, (CE_CONT,
- "type %d off 0x%" PRIx64 " len 0x%" PRIx64,
- flk->l_type, flk->l_start, flk->l_len));
+ "type %d off 0x%" PRIx64 " len 0x%" PRIx64,
+ flk->l_type, flk->l_start, flk->l_len));
(void) reclock(vp, flk, 0, flag, offset, NULL);
NFS4_DEBUG(nfs4_client_lock_debug, (CE_CONT,
- "blocked by pid %d sysid 0x%x type %d "
- "off 0x%" PRIx64 " len 0x%" PRIx64,
- flk->l_pid, flk->l_sysid, flk->l_type, flk->l_start,
- flk->l_len));
+ "blocked by pid %d sysid 0x%x type %d "
+ "off 0x%" PRIx64 " len 0x%" PRIx64,
+ flk->l_pid, flk->l_sysid, flk->l_type, flk->l_start,
+ flk->l_len));
}
#endif
flk->l_sysid = oldsysid;
@@ -14515,7 +14459,7 @@ nfs4_lockrelease(vnode_t *vp, int flag, offset_t offset, cred_t *cr)
recov_state.rs_flags = 0;
recov_state.rs_num_retry_despite_err = 0;
error = nfs4_start_fop(mi, vp, NULL, OH_LOCKU, &recov_state,
- &recovonly);
+ &recovonly);
if (error) {
mutex_enter(&rp->r_statelock);
rp->r_flags |= R4LODANGLERS;
@@ -14568,15 +14512,15 @@ nfs4_lockrelease(vnode_t *vp, int flag, offset_t offset, cred_t *cr)
ld.l_pid = ttoproc(curthread)->p_pid;
nfs4_register_lock_locally(vp, &ld, flag, offset);
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE,
- "nfs4_lockrelease: lock release error on vp"
- " %p: error %d.\n", (void *)vp, ret));
+ "nfs4_lockrelease: lock release error on vp"
+ " %p: error %d.\n", (void *)vp, ret));
}
}
recov_state.rs_flags = 0;
recov_state.rs_num_retry_despite_err = 0;
error = nfs4_start_fop(mi, vp, NULL, OH_LOCKU, &recov_state,
- &recovonly);
+ &recovonly);
if (error) {
mutex_enter(&rp->r_statelock);
rp->r_flags |= R4LODANGLERS;
@@ -14618,8 +14562,8 @@ nfs4_block_and_wait(clock_t *tick_delay, rnode4_t *rp)
return (EINTR);
}
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE, "nfs4_block_and_wait: "
- "reissue the lock request: blocked for %ld clock ticks: %ld "
- "milliseconds", *tick_delay, drv_hztousec(*tick_delay) / 1000));
+ "reissue the lock request: blocked for %ld clock ticks: %ld "
+ "milliseconds", *tick_delay, drv_hztousec(*tick_delay) / 1000));
/* get the lease time */
lock_lease_time = r2lease_time(rp);
@@ -14694,26 +14638,26 @@ vtodv(vnode_t *vp, vnode_t **dvpp, cred_t *cr, bool_t need_start_op)
if (svnp == NULL) {
NFS4_DEBUG(nfs4_client_shadow_debug, (CE_NOTE, "vtodv: "
- "shadow node is NULL"));
+ "shadow node is NULL"));
return (EINVAL);
}
if (svnp->sv_name == NULL || svnp->sv_dfh == NULL) {
NFS4_DEBUG(nfs4_client_shadow_debug, (CE_NOTE, "vtodv: "
- "shadow node name or dfh val == NULL"));
+ "shadow node name or dfh val == NULL"));
return (EINVAL);
}
error = nfs4_make_dotdot(svnp->sv_dfh, 0, vp, cr, &dvp,
- (int)need_start_op);
+ (int)need_start_op);
if (error != 0) {
NFS4_DEBUG(nfs4_client_shadow_debug, (CE_NOTE, "vtodv: "
- "nfs4_make_dotdot returned %d", error));
+ "nfs4_make_dotdot returned %d", error));
return (error);
}
if (!dvp) {
NFS4_DEBUG(nfs4_client_shadow_debug, (CE_NOTE, "vtodv: "
- "nfs4_make_dotdot returned a NULL dvp"));
+ "nfs4_make_dotdot returned a NULL dvp"));
return (EIO);
}
if (dvp->v_type == VNON)
@@ -14957,9 +14901,9 @@ nfs4close_all(vnode_t *vp, cred_t *cr)
*/
void
nfs4close_one(vnode_t *vp, nfs4_open_stream_t *provided_osp, cred_t *cr,
- int access_bits, nfs4_lost_rqst_t *lrp, nfs4_error_t *ep,
- nfs4_close_type_t close_type, size_t len, uint_t maxprot,
- uint_t mmap_flags)
+ int access_bits, nfs4_lost_rqst_t *lrp, nfs4_error_t *ep,
+ nfs4_close_type_t close_type, size_t len, uint_t maxprot,
+ uint_t mmap_flags)
{
nfs4_open_owner_t *oop;
nfs4_open_stream_t *osp = NULL;
@@ -14990,7 +14934,7 @@ nfs4close_one(vnode_t *vp, nfs4_open_stream_t *provided_osp, cred_t *cr,
rp = VTOR4(vp);
mi = VTOMI4(vp);
isrecov = (close_type == CLOSE_RESEND ||
- close_type == CLOSE_AFTER_RESEND);
+ close_type == CLOSE_AFTER_RESEND);
/*
* First get the open owner.
@@ -15031,7 +14975,7 @@ recov_retry:
*/
if (!isrecov) {
ep->error = nfs4_start_fop(mi, vp, NULL, OH_CLOSE,
- &recov_state, &recovonly);
+ &recov_state, &recovonly);
if (!ep->error) {
did_start_op = 1;
} else {
@@ -15044,7 +14988,7 @@ recov_retry:
*/
if (close_type == CLOSE_FORCE) {
(void) nfs_rw_enter_sig(&mi->mi_recovlock,
- RW_READER, FALSE);
+ RW_READER, FALSE);
did_force_recovlock = 1;
} else
goto out;
@@ -15067,7 +15011,7 @@ recov_retry:
ASSERT(!isrecov);
if (did_start_op)
nfs4_end_fop(mi, vp, NULL, OH_CLOSE,
- &recov_state, TRUE);
+ &recov_state, TRUE);
if (did_force_recovlock)
nfs_rw_exit(&mi->mi_recovlock);
goto recov_retry;
@@ -15177,12 +15121,12 @@ recov_retry:
ASSERT(lrp == NULL);
nfs4_error_init(ep, EINTR);
nfs4close_save_lost_rqst(ep->error, &lost_rqst, oop,
- osp, cred_otw, vp);
+ osp, cred_otw, vp);
mutex_exit(&osp->os_sync_lock);
have_sync_lock = 0;
(void) nfs4_start_recovery(ep, mi, vp, NULL, NULL,
- lost_rqst.lr_op == OP_CLOSE ?
- &lost_rqst : NULL, OP_CLOSE, NULL);
+ lost_rqst.lr_op == OP_CLOSE ?
+ &lost_rqst : NULL, OP_CLOSE, NULL);
close_failed = 1;
force_close = 0;
goto close_cleanup;
@@ -15247,7 +15191,7 @@ recov_retry:
goto out;
}
nfs4_open_downgrade(access_bits, 0, oop, osp, vp, cr,
- lrp, ep, &odg_cred_otw, &open_dg_seqid);
+ lrp, ep, &odg_cred_otw, &open_dg_seqid);
needrecov = nfs4_needs_recovery(ep, TRUE, mi->mi_vfsp);
if (needrecov && !isrecov) {
bool_t abort;
@@ -15255,18 +15199,18 @@ recov_retry:
if (!ep->error && ep->stat == NFS4ERR_BAD_SEQID)
bsep = nfs4_create_bseqid_entry(oop, NULL,
- vp, 0,
- lrp ? TAG_OPEN_DG_LOST : TAG_OPEN_DG,
- open_dg_seqid);
+ vp, 0,
+ lrp ? TAG_OPEN_DG_LOST : TAG_OPEN_DG,
+ open_dg_seqid);
nfs4open_dg_save_lost_rqst(ep->error, &new_lost_rqst,
oop, osp, odg_cred_otw, vp, access_bits, 0);
mutex_exit(&osp->os_sync_lock);
have_sync_lock = 0;
abort = nfs4_start_recovery(ep, mi, vp, NULL, NULL,
- new_lost_rqst.lr_op == OP_OPEN_DOWNGRADE ?
- &new_lost_rqst : NULL, OP_OPEN_DOWNGRADE,
- bsep);
+ new_lost_rqst.lr_op == OP_OPEN_DOWNGRADE ?
+ &new_lost_rqst : NULL, OP_OPEN_DOWNGRADE,
+ bsep);
if (odg_cred_otw)
crfree(odg_cred_otw);
if (bsep)
@@ -15283,7 +15227,7 @@ recov_retry:
if (did_start_op)
nfs4_end_fop(mi, vp, NULL, OH_CLOSE,
- &recov_state, FALSE);
+ &recov_state, FALSE);
if (did_force_recovlock)
nfs_rw_exit(&mi->mi_recovlock);
@@ -15394,12 +15338,12 @@ recov_retry:
if (did_start_op)
nfs4_end_fop(mi, vp, NULL, OH_CLOSE,
- &recov_state, FALSE);
+ &recov_state, FALSE);
if (did_force_recovlock)
nfs_rw_exit(&mi->mi_recovlock);
NFS4_DEBUG(nfs4_client_recov_debug, (CE_NOTE,
- "nfs4close_one: need to retry the close "
- "operation"));
+ "nfs4close_one: need to retry the close "
+ "operation"));
goto recov_retry;
}
close_cleanup:
@@ -15496,12 +15440,12 @@ denied_to_flk(LOCK4denied *lockt_denied, flock64_t *flk, LOCKT4args *lockt_args)
if (lockt_denied->owner.owner_len == sizeof (*lo)) {
lo = (nfs4_lo_name_t *)
- lockt_denied->owner.owner_val;
+ lockt_denied->owner.owner_val;
flk->l_pid = lo->ln_pid;
} else {
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE,
- "denied_to_flk: bad lock owner length\n"));
+ "denied_to_flk: bad lock owner length\n"));
flk->l_pid = lo_to_pid(&lockt_denied->owner);
}
@@ -15601,7 +15545,7 @@ locks_intersect(flock64_t *llfp, flock64_t *curfp)
curfp_end = lock_to_end(curfp);
if (((llfp_end >= curfp->l_start) &&
- (llfp->l_start <= curfp->l_start)) ||
+ (llfp->l_start <= curfp->l_start)) ||
((curfp->l_start <= llfp->l_start) && (curfp_end >= llfp->l_start)))
return (1);
return (0);
@@ -15613,7 +15557,7 @@ locks_intersect(flock64_t *llfp, flock64_t *curfp)
*/
static void
nfs4_add_lock_range(flock64_t *lost_flp, flock64_t *local_flp,
- locklist_t **nl_llpp, vnode_t *vp)
+ locklist_t **nl_llpp, vnode_t *vp)
{
locklist_t *intersect_llp, *tmp_fllp, *cur_fllp;
off64_t lost_flp_end, local_flp_end, len, start;
@@ -15660,7 +15604,7 @@ nfs4_add_lock_range(flock64_t *lost_flp, flock64_t *local_flp,
tmp_fllp = *nl_llpp;
cur_fllp = NULL;
while (tmp_fllp != NULL && tmp_fllp->ll_flock.l_start <
- intersect_llp->ll_flock.l_start) {
+ intersect_llp->ll_flock.l_start) {
cur_fllp = tmp_fllp;
tmp_fllp = tmp_fllp->ll_next;
}
@@ -15698,7 +15642,7 @@ nfs4_add_lock_range(flock64_t *lost_flp, flock64_t *local_flp,
*/
static void
nfs4_reinstitute_local_lock_state(vnode_t *vp, flock64_t *lost_flp, cred_t *cr,
- nfs4_lock_owner_t *lop)
+ nfs4_lock_owner_t *lop)
{
locklist_t *locks, *llp, *ri_llp, *tmp_llp;
mntinfo4_t *mi = VTOMI4(vp);
@@ -15707,7 +15651,7 @@ nfs4_reinstitute_local_lock_state(vnode_t *vp, flock64_t *lost_flp, cred_t *cr,
flock64_t ul_fl;
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE,
- "nfs4_reinstitute_local_lock_state"));
+ "nfs4_reinstitute_local_lock_state"));
/*
* Find active locks for this vp from the local locking code.
@@ -15785,9 +15729,9 @@ nfs4_reinstitute_local_lock_state(vnode_t *vp, flock64_t *lost_flp, cred_t *cr,
continue;
}
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE,
- "nfs4_reinstitute_local_lock_state: "
- "UNLOCK [%"PRIx64" - %"PRIx64"]",
- cur_start, llp->ll_flock.l_start));
+ "nfs4_reinstitute_local_lock_state: "
+ "UNLOCK [%"PRIx64" - %"PRIx64"]",
+ cur_start, llp->ll_flock.l_start));
ul_fl.l_start = cur_start;
ul_fl.l_len = end_to_len(cur_start,
@@ -15803,9 +15747,9 @@ nfs4_reinstitute_local_lock_state(vnode_t *vp, flock64_t *lost_flp, cred_t *cr,
*/
if (cur_start != start_check(lost_flp_end)) {
NFS4_DEBUG(nfs4_lost_rqst_debug, (CE_NOTE,
- "nfs4_reinstitute_local_lock_state: UNLOCK end of the "
- "lost lock region [%"PRIx64" - %"PRIx64"]",
- cur_start, lost_flp->l_start + lost_flp->l_len));
+ "nfs4_reinstitute_local_lock_state: UNLOCK end of the "
+ "lost lock region [%"PRIx64" - %"PRIx64"]",
+ cur_start, lost_flp->l_start + lost_flp->l_len));
ul_fl.l_start = cur_start;
/*
@@ -15841,7 +15785,7 @@ nfs4_reinstitute_local_lock_state(vnode_t *vp, flock64_t *lost_flp, cred_t *cr,
*/
static void
push_reinstate(vnode_t *vp, int cmd, flock64_t *flk, cred_t *cr,
- nfs4_lock_owner_t *lop)
+ nfs4_lock_owner_t *lop)
{
nfs4_lost_rqst_t req;
nfs_lock_type4 locktype;
@@ -15851,9 +15795,9 @@ push_reinstate(vnode_t *vp, int cmd, flock64_t *flk, cred_t *cr,
locktype = flk_to_locktype(cmd, flk->l_type);
nfs4frlock_save_lost_rqst(NFS4_LCK_CTYPE_REINSTATE, EINTR, locktype,
- NULL, NULL, lop, flk, &req, cr, vp);
+ NULL, NULL, lop, flk, &req, cr, vp);
(void) nfs4_start_recovery(&e, VTOMI4(vp), vp, NULL, NULL,
- (req.lr_op == OP_LOCK || req.lr_op == OP_LOCKU) ?
- &req : NULL, flk->l_type == F_UNLCK ? OP_LOCKU : OP_LOCK,
- NULL);
+ (req.lr_op == OP_LOCK || req.lr_op == OP_LOCKU) ?
+ &req : NULL, flk->l_type == F_UNLCK ? OP_LOCKU : OP_LOCK,
+ NULL);
}
diff --git a/usr/src/uts/common/fs/nfs/nfs_sys.c b/usr/src/uts/common/fs/nfs/nfs_sys.c
index f42361def0..6034b67145 100644
--- a/usr/src/uts/common/fs/nfs/nfs_sys.c
+++ b/usr/src/uts/common/fs/nfs/nfs_sys.c
@@ -358,6 +358,19 @@ nfssys(enum nfssys_op opcode, void *arg)
break;
}
+ case NFS4_EPHEMERAL_MOUNT_TO: {
+ uint_t mount_to;
+
+ /*
+ * Not a very complicated call.
+ */
+ if (copyin(arg, &mount_to, sizeof (mount_to)))
+ return (set_errno(EFAULT));
+ nfs4_ephemeral_set_mount_to(mount_to);
+ error = 0;
+ break;
+ }
+
case MOUNTD_ARGS: {
uint_t did;
diff --git a/usr/src/uts/common/fs/vfs.c b/usr/src/uts/common/fs/vfs.c
index db456f4d34..a1b7059e9b 100644
--- a/usr/src/uts/common/fs/vfs.c
+++ b/usr/src/uts/common/fs/vfs.c
@@ -957,7 +957,7 @@ stripzonepath(const char *strpath)
/*
* Common mount code. Called from the system call entry point, from autofs,
- * and from pxfs.
+ * nfsv4 trigger mounts, and from pxfs.
*
* Takes the effective file system type, mount arguments, the mount point
* vnode, flags specifying whether the mount is a remount and whether it
diff --git a/usr/src/uts/common/nfs/mount.h b/usr/src/uts/common/nfs/mount.h
index 91e6e66c69..4b5c3adb9c 100644
--- a/usr/src/uts/common/nfs/mount.h
+++ b/usr/src/uts/common/nfs/mount.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -157,6 +156,12 @@ struct nfs_args32 {
#define NFSMNT_SECDEFAULT 0x4000000 /* mount using default sec flavor */
#define NFSMNT_TRYRDMA 0x8000000 /* Try RDMA mount,no proto advised */
#define NFSMNT_DORDMA 0x10000000 /* Do an RDMA mount, regardless */
+#define NFSMNT_MIRRORMOUNT 0x20000000 /* Is a mirrormount */
+
+/*
+ * This will have to change when we do referrals.
+ */
+#define NFSMNT_EPHEMERAL NFSMNT_MIRRORMOUNT
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/nfs/nfs4.h b/usr/src/uts/common/nfs/nfs4.h
index ef4365b9d0..2000cac44f 100644
--- a/usr/src/uts/common/nfs/nfs4.h
+++ b/usr/src/uts/common/nfs/nfs4.h
@@ -942,7 +942,6 @@ extern int nfs4_seqid_sync;
extern int nfs4_client_map_debug;
extern int nfs4_client_inactive_debug;
extern int nfs4_client_recov_debug;
-extern int nfs4_client_recov_stub_debug;
extern int nfs4_client_failover_debug;
extern int nfs4_client_call_debug;
extern int nfs4_client_foo_debug;
@@ -1328,6 +1327,8 @@ extern kstat_named_t *rfsproccnt_v4_ptr;
extern struct vfsops *nfs4_vfsops;
extern struct vnodeops *nfs4_vnodeops;
extern const struct fs_operation_def nfs4_vnodeops_template[];
+extern vnodeops_t *nfs4_trigger_vnodeops;
+extern const struct fs_operation_def nfs4_trigger_vnodeops_template[];
extern uint_t nfs4_tsize(struct knetconfig *);
extern uint_t rfs4_tsize(struct svc_req *);
diff --git a/usr/src/uts/common/nfs/nfs4_clnt.h b/usr/src/uts/common/nfs/nfs4_clnt.h
index df23a4da0d..e91abcd81d 100644
--- a/usr/src/uts/common/nfs/nfs4_clnt.h
+++ b/usr/src/uts/common/nfs/nfs4_clnt.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,6 +47,7 @@
#include <nfs/rnode.h>
#include <sys/avl.h>
#include <sys/list.h>
+#include <rpc/auth.h>
#ifdef __cplusplus
extern "C" {
@@ -823,6 +824,8 @@ typedef struct nfs4_debug_msg {
* mi_foo_max
* mi_lost_state
* mi_bseqid_list
+ * mi_ephemeral
+ * mi_ephemeral_tree
*
* Normally the netconfig information for the mount comes from
* mi_curr_serv and mi_klmconfig is NULL. If NLM calls need to use a
@@ -881,8 +884,19 @@ typedef struct nfs4_debug_msg {
*
* mi_zone_node is linkage into the mi4_globals.mig_list, and is
* protected by mi4_globals.mig_list_lock.
+ *
+ * If MI4_EPHEMERAL is set in mi_flags, then mi_ephemeral points to an
+ * ephemeral structure for this ephemeral mount point. It can not be
+ * NULL. Also, mi_ephemeral_tree points to the root of the ephemeral
+ * tree.
+ *
+ * If MI4_EPHEMERAL is not set in mi_flags, then mi_ephemeral has
+ * to be NULL. If mi_ephemeral_tree is non-NULL, then this node
+ * is the enclosing mntinfo4 for the ephemeral tree.
*/
struct zone;
+struct nfs4_ephemeral;
+struct nfs4_ephemeral_tree;
typedef struct mntinfo4 {
kmutex_t mi_lock; /* protects mntinfo4 fields */
struct servinfo4 *mi_servers; /* server list */
@@ -1003,6 +1017,12 @@ typedef struct mntinfo4 {
*/
struct zone *mi_zone; /* Zone mounted in */
list_node_t mi_zone_node; /* linkage into per-zone mi list */
+
+ /*
+ * Links for unmounting ephemeral mounts.
+ */
+ struct nfs4_ephemeral *mi_ephemeral;
+ struct nfs4_ephemeral_tree *mi_ephemeral_tree;
} mntinfo4_t;
/*
@@ -1019,7 +1039,11 @@ typedef struct mntinfo4 {
* MI4_SHUTDOWN System is rebooting or shutting down
* MI4_LINK server supports link
* MI4_SYMLINK server supports symlink
+ * MI4_EPHEMERAL_RECURSED an ephemeral mount being unmounted
+ * due to a recursive call - no need
+ * for additional recursion
* MI4_ACL server supports NFSv4 ACLs
+ * MI4_MIRRORMOUNT is a mirrormount
* MI4_NOPRINT don't print messages
* MI4_DIRECTIO do direct I/O
* MI4_RECOV_ACTIV filesystem has recovery a thread
@@ -1034,6 +1058,7 @@ typedef struct mntinfo4 {
* MI4_BADOWNER_DEBUG badowner error msg per mount
* MI4_ASYNC_MGR_STOP tell async manager to die
* MI4_TIMEDOUT saw a timeout during zone shutdown
+ * MI4_EPHEMERAL is an ephemeral mount
*/
#define MI4_HARD 0x1
#define MI4_PRINTED 0x2
@@ -1046,9 +1071,10 @@ typedef struct mntinfo4 {
#define MI4_SHUTDOWN 0x200
#define MI4_LINK 0x400
#define MI4_SYMLINK 0x800
-/* 0x1000 is available */
+#define MI4_EPHEMERAL_RECURSED 0x1000
#define MI4_ACL 0x2000
-/* 0x4000 is available */
+/* MI4_MIRRORMOUNT is also defined in nfsstat.c */
+#define MI4_MIRRORMOUNT 0x4000
/* 0x8000 is available */
/* 0x10000 is available */
#define MI4_NOPRINT 0x20000
@@ -1067,6 +1093,12 @@ typedef struct mntinfo4 {
#define MI4_ASYNC_MGR_STOP 0x40000000
#define MI4_TIMEDOUT 0x80000000
+/*
+ * Note that when we add referrals, then MI4_EPHEMERAL
+ * will be MI4_MIRRORMOUNT | MI4_REFERRAL.
+ */
+#define MI4_EPHEMERAL MI4_MIRRORMOUNT
+
#define INTR4(vp) (VTOMI4(vp)->mi_flags & MI4_INT)
#define FAILOVER_MOUNT4(mi) (mi->mi_servers->sv_next)
@@ -1252,6 +1284,114 @@ typedef enum {
} nfs4_op_hint_t;
/*
+ * This data structure is used to track ephemeral mounts for both
+ * mirror mounts and referrals.
+ *
+ * Note that each nfs4_ephemeral can only have one other nfs4_ephemeral
+ * pointing at it. So we don't need two backpointers to walk
+ * back up the tree.
+ *
+ * An ephemeral tree is pointed to by an enclosing non-ephemeral
+ * mntinfo4. The root is also pointed to by its ephemeral
+ * mntinfo4. ne_child will get us back to it, while ne_prior
+ * will get us back to the non-ephemeral mntinfo4. This is an
+ * edge case we will need to be wary of when walking back up the
+ * tree.
+ *
+ * The way we handle this edge case is to have ne_prior be NULL
+ * for the root nfs4_ephemeral node.
+ */
+typedef struct nfs4_ephemeral {
+ mntinfo4_t *ne_mount; /* who encloses us */
+ struct nfs4_ephemeral *ne_child; /* first child node */
+ struct nfs4_ephemeral *ne_peer; /* next sibling */
+ struct nfs4_ephemeral *ne_prior; /* who points at us */
+ time_t ne_ref_time; /* time last referenced */
+ uint_t ne_mount_to; /* timeout at */
+ int ne_state; /* used to traverse */
+} nfs4_ephemeral_t;
+
+/*
+ * State for the node (set in ne_state):
+ */
+#define NFS4_EPHEMERAL_OK 0x0
+#define NFS4_EPHEMERAL_VISIT_CHILD 0x1
+#define NFS4_EPHEMERAL_VISIT_SIBLING 0x2
+#define NFS4_EPHEMERAL_PROCESS_ME 0x4
+#define NFS4_EPHEMERAL_CHILD_ERROR 0x8
+#define NFS4_EPHEMERAL_PEER_ERROR 0x10
+
+/*
+ * These are the locks used in processing ephemeral data:
+ *
+ * mi->mi_lock
+ *
+ * net->net_tree_lock
+ * This lock is used to gate all tree operations.
+ * If it is held, then no other process may
+ * traverse the tree. This allows us to not
+ * throw a hold on each vfs_t in the tree.
+ * Can be held for a "long" time.
+ *
+ * net->net_cnt_lock
+ * Used to protect refcnt and status.
+ * Must be held for a really short time.
+ *
+ * nfs4_ephemeral_thread_lock
+ * Is only held to create the harvester for the zone.
+ * There is no ordering imposed on it.
+ * Held for a really short time.
+ *
+ * Some further detail on the interactions:
+ *
+ * net_tree_lock controls access to net_root. Access needs to first be
+ * attempted in a non-blocking check.
+ *
+ * net_cnt_lock controls access to net_refcnt and net_status. It must only be
+ * held for very short periods of time, unless the refcnt is 0 and the status
+ * is INVALID.
+ *
+ * Before a caller can grab net_tree_lock, it must first grab net_cnt_lock
+ * to bump the net_refcnt. It then releases it and does the action specific
+ * algorithm to get the net_tree_lock. Once it has that, then it is okay to
+ * grab the net_cnt_lock and change the status. The status can only be
+ * changed if the caller has the net_tree_lock held as well.
+ *
+ * When a caller is done with net_tree_lock, it can decrement the net_refcnt
+ * either before it releases net_tree_lock or after.
+ *
+ * In either event, to decrement net_refcnt, it must hold net_cnt_lock.
+ *
+ * Note that the overall locking scheme for the nodes is to control access
+ * via the tree. The current scheme could easily be extended such that
+ * the enclosing root referenced a "forest" of trees. The underlying trees
+ * would be autonomous with respect to locks.
+ *
+ * Note that net_next is controlled by external locks
+ * particular to the data structure that the tree is being added to.
+ */
+typedef struct nfs4_ephemeral_tree {
+ mntinfo4_t *net_mount;
+ nfs4_ephemeral_t *net_root;
+ struct nfs4_ephemeral_tree *net_next;
+ kmutex_t net_tree_lock;
+ kmutex_t net_cnt_lock;
+ uint_t net_status;
+ uint_t net_refcnt;
+} nfs4_ephemeral_tree_t;
+
+/*
+ * State for the tree (set in net_status):
+ */
+#define NFS4_EPHEMERAL_TREE_OK 0x0
+#define NFS4_EPHEMERAL_TREE_BUILDING 0x1
+#define NFS4_EPHEMERAL_TREE_DEROOTING 0x2
+#define NFS4_EPHEMERAL_TREE_INVALID 0x4
+#define NFS4_EPHEMERAL_TREE_MOUNTING 0x8
+#define NFS4_EPHEMERAL_TREE_UMOUNTING 0x10
+#define NFS4_EPHEMERAL_TREE_LOCKED 0x20
+
+/*
* This macro evaluates to non-zero if the given op releases state at the
* server.
*/
@@ -1335,10 +1475,14 @@ extern void nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *,
nfs4_error_t *, int *);
extern void nfs4_error_zinit(nfs4_error_t *);
extern void nfs4_error_init(nfs4_error_t *, int);
+extern void nfs4_free_args(struct nfs_args *);
extern void mi_hold(mntinfo4_t *);
extern void mi_rele(mntinfo4_t *);
+extern sec_data_t *copy_sec_data(sec_data_t *);
+extern gss_clntdata_t *copy_sec_data_gss(gss_clntdata_t *);
+
#ifdef DEBUG
extern int nfs4_consistent_type(vnode_t *);
#endif
@@ -1814,6 +1958,25 @@ extern void nfs4_end_fop(struct mntinfo4 *, vnode_t *, vnode_t *,
nfs4_op_hint_t, nfs4_recov_state_t *, bool_t);
extern char *nfs4_recov_action_to_str(nfs4_recov_t);
+/*
+ * In sequence, code desiring to unmount an ephemeral tree must
+ * call nfs4_ephemeral_umount, nfs4_ephemeral_umount_activate,
+ * and nfs4_ephemeral_umount_unlock. The _unlock must also be
+ * called on all error paths that occur before it would naturally
+ * be invoked.
+ *
+ * The caller must also provde a pointer to a boolean to keep track
+ * of whether or not the code in _unlock is to be ran.
+ */
+extern void nfs4_ephemeral_umount_activate(mntinfo4_t *,
+ bool_t *, nfs4_ephemeral_tree_t **);
+extern int nfs4_ephemeral_umount(mntinfo4_t *, int, cred_t *,
+ bool_t *, nfs4_ephemeral_tree_t **);
+extern void nfs4_ephemeral_umount_unlock(bool_t *,
+ nfs4_ephemeral_tree_t **);
+
+extern void nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp);
+
extern int wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t,
nfs4_recov_state_t *);
extern void nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *);
diff --git a/usr/src/uts/common/nfs/nfssys.h b/usr/src/uts/common/nfs/nfssys.h
index 3e7893bfb2..f11f81e7ec 100644
--- a/usr/src/uts/common/nfs/nfssys.h
+++ b/usr/src/uts/common/nfs/nfssys.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,7 +51,7 @@ enum nfssys_op { OLD_NFS_SVC, OLD_ASYNC_DAEMON, EXPORTFS, OLD_NFS_GETFH,
LOG_FLUSH, SVCPOOL_CREATE, NFS_SVC, LM_SVC, SVCPOOL_WAIT, SVCPOOL_RUN,
NFS4_SVC, RDMA_SVC_INIT, NFS4_CLR_STATE, NFS_IDMAP,
NFS4_SVC_REQUEST_QUIESCE, NFS_GETFH, NFS4_DSS_SETPATHS,
- NFS4_DSS_SETPATHS_SIZE, MOUNTD_ARGS };
+ NFS4_DSS_SETPATHS_SIZE, NFS4_EPHEMERAL_MOUNT_TO, MOUNTD_ARGS };
struct nfs_svc_args {
int fd; /* Connection endpoint */
@@ -318,6 +318,7 @@ extern int nfs4_svc(struct nfs4_svc_args *, model_t);
extern int rdma_start(struct rdma_svc_args *);
extern void rfs4_clear_client_state(struct nfs4clrst_args *);
extern void nfs_idmap_args(struct nfsidmap_args *);
+extern void nfs4_ephemeral_set_mount_to(uint_t);
extern void mountd_args(uint_t);
#endif
diff --git a/usr/src/uts/common/nfs/rnode4.h b/usr/src/uts/common/nfs/rnode4.h
index d65e1011c0..a07c2b5be0 100644
--- a/usr/src/uts/common/nfs/rnode4.h
+++ b/usr/src/uts/common/nfs/rnode4.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,6 +41,11 @@ extern "C" {
#include <sys/thread.h>
#include <sys/sysmacros.h> /* for offsetof */
+typedef enum nfs4_stub_type {
+ NFS4_STUB_NONE,
+ NFS4_STUB_MIRRORMOUNT
+} nfs4_stub_type_t;
+
typedef enum nfs4_access_type {
NFS4_ACCESS_UNKNOWN,
NFS4_ACCESS_ALLOWED,
@@ -319,7 +323,9 @@ typedef struct rnode4 {
fattr4_fsid r_srv_fsid; /* fsid of srv fs containing object */
/* when rnode created; compare with */
/* sv_fsid (servinfo4_t) to see why */
- /* R4SRVSTUB was set */
+ /* stub type was set */
+ nfs4_stub_type_t r_stub_type;
+ /* e.g. mirror-mount */
} rnode4_t;
#define r_vnode r_svnode.sv_r_vnode
@@ -343,7 +349,6 @@ typedef struct rnode4 {
#define R4RECOVERR 0x2000 /* couldn't recover */
#define R4RECEXPFH 0x4000 /* recovering expired filehandle */
#define R4RECOVERRP 0x8000 /* R4RECOVERR pending, but not set (yet) */
-#define R4SRVSTUB 0x10000 /* server stub / fs mntpnt */
#define R4ISXATTR 0x20000 /* rnode is a named attribute */
#define R4DELMAPLIST 0x40000 /* delmap callers tracked for as callback */
#define R4PGFLUSH 0x80000 /* page flush thread active */
@@ -354,6 +359,9 @@ typedef struct rnode4 {
#define RTOV4(rp) ((rp)->r_vnode)
#define VTOR4(vp) ((rnode4_t *)((vp)->v_data))
+#define RP_ISSTUB(rp) (((rp)->r_stub_type != NFS4_STUB_NONE))
+#define RP_ISSTUB_MIRRORMOUNT(rp) ((rp)->r_stub_type == NFS4_STUB_MIRRORMOUNT)
+
/*
* Open file instances.
*/
@@ -474,6 +482,9 @@ extern void rddir4_cache_destroy(rnode4_t *);
extern rddir4_cache *rddir4_cache_lookup(rnode4_t *, offset_t, int);
extern void rddir4_cache_rele(rnode4_t *, rddir4_cache *);
+extern void r4_stub_mirrormount(rnode4_t *);
+extern void r4_stub_none(rnode4_t *);
+
#ifdef DEBUG
extern char *rddir4_cache_buf_alloc(size_t, int);
extern void rddir4_cache_buf_free(void *, size_t);
diff --git a/usr/src/uts/common/rpc/sec/sec_clnt.c b/usr/src/uts/common/rpc/sec/sec_clnt.c
index f5e90c7225..e73c723142 100644
--- a/usr/src/uts/common/rpc/sec/sec_clnt.c
+++ b/usr/src/uts/common/rpc/sec/sec_clnt.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -111,7 +110,7 @@ gss_clnt_loadinfo(caddr_t usrdata, caddr_t *kdata, model_t model)
} else {
data->mechanism.length = gd32.mechanism.length;
data->mechanism.elements =
- (caddr_t)(uintptr_t)gd32.mechanism.elements;
+ (caddr_t)(uintptr_t)gd32.mechanism.elements;
data->service = gd32.service;
bcopy(gd32.uname, data->uname, sizeof (gd32.uname));
bcopy(gd32.inst, data->inst, sizeof (gd32.inst));
@@ -441,6 +440,9 @@ sec_clnt_geth(CLIENT *client, struct sec_data *secdata, cred_t *cr, AUTH **ap)
authflavor = secdata->rpcflavor;
for (;;) {
+ int nlen;
+ char *netname;
+
switch (authflavor) {
case AUTH_NONE:
/*
@@ -482,12 +484,28 @@ sec_clnt_geth(CLIENT *client, struct sec_data *secdata, cred_t *cr, AUTH **ap)
*/
savecred = curthread->t_cred;
curthread->t_cred = cr;
+
+ /*
+ * Note that authdes_create() expects a
+ * NUL-terminated string for netname, but
+ * dh_k4_clntdata_t gives us netname & netnamelen.
+ *
+ * We must create a string for authdes_create();
+ * the latter takes a copy of it, so we may
+ * immediately free it.
+ */
desdata = (dh_k4_clntdata_t *)secdata->data;
- stat = authdes_create(desdata->netname, authdes_win,
- &desdata->syncaddr, desdata->knconf,
- (des_block *)NULL,
- (secdata->flags & AUTH_F_RPCTIMESYNC) ? 1 : 0,
- &auth);
+ nlen = desdata->netnamelen;
+ /* must be NUL-terminated */
+ netname = kmem_zalloc(nlen + 1, KM_SLEEP);
+ bcopy(desdata->netname, netname, nlen);
+ stat = authdes_create(netname, authdes_win,
+ &desdata->syncaddr, desdata->knconf,
+ (des_block *)NULL,
+ (secdata->flags & AUTH_F_RPCTIMESYNC) ? 1 : 0,
+ &auth);
+ kmem_free(netname, nlen + 1);
+
curthread->t_cred = savecred;
*ap = auth;
@@ -566,7 +584,7 @@ sec_clnt_geth(CLIENT *client, struct sec_data *secdata, cred_t *cr, AUTH **ap)
}
RPCLOG(1, "sec_clnt_geth: rpc_gss_secget"
- " failed with %d", stat);
+ " failed with %d", stat);
return (stat);
default:
@@ -596,14 +614,14 @@ sec_clnt_freeh(AUTH *auth)
case AUTH_DES:
mutex_enter(&desauthtab_lock);
if (desauthtab != NULL) {
- for (da = desauthtab;
- da < &desauthtab[clnt_authdes_cachesz]; da++) {
- if (da->da_auth == auth) {
- da->da_inuse = 0;
- mutex_exit(&desauthtab_lock);
- return;
+ for (da = desauthtab;
+ da < &desauthtab[clnt_authdes_cachesz]; da++) {
+ if (da->da_auth == auth) {
+ da->da_inuse = 0;
+ mutex_exit(&desauthtab_lock);
+ return;
+ }
}
- }
}
mutex_exit(&desauthtab_lock);
auth_destroy(auth); /* was overflow */
@@ -615,7 +633,7 @@ sec_clnt_freeh(AUTH *auth)
default:
cmn_err(CE_NOTE, "sec_clnt_freeh: unknown authflavor %d",
- auth->ah_cred.oa_flavor);
+ auth->ah_cred.oa_flavor);
break;
}
}
@@ -678,11 +696,12 @@ sec_clnt_revoke(int rpcflavor, uid_t uid, cred_t *cr, void *mechanism,
case AUTH_DES:
mutex_enter(&desauthtab_lock);
if (desauthtab != NULL) {
- for (da = desauthtab;
- da < &desauthtab[clnt_authdes_cachesz]; da++) {
- if (uid == da->da_uid && zoneid == da->da_zoneid)
- revoke_key(da->da_auth, 1);
- }
+ for (da = desauthtab;
+ da < &desauthtab[clnt_authdes_cachesz]; da++) {
+ if (uid == da->da_uid &&
+ zoneid == da->da_zoneid)
+ revoke_key(da->da_auth, 1);
+ }
}
mutex_exit(&desauthtab_lock);
return (0);
@@ -751,13 +770,13 @@ purge_authtab(struct sec_data *secdata)
case AUTH_DES:
mutex_enter(&desauthtab_lock);
if (desauthtab != NULL) {
- for (da = desauthtab;
- da < &desauthtab[clnt_authdes_cachesz]; da++) {
- if (da->da_data == secdata) {
- da->da_data = NULL;
- da->da_inuse = 0;
+ for (da = desauthtab;
+ da < &desauthtab[clnt_authdes_cachesz]; da++) {
+ if (da->da_data == secdata) {
+ da->da_data = NULL;
+ da->da_inuse = 0;
+ }
}
- }
}
mutex_exit(&desauthtab_lock);
return;
diff --git a/usr/src/uts/common/sys/fcntl.h b/usr/src/uts/common/sys/fcntl.h
index 22050a3d54..70df5244f6 100644
--- a/usr/src/uts/common/sys/fcntl.h
+++ b/usr/src/uts/common/sys/fcntl.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -349,6 +349,7 @@ typedef struct fshare {
#define AT_FDCWD 0xffd19553
#define AT_SYMLINK_NOFOLLOW 0x1000
#define AT_REMOVEDIR 0x1
+#define _AT_TRIGGER 0x2
#endif
#ifdef __cplusplus
diff --git a/usr/src/uts/common/sys/vnode.h b/usr/src/uts/common/sys/vnode.h
index 3d54125d84..56f4ac42d8 100644
--- a/usr/src/uts/common/sys/vnode.h
+++ b/usr/src/uts/common/sys/vnode.h
@@ -993,6 +993,7 @@ extern struct vnode zvp;
#define ATTR_COMM 0x04 /* yield common vp attributes */
#define ATTR_HINT 0x08 /* information returned will be `hint' */
#define ATTR_REAL 0x10 /* yield attributes of the real vp */
+#define ATTR_TRIGGER 0x40 /* Mount first if vnode is a trigger mount */
/*
* Generally useful macros.
diff --git a/usr/src/uts/common/syscall/stat.c b/usr/src/uts/common/syscall/stat.c
index ac249e183b..33403cf89e 100644
--- a/usr/src/uts/common/syscall/stat.c
+++ b/usr/src/uts/common/syscall/stat.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -196,7 +196,9 @@ fstat(int fd, struct stat *sb)
int
fstatat(int fd, char *name, struct stat *sb, int flags)
{
- return (cstatat(fd, name, 2, sb, flags, 0));
+ return (cstatat(fd, name, 2, sb,
+ flags & AT_SYMLINK_NOFOLLOW ? AT_SYMLINK_NOFOLLOW : 0,
+ flags & _AT_TRIGGER ? ATTR_TRIGGER : 0));
}
#if defined(__i386) || defined(__i386_COMPAT)
@@ -357,9 +359,11 @@ fstat32(int fd, struct stat32 *sb)
}
int
-fstatat32(int fd, char *name, struct stat32 *sb, int flag)
+fstatat32(int fd, char *name, struct stat32 *sb, int flags)
{
- return (cstatat32(fd, name, 2, sb, flag, 0));
+ return (cstatat32(fd, name, 2, sb,
+ flags & AT_SYMLINK_NOFOLLOW ? AT_SYMLINK_NOFOLLOW : 0,
+ flags & _AT_TRIGGER ? ATTR_TRIGGER : 0));
}
#if defined(__i386_COMPAT)
@@ -503,7 +507,9 @@ fstat64(int fd, struct stat64 *sb)
int
fstatat64(int fd, char *name, struct stat64 *sb, int flags)
{
- return (cstatat64(fd, name, 2, sb, flags, 0));
+ return (cstatat64(fd, name, 2, sb,
+ flags & AT_SYMLINK_NOFOLLOW ? AT_SYMLINK_NOFOLLOW : 0,
+ flags & _AT_TRIGGER ? ATTR_TRIGGER : 0));
}
static int
@@ -604,9 +610,11 @@ fstat64_32(int fd, struct stat64_32 *sb)
}
int
-fstatat64_32(int fd, char *name, struct stat64_32 *sb, int flag)
+fstatat64_32(int fd, char *name, struct stat64_32 *sb, int flags)
{
- return (cstatat64_32(fd, name, 2, sb, flag, 0));
+ return (cstatat64_32(fd, name, 2, sb,
+ flags & AT_SYMLINK_NOFOLLOW ? AT_SYMLINK_NOFOLLOW : 0,
+ flags & _AT_TRIGGER ? ATTR_TRIGGER : 0));
}
static int
diff --git a/usr/src/uts/common/syscall/umount.c b/usr/src/uts/common/syscall/umount.c
index f5fb881f5d..970afd9b2b 100644
--- a/usr/src/uts/common/syscall/umount.c
+++ b/usr/src/uts/common/syscall/umount.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,6 +50,72 @@
#include <sys/policy.h>
#include <sys/zone.h>
+#define UMOUNT2_SET_ERRNO(e, is_syscall) ((is_syscall) ? set_errno((e)) : (e))
+
+/*
+ * The heart of the umount2 call - it is pulled out to allow kernel
+ * level particpation when the only reference is the vfs pointer.
+ *
+ * Note that some of the callers may not be in the context of a
+ * syscall (created by zthread_create() for example) and as such
+ * may not have an associated curthread->t_lwp. This is handled
+ * by is_syscall.
+ */
+int
+umount2_engine(vfs_t *vfsp, int flag, cred_t *cr, int is_syscall)
+{
+ int error;
+
+ /*
+ * Protect the call to vn_vfswlock() with the vfs reflock. This
+ * ensures vfs_vnodecovered will either be NULL (because someone
+ * beat us to the umount) or valid (because vfs_lock() prevents
+ * another umount from getting through here until we've called
+ * vn_vfswlock() on the covered vnode).
+ *
+ * At one point, we did the non-blocking version (vfs_lock()),
+ * and if it failed, bailed out with EBUSY. However, dounmount()
+ * calls vfs_lock_wait() and we drop the vfs lock before calling
+ * dounmount(), so there's no difference between waiting here
+ * for the lock or waiting there because grabbed it as soon as
+ * we drop it below. No returning with EBUSY at this point
+ * reduces the number of spurious unmount failures that happen
+ * as a side-effect of fsflush() and other mount and unmount
+ * operations that might be going on simultaneously.
+ */
+ vfs_lock_wait(vfsp);
+
+ /*
+ * Call vn_vfswlock() on the covered vnode so that dounmount()
+ * can do its thing. It will call the corresponding vn_vfsunlock().
+ * Note that vfsp->vfs_vnodecovered can be NULL here, either because
+ * someone did umount on "/" or because someone beat us to the umount
+ * before we did the vfs_lock() above. In these cases, vn_vfswlock()
+ * returns EBUSY and we just pass that up. Also note that we're
+ * looking at a vnode without doing a VN_HOLD() on it. This is
+ * safe because it can't go away while something is mounted on it
+ * and we're locking out other umounts at this point.
+ */
+ if (vn_vfswlock(vfsp->vfs_vnodecovered)) {
+ vfs_unlock(vfsp);
+ VFS_RELE(vfsp);
+ return (UMOUNT2_SET_ERRNO(EBUSY, is_syscall));
+ }
+
+ /*
+ * Now that the VVFSLOCK in the covered vnode is protecting this
+ * path, we don't need the vfs reflock or the hold on the vfs anymore.
+ */
+ vfs_unlock(vfsp);
+ VFS_RELE(vfsp);
+
+ /*
+ * Perform the unmount.
+ */
+ if ((error = dounmount(vfsp, flag, cr)) != 0)
+ return (UMOUNT2_SET_ERRNO(error, is_syscall));
+ return (0);
+}
/*
* New umount() system call (for force unmount flag and perhaps others later).
@@ -126,55 +191,7 @@ umount2(char *pathp, int flag)
}
pn_free(&pn);
- /*
- * Protect the call to vn_vfswlock() with the vfs reflock. This
- * ensures vfs_vnodecovered will either be NULL (because someone
- * beat us to the umount) or valid (because vfs_lock() prevents
- * another umount from getting through here until we've called
- * vn_vfswlock() on the covered vnode).
- *
- * At one point, we did the non-blocking version (vfs_lock()),
- * and if it failed, bailed out with EBUSY. However, dounmount()
- * calls vfs_lock_wait() and we drop the vfs lock before calling
- * dounmount(), so there's no difference between waiting here
- * for the lock or waiting there because grabbed it as soon as
- * we drop it below. No returning with EBUSY at this point
- * reduces the number of spurious unmount failures that happen
- * as a side-effect of fsflush() and other mount and unmount
- * operations that might be going on simultaneously.
- */
- vfs_lock_wait(vfsp);
-
- /*
- * Call vn_vfswlock() on the covered vnode so that dounmount()
- * can do its thing. It will call the corresponding vn_vfsunlock().
- * Note that vfsp->vfs_vnodecovered can be NULL here, either because
- * someone did umount on "/" or because someone beat us to the umount
- * before we did the vfs_lock() above. In these cases, vn_vfswlock()
- * returns EBUSY and we just pass that up. Also note that we're
- * looking at a vnode without doing a VN_HOLD() on it. This is
- * safe because it can't go away while something is mounted on it
- * and we're locking out other umounts at this point.
- */
- if (vn_vfswlock(vfsp->vfs_vnodecovered)) {
- vfs_unlock(vfsp);
- VFS_RELE(vfsp);
- return (set_errno(EBUSY));
- }
-
- /*
- * Now that the VVFSLOCK in the covered vnode is protecting this
- * path, we don't need the vfs reflock or the hold on the vfs anymore.
- */
- vfs_unlock(vfsp);
- VFS_RELE(vfsp);
-
- /*
- * Perform the unmount.
- */
- if ((error = dounmount(vfsp, flag, CRED())) != 0)
- return (set_errno(error));
- return (0);
+ return (umount2_engine(vfsp, flag, CRED(), 1));
}
/*
diff --git a/usr/src/uts/intel/nfs/Makefile b/usr/src/uts/intel/nfs/Makefile
index d6d3212d22..0e159d2ba6 100644
--- a/usr/src/uts/intel/nfs/Makefile
+++ b/usr/src/uts/intel/nfs/Makefile
@@ -21,7 +21,7 @@
#
# uts/intel/nfs/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -65,6 +65,8 @@ MODSTUBS_DIR = $(OBJS_DIR)
$(MODSTUBS_O) := AS_CPPFLAGS += -DNFS_MODULE
CLEANFILES += $(MODSTUBS_O)
+INC_PATH += -I$(SRC)/common
+
#
# For now, disable these lint checks; maintainers should endeavor
# to investigate and remove these for maximum lint coverage.
diff --git a/usr/src/uts/sparc/nfs/Makefile b/usr/src/uts/sparc/nfs/Makefile
index 73fe1e7acd..49af3286df 100644
--- a/usr/src/uts/sparc/nfs/Makefile
+++ b/usr/src/uts/sparc/nfs/Makefile
@@ -20,7 +20,8 @@
#
#
# uts/sparc/nfs/Makefile
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -65,6 +66,8 @@ $(MODSTUBS_O) := AS_CPPFLAGS += -DNFS_MODULE
CLEANFILES += $(MODSTUBS_O)
CFLAGS += $(CCVERBOSE)
+INC_PATH += -I$(SRC)/common
+
#
# For now, disable these lint checks; maintainers should endeavor
# to investigate and remove these for maximum lint coverage.