From fabf08ae7a95a47c3e249ee651d83d26f798bcfa Mon Sep 17 00:00:00 2001 From: Gordon Ross Date: Sun, 16 Dec 2012 22:14:45 -0500 Subject: [PATCH] 3514 Spurious errors setting up new SMB client sessions Reviewed by: Bayard Bell Reviewed by: Dan McDonald Approved by: Richard Lowe --- usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c | 33 ++++++++++++++++++++++---------- 1 file 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) { -- 2.11.4.GIT