| 1773 | } |
| 1774 | |
| 1775 | int |
| 1776 | aio_queue_file(struct file *fp, struct kaiocb *job) |
| 1777 | { |
| 1778 | struct kaioinfo *ki; |
| 1779 | struct kaiocb *job2; |
| 1780 | struct vnode *vp; |
| 1781 | struct mount *mp; |
| 1782 | int error; |
| 1783 | bool safe; |
| 1784 | |
| 1785 | ki = job->userproc->p_aioinfo; |
| 1786 | error = aio_qbio(job->userproc, job); |
| 1787 | if (error >= 0) |
| 1788 | return (error); |
| 1789 | safe = false; |
| 1790 | if (fp->f_type == DTYPE_VNODE) { |
| 1791 | vp = fp->f_vnode; |
| 1792 | if (vp->v_type == VREG || vp->v_type == VDIR) { |
| 1793 | mp = fp->f_vnode->v_mount; |
| 1794 | if (mp == NULL || (mp->mnt_flag & MNT_LOCAL) != 0) |
| 1795 | safe = true; |
| 1796 | } |
| 1797 | } |
| 1798 | if (!(safe || enable_aio_unsafe)) { |
| 1799 | counted_warning(&unsafe_warningcnt, |
| 1800 | "is attempting to use unsafe AIO requests"); |
| 1801 | return (EOPNOTSUPP); |
| 1802 | } |
| 1803 | |
| 1804 | if (job->uaiocb.aio_lio_opcode & (LIO_WRITE | LIO_READ)) { |
| 1805 | aio_schedule(job, aio_process_rw); |
| 1806 | error = 0; |
| 1807 | } else if (job->uaiocb.aio_lio_opcode & LIO_SYNC) { |
| 1808 | AIO_LOCK(ki); |
| 1809 | TAILQ_FOREACH(job2, &ki->kaio_jobqueue, plist) { |
| 1810 | if (job2->fd_file == job->fd_file && |
| 1811 | ((job2->uaiocb.aio_lio_opcode & LIO_SYNC) == 0) && |
| 1812 | job2->seqno < job->seqno) { |
| 1813 | job2->jobflags |= KAIOCB_CHECKSYNC; |
| 1814 | job->pending++; |
| 1815 | } |
| 1816 | } |
| 1817 | if (job->pending != 0) { |
| 1818 | if (!aio_set_cancel_function_locked(job, |
| 1819 | aio_cancel_sync)) { |
| 1820 | AIO_UNLOCK(ki); |
| 1821 | aio_cancel(job); |
| 1822 | return (0); |
| 1823 | } |
| 1824 | TAILQ_INSERT_TAIL(&ki->kaio_syncqueue, job, list); |
| 1825 | AIO_UNLOCK(ki); |
| 1826 | return (0); |
| 1827 | } |
| 1828 | AIO_UNLOCK(ki); |
| 1829 | aio_schedule(job, aio_process_sync); |
| 1830 | error = 0; |
| 1831 | } else { |
| 1832 | error = EINVAL; |
no test coverage detected