Print this page
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)
NEX-16824 SMB client connection setup rework
NEX-17232 SMB client reconnect failures
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (improve debug)
NEX-16818 Add fksmbcl development tool
NEX-17264 SMB client test tp_smbutil_013 fails after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (fix ref leaks)
re #11128 nsmb_close locking and teardown deadlock
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c
+++ new/usr/src/uts/common/fs/smbclnt/netsmb/smb_dev.c
1 1 /*
2 2 * Copyright (c) 2000-2001 Boris Popov
3 3 * All rights reserved.
4 4 *
5 5 * Redistribution and use in source and binary forms, with or without
6 6 * modification, are permitted provided that the following conditions
7 7 * are met:
8 8 * 1. Redistributions of source code must retain the above copyright
9 9 * notice, this list of conditions and the following disclaimer.
10 10 * 2. Redistributions in binary form must reproduce the above copyright
11 11 * notice, this list of conditions and the following disclaimer in the
12 12 * documentation and/or other materials provided with the distribution.
13 13 * 3. All advertising materials mentioning features or use of this software
14 14 * must display the following acknowledgement:
15 15 * This product includes software developed by Boris Popov.
16 16 * 4. Neither the name of the author nor the names of any co-contributors
17 17 * may be used to endorse or promote products derived from this software
18 18 * without specific prior written permission.
19 19 *
20 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
24 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 30 * SUCH DAMAGE.
31 31 */
32 32
33 33 /*
34 - * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
35 34 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
36 35 * Use is subject to license terms.
36 + *
37 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
37 38 */
38 39
39 40 #include <sys/types.h>
40 41 #include <sys/param.h>
41 42 #include <sys/errno.h>
42 43 #include <sys/sysmacros.h>
43 44 #include <sys/uio.h>
44 45 #include <sys/buf.h>
45 46 #include <sys/modctl.h>
46 47 #include <sys/open.h>
47 48 #include <sys/file.h>
48 49 #include <sys/kmem.h>
49 50 #include <sys/conf.h>
50 51 #include <sys/cmn_err.h>
51 52 #include <sys/stat.h>
52 53 #include <sys/ddi.h>
53 54 #include <sys/sunddi.h>
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
54 55 #include <sys/sunldi.h>
55 56 #include <sys/policy.h>
56 57 #include <sys/zone.h>
57 58 #include <sys/pathname.h>
58 59 #include <sys/mount.h>
59 60 #include <sys/sdt.h>
60 61 #include <fs/fs_subr.h>
61 62 #include <sys/modctl.h>
62 63 #include <sys/devops.h>
63 64 #include <sys/thread.h>
64 -#include <sys/types.h>
65 +#include <sys/socket.h>
65 66 #include <sys/zone.h>
66 67
67 68 #include <netsmb/smb_osdep.h>
68 69 #include <netsmb/mchain.h> /* for "htoles()" */
69 70
70 71 #include <netsmb/smb.h>
72 +#include <netsmb/smb2.h>
71 73 #include <netsmb/smb_conn.h>
72 74 #include <netsmb/smb_subr.h>
73 75 #include <netsmb/smb_dev.h>
74 76 #include <netsmb/smb_pass.h>
75 77
78 +#ifndef _KERNEL
79 +#include <libfknsmb.h>
80 +
81 +#define _init(v) nsmb_drv_init(v)
82 +#define _fini(v) nsmb_drv_fini(v)
83 +
84 +#endif /* _KERNEL */
85 +
76 86 #define NSMB_MIN_MINOR 1
77 87 #define NSMB_MAX_MINOR L_MAXMIN32
78 88
79 89 /* for version checks */
80 90 const uint32_t nsmb_version = NSMB_VERSION;
81 91
92 +/* for smb_nbst_create() */
93 +dev_t nsmb_dev_tcp = NODEV;
94 +dev_t nsmb_dev_tcp6 = NODEV;
95 +
82 96 static void *statep;
83 97 static major_t nsmb_major;
84 98 static minor_t last_minor = NSMB_MIN_MINOR;
85 -static dev_info_t *nsmb_dip;
86 99 static kmutex_t dev_lck;
87 100
88 -/* Zone support */
89 -zone_key_t nsmb_zone_key;
90 -extern void nsmb_zone_shutdown(zoneid_t zoneid, void *data);
91 -extern void nsmb_zone_destroy(zoneid_t zoneid, void *data);
92 -
93 101 /*
94 102 * cb_ops device operations.
95 103 */
96 104 static int nsmb_open(dev_t *devp, int flag, int otyp, cred_t *credp);
97 105 static int nsmb_close(dev_t dev, int flag, int otyp, cred_t *credp);
98 106 static int nsmb_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
99 107 cred_t *credp, int *rvalp);
100 108 static int nsmb_close2(smb_dev_t *sdp, cred_t *cr);
101 109
110 +#ifdef _KERNEL
111 +
112 +static dev_info_t *nsmb_dip;
113 +
114 +/* Zone support */
115 +zone_key_t nsmb_zone_key;
116 +extern void nsmb_zone_shutdown(zoneid_t zoneid, void *data);
117 +extern void nsmb_zone_destroy(zoneid_t zoneid, void *data);
118 +
102 119 /* smbfs cb_ops */
103 120 static struct cb_ops nsmb_cbops = {
104 121 nsmb_open, /* open */
105 122 nsmb_close, /* close */
106 123 nodev, /* strategy */
107 124 nodev, /* print */
108 125 nodev, /* dump */
109 126 nodev, /* read */
110 127 nodev, /* write */
111 128 nsmb_ioctl, /* ioctl */
112 129 nodev, /* devmap */
113 130 nodev, /* mmap */
114 131 nodev, /* segmap */
115 132 nochpoll, /* poll */
116 133 ddi_prop_op, /* prop_op */
117 134 NULL, /* stream */
118 135 D_MP, /* cb_flag */
119 136 CB_REV, /* rev */
120 137 nodev, /* int (*cb_aread)() */
121 138 nodev /* int (*cb_awrite)() */
122 139 };
123 140
124 141 /*
125 142 * Device options
126 143 */
127 144 static int nsmb_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
128 145 static int nsmb_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
129 146 static int nsmb_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd,
130 147 void *arg, void **result);
131 148
132 149 static struct dev_ops nsmb_ops = {
133 150 DEVO_REV, /* devo_rev, */
134 151 0, /* refcnt */
135 152 nsmb_getinfo, /* info */
136 153 nulldev, /* identify */
137 154 nulldev, /* probe */
138 155 nsmb_attach, /* attach */
139 156 nsmb_detach, /* detach */
140 157 nodev, /* reset */
141 158 &nsmb_cbops, /* driver ops - devctl interfaces */
142 159 NULL, /* bus operations */
143 160 NULL, /* power */
144 161 ddi_quiesce_not_needed, /* quiesce */
145 162 };
146 163
147 164 /*
148 165 * Module linkage information.
149 166 */
150 167
151 168 static struct modldrv nsmb_modldrv = {
152 169 &mod_driverops, /* Driver module */
|
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
153 170 "SMBFS network driver",
154 171 &nsmb_ops /* Driver ops */
155 172 };
156 173
157 174 static struct modlinkage nsmb_modlinkage = {
158 175 MODREV_1,
159 176 (void *)&nsmb_modldrv,
160 177 NULL
161 178 };
162 179
180 +#endif /* _KERNEL */
181 +
163 182 int
164 183 _init(void)
165 184 {
185 +#ifdef _KERNEL
166 186 int error;
187 +#endif /* _KERNEL */
167 188
168 189 (void) ddi_soft_state_init(&statep, sizeof (smb_dev_t), 1);
169 190
170 191 /* Can initialize some mutexes also. */
171 192 mutex_init(&dev_lck, NULL, MUTEX_DRIVER, NULL);
172 193
173 194 /* Connection data structures. */
174 195 (void) smb_sm_init();
175 196
176 197 /* Initialize password Key chain DB. */
177 198 smb_pkey_init();
178 199
179 - /* Time conversion stuff. */
180 - smb_time_init();
181 -
182 - /* Initialize crypto mechanisms. */
183 - smb_crypto_mech_init();
184 -
200 +#ifdef _KERNEL
185 201 zone_key_create(&nsmb_zone_key, NULL, nsmb_zone_shutdown,
186 202 nsmb_zone_destroy);
187 203
188 204 /*
189 205 * Install the module. Do this after other init,
190 206 * to prevent entrances before we're ready.
191 207 */
192 208 if ((error = mod_install((&nsmb_modlinkage))) != 0) {
193 209
194 210 /* Same as 2nd half of _fini */
195 211 (void) zone_key_delete(nsmb_zone_key);
196 212 smb_pkey_fini();
197 213 smb_sm_done();
198 214 mutex_destroy(&dev_lck);
199 215 ddi_soft_state_fini(&statep);
200 216
201 217 return (error);
202 218 }
219 +#else /* _KERNEL */
220 + streams_msg_init();
221 + /* No attach, so need to set major. */
222 + nsmb_major = 1;
223 + /* And these, for smb_nbst_create() */
224 + nsmb_dev_tcp = AF_INET;
225 + nsmb_dev_tcp6 = AF_INET6;
226 +#endif /* _KERNEL */
203 227
204 228 return (0);
205 229 }
206 230
207 231 int
208 232 _fini(void)
209 233 {
210 234 int status;
211 235
212 236 /*
213 237 * Prevent unload if we have active VCs
214 238 * or stored passwords
215 239 */
216 240 if ((status = smb_sm_idle()) != 0)
217 241 return (status);
218 242 if ((status = smb_pkey_idle()) != 0)
219 243 return (status);
220 244
245 +#ifdef _KERNEL
221 246 /*
222 247 * Remove the module. Do this before destroying things,
223 248 * to prevent new entrances while we're destorying.
224 249 */
225 250 if ((status = mod_remove(&nsmb_modlinkage)) != 0) {
226 251 return (status);
227 252 }
228 253
229 254 (void) zone_key_delete(nsmb_zone_key);
255 +#endif /* _KERNEL */
230 256
231 - /* Time conversion stuff. */
232 - smb_time_fini();
233 -
234 257 /* Destroy password Key chain DB. */
235 258 smb_pkey_fini();
236 259
237 260 smb_sm_done();
238 261
239 262 mutex_destroy(&dev_lck);
240 263 ddi_soft_state_fini(&statep);
241 264
242 265 return (status);
243 266 }
244 267
268 +#ifdef _KERNEL
269 +
245 270 int
246 271 _info(struct modinfo *modinfop)
247 272 {
248 273 return (mod_info(&nsmb_modlinkage, modinfop));
249 274 }
250 275
251 276 /*ARGSUSED*/
252 277 static int
253 278 nsmb_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
254 279 {
255 280 int ret = DDI_SUCCESS;
256 281
257 282 switch (cmd) {
258 283 case DDI_INFO_DEVT2DEVINFO:
259 284 *result = nsmb_dip;
260 285 break;
261 286 case DDI_INFO_DEVT2INSTANCE:
262 287 *result = NULL;
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
263 288 break;
264 289 default:
265 290 ret = DDI_FAILURE;
266 291 }
267 292 return (ret);
268 293 }
269 294
270 295 static int
271 296 nsmb_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
272 297 {
298 + major_t tmaj;
273 299
274 300 if (cmd != DDI_ATTACH)
275 301 return (DDI_FAILURE);
276 302
277 303 /*
278 304 * We only support only one "instance". Note that
279 305 * "instances" are different from minor units.
280 306 * We get one (unique) minor unit per open.
281 307 */
282 308 if (ddi_get_instance(dip) > 0)
283 309 return (DDI_FAILURE);
284 310
285 311 if (ddi_create_minor_node(dip, "nsmb", S_IFCHR, 0, DDI_PSEUDO,
286 312 NULL) == DDI_FAILURE) {
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
287 313 cmn_err(CE_WARN, "nsmb_attach: create minor");
288 314 return (DDI_FAILURE);
289 315 }
290 316
291 317 /*
292 318 * We need the major number a couple places,
293 319 * i.e. in smb_dev2share()
294 320 */
295 321 nsmb_major = ddi_name_to_major(NSMB_NAME);
296 322
323 + /*
324 + * We also need major numbers for t_kopen
325 + */
326 + tmaj = ddi_name_to_major("tcp");
327 + if (tmaj == DDI_MAJOR_T_NONE)
328 + cmn_err(CE_NOTE, "no tcp major?");
329 + else
330 + nsmb_dev_tcp = makedevice(tmaj, 0);
331 + tmaj = ddi_name_to_major("tcp6");
332 + if (tmaj == DDI_MAJOR_T_NONE)
333 + cmn_err(CE_NOTE, "no tcp6 major?");
334 + else
335 + nsmb_dev_tcp6 = makedevice(tmaj, 0);
336 +
297 337 nsmb_dip = dip;
298 338 ddi_report_dev(dip);
299 339 return (DDI_SUCCESS);
300 340 }
301 341
302 342 /*ARGSUSED*/
303 343 static int
304 344 nsmb_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
305 345 {
306 346
307 347 if (cmd != DDI_DETACH)
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
308 348 return (DDI_FAILURE);
309 349 if (ddi_get_instance(dip) > 0)
310 350 return (DDI_FAILURE);
311 351
312 352 nsmb_dip = NULL;
313 353 ddi_remove_minor_node(dip, NULL);
314 354
315 355 return (DDI_SUCCESS);
316 356 }
317 357
358 +#else /* _KERNEL */
359 +
360 +/*
361 + * Wrappers for libfknsmb: ioctl, open, close, load
362 + */
363 +
318 364 /*ARGSUSED*/
365 +int
366 +nsmb_drv_ioctl(dev32_t dev32, int cmd, intptr_t arg, int flags)
367 +{
368 + dev_t dev = expldev(dev32);
369 + cred_t *cr = CRED();
370 + int err;
371 +
372 + err = nsmb_ioctl(dev, cmd, arg, flags, cr, NULL);
373 + return (err);
374 +}
375 +
376 +/*ARGSUSED*/
377 +int
378 +nsmb_drv_open(dev32_t *dev32p, int flags, int otyp)
379 +{
380 + dev_t dev = expldev(*dev32p);
381 + int err;
382 +
383 + err = nsmb_open(&dev, flags, otyp, CRED());
384 + if (err == 0) {
385 + /*
386 + * We have NSMB_MAX_MINOR == L_MAXMIN32
387 + * therefore cmpldev never fails.
388 + */
389 + VERIFY(cmpldev(dev32p, dev) != 0);
390 + }
391 + return (err);
392 +}
393 +
394 +/*ARGSUSED*/
395 +int
396 +nsmb_drv_close(dev32_t dev32, int flags, int otyp)
397 +{
398 + dev_t dev = expldev(dev32);
399 + int err;
400 +
401 + err = nsmb_close(dev, flags, otyp, CRED());
402 + return (err);
403 +}
404 +
405 +/*
406 + * This function intentionally does nothing. It's used only to
407 + * force libfknsmb to load at program start so one can set
408 + * breakpoints etc. without debugger "force load" tricks.
409 + */
410 +void
411 +nsmb_drv_load(void)
412 +{
413 +}
414 +
415 +#endif /* _KERNEL */
416 +
417 +/*ARGSUSED*/
319 418 static int
320 419 nsmb_ioctl(dev_t dev, int cmd, intptr_t arg, int flags, /* model.h */
321 420 cred_t *cr, int *rvalp)
322 421 {
323 422 smb_dev_t *sdp;
324 423 int err;
325 424
326 425 sdp = ddi_get_soft_state(statep, getminor(dev));
327 426 if (sdp == NULL) {
328 - return (DDI_FAILURE);
427 + return (EBADF);
329 428 }
330 429 if ((sdp->sd_flags & NSMBFL_OPEN) == 0) {
331 430 return (EBADF);
332 431 }
333 432
334 433 /*
335 434 * Dont give access if the zone id is not as the same as we
336 435 * set in the nsmb_open or dont belong to the global zone.
337 436 * Check if the user belongs to this zone..
338 437 */
339 438 if (sdp->zoneid != getzoneid())
340 439 return (EIO);
341 440
342 441 /*
343 442 * We have a zone_shutdown call back that kills all the VCs
344 443 * in a zone that's shutting down. That action will cause
345 444 * all of these ioctls to fail on such VCs, so no need to
346 445 * check the zone status here on every ioctl call.
347 446 */
348 447
349 - /*
350 - * Serialize ioctl calls. The smb_usr_... functions
351 - * don't expect concurrent calls on a given sdp.
352 - */
353 - mutex_enter(&sdp->sd_lock);
354 - if ((sdp->sd_flags & NSMBFL_IOCTL) != 0) {
355 - mutex_exit(&sdp->sd_lock);
356 - return (EBUSY);
357 - }
358 - sdp->sd_flags |= NSMBFL_IOCTL;
359 - mutex_exit(&sdp->sd_lock);
448 + err = smb_usr_ioctl(sdp, cmd, arg, flags, cr);
360 449
361 - err = 0;
362 - switch (cmd) {
363 - case SMBIOC_GETVERS:
364 - (void) ddi_copyout(&nsmb_version, (void *)arg,
365 - sizeof (nsmb_version), flags);
366 - break;
367 -
368 - case SMBIOC_FLAGS2:
369 - err = smb_usr_get_flags2(sdp, arg, flags);
370 - break;
371 -
372 - case SMBIOC_GETSSNKEY:
373 - err = smb_usr_get_ssnkey(sdp, arg, flags);
374 - break;
375 -
376 - case SMBIOC_DUP_DEV:
377 - err = smb_usr_dup_dev(sdp, arg, flags);
378 - break;
379 -
380 - case SMBIOC_REQUEST:
381 - err = smb_usr_simplerq(sdp, arg, flags, cr);
382 - break;
383 -
384 - case SMBIOC_T2RQ:
385 - err = smb_usr_t2request(sdp, arg, flags, cr);
386 - break;
387 -
388 - case SMBIOC_READ:
389 - case SMBIOC_WRITE:
390 - err = smb_usr_rw(sdp, cmd, arg, flags, cr);
391 - break;
392 -
393 - case SMBIOC_NTCREATE:
394 - err = smb_usr_ntcreate(sdp, arg, flags, cr);
395 - break;
396 -
397 - case SMBIOC_PRINTJOB:
398 - err = smb_usr_printjob(sdp, arg, flags, cr);
399 - break;
400 -
401 - case SMBIOC_CLOSEFH:
402 - err = smb_usr_closefh(sdp, cr);
403 - break;
404 -
405 - case SMBIOC_SSN_CREATE:
406 - case SMBIOC_SSN_FIND:
407 - err = smb_usr_get_ssn(sdp, cmd, arg, flags, cr);
408 - break;
409 -
410 - case SMBIOC_SSN_KILL:
411 - case SMBIOC_SSN_RELE:
412 - err = smb_usr_drop_ssn(sdp, cmd);
413 - break;
414 -
415 - case SMBIOC_TREE_CONNECT:
416 - case SMBIOC_TREE_FIND:
417 - err = smb_usr_get_tree(sdp, cmd, arg, flags, cr);
418 - break;
419 -
420 - case SMBIOC_TREE_KILL:
421 - case SMBIOC_TREE_RELE:
422 - err = smb_usr_drop_tree(sdp, cmd);
423 - break;
424 -
425 - case SMBIOC_IOD_WORK:
426 - err = smb_usr_iod_work(sdp, arg, flags, cr);
427 - break;
428 -
429 - case SMBIOC_IOD_IDLE:
430 - case SMBIOC_IOD_RCFAIL:
431 - err = smb_usr_iod_ioctl(sdp, cmd, arg, flags);
432 - break;
433 -
434 - case SMBIOC_PK_ADD:
435 - case SMBIOC_PK_DEL:
436 - case SMBIOC_PK_CHK:
437 - case SMBIOC_PK_DEL_OWNER:
438 - case SMBIOC_PK_DEL_EVERYONE:
439 - err = smb_pkey_ioctl(cmd, arg, flags, cr);
440 - break;
441 -
442 - default:
443 - err = ENOTTY;
444 - break;
445 - }
446 -
447 - mutex_enter(&sdp->sd_lock);
448 - sdp->sd_flags &= ~NSMBFL_IOCTL;
449 - mutex_exit(&sdp->sd_lock);
450 -
451 450 return (err);
452 451 }
453 452
454 453 /*
455 454 * This does "clone" open, meaning it automatically
456 455 * assigns an available minor unit for each open.
457 456 */
458 457 /*ARGSUSED*/
459 458 static int
460 459 nsmb_open(dev_t *dev, int flags, int otyp, cred_t *cr)
461 460 {
462 461 smb_dev_t *sdp;
463 462 minor_t m;
464 463
465 464 mutex_enter(&dev_lck);
466 465
467 466 for (m = last_minor + 1; m != last_minor; m++) {
468 467 if (m > NSMB_MAX_MINOR)
469 468 m = NSMB_MIN_MINOR;
470 469
471 470 if (ddi_get_soft_state(statep, m) == NULL) {
472 471 last_minor = m;
473 472 goto found;
474 473 }
475 474 }
476 475
477 476 /* No available minor units. */
478 477 mutex_exit(&dev_lck);
479 478 return (ENXIO);
480 479
481 480 found:
482 481 /* NB: dev_lck still held */
483 482 if (ddi_soft_state_zalloc(statep, m) == DDI_FAILURE) {
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
484 483 mutex_exit(&dev_lck);
485 484 return (ENXIO);
486 485 }
487 486 if ((sdp = ddi_get_soft_state(statep, m)) == NULL) {
488 487 mutex_exit(&dev_lck);
489 488 return (ENXIO);
490 489 }
491 490 *dev = makedevice(nsmb_major, m);
492 491 mutex_exit(&dev_lck);
493 492
494 - sdp->sd_smbfid = -1;
495 493 sdp->sd_flags |= NSMBFL_OPEN;
496 494 sdp->zoneid = crgetzoneid(cr);
497 495 mutex_init(&sdp->sd_lock, NULL, MUTEX_DRIVER, NULL);
498 496
499 497 return (0);
500 498 }
501 499
502 500 /*ARGSUSED*/
503 501 static int
504 502 nsmb_close(dev_t dev, int flags, int otyp, cred_t *cr)
505 503 {
506 504 minor_t inst = getminor(dev);
507 505 smb_dev_t *sdp;
508 506 int err;
509 507
510 508 /*
511 509 * 1. Check the validity of the minor number.
512 510 * 2. Release any shares/vc associated with the connection.
513 511 * 3. Can close the minor number.
514 512 * 4. Deallocate any resources allocated in open() call.
515 513 */
516 514
517 515 sdp = ddi_get_soft_state(statep, inst);
518 516 if (sdp != NULL)
519 517 err = nsmb_close2(sdp, cr);
520 518 else
521 519 err = ENXIO;
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
522 520
523 521 /*
524 522 * Free the instance
525 523 */
526 524 mutex_enter(&dev_lck);
527 525 ddi_soft_state_free(statep, inst);
528 526 mutex_exit(&dev_lck);
529 527 return (err);
530 528 }
531 529
530 +/*ARGSUSED*/
532 531 static int
533 532 nsmb_close2(smb_dev_t *sdp, cred_t *cr)
534 533 {
535 534 struct smb_vc *vcp;
536 535 struct smb_share *ssp;
536 + struct smb_fh *fhp;
537 537
538 - if (sdp->sd_smbfid != -1)
539 - (void) smb_usr_closefh(sdp, cr);
538 + fhp = sdp->sd_fh;
539 + if (fhp != NULL)
540 + smb_fh_rele(fhp);
540 541
541 542 ssp = sdp->sd_share;
542 543 if (ssp != NULL)
543 544 smb_share_rele(ssp);
544 545
545 546 vcp = sdp->sd_vc;
546 547 if (vcp != NULL) {
547 548 /*
548 549 * If this dev minor was opened by smbiod,
549 550 * mark this VC as "dead" because it now
550 551 * will have no IOD to service it.
551 552 */
552 553 if (sdp->sd_flags & NSMBFL_IOD)
553 554 smb_iod_disconnect(vcp);
554 555 smb_vc_rele(vcp);
555 556 }
556 557 mutex_destroy(&sdp->sd_lock);
557 558
558 559 return (0);
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
559 560 }
560 561
561 562 /*
562 563 * Helper for SMBIOC_DUP_DEV
563 564 * Duplicate state from the FD @arg ("from") onto
564 565 * the FD for this device instance.
565 566 */
566 567 int
567 568 smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags)
568 569 {
570 +#ifdef _KERNEL
569 571 file_t *fp = NULL;
570 572 vnode_t *vp;
573 +#endif /* _KERNEL */
571 574 smb_dev_t *from_sdp;
572 575 dev_t dev;
573 576 int32_t ufd;
574 577 int err;
575 578
576 579 /* Should be no VC */
577 580 if (sdp->sd_vc != NULL)
578 581 return (EISCONN);
579 582
580 583 /*
581 584 * Get from_sdp (what we will duplicate)
582 585 */
583 586 if (ddi_copyin((void *) arg, &ufd, sizeof (ufd), flags))
584 587 return (EFAULT);
588 +#ifdef _KERNEL
585 589 if ((fp = getf(ufd)) == NULL)
586 590 return (EBADF);
587 591 /* rele fp below */
588 592 vp = fp->f_vnode;
589 593 dev = vp->v_rdev;
594 +#else /* _KERNEL */
595 + /*
596 + * No getf(ufd) -- ufd is really a dev32_t
597 + */
598 + dev = expldev((dev32_t)ufd);
599 +#endif /* _KERNEL */
590 600 if (dev == 0 || dev == NODEV ||
591 601 getmajor(dev) != nsmb_major) {
592 602 err = EINVAL;
593 603 goto out;
594 604 }
605 +
595 606 from_sdp = ddi_get_soft_state(statep, getminor(dev));
596 607 if (from_sdp == NULL) {
597 608 err = EINVAL;
598 609 goto out;
599 610 }
600 611
601 612 /*
602 613 * Duplicate VC and share references onto this FD.
603 614 */
604 615 if ((sdp->sd_vc = from_sdp->sd_vc) != NULL)
605 616 smb_vc_hold(sdp->sd_vc);
606 617 if ((sdp->sd_share = from_sdp->sd_share) != NULL)
607 618 smb_share_hold(sdp->sd_share);
608 619 sdp->sd_level = from_sdp->sd_level;
609 620 err = 0;
610 621
611 622 out:
623 +#ifdef _KERNEL
612 624 if (fp)
613 625 releasef(ufd);
626 +#endif /* _KERNEL */
614 627 return (err);
615 628 }
616 629
617 630
618 631 /*
619 632 * Helper used by smbfs_mount
620 633 */
621 634 int
622 635 smb_dev2share(int fd, struct smb_share **sspp)
623 636 {
637 +#ifdef _KERNEL
624 638 file_t *fp = NULL;
625 639 vnode_t *vp;
640 +#endif /* _KERNEL */
626 641 smb_dev_t *sdp;
627 642 smb_share_t *ssp;
628 643 dev_t dev;
629 644 int err;
630 645
646 +#ifdef _KERNEL
631 647 if ((fp = getf(fd)) == NULL)
632 648 return (EBADF);
633 649 /* rele fp below */
634 -
635 650 vp = fp->f_vnode;
636 651 dev = vp->v_rdev;
652 +#else /* _KERNEL */
653 + /*
654 + * No getf(ufd) -- fd is really a dev32_t
655 + */
656 + dev = expldev((dev32_t)fd);
657 +#endif /* _KERNEL */
637 658 if (dev == 0 || dev == NODEV ||
638 659 getmajor(dev) != nsmb_major) {
639 660 err = EINVAL;
640 661 goto out;
641 662 }
642 663
643 664 sdp = ddi_get_soft_state(statep, getminor(dev));
644 665 if (sdp == NULL) {
645 666 err = EINVAL;
646 667 goto out;
647 668 }
648 669
649 670 ssp = sdp->sd_share;
650 671 if (ssp == NULL) {
651 672 err = ENOTCONN;
652 673 goto out;
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
653 674 }
654 675
655 676 /*
656 677 * Our caller gains a ref. to this share.
657 678 */
658 679 *sspp = ssp;
659 680 smb_share_hold(ssp);
660 681 err = 0;
661 682
662 683 out:
684 +#ifdef _KERNEL
663 685 if (fp)
664 686 releasef(fd);
687 +#endif /* _KERNEL */
665 688 return (err);
666 689 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX