* Internal form of close. Decrement reference count on file structure. * Note: td may be NULL when closing a file that was being passed in a * message. */
| 2843 | * message. |
| 2844 | */ |
| 2845 | int |
| 2846 | closef(struct file *fp, struct thread *td) |
| 2847 | { |
| 2848 | struct vnode *vp; |
| 2849 | struct flock lf; |
| 2850 | struct filedesc_to_leader *fdtol; |
| 2851 | struct filedesc *fdp; |
| 2852 | |
| 2853 | MPASS(td != NULL); |
| 2854 | |
| 2855 | /* |
| 2856 | * POSIX record locking dictates that any close releases ALL |
| 2857 | * locks owned by this process. This is handled by setting |
| 2858 | * a flag in the unlock to free ONLY locks obeying POSIX |
| 2859 | * semantics, and not to free BSD-style file locks. |
| 2860 | * If the descriptor was in a message, POSIX-style locks |
| 2861 | * aren't passed with the descriptor, and the thread pointer |
| 2862 | * will be NULL. Callers should be careful only to pass a |
| 2863 | * NULL thread pointer when there really is no owning |
| 2864 | * context that might have locks, or the locks will be |
| 2865 | * leaked. |
| 2866 | */ |
| 2867 | if (fp->f_type == DTYPE_VNODE) { |
| 2868 | vp = fp->f_vnode; |
| 2869 | if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) { |
| 2870 | lf.l_whence = SEEK_SET; |
| 2871 | lf.l_start = 0; |
| 2872 | lf.l_len = 0; |
| 2873 | lf.l_type = F_UNLCK; |
| 2874 | (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader, |
| 2875 | F_UNLCK, &lf, F_POSIX); |
| 2876 | } |
| 2877 | fdtol = td->td_proc->p_fdtol; |
| 2878 | if (fdtol != NULL) { |
| 2879 | /* |
| 2880 | * Handle special case where file descriptor table is |
| 2881 | * shared between multiple process leaders. |
| 2882 | */ |
| 2883 | fdp = td->td_proc->p_fd; |
| 2884 | FILEDESC_XLOCK(fdp); |
| 2885 | for (fdtol = fdtol->fdl_next; |
| 2886 | fdtol != td->td_proc->p_fdtol; |
| 2887 | fdtol = fdtol->fdl_next) { |
| 2888 | if ((fdtol->fdl_leader->p_flag & |
| 2889 | P_ADVLOCK) == 0) |
| 2890 | continue; |
| 2891 | fdtol->fdl_holdcount++; |
| 2892 | FILEDESC_XUNLOCK(fdp); |
| 2893 | lf.l_whence = SEEK_SET; |
| 2894 | lf.l_start = 0; |
| 2895 | lf.l_len = 0; |
| 2896 | lf.l_type = F_UNLCK; |
| 2897 | vp = fp->f_vnode; |
| 2898 | (void) VOP_ADVLOCK(vp, |
| 2899 | (caddr_t)fdtol->fdl_leader, F_UNLCK, &lf, |
| 2900 | F_POSIX); |
| 2901 | FILEDESC_XLOCK(fdp); |
| 2902 | fdtol->fdl_holdcount--; |
no test coverage detected