Print this page
cstyle
Implement ioctl _FIODIRECTIO
Lots of comment cleanup
5404 smbfs needs mmap support
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_subr2.c
          +++ new/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_subr2.c
↓ open down ↓ 36 lines elided ↑ open up ↑
  37   37  
  38   38  #include <sys/param.h>
  39   39  #include <sys/systm.h>
  40   40  #include <sys/time.h>
  41   41  #include <sys/vnode.h>
  42   42  #include <sys/bitmap.h>
  43   43  #include <sys/dnlc.h>
  44   44  #include <sys/kmem.h>
  45   45  #include <sys/sunddi.h>
  46   46  #include <sys/sysmacros.h>
       47 +#include <sys/fcntl.h>
  47   48  
  48   49  #include <netsmb/smb_osdep.h>
  49   50  
  50   51  #include <netsmb/smb.h>
  51   52  #include <netsmb/smb_conn.h>
  52   53  #include <netsmb/smb_subr.h>
  53   54  #include <netsmb/smb_rq.h>
  54   55  
  55   56  #include <smbfs/smbfs.h>
  56   57  #include <smbfs/smbfs_node.h>
↓ open down ↓ 87 lines elided ↑ open up ↑
 144  145  static smbnode_t *
 145  146  sn_hashfind(smbmntinfo_t *, const char *, int, avl_index_t *);
 146  147  
 147  148  static smbnode_t *
 148  149  make_smbnode(smbmntinfo_t *, const char *, int, int *);
 149  150  
 150  151  /*
 151  152   * Free the resources associated with an smbnode.
 152  153   * Note: This is different from smbfs_inactive
 153  154   *
 154      - * NFS: nfs_subr.c:rinactive
      155 + * From NFS: nfs_subr.c:rinactive
 155  156   */
 156  157  static void
 157  158  sn_inactive(smbnode_t *np)
 158  159  {
 159  160          vsecattr_t      ovsa;
 160  161          cred_t          *oldcr;
 161  162          char            *orpath;
 162  163          int             orplen;
      164 +        vnode_t         *vp;
 163  165  
 164  166          /*
 165      -         * Flush and invalidate all pages (todo)
      167 +         * Here NFS has:
      168 +         * Flush and invalidate all pages (done by caller)
 166  169           * Free any held credentials and caches...
 167  170           * etc.  (See NFS code)
 168  171           */
 169  172          mutex_enter(&np->r_statelock);
 170  173  
 171  174          ovsa = np->r_secattr;
 172  175          np->r_secattr = smbfs_vsa0;
 173  176          np->r_sectime = 0;
 174  177  
 175  178          oldcr = np->r_cred;
 176  179          np->r_cred = NULL;
 177  180  
 178  181          orpath = np->n_rpath;
 179  182          orplen = np->n_rplen;
 180  183          np->n_rpath = NULL;
 181  184          np->n_rplen = 0;
 182  185  
 183  186          mutex_exit(&np->r_statelock);
 184  187  
      188 +        vp = SMBTOV(np);
      189 +        if (vn_has_cached_data(vp)) {
      190 +                ASSERT3P(vp,==,NULL);
      191 +        }
      192 +
 185  193          if (ovsa.vsa_aclentp != NULL)
 186  194                  kmem_free(ovsa.vsa_aclentp, ovsa.vsa_aclentsz);
 187  195  
 188  196          if (oldcr != NULL)
 189  197                  crfree(oldcr);
 190  198  
 191  199          if (orpath != NULL)
 192  200                  kmem_free(orpath, orplen + 1);
 193  201  }
 194  202  
↓ open down ↓ 2 lines elided ↑ open up ↑
 197  205   * mountinfo, directory, separator, and name.  If the
 198  206   * desired smbnode already exists, return a reference.
 199  207   * If the file attributes pointer is non-null, the node
 200  208   * is created if necessary and linked into the AVL tree.
 201  209   *
 202  210   * Callers that need a node created but don't have the
 203  211   * real attributes pass smbfs_fattr0 to force creation.
 204  212   *
 205  213   * Note: make_smbnode() may upgrade the "hash" lock to exclusive.
 206  214   *
 207      - * NFS: nfs_subr.c:makenfsnode
      215 + * Based on NFS: nfs_subr.c:makenfsnode
 208  216   */
 209  217  smbnode_t *
 210  218  smbfs_node_findcreate(
 211  219          smbmntinfo_t *mi,
 212  220          const char *dirnm,
 213  221          int dirlen,
 214  222          const char *name,
 215  223          int nmlen,
 216  224          char sep,
 217  225          struct smbfattr *fap)
↓ open down ↓ 61 lines elided ↑ open up ↑
 279  287           */
 280  288          ASSERT(np != NULL);
 281  289          if (fap == &smbfs_fattr0)
 282  290                  return (np);
 283  291  
 284  292          /*
 285  293           * Apply the given attributes to this node,
 286  294           * dealing with any cache impact, etc.
 287  295           */
 288  296          vp = SMBTOV(np);
 289      -        if (!newnode) {
 290      -                /*
 291      -                 * Found an existing node.
 292      -                 * Maybe purge caches...
 293      -                 */
 294      -                smbfs_cache_check(vp, fap);
 295      -        }
 296  297          smbfs_attrcache_fa(vp, fap);
 297  298  
 298  299          /*
 299  300           * Note NFS sets vp->v_type here, assuming it
 300  301           * can never change for the life of a node.
 301  302           * We allow v_type to change, and set it in
 302  303           * smbfs_attrcache().  Also: mode, uid, gid
 303  304           */
 304  305          return (np);
 305  306  }
 306  307  
 307  308  /*
 308      - * NFS: nfs_subr.c:rtablehash
      309 + * Here NFS has: nfs_subr.c:rtablehash
 309  310   * We use smbfs_hash().
 310  311   */
 311  312  
 312  313  /*
 313  314   * Find or create an smbnode.
 314      - * NFS: nfs_subr.c:make_rnode
      315 + * From NFS: nfs_subr.c:make_rnode
 315  316   */
 316  317  static smbnode_t *
 317  318  make_smbnode(
 318  319          smbmntinfo_t *mi,
 319  320          const char *rpath,
 320  321          int rplen,
 321  322          int *newnode)
 322  323  {
 323  324          smbnode_t *np;
 324  325          smbnode_t *tnp;
↓ open down ↓ 102 lines elided ↑ open up ↑
 427  428          /* cv_init(&np->r_commit.c_cv, NULL, CV_DEFAULT, NULL); */
 428  429  
 429  430          np->r_vnode = vp;
 430  431          np->n_mount = mi;
 431  432  
 432  433          np->n_fid = SMB_FID_UNUSED;
 433  434          np->n_uid = mi->smi_uid;
 434  435          np->n_gid = mi->smi_gid;
 435  436          /* Leave attributes "stale." */
 436  437  
 437      -#if 0 /* XXX dircache */
 438  438          /*
 439      -         * We don't know if it's a directory yet.
 440      -         * Let the caller do this?  XXX
      439 +         * Here NFS has avl_create(&np->r_dir, ...)
      440 +         * for the readdir cache (not used here).
 441  441           */
 442      -        avl_create(&np->r_dir, compar, sizeof (rddir_cache),
 443      -            offsetof(rddir_cache, tree));
 444      -#endif
 445  442  
 446  443          /* Now fill in the vnode. */
 447  444          vn_setops(vp, smbfs_vnodeops);
 448  445          vp->v_data = (caddr_t)np;
 449  446          VFS_HOLD(vfsp);
 450  447          vp->v_vfsp = vfsp;
 451  448          vp->v_type = VNON;
 452  449  
 453  450          /*
 454  451           * We entered with mi->smi_hash_lk held (reader).
↓ open down ↓ 37 lines elided ↑ open up ↑
 492  489  
 493  490  /*
 494  491   * smbfs_addfree
 495  492   * Put an smbnode on the free list, or destroy it immediately
 496  493   * if it offers no value were it to be reclaimed later.  Also
 497  494   * destroy immediately when we have too many smbnodes, etc.
 498  495   *
 499  496   * Normally called by smbfs_inactive, but also
 500  497   * called in here during cleanup operations.
 501  498   *
 502      - * NFS: nfs_subr.c:rp_addfree
      499 + * From NFS: nfs_subr.c:rp_addfree
 503  500   */
 504  501  void
 505  502  smbfs_addfree(smbnode_t *np)
 506  503  {
 507  504          vnode_t *vp;
 508  505          struct vfs *vfsp;
 509  506          smbmntinfo_t *mi;
 510  507  
 511  508          ASSERT(np->r_freef == NULL && np->r_freeb == NULL);
 512  509  
↓ open down ↓ 107 lines elided ↑ open up ↑
 620  617  
 621  618          rw_exit(&mi->smi_hash_lk);
 622  619  }
 623  620  
 624  621  /*
 625  622   * Remove an smbnode from the free list.
 626  623   *
 627  624   * The caller must be holding smbfreelist_lock and the smbnode
 628  625   * must be on the freelist.
 629  626   *
 630      - * NFS: nfs_subr.c:rp_rmfree
      627 + * From NFS: nfs_subr.c:rp_rmfree
 631  628   */
 632  629  static void
 633  630  sn_rmfree(smbnode_t *np)
 634  631  {
 635  632  
 636  633          ASSERT(MUTEX_HELD(&smbfreelist_lock));
 637  634          ASSERT(np->r_freef != NULL && np->r_freeb != NULL);
 638  635  
 639  636          if (np == smbfreelist) {
 640  637                  smbfreelist = np->r_freef;
↓ open down ↓ 5 lines elided ↑ open up ↑
 646  643          np->r_freef->r_freeb = np->r_freeb;
 647  644  
 648  645          np->r_freef = np->r_freeb = NULL;
 649  646  }
 650  647  
 651  648  /*
 652  649   * Put an smbnode in the "hash" AVL tree.
 653  650   *
 654  651   * The caller must be hold the rwlock as writer.
 655  652   *
 656      - * NFS: nfs_subr.c:rp_addhash
      653 + * From NFS: nfs_subr.c:rp_addhash
 657  654   */
 658  655  static void
 659  656  sn_addhash_locked(smbnode_t *np, avl_index_t where)
 660  657  {
 661  658          smbmntinfo_t *mi = np->n_mount;
 662  659  
 663  660          ASSERT(RW_WRITE_HELD(&mi->smi_hash_lk));
 664  661  
 665  662          mutex_enter(&np->r_statelock);
 666  663          if ((np->r_flags & RHASHED) == 0) {
↓ open down ↓ 1 lines elided ↑ open up ↑
 668  665                  np->r_flags |= RHASHED;
 669  666          }
 670  667          mutex_exit(&np->r_statelock);
 671  668  }
 672  669  
 673  670  /*
 674  671   * Remove an smbnode from the "hash" AVL tree.
 675  672   *
 676  673   * The caller must hold the rwlock as writer.
 677  674   *
 678      - * NFS: nfs_subr.c:rp_rmhash_locked
      675 + * From NFS: nfs_subr.c:rp_rmhash_locked
 679  676   */
 680  677  static void
 681  678  sn_rmhash_locked(smbnode_t *np)
 682  679  {
 683  680          smbmntinfo_t *mi = np->n_mount;
 684  681  
 685  682          ASSERT(RW_WRITE_HELD(&mi->smi_hash_lk));
 686  683  
 687  684          mutex_enter(&np->r_statelock);
 688  685          if ((np->r_flags & RHASHED) != 0) {
↓ open down ↓ 16 lines elided ↑ open up ↑
 705  702          rw_enter(&mi->smi_hash_lk, RW_WRITER);
 706  703          sn_rmhash_locked(np);
 707  704          rw_exit(&mi->smi_hash_lk);
 708  705  }
 709  706  
 710  707  /*
 711  708   * Lookup an smbnode by remote pathname
 712  709   *
 713  710   * The caller must be holding the AVL rwlock, either shared or exclusive.
 714  711   *
 715      - * NFS: nfs_subr.c:rfind
      712 + * From NFS: nfs_subr.c:rfind
 716  713   */
 717  714  static smbnode_t *
 718  715  sn_hashfind(
 719  716          smbmntinfo_t *mi,
 720  717          const char *rpath,
 721  718          int rplen,
 722  719          avl_index_t *pwhere) /* optional */
 723  720  {
 724  721          smbfs_node_hdr_t nhdr;
 725  722          smbnode_t *np;
↓ open down ↓ 134 lines elided ↑ open up ↑
 860  857  
 861  858  /*
 862  859   * Return 1 if there is a active vnode belonging to this vfs in the
 863  860   * smbnode cache.
 864  861   *
 865  862   * Several of these checks are done without holding the usual
 866  863   * locks.  This is safe because destroy_smbtable(), smbfs_addfree(),
 867  864   * etc. will redo the necessary checks before actually destroying
 868  865   * any smbnodes.
 869  866   *
 870      - * NFS: nfs_subr.c:check_rtable
      867 + * From NFS: nfs_subr.c:check_rtable
 871  868   *
 872  869   * Debugging changes here relative to NFS.
 873  870   * Relatively harmless, so left 'em in.
 874  871   */
 875  872  int
 876  873  smbfs_check_table(struct vfs *vfsp, smbnode_t *rtnp)
 877  874  {
 878  875          smbmntinfo_t *mi;
 879  876          smbnode_t *np;
 880  877          vnode_t *vp;
↓ open down ↓ 38 lines elided ↑ open up ↑
 919  916          rw_exit(&mi->smi_hash_lk);
 920  917  
 921  918          return (busycnt);
 922  919  }
 923  920  
 924  921  /*
 925  922   * Destroy inactive vnodes from the AVL tree which belong to this
 926  923   * vfs.  It is essential that we destroy all inactive vnodes during a
 927  924   * forced unmount as well as during a normal unmount.
 928  925   *
 929      - * NFS: nfs_subr.c:destroy_rtable
      926 + * Based on NFS: nfs_subr.c:destroy_rtable
 930  927   *
 931  928   * In here, we're normally destrying all or most of the AVL tree,
 932  929   * so the natural choice is to use avl_destroy_nodes.  However,
 933  930   * there may be a few busy nodes that should remain in the AVL
 934  931   * tree when we're done.  The solution: use a temporary tree to
 935  932   * hold the busy nodes until we're done destroying the old tree,
 936  933   * then copy the temporary tree over the (now emtpy) real tree.
 937  934   */
 938  935  void
 939  936  smbfs_destroy_table(struct vfs *vfsp)
↓ open down ↓ 64 lines elided ↑ open up ↑
1004 1001          while ((np = rlist) != NULL) {
1005 1002                  rlist = (smbnode_t *)np->r_avl_node.avl_child[0];
1006 1003                  smbfs_addfree(np);
1007 1004          }
1008 1005  }
1009 1006  
1010 1007  /*
1011 1008   * This routine destroys all the resources associated with the smbnode
1012 1009   * and then the smbnode itself.  Note: sn_inactive has been called.
1013 1010   *
1014      - * NFS: nfs_subr.c:destroy_rnode
     1011 + * From NFS: nfs_subr.c:destroy_rnode
1015 1012   */
1016 1013  static void
1017 1014  sn_destroy_node(smbnode_t *np)
1018 1015  {
1019 1016          vnode_t *vp;
1020 1017          vfs_t *vfsp;
1021 1018  
1022 1019          vp = SMBTOV(np);
1023 1020          vfsp = vp->v_vfsp;
1024 1021  
↓ open down ↓ 6 lines elided ↑ open up ↑
1031 1028          ASSERT(!(np->r_flags & RHASHED));
1032 1029          ASSERT(np->r_freef == NULL && np->r_freeb == NULL);
1033 1030          atomic_dec_ulong((ulong_t *)&smbnodenew);
1034 1031          vn_invalid(vp);
1035 1032          vn_free(vp);
1036 1033          kmem_cache_free(smbnode_cache, np);
1037 1034          VFS_RELE(vfsp);
1038 1035  }
1039 1036  
1040 1037  /*
     1038 + * From NFS rflush()
1041 1039   * Flush all vnodes in this (or every) vfs.
1042      - * Used by nfs_sync and by nfs_unmount.
     1040 + * Used by smbfs_sync and by smbfs_unmount.
1043 1041   */
1044 1042  /*ARGSUSED*/
1045 1043  void
1046 1044  smbfs_rflush(struct vfs *vfsp, cred_t *cr)
1047 1045  {
1048      -        /* Todo: mmap support. */
     1046 +        smbmntinfo_t *mi;
     1047 +        smbnode_t *np;
     1048 +        vnode_t *vp, **vplist;
     1049 +        long num, cnt;
     1050 +
     1051 +        mi = VFTOSMI(vfsp);
     1052 +
     1053 +        /*
     1054 +         * Check to see whether there is anything to do.
     1055 +         */
     1056 +        num = avl_numnodes(&mi->smi_hash_avl);
     1057 +        if (num == 0)
     1058 +                return;
     1059 +
     1060 +        /*
     1061 +         * Allocate a slot for all currently active rnodes on the
     1062 +         * supposition that they all may need flushing.
     1063 +         */
     1064 +        vplist = kmem_alloc(num * sizeof (*vplist), KM_SLEEP);
     1065 +        cnt = 0;
     1066 +
     1067 +        /*
     1068 +         * Walk the AVL tree looking for rnodes with page
     1069 +         * lists associated with them.  Make a list of these
     1070 +         * files.
     1071 +         */
     1072 +        rw_enter(&mi->smi_hash_lk, RW_READER);
     1073 +        for (np = avl_first(&mi->smi_hash_avl); np != NULL;
     1074 +            np = avl_walk(&mi->smi_hash_avl, np, AVL_AFTER)) {
     1075 +                vp = SMBTOV(np);
     1076 +                /*
     1077 +                 * Don't bother sync'ing a vp if it
     1078 +                 * is part of virtual swap device or
     1079 +                 * if VFS is read-only
     1080 +                 */
     1081 +                if (IS_SWAPVP(vp) || vn_is_readonly(vp))
     1082 +                        continue;
     1083 +                /*
     1084 +                 * If the vnode has pages and is marked as either
     1085 +                 * dirty or mmap'd, hold and add this vnode to the
     1086 +                 * list of vnodes to flush.
     1087 +                 */
     1088 +                if (vn_has_cached_data(vp) &&
     1089 +                    ((np->r_flags & RDIRTY) || np->r_mapcnt > 0)) {
     1090 +                        VN_HOLD(vp);
     1091 +                        vplist[cnt++] = vp;
     1092 +                        if (cnt == num)
     1093 +                                break;
     1094 +                }
     1095 +        }
     1096 +        rw_exit(&mi->smi_hash_lk);
     1097 +
     1098 +        /*
     1099 +         * Flush and release all of the files on the list.
     1100 +         */
     1101 +        while (cnt-- > 0) {
     1102 +                vp = vplist[cnt];
     1103 +                (void) VOP_PUTPAGE(vp, (u_offset_t)0, 0, B_ASYNC, cr, NULL);
     1104 +                VN_RELE(vp);
     1105 +        }
     1106 +
     1107 +        kmem_free(vplist, num * sizeof (vnode_t *));
1049 1108  }
1050 1109  
1051      -/* access cache (nfs_subr.c) not used here */
     1110 +/* Here NFS has access cache stuff (nfs_subr.c) not used here */
1052 1111  
     1112 +/*
     1113 + * Set or Clear direct I/O flag
     1114 + * VOP_RWLOCK() is held for write access to prevent a race condition
     1115 + * which would occur if a process is in the middle of a write when
     1116 + * directio flag gets set. It is possible that all pages may not get flushed.
     1117 + * From nfs_common.c
     1118 + */
     1119 +
     1120 +/* ARGSUSED */
     1121 +int
     1122 +smbfs_directio(vnode_t *vp, int cmd, cred_t *cr)
     1123 +{
     1124 +        int     error = 0;
     1125 +        smbnode_t       *np;
     1126 +
     1127 +        np = VTOSMB(vp);
     1128 +
     1129 +        if (cmd == DIRECTIO_ON) {
     1130 +
     1131 +                if (np->r_flags & RDIRECTIO)
     1132 +                        return (0);
     1133 +
     1134 +                /*
     1135 +                 * Flush the page cache.
     1136 +                 */
     1137 +
     1138 +                (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
     1139 +
     1140 +                if (np->r_flags & RDIRECTIO) {
     1141 +                        VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
     1142 +                        return (0);
     1143 +                }
     1144 +
     1145 +                /* Here NFS also checks ->r_awcount */
     1146 +                if (vn_has_cached_data(vp) &&
     1147 +                    (np->r_flags & RDIRTY) != 0) {
     1148 +                        error = VOP_PUTPAGE(vp, (offset_t)0, (uint_t)0,
     1149 +                            B_INVAL, cr, NULL);
     1150 +                        if (error) {
     1151 +                                if (error == ENOSPC || error == EDQUOT) {
     1152 +                                        mutex_enter(&np->r_statelock);
     1153 +                                        if (!np->r_error)
     1154 +                                                np->r_error = error;
     1155 +                                        mutex_exit(&np->r_statelock);
     1156 +                                }
     1157 +                                VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
     1158 +                                return (error);
     1159 +                        }
     1160 +                }
     1161 +
     1162 +                mutex_enter(&np->r_statelock);
     1163 +                np->r_flags |= RDIRECTIO;
     1164 +                mutex_exit(&np->r_statelock);
     1165 +                VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
     1166 +                return (0);
     1167 +        }
     1168 +
     1169 +        if (cmd == DIRECTIO_OFF) {
     1170 +                mutex_enter(&np->r_statelock);
     1171 +                np->r_flags &= ~RDIRECTIO;      /* disable direct mode */
     1172 +                mutex_exit(&np->r_statelock);
     1173 +                return (0);
     1174 +        }
     1175 +
     1176 +        return (EINVAL);
     1177 +}
     1178 +
1053 1179  static kmutex_t smbfs_newnum_lock;
1054 1180  static uint32_t smbfs_newnum_val = 0;
1055 1181  
1056 1182  /*
1057 1183   * Return a number 0..0xffffffff that's different from the last
1058 1184   * 0xffffffff numbers this returned.  Used for unlinked files.
1059      - * (This too was copied from nfs_subr.c)
     1185 + * From NFS nfs_subr.c newnum
1060 1186   */
1061 1187  uint32_t
1062 1188  smbfs_newnum(void)
1063 1189  {
1064 1190          uint32_t id;
1065 1191  
1066 1192          mutex_enter(&smbfs_newnum_lock);
1067 1193          if (smbfs_newnum_val == 0)
1068 1194                  smbfs_newnum_val = (uint32_t)gethrestime_sec();
1069 1195          id = smbfs_newnum_val++;
↓ open down ↓ 13 lines elided ↑ open up ↑
1083 1209          id = smbfs_newnum();
1084 1210          n = snprintf(buf, buflen, "~$smbfs%08X", id);
1085 1211          return (n);
1086 1212  }
1087 1213  
1088 1214  
1089 1215  /*
1090 1216   * initialize resources that are used by smbfs_subr.c
1091 1217   * this is called from the _init() routine (by the way of smbfs_clntinit())
1092 1218   *
1093      - * NFS: nfs_subr.c:nfs_subrinit
     1219 + * From NFS: nfs_subr.c:nfs_subrinit
1094 1220   */
1095 1221  int
1096 1222  smbfs_subrinit(void)
1097 1223  {
1098 1224          ulong_t nsmbnode_max;
1099 1225  
1100 1226          /*
1101 1227           * Allocate and initialize the smbnode cache
1102 1228           */
1103 1229          if (nsmbnode <= 0)
↓ open down ↓ 23 lines elided ↑ open up ↑
1127 1253                      "smbfs: init: can't get unique device number");
1128 1254                  smbfs_major = 0;
1129 1255          }
1130 1256          smbfs_minor = 0;
1131 1257  
1132 1258          return (0);
1133 1259  }
1134 1260  
1135 1261  /*
1136 1262   * free smbfs hash table, etc.
1137      - * NFS: nfs_subr.c:nfs_subrfini
     1263 + * From NFS: nfs_subr.c:nfs_subrfini
1138 1264   */
1139 1265  void
1140 1266  smbfs_subrfini(void)
1141 1267  {
1142 1268  
1143 1269          /*
1144 1270           * Destroy the smbnode cache
1145 1271           */
1146 1272          kmem_cache_destroy(smbnode_cache);
1147 1273  
↓ open down ↓ 54 lines elided ↑ open up ↑
1202 1328   *
1203 1329   * Todo: dump nodes from the free list?
1204 1330   */
1205 1331  /*ARGSUSED*/
1206 1332  void
1207 1333  smbfs_kmem_reclaim(void *cdrarg)
1208 1334  {
1209 1335          smbfs_node_reclaim();
1210 1336  }
1211 1337  
1212      -/* nfs failover stuff */
1213      -/* nfs_rw_xxx - see smbfs_rwlock.c */
     1338 +/*
     1339 + * Here NFS has failover stuff and
     1340 + * nfs_rw_xxx - see smbfs_rwlock.c
     1341 + */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX