Date: Sat, 22 May 2021 18:23:57 GMT From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 2923b7015ffb - stable/13 - vfs: add more safety against concurrent forced unmount to vn_write Message-ID: <202105221823.14MINvV9005880@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=2923b7015ffb808ed5219cb04d42d1756ba06361 commit 2923b7015ffb808ed5219cb04d42d1756ba06361 Author: Mateusz Guzik <mjg@FreeBSD.org> AuthorDate: 2021-05-14 11:26:56 +0000 Commit: Mateusz Guzik <mjg@FreeBSD.org> CommitDate: 2021-05-22 18:22:10 +0000 vfs: add more safety against concurrent forced unmount to vn_write 1. stop re-reading ->v_mount (can become NULL) 2. stop re-reading ->v_type (can change to VBAD) (cherry picked from commit ca1ce50b2b5ef11d85841f3aead98b2a9ad18819) --- sys/kern/vfs_vnops.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 8f583329f067..6bf798cd73c5 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1107,6 +1107,7 @@ vn_write(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, off_t orig_offset; int error, ioflag, lock_flags; int advice; + bool need_finished_write; KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); @@ -1121,9 +1122,11 @@ vn_write(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, ioflag |= IO_NDELAY; if (fp->f_flag & O_DIRECT) ioflag |= IO_DIRECT; - if ((fp->f_flag & O_FSYNC) || - (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS))) - ioflag |= IO_SYNC; + if (fp->f_flag & O_FSYNC) { + mp = atomic_load_ptr(&vp->v_mount); + if (mp != NULL && mp->mnt_flag & MNT_SYNCHRONOUS) + ioflag |= IO_SYNC; + } /* * For O_DSYNC we set both IO_SYNC and IO_DATASYNC, so that VOP_WRITE() * implementations that don't understand IO_DATASYNC fall back to full @@ -1132,9 +1135,13 @@ vn_write(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, if (fp->f_flag & O_DSYNC) ioflag |= IO_SYNC | IO_DATASYNC; mp = NULL; - if (vp->v_type != VCHR && - (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) - goto unlock; + need_finished_write = false; + if (vp->v_type != VCHR) { + error = vn_start_write(vp, &mp, V_WAIT | PCATCH); + if (error != 0) + goto unlock; + need_finished_write = true; + } advice = get_advice(fp, uio); @@ -1165,7 +1172,7 @@ vn_write(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, error = VOP_WRITE(vp, uio, ioflag, fp->f_cred); fp->f_nextoff[UIO_WRITE] = uio->uio_offset; VOP_UNLOCK(vp); - if (vp->v_type != VCHR) + if (need_finished_write) vn_finished_write(mp); if (error == 0 && advice == POSIX_FADV_NOREUSE && orig_offset != uio->uio_offset)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105221823.14MINvV9005880>