diff options
author | Gordon Ross <gwr@nexenta.com> | 2012-12-16 22:14:45 -0500 |
---|---|---|
committer | Gordon Ross <gwr@nexenta.com> | 2013-02-01 22:18:00 -0500 |
commit | fabf08ae7a95a47c3e249ee651d83d26f798bcfa (patch) | |
tree | 46835235b4664bc5b4e24cd23894af1650ebe6f5 /usr/src | |
parent | 1b912ec7100c10e7243bf0879af0fe580e08c73d (diff) | |
download | illumos-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.c | 33 |
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) { |