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,
|