diff options
author | kib <kib@FreeBSD.org> | 2015-12-21 11:50:32 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-12-21 11:50:32 +0000 |
commit | 70adc1e2169681308132c25cd91bcf7eda31444b (patch) | |
tree | 7807eb51e0c1cb886698a62ce45cc19968d2bb3a /sys/ufs/ffs | |
parent | 17cf2dee7c4e8009b175da82f34d607b8097696b (diff) | |
download | FreeBSD-src-70adc1e2169681308132c25cd91bcf7eda31444b.zip FreeBSD-src-70adc1e2169681308132c25cd91bcf7eda31444b.tar.gz |
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
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index f6ee661..04ea39c 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -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; + request_cleanup(mp, FLUSH_INODES); + } + if (softdep_excess_items(ump, D_DIRREM)) { req = true; - VFS_SYNC(mp, MNT_WAIT); - vn_finished_write(mp); + 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); } /* |