Print this page
Fix NFS design problems re. multiple zone keys
Make NFS server zone-specific data all have the same lifetime
Fix rfs4_clean_state_exi
Fix exi_cache_reclaim
Fix mistakes in zone keys work
More fixes re. exi_zoneid and exi_tree
(danmcd -> Keep some ASSERT()s around for readability.)


 143         rw_enter(&nsrv4->deleg_policy_lock, RW_WRITER);
 144         nsrv4->nfs4_deleg_policy = new_policy;
 145         rw_exit(&nsrv4->deleg_policy_lock);
 146 }
 147 
 148 void
 149 rfs4_hold_deleg_policy(nfs4_srv_t *nsrv4)
 150 {
 151         rw_enter(&nsrv4->deleg_policy_lock, RW_READER);
 152 }
 153 
 154 void
 155 rfs4_rele_deleg_policy(nfs4_srv_t *nsrv4)
 156 {
 157         rw_exit(&nsrv4->deleg_policy_lock);
 158 }
 159 
 160 srv_deleg_policy_t
 161 nfs4_get_deleg_policy()
 162 {
 163         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
 164         return (nsrv4->nfs4_deleg_policy);
 165 }
 166 
 167 
 168 /*
 169  * This free function is to be used when the client struct is being
 170  * released and nothing at all is needed of the callback info any
 171  * longer.
 172  */
 173 void
 174 rfs4_cbinfo_free(rfs4_cbinfo_t *cbp)
 175 {
 176         char *addr = cbp->cb_callback.cb_location.r_addr;
 177         char *netid = cbp->cb_callback.cb_location.r_netid;
 178 
 179         /* Free old address if any */
 180 
 181         if (addr)
 182                 kmem_free(addr, strlen(addr) + 1);
 183         if (netid)


1253         return (dtype);
1254 }
1255 
1256 /*
1257  * Try and grant a delegation for an open give the state. The routine
1258  * returns the delegation type granted. This could be OPEN_DELEGATE_NONE.
1259  *
1260  * The state and associate file entry must be locked
1261  */
1262 rfs4_deleg_state_t *
1263 rfs4_grant_delegation(delegreq_t dreq, rfs4_state_t *sp, int *recall)
1264 {
1265         nfs4_srv_t *nsrv4;
1266         rfs4_file_t *fp = sp->rs_finfo;
1267         open_delegation_type4 dtype;
1268         int no_delegation;
1269 
1270         ASSERT(rfs4_dbe_islocked(sp->rs_dbe));
1271         ASSERT(rfs4_dbe_islocked(fp->rf_dbe));
1272 
1273         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1274 
1275         /* Is the server even providing delegations? */
1276         if (nsrv4->nfs4_deleg_policy == SRV_NEVER_DELEGATE || dreq == DELEG_NONE)
1277                 return (NULL);
1278 
1279         /* Check to see if delegations have been temporarily disabled */
1280         mutex_enter(&nsrv4->deleg_lock);
1281         no_delegation = rfs4_deleg_disabled;
1282         mutex_exit(&nsrv4->deleg_lock);
1283 
1284         if (no_delegation)
1285                 return (NULL);
1286 
1287         /* Don't grant a delegation if a deletion is impending. */
1288         if (fp->rf_dinfo.rd_hold_grant > 0) {
1289                 return (NULL);
1290         }
1291 
1292         /*
1293          * Don't grant a delegation if there are any lock manager


1432                 break;
1433         }
1434 }
1435 
1436 /*
1437  * Check if the file is delegated via the provided file struct.
1438  * Return TRUE if it is delegated.  This is intended for use by
1439  * the v4 server.  The v2/v3 server code should use rfs4_check_delegated().
1440  *
1441  * Note that if the file is found to have a delegation, it is
1442  * recalled, unless the clientid of the caller matches the clientid of the
1443  * delegation. If the caller has specified, there is a slight delay
1444  * inserted in the hopes that the delegation will be returned quickly.
1445  */
1446 bool_t
1447 rfs4_check_delegated_byfp(int mode, rfs4_file_t *fp,
1448     bool_t trunc, bool_t do_delay, bool_t is_rm, clientid4 *cp)
1449 {
1450         rfs4_deleg_state_t *dsp;
1451 
1452         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1453 
1454         /* Is delegation enabled? */
1455         if (nsrv4->nfs4_deleg_policy == SRV_NEVER_DELEGATE)
1456                 return (FALSE);
1457 
1458         /* do we have a delegation on this file? */
1459         rfs4_dbe_lock(fp->rf_dbe);
1460         if (fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_NONE) {
1461                 if (is_rm)
1462                         fp->rf_dinfo.rd_hold_grant++;
1463                 rfs4_dbe_unlock(fp->rf_dbe);
1464                 return (FALSE);
1465         }
1466         /*
1467          * do we have a write delegation on this file or are we
1468          * requesting write access to a file with any type of existing
1469          * delegation?
1470          */
1471         if (mode == FWRITE || fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_WRITE) {
1472                 if (cp != NULL) {


1505         }
1506         if (is_rm)
1507                 fp->rf_dinfo.rd_hold_grant++;
1508         rfs4_dbe_unlock(fp->rf_dbe);
1509         return (FALSE);
1510 }
1511 
1512 /*
1513  * Check if the file is delegated in the case of a v2 or v3 access.
1514  * Return TRUE if it is delegated which in turn means that v2 should
1515  * drop the request and in the case of v3 JUKEBOX should be returned.
1516  */
1517 bool_t
1518 rfs4_check_delegated(int mode, vnode_t *vp, bool_t trunc)
1519 {
1520         nfs4_srv_t *nsrv4;
1521         rfs4_file_t *fp;
1522         bool_t create = FALSE;
1523         bool_t rc = FALSE;
1524 
1525         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1526         rfs4_hold_deleg_policy(nsrv4);
1527 
1528         /* Is delegation enabled? */
1529         if (nsrv4->nfs4_deleg_policy != SRV_NEVER_DELEGATE) {
1530                 fp = rfs4_findfile(vp, NULL, &create);
1531                 if (fp != NULL) {
1532                         if (rfs4_check_delegated_byfp(mode, fp, trunc,
1533                             TRUE, FALSE, NULL)) {
1534                                 rc = TRUE;
1535                         }
1536                         rfs4_file_rele(fp);
1537                 }
1538         }
1539         rfs4_rele_deleg_policy(nsrv4);
1540         return (rc);
1541 }
1542 
1543 /*
1544  * Release a hold on the hold_grant counter which
1545  * prevents delegation from being granted while a remove
1546  * or a rename is in progress.
1547  */
1548 void
1549 rfs4_clear_dont_grant(rfs4_file_t *fp)
1550 {
1551         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1552 
1553         if (nsrv4->nfs4_deleg_policy == SRV_NEVER_DELEGATE)
1554                 return;
1555         rfs4_dbe_lock(fp->rf_dbe);
1556         ASSERT(fp->rf_dinfo.rd_hold_grant > 0);
1557         fp->rf_dinfo.rd_hold_grant--;
1558         fp->rf_dinfo.rd_time_rm_delayed = 0;
1559         rfs4_dbe_unlock(fp->rf_dbe);
1560 }
1561 
1562 /*
1563  * State support for delegation.
1564  * Set the state delegation type for this state;
1565  * This routine is called from open via rfs4_grant_delegation and the entry
1566  * locks on sp and sp->rs_finfo are assumed.
1567  */
1568 static rfs4_deleg_state_t *
1569 rfs4_deleg_state(rfs4_state_t *sp, open_delegation_type4 dtype, int *recall)
1570 {
1571         rfs4_file_t *fp = sp->rs_finfo;


1871 {
1872         rfs4_deleg_state_t *dsp;
1873         rfs4_file_t *fp = sp->rs_finfo;
1874         rfs4_client_t *cp = sp->rs_owner->ro_client;
1875 
1876         ASSERT(rfs4_dbe_islocked(fp->rf_dbe));
1877         for (dsp = list_head(&fp->rf_delegstatelist); dsp != NULL;
1878             dsp = list_next(&fp->rf_delegstatelist, dsp)) {
1879                 if (cp != dsp->rds_client) {
1880                         return (TRUE);
1881                 }
1882         }
1883         return (FALSE);
1884 }
1885 
1886 void
1887 rfs4_disable_delegation(void)
1888 {
1889         nfs4_srv_t *nsrv4;
1890 
1891         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1892         mutex_enter(&nsrv4->deleg_lock);
1893         rfs4_deleg_disabled++;
1894         mutex_exit(&nsrv4->deleg_lock);
1895 }
1896 
1897 void
1898 rfs4_enable_delegation(void)
1899 {
1900         nfs4_srv_t *nsrv4;
1901 
1902         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1903         mutex_enter(&nsrv4->deleg_lock);
1904         ASSERT(rfs4_deleg_disabled > 0);
1905         rfs4_deleg_disabled--;
1906         mutex_exit(&nsrv4->deleg_lock);
1907 }
1908 
1909 void
1910 rfs4_mon_hold(void *arg)
1911 {
1912         rfs4_file_t *fp = arg;
1913 
1914         rfs4_dbe_hold(fp->rf_dbe);
1915 }
1916 
1917 void
1918 rfs4_mon_rele(void *arg)
1919 {
1920         rfs4_file_t *fp = arg;
1921 
1922         rfs4_dbe_rele_nolock(fp->rf_dbe);


 143         rw_enter(&nsrv4->deleg_policy_lock, RW_WRITER);
 144         nsrv4->nfs4_deleg_policy = new_policy;
 145         rw_exit(&nsrv4->deleg_policy_lock);
 146 }
 147 
 148 void
 149 rfs4_hold_deleg_policy(nfs4_srv_t *nsrv4)
 150 {
 151         rw_enter(&nsrv4->deleg_policy_lock, RW_READER);
 152 }
 153 
 154 void
 155 rfs4_rele_deleg_policy(nfs4_srv_t *nsrv4)
 156 {
 157         rw_exit(&nsrv4->deleg_policy_lock);
 158 }
 159 
 160 srv_deleg_policy_t
 161 nfs4_get_deleg_policy()
 162 {
 163         nfs4_srv_t *nsrv4 = nfs4_get_srv();
 164         return (nsrv4->nfs4_deleg_policy);
 165 }
 166 
 167 
 168 /*
 169  * This free function is to be used when the client struct is being
 170  * released and nothing at all is needed of the callback info any
 171  * longer.
 172  */
 173 void
 174 rfs4_cbinfo_free(rfs4_cbinfo_t *cbp)
 175 {
 176         char *addr = cbp->cb_callback.cb_location.r_addr;
 177         char *netid = cbp->cb_callback.cb_location.r_netid;
 178 
 179         /* Free old address if any */
 180 
 181         if (addr)
 182                 kmem_free(addr, strlen(addr) + 1);
 183         if (netid)


1253         return (dtype);
1254 }
1255 
1256 /*
1257  * Try and grant a delegation for an open give the state. The routine
1258  * returns the delegation type granted. This could be OPEN_DELEGATE_NONE.
1259  *
1260  * The state and associate file entry must be locked
1261  */
1262 rfs4_deleg_state_t *
1263 rfs4_grant_delegation(delegreq_t dreq, rfs4_state_t *sp, int *recall)
1264 {
1265         nfs4_srv_t *nsrv4;
1266         rfs4_file_t *fp = sp->rs_finfo;
1267         open_delegation_type4 dtype;
1268         int no_delegation;
1269 
1270         ASSERT(rfs4_dbe_islocked(sp->rs_dbe));
1271         ASSERT(rfs4_dbe_islocked(fp->rf_dbe));
1272 
1273         nsrv4 = nfs4_get_srv();
1274 
1275         /* Is the server even providing delegations? */
1276         if (nsrv4->nfs4_deleg_policy == SRV_NEVER_DELEGATE || dreq == DELEG_NONE)
1277                 return (NULL);
1278 
1279         /* Check to see if delegations have been temporarily disabled */
1280         mutex_enter(&nsrv4->deleg_lock);
1281         no_delegation = rfs4_deleg_disabled;
1282         mutex_exit(&nsrv4->deleg_lock);
1283 
1284         if (no_delegation)
1285                 return (NULL);
1286 
1287         /* Don't grant a delegation if a deletion is impending. */
1288         if (fp->rf_dinfo.rd_hold_grant > 0) {
1289                 return (NULL);
1290         }
1291 
1292         /*
1293          * Don't grant a delegation if there are any lock manager


1432                 break;
1433         }
1434 }
1435 
1436 /*
1437  * Check if the file is delegated via the provided file struct.
1438  * Return TRUE if it is delegated.  This is intended for use by
1439  * the v4 server.  The v2/v3 server code should use rfs4_check_delegated().
1440  *
1441  * Note that if the file is found to have a delegation, it is
1442  * recalled, unless the clientid of the caller matches the clientid of the
1443  * delegation. If the caller has specified, there is a slight delay
1444  * inserted in the hopes that the delegation will be returned quickly.
1445  */
1446 bool_t
1447 rfs4_check_delegated_byfp(int mode, rfs4_file_t *fp,
1448     bool_t trunc, bool_t do_delay, bool_t is_rm, clientid4 *cp)
1449 {
1450         rfs4_deleg_state_t *dsp;
1451 
1452         nfs4_srv_t *nsrv4 = nfs4_get_srv();
1453 
1454         /* Is delegation enabled? */
1455         if (nsrv4->nfs4_deleg_policy == SRV_NEVER_DELEGATE)
1456                 return (FALSE);
1457 
1458         /* do we have a delegation on this file? */
1459         rfs4_dbe_lock(fp->rf_dbe);
1460         if (fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_NONE) {
1461                 if (is_rm)
1462                         fp->rf_dinfo.rd_hold_grant++;
1463                 rfs4_dbe_unlock(fp->rf_dbe);
1464                 return (FALSE);
1465         }
1466         /*
1467          * do we have a write delegation on this file or are we
1468          * requesting write access to a file with any type of existing
1469          * delegation?
1470          */
1471         if (mode == FWRITE || fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_WRITE) {
1472                 if (cp != NULL) {


1505         }
1506         if (is_rm)
1507                 fp->rf_dinfo.rd_hold_grant++;
1508         rfs4_dbe_unlock(fp->rf_dbe);
1509         return (FALSE);
1510 }
1511 
1512 /*
1513  * Check if the file is delegated in the case of a v2 or v3 access.
1514  * Return TRUE if it is delegated which in turn means that v2 should
1515  * drop the request and in the case of v3 JUKEBOX should be returned.
1516  */
1517 bool_t
1518 rfs4_check_delegated(int mode, vnode_t *vp, bool_t trunc)
1519 {
1520         nfs4_srv_t *nsrv4;
1521         rfs4_file_t *fp;
1522         bool_t create = FALSE;
1523         bool_t rc = FALSE;
1524 
1525         nsrv4 = nfs4_get_srv();
1526         rfs4_hold_deleg_policy(nsrv4);
1527 
1528         /* Is delegation enabled? */
1529         if (nsrv4->nfs4_deleg_policy != SRV_NEVER_DELEGATE) {
1530                 fp = rfs4_findfile(vp, NULL, &create);
1531                 if (fp != NULL) {
1532                         if (rfs4_check_delegated_byfp(mode, fp, trunc,
1533                             TRUE, FALSE, NULL)) {
1534                                 rc = TRUE;
1535                         }
1536                         rfs4_file_rele(fp);
1537                 }
1538         }
1539         rfs4_rele_deleg_policy(nsrv4);
1540         return (rc);
1541 }
1542 
1543 /*
1544  * Release a hold on the hold_grant counter which
1545  * prevents delegation from being granted while a remove
1546  * or a rename is in progress.
1547  */
1548 void
1549 rfs4_clear_dont_grant(rfs4_file_t *fp)
1550 {
1551         nfs4_srv_t *nsrv4 = nfs4_get_srv();
1552 
1553         if (nsrv4->nfs4_deleg_policy == SRV_NEVER_DELEGATE)
1554                 return;
1555         rfs4_dbe_lock(fp->rf_dbe);
1556         ASSERT(fp->rf_dinfo.rd_hold_grant > 0);
1557         fp->rf_dinfo.rd_hold_grant--;
1558         fp->rf_dinfo.rd_time_rm_delayed = 0;
1559         rfs4_dbe_unlock(fp->rf_dbe);
1560 }
1561 
1562 /*
1563  * State support for delegation.
1564  * Set the state delegation type for this state;
1565  * This routine is called from open via rfs4_grant_delegation and the entry
1566  * locks on sp and sp->rs_finfo are assumed.
1567  */
1568 static rfs4_deleg_state_t *
1569 rfs4_deleg_state(rfs4_state_t *sp, open_delegation_type4 dtype, int *recall)
1570 {
1571         rfs4_file_t *fp = sp->rs_finfo;


1871 {
1872         rfs4_deleg_state_t *dsp;
1873         rfs4_file_t *fp = sp->rs_finfo;
1874         rfs4_client_t *cp = sp->rs_owner->ro_client;
1875 
1876         ASSERT(rfs4_dbe_islocked(fp->rf_dbe));
1877         for (dsp = list_head(&fp->rf_delegstatelist); dsp != NULL;
1878             dsp = list_next(&fp->rf_delegstatelist, dsp)) {
1879                 if (cp != dsp->rds_client) {
1880                         return (TRUE);
1881                 }
1882         }
1883         return (FALSE);
1884 }
1885 
1886 void
1887 rfs4_disable_delegation(void)
1888 {
1889         nfs4_srv_t *nsrv4;
1890 
1891         nsrv4 = nfs4_get_srv();
1892         mutex_enter(&nsrv4->deleg_lock);
1893         rfs4_deleg_disabled++;
1894         mutex_exit(&nsrv4->deleg_lock);
1895 }
1896 
1897 void
1898 rfs4_enable_delegation(void)
1899 {
1900         nfs4_srv_t *nsrv4;
1901 
1902         nsrv4 = nfs4_get_srv();
1903         mutex_enter(&nsrv4->deleg_lock);
1904         ASSERT(rfs4_deleg_disabled > 0);
1905         rfs4_deleg_disabled--;
1906         mutex_exit(&nsrv4->deleg_lock);
1907 }
1908 
1909 void
1910 rfs4_mon_hold(void *arg)
1911 {
1912         rfs4_file_t *fp = arg;
1913 
1914         rfs4_dbe_hold(fp->rf_dbe);
1915 }
1916 
1917 void
1918 rfs4_mon_rele(void *arg)
1919 {
1920         rfs4_file_t *fp = arg;
1921 
1922         rfs4_dbe_rele_nolock(fp->rf_dbe);