From 6299d78713ef2b6f69f6dd046256aa91a85147a8 Mon Sep 17 00:00:00 2001 From: Kit Westneat Date: Thu, 11 Jun 2015 16:37:18 -0400 Subject: [PATCH] LU-6409 nodemap: don't destroy nodemaps in cfs_hash_for_each nodemap_destroy might sleep, but cfs_hash_for_each iterators aren't allowed to sleep. This patch changes nodemap_cleanup_all to avoid destroying nodemaps in its cfs_hash_for_each iterator. Instead, the iterator creats a list of nodemaps, and then all the nodemaps in the list are destroyed. Signed-off-by: Kit Westneat Change-Id: I1d16f61ba7739af0494944f6515508b3f0d19ba1 Reviewed-on: http://review.whamcloud.com/14275 Tested-by: Jenkins Reviewed-by: James Simmons Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Andrew Perepechko Reviewed-by: John L. Hammond --- lustre/include/lustre_nodemap.h | 3 +++ lustre/ptlrpc/nodemap_handler.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lustre/include/lustre_nodemap.h b/lustre/include/lustre_nodemap.h index 53686cc..90555e3 100644 --- a/lustre/include/lustre_nodemap.h +++ b/lustre/include/lustre_nodemap.h @@ -87,6 +87,9 @@ struct lu_nodemap { struct cfs_hash *nm_member_hash; /* access by nodemap name */ struct hlist_node nm_hash; + + /* used when unloading nodemaps */ + struct list_head nm_list; }; void nodemap_activate(const bool value); diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index 5a634b2..7445c94 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -173,20 +173,21 @@ static struct cfs_hash_ops nodemap_hash_operations = { /* end of cfs_hash functions */ /** - * Helper iterator to clean up nodemap on module exit. + * Helper iterator to convert nodemap hash to list. * - * \param hs hash structure - * \param bd bucket descriptor - * \param hnode hash node - * \param data not used here + * \param hs hash structure + * \param bd bucket descriptor + * \param hnode hash node + * \param nodemap_list_head list head for list of nodemaps in hash */ static int nodemap_cleanup_iter_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd, - struct hlist_node *hnode, void *data) + struct hlist_node *hnode, + void *nodemap_list_head) { - struct lu_nodemap *nodemap; + struct lu_nodemap *nodemap; nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash); - nodemap_putref(nodemap); + list_add(&nodemap->nm_list, (struct list_head *)nodemap_list_head); return 0; } @@ -196,8 +197,21 @@ static int nodemap_cleanup_iter_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd, */ void nodemap_cleanup_all(void) { - cfs_hash_for_each_safe(nodemap_hash, nodemap_cleanup_iter_cb, NULL); + struct lu_nodemap *nodemap = NULL; + struct list_head *pos, *next; + struct list_head nodemap_list_head = LIST_HEAD_INIT(nodemap_list_head); + + cfs_hash_for_each_safe(nodemap_hash, nodemap_cleanup_iter_cb, + &nodemap_list_head); cfs_hash_putref(nodemap_hash); + + /* Because nodemap_destroy might sleep, we can't destroy them + * in cfs_hash_for_each. Instead we build a list and destroy here + */ + list_for_each_safe(pos, next, &nodemap_list_head) { + nodemap = list_entry(pos, struct lu_nodemap, nm_list); + nodemap_putref(nodemap); + } } /** @@ -763,6 +777,7 @@ static int nodemap_create(const char *name, bool is_default) } INIT_LIST_HEAD(&nodemap->nm_ranges); + INIT_LIST_HEAD(&nodemap->nm_list); rwlock_init(&nodemap->nm_idmap_lock); nodemap->nm_fs_to_client_uidmap = RB_ROOT; -- 1.8.3.1