diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-08-02 14:46:29 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-08-04 11:55:35 -0400 |
commit | 55a673990ec04cf63005318bcf08c2b0046e5778 (patch) | |
tree | 71e4fb3292060553063042c6190031d104d9c1f5 /fs/nfs/callback.h | |
parent | 9af7db3228acc286c50e3a0f054ec982efdbc6c6 (diff) | |
download | linux-stable-55a673990ec04cf63005318bcf08c2b0046e5778.tar.gz linux-stable-55a673990ec04cf63005318bcf08c2b0046e5778.tar.bz2 linux-stable-55a673990ec04cf63005318bcf08c2b0046e5778.zip |
NFSv4.1: Fix the callback 'highest_used_slotid' behaviour
Currently, there is no guarantee that we will call nfs4_cb_take_slot() even
though nfs4_callback_compound() will consistently call
nfs4_cb_free_slot() provided the cb_process_state has set the 'clp' field.
The result is that we can trigger the BUG_ON() upon the next call to
nfs4_cb_take_slot().
This patch fixes the above problem by using the slot id that was taken in
the CB_SEQUENCE operation as a flag for whether or not we need to call
nfs4_cb_free_slot().
It also fixes an atomicity problem: we need to set tbl->highest_used_slotid
atomically with the check for NFS4_SESSION_DRAINING, otherwise we end up
racing with the various tests in nfs4_begin_drain_session().
Cc: stable@kernel.org [2.6.38+]
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/callback.h')
-rw-r--r-- | fs/nfs/callback.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index b257383bb565..07df5f1d85e5 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -38,6 +38,7 @@ enum nfs4_callback_opnum { struct cb_process_state { __be32 drc_status; struct nfs_client *clp; + int slotid; }; struct cb_compound_hdr_arg { @@ -166,7 +167,6 @@ extern unsigned nfs4_callback_layoutrecall( void *dummy, struct cb_process_state *cps); extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); -extern void nfs4_cb_take_slot(struct nfs_client *clp); struct cb_devicenotifyitem { uint32_t cbd_notify_type; |