Print this page
*** NO COMMENTS ***

*** 324,333 **** --- 324,378 ---- rfs_setattr_getfh(struct nfssaargs *args) { return (&args->saa_fh); } + /* Change and release @exip and @vpp only in success */ + int + rfs_cross_mnt(vnode_t **vpp, struct exportinfo **exip) + { + struct exportinfo *exi; + vnode_t *vp; + fid_t fid; + int error; + + vp = *vpp; + + /* traverse() releases argument in success */ + VN_HOLD(*vpp); + + if ((error = traverse(&vp)) != 0) { + VN_RELE(*vpp); + return (error); + } + + bzero(&fid, sizeof (fid)); + fid.fid_len = MAXFIDSZ; + error = VOP_FID(vp, &fid, NULL); + if (error) { + VN_RELE(vp); + return (error); + } + + exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid); + if (exi == NULL || + (exi->exi_export.ex_flags & EX_NOHIDE) == 0) { + /* It is not error, just subdir is not exported + * or "nohide" is not set + */ + VN_RELE(vp); + } else { + /* go to submount */ + exi_rele(*exip); + *exip = exi; + + VN_RELE(*vpp); + *vpp = vp; + } + return (0); + } + /* * Directory lookup. * Returns an fhandle and file attributes for file name in a directory. */ /* ARGSUSED */
*** 397,419 **** if (name == NULL) { dr->dr_status = NFSERR_ACCES; return; } /* * If the public filehandle is used then allow * a multi-component lookup, i.e. evaluate * a pathname and follow symbolic links if * necessary. * * This may result in a vnode in another filesystem * which is OK as long as the filesystem is exported. */ if (PUBLIC_FH2(fhp)) { publicfh_flag = TRUE; ! error = rfs_publicfh_mclookup(name, dvp, cr, &vp, &exi, &sec); } else { /* * Do a normal single component lookup. */ error = VOP_LOOKUP(dvp, name, &vp, NULL, 0, NULL, cr, --- 442,473 ---- if (name == NULL) { dr->dr_status = NFSERR_ACCES; return; } + exi_hold(exi); + /* * If the public filehandle is used then allow * a multi-component lookup, i.e. evaluate * a pathname and follow symbolic links if * necessary. * * This may result in a vnode in another filesystem * which is OK as long as the filesystem is exported. */ if (PUBLIC_FH2(fhp)) { + struct exportinfo *new; + publicfh_flag = TRUE; ! error = rfs_publicfh_mclookup(name, dvp, cr, &vp, &new, &sec); + + if (error == 0) { + exi_rele(exi); + exi = new; + } } else { /* * Do a normal single component lookup. */ error = VOP_LOOKUP(dvp, name, &vp, NULL, 0, NULL, cr,
*** 421,430 **** --- 475,489 ---- } if (name != da->da_name) kmem_free(name, MAXPATHLEN); + if (error == 0 && vn_ismntpt(vp)) { + error = rfs_cross_mnt(&vp, &exi); + if (error) + VN_RELE(vp); + } if (!error) { va.va_mask = AT_ALL; /* we want everything */ error = rfs4_delegated_getattr(vp, &va, 0, cr);
*** 449,465 **** VN_RELE(vp); } VN_RELE(dvp); ! /* ! * If publicfh_flag is true then we have called rfs_publicfh_mclookup ! * and have obtained a new exportinfo in exi which needs to be ! * released. Note the the original exportinfo pointed to by exi ! * will be released by the caller, comon_dispatch. */ - if (publicfh_flag && exi != NULL) exi_rele(exi); /* * If it's public fh, no 0x81, and client's flavor is * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now. --- 508,520 ---- VN_RELE(vp); } VN_RELE(dvp); ! /* The passed argument exportinfo is released by the ! * caller, comon_dispatch */ exi_rele(exi); /* * If it's public fh, no 0x81, and client's flavor is * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.