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
↓ 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>
↓ 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 */
↓ 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  {
↓ 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)
↓ 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  
↓ 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)
↓ 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)
↓ 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
↓ 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;
↓ 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