* Common code for vnode open operations once a vnode is located. * Check permissions, and call the VOP_OPEN routine. */
| 363 | * Check permissions, and call the VOP_OPEN routine. |
| 364 | */ |
| 365 | int |
| 366 | vn_open_vnode(struct vnode *vp, int fmode, struct ucred *cred, |
| 367 | struct thread *td, struct file *fp) |
| 368 | { |
| 369 | accmode_t accmode; |
| 370 | int error; |
| 371 | |
| 372 | if (vp->v_type == VLNK) |
| 373 | return (EMLINK); |
| 374 | if (vp->v_type == VSOCK) |
| 375 | return (EOPNOTSUPP); |
| 376 | if (vp->v_type != VDIR && fmode & O_DIRECTORY) |
| 377 | return (ENOTDIR); |
| 378 | accmode = 0; |
| 379 | if (fmode & (FWRITE | O_TRUNC)) { |
| 380 | if (vp->v_type == VDIR) |
| 381 | return (EISDIR); |
| 382 | accmode |= VWRITE; |
| 383 | } |
| 384 | if (fmode & FREAD) |
| 385 | accmode |= VREAD; |
| 386 | if (fmode & FEXEC) |
| 387 | accmode |= VEXEC; |
| 388 | if ((fmode & O_APPEND) && (fmode & FWRITE)) |
| 389 | accmode |= VAPPEND; |
| 390 | #ifdef MAC |
| 391 | if (fmode & O_CREAT) |
| 392 | accmode |= VCREAT; |
| 393 | if (fmode & O_VERIFY) |
| 394 | accmode |= VVERIFY; |
| 395 | error = mac_vnode_check_open(cred, vp, accmode); |
| 396 | if (error) |
| 397 | return (error); |
| 398 | |
| 399 | accmode &= ~(VCREAT | VVERIFY); |
| 400 | #endif |
| 401 | if ((fmode & O_CREAT) == 0 && accmode != 0) { |
| 402 | error = VOP_ACCESS(vp, accmode, cred, td); |
| 403 | if (error != 0) |
| 404 | return (error); |
| 405 | } |
| 406 | if (vp->v_type == VFIFO && VOP_ISLOCKED(vp) != LK_EXCLUSIVE) |
| 407 | vn_lock(vp, LK_UPGRADE | LK_RETRY); |
| 408 | error = VOP_OPEN(vp, fmode, cred, td, fp); |
| 409 | if (error != 0) |
| 410 | return (error); |
| 411 | |
| 412 | error = vn_open_vnode_advlock(vp, fmode, fp); |
| 413 | if (error == 0 && (fmode & FWRITE) != 0) { |
| 414 | error = VOP_ADD_WRITECOUNT(vp, 1); |
| 415 | if (error == 0) { |
| 416 | CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", |
| 417 | __func__, vp, vp->v_writecount); |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | /* |
| 422 | * Error from advlock or VOP_ADD_WRITECOUNT() still requires |
no test coverage detected