1116                  */
1117                 if (ent_sin->sin_addr.s_addr == clr_in.s_addr) {
1118                         cp->rc_forced_expire = 1;
1119                 }
1120                 break;
1121 
1122         default:
1123                 /* force this assert to fail */
1124                 ASSERT(clr->addr_type != clr->addr_type);
1125         }
1126 }
1127 
1128 /*
1129  * This is called from nfssys() in order to clear server state
1130  * for the specified client IP Address.
1131  */
1132 void
1133 rfs4_clear_client_state(struct nfs4clrst_args *clr)
1134 {
1135         nfs4_srv_t *nsrv4;
1136         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1137         (void) rfs4_dbe_walk(nsrv4->rfs4_client_tab, rfs4_client_scrub, clr);
1138 }
1139 
1140 /*
1141  * Used to initialize the NFSv4 server's state or database.  All of
1142  * the tables are created and timers are set.
1143  */
1144 void
1145 rfs4_state_g_init()
1146 {
1147         extern boolean_t rfs4_cpr_callb(void *, int);
1148         /*
1149          * Add a CPR callback so that we can update client
1150          * access times to extend the lease after a suspend
1151          * and resume (using the same class as rpcmod/connmgr)
1152          */
1153         cpr_id = callb_add(rfs4_cpr_callb, 0, CB_CL_CPR_RPC, "rfs4");
1154 
1155         /*
1156          * NFSv4 server state databases
 
1475             deleg_state_compare,
1476             deleg_state_mkkey, FALSE);
1477 
1478         mutex_exit(&nsrv4->state_lock);
1479 
1480         /*
1481          * Init the stable storage.
1482          */
1483         rfs4_ss_init(nsrv4);
1484 }
1485 
1486 /*
1487  * Used at server shutdown to cleanup all of NFSv4 server's zone structures
1488  * and state.
1489  */
1490 void
1491 rfs4_state_zone_fini()
1492 {
1493         rfs4_database_t *dbp;
1494         nfs4_srv_t *nsrv4;
1495         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1496 
1497         rfs4_set_deleg_policy(nsrv4, SRV_NEVER_DELEGATE);
1498 
1499         /*
1500          * Clean up any dangling stable storage structures BEFORE calling
1501          * rfs4_servinst_destroy_all() so there are no dangling structures
1502          * (i.e. the srvinsts are all cleared of danglers BEFORE they get
1503          * freed).
1504          */
1505         rfs4_ss_fini(nsrv4);
1506 
1507         mutex_enter(&nsrv4->state_lock);
1508 
1509         if (nsrv4->nfs4_server_state == NULL) {
1510                 mutex_exit(&nsrv4->state_lock);
1511                 return;
1512         }
1513 
1514         /* destroy server instances and current instance ptr */
1515         rfs4_servinst_destroy_all(nsrv4);
 
1651                 cp->rc_ss_remove = 1;
1652         return (cp_expired);
1653 }
1654 
1655 /*
1656  * Remove the leaf file from all distributed stable storage paths.
1657  */
1658 static void
1659 rfs4_dss_remove_cpleaf(rfs4_client_t *cp)
1660 {
1661         nfs4_srv_t *nsrv4;
1662         rfs4_servinst_t *sip;
1663         char *leaf = cp->rc_ss_pn->leaf;
1664 
1665         /*
1666          * since the state files are written to all DSS
1667          * paths we must remove this leaf file instance
1668          * from all server instances.
1669          */
1670 
1671         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1672         mutex_enter(&nsrv4->servinst_lock);
1673         for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
1674                 /* remove the leaf file associated with this server instance */
1675                 rfs4_dss_remove_leaf(sip, NFS4_DSS_STATE_LEAF, leaf);
1676         }
1677         mutex_exit(&nsrv4->servinst_lock);
1678 }
1679 
1680 static void
1681 rfs4_dss_remove_leaf(rfs4_servinst_t *sip, char *dir_leaf, char *leaf)
1682 {
1683         int i, npaths = sip->dss_npaths;
1684 
1685         for (i = 0; i < npaths; i++) {
1686                 rfs4_dss_path_t *dss_path = sip->dss_paths[i];
1687                 char *path, *dir;
1688                 size_t pathlen;
1689 
1690                 /* the HA-NFSv4 path might have been failed-over away from us */
1691                 if (dss_path == NULL)
 
1727                 rfs4_ss_pnfree(cp->rc_ss_pn);
1728         }
1729 
1730         /* Free the client supplied client id */
1731         kmem_free(cp->rc_nfs_client.id_val, cp->rc_nfs_client.id_len);
1732 
1733         if (cp->rc_sysidt != LM_NOSYSID)
1734                 lm_free_sysidt(cp->rc_sysidt);
1735 }
1736 
1737 static bool_t
1738 rfs4_client_create(rfs4_entry_t u_entry, void *arg)
1739 {
1740         rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1741         nfs_client_id4 *client = (nfs_client_id4 *)arg;
1742         struct sockaddr *ca;
1743         cid *cidp;
1744         scid_confirm_verf *scvp;
1745         nfs4_srv_t *nsrv4;
1746 
1747         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1748 
1749         /* Get a clientid to give to the client */
1750         cidp = (cid *)&cp->rc_clientid;
1751         cidp->impl_id.start_time = nsrv4->rfs4_start_time;
1752         cidp->impl_id.c_id = (uint32_t)rfs4_dbe_getid(cp->rc_dbe);
1753 
1754         /* If we are booted as a cluster node, embed our nodeid */
1755         if (cluster_bootflags & CLUSTER_BOOTED)
1756                 embed_nodeid(cidp);
1757 
1758         /* Allocate and copy client's client id value */
1759         cp->rc_nfs_client.id_val = kmem_alloc(client->id_len, KM_SLEEP);
1760         cp->rc_nfs_client.id_len = client->id_len;
1761         bcopy(client->id_val, cp->rc_nfs_client.id_val, client->id_len);
1762         cp->rc_nfs_client.verifier = client->verifier;
1763 
1764         /* Copy client's IP address */
1765         ca = client->cl_addr;
1766         if (ca->sa_family == AF_INET)
1767                 bcopy(ca, &cp->rc_addr, sizeof (struct sockaddr_in));
 
1821 rfs4_client_scv_next(rfs4_client_t *cp)
1822 {
1823         scid_confirm_verf *scvp;
1824 
1825         /* Init the value for the SETCLIENTID_CONFIRM verifier */
1826         scvp = (scid_confirm_verf *)&cp->rc_confirm_verf;
1827         scvp->cv_impl.gen_num++;
1828 }
1829 
1830 void
1831 rfs4_client_rele(rfs4_client_t *cp)
1832 {
1833         rfs4_dbe_rele(cp->rc_dbe);
1834 }
1835 
1836 rfs4_client_t *
1837 rfs4_findclient(nfs_client_id4 *client, bool_t *create, rfs4_client_t *oldcp)
1838 {
1839         rfs4_client_t *cp;
1840         nfs4_srv_t *nsrv4;
1841         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1842 
1843 
1844         if (oldcp) {
1845                 rw_enter(&nsrv4->rfs4_findclient_lock, RW_WRITER);
1846                 rfs4_dbe_hide(oldcp->rc_dbe);
1847         } else {
1848                 rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1849         }
1850 
1851         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_nfsclnt_idx, client,
1852             create, (void *)client, RFS4_DBS_VALID);
1853 
1854         if (oldcp)
1855                 rfs4_dbe_unhide(oldcp->rc_dbe);
1856 
1857         rw_exit(&nsrv4->rfs4_findclient_lock);
1858 
1859         return (cp);
1860 }
1861 
1862 rfs4_client_t *
1863 rfs4_findclient_by_id(clientid4 clientid, bool_t find_unconfirmed)
1864 {
1865         rfs4_client_t *cp;
1866         bool_t create = FALSE;
1867         cid *cidp = (cid *)&clientid;
1868         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1869 
1870         /* If we're a cluster and the nodeid isn't right, short-circuit */
1871         if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
1872                 return (NULL);
1873 
1874         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1875 
1876         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx, &clientid,
1877             &create, NULL, RFS4_DBS_VALID);
1878 
1879         rw_exit(&nsrv4->rfs4_findclient_lock);
1880 
1881         if (cp && cp->rc_need_confirm && find_unconfirmed == FALSE) {
1882                 rfs4_client_rele(cp);
1883                 return (NULL);
1884         } else {
1885                 return (cp);
1886         }
1887 }
1888 
 
1969         struct sockaddr *ca = (struct sockaddr *)arg;
1970 
1971         /* Copy client's IP address */
1972         if (ca->sa_family == AF_INET)
1973                 bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in));
1974         else if (ca->sa_family == AF_INET6)
1975                 bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in6));
1976         else
1977                 return (FALSE);
1978         cp->ri_no_referrals = 1;
1979 
1980         return (TRUE);
1981 }
1982 
1983 rfs4_clntip_t *
1984 rfs4_find_clntip(struct sockaddr *addr, bool_t *create)
1985 {
1986         rfs4_clntip_t *cp;
1987         nfs4_srv_t *nsrv4;
1988 
1989         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1990 
1991         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1992 
1993         cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
1994             create, addr, RFS4_DBS_VALID);
1995 
1996         rw_exit(&nsrv4->rfs4_findclient_lock);
1997 
1998         return (cp);
1999 }
2000 
2001 void
2002 rfs4_invalidate_clntip(struct sockaddr *addr)
2003 {
2004         rfs4_clntip_t *cp;
2005         bool_t create = FALSE;
2006         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2007 
2008         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2009 
2010         cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
2011             &create, NULL, RFS4_DBS_VALID);
2012         if (cp == NULL) {
2013                 rw_exit(&nsrv4->rfs4_findclient_lock);
2014                 return;
2015         }
2016         rfs4_dbe_invalidate(cp->ri_dbe);
2017         rfs4_dbe_rele(cp->ri_dbe);
2018 
2019         rw_exit(&nsrv4->rfs4_findclient_lock);
2020 }
2021 
2022 bool_t
2023 rfs4_lease_expired(rfs4_client_t *cp)
2024 {
2025         bool_t rc;
2026 
 
2147 
2148         /* Free the lock owner id */
2149         kmem_free(oo->ro_owner.owner_val, oo->ro_owner.owner_len);
2150 }
2151 
2152 void
2153 rfs4_openowner_rele(rfs4_openowner_t *oo)
2154 {
2155         rfs4_dbe_rele(oo->ro_dbe);
2156 }
2157 
2158 static bool_t
2159 rfs4_openowner_create(rfs4_entry_t u_entry, void *arg)
2160 {
2161         rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2162         rfs4_openowner_t *argp = (rfs4_openowner_t *)arg;
2163         open_owner4 *openowner = &argp->ro_owner;
2164         seqid4 seqid = argp->ro_open_seqid;
2165         rfs4_client_t *cp;
2166         bool_t create = FALSE;
2167         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2168 
2169         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2170 
2171         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2172             &openowner->clientid,
2173             &create, NULL, RFS4_DBS_VALID);
2174 
2175         rw_exit(&nsrv4->rfs4_findclient_lock);
2176 
2177         if (cp == NULL)
2178                 return (FALSE);
2179 
2180         oo->ro_reply_fh.nfs_fh4_len = 0;
2181         oo->ro_reply_fh.nfs_fh4_val = NULL;
2182 
2183         oo->ro_owner.clientid = openowner->clientid;
2184         oo->ro_owner.owner_val =
2185             kmem_alloc(openowner->owner_len, KM_SLEEP);
2186 
2187         bcopy(openowner->owner_val,
 
2197         bzero(&oo->ro_reply, sizeof (nfs_resop4));
2198         oo->ro_client = cp;
2199         oo->ro_cr_set = NULL;
2200 
2201         list_create(&oo->ro_statelist, sizeof (rfs4_state_t),
2202             offsetof(rfs4_state_t, rs_node));
2203 
2204         /* Insert openowner into client's open owner list */
2205         rfs4_dbe_lock(cp->rc_dbe);
2206         list_insert_tail(&cp->rc_openownerlist, oo);
2207         rfs4_dbe_unlock(cp->rc_dbe);
2208 
2209         return (TRUE);
2210 }
2211 
2212 rfs4_openowner_t *
2213 rfs4_findopenowner(open_owner4 *openowner, bool_t *create, seqid4 seqid)
2214 {
2215         rfs4_openowner_t *oo;
2216         rfs4_openowner_t arg;
2217         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2218 
2219         arg.ro_owner = *openowner;
2220         arg.ro_open_seqid = seqid;
2221         /* CSTYLED */
2222         oo = (rfs4_openowner_t *)rfs4_dbsearch(nsrv4->rfs4_openowner_idx, openowner,
2223             create, &arg, RFS4_DBS_VALID);
2224 
2225         return (oo);
2226 }
2227 
2228 void
2229 rfs4_update_open_sequence(rfs4_openowner_t *oo)
2230 {
2231 
2232         rfs4_dbe_lock(oo->ro_dbe);
2233 
2234         oo->ro_open_seqid++;
2235 
2236         rfs4_dbe_unlock(oo->ro_dbe);
2237 }
 
2345 }
2346 
2347 /* ARGSUSED */
2348 static bool_t
2349 rfs4_lockowner_expiry(rfs4_entry_t u_entry)
2350 {
2351         /*
2352          * Since expiry is called with no other references on
2353          * this struct, go ahead and have it removed.
2354          */
2355         return (TRUE);
2356 }
2357 
2358 static bool_t
2359 rfs4_lockowner_create(rfs4_entry_t u_entry, void *arg)
2360 {
2361         rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2362         lock_owner4 *lockowner = (lock_owner4 *)arg;
2363         rfs4_client_t *cp;
2364         bool_t create = FALSE;
2365         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2366 
2367         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2368 
2369         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2370             &lockowner->clientid,
2371             &create, NULL, RFS4_DBS_VALID);
2372 
2373         rw_exit(&nsrv4->rfs4_findclient_lock);
2374 
2375         if (cp == NULL)
2376                 return (FALSE);
2377 
2378         /* Reference client */
2379         lo->rl_client = cp;
2380         lo->rl_owner.clientid = lockowner->clientid;
2381         lo->rl_owner.owner_val = kmem_alloc(lockowner->owner_len, KM_SLEEP);
2382         bcopy(lockowner->owner_val, lo->rl_owner.owner_val,
2383             lockowner->owner_len);
2384         lo->rl_owner.owner_len = lockowner->owner_len;
2385         lo->rl_pid = rfs4_dbe_getid(lo->rl_dbe);
2386 
2387         return (TRUE);
2388 }
2389 
2390 rfs4_lockowner_t *
2391 rfs4_findlockowner(lock_owner4 *lockowner, bool_t *create)
2392 {
2393         rfs4_lockowner_t *lo;
2394         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2395 
2396         /* CSTYLED */
2397         lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_idx, lockowner,
2398             create, lockowner, RFS4_DBS_VALID);
2399 
2400         return (lo);
2401 }
2402 
2403 rfs4_lockowner_t *
2404 rfs4_findlockowner_by_pid(pid_t pid)
2405 {
2406         rfs4_lockowner_t *lo;
2407         bool_t create = FALSE;
2408         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2409 
2410         lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_pid_idx,
2411             (void *)(uintptr_t)pid, &create, NULL, RFS4_DBS_VALID);
2412 
2413         return (lo);
2414 }
2415 
2416 
2417 static uint32_t
2418 file_hash(void *key)
2419 {
2420         return (ADDRHASH(key));
2421 }
2422 
2423 static void *
2424 file_mkkey(rfs4_entry_t u_entry)
2425 {
2426         rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2427 
2428         return (fp->rf_vp);
 
2501 
2502         mutex_init(fp->rf_dinfo.rd_recall_lock, NULL, MUTEX_DEFAULT, NULL);
2503         cv_init(fp->rf_dinfo.rd_recall_cv, NULL, CV_DEFAULT, NULL);
2504 
2505         fp->rf_dinfo.rd_dtype = OPEN_DELEGATE_NONE;
2506 
2507         rw_init(&fp->rf_file_rwlock, NULL, RW_DEFAULT, NULL);
2508 
2509         mutex_enter(&vp->v_vsd_lock);
2510         VERIFY(vsd_set(vp, nfs4_srv_vkey, (void *)fp) == 0);
2511         mutex_exit(&vp->v_vsd_lock);
2512 
2513         return (TRUE);
2514 }
2515 
2516 rfs4_file_t *
2517 rfs4_findfile(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2518 {
2519         rfs4_file_t *fp;
2520         rfs4_fcreate_arg arg;
2521         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2522 
2523         arg.vp = vp;
2524         arg.fh = fh;
2525 
2526         if (*create == TRUE)
2527                 /* CSTYLED */
2528                 fp = (rfs4_file_t *)rfs4_dbsearch(nsrv4->rfs4_file_idx, vp, create,
2529                     &arg, RFS4_DBS_VALID);
2530         else {
2531                 mutex_enter(&vp->v_vsd_lock);
2532                 fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2533                 if (fp) {
2534                         rfs4_dbe_lock(fp->rf_dbe);
2535                         if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2536                             (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2537                                 rfs4_dbe_unlock(fp->rf_dbe);
2538                                 fp = NULL;
2539                         } else {
2540                                 rfs4_dbe_hold(fp->rf_dbe);
2541                                 rfs4_dbe_unlock(fp->rf_dbe);
 
2543                 }
2544                 mutex_exit(&vp->v_vsd_lock);
2545         }
2546         return (fp);
2547 }
2548 
2549 /*
2550  * Find a file in the db and once it is located, take the rw lock.
2551  * Need to check the vnode pointer and if it does not exist (it was
2552  * removed between the db location and check) redo the find.  This
2553  * assumes that a file struct that has a NULL vnode pointer is marked
2554  * at 'invalid' and will not be found in the db the second time
2555  * around.
2556  */
2557 rfs4_file_t *
2558 rfs4_findfile_withlock(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2559 {
2560         rfs4_file_t *fp;
2561         rfs4_fcreate_arg arg;
2562         bool_t screate = *create;
2563         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2564 
2565         if (screate == FALSE) {
2566                 mutex_enter(&vp->v_vsd_lock);
2567                 fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2568                 if (fp) {
2569                         rfs4_dbe_lock(fp->rf_dbe);
2570                         if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2571                             (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2572                                 rfs4_dbe_unlock(fp->rf_dbe);
2573                                 mutex_exit(&vp->v_vsd_lock);
2574                                 fp = NULL;
2575                         } else {
2576                                 rfs4_dbe_hold(fp->rf_dbe);
2577                                 rfs4_dbe_unlock(fp->rf_dbe);
2578                                 mutex_exit(&vp->v_vsd_lock);
2579                                 rw_enter(&fp->rf_file_rwlock, RW_WRITER);
2580                                 if (fp->rf_vp == NULL) {
2581                                         rw_exit(&fp->rf_file_rwlock);
2582                                         rfs4_file_rele(fp);
2583                                         fp = NULL;
 
2730         list_insert_tail(&sp->rs_lostatelist, lsp);
2731         rfs4_dbe_hold(sp->rs_dbe);
2732         rfs4_dbe_unlock(sp->rs_dbe);
2733 
2734         return (TRUE);
2735 }
2736 
2737 void
2738 rfs4_lo_state_rele(rfs4_lo_state_t *lsp, bool_t unlock_fp)
2739 {
2740         if (unlock_fp == TRUE)
2741                 rw_exit(&lsp->rls_state->rs_finfo->rf_file_rwlock);
2742         rfs4_dbe_rele(lsp->rls_dbe);
2743 }
2744 
2745 static rfs4_lo_state_t *
2746 rfs4_findlo_state(stateid_t *id, bool_t lock_fp)
2747 {
2748         rfs4_lo_state_t *lsp;
2749         bool_t create = FALSE;
2750         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2751 
2752         lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_idx, id,
2753             &create, NULL, RFS4_DBS_VALID);
2754         if (lock_fp == TRUE && lsp != NULL)
2755                 rw_enter(&lsp->rls_state->rs_finfo->rf_file_rwlock, RW_READER);
2756 
2757         return (lsp);
2758 }
2759 
2760 
2761 static uint32_t
2762 lo_state_lo_hash(void *key)
2763 {
2764         rfs4_lo_state_t *lsp = key;
2765 
2766         return (ADDRHASH(lsp->rls_locker) ^ ADDRHASH(lsp->rls_state));
2767 }
2768 
2769 static bool_t
2770 lo_state_lo_compare(rfs4_entry_t u_entry, void *key)
2771 {
2772         rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2773         rfs4_lo_state_t *keyp = key;
2774 
2775         return (keyp->rls_locker == lsp->rls_locker &&
2776             keyp->rls_state == lsp->rls_state);
2777 }
2778 
2779 static void *
2780 lo_state_lo_mkkey(rfs4_entry_t u_entry)
2781 {
2782         return (u_entry);
2783 }
2784 
2785 rfs4_lo_state_t *
2786 rfs4_findlo_state_by_owner(rfs4_lockowner_t *lo, rfs4_state_t *sp,
2787     bool_t *create)
2788 {
2789         rfs4_lo_state_t *lsp;
2790         rfs4_lo_state_t arg;
2791         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2792 
2793         arg.rls_locker = lo;
2794         arg.rls_state = sp;
2795 
2796         lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_owner_idx,
2797             &arg, create, &arg, RFS4_DBS_VALID);
2798 
2799         return (lsp);
2800 }
2801 
2802 static stateid_t
2803 get_stateid(id_t eid)
2804 {
2805         stateid_t id;
2806         nfs4_srv_t *nsrv4;
2807 
2808         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2809 
2810         id.bits.boottime = nsrv4->rfs4_start_time;
2811         id.bits.ident = eid;
2812         id.bits.chgseq = 0;
2813         id.bits.type = 0;
2814         id.bits.pid = 0;
2815 
2816         /*
2817          * If we are booted as a cluster node, embed our nodeid.
2818          * We've already done sanity checks in rfs4_client_create() so no
2819          * need to repeat them here.
2820          */
2821         id.bits.clnodeid = (cluster_bootflags & CLUSTER_BOOTED) ?
2822             clconf_get_nodeid() : 0;
2823 
2824         return (id);
2825 }
2826 
2827 /*
2828  * For use only when booted as a cluster node.
 
3046 rfs4_deleg_state_destroy(rfs4_entry_t u_entry)
3047 {
3048         rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
3049 
3050         /* return delegation if necessary */
3051         rfs4_return_deleg(dsp, FALSE);
3052 
3053         /* Were done with the file */
3054         rfs4_file_rele(dsp->rds_finfo);
3055         dsp->rds_finfo = NULL;
3056 
3057         /* And now with the openowner */
3058         rfs4_client_rele(dsp->rds_client);
3059         dsp->rds_client = NULL;
3060 }
3061 
3062 rfs4_deleg_state_t *
3063 rfs4_finddeleg(rfs4_state_t *sp, bool_t *create)
3064 {
3065         rfs4_deleg_state_t ds, *dsp;
3066         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3067 
3068         ds.rds_client = sp->rs_owner->ro_client;
3069         ds.rds_finfo = sp->rs_finfo;
3070 
3071         dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_idx, &ds,
3072             create, &ds, RFS4_DBS_VALID);
3073 
3074         return (dsp);
3075 }
3076 
3077 rfs4_deleg_state_t *
3078 rfs4_finddelegstate(stateid_t *id)
3079 {
3080         rfs4_deleg_state_t *dsp;
3081         bool_t create = FALSE;
3082         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3083 
3084         dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_state_idx,
3085             id, &create, NULL, RFS4_DBS_VALID);
3086 
3087         return (dsp);
3088 }
3089 
3090 void
3091 rfs4_deleg_state_rele(rfs4_deleg_state_t *dsp)
3092 {
3093         rfs4_dbe_rele(dsp->rds_dbe);
3094 }
3095 
3096 void
3097 rfs4_update_lock_sequence(rfs4_lo_state_t *lsp)
3098 {
3099 
3100         rfs4_dbe_lock(lsp->rls_dbe);
3101 
3102         /*
 
3184         if (sp->rs_closed == TRUE)
3185                 return (FALSE);
3186 
3187         return (fp == sp->rs_finfo);
3188 }
3189 
3190 static void *
3191 state_file_mkkey(rfs4_entry_t u_entry)
3192 {
3193         rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3194 
3195         return (sp->rs_finfo);
3196 }
3197 
3198 rfs4_state_t *
3199 rfs4_findstate_by_owner_file(rfs4_openowner_t *oo, rfs4_file_t *fp,
3200     bool_t *create)
3201 {
3202         rfs4_state_t *sp;
3203         rfs4_state_t key;
3204         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3205 
3206         key.rs_owner = oo;
3207         key.rs_finfo = fp;
3208 
3209         sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_owner_file_idx,
3210             &key, create, &key, RFS4_DBS_VALID);
3211 
3212         return (sp);
3213 }
3214 
3215 /* This returns ANY state struct that refers to this file */
3216 static rfs4_state_t *
3217 rfs4_findstate_by_file(rfs4_file_t *fp)
3218 {
3219         bool_t create = FALSE;
3220         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3221 
3222         return ((rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_file_idx, fp,
3223             &create, fp, RFS4_DBS_VALID));
3224 }
3225 
3226 static bool_t
3227 rfs4_state_expiry(rfs4_entry_t u_entry)
3228 {
3229         rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3230 
3231         if (rfs4_dbe_is_invalid(sp->rs_dbe))
3232                 return (TRUE);
3233 
3234         if (sp->rs_closed == TRUE &&
3235             ((gethrestime_sec() - rfs4_dbe_get_timerele(sp->rs_dbe))
3236             > rfs4_lease_time))
3237                 return (TRUE);
3238 
3239         return ((gethrestime_sec() - sp->rs_owner->ro_client->rc_last_access
3240             > rfs4_lease_time));
 
3253         sp->rs_stateid.bits.type = OPENID;
3254         sp->rs_owner = oo;
3255         sp->rs_finfo = fp;
3256 
3257         list_create(&sp->rs_lostatelist, sizeof (rfs4_lo_state_t),
3258             offsetof(rfs4_lo_state_t, rls_node));
3259 
3260         /* Insert state on per open owner's list */
3261         rfs4_dbe_lock(oo->ro_dbe);
3262         list_insert_tail(&oo->ro_statelist, sp);
3263         rfs4_dbe_unlock(oo->ro_dbe);
3264 
3265         return (TRUE);
3266 }
3267 
3268 static rfs4_state_t *
3269 rfs4_findstate(stateid_t *id, rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
3270 {
3271         rfs4_state_t *sp;
3272         bool_t create = FALSE;
3273         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3274 
3275         sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_idx, id,
3276             &create, NULL, find_invalid);
3277         if (lock_fp == TRUE && sp != NULL)
3278                 rw_enter(&sp->rs_finfo->rf_file_rwlock, RW_READER);
3279 
3280         return (sp);
3281 }
3282 
3283 void
3284 rfs4_state_close(rfs4_state_t *sp, bool_t lock_held, bool_t close_of_client,
3285     cred_t *cr)
3286 {
3287         /* Remove the associated lo_state owners */
3288         if (!lock_held)
3289                 rfs4_dbe_lock(sp->rs_dbe);
3290 
3291         /*
3292          * If refcnt == 0, the dbe is about to be destroyed.
3293          * lock state will be released by the reaper thread.
 
3325 void
3326 rfs4_client_close(rfs4_client_t *cp)
3327 {
3328         /* Mark client as going away. */
3329         rfs4_dbe_lock(cp->rc_dbe);
3330         rfs4_dbe_invalidate(cp->rc_dbe);
3331         rfs4_dbe_unlock(cp->rc_dbe);
3332 
3333         rfs4_client_state_remove(cp);
3334 
3335         /* Release the client */
3336         rfs4_client_rele(cp);
3337 }
3338 
3339 nfsstat4
3340 rfs4_check_clientid(clientid4 *cp, int setclid_confirm)
3341 {
3342         cid *cidp = (cid *) cp;
3343         nfs4_srv_t *nsrv4;
3344 
3345         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3346 
3347         /*
3348          * If we are booted as a cluster node, check the embedded nodeid.
3349          * If it indicates that this clientid was generated on another node,
3350          * inform the client accordingly.
3351          */
3352         if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
3353                 return (NFS4ERR_STALE_CLIENTID);
3354 
3355         /*
3356          * If the server start time matches the time provided
3357          * by the client (via the clientid) and this is NOT a
3358          * setclientid_confirm then return EXPIRED.
3359          */
3360         if (!setclid_confirm &&
3361             cidp->impl_id.start_time == nsrv4->rfs4_start_time)
3362                 return (NFS4ERR_EXPIRED);
3363 
3364         return (NFS4ERR_STALE_CLIENTID);
3365 }
3366 
3367 /*
3368  * This is used when a stateid has not been found amongst the
3369  * current server's state.  Check the stateid to see if it
3370  * was from this server instantiation or not.
3371  */
3372 static nfsstat4
3373 what_stateid_error(stateid_t *id, stateid_type_t type)
3374 {
3375         nfs4_srv_t *nsrv4;
3376 
3377         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3378 
3379         /* If we are booted as a cluster node, was stateid locally generated? */
3380         if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3381                 return (NFS4ERR_STALE_STATEID);
3382 
3383         /* If types don't match then no use checking further */
3384         if (type != id->bits.type)
3385                 return (NFS4ERR_BAD_STATEID);
3386 
3387         /* From a different server instantiation, return STALE */
3388         if (id->bits.boottime != nsrv4->rfs4_start_time)
3389                 return (NFS4ERR_STALE_STATEID);
3390 
3391         /*
3392          * From this server but the state is most likely beyond lease
3393          * timeout: return NFS4ERR_EXPIRED.  However, there is the
3394          * case of a delegation stateid.  For delegations, there is a
3395          * case where the state can be removed without the client's
3396          * knowledge/consent: revocation.  In the case of delegation
3397          * revocation, the delegation state will be removed and will
 
4091                             OPEN_DELEGATE_WRITE) {
4092                                 (void) fem_uninstall(vp, deleg_wrops,
4093                                     (void *)fp);
4094                                 vn_open_downgrade(vp, FREAD|FWRITE);
4095                         }
4096                         mutex_enter(&vp->v_vsd_lock);
4097                         (void) vsd_set(vp, nfs4_srv_vkey, NULL);
4098                         mutex_exit(&vp->v_vsd_lock);
4099                         VN_RELE(vp);
4100                         fp->rf_vp = NULL;
4101                 }
4102                 rfs4_dbe_invalidate(fp->rf_dbe);
4103         }
4104 }
4105 
4106 /*
4107  * Given a directory that is being unexported, cleanup/release all
4108  * state in the server that refers to objects residing underneath this
4109  * particular export.  The ordering of the release is important.
4110  * Lock_owner, then state and then file.
4111  */
4112 void
4113 rfs4_clean_state_exi(struct exportinfo *exi)
4114 {
4115         nfs4_srv_t *nsrv4;
4116 
4117         /* curzone mightn't be exi_zone, so use exi_zone instead. */
4118         ASSERT(exi->exi_zone == curzone || curzone == global_zone);
4119         nsrv4 = zone_getspecific(rfs4_zone_key, exi->exi_zone);
4120         if (nsrv4 == NULL) /* NOTE: NFSv4 cleanup MAY have already happened. */
4121                 return;
4122         mutex_enter(&nsrv4->state_lock);
4123 
4124         if (nsrv4->nfs4_server_state == NULL) {
4125                 mutex_exit(&nsrv4->state_lock);
4126                 return;
4127         }
4128 
4129         /* CSTYLED */
4130         rfs4_dbe_walk(nsrv4->rfs4_lo_state_tab, rfs4_lo_state_walk_callout, exi);
4131         rfs4_dbe_walk(nsrv4->rfs4_state_tab, rfs4_state_walk_callout, exi);
4132         /* CSTYLED */
4133         rfs4_dbe_walk(nsrv4->rfs4_deleg_state_tab, rfs4_deleg_state_walk_callout, exi);
4134         rfs4_dbe_walk(nsrv4->rfs4_file_tab, rfs4_file_walk_callout, exi);
4135 
4136         mutex_exit(&nsrv4->state_lock);
4137 }
 | 
 
 
1116                  */
1117                 if (ent_sin->sin_addr.s_addr == clr_in.s_addr) {
1118                         cp->rc_forced_expire = 1;
1119                 }
1120                 break;
1121 
1122         default:
1123                 /* force this assert to fail */
1124                 ASSERT(clr->addr_type != clr->addr_type);
1125         }
1126 }
1127 
1128 /*
1129  * This is called from nfssys() in order to clear server state
1130  * for the specified client IP Address.
1131  */
1132 void
1133 rfs4_clear_client_state(struct nfs4clrst_args *clr)
1134 {
1135         nfs4_srv_t *nsrv4;
1136         nsrv4 = nfs4_get_srv();
1137         (void) rfs4_dbe_walk(nsrv4->rfs4_client_tab, rfs4_client_scrub, clr);
1138 }
1139 
1140 /*
1141  * Used to initialize the NFSv4 server's state or database.  All of
1142  * the tables are created and timers are set.
1143  */
1144 void
1145 rfs4_state_g_init()
1146 {
1147         extern boolean_t rfs4_cpr_callb(void *, int);
1148         /*
1149          * Add a CPR callback so that we can update client
1150          * access times to extend the lease after a suspend
1151          * and resume (using the same class as rpcmod/connmgr)
1152          */
1153         cpr_id = callb_add(rfs4_cpr_callb, 0, CB_CL_CPR_RPC, "rfs4");
1154 
1155         /*
1156          * NFSv4 server state databases
 
1475             deleg_state_compare,
1476             deleg_state_mkkey, FALSE);
1477 
1478         mutex_exit(&nsrv4->state_lock);
1479 
1480         /*
1481          * Init the stable storage.
1482          */
1483         rfs4_ss_init(nsrv4);
1484 }
1485 
1486 /*
1487  * Used at server shutdown to cleanup all of NFSv4 server's zone structures
1488  * and state.
1489  */
1490 void
1491 rfs4_state_zone_fini()
1492 {
1493         rfs4_database_t *dbp;
1494         nfs4_srv_t *nsrv4;
1495         nsrv4 = nfs4_get_srv();
1496 
1497         rfs4_set_deleg_policy(nsrv4, SRV_NEVER_DELEGATE);
1498 
1499         /*
1500          * Clean up any dangling stable storage structures BEFORE calling
1501          * rfs4_servinst_destroy_all() so there are no dangling structures
1502          * (i.e. the srvinsts are all cleared of danglers BEFORE they get
1503          * freed).
1504          */
1505         rfs4_ss_fini(nsrv4);
1506 
1507         mutex_enter(&nsrv4->state_lock);
1508 
1509         if (nsrv4->nfs4_server_state == NULL) {
1510                 mutex_exit(&nsrv4->state_lock);
1511                 return;
1512         }
1513 
1514         /* destroy server instances and current instance ptr */
1515         rfs4_servinst_destroy_all(nsrv4);
 
1651                 cp->rc_ss_remove = 1;
1652         return (cp_expired);
1653 }
1654 
1655 /*
1656  * Remove the leaf file from all distributed stable storage paths.
1657  */
1658 static void
1659 rfs4_dss_remove_cpleaf(rfs4_client_t *cp)
1660 {
1661         nfs4_srv_t *nsrv4;
1662         rfs4_servinst_t *sip;
1663         char *leaf = cp->rc_ss_pn->leaf;
1664 
1665         /*
1666          * since the state files are written to all DSS
1667          * paths we must remove this leaf file instance
1668          * from all server instances.
1669          */
1670 
1671         nsrv4 = nfs4_get_srv();
1672         mutex_enter(&nsrv4->servinst_lock);
1673         for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
1674                 /* remove the leaf file associated with this server instance */
1675                 rfs4_dss_remove_leaf(sip, NFS4_DSS_STATE_LEAF, leaf);
1676         }
1677         mutex_exit(&nsrv4->servinst_lock);
1678 }
1679 
1680 static void
1681 rfs4_dss_remove_leaf(rfs4_servinst_t *sip, char *dir_leaf, char *leaf)
1682 {
1683         int i, npaths = sip->dss_npaths;
1684 
1685         for (i = 0; i < npaths; i++) {
1686                 rfs4_dss_path_t *dss_path = sip->dss_paths[i];
1687                 char *path, *dir;
1688                 size_t pathlen;
1689 
1690                 /* the HA-NFSv4 path might have been failed-over away from us */
1691                 if (dss_path == NULL)
 
1727                 rfs4_ss_pnfree(cp->rc_ss_pn);
1728         }
1729 
1730         /* Free the client supplied client id */
1731         kmem_free(cp->rc_nfs_client.id_val, cp->rc_nfs_client.id_len);
1732 
1733         if (cp->rc_sysidt != LM_NOSYSID)
1734                 lm_free_sysidt(cp->rc_sysidt);
1735 }
1736 
1737 static bool_t
1738 rfs4_client_create(rfs4_entry_t u_entry, void *arg)
1739 {
1740         rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1741         nfs_client_id4 *client = (nfs_client_id4 *)arg;
1742         struct sockaddr *ca;
1743         cid *cidp;
1744         scid_confirm_verf *scvp;
1745         nfs4_srv_t *nsrv4;
1746 
1747         nsrv4 = nfs4_get_srv();
1748 
1749         /* Get a clientid to give to the client */
1750         cidp = (cid *)&cp->rc_clientid;
1751         cidp->impl_id.start_time = nsrv4->rfs4_start_time;
1752         cidp->impl_id.c_id = (uint32_t)rfs4_dbe_getid(cp->rc_dbe);
1753 
1754         /* If we are booted as a cluster node, embed our nodeid */
1755         if (cluster_bootflags & CLUSTER_BOOTED)
1756                 embed_nodeid(cidp);
1757 
1758         /* Allocate and copy client's client id value */
1759         cp->rc_nfs_client.id_val = kmem_alloc(client->id_len, KM_SLEEP);
1760         cp->rc_nfs_client.id_len = client->id_len;
1761         bcopy(client->id_val, cp->rc_nfs_client.id_val, client->id_len);
1762         cp->rc_nfs_client.verifier = client->verifier;
1763 
1764         /* Copy client's IP address */
1765         ca = client->cl_addr;
1766         if (ca->sa_family == AF_INET)
1767                 bcopy(ca, &cp->rc_addr, sizeof (struct sockaddr_in));
 
1821 rfs4_client_scv_next(rfs4_client_t *cp)
1822 {
1823         scid_confirm_verf *scvp;
1824 
1825         /* Init the value for the SETCLIENTID_CONFIRM verifier */
1826         scvp = (scid_confirm_verf *)&cp->rc_confirm_verf;
1827         scvp->cv_impl.gen_num++;
1828 }
1829 
1830 void
1831 rfs4_client_rele(rfs4_client_t *cp)
1832 {
1833         rfs4_dbe_rele(cp->rc_dbe);
1834 }
1835 
1836 rfs4_client_t *
1837 rfs4_findclient(nfs_client_id4 *client, bool_t *create, rfs4_client_t *oldcp)
1838 {
1839         rfs4_client_t *cp;
1840         nfs4_srv_t *nsrv4;
1841         nsrv4 = nfs4_get_srv();
1842 
1843 
1844         if (oldcp) {
1845                 rw_enter(&nsrv4->rfs4_findclient_lock, RW_WRITER);
1846                 rfs4_dbe_hide(oldcp->rc_dbe);
1847         } else {
1848                 rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1849         }
1850 
1851         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_nfsclnt_idx, client,
1852             create, (void *)client, RFS4_DBS_VALID);
1853 
1854         if (oldcp)
1855                 rfs4_dbe_unhide(oldcp->rc_dbe);
1856 
1857         rw_exit(&nsrv4->rfs4_findclient_lock);
1858 
1859         return (cp);
1860 }
1861 
1862 rfs4_client_t *
1863 rfs4_findclient_by_id(clientid4 clientid, bool_t find_unconfirmed)
1864 {
1865         rfs4_client_t *cp;
1866         bool_t create = FALSE;
1867         cid *cidp = (cid *)&clientid;
1868         nfs4_srv_t *nsrv4 = nfs4_get_srv();
1869 
1870         /* If we're a cluster and the nodeid isn't right, short-circuit */
1871         if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
1872                 return (NULL);
1873 
1874         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1875 
1876         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx, &clientid,
1877             &create, NULL, RFS4_DBS_VALID);
1878 
1879         rw_exit(&nsrv4->rfs4_findclient_lock);
1880 
1881         if (cp && cp->rc_need_confirm && find_unconfirmed == FALSE) {
1882                 rfs4_client_rele(cp);
1883                 return (NULL);
1884         } else {
1885                 return (cp);
1886         }
1887 }
1888 
 
1969         struct sockaddr *ca = (struct sockaddr *)arg;
1970 
1971         /* Copy client's IP address */
1972         if (ca->sa_family == AF_INET)
1973                 bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in));
1974         else if (ca->sa_family == AF_INET6)
1975                 bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in6));
1976         else
1977                 return (FALSE);
1978         cp->ri_no_referrals = 1;
1979 
1980         return (TRUE);
1981 }
1982 
1983 rfs4_clntip_t *
1984 rfs4_find_clntip(struct sockaddr *addr, bool_t *create)
1985 {
1986         rfs4_clntip_t *cp;
1987         nfs4_srv_t *nsrv4;
1988 
1989         nsrv4 = nfs4_get_srv();
1990 
1991         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1992 
1993         cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
1994             create, addr, RFS4_DBS_VALID);
1995 
1996         rw_exit(&nsrv4->rfs4_findclient_lock);
1997 
1998         return (cp);
1999 }
2000 
2001 void
2002 rfs4_invalidate_clntip(struct sockaddr *addr)
2003 {
2004         rfs4_clntip_t *cp;
2005         bool_t create = FALSE;
2006         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2007 
2008         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2009 
2010         cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
2011             &create, NULL, RFS4_DBS_VALID);
2012         if (cp == NULL) {
2013                 rw_exit(&nsrv4->rfs4_findclient_lock);
2014                 return;
2015         }
2016         rfs4_dbe_invalidate(cp->ri_dbe);
2017         rfs4_dbe_rele(cp->ri_dbe);
2018 
2019         rw_exit(&nsrv4->rfs4_findclient_lock);
2020 }
2021 
2022 bool_t
2023 rfs4_lease_expired(rfs4_client_t *cp)
2024 {
2025         bool_t rc;
2026 
 
2147 
2148         /* Free the lock owner id */
2149         kmem_free(oo->ro_owner.owner_val, oo->ro_owner.owner_len);
2150 }
2151 
2152 void
2153 rfs4_openowner_rele(rfs4_openowner_t *oo)
2154 {
2155         rfs4_dbe_rele(oo->ro_dbe);
2156 }
2157 
2158 static bool_t
2159 rfs4_openowner_create(rfs4_entry_t u_entry, void *arg)
2160 {
2161         rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2162         rfs4_openowner_t *argp = (rfs4_openowner_t *)arg;
2163         open_owner4 *openowner = &argp->ro_owner;
2164         seqid4 seqid = argp->ro_open_seqid;
2165         rfs4_client_t *cp;
2166         bool_t create = FALSE;
2167         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2168 
2169         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2170 
2171         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2172             &openowner->clientid,
2173             &create, NULL, RFS4_DBS_VALID);
2174 
2175         rw_exit(&nsrv4->rfs4_findclient_lock);
2176 
2177         if (cp == NULL)
2178                 return (FALSE);
2179 
2180         oo->ro_reply_fh.nfs_fh4_len = 0;
2181         oo->ro_reply_fh.nfs_fh4_val = NULL;
2182 
2183         oo->ro_owner.clientid = openowner->clientid;
2184         oo->ro_owner.owner_val =
2185             kmem_alloc(openowner->owner_len, KM_SLEEP);
2186 
2187         bcopy(openowner->owner_val,
 
2197         bzero(&oo->ro_reply, sizeof (nfs_resop4));
2198         oo->ro_client = cp;
2199         oo->ro_cr_set = NULL;
2200 
2201         list_create(&oo->ro_statelist, sizeof (rfs4_state_t),
2202             offsetof(rfs4_state_t, rs_node));
2203 
2204         /* Insert openowner into client's open owner list */
2205         rfs4_dbe_lock(cp->rc_dbe);
2206         list_insert_tail(&cp->rc_openownerlist, oo);
2207         rfs4_dbe_unlock(cp->rc_dbe);
2208 
2209         return (TRUE);
2210 }
2211 
2212 rfs4_openowner_t *
2213 rfs4_findopenowner(open_owner4 *openowner, bool_t *create, seqid4 seqid)
2214 {
2215         rfs4_openowner_t *oo;
2216         rfs4_openowner_t arg;
2217         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2218 
2219         arg.ro_owner = *openowner;
2220         arg.ro_open_seqid = seqid;
2221         /* CSTYLED */
2222         oo = (rfs4_openowner_t *)rfs4_dbsearch(nsrv4->rfs4_openowner_idx, openowner,
2223             create, &arg, RFS4_DBS_VALID);
2224 
2225         return (oo);
2226 }
2227 
2228 void
2229 rfs4_update_open_sequence(rfs4_openowner_t *oo)
2230 {
2231 
2232         rfs4_dbe_lock(oo->ro_dbe);
2233 
2234         oo->ro_open_seqid++;
2235 
2236         rfs4_dbe_unlock(oo->ro_dbe);
2237 }
 
2345 }
2346 
2347 /* ARGSUSED */
2348 static bool_t
2349 rfs4_lockowner_expiry(rfs4_entry_t u_entry)
2350 {
2351         /*
2352          * Since expiry is called with no other references on
2353          * this struct, go ahead and have it removed.
2354          */
2355         return (TRUE);
2356 }
2357 
2358 static bool_t
2359 rfs4_lockowner_create(rfs4_entry_t u_entry, void *arg)
2360 {
2361         rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2362         lock_owner4 *lockowner = (lock_owner4 *)arg;
2363         rfs4_client_t *cp;
2364         bool_t create = FALSE;
2365         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2366 
2367         rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2368 
2369         cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2370             &lockowner->clientid,
2371             &create, NULL, RFS4_DBS_VALID);
2372 
2373         rw_exit(&nsrv4->rfs4_findclient_lock);
2374 
2375         if (cp == NULL)
2376                 return (FALSE);
2377 
2378         /* Reference client */
2379         lo->rl_client = cp;
2380         lo->rl_owner.clientid = lockowner->clientid;
2381         lo->rl_owner.owner_val = kmem_alloc(lockowner->owner_len, KM_SLEEP);
2382         bcopy(lockowner->owner_val, lo->rl_owner.owner_val,
2383             lockowner->owner_len);
2384         lo->rl_owner.owner_len = lockowner->owner_len;
2385         lo->rl_pid = rfs4_dbe_getid(lo->rl_dbe);
2386 
2387         return (TRUE);
2388 }
2389 
2390 rfs4_lockowner_t *
2391 rfs4_findlockowner(lock_owner4 *lockowner, bool_t *create)
2392 {
2393         rfs4_lockowner_t *lo;
2394         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2395 
2396         /* CSTYLED */
2397         lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_idx, lockowner,
2398             create, lockowner, RFS4_DBS_VALID);
2399 
2400         return (lo);
2401 }
2402 
2403 rfs4_lockowner_t *
2404 rfs4_findlockowner_by_pid(pid_t pid)
2405 {
2406         rfs4_lockowner_t *lo;
2407         bool_t create = FALSE;
2408         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2409 
2410         lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_pid_idx,
2411             (void *)(uintptr_t)pid, &create, NULL, RFS4_DBS_VALID);
2412 
2413         return (lo);
2414 }
2415 
2416 
2417 static uint32_t
2418 file_hash(void *key)
2419 {
2420         return (ADDRHASH(key));
2421 }
2422 
2423 static void *
2424 file_mkkey(rfs4_entry_t u_entry)
2425 {
2426         rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2427 
2428         return (fp->rf_vp);
 
2501 
2502         mutex_init(fp->rf_dinfo.rd_recall_lock, NULL, MUTEX_DEFAULT, NULL);
2503         cv_init(fp->rf_dinfo.rd_recall_cv, NULL, CV_DEFAULT, NULL);
2504 
2505         fp->rf_dinfo.rd_dtype = OPEN_DELEGATE_NONE;
2506 
2507         rw_init(&fp->rf_file_rwlock, NULL, RW_DEFAULT, NULL);
2508 
2509         mutex_enter(&vp->v_vsd_lock);
2510         VERIFY(vsd_set(vp, nfs4_srv_vkey, (void *)fp) == 0);
2511         mutex_exit(&vp->v_vsd_lock);
2512 
2513         return (TRUE);
2514 }
2515 
2516 rfs4_file_t *
2517 rfs4_findfile(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2518 {
2519         rfs4_file_t *fp;
2520         rfs4_fcreate_arg arg;
2521         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2522 
2523         arg.vp = vp;
2524         arg.fh = fh;
2525 
2526         if (*create == TRUE)
2527                 /* CSTYLED */
2528                 fp = (rfs4_file_t *)rfs4_dbsearch(nsrv4->rfs4_file_idx, vp, create,
2529                     &arg, RFS4_DBS_VALID);
2530         else {
2531                 mutex_enter(&vp->v_vsd_lock);
2532                 fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2533                 if (fp) {
2534                         rfs4_dbe_lock(fp->rf_dbe);
2535                         if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2536                             (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2537                                 rfs4_dbe_unlock(fp->rf_dbe);
2538                                 fp = NULL;
2539                         } else {
2540                                 rfs4_dbe_hold(fp->rf_dbe);
2541                                 rfs4_dbe_unlock(fp->rf_dbe);
 
2543                 }
2544                 mutex_exit(&vp->v_vsd_lock);
2545         }
2546         return (fp);
2547 }
2548 
2549 /*
2550  * Find a file in the db and once it is located, take the rw lock.
2551  * Need to check the vnode pointer and if it does not exist (it was
2552  * removed between the db location and check) redo the find.  This
2553  * assumes that a file struct that has a NULL vnode pointer is marked
2554  * at 'invalid' and will not be found in the db the second time
2555  * around.
2556  */
2557 rfs4_file_t *
2558 rfs4_findfile_withlock(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2559 {
2560         rfs4_file_t *fp;
2561         rfs4_fcreate_arg arg;
2562         bool_t screate = *create;
2563         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2564 
2565         if (screate == FALSE) {
2566                 mutex_enter(&vp->v_vsd_lock);
2567                 fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2568                 if (fp) {
2569                         rfs4_dbe_lock(fp->rf_dbe);
2570                         if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2571                             (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2572                                 rfs4_dbe_unlock(fp->rf_dbe);
2573                                 mutex_exit(&vp->v_vsd_lock);
2574                                 fp = NULL;
2575                         } else {
2576                                 rfs4_dbe_hold(fp->rf_dbe);
2577                                 rfs4_dbe_unlock(fp->rf_dbe);
2578                                 mutex_exit(&vp->v_vsd_lock);
2579                                 rw_enter(&fp->rf_file_rwlock, RW_WRITER);
2580                                 if (fp->rf_vp == NULL) {
2581                                         rw_exit(&fp->rf_file_rwlock);
2582                                         rfs4_file_rele(fp);
2583                                         fp = NULL;
 
2730         list_insert_tail(&sp->rs_lostatelist, lsp);
2731         rfs4_dbe_hold(sp->rs_dbe);
2732         rfs4_dbe_unlock(sp->rs_dbe);
2733 
2734         return (TRUE);
2735 }
2736 
2737 void
2738 rfs4_lo_state_rele(rfs4_lo_state_t *lsp, bool_t unlock_fp)
2739 {
2740         if (unlock_fp == TRUE)
2741                 rw_exit(&lsp->rls_state->rs_finfo->rf_file_rwlock);
2742         rfs4_dbe_rele(lsp->rls_dbe);
2743 }
2744 
2745 static rfs4_lo_state_t *
2746 rfs4_findlo_state(stateid_t *id, bool_t lock_fp)
2747 {
2748         rfs4_lo_state_t *lsp;
2749         bool_t create = FALSE;
2750         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2751 
2752         lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_idx, id,
2753             &create, NULL, RFS4_DBS_VALID);
2754         if (lock_fp == TRUE && lsp != NULL)
2755                 rw_enter(&lsp->rls_state->rs_finfo->rf_file_rwlock, RW_READER);
2756 
2757         return (lsp);
2758 }
2759 
2760 
2761 static uint32_t
2762 lo_state_lo_hash(void *key)
2763 {
2764         rfs4_lo_state_t *lsp = key;
2765 
2766         return (ADDRHASH(lsp->rls_locker) ^ ADDRHASH(lsp->rls_state));
2767 }
2768 
2769 static bool_t
2770 lo_state_lo_compare(rfs4_entry_t u_entry, void *key)
2771 {
2772         rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2773         rfs4_lo_state_t *keyp = key;
2774 
2775         return (keyp->rls_locker == lsp->rls_locker &&
2776             keyp->rls_state == lsp->rls_state);
2777 }
2778 
2779 static void *
2780 lo_state_lo_mkkey(rfs4_entry_t u_entry)
2781 {
2782         return (u_entry);
2783 }
2784 
2785 rfs4_lo_state_t *
2786 rfs4_findlo_state_by_owner(rfs4_lockowner_t *lo, rfs4_state_t *sp,
2787     bool_t *create)
2788 {
2789         rfs4_lo_state_t *lsp;
2790         rfs4_lo_state_t arg;
2791         nfs4_srv_t *nsrv4 = nfs4_get_srv();
2792 
2793         arg.rls_locker = lo;
2794         arg.rls_state = sp;
2795 
2796         lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_owner_idx,
2797             &arg, create, &arg, RFS4_DBS_VALID);
2798 
2799         return (lsp);
2800 }
2801 
2802 static stateid_t
2803 get_stateid(id_t eid)
2804 {
2805         stateid_t id;
2806         nfs4_srv_t *nsrv4;
2807 
2808         nsrv4 = nfs4_get_srv();
2809 
2810         id.bits.boottime = nsrv4->rfs4_start_time;
2811         id.bits.ident = eid;
2812         id.bits.chgseq = 0;
2813         id.bits.type = 0;
2814         id.bits.pid = 0;
2815 
2816         /*
2817          * If we are booted as a cluster node, embed our nodeid.
2818          * We've already done sanity checks in rfs4_client_create() so no
2819          * need to repeat them here.
2820          */
2821         id.bits.clnodeid = (cluster_bootflags & CLUSTER_BOOTED) ?
2822             clconf_get_nodeid() : 0;
2823 
2824         return (id);
2825 }
2826 
2827 /*
2828  * For use only when booted as a cluster node.
 
3046 rfs4_deleg_state_destroy(rfs4_entry_t u_entry)
3047 {
3048         rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
3049 
3050         /* return delegation if necessary */
3051         rfs4_return_deleg(dsp, FALSE);
3052 
3053         /* Were done with the file */
3054         rfs4_file_rele(dsp->rds_finfo);
3055         dsp->rds_finfo = NULL;
3056 
3057         /* And now with the openowner */
3058         rfs4_client_rele(dsp->rds_client);
3059         dsp->rds_client = NULL;
3060 }
3061 
3062 rfs4_deleg_state_t *
3063 rfs4_finddeleg(rfs4_state_t *sp, bool_t *create)
3064 {
3065         rfs4_deleg_state_t ds, *dsp;
3066         nfs4_srv_t *nsrv4 = nfs4_get_srv();
3067 
3068         ds.rds_client = sp->rs_owner->ro_client;
3069         ds.rds_finfo = sp->rs_finfo;
3070 
3071         dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_idx, &ds,
3072             create, &ds, RFS4_DBS_VALID);
3073 
3074         return (dsp);
3075 }
3076 
3077 rfs4_deleg_state_t *
3078 rfs4_finddelegstate(stateid_t *id)
3079 {
3080         rfs4_deleg_state_t *dsp;
3081         bool_t create = FALSE;
3082         nfs4_srv_t *nsrv4 = nfs4_get_srv();
3083 
3084         dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_state_idx,
3085             id, &create, NULL, RFS4_DBS_VALID);
3086 
3087         return (dsp);
3088 }
3089 
3090 void
3091 rfs4_deleg_state_rele(rfs4_deleg_state_t *dsp)
3092 {
3093         rfs4_dbe_rele(dsp->rds_dbe);
3094 }
3095 
3096 void
3097 rfs4_update_lock_sequence(rfs4_lo_state_t *lsp)
3098 {
3099 
3100         rfs4_dbe_lock(lsp->rls_dbe);
3101 
3102         /*
 
3184         if (sp->rs_closed == TRUE)
3185                 return (FALSE);
3186 
3187         return (fp == sp->rs_finfo);
3188 }
3189 
3190 static void *
3191 state_file_mkkey(rfs4_entry_t u_entry)
3192 {
3193         rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3194 
3195         return (sp->rs_finfo);
3196 }
3197 
3198 rfs4_state_t *
3199 rfs4_findstate_by_owner_file(rfs4_openowner_t *oo, rfs4_file_t *fp,
3200     bool_t *create)
3201 {
3202         rfs4_state_t *sp;
3203         rfs4_state_t key;
3204         nfs4_srv_t *nsrv4 = nfs4_get_srv();
3205 
3206         key.rs_owner = oo;
3207         key.rs_finfo = fp;
3208 
3209         sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_owner_file_idx,
3210             &key, create, &key, RFS4_DBS_VALID);
3211 
3212         return (sp);
3213 }
3214 
3215 /* This returns ANY state struct that refers to this file */
3216 static rfs4_state_t *
3217 rfs4_findstate_by_file(rfs4_file_t *fp)
3218 {
3219         bool_t create = FALSE;
3220         nfs4_srv_t *nsrv4 = nfs4_get_srv();
3221 
3222         return ((rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_file_idx, fp,
3223             &create, fp, RFS4_DBS_VALID));
3224 }
3225 
3226 static bool_t
3227 rfs4_state_expiry(rfs4_entry_t u_entry)
3228 {
3229         rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3230 
3231         if (rfs4_dbe_is_invalid(sp->rs_dbe))
3232                 return (TRUE);
3233 
3234         if (sp->rs_closed == TRUE &&
3235             ((gethrestime_sec() - rfs4_dbe_get_timerele(sp->rs_dbe))
3236             > rfs4_lease_time))
3237                 return (TRUE);
3238 
3239         return ((gethrestime_sec() - sp->rs_owner->ro_client->rc_last_access
3240             > rfs4_lease_time));
 
3253         sp->rs_stateid.bits.type = OPENID;
3254         sp->rs_owner = oo;
3255         sp->rs_finfo = fp;
3256 
3257         list_create(&sp->rs_lostatelist, sizeof (rfs4_lo_state_t),
3258             offsetof(rfs4_lo_state_t, rls_node));
3259 
3260         /* Insert state on per open owner's list */
3261         rfs4_dbe_lock(oo->ro_dbe);
3262         list_insert_tail(&oo->ro_statelist, sp);
3263         rfs4_dbe_unlock(oo->ro_dbe);
3264 
3265         return (TRUE);
3266 }
3267 
3268 static rfs4_state_t *
3269 rfs4_findstate(stateid_t *id, rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
3270 {
3271         rfs4_state_t *sp;
3272         bool_t create = FALSE;
3273         nfs4_srv_t *nsrv4 = nfs4_get_srv();
3274 
3275         sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_idx, id,
3276             &create, NULL, find_invalid);
3277         if (lock_fp == TRUE && sp != NULL)
3278                 rw_enter(&sp->rs_finfo->rf_file_rwlock, RW_READER);
3279 
3280         return (sp);
3281 }
3282 
3283 void
3284 rfs4_state_close(rfs4_state_t *sp, bool_t lock_held, bool_t close_of_client,
3285     cred_t *cr)
3286 {
3287         /* Remove the associated lo_state owners */
3288         if (!lock_held)
3289                 rfs4_dbe_lock(sp->rs_dbe);
3290 
3291         /*
3292          * If refcnt == 0, the dbe is about to be destroyed.
3293          * lock state will be released by the reaper thread.
 
3325 void
3326 rfs4_client_close(rfs4_client_t *cp)
3327 {
3328         /* Mark client as going away. */
3329         rfs4_dbe_lock(cp->rc_dbe);
3330         rfs4_dbe_invalidate(cp->rc_dbe);
3331         rfs4_dbe_unlock(cp->rc_dbe);
3332 
3333         rfs4_client_state_remove(cp);
3334 
3335         /* Release the client */
3336         rfs4_client_rele(cp);
3337 }
3338 
3339 nfsstat4
3340 rfs4_check_clientid(clientid4 *cp, int setclid_confirm)
3341 {
3342         cid *cidp = (cid *) cp;
3343         nfs4_srv_t *nsrv4;
3344 
3345         nsrv4 = nfs4_get_srv();
3346 
3347         /*
3348          * If we are booted as a cluster node, check the embedded nodeid.
3349          * If it indicates that this clientid was generated on another node,
3350          * inform the client accordingly.
3351          */
3352         if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
3353                 return (NFS4ERR_STALE_CLIENTID);
3354 
3355         /*
3356          * If the server start time matches the time provided
3357          * by the client (via the clientid) and this is NOT a
3358          * setclientid_confirm then return EXPIRED.
3359          */
3360         if (!setclid_confirm &&
3361             cidp->impl_id.start_time == nsrv4->rfs4_start_time)
3362                 return (NFS4ERR_EXPIRED);
3363 
3364         return (NFS4ERR_STALE_CLIENTID);
3365 }
3366 
3367 /*
3368  * This is used when a stateid has not been found amongst the
3369  * current server's state.  Check the stateid to see if it
3370  * was from this server instantiation or not.
3371  */
3372 static nfsstat4
3373 what_stateid_error(stateid_t *id, stateid_type_t type)
3374 {
3375         nfs4_srv_t *nsrv4;
3376 
3377         nsrv4 = nfs4_get_srv();
3378 
3379         /* If we are booted as a cluster node, was stateid locally generated? */
3380         if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3381                 return (NFS4ERR_STALE_STATEID);
3382 
3383         /* If types don't match then no use checking further */
3384         if (type != id->bits.type)
3385                 return (NFS4ERR_BAD_STATEID);
3386 
3387         /* From a different server instantiation, return STALE */
3388         if (id->bits.boottime != nsrv4->rfs4_start_time)
3389                 return (NFS4ERR_STALE_STATEID);
3390 
3391         /*
3392          * From this server but the state is most likely beyond lease
3393          * timeout: return NFS4ERR_EXPIRED.  However, there is the
3394          * case of a delegation stateid.  For delegations, there is a
3395          * case where the state can be removed without the client's
3396          * knowledge/consent: revocation.  In the case of delegation
3397          * revocation, the delegation state will be removed and will
 
4091                             OPEN_DELEGATE_WRITE) {
4092                                 (void) fem_uninstall(vp, deleg_wrops,
4093                                     (void *)fp);
4094                                 vn_open_downgrade(vp, FREAD|FWRITE);
4095                         }
4096                         mutex_enter(&vp->v_vsd_lock);
4097                         (void) vsd_set(vp, nfs4_srv_vkey, NULL);
4098                         mutex_exit(&vp->v_vsd_lock);
4099                         VN_RELE(vp);
4100                         fp->rf_vp = NULL;
4101                 }
4102                 rfs4_dbe_invalidate(fp->rf_dbe);
4103         }
4104 }
4105 
4106 /*
4107  * Given a directory that is being unexported, cleanup/release all
4108  * state in the server that refers to objects residing underneath this
4109  * particular export.  The ordering of the release is important.
4110  * Lock_owner, then state and then file.
4111  *
4112  * NFS zones note: nfs_export.c:unexport() calls this from a
4113  * thread in the global zone for NGZ data structures, so we
4114  * CANNOT use zone_getspecific anywhere in this code path.
4115  */
4116 void
4117 rfs4_clean_state_exi(nfs_export_t *ne, struct exportinfo *exi)
4118 {
4119         nfs_globals_t *ng;
4120         nfs4_srv_t *nsrv4;
4121 
4122         ng = ne->ne_globals;
4123         ASSERT(ng->nfs_zoneid == exi->exi_zoneid);
4124         nsrv4 = ng->nfs4_srv;
4125 
4126         mutex_enter(&nsrv4->state_lock);
4127 
4128         if (nsrv4->nfs4_server_state == NULL) {
4129                 mutex_exit(&nsrv4->state_lock);
4130                 return;
4131         }
4132 
4133         rfs4_dbe_walk(nsrv4->rfs4_lo_state_tab,
4134             rfs4_lo_state_walk_callout, exi);
4135         rfs4_dbe_walk(nsrv4->rfs4_state_tab, rfs4_state_walk_callout, exi);
4136         rfs4_dbe_walk(nsrv4->rfs4_deleg_state_tab,
4137             rfs4_deleg_state_walk_callout, exi);
4138         rfs4_dbe_walk(nsrv4->rfs4_file_tab, rfs4_file_walk_callout, exi);
4139 
4140         mutex_exit(&nsrv4->state_lock);
4141 }
 |