Print this page
7378 exported_lock held during nfs4 compound processing

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs_export.c
          +++ new/usr/src/uts/common/fs/nfs/nfs_export.c
↓ open down ↓ 1914 lines elided ↑ open up ↑
1915 1915                          /*
1916 1916                           * If vop_fid_pseudo returns ENOSPC then the fid
1917 1917                           * supplied is too small. For now we simply
1918 1918                           * return EREMOTE.
1919 1919                           */
1920 1920                          if (error == ENOSPC)
1921 1921                                  error = EREMOTE;
1922 1922                          break;
1923 1923                  }
1924 1924  
1925      -                if (v4srv)
1926      -                        exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
1927      -                else
1928      -                        exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid);
1929      -
     1925 +                exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid,
     1926 +                    v4srv ? vp : NULL);
1930 1927                  if (exi != NULL) {
1931 1928                          /*
1932 1929                           * Found the export info
1933 1930                           */
1934 1931                          break;
1935 1932                  }
1936 1933  
1937 1934                  /*
1938 1935                   * We have just failed finding a matching export.
1939 1936                   * If we're at the root of this filesystem, then
↓ open down ↓ 484 lines elided ↑ open up ↑
2424 2421                  *statp = NFS4ERR_STALE;
2425 2422                  return (NULL);
2426 2423          }
2427 2424          /* XXX - disgusting hack */
2428 2425          if (vp->v_type == VNON && vp->v_flag & V_XATTRDIR)
2429 2426                  vp->v_type = VDIR;
2430 2427          *statp = NFS4_OK;
2431 2428          return (vp);
2432 2429  }
2433 2430  
2434      -/*
2435      - * Find the export structure associated with the given filesystem.
2436      - * If found, then increment the ref count (exi_count).
2437      - */
2438 2431  struct exportinfo *
2439      -checkexport(fsid_t *fsid, fid_t *fid)
     2432 +checkexport_nohold(fsid_t *fsid, fid_t *fid, vnode_t *vp)
2440 2433  {
2441 2434          struct exportinfo *exi;
2442 2435  
2443      -        rw_enter(&exported_lock, RW_READER);
2444      -        for (exi = exptable[exptablehash(fsid, fid)];
2445      -            exi != NULL;
2446      -            exi = exi->fid_hash.next) {
2447      -                if (exportmatch(exi, fsid, fid)) {
2448      -                        /*
2449      -                         * If this is the place holder for the
2450      -                         * public file handle, then return the
2451      -                         * real export entry for the public file
2452      -                         * handle.
2453      -                         */
2454      -                        if (exi->exi_export.ex_flags & EX_PUBLIC) {
2455      -                                exi = exi_public;
2456      -                        }
2457      -
2458      -                        exi_hold(exi);
2459      -                        rw_exit(&exported_lock);
2460      -                        return (exi);
2461      -                }
2462      -        }
2463      -        rw_exit(&exported_lock);
2464      -        return (NULL);
2465      -}
2466      -
2467      -
2468      -/*
2469      - * "old school" version of checkexport() for NFS4.  NFS4
2470      - * rfs4_compound holds exported_lock for duration of compound
2471      - * processing.  This version doesn't manipulate exi_count
2472      - * since NFS4 breaks fundamental assumptions in the exi_count
2473      - * design.
2474      - */
2475      -struct exportinfo *
2476      -checkexport4(fsid_t *fsid, fid_t *fid, vnode_t *vp)
2477      -{
2478      -        struct exportinfo *exi;
2479      -
2480      -        ASSERT(RW_LOCK_HELD(&exported_lock));
2481      -
2482 2436          for (exi = exptable[exptablehash(fsid, fid)];
2483 2437              exi != NULL;
2484 2438              exi = exi->fid_hash.next) {
2485 2439                  if (exportmatch(exi, fsid, fid)) {
2486 2440                          /*
2487 2441                           * If this is the place holder for the
2488 2442                           * public file handle, then return the
2489 2443                           * real export entry for the public file
2490 2444                           * handle.
2491 2445                           */
↓ open down ↓ 3 lines elided ↑ open up ↑
2495 2449  
2496 2450                          /*
2497 2451                           * If vp is given, check if vp is the
2498 2452                           * same vnode as the exported node.
2499 2453                           *
2500 2454                           * Since VOP_FID of a lofs node returns the
2501 2455                           * fid of its real node (ufs), the exported
2502 2456                           * node for lofs and (pseudo) ufs may have
2503 2457                           * the same fsid and fid.
2504 2458                           */
2505      -                        if (vp == NULL || vp == exi->exi_vp)
     2459 +                        if (vp == NULL || vp == exi->exi_vp) {
2506 2460                                  return (exi);
     2461 +                        }
2507 2462                  }
2508 2463          }
2509      -
2510 2464          return (NULL);
2511 2465  }
2512 2466  
2513 2467  /*
     2468 + * Find the export structure associated with the given filesystem.
     2469 + * If found, then increment the ref count (exi_count).
     2470 + */
     2471 +struct exportinfo *
     2472 +checkexport(fsid_t *fsid, fid_t *fid, vnode_t *vp)
     2473 +{
     2474 +        struct exportinfo *exi;
     2475 +
     2476 +        rw_enter(&exported_lock, RW_READER);
     2477 +        exi = checkexport_nohold(fsid, fid, vp);
     2478 +        if (exi)
     2479 +                exi_hold(exi);
     2480 +        rw_exit(&exported_lock);
     2481 +
     2482 +        return (exi);
     2483 +}
     2484 +
     2485 +/*
2514 2486   * Free an entire export list node
2515 2487   */
2516 2488  void
2517 2489  exportfree(struct exportinfo *exi)
2518 2490  {
2519 2491          struct exportdata *ex;
2520 2492          struct charset_cache *cache;
2521 2493          int i;
2522 2494  
2523 2495          ex = &exi->exi_export;
↓ open down ↓ 211 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX