changeset 13942:0803117c24d3

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>
author Gordon Ross <gwr@nexenta.com>
date Sun, 16 Dec 2012 22:14:45 -0500
parents d48547176ab4
children e1ea18b9c0de
files usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c
diffstat 1 files changed, 24 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c	Fri Feb 01 14:11:09 2013 -0800
+++ b/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c	Sun Dec 16 22:14:45 2012 -0500
@@ -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,6 +282,29 @@
 	bcopy(clnt_ssn, &ctx->ct_iod_ssn, sizeof (ctx->ct_iod_ssn));
 
 	/*
+	 * 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.
 	 */
@@ -288,17 +312,6 @@
 	if (err != 0)
 		goto out;
 
-	/*
-	 * Create the driver session now, so we don't
-	 * race with the door client findvc call.
-	 */
-	if ((err = smb_ctx_gethandle(ctx)) != 0)
-		goto out;
-	if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) {
-		err = errno;
-		goto out;
-	}
-
 	/* The rest happens in the iod_work thread. */
 	err = thr_create(NULL, 0, iod_work, ctx, THR_DETACHED, &tid);
 	if (err == 0) {