4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (C) 2013, Trustees of Indiana University
24 * Author: Joshua Walgenbach <jjw@iu.edu>
27 #include <lustre_net.h>
28 #include "nodemap_internal.h"
29 #include <linux/interval_tree_generic.h>
34 * To classify clients when they connect, build a global range tree
35 * containing all admin defined ranges. Incoming clients can then be
36 * classified into their nodemaps, and the lu_nodemap structure will be
37 * set in the export structure for the connecting client. Pointers to
38 * the lu_nid_range nodes will be added to linked links within the
39 * lu_nodemap structure for reporting purposes. Access to range tree should be
40 * controlled to prevent read access during update operations.
43 #define START(node) ((node)->rn_start)
44 #define LAST(node) ((node)->rn_end)
46 INTERVAL_TREE_DEFINE(struct lu_nid_range, rn_rb, lnet_nid_t, rn_subtree_last,
47 START, LAST, static, nm_range)
52 * \param min starting nid of the range
53 * \param max ending nid of the range
54 * \param nodemap nodemap that contains this range
55 * \retval lu_nid_range on success, NULL on failure
57 struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
58 lnet_nid_t start_nid, lnet_nid_t end_nid,
59 struct lu_nodemap *nodemap, unsigned range_id)
61 struct lu_nid_range *range;
63 if (LNET_NIDNET(start_nid) != LNET_NIDNET(end_nid) ||
64 LNET_NIDADDR(start_nid) > LNET_NIDADDR(end_nid))
69 CERROR("cannot allocate lu_nid_range of size %zu bytes\n",
74 /* if we are loading from save, use on disk id num */
76 if (nm_range_tree->nmrt_range_highest_id < range_id)
77 nm_range_tree->nmrt_range_highest_id = range_id;
78 range->rn_id = range_id;
80 nm_range_tree->nmrt_range_highest_id++;
81 range->rn_id = nm_range_tree->nmrt_range_highest_id;
83 range->rn_nodemap = nodemap;
85 range->rn_start = start_nid;
86 range->rn_end = end_nid;
88 INIT_LIST_HEAD(&range->rn_list);
94 * find the exact range
96 * \param start_nid starting nid
97 * \param end_nid ending nid
98 * \retval matching range or NULL
100 struct lu_nid_range *range_find(struct nodemap_range_tree *nm_range_tree,
101 lnet_nid_t start_nid, lnet_nid_t end_nid)
103 struct lu_nid_range *range;
105 range = nm_range_iter_first(
106 &nm_range_tree->nmrt_range_interval_root, start_nid, end_nid);
108 (range->rn_start != start_nid || range->rn_end != end_nid))
109 range = nm_range_iter_next(range, start_nid, end_nid);
117 void range_destroy(struct lu_nid_range *range)
119 LASSERT(list_empty(&range->rn_list) == 0);
125 * insert an nid range into the interval tree
127 * \param range range to insetr
128 * \retval 0 on success
130 * This function checks that the given nid range
131 * does not overlap so that each nid can belong
132 * to exactly one range
134 int range_insert(struct nodemap_range_tree *nm_range_tree,
135 struct lu_nid_range *range)
137 if (nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
142 nm_range_insert(range, &nm_range_tree->nmrt_range_interval_root);
148 * delete a range from the interval tree and any
149 * associated nodemap references
151 * \param range range to remove
153 void range_delete(struct nodemap_range_tree *nm_range_tree,
154 struct lu_nid_range *range)
156 list_del(&range->rn_list);
157 nm_range_remove(range, &nm_range_tree->nmrt_range_interval_root);
158 range_destroy(range);
162 * search the interval tree for an nid within a range
164 * \param nid nid to search for
166 struct lu_nid_range *range_search(struct nodemap_range_tree *nm_range_tree,
169 return nm_range_iter_first(
170 &nm_range_tree->nmrt_range_interval_root, nid, nid);