mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-23 11:18:54 +00:00
- Solve a LOR with the sync_mtx by using the VI_ONWORKLST flag to determine
whether or not the sync failed. This could potentially get set between the time that we VOP_UNLOCK and VI_LOCK() but the race would harmelssly lead to the sync being delayed by an extra 30 seconds. If we do not move the vnode it could cause an endless loop if it continues to fail to sync. - Use vhold and vdrop to stop the vnode from changing identities while we have it unlocked. Other internal vfs lists are likely to follow this scheme.
This commit is contained in:
parent
ab87e2fb83
commit
ce13b187e7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=120773
@ -1725,15 +1725,20 @@ sched_sync(void)
|
||||
vn_finished_write(mp);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* We use vhold in case the vnode does not
|
||||
* successfully sync. vhold prevents the vnode from
|
||||
* going away when we unlock the sync_mtx so that
|
||||
* we can acquire the vnode interlock.
|
||||
*/
|
||||
vholdl(vp);
|
||||
mtx_unlock(&sync_mtx);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td);
|
||||
(void) VOP_FSYNC(vp, td->td_ucred, MNT_LAZY, td);
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
vn_finished_write(mp);
|
||||
mtx_lock(&sync_mtx);
|
||||
if (LIST_FIRST(slp) == vp) {
|
||||
VI_LOCK(vp);
|
||||
mtx_unlock(&sync_mtx);
|
||||
VI_LOCK(vp);
|
||||
if ((vp->v_iflag | VI_ONWORKLST) != 0) {
|
||||
/*
|
||||
* Put us back on the worklist. The worklist
|
||||
* routine will remove us from our current
|
||||
@ -1741,9 +1746,10 @@ sched_sync(void)
|
||||
* position.
|
||||
*/
|
||||
vn_syncer_add_to_worklist(vp, syncdelay);
|
||||
VI_UNLOCK(vp);
|
||||
mtx_lock(&sync_mtx);
|
||||
}
|
||||
vdropl(vp);
|
||||
VI_UNLOCK(vp);
|
||||
mtx_lock(&sync_mtx);
|
||||
}
|
||||
mtx_unlock(&sync_mtx);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user