Print this page
11083 support NFS server in zone
Portions contributed by: Dan Kruchinin <dan.kruchinin@nexenta.com>
Portions contributed by: Stepan Zastupov <stepan.zastupov@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Portions contributed by: Mike Zeller <mike@mikezeller.net>
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>
Portions contributed by: Vitaliy Gusev <gusev.vitaliy@gmail.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Jason King <jbk@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Change-Id: I22f289d357503f9b48a0bc2482cc4328a6d43d16
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */

  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */

  25 /*
  26  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  27  */
  28 
  29 #include <sys/systm.h>
  30 #include <sys/cmn_err.h>
  31 #include <nfs/nfs.h>
  32 #include <nfs/export.h>
  33 #include <nfs/nfs4.h>
  34 #include <sys/ddi.h>
  35 #include <sys/door.h>
  36 #include <sys/sdt.h>
  37 #include <nfs/nfssys.h>
  38 
  39 void    rfs4_init_compound_state(struct compound_state *);
  40 
  41 bitmap4 rfs4_supported_attrs;
  42 int MSG_PRT_DEBUG = FALSE;
  43 
  44 /* If building with DEBUG enabled, enable mandattr tunable by default */
  45 #ifdef DEBUG
  46 #ifndef RFS4_SUPPORT_MANDATTR_ONLY


 116 static int rfs4_fattr4_time_access_set();
 117 static int rfs4_fattr4_time_backup();
 118 static int rfs4_fattr4_time_create();
 119 static int rfs4_fattr4_time_delta();
 120 static int rfs4_fattr4_time_metadata();
 121 static int rfs4_fattr4_time_modify();
 122 static int rfs4_fattr4_time_modify_set();
 123 
 124 /*
 125  * Initialize the supported attributes
 126  */
 127 void
 128 rfs4_attr_init()
 129 {
 130         int i;
 131         struct nfs4_svgetit_arg sarg;
 132         struct compound_state cs;
 133         struct statvfs64 sb;
 134 
 135         rfs4_init_compound_state(&cs);





 136         cs.vp = rootvp;
 137         cs.fh.nfs_fh4_val = NULL;
 138         cs.cr = kcred;
 139 
 140         /*
 141          * Get all the supported attributes
 142          */
 143         sarg.op = NFS4ATTR_SUPPORTED;
 144         sarg.cs = &cs;
 145         sarg.vap->va_mask = AT_ALL;
 146         sarg.sbp = &sb;
 147         sarg.flag = 0;
 148         sarg.rdattr_error = NFS4_OK;
 149         sarg.rdattr_error_req = FALSE;
 150         sarg.is_referral = B_FALSE;
 151 
 152         rfs4_ntov_init();
 153 
 154         rfs4_supported_attrs = 0;
 155         for (i = 0; i < NFS4_MAXNUM_ATTRS; i++) {


1284                 if (sarg->vap->va_nodeid != na->fileid)
1285                         error = -1;     /* no match */
1286                 break;
1287         case NFS4ATTR_FREEIT:
1288                 break;
1289         }
1290         return (error);
1291 }
1292 
1293 /* ARGSUSED */
1294 static int
1295 rfs4_get_mntdfileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg)
1296 {
1297         int error = 0;
1298         vattr_t *vap, va;
1299         vnode_t *stubvp = NULL, *vp;
1300 
1301         vp = sarg->cs->vp;
1302         sarg->mntdfid_set = FALSE;
1303 
1304         /* VROOT object, must untraverse */
1305         if (vp->v_flag & VROOT) {







1306 
1307                 /* extra hold for vp since untraverse might rele */
1308                 VN_HOLD(vp);
1309                 stubvp = untraverse(vp);
1310 
1311                 /*
1312                  * If vp/stubvp are same, we must be at system
1313                  * root because untraverse returned same vp
1314                  * for a VROOT object.  sarg->vap was setup
1315                  * before we got here, so there's no need to do
1316                  * another getattr -- just use the one in sarg.
1317                  */
1318                 if (VN_CMP(vp, stubvp)) {
1319                         ASSERT(VN_CMP(vp, rootdir));
1320                         vap = sarg->vap;
1321                 } else {
1322                         va.va_mask = AT_NODEID;
1323                         vap = &va;
1324                         error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr);
1325                 }
1326 
1327                 /*
1328                  * Done with stub, time to rele.  If vp and stubvp
1329                  * were the same, then we need to rele either vp or
1330                  * stubvp.  If they weren't the same, then untraverse()
1331                  * already took case of the extra hold on vp, and only
1332                  * the stub needs to be rele'd.  Both cases are handled
1333                  * by unconditionally rele'ing the stub.
1334                  */
1335                 VN_RELE(stubvp);
1336         } else
1337                 vap = sarg->vap;
1338 
1339         /*


1358         return (error);
1359 }
1360 
1361 /* ARGSUSED */
1362 static int
1363 rfs4_fattr4_mounted_on_fileid(nfs4_attr_cmd_t cmd,
1364     struct nfs4_svgetit_arg *sarg, union nfs4_attr_u *na)
1365 {
1366         int     error = 0;
1367 
1368         if (RFS4_MANDATTR_ONLY)
1369                 return (ENOTSUP);
1370 
1371         switch (cmd) {
1372         case NFS4ATTR_SUPPORTED:
1373                 if (sarg->op == NFS4ATTR_SETIT)
1374                         error = EINVAL;
1375                 break;          /* this attr is supported */
1376         case NFS4ATTR_GETIT:
1377         case NFS4ATTR_VERIT:
1378                 if (! sarg->mntdfid_set)
1379                         error = rfs4_get_mntdfileid(cmd, sarg);
1380 
1381                 if (! error && sarg->mntdfid_set) {
1382                         if (cmd == NFS4ATTR_GETIT)
1383                                 na->mounted_on_fileid = sarg->mounted_on_fileid;
1384                         else
1385                                 if (na->mounted_on_fileid !=
1386                                     sarg->mounted_on_fileid)
1387                                         error = -1;
1388                 }
1389                 break;
1390         case NFS4ATTR_SETIT:
1391                 /* read-only attr */
1392                 error = EINVAL;
1393                 break;
1394         case NFS4ATTR_FREEIT:
1395                 break;
1396         }
1397         return (error);
1398 }
1399 
1400 /* ARGSUSED */
1401 static int


1578 }
1579 
1580 /* ARGSUSED */
1581 static int
1582 rfs4_fattr4_fs_locations(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1583     union nfs4_attr_u *na)
1584 {
1585         int error = 0;
1586         fs_locations4 *fsl;
1587 
1588         if (RFS4_MANDATTR_ONLY)
1589                 return (ENOTSUP);
1590 
1591         switch (cmd) {
1592         case NFS4ATTR_SUPPORTED:
1593                 if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
1594                         error = EINVAL;
1595                 break;  /* this attr is supported */
1596 
1597         case NFS4ATTR_GETIT:




1598                 fsl = fetch_referral(sarg->cs->vp, sarg->cs->cr);
1599                 if (fsl == NULL)
1600                         (void) memset(&(na->fs_locations), 0,
1601                             sizeof (fs_locations4));
1602                 else {
1603                         na->fs_locations = *fsl;
1604                         kmem_free(fsl, sizeof (fs_locations4));
1605                 }
1606                 global_svstat_ptr[4][NFS_REFERRALS].value.ui64++;
1607                 break;
1608 
1609         case NFS4ATTR_FREEIT:
1610                 if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
1611                         error = EINVAL;
1612                 rfs4_free_fs_locations4(&na->fs_locations);
1613                 break;
1614 
1615         case NFS4ATTR_SETIT:
1616         case NFS4ATTR_VERIT:
1617                 /*
1618                  * read-only attr
1619                  */
1620                 error = EINVAL;
1621                 break;
1622         }
1623         return (error);
1624 }
1625 
1626 /* ARGSUSED */
1627 static int
1628 rfs4_fattr4_hidden(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,


   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2018 Nexenta Systems, Inc.
  29  */
  30 
  31 #include <sys/systm.h>
  32 #include <sys/cmn_err.h>
  33 #include <nfs/nfs.h>
  34 #include <nfs/export.h>
  35 #include <nfs/nfs4.h>
  36 #include <sys/ddi.h>
  37 #include <sys/door.h>
  38 #include <sys/sdt.h>
  39 #include <nfs/nfssys.h>
  40 
  41 void    rfs4_init_compound_state(struct compound_state *);
  42 
  43 bitmap4 rfs4_supported_attrs;
  44 int MSG_PRT_DEBUG = FALSE;
  45 
  46 /* If building with DEBUG enabled, enable mandattr tunable by default */
  47 #ifdef DEBUG
  48 #ifndef RFS4_SUPPORT_MANDATTR_ONLY


 118 static int rfs4_fattr4_time_access_set();
 119 static int rfs4_fattr4_time_backup();
 120 static int rfs4_fattr4_time_create();
 121 static int rfs4_fattr4_time_delta();
 122 static int rfs4_fattr4_time_metadata();
 123 static int rfs4_fattr4_time_modify();
 124 static int rfs4_fattr4_time_modify_set();
 125 
 126 /*
 127  * Initialize the supported attributes
 128  */
 129 void
 130 rfs4_attr_init()
 131 {
 132         int i;
 133         struct nfs4_svgetit_arg sarg;
 134         struct compound_state cs;
 135         struct statvfs64 sb;
 136 
 137         rfs4_init_compound_state(&cs);
 138         /*
 139          * This is global state checking, called once. We might be in
 140          * non-global-zone context here (say a modload happens from a zone
 141          * process) so in this case, we want the global-zone root vnode.
 142          */
 143         cs.vp = rootvp;
 144         cs.fh.nfs_fh4_val = NULL;
 145         cs.cr = kcred;
 146 
 147         /*
 148          * Get all the supported attributes
 149          */
 150         sarg.op = NFS4ATTR_SUPPORTED;
 151         sarg.cs = &cs;
 152         sarg.vap->va_mask = AT_ALL;
 153         sarg.sbp = &sb;
 154         sarg.flag = 0;
 155         sarg.rdattr_error = NFS4_OK;
 156         sarg.rdattr_error_req = FALSE;
 157         sarg.is_referral = B_FALSE;
 158 
 159         rfs4_ntov_init();
 160 
 161         rfs4_supported_attrs = 0;
 162         for (i = 0; i < NFS4_MAXNUM_ATTRS; i++) {


1291                 if (sarg->vap->va_nodeid != na->fileid)
1292                         error = -1;     /* no match */
1293                 break;
1294         case NFS4ATTR_FREEIT:
1295                 break;
1296         }
1297         return (error);
1298 }
1299 
1300 /* ARGSUSED */
1301 static int
1302 rfs4_get_mntdfileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg)
1303 {
1304         int error = 0;
1305         vattr_t *vap, va;
1306         vnode_t *stubvp = NULL, *vp;
1307 
1308         vp = sarg->cs->vp;
1309         sarg->mntdfid_set = FALSE;
1310 
1311         /*
1312          * VROOT object or zone's root, must untraverse.
1313          *
1314          * NOTE: Not doing reality checks on curzone vs. compound
1315          * state vnode because it will mismatch once at initialization
1316          * if a non-global-zone triggers the module load, BUT in that case
1317          * the vp is literally "/" which has VROOT set.
1318          */
1319         if ((vp->v_flag & VROOT) || VN_IS_CURZONEROOT(vp)) {
1320 
1321                 /* extra hold for vp since untraverse might rele */
1322                 VN_HOLD(vp);
1323                 stubvp = untraverse(vp, ZONE_ROOTVP());
1324 
1325                 /*
1326                  * If vp/stubvp are same, we must be at system-or-zone
1327                  * root because untraverse returned same vp
1328                  * for a VROOT object.  sarg->vap was setup
1329                  * before we got here, so there's no need to do
1330                  * another getattr -- just use the one in sarg.
1331                  */
1332                 if (VN_CMP(vp, stubvp)) {
1333                         ASSERT(VN_IS_CURZONEROOT(vp));
1334                         vap = sarg->vap;
1335                 } else {
1336                         va.va_mask = AT_NODEID;
1337                         vap = &va;
1338                         error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr);
1339                 }
1340 
1341                 /*
1342                  * Done with stub, time to rele.  If vp and stubvp
1343                  * were the same, then we need to rele either vp or
1344                  * stubvp.  If they weren't the same, then untraverse()
1345                  * already took case of the extra hold on vp, and only
1346                  * the stub needs to be rele'd.  Both cases are handled
1347                  * by unconditionally rele'ing the stub.
1348                  */
1349                 VN_RELE(stubvp);
1350         } else
1351                 vap = sarg->vap;
1352 
1353         /*


1372         return (error);
1373 }
1374 
1375 /* ARGSUSED */
1376 static int
1377 rfs4_fattr4_mounted_on_fileid(nfs4_attr_cmd_t cmd,
1378     struct nfs4_svgetit_arg *sarg, union nfs4_attr_u *na)
1379 {
1380         int     error = 0;
1381 
1382         if (RFS4_MANDATTR_ONLY)
1383                 return (ENOTSUP);
1384 
1385         switch (cmd) {
1386         case NFS4ATTR_SUPPORTED:
1387                 if (sarg->op == NFS4ATTR_SETIT)
1388                         error = EINVAL;
1389                 break;          /* this attr is supported */
1390         case NFS4ATTR_GETIT:
1391         case NFS4ATTR_VERIT:
1392                 if (!sarg->mntdfid_set)
1393                         error = rfs4_get_mntdfileid(cmd, sarg);
1394 
1395                 if (!error && sarg->mntdfid_set) {
1396                         if (cmd == NFS4ATTR_GETIT)
1397                                 na->mounted_on_fileid = sarg->mounted_on_fileid;
1398                         else
1399                                 if (na->mounted_on_fileid !=
1400                                     sarg->mounted_on_fileid)
1401                                         error = -1;
1402                 }
1403                 break;
1404         case NFS4ATTR_SETIT:
1405                 /* read-only attr */
1406                 error = EINVAL;
1407                 break;
1408         case NFS4ATTR_FREEIT:
1409                 break;
1410         }
1411         return (error);
1412 }
1413 
1414 /* ARGSUSED */
1415 static int


1592 }
1593 
1594 /* ARGSUSED */
1595 static int
1596 rfs4_fattr4_fs_locations(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1597     union nfs4_attr_u *na)
1598 {
1599         int error = 0;
1600         fs_locations4 *fsl;
1601 
1602         if (RFS4_MANDATTR_ONLY)
1603                 return (ENOTSUP);
1604 
1605         switch (cmd) {
1606         case NFS4ATTR_SUPPORTED:
1607                 if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
1608                         error = EINVAL;
1609                 break;  /* this attr is supported */
1610 
1611         case NFS4ATTR_GETIT:
1612         {
1613                 kstat_named_t *stat =
1614                     sarg->cs->exi->exi_ne->ne_globals->svstat[NFS_V4];
1615 
1616                 fsl = fetch_referral(sarg->cs->vp, sarg->cs->cr);
1617                 if (fsl == NULL)
1618                         (void) memset(&(na->fs_locations), 0,
1619                             sizeof (fs_locations4));
1620                 else {
1621                         na->fs_locations = *fsl;
1622                         kmem_free(fsl, sizeof (fs_locations4));
1623                 }
1624                 stat[NFS_REFERRALS].value.ui64++;
1625                 break;
1626         }
1627         case NFS4ATTR_FREEIT:
1628                 if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
1629                         error = EINVAL;
1630                 rfs4_free_fs_locations4(&na->fs_locations);
1631                 break;
1632 
1633         case NFS4ATTR_SETIT:
1634         case NFS4ATTR_VERIT:
1635                 /*
1636                  * read-only attr
1637                  */
1638                 error = EINVAL;
1639                 break;
1640         }
1641         return (error);
1642 }
1643 
1644 /* ARGSUSED */
1645 static int
1646 rfs4_fattr4_hidden(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,