gfs2: gfs2_evict_inode: Put glocks asynchronously
authorAndreas Gruenbacher <agruenba@redhat.com>
Tue, 1 Aug 2017 16:45:23 +0000 (11:45 -0500)
committerBob Peterson <rpeterso@redhat.com>
Thu, 10 Aug 2017 15:45:21 +0000 (10:45 -0500)
commit71c1b2136835c88c231f7a5e3dc618f7568f84f7
tree73a9839b924775b9e91e47a7f5a1288cc583d31c
parenteebd2e813f7ef688e22cd0b68aea78fb3d1ef19c
gfs2: gfs2_evict_inode: Put glocks asynchronously

gfs2_evict_inode is called to free inodes under memory pressure.  The
function calls into DLM when an inode's last cluster-wide reference goes
away (remote unlink) and to release the glock and associated DLM lock
before finally destroying the inode.  However, if DLM is blocked on
memory to become available, calling into DLM again will deadlock.

Avoid that by decoupling releasing glocks from destroying inodes in that
case: with gfs2_glock_queue_put, glocks will be dequeued asynchronously
in work queue context, when the associated inodes have likely already
been destroyed.

With this change, inodes can end up being unlinked, remote-unlink can be
triggered, and then the inode can be reallocated before all
remote-unlink callbacks are processed.  To detect that, revalidate the
link count in gfs2_evict_inode to make sure we're not deleting an
allocated, referenced inode.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/super.c