The process_deferred_inactive() function locks the vnodes of the ufs
mount, which means that is must not be called while the snaplock is owned. The vfs_write_resume(9) does call the function as the VFS_SUSP_CLEAN() method, which is too early and falls into the region still protected by snaplock. Add yet another flag for the vfs_write_resume_flags() to avoid calling suspension cleanup handler after the suspend is lifted, and use it in the ffs_snapshot() call to vfs_write_resume. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
364d32d67d
commit
f99cb34c4f
@ -1667,7 +1667,8 @@ vfs_write_resume_flags(struct mount *mp, int flags)
|
||||
mp->mnt_writeopcount++;
|
||||
}
|
||||
MNT_IUNLOCK(mp);
|
||||
VFS_SUSP_CLEAN(mp);
|
||||
if ((flags & VR_NO_SUSPCLR) == 0)
|
||||
VFS_SUSP_CLEAN(mp);
|
||||
} else if ((flags & VR_START_WRITE) != 0) {
|
||||
MNT_REF(mp);
|
||||
vn_start_write_locked(mp, 0);
|
||||
|
@ -393,6 +393,7 @@ extern int vttoif_tab[];
|
||||
#define V_XSLEEP 0x0004 /* vn_start_write: just return after sleep */
|
||||
|
||||
#define VR_START_WRITE 0x0001 /* vfs_write_resume: start write atomically */
|
||||
#define VR_NO_SUSPCLR 0x0002 /* vfs_write_resume: do not clear suspension */
|
||||
|
||||
#define VREF(vp) vref(vp)
|
||||
|
||||
|
@ -687,7 +687,7 @@ ffs_snapshot(mp, snapfile)
|
||||
/*
|
||||
* Resume operation on filesystem.
|
||||
*/
|
||||
vfs_write_resume_flags(vp->v_mount, VR_START_WRITE);
|
||||
vfs_write_resume_flags(vp->v_mount, VR_START_WRITE | VR_NO_SUSPCLR);
|
||||
if (collectsnapstats && starttime.tv_sec > 0) {
|
||||
nanotime(&endtime);
|
||||
timespecsub(&endtime, &starttime);
|
||||
|
Loading…
Reference in New Issue
Block a user