Whamcloud - gitweb
LU-6409 nodemap: don't destroy nodemaps in cfs_hash_for_each 75/14275/10
authorKit Westneat <kit.westneat@gmail.com>
Thu, 11 Jun 2015 20:37:18 +0000 (16:37 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 29 Jun 2015 22:06:38 +0000 (22:06 +0000)
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 <kit.westneat@gmail.com>
Change-Id: I1d16f61ba7739af0494944f6515508b3f0d19ba1
Reviewed-on: http://review.whamcloud.com/14275
Tested-by: Jenkins
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Andrew Perepechko <andrew.perepechko@seagate.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
lustre/include/lustre_nodemap.h
lustre/ptlrpc/nodemap_handler.c

index 53686cc..90555e3 100644 (file)
@@ -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);
index 5a634b2..7445c94 100644 (file)
@@ -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;