Print this page
Revert exi_zone to exi_zoneid, and install exi_ne backpointer
Caution with use after exi_rele()
Dan mods to NFS desgin problems re. multiple zone keys
curzone reality check and teardown changes to use the RIGHT zone
Try to remove assumption that zone's root vnode is marked VROOT


 400                 *exip = exi;
 401 
 402                 VN_RELE(*vpp);
 403                 *vpp = vp;
 404         }
 405 
 406         return (0);
 407 }
 408 
 409 /*
 410  * Given mounted "dvp" and "exi", go upper mountpoint
 411  * with dvp/exi correction
 412  * Return 0 in success
 413  */
 414 int
 415 rfs_climb_crossmnt(vnode_t **dvpp, struct exportinfo **exip, cred_t *cr)
 416 {
 417         struct exportinfo *exi;
 418         vnode_t *dvp = *dvpp;
 419 
 420         ASSERT(dvp->v_flag & VROOT);

 421 
 422         VN_HOLD(dvp);
 423         dvp = untraverse(dvp);
 424         exi = nfs_vptoexi(NULL, dvp, cr, NULL, NULL, FALSE);
 425         if (exi == NULL) {
 426                 VN_RELE(dvp);
 427                 return (-1);
 428         }
 429 

 430         exi_rele(*exip);
 431         *exip = exi;
 432         VN_RELE(*dvpp);
 433         *dvpp = dvp;
 434 
 435         return (0);
 436 }
 437 /*
 438  * Directory lookup.
 439  * Returns an fhandle and file attributes for file name in a directory.
 440  */
 441 /* ARGSUSED */
 442 void
 443 rfs_lookup(struct nfsdiropargs *da, struct nfsdiropres *dr,
 444     struct exportinfo *exi, struct svc_req *req, cred_t *cr, bool_t ro)
 445 {
 446         int error;
 447         vnode_t *dvp;
 448         vnode_t *vp;
 449         struct vattr va;


 470                 dr->dr_status = NFSERR_ACCES;
 471                 return;
 472         }
 473 
 474         /*
 475          * Allow lookups from the root - the default
 476          * location of the public filehandle.
 477          */
 478         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 479                 dvp = ZONE_ROOTVP();
 480                 VN_HOLD(dvp);
 481         } else {
 482                 dvp = nfs_fhtovp(fhp, exi);
 483                 if (dvp == NULL) {
 484                         dr->dr_status = NFSERR_STALE;
 485                         return;
 486                 }
 487         }
 488 
 489         exi_hold(exi);

 490 
 491         /*
 492          * Not allow lookup beyond root.
 493          * If the filehandle matches a filehandle of the exi,
 494          * then the ".." refers beyond the root of an exported filesystem.
 495          */
 496         if (strcmp(da->da_name, "..") == 0 &&
 497             EQFID(&exi->exi_fid, (fid_t *)&fhp->fh_len)) {
 498                 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
 499                     (dvp->v_flag & VROOT)) {
 500                         /*
 501                          * special case for ".." and 'nohide'exported root
 502                          */
 503                         if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
 504                                 error = NFSERR_ACCES;
 505                                 goto out;
 506                         }
 507                 } else  {
 508                         error = NFSERR_NOENT;
 509                         goto out;
 510                 }
 511         }
 512 
 513         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 514         name = nfscmd_convname(ca, exi, da->da_name, NFSCMD_CONV_INBOUND,
 515             MAXPATHLEN);
 516 
 517         if (name == NULL) {
 518                 error = NFSERR_ACCES;
 519                 goto out;
 520         }
 521 
 522         /*
 523          * If the public filehandle is used then allow
 524          * a multi-component lookup, i.e. evaluate
 525          * a pathname and follow symbolic links if
 526          * necessary.
 527          *
 528          * This may result in a vnode in another filesystem
 529          * which is OK as long as the filesystem is exported.
 530          */
 531         if (PUBLIC_FH2(fhp)) {
 532                 publicfh_flag = TRUE;
 533 
 534                 exi_rele(exi);

 535 
 536                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp, &exi,
 537                     &sec);
 538         } else {
 539                 /*
 540                  * Do a normal single component lookup.
 541                  */
 542                 error = VOP_LOOKUP(dvp, name, &vp, NULL, 0, NULL, cr,
 543                     NULL, NULL, NULL);
 544         }
 545 
 546         if (name != da->da_name)
 547                 kmem_free(name, MAXPATHLEN);
 548 
 549         if (error == 0 && vn_ismntpt(vp)) {
 550                 error = rfs_cross_mnt(&vp, &exi);
 551                 if (error)
 552                         VN_RELE(vp);
 553         }
 554 


1301         struct rfs_async_write *trp;
1302         struct rfs_async_write *lrp;
1303         int data_written;
1304         int iovcnt;
1305         mblk_t *m;
1306         struct iovec *iovp;
1307         struct iovec *niovp;
1308         struct iovec iov[MAXCLIOVECS];
1309         int count;
1310         int rcount;
1311         uint_t off;
1312         uint_t len;
1313         struct rfs_async_write nrpsp;
1314         struct rfs_async_write_list nlpsp;
1315         ushort_t t_flag;
1316         cred_t *savecred;
1317         int in_crit = 0;
1318         caller_context_t ct;
1319         nfs_srv_t *nsrv;
1320 

1321         nsrv = nfs_get_srv();
1322         if (!nsrv->write_async) {
1323                 rfs_write_sync(wa, ns, exi, req, cr, ro);
1324                 return;
1325         }
1326 
1327         /*
1328          * Initialize status to RFSWRITE_INITVAL instead of 0, since value of 0
1329          * is considered an OK.
1330          */
1331         ns->ns_status = RFSWRITE_INITVAL;
1332 
1333         nrp = &nrpsp;
1334         nrp->wa = wa;
1335         nrp->ns = ns;
1336         nrp->req = req;
1337         nrp->cr = cr;
1338         nrp->ro = ro;
1339         nrp->thread = curthread;
1340 




 400                 *exip = exi;
 401 
 402                 VN_RELE(*vpp);
 403                 *vpp = vp;
 404         }
 405 
 406         return (0);
 407 }
 408 
 409 /*
 410  * Given mounted "dvp" and "exi", go upper mountpoint
 411  * with dvp/exi correction
 412  * Return 0 in success
 413  */
 414 int
 415 rfs_climb_crossmnt(vnode_t **dvpp, struct exportinfo **exip, cred_t *cr)
 416 {
 417         struct exportinfo *exi;
 418         vnode_t *dvp = *dvpp;
 419 
 420         ASSERT3U((*exip)->exi_zoneid, ==, curzone->zone_id);
 421         ASSERT((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp));
 422 
 423         VN_HOLD(dvp);
 424         dvp = untraverse(dvp);
 425         exi = nfs_vptoexi(NULL, dvp, cr, NULL, NULL, FALSE);
 426         if (exi == NULL) {
 427                 VN_RELE(dvp);
 428                 return (-1);
 429         }
 430 
 431         ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
 432         exi_rele(*exip);
 433         *exip = exi;
 434         VN_RELE(*dvpp);
 435         *dvpp = dvp;
 436 
 437         return (0);
 438 }
 439 /*
 440  * Directory lookup.
 441  * Returns an fhandle and file attributes for file name in a directory.
 442  */
 443 /* ARGSUSED */
 444 void
 445 rfs_lookup(struct nfsdiropargs *da, struct nfsdiropres *dr,
 446     struct exportinfo *exi, struct svc_req *req, cred_t *cr, bool_t ro)
 447 {
 448         int error;
 449         vnode_t *dvp;
 450         vnode_t *vp;
 451         struct vattr va;


 472                 dr->dr_status = NFSERR_ACCES;
 473                 return;
 474         }
 475 
 476         /*
 477          * Allow lookups from the root - the default
 478          * location of the public filehandle.
 479          */
 480         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 481                 dvp = ZONE_ROOTVP();
 482                 VN_HOLD(dvp);
 483         } else {
 484                 dvp = nfs_fhtovp(fhp, exi);
 485                 if (dvp == NULL) {
 486                         dr->dr_status = NFSERR_STALE;
 487                         return;
 488                 }
 489         }
 490 
 491         exi_hold(exi);
 492         ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
 493 
 494         /*
 495          * Not allow lookup beyond root.
 496          * If the filehandle matches a filehandle of the exi,
 497          * then the ".." refers beyond the root of an exported filesystem.
 498          */
 499         if (strcmp(da->da_name, "..") == 0 &&
 500             EQFID(&exi->exi_fid, (fid_t *)&fhp->fh_len)) {
 501                 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
 502                     ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp))) {
 503                         /*
 504                          * special case for ".." and 'nohide'exported root
 505                          */
 506                         if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
 507                                 error = NFSERR_ACCES;
 508                                 goto out;
 509                         }
 510                 } else  {
 511                         error = NFSERR_NOENT;
 512                         goto out;
 513                 }
 514         }
 515 
 516         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 517         name = nfscmd_convname(ca, exi, da->da_name, NFSCMD_CONV_INBOUND,
 518             MAXPATHLEN);
 519 
 520         if (name == NULL) {
 521                 error = NFSERR_ACCES;
 522                 goto out;
 523         }
 524 
 525         /*
 526          * If the public filehandle is used then allow
 527          * a multi-component lookup, i.e. evaluate
 528          * a pathname and follow symbolic links if
 529          * necessary.
 530          *
 531          * This may result in a vnode in another filesystem
 532          * which is OK as long as the filesystem is exported.
 533          */
 534         if (PUBLIC_FH2(fhp)) {
 535                 publicfh_flag = TRUE;
 536 
 537                 exi_rele(exi);
 538                 exi = NULL;
 539 
 540                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp, &exi,
 541                     &sec);
 542         } else {
 543                 /*
 544                  * Do a normal single component lookup.
 545                  */
 546                 error = VOP_LOOKUP(dvp, name, &vp, NULL, 0, NULL, cr,
 547                     NULL, NULL, NULL);
 548         }
 549 
 550         if (name != da->da_name)
 551                 kmem_free(name, MAXPATHLEN);
 552 
 553         if (error == 0 && vn_ismntpt(vp)) {
 554                 error = rfs_cross_mnt(&vp, &exi);
 555                 if (error)
 556                         VN_RELE(vp);
 557         }
 558 


1305         struct rfs_async_write *trp;
1306         struct rfs_async_write *lrp;
1307         int data_written;
1308         int iovcnt;
1309         mblk_t *m;
1310         struct iovec *iovp;
1311         struct iovec *niovp;
1312         struct iovec iov[MAXCLIOVECS];
1313         int count;
1314         int rcount;
1315         uint_t off;
1316         uint_t len;
1317         struct rfs_async_write nrpsp;
1318         struct rfs_async_write_list nlpsp;
1319         ushort_t t_flag;
1320         cred_t *savecred;
1321         int in_crit = 0;
1322         caller_context_t ct;
1323         nfs_srv_t *nsrv;
1324 
1325         ASSERT(exi == NULL || exi->exi_zoneid == curzone->zone_id);
1326         nsrv = nfs_get_srv();
1327         if (!nsrv->write_async) {
1328                 rfs_write_sync(wa, ns, exi, req, cr, ro);
1329                 return;
1330         }
1331 
1332         /*
1333          * Initialize status to RFSWRITE_INITVAL instead of 0, since value of 0
1334          * is considered an OK.
1335          */
1336         ns->ns_status = RFSWRITE_INITVAL;
1337 
1338         nrp = &nrpsp;
1339         nrp->wa = wa;
1340         nrp->ns = ns;
1341         nrp->req = req;
1342         nrp->cr = cr;
1343         nrp->ro = ro;
1344         nrp->thread = curthread;
1345