From 526fce4d2d2ce75e17fa89715624fe1e7349cc05 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 4 Feb 2011 11:55:02 -0800 Subject: [PATCH] HAMMER VFS - Fix deadlock which can occur under severe filesystem pressure * Inode reflushes (a fsync occuring while the inode is still queued for a prior fsync) were not ensuring that the inode got pushed to the backend flusher. This could lead to deadlocks when the process trying to issue the flush is the syncer itself. * The problem typically occured under filesystem loads where a large number of inodes (aka due to a bulk build) are being flushed at once, and the flush is unable to finish running before the next syncer cycle comes around. --- sys/vfs/hammer/hammer_inode.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/vfs/hammer/hammer_inode.c b/sys/vfs/hammer/hammer_inode.c index 231883e426..9448e16be6 100644 --- a/sys/vfs/hammer/hammer_inode.c +++ b/sys/vfs/hammer/hammer_inode.c @@ -2370,6 +2370,21 @@ hammer_wait_inode(hammer_inode_t ip) (ip->hmp->flags & HAMMER_MOUNT_CRITICAL_ERROR) == 0) { if (ip->flush_state == HAMMER_FST_SETUP) hammer_flush_inode(ip, HAMMER_FLUSH_SIGNAL); + + /* + * If the inode was already being flushed its flg + * may not have been queued to the backend. We have + * to make sure it gets queued or we can wind up + * blocked or deadlocked (particularly if we are + * the vnlru thread). + */ + KKASSERT(ip->flush_group); + if (ip->flush_group->closed == 0) { + kprintf("hammer: debug: forcing async " + "flush ip %016jx\n", + (intmax_t)ip->obj_id); + hammer_flusher_async(ip->hmp, ip->flush_group); + } if (ip->flush_state != HAMMER_FST_IDLE) { ip->flags |= HAMMER_INODE_FLUSHW; tsleep(&ip->flags, 0, "hmrwin", 0); -- 2.41.0