| 747 | } |
| 748 | |
| 749 | void |
| 750 | foffset_unlock(struct file *fp, off_t val, int flags) |
| 751 | { |
| 752 | volatile short *flagsp; |
| 753 | short state; |
| 754 | |
| 755 | KASSERT((flags & FOF_OFFSET) == 0, ("FOF_OFFSET passed")); |
| 756 | |
| 757 | if ((flags & FOF_NOUPDATE) == 0) |
| 758 | atomic_store_long(&fp->f_offset, val); |
| 759 | if ((flags & FOF_NEXTOFF_R) != 0) |
| 760 | fp->f_nextoff[UIO_READ] = val; |
| 761 | if ((flags & FOF_NEXTOFF_W) != 0) |
| 762 | fp->f_nextoff[UIO_WRITE] = val; |
| 763 | |
| 764 | if ((flags & FOF_NOLOCK) != 0) |
| 765 | return; |
| 766 | |
| 767 | flagsp = &fp->f_vnread_flags; |
| 768 | state = atomic_load_16(flagsp); |
| 769 | if ((state & FOFFSET_LOCK_WAITING) == 0 && |
| 770 | atomic_cmpset_rel_16(flagsp, state, 0)) |
| 771 | return; |
| 772 | |
| 773 | sleepq_lock(&fp->f_vnread_flags); |
| 774 | MPASS((fp->f_vnread_flags & FOFFSET_LOCKED) != 0); |
| 775 | MPASS((fp->f_vnread_flags & FOFFSET_LOCK_WAITING) != 0); |
| 776 | fp->f_vnread_flags = 0; |
| 777 | sleepq_broadcast(&fp->f_vnread_flags, SLEEPQ_SLEEP, 0, 0); |
| 778 | sleepq_release(&fp->f_vnread_flags); |
| 779 | } |
| 780 | #else |
| 781 | off_t |
| 782 | foffset_lock(struct file *fp, int flags) |
no test coverage detected