nfsd: Don't release the callback slot unless it was actually held
authorTrond Myklebust <trondmy@gmail.com>
Fri, 5 Apr 2019 15:54:37 +0000 (08:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 May 2019 07:32:01 +0000 (09:32 +0200)
commit28154b865fadb21916069b06ffa1f0ea7012ac19
tree95c848321655a6e0b0baea2bf492c8f6e6fa69a5
parent99055c03d2eaa6a9481ee6c61aa91f2055c90c8e
nfsd: Don't release the callback slot unless it was actually held

commit e6abc8caa6deb14be2a206253f7e1c5e37e9515b upstream.

If there are multiple callbacks queued, waiting for the callback
slot when the callback gets shut down, then they all currently
end up acting as if they hold the slot, and call
nfsd4_cb_sequence_done() resulting in interesting side-effects.

In addition, the 'retry_nowait' path in nfsd4_cb_sequence_done()
causes a loop back to nfsd4_cb_prepare() without first freeing the
slot, which causes a deadlock when nfsd41_cb_get_slot() gets called
a second time.

This patch therefore adds a boolean to track whether or not the
callback did pick up the slot, so that it can do the right thing
in these 2 cases.

Cc: stable@vger.kernel.org
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/nfsd/nfs4callback.c
fs/nfsd/state.h