Whamcloud - gitweb
LU-13307 nodemap: have nodemap_add_member support large NIDs
[fs/lustre-release.git] / lustre / ptlrpc / nodemap_range.c
index ca08d11..35ed82f 100644 (file)
@@ -40,8 +40,8 @@
  * controlled to prevent read access during update operations.
  */
 
-#define START(node)    ((node)->rn_start)
-#define LAST(node)     ((node)->rn_end)
+#define START(node)    (lnet_nid_to_nid4(&((node)->rn_start)))
+#define LAST(node)     (lnet_nid_to_nid4(&((node)->rn_end)))
 
 INTERVAL_TREE_DEFINE(struct lu_nid_range, rn_rb, lnet_nid_t, rn_subtree_last,
                     START, LAST, static, nm_range)
@@ -54,16 +54,31 @@ INTERVAL_TREE_DEFINE(struct lu_nid_range, rn_rb, lnet_nid_t, rn_subtree_last,
  * \param      nodemap         nodemap that contains this range
  * \retval     lu_nid_range on success, NULL on failure
  */
-struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
-                                 lnet_nid_t start_nid, lnet_nid_t end_nid,
-                                 struct lu_nodemap *nodemap, unsigned range_id)
+struct lu_nid_range *range_create(struct nodemap_config *config,
+                                 const struct lnet_nid *start_nid,
+                                 const struct lnet_nid *end_nid,
+                                 u8 netmask, struct lu_nodemap *nodemap,
+                                 unsigned int range_id)
 {
+       struct nodemap_range_tree *nm_range_tree;
        struct lu_nid_range *range;
 
-       if (LNET_NIDNET(start_nid) != LNET_NIDNET(end_nid) ||
-           LNET_NIDADDR(start_nid) > LNET_NIDADDR(end_nid))
+       if (LNET_NID_NET(start_nid) != LNET_NID_NET(end_nid))
                return NULL;
 
+       if (!netmask) {
+               lnet_nid_t nid4[2] = {
+                       lnet_nid_to_nid4(start_nid),
+                       lnet_nid_to_nid4(end_nid)
+               };
+
+               if (LNET_NIDADDR(nid4[0]) > LNET_NIDADDR(nid4[1]))
+                       return NULL;
+       } else if (!nid_same(start_nid, end_nid)) {
+               /* FIXME Currently we only support one large NID per nodemap */
+               return NULL;
+       }
+
        OBD_ALLOC_PTR(range);
        if (range == NULL) {
                CERROR("cannot allocate lu_nid_range of size %zu bytes\n",
@@ -72,6 +87,7 @@ struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
        }
 
        /* if we are loading from save, use on disk id num */
+       nm_range_tree = &config->nmc_range_tree;
        if (range_id != 0) {
                if (nm_range_tree->nmrt_range_highest_id < range_id)
                        nm_range_tree->nmrt_range_highest_id = range_id;
@@ -82,8 +98,9 @@ struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
        }
        range->rn_nodemap = nodemap;
 
-       range->rn_start = start_nid;
-       range->rn_end = end_nid;
+       range->rn_netmask = netmask;
+       range->rn_start = *start_nid;
+       range->rn_end = *end_nid;
 
        INIT_LIST_HEAD(&range->rn_list);
 
@@ -97,17 +114,44 @@ struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
  * \param      end_nid                 ending nid
  * \retval     matching range or NULL
  */
-struct lu_nid_range *range_find(struct nodemap_range_tree *nm_range_tree,
-                               lnet_nid_t start_nid, lnet_nid_t end_nid)
+struct lu_nid_range *range_find(struct nodemap_config *config,
+                               const struct lnet_nid *start_nid,
+                               const struct lnet_nid *end_nid,
+                               u8 netmask)
 {
-       struct lu_nid_range *range;
-
-       range = nm_range_iter_first(
-               &nm_range_tree->nmrt_range_interval_root, start_nid, end_nid);
-       while (range &&
-              (range->rn_start != start_nid || range->rn_end != end_nid))
-               range = nm_range_iter_next(range, start_nid, end_nid);
-
+       struct lu_nid_range *range = NULL;
+
+       if (!netmask) {
+               struct nodemap_range_tree *nm_range_tree;
+               lnet_nid_t nid4[2];
+
+               if (!nid_is_nid4(start_nid) || !nid_is_nid4(end_nid))
+                       return NULL;
+
+               nid4[0] = lnet_nid_to_nid4(start_nid);
+               nid4[1] = lnet_nid_to_nid4(end_nid);
+               nm_range_tree = &config->nmc_range_tree;
+               range = nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
+                                           nid4[0], nid4[1]);
+               while (range &&
+                      (!nid_same(&range->rn_start, start_nid) ||
+                       !nid_same(&range->rn_end, end_nid)))
+                       range = nm_range_iter_next(range, nid4[0], nid4[1]);
+       } else if (!list_empty(&config->nmc_netmask_setup)) {
+               struct lu_nid_range *range_temp;
+
+               /* FIXME. We scan the config for large NIDs. Each range
+                * only contains one large NID for now.
+                */
+               list_for_each_entry_safe(range, range_temp,
+                                        &config->nmc_netmask_setup,
+                                        rn_collect) {
+                       if (nid_same(&range->rn_start, start_nid) &&
+                           range->rn_netmask == netmask)
+                               break;
+                       range = NULL;
+               }
+       }
        return range;
 }
 
@@ -131,16 +175,22 @@ void range_destroy(struct lu_nid_range *range)
  * does not overlap so that each nid can belong
  * to exactly one range
  */
-int range_insert(struct nodemap_range_tree *nm_range_tree,
-                struct lu_nid_range *range)
+int range_insert(struct nodemap_config *config, struct lu_nid_range *range)
 {
-       if (nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
-                               range->rn_start,
-                               range->rn_end))
-               return -EEXIST;
+       if (!range->rn_netmask) {
+               struct nodemap_range_tree *nm_range_tree;
 
-       nm_range_insert(range, &nm_range_tree->nmrt_range_interval_root);
+               nm_range_tree = &config->nmc_range_tree;
+               if (nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
+                                       lnet_nid_to_nid4(&range->rn_start),
+                                       lnet_nid_to_nid4(&range->rn_end)))
+                       return -EEXIST;
 
+               nm_range_insert(range,
+                               &nm_range_tree->nmrt_range_interval_root);
+       } else {
+               list_add(&range->rn_collect, &config->nmc_netmask_setup);
+       }
        return 0;
 }
 
@@ -150,11 +200,18 @@ int range_insert(struct nodemap_range_tree *nm_range_tree,
  *
  * \param      range           range to remove
  */
-void range_delete(struct nodemap_range_tree *nm_range_tree,
-                 struct lu_nid_range *range)
+void range_delete(struct nodemap_config *config, struct lu_nid_range *range)
 {
        list_del(&range->rn_list);
-       nm_range_remove(range, &nm_range_tree->nmrt_range_interval_root);
+       if (!range->rn_netmask) {
+               struct nodemap_range_tree *nm_range_tree;
+
+               nm_range_tree = &config->nmc_range_tree;
+               nm_range_remove(range,
+                               &nm_range_tree->nmrt_range_interval_root);
+       } else {
+               list_del(&range->rn_collect);
+       }
        range_destroy(range);
 }
 
@@ -163,9 +220,32 @@ void range_delete(struct nodemap_range_tree *nm_range_tree,
  *
  * \param      nid             nid to search for
  */
-struct lu_nid_range *range_search(struct nodemap_range_tree *nm_range_tree,
-                                 lnet_nid_t nid)
+struct lu_nid_range *range_search(struct nodemap_config *config,
+                                 struct lnet_nid *nid)
 {
-       return nm_range_iter_first(
-               &nm_range_tree->nmrt_range_interval_root, nid, nid);
+       struct lu_nid_range *range = NULL;
+
+       if (nid_is_nid4(nid)) {
+               struct nodemap_range_tree *nm_range_tree;
+
+               nm_range_tree = &config->nmc_range_tree;
+               range = nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
+                                           lnet_nid_to_nid4(nid),
+                                           lnet_nid_to_nid4(nid));
+       } else if (!list_empty(&config->nmc_netmask_setup)) {
+               struct lu_nid_range *range_temp;
+
+               /* FIXME. We scan the config for the large NIDs. Each range
+                * only contains one large NID for now.
+                */
+               list_for_each_entry_safe(range, range_temp,
+                                        &config->nmc_netmask_setup,
+                                        rn_collect) {
+                       if (nid_same(&range->rn_start, nid))
+                               break;
+                       range = NULL;
+               }
+       }
+
+       return range;
 }