Recheck curthread->td_su after the VFS_SYNC() call, and re-sync if the
ast was rescheduled during VFS_SYNC(). It is possible that enough parallel writes or slow/hung volume result in VFS_SYNC() deferring to the ast flushing of workqueue. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
e85324c92f
commit
44de1ba141
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=292541
@ -13301,43 +13301,43 @@ softdep_ast_cleanup_proc(void)
|
||||
bool req;
|
||||
|
||||
td = curthread;
|
||||
mp = td->td_su;
|
||||
if (mp == NULL)
|
||||
return;
|
||||
td->td_su = NULL;
|
||||
error = vfs_busy(mp, MBF_NOWAIT);
|
||||
vfs_rel(mp);
|
||||
if (error != 0)
|
||||
return;
|
||||
if (ffs_own_mount(mp) && MOUNTEDSOFTDEP(mp)) {
|
||||
ump = VFSTOUFS(mp);
|
||||
for (;;) {
|
||||
req = false;
|
||||
ACQUIRE_LOCK(ump);
|
||||
if (softdep_excess_items(ump, D_INODEDEP)) {
|
||||
req = true;
|
||||
request_cleanup(mp, FLUSH_INODES);
|
||||
}
|
||||
if (softdep_excess_items(ump, D_DIRREM)) {
|
||||
req = true;
|
||||
request_cleanup(mp, FLUSH_BLOCKS);
|
||||
}
|
||||
FREE_LOCK(ump);
|
||||
if (softdep_excess_items(ump, D_NEWBLK) ||
|
||||
softdep_excess_items(ump, D_ALLOCDIRECT) ||
|
||||
softdep_excess_items(ump, D_ALLOCINDIR)) {
|
||||
error = vn_start_write(NULL, &mp, V_WAIT);
|
||||
if (error == 0) {
|
||||
while ((mp = td->td_su) != NULL) {
|
||||
td->td_su = NULL;
|
||||
error = vfs_busy(mp, MBF_NOWAIT);
|
||||
vfs_rel(mp);
|
||||
if (error != 0)
|
||||
return;
|
||||
if (ffs_own_mount(mp) && MOUNTEDSOFTDEP(mp)) {
|
||||
ump = VFSTOUFS(mp);
|
||||
for (;;) {
|
||||
req = false;
|
||||
ACQUIRE_LOCK(ump);
|
||||
if (softdep_excess_items(ump, D_INODEDEP)) {
|
||||
req = true;
|
||||
VFS_SYNC(mp, MNT_WAIT);
|
||||
vn_finished_write(mp);
|
||||
request_cleanup(mp, FLUSH_INODES);
|
||||
}
|
||||
if (softdep_excess_items(ump, D_DIRREM)) {
|
||||
req = true;
|
||||
request_cleanup(mp, FLUSH_BLOCKS);
|
||||
}
|
||||
FREE_LOCK(ump);
|
||||
if (softdep_excess_items(ump, D_NEWBLK) ||
|
||||
softdep_excess_items(ump, D_ALLOCDIRECT) ||
|
||||
softdep_excess_items(ump, D_ALLOCINDIR)) {
|
||||
error = vn_start_write(NULL, &mp,
|
||||
V_WAIT);
|
||||
if (error == 0) {
|
||||
req = true;
|
||||
VFS_SYNC(mp, MNT_WAIT);
|
||||
vn_finished_write(mp);
|
||||
}
|
||||
}
|
||||
if ((td->td_pflags & TDP_KTHREAD) != 0 || !req)
|
||||
break;
|
||||
}
|
||||
if ((td->td_pflags & TDP_KTHREAD) != 0 || !req)
|
||||
break;
|
||||
}
|
||||
vfs_unbusy(mp);
|
||||
}
|
||||
vfs_unbusy(mp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user