* Clear POSIX style locks. This is only used when fdp looses a reference (i.e. * one of processes using it exits) and the table used to be shared. */
| 2439 | * one of processes using it exits) and the table used to be shared. |
| 2440 | */ |
| 2441 | static void |
| 2442 | fdclearlocks(struct thread *td) |
| 2443 | { |
| 2444 | struct filedesc *fdp; |
| 2445 | struct filedesc_to_leader *fdtol; |
| 2446 | struct flock lf; |
| 2447 | struct file *fp; |
| 2448 | struct proc *p; |
| 2449 | struct vnode *vp; |
| 2450 | int i, lastfile; |
| 2451 | |
| 2452 | p = td->td_proc; |
| 2453 | fdp = p->p_fd; |
| 2454 | fdtol = p->p_fdtol; |
| 2455 | MPASS(fdtol != NULL); |
| 2456 | |
| 2457 | FILEDESC_XLOCK(fdp); |
| 2458 | KASSERT(fdtol->fdl_refcount > 0, |
| 2459 | ("filedesc_to_refcount botch: fdl_refcount=%d", |
| 2460 | fdtol->fdl_refcount)); |
| 2461 | if (fdtol->fdl_refcount == 1 && |
| 2462 | (p->p_leader->p_flag & P_ADVLOCK) != 0) { |
| 2463 | lastfile = fdlastfile(fdp); |
| 2464 | for (i = 0; i <= lastfile; i++) { |
| 2465 | fp = fdp->fd_ofiles[i].fde_file; |
| 2466 | if (fp == NULL || fp->f_type != DTYPE_VNODE || |
| 2467 | !fhold(fp)) |
| 2468 | continue; |
| 2469 | FILEDESC_XUNLOCK(fdp); |
| 2470 | lf.l_whence = SEEK_SET; |
| 2471 | lf.l_start = 0; |
| 2472 | lf.l_len = 0; |
| 2473 | lf.l_type = F_UNLCK; |
| 2474 | vp = fp->f_vnode; |
| 2475 | (void) VOP_ADVLOCK(vp, |
| 2476 | (caddr_t)p->p_leader, F_UNLCK, |
| 2477 | &lf, F_POSIX); |
| 2478 | FILEDESC_XLOCK(fdp); |
| 2479 | fdrop(fp, td); |
| 2480 | } |
| 2481 | } |
| 2482 | retry: |
| 2483 | if (fdtol->fdl_refcount == 1) { |
| 2484 | if (fdp->fd_holdleaderscount > 0 && |
| 2485 | (p->p_leader->p_flag & P_ADVLOCK) != 0) { |
| 2486 | /* |
| 2487 | * close() or kern_dup() has cleared a reference |
| 2488 | * in a shared file descriptor table. |
| 2489 | */ |
| 2490 | fdp->fd_holdleaderswakeup = 1; |
| 2491 | sx_sleep(&fdp->fd_holdleaderscount, |
| 2492 | FILEDESC_LOCK(fdp), PLOCK, "fdlhold", 0); |
| 2493 | goto retry; |
| 2494 | } |
| 2495 | if (fdtol->fdl_holdcount > 0) { |
| 2496 | /* |
| 2497 | * Ensure that fdtol->fdl_leader remains |
| 2498 | * valid in closef(). |
no test coverage detected