| 328 | } |
| 329 | |
| 330 | static int |
| 331 | vn_open_vnode_advlock(struct vnode *vp, int fmode, struct file *fp) |
| 332 | { |
| 333 | struct flock lf; |
| 334 | int error, lock_flags, type; |
| 335 | |
| 336 | ASSERT_VOP_LOCKED(vp, "vn_open_vnode_advlock"); |
| 337 | if ((fmode & (O_EXLOCK | O_SHLOCK)) == 0) |
| 338 | return (0); |
| 339 | KASSERT(fp != NULL, ("open with flock requires fp")); |
| 340 | if (fp->f_type != DTYPE_NONE && fp->f_type != DTYPE_VNODE) |
| 341 | return (EOPNOTSUPP); |
| 342 | |
| 343 | lock_flags = VOP_ISLOCKED(vp); |
| 344 | VOP_UNLOCK(vp); |
| 345 | |
| 346 | lf.l_whence = SEEK_SET; |
| 347 | lf.l_start = 0; |
| 348 | lf.l_len = 0; |
| 349 | lf.l_type = (fmode & O_EXLOCK) != 0 ? F_WRLCK : F_RDLCK; |
| 350 | type = F_FLOCK; |
| 351 | if ((fmode & FNONBLOCK) == 0) |
| 352 | type |= F_WAIT; |
| 353 | error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type); |
| 354 | if (error == 0) |
| 355 | fp->f_flag |= FHASLOCK; |
| 356 | |
| 357 | vn_lock(vp, lock_flags | LK_RETRY); |
| 358 | return (error); |
| 359 | } |
| 360 | |
| 361 | /* |
| 362 | * Common code for vnode open operations once a vnode is located. |
no test coverage detected