Fix a bunch of race cases in the NFS callout timer code, in the handling
of the NFS request queue and, in the handling of R_SENT.
The NFS stack can block in the callout timer code's request queue loop,
possibly resulting in another process ripping the current request in the
TAILQ_FOREACH scan out from under the loop.
R_MASKTIMER was being cleared too early, potentially allowing the callout
timer code to modify a request at the same time mainline code was working
on the same request synchronously.
The R_SENT bit would sometimes get set after the request had completed, or
get set twice, causing nmp->nm_sent to 'stick' and never return to 0. This
in turn would stop the NFS retry code dead in its tracks and cause the NFS
mount to hang.
Reported-by: Stefan Krueger <skrueger@meinberlikomm.de>
Testing-by: Stefan Krueger <skrueger@meinberlikomm.de>
Also-thanks-to: Peter Holms filesystem and load testing suite (stress2).