| 4465 | } |
| 4466 | |
| 4467 | int |
| 4468 | kern_fhopen(struct thread *td, const struct fhandle *u_fhp, int flags) |
| 4469 | { |
| 4470 | struct mount *mp; |
| 4471 | struct vnode *vp; |
| 4472 | struct fhandle fhp; |
| 4473 | struct file *fp; |
| 4474 | int fmode, error; |
| 4475 | int indx; |
| 4476 | |
| 4477 | error = priv_check(td, PRIV_VFS_FHOPEN); |
| 4478 | if (error != 0) |
| 4479 | return (error); |
| 4480 | indx = -1; |
| 4481 | fmode = FFLAGS(flags); |
| 4482 | /* why not allow a non-read/write open for our lockd? */ |
| 4483 | if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) |
| 4484 | return (EINVAL); |
| 4485 | error = copyin(u_fhp, &fhp, sizeof(fhp)); |
| 4486 | if (error != 0) |
| 4487 | return(error); |
| 4488 | /* find the mount point */ |
| 4489 | mp = vfs_busyfs(&fhp.fh_fsid); |
| 4490 | if (mp == NULL) |
| 4491 | return (ESTALE); |
| 4492 | /* now give me my vnode, it gets returned to me locked */ |
| 4493 | error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp); |
| 4494 | vfs_unbusy(mp); |
| 4495 | if (error != 0) |
| 4496 | return (error); |
| 4497 | |
| 4498 | error = falloc_noinstall(td, &fp); |
| 4499 | if (error != 0) { |
| 4500 | vput(vp); |
| 4501 | return (error); |
| 4502 | } |
| 4503 | /* |
| 4504 | * An extra reference on `fp' has been held for us by |
| 4505 | * falloc_noinstall(). |
| 4506 | */ |
| 4507 | |
| 4508 | #ifdef INVARIANTS |
| 4509 | td->td_dupfd = -1; |
| 4510 | #endif |
| 4511 | error = vn_open_vnode(vp, fmode, td->td_ucred, td, fp); |
| 4512 | if (error != 0) { |
| 4513 | KASSERT(fp->f_ops == &badfileops, |
| 4514 | ("VOP_OPEN in fhopen() set f_ops")); |
| 4515 | KASSERT(td->td_dupfd < 0, |
| 4516 | ("fhopen() encountered fdopen()")); |
| 4517 | |
| 4518 | vput(vp); |
| 4519 | goto bad; |
| 4520 | } |
| 4521 | #ifdef INVARIANTS |
| 4522 | td->td_dupfd = 0; |
| 4523 | #endif |
| 4524 | fp->f_vnode = vp; |
no test coverage detected