394 *exip = exi;
395
396 VN_RELE(*vpp);
397 *vpp = vp;
398 }
399
400 return (0);
401 }
402
403 /*
404 * Given mounted "dvp" and "exi", go upper mountpoint
405 * with dvp/exi correction
406 * Return 0 in success
407 */
408 int
409 rfs_climb_crossmnt(vnode_t **dvpp, struct exportinfo **exip, cred_t *cr)
410 {
411 struct exportinfo *exi;
412 vnode_t *dvp = *dvpp;
413
414 ASSERT((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp));
415
416 VN_HOLD(dvp);
417 dvp = untraverse(dvp);
418 exi = nfs_vptoexi(NULL, dvp, cr, NULL, NULL, FALSE);
419 if (exi == NULL) {
420 VN_RELE(dvp);
421 return (-1);
422 }
423
424 exi_rele(*exip);
425 *exip = exi;
426 VN_RELE(*dvpp);
427 *dvpp = dvp;
428
429 return (0);
430 }
431 /*
432 * Directory lookup.
433 * Returns an fhandle and file attributes for file name in a directory.
434 */
435 /* ARGSUSED */
436 void
437 rfs_lookup(struct nfsdiropargs *da, struct nfsdiropres *dr,
438 struct exportinfo *exi, struct svc_req *req, cred_t *cr, bool_t ro)
439 {
440 int error;
441 vnode_t *dvp;
442 vnode_t *vp;
443 struct vattr va;
464 dr->dr_status = NFSERR_ACCES;
465 return;
466 }
467
468 /*
469 * Allow lookups from the root - the default
470 * location of the public filehandle.
471 */
472 if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
473 dvp = ZONE_ROOTVP();
474 VN_HOLD(dvp);
475 } else {
476 dvp = nfs_fhtovp(fhp, exi);
477 if (dvp == NULL) {
478 dr->dr_status = NFSERR_STALE;
479 return;
480 }
481 }
482
483 exi_hold(exi);
484
485 /*
486 * Not allow lookup beyond root.
487 * If the filehandle matches a filehandle of the exi,
488 * then the ".." refers beyond the root of an exported filesystem.
489 */
490 if (strcmp(da->da_name, "..") == 0 &&
491 EQFID(&exi->exi_fid, (fid_t *)&fhp->fh_len)) {
492 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
493 ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp))) {
494 /*
495 * special case for ".." and 'nohide'exported root
496 */
497 if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
498 error = NFSERR_ACCES;
499 goto out;
500 }
501 } else {
502 error = NFSERR_NOENT;
503 goto out;
1295 struct rfs_async_write *trp;
1296 struct rfs_async_write *lrp;
1297 int data_written;
1298 int iovcnt;
1299 mblk_t *m;
1300 struct iovec *iovp;
1301 struct iovec *niovp;
1302 struct iovec iov[MAXCLIOVECS];
1303 int count;
1304 int rcount;
1305 uint_t off;
1306 uint_t len;
1307 struct rfs_async_write nrpsp;
1308 struct rfs_async_write_list nlpsp;
1309 ushort_t t_flag;
1310 cred_t *savecred;
1311 int in_crit = 0;
1312 caller_context_t ct;
1313 nfs_srv_t *nsrv;
1314
1315 nsrv = zone_getspecific(rfs_zone_key, curzone);
1316 if (!nsrv->write_async) {
1317 rfs_write_sync(wa, ns, exi, req, cr, ro);
1318 return;
1319 }
1320
1321 /*
1322 * Initialize status to RFSWRITE_INITVAL instead of 0, since value of 0
1323 * is considered an OK.
1324 */
1325 ns->ns_status = RFSWRITE_INITVAL;
1326
1327 nrp = &nrpsp;
1328 nrp->wa = wa;
1329 nrp->ns = ns;
1330 nrp->req = req;
1331 nrp->cr = cr;
1332 nrp->ro = ro;
1333 nrp->thread = curthread;
1334
|
394 *exip = exi;
395
396 VN_RELE(*vpp);
397 *vpp = vp;
398 }
399
400 return (0);
401 }
402
403 /*
404 * Given mounted "dvp" and "exi", go upper mountpoint
405 * with dvp/exi correction
406 * Return 0 in success
407 */
408 int
409 rfs_climb_crossmnt(vnode_t **dvpp, struct exportinfo **exip, cred_t *cr)
410 {
411 struct exportinfo *exi;
412 vnode_t *dvp = *dvpp;
413
414 ASSERT3P((*exip)->exi_zone, ==, curzone);
415 ASSERT((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp));
416
417 VN_HOLD(dvp);
418 dvp = untraverse(dvp);
419 exi = nfs_vptoexi(NULL, dvp, cr, NULL, NULL, FALSE);
420 if (exi == NULL) {
421 VN_RELE(dvp);
422 return (-1);
423 }
424
425 ASSERT3P(exi->exi_zone, ==, curzone);
426 exi_rele(*exip);
427 *exip = exi;
428 VN_RELE(*dvpp);
429 *dvpp = dvp;
430
431 return (0);
432 }
433 /*
434 * Directory lookup.
435 * Returns an fhandle and file attributes for file name in a directory.
436 */
437 /* ARGSUSED */
438 void
439 rfs_lookup(struct nfsdiropargs *da, struct nfsdiropres *dr,
440 struct exportinfo *exi, struct svc_req *req, cred_t *cr, bool_t ro)
441 {
442 int error;
443 vnode_t *dvp;
444 vnode_t *vp;
445 struct vattr va;
466 dr->dr_status = NFSERR_ACCES;
467 return;
468 }
469
470 /*
471 * Allow lookups from the root - the default
472 * location of the public filehandle.
473 */
474 if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
475 dvp = ZONE_ROOTVP();
476 VN_HOLD(dvp);
477 } else {
478 dvp = nfs_fhtovp(fhp, exi);
479 if (dvp == NULL) {
480 dr->dr_status = NFSERR_STALE;
481 return;
482 }
483 }
484
485 exi_hold(exi);
486 ASSERT3P(exi->exi_zone, ==, curzone);
487
488 /*
489 * Not allow lookup beyond root.
490 * If the filehandle matches a filehandle of the exi,
491 * then the ".." refers beyond the root of an exported filesystem.
492 */
493 if (strcmp(da->da_name, "..") == 0 &&
494 EQFID(&exi->exi_fid, (fid_t *)&fhp->fh_len)) {
495 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
496 ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp))) {
497 /*
498 * special case for ".." and 'nohide'exported root
499 */
500 if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
501 error = NFSERR_ACCES;
502 goto out;
503 }
504 } else {
505 error = NFSERR_NOENT;
506 goto out;
1298 struct rfs_async_write *trp;
1299 struct rfs_async_write *lrp;
1300 int data_written;
1301 int iovcnt;
1302 mblk_t *m;
1303 struct iovec *iovp;
1304 struct iovec *niovp;
1305 struct iovec iov[MAXCLIOVECS];
1306 int count;
1307 int rcount;
1308 uint_t off;
1309 uint_t len;
1310 struct rfs_async_write nrpsp;
1311 struct rfs_async_write_list nlpsp;
1312 ushort_t t_flag;
1313 cred_t *savecred;
1314 int in_crit = 0;
1315 caller_context_t ct;
1316 nfs_srv_t *nsrv;
1317
1318 ASSERT3P(curzone, ==, ((exi == NULL) ? curzone : exi->exi_zone));
1319 nsrv = zone_getspecific(rfs_zone_key, curzone);
1320 if (!nsrv->write_async) {
1321 rfs_write_sync(wa, ns, exi, req, cr, ro);
1322 return;
1323 }
1324
1325 /*
1326 * Initialize status to RFSWRITE_INITVAL instead of 0, since value of 0
1327 * is considered an OK.
1328 */
1329 ns->ns_status = RFSWRITE_INITVAL;
1330
1331 nrp = &nrpsp;
1332 nrp->wa = wa;
1333 nrp->ns = ns;
1334 nrp->req = req;
1335 nrp->cr = cr;
1336 nrp->ro = ro;
1337 nrp->thread = curthread;
1338
|