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 cs.vp = ZONE_ROOTVP();
139 cs.fh.nfs_fh4_val = NULL;
140 cs.cr = kcred;
141
142 /*
143 * Get all the supported attributes
144 */
145 sarg.op = NFS4ATTR_SUPPORTED;
146 sarg.cs = &cs;
147 sarg.vap->va_mask = AT_ALL;
148 sarg.sbp = &sb;
149 sarg.flag = 0;
150 sarg.rdattr_error = NFS4_OK;
151 sarg.rdattr_error_req = FALSE;
152 sarg.is_referral = B_FALSE;
153
154 rfs4_ntov_init();
155
156 rfs4_supported_attrs = 0;
157 for (i = 0; i < NFS4_MAXNUM_ATTRS; i++) {
158 #ifdef RFS4_SUPPORT_MANDATTR_ONLY
1286 if (sarg->vap->va_nodeid != na->fileid)
1287 error = -1; /* no match */
1288 break;
1289 case NFS4ATTR_FREEIT:
1290 break;
1291 }
1292 return (error);
1293 }
1294
1295 /* ARGSUSED */
1296 static int
1297 rfs4_get_mntdfileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg)
1298 {
1299 int error = 0;
1300 vattr_t *vap, va;
1301 vnode_t *stubvp = NULL, *vp;
1302
1303 vp = sarg->cs->vp;
1304 sarg->mntdfid_set = FALSE;
1305
1306 /* VROOT object, must untraverse */
1307 if (vp->v_flag & VROOT) {
1308
1309 /* extra hold for vp since untraverse might rele */
1310 VN_HOLD(vp);
1311 stubvp = untraverse(vp);
1312
1313 /*
1314 * If vp/stubvp are same, we must be at system
1315 * root because untraverse returned same vp
1316 * for a VROOT object. sarg->vap was setup
1317 * before we got here, so there's no need to do
1318 * another getattr -- just use the one in sarg.
1319 */
1320 if (VN_CMP(vp, stubvp)) {
1321 ASSERT(VN_CMP(vp, ZONE_ROOTVP()));
1322 vap = sarg->vap;
1323 } else {
1324 va.va_mask = AT_NODEID;
1325 vap = &va;
1326 error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr);
1327 }
1328
1329 /*
1330 * Done with stub, time to rele. If vp and stubvp
1331 * were the same, then we need to rele either vp or
1332 * stubvp. If they weren't the same, then untraverse()
1333 * already took case of the extra hold on vp, and only
1334 * the stub needs to be rele'd. Both cases are handled
1335 * by unconditionally rele'ing the stub.
1336 */
1337 VN_RELE(stubvp);
1338 } else
1339 vap = sarg->vap;
1340
1341 /*
1360 return (error);
1361 }
1362
1363 /* ARGSUSED */
1364 static int
1365 rfs4_fattr4_mounted_on_fileid(nfs4_attr_cmd_t cmd,
1366 struct nfs4_svgetit_arg *sarg, union nfs4_attr_u *na)
1367 {
1368 int error = 0;
1369
1370 if (RFS4_MANDATTR_ONLY)
1371 return (ENOTSUP);
1372
1373 switch (cmd) {
1374 case NFS4ATTR_SUPPORTED:
1375 if (sarg->op == NFS4ATTR_SETIT)
1376 error = EINVAL;
1377 break; /* this attr is supported */
1378 case NFS4ATTR_GETIT:
1379 case NFS4ATTR_VERIT:
1380 if (! sarg->mntdfid_set)
1381 error = rfs4_get_mntdfileid(cmd, sarg);
1382
1383 if (! error && sarg->mntdfid_set) {
1384 if (cmd == NFS4ATTR_GETIT)
1385 na->mounted_on_fileid = sarg->mounted_on_fileid;
1386 else
1387 if (na->mounted_on_fileid !=
1388 sarg->mounted_on_fileid)
1389 error = -1;
1390 }
1391 break;
1392 case NFS4ATTR_SETIT:
1393 /* read-only attr */
1394 error = EINVAL;
1395 break;
1396 case NFS4ATTR_FREEIT:
1397 break;
1398 }
1399 return (error);
1400 }
1401
1402 /* ARGSUSED */
1403 static int
|
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++) {
163 #ifdef RFS4_SUPPORT_MANDATTR_ONLY
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);
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
|