If kthread_run fails we put the client and delegation. This requires the state lock since the fi_hash is manipulated in the process. Use nfs4_lock_state_nested as nfsd_break_deleg_cb may be called back by the filesystem while under the state lock (e.g. in the close path) Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> --- fs/nfsd/nfs4state.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 7fe074a..0b45680 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -94,6 +94,7 @@ static void nfs4_set_recdir(char *recdir); * unconfstr_hashtbl[], uncofid_hashtbl[]. */ static DEFINE_MUTEX(client_mutex); +static struct thread_info *client_mutex_owner; static struct kmem_cache *stateowner_slab = NULL; static struct kmem_cache *file_slab = NULL; @@ -106,14 +107,26 @@ void nfs4_lock_state(void) { mutex_lock(&client_mutex); + client_mutex_owner = current_thread_info(); } void nfs4_unlock_state(void) { + BUG_ON(client_mutex_owner != current_thread_info()); + client_mutex_owner = NULL; mutex_unlock(&client_mutex); } +static int +nfs4_lock_state_nested(void) +{ + if (client_mutex_owner == current_thread_info()) + return 0; + nfs4_lock_state(); + return 1; +} + static inline u32 opaque_hashval(const void *ptr, int nbytes) { @@ -1798,6 +1811,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl) { struct nfs4_delegation *dp= (struct nfs4_delegation *)fl->fl_owner; struct task_struct *t; + int did_lock; dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl); if (!dp) @@ -1832,8 +1846,11 @@ void nfsd_break_deleg_cb(struct file_lock *fl) printk(KERN_INFO "NFSD: Callback thread failed for " "for client (clientid %08x/%08x)\n", clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); + did_lock = nfs4_lock_state_nested(); put_nfs4_client(dp->dl_client); nfs4_put_delegation(dp); + if (did_lock) + nfs4_unlock_state(); } } -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html