summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorGordon Ross <gwr@nexenta.com>2012-12-16 22:14:45 -0500
committerGordon Ross <gwr@nexenta.com>2013-02-01 22:18:00 -0500
commitfabf08ae7a95a47c3e249ee651d83d26f798bcfa (patch)
tree46835235b4664bc5b4e24cd23894af1650ebe6f5 /usr/src
parent1b912ec7100c10e7243bf0879af0fe580e08c73d (diff)
downloadillumos-joyent-fabf08ae7a95a47c3e249ee651d83d26f798bcfa.tar.gz
3514 Spurious errors setting up new SMB client sessions
Reviewed by: Bayard Bell <bayard.bell@nexenta.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c b/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c
index 5296cb2be9..32fda8d5fb 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -281,24 +282,36 @@ iod_newvc(smb_iod_ssn_t *clnt_ssn)
bcopy(clnt_ssn, &ctx->ct_iod_ssn, sizeof (ctx->ct_iod_ssn));
/*
- * Do the initial connection setup here, so we can
- * report the outcome to the door client.
- */
- err = smb_iod_connect(ctx);
- if (err != 0)
- goto out;
-
- /*
- * Create the driver session now, so we don't
- * race with the door client findvc call.
+ * Create the driver session first, so that any subsequent
+ * requests for the same session will find this one and
+ * wait, the same as when a reconnect is triggered.
+ *
+ * There is still an inherent race here, where two callers
+ * both find no VC in the driver, and both come here trying
+ * to create the VC. In this case, we want the first one
+ * to actually do the VC setup, and the second to proceed
+ * as if the VC had been found in the driver. The second
+ * caller gets an EEXIST error from the ioctl in this case,
+ * which we therefore ignore here so that the caller will
+ * go ahead and look again in the driver for the new VC.
*/
if ((err = smb_ctx_gethandle(ctx)) != 0)
goto out;
if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) {
err = errno;
+ if (err == EEXIST)
+ err = 0; /* see above */
goto out;
}
+ /*
+ * Do the initial connection setup here, so we can
+ * report the outcome to the door client.
+ */
+ err = smb_iod_connect(ctx);
+ if (err != 0)
+ goto out;
+
/* The rest happens in the iod_work thread. */
err = thr_create(NULL, 0, iod_work, ctx, THR_DETACHED, &tid);
if (err == 0) {