Print this page
7378 exported_lock held during nfs4 compound processing


1905                 VN_HOLD(dvp);
1906         }
1907         if (walk != NULL)
1908                 *walk = 0;
1909 
1910         for (;;) {
1911                 bzero(&fid, sizeof (fid));
1912                 fid.fid_len = MAXFIDSZ;
1913                 error = vop_fid_pseudo(vp, &fid);
1914                 if (error) {
1915                         /*
1916                          * If vop_fid_pseudo returns ENOSPC then the fid
1917                          * supplied is too small. For now we simply
1918                          * return EREMOTE.
1919                          */
1920                         if (error == ENOSPC)
1921                                 error = EREMOTE;
1922                         break;
1923                 }
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 
1930                 if (exi != NULL) {
1931                         /*
1932                          * Found the export info
1933                          */
1934                         break;
1935                 }
1936 
1937                 /*
1938                  * We have just failed finding a matching export.
1939                  * If we're at the root of this filesystem, then
1940                  * it's time to stop (with failure).
1941                  */
1942                 if (vp->v_flag & VROOT) {
1943                         error = EINVAL;
1944                         break;
1945                 }
1946 
1947                 if (walk != NULL)
1948                         (*walk)++;
1949 


2414         error = VFS_VGET(vfsp, &vp, fidp);
2415         /*
2416          * If we can not get vp from VFS_VGET, perhaps this is
2417          * an nfs v2/v3/v4 node in an nfsv4 pseudo filesystem.
2418          * Check it out.
2419          */
2420         if (error && PSEUDO(exi))
2421                 error = nfs4_vget_pseudo(exi, &vp, fidp);
2422 
2423         if (error || vp == NULL) {
2424                 *statp = NFS4ERR_STALE;
2425                 return (NULL);
2426         }
2427         /* XXX - disgusting hack */
2428         if (vp->v_type == VNON && vp->v_flag & V_XATTRDIR)
2429                 vp->v_type = VDIR;
2430         *statp = NFS4_OK;
2431         return (vp);
2432 }
2433 
2434 /*
2435  * Find the export structure associated with the given filesystem.
2436  * If found, then increment the ref count (exi_count).
2437  */
2438 struct exportinfo *
2439 checkexport(fsid_t *fsid, fid_t *fid)
2440 {
2441         struct exportinfo *exi;
2442 
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         for (exi = exptable[exptablehash(fsid, fid)];
2483             exi != NULL;
2484             exi = exi->fid_hash.next) {
2485                 if (exportmatch(exi, fsid, fid)) {
2486                         /*
2487                          * If this is the place holder for the
2488                          * public file handle, then return the
2489                          * real export entry for the public file
2490                          * handle.
2491                          */
2492                         if (exi->exi_export.ex_flags & EX_PUBLIC) {
2493                                 exi = exi_public;
2494                         }
2495 
2496                         /*
2497                          * If vp is given, check if vp is the
2498                          * same vnode as the exported node.
2499                          *
2500                          * Since VOP_FID of a lofs node returns the
2501                          * fid of its real node (ufs), the exported
2502                          * node for lofs and (pseudo) ufs may have
2503                          * the same fsid and fid.
2504                          */
2505                         if (vp == NULL || vp == exi->exi_vp)
2506                                 return (exi);
2507                 }
2508         }
2509 
2510         return (NULL);
2511 }
2512 
2513 /*
2514  * Free an entire export list node
2515  */
2516 void
2517 exportfree(struct exportinfo *exi)
2518 {
2519         struct exportdata *ex;
2520         struct charset_cache *cache;
2521         int i;
2522 
2523         ex = &exi->exi_export;
2524 
2525         ASSERT(exi->exi_vp != NULL && !(exi->exi_export.ex_flags & EX_PUBLIC));
2526         VN_RELE(exi->exi_vp);
2527         if (exi->exi_dvp != NULL)
2528                 VN_RELE(exi->exi_dvp);
2529 
2530         if (ex->ex_flags & EX_INDEX)




1905                 VN_HOLD(dvp);
1906         }
1907         if (walk != NULL)
1908                 *walk = 0;
1909 
1910         for (;;) {
1911                 bzero(&fid, sizeof (fid));
1912                 fid.fid_len = MAXFIDSZ;
1913                 error = vop_fid_pseudo(vp, &fid);
1914                 if (error) {
1915                         /*
1916                          * If vop_fid_pseudo returns ENOSPC then the fid
1917                          * supplied is too small. For now we simply
1918                          * return EREMOTE.
1919                          */
1920                         if (error == ENOSPC)
1921                                 error = EREMOTE;
1922                         break;
1923                 }
1924 
1925                 exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid,
1926                     v4srv ? vp : NULL);



1927                 if (exi != NULL) {
1928                         /*
1929                          * Found the export info
1930                          */
1931                         break;
1932                 }
1933 
1934                 /*
1935                  * We have just failed finding a matching export.
1936                  * If we're at the root of this filesystem, then
1937                  * it's time to stop (with failure).
1938                  */
1939                 if (vp->v_flag & VROOT) {
1940                         error = EINVAL;
1941                         break;
1942                 }
1943 
1944                 if (walk != NULL)
1945                         (*walk)++;
1946 


2411         error = VFS_VGET(vfsp, &vp, fidp);
2412         /*
2413          * If we can not get vp from VFS_VGET, perhaps this is
2414          * an nfs v2/v3/v4 node in an nfsv4 pseudo filesystem.
2415          * Check it out.
2416          */
2417         if (error && PSEUDO(exi))
2418                 error = nfs4_vget_pseudo(exi, &vp, fidp);
2419 
2420         if (error || vp == NULL) {
2421                 *statp = NFS4ERR_STALE;
2422                 return (NULL);
2423         }
2424         /* XXX - disgusting hack */
2425         if (vp->v_type == VNON && vp->v_flag & V_XATTRDIR)
2426                 vp->v_type = VDIR;
2427         *statp = NFS4_OK;
2428         return (vp);
2429 }
2430 




2431 struct exportinfo *
2432 checkexport_nohold(fsid_t *fsid, fid_t *fid, vnode_t *vp)
2433 {
2434         struct exportinfo *exi;
2435 

2436         for (exi = exptable[exptablehash(fsid, fid)];
2437             exi != NULL;
2438             exi = exi->fid_hash.next) {
2439                 if (exportmatch(exi, fsid, fid)) {
2440                         /*
2441                          * If this is the place holder for the
2442                          * public file handle, then return the
2443                          * real export entry for the public file
2444                          * handle.
2445                          */
2446                         if (exi->exi_export.ex_flags & EX_PUBLIC) {
2447                                 exi = exi_public;
2448                         }
2449 
2450                         /*
2451                          * If vp is given, check if vp is the
2452                          * same vnode as the exported node.
2453                          *
2454                          * Since VOP_FID of a lofs node returns the
2455                          * fid of its real node (ufs), the exported
2456                          * node for lofs and (pseudo) ufs may have
2457                          * the same fsid and fid.
2458                          */
2459                         if (vp == NULL || vp == exi->exi_vp) {
2460                                 return (exi);
2461                         }
2462                 }
2463         }
2464         return (NULL);
2465 }
2466 

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 /*
2486  * Free an entire export list node
2487  */
2488 void
2489 exportfree(struct exportinfo *exi)
2490 {
2491         struct exportdata *ex;
2492         struct charset_cache *cache;
2493         int i;
2494 
2495         ex = &exi->exi_export;
2496 
2497         ASSERT(exi->exi_vp != NULL && !(exi->exi_export.ex_flags & EX_PUBLIC));
2498         VN_RELE(exi->exi_vp);
2499         if (exi->exi_dvp != NULL)
2500                 VN_RELE(exi->exi_dvp);
2501 
2502         if (ex->ex_flags & EX_INDEX)