* Preparing to start a filesystem write operation. If the operation is * permitted, then we bump the count of operations in progress and * proceed. If a suspend request is in progress, we wait until the * suspension is over, and then proceed. */
| 1780 | * suspension is over, and then proceed. |
| 1781 | */ |
| 1782 | static int |
| 1783 | vn_start_write_refed(struct mount *mp, int flags, bool mplocked) |
| 1784 | { |
| 1785 | struct mount_pcpu *mpcpu; |
| 1786 | int error, mflags; |
| 1787 | |
| 1788 | if (__predict_true(!mplocked) && (flags & V_XSLEEP) == 0 && |
| 1789 | vfs_op_thread_enter(mp, mpcpu)) { |
| 1790 | MPASS((mp->mnt_kern_flag & MNTK_SUSPEND) == 0); |
| 1791 | vfs_mp_count_add_pcpu(mpcpu, writeopcount, 1); |
| 1792 | vfs_op_thread_exit(mp, mpcpu); |
| 1793 | return (0); |
| 1794 | } |
| 1795 | |
| 1796 | if (mplocked) |
| 1797 | mtx_assert(MNT_MTX(mp), MA_OWNED); |
| 1798 | else |
| 1799 | MNT_ILOCK(mp); |
| 1800 | |
| 1801 | error = 0; |
| 1802 | |
| 1803 | /* |
| 1804 | * Check on status of suspension. |
| 1805 | */ |
| 1806 | if ((curthread->td_pflags & TDP_IGNSUSP) == 0 || |
| 1807 | mp->mnt_susp_owner != curthread) { |
| 1808 | mflags = ((mp->mnt_vfc->vfc_flags & VFCF_SBDRY) != 0 ? |
| 1809 | (flags & PCATCH) : 0) | (PUSER - 1); |
| 1810 | while ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) { |
| 1811 | if (flags & V_NOWAIT) { |
| 1812 | error = EWOULDBLOCK; |
| 1813 | goto unlock; |
| 1814 | } |
| 1815 | error = msleep(&mp->mnt_flag, MNT_MTX(mp), mflags, |
| 1816 | "suspfs", 0); |
| 1817 | if (error) |
| 1818 | goto unlock; |
| 1819 | } |
| 1820 | } |
| 1821 | if (flags & V_XSLEEP) |
| 1822 | goto unlock; |
| 1823 | mp->mnt_writeopcount++; |
| 1824 | unlock: |
| 1825 | if (error != 0 || (flags & V_XSLEEP) != 0) |
| 1826 | MNT_REL(mp); |
| 1827 | MNT_IUNLOCK(mp); |
| 1828 | return (error); |
| 1829 | } |
| 1830 | |
| 1831 | int |
| 1832 | vn_start_write(struct vnode *vp, struct mount **mpp, int flags) |
no test coverage detected