Only sleep interruptible while waiting for suspension end when
filesystem specified VFCF_SBDRY flag, i.e. for NFS. There are two issues with the sleeps. First, applications may get unexpected EINTR from the disk i/o syscalls. Second, interruptible sleep allows the stop of the process, and since mount point is referenced while thread sleeps, unmount cannot free mount point structure' memory, blocking unmount indefinitely. Even for NFS, it is probably only reasonable to enable PCATCH for intr mounts, but this information is currently not available at VFS level. Reported and tested by: pho (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
ea117d1735
commit
0061ddb3ed
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=275744
@ -1600,7 +1600,7 @@ vn_suspendable(struct vnode *vp, struct mount **mpp)
|
||||
static int
|
||||
vn_start_write_locked(struct mount *mp, int flags)
|
||||
{
|
||||
int error;
|
||||
int error, mflags;
|
||||
|
||||
mtx_assert(MNT_MTX(mp), MA_OWNED);
|
||||
error = 0;
|
||||
@ -1610,13 +1610,15 @@ vn_start_write_locked(struct mount *mp, int flags)
|
||||
*/
|
||||
if ((curthread->td_pflags & TDP_IGNSUSP) == 0 ||
|
||||
mp->mnt_susp_owner != curthread) {
|
||||
mflags = ((mp->mnt_vfc->vfc_flags & VFCF_SBDRY) != 0 ?
|
||||
(flags & PCATCH) : 0) | (PUSER - 1);
|
||||
while ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
|
||||
if (flags & V_NOWAIT) {
|
||||
error = EWOULDBLOCK;
|
||||
goto unlock;
|
||||
}
|
||||
error = msleep(&mp->mnt_flag, MNT_MTX(mp),
|
||||
(PUSER - 1) | (flags & PCATCH), "suspfs", 0);
|
||||
error = msleep(&mp->mnt_flag, MNT_MTX(mp), mflags,
|
||||
"suspfs", 0);
|
||||
if (error)
|
||||
goto unlock;
|
||||
}
|
||||
@ -1732,8 +1734,9 @@ vn_start_secondary_write(vp, mpp, flags)
|
||||
/*
|
||||
* Wait for the suspension to finish.
|
||||
*/
|
||||
error = msleep(&mp->mnt_flag, MNT_MTX(mp),
|
||||
(PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0);
|
||||
error = msleep(&mp->mnt_flag, MNT_MTX(mp), (PUSER - 1) | PDROP |
|
||||
((mp->mnt_vfc->vfc_flags & VFCF_SBDRY) != 0 ? (flags & PCATCH) : 0),
|
||||
"suspfs", 0);
|
||||
vfs_rel(mp);
|
||||
if (error == 0)
|
||||
goto retry;
|
||||
|
Loading…
Reference in New Issue
Block a user