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
25 * Copyright (c) 2017, Intel Corporation.
27 * Author: Joshua Walgenbach <jjw@iu.edu>
29 #include <linux/module.h>
30 #include <linux/sort.h>
31 #include <uapi/linux/lnet/nidstr.h>
32 #include <lustre_net.h>
33 #include <lustre_acl.h>
34 #include <obd_class.h>
36 #include "nodemap_internal.h"
37 #include "ptlrpc_internal.h"
39 #define HASH_NODEMAP_BKT_BITS 3
40 #define HASH_NODEMAP_CUR_BITS 3
41 #define HASH_NODEMAP_MAX_BITS 7
43 #define DEFAULT_NODEMAP "default"
45 /* nodemap proc root proc directory under fs/lustre */
46 struct proc_dir_entry *proc_lustre_nodemap_root;
48 /* Copy of config active flag to avoid locking in mapping functions */
51 /* Lock protecting the active config, useful primarily when proc and
52 * nodemap_hash might be replaced when loading a new config
53 * Any time the active config is referenced, the lock should be held.
55 DEFINE_MUTEX(active_config_lock);
56 struct nodemap_config *active_config;
61 * \param nodemap nodemap to destroy
63 static void nodemap_destroy(struct lu_nodemap *nodemap)
67 if (nodemap->nm_pde_data != NULL)
68 lprocfs_nodemap_remove(nodemap->nm_pde_data);
70 mutex_lock(&active_config_lock);
71 down_read(&active_config->nmc_range_tree_lock);
72 nm_member_reclassify_nodemap(nodemap);
73 up_read(&active_config->nmc_range_tree_lock);
75 down_write(&nodemap->nm_idmap_lock);
76 idmap_delete_tree(nodemap);
77 up_write(&nodemap->nm_idmap_lock);
79 mutex_unlock(&active_config_lock);
81 if (!list_empty(&nodemap->nm_member_list))
82 CWARN("nodemap_destroy failed to reclassify all members\n");
84 nm_member_delete_list(nodemap);
86 OBD_FREE_PTR(nodemap);
92 * Functions used for the cfs_hash
94 void nodemap_getref(struct lu_nodemap *nodemap)
96 atomic_inc(&nodemap->nm_refcount);
97 CDEBUG(D_INFO, "GETting nodemap %s(p=%p) : new refcount %d\n",
98 nodemap->nm_name, nodemap, atomic_read(&nodemap->nm_refcount));
102 * Destroy nodemap if last reference is put. Should be called outside
105 void nodemap_putref(struct lu_nodemap *nodemap)
110 LASSERT(atomic_read(&nodemap->nm_refcount) > 0);
112 CDEBUG(D_INFO, "PUTting nodemap %s(p=%p) : new refcount %d\n",
113 nodemap->nm_name, nodemap,
114 atomic_read(&nodemap->nm_refcount) - 1);
116 if (atomic_dec_and_test(&nodemap->nm_refcount))
117 nodemap_destroy(nodemap);
119 EXPORT_SYMBOL(nodemap_putref);
122 nodemap_hashfn(struct cfs_hash *hash_body,
123 const void *key, const unsigned int bits)
125 return cfs_hash_djb2_hash(key, strlen(key), bits);
128 static void *nodemap_hs_key(struct hlist_node *hnode)
130 struct lu_nodemap *nodemap;
132 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
134 return nodemap->nm_name;
137 static int nodemap_hs_keycmp(const void *key,
138 struct hlist_node *compared_hnode)
142 nodemap_name = nodemap_hs_key(compared_hnode);
144 return !strcmp(key, nodemap_name);
147 static void *nodemap_hs_hashobject(struct hlist_node *hnode)
149 return hlist_entry(hnode, struct lu_nodemap, nm_hash);
152 static void nodemap_hs_get(struct cfs_hash *hs, struct hlist_node *hnode)
154 struct lu_nodemap *nodemap;
156 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
157 nodemap_getref(nodemap);
160 static void nodemap_hs_put_locked(struct cfs_hash *hs,
161 struct hlist_node *hnode)
163 struct lu_nodemap *nodemap;
165 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
166 nodemap_putref(nodemap);
169 static struct cfs_hash_ops nodemap_hash_operations = {
170 .hs_hash = nodemap_hashfn,
171 .hs_key = nodemap_hs_key,
172 .hs_keycmp = nodemap_hs_keycmp,
173 .hs_object = nodemap_hs_hashobject,
174 .hs_get = nodemap_hs_get,
175 .hs_put_locked = nodemap_hs_put_locked,
178 /* end of cfs_hash functions */
181 * Initialize nodemap_hash
184 * \retval -ENOMEM cannot create hash
186 static int nodemap_init_hash(struct nodemap_config *nmc)
188 nmc->nmc_nodemap_hash = cfs_hash_create("NODEMAP",
189 HASH_NODEMAP_CUR_BITS,
190 HASH_NODEMAP_MAX_BITS,
191 HASH_NODEMAP_BKT_BITS, 0,
194 &nodemap_hash_operations,
197 if (nmc->nmc_nodemap_hash == NULL) {
198 CERROR("cannot create nodemap_hash table\n");
206 * Check for valid nodemap name
208 * \param name nodemap name
210 * \retval false invalid
212 static bool nodemap_name_is_valid(const char *name)
214 if (strlen(name) > LUSTRE_NODEMAP_NAME_LENGTH ||
218 for (; *name != '\0'; name++) {
219 if (!isalnum(*name) && *name != '_')
229 * Look nodemap up in the active_config nodemap hash. Caller should hold the
230 * active_config_lock.
232 * \param name name of nodemap
233 * \retval nodemap pointer set to found nodemap
234 * \retval -EINVAL name is not valid
235 * \retval -ENOENT nodemap not found
237 struct lu_nodemap *nodemap_lookup(const char *name)
239 struct lu_nodemap *nodemap = NULL;
241 if (!nodemap_name_is_valid(name))
242 return ERR_PTR(-EINVAL);
244 nodemap = cfs_hash_lookup(active_config->nmc_nodemap_hash, name);
246 return ERR_PTR(-ENOENT);
252 * Classify the nid into the proper nodemap. Caller must hold active config and
253 * nm_range_tree_lock, and call nodemap_putref when done with nodemap.
255 * \param nid nid to classify
256 * \retval nodemap nodemap containing the nid
257 * \retval default_nodemap default nodemap
258 * \retval -EINVAL LO nid given without other local nid
260 struct lu_nodemap *nodemap_classify_nid(struct lnet_nid *nid)
262 struct lu_nid_range *range;
263 struct lu_nodemap *nodemap;
267 /* don't use 0@lo, use the first non-lo local NID instead */
268 if (nid_is_lo0(nid)) {
269 struct lnet_processid id;
273 rc = LNetGetId(i++, &id, true);
275 RETURN(ERR_PTR(-EINVAL));
276 } while (nid_is_lo0(&id.nid));
279 CDEBUG(D_INFO, "found nid %s\n", libcfs_nidstr(nid));
282 range = range_search(active_config, nid);
284 nodemap = range->rn_nodemap;
286 nodemap = active_config->nmc_default_nodemap;
288 LASSERT(nodemap != NULL);
289 nodemap_getref(nodemap);
295 * simple check for default nodemap
297 static bool is_default_nodemap(const struct lu_nodemap *nodemap)
299 return nodemap->nm_id == 0;
303 * parse a nodemap range string into two nids
305 * \param range_str string to parse
306 * \param range[2] array of two nids
307 * \reyval 0 on success
309 int nodemap_parse_range(const char *range_str, struct lnet_nid range[2],
312 char buf[LNET_NIDSTR_SIZE * 2 + 2];
318 snprintf(buf, sizeof(buf), "%s", range_str);
321 /* For large NID we use netmasks. Currently we only
322 * support /128 which is a single NID.
324 if (strchr(ptr, '/')) {
325 start_nidstr = strsep(&ptr, "/");
327 rc = kstrtou8(ptr, 10, netmask);
331 GOTO(out, rc = -ERANGE);
332 end_nidstr = start_nidstr;
334 start_nidstr = strsep(&ptr, ":");
335 end_nidstr = strsep(&ptr, ":");
338 if (start_nidstr == NULL || end_nidstr == NULL)
339 GOTO(out, rc = -EINVAL);
341 rc = libcfs_strnid(&range[0], start_nidstr);
345 rc = libcfs_strnid(&range[1], end_nidstr);
350 EXPORT_SYMBOL(nodemap_parse_range);
353 * parse a string containing an id map of form "client_id:filesystem_id"
354 * into an array of __u32 * for use in mapping functions
356 * \param idmap_str map string
357 * \param idmap array[2] of __u32
359 * \retval 0 on success
360 * \retval -EINVAL if idmap cannot be parsed
362 int nodemap_parse_idmap(char *idmap_str, __u32 idmap[2])
365 long unsigned int idmap_buf;
368 if (idmap_str == NULL)
371 sep = strchr(idmap_str, ':');
377 rc = kstrtoul(idmap_str, 10, &idmap_buf);
380 idmap[0] = idmap_buf;
382 rc = kstrtoul(sep, 10, &idmap_buf);
385 idmap[1] = idmap_buf;
389 EXPORT_SYMBOL(nodemap_parse_idmap);
392 * add a member to a nodemap
394 * \param nid nid to add to the members
395 * \param exp obd_export structure for the connection
396 * that is being added
397 * \retval -EINVAL export is NULL, or has invalid NID
398 * \retval -EEXIST export is already member of a nodemap
400 int nodemap_add_member(struct lnet_nid *nid, struct obd_export *exp)
402 struct lu_nodemap *nodemap;
406 mutex_lock(&active_config_lock);
407 down_read(&active_config->nmc_range_tree_lock);
409 nodemap = nodemap_classify_nid(nid);
410 if (IS_ERR(nodemap)) {
411 CWARN("%s: error adding to nodemap, no valid NIDs found\n",
412 exp->exp_obd->obd_name);
415 rc = nm_member_add(nodemap, exp);
418 up_read(&active_config->nmc_range_tree_lock);
419 mutex_unlock(&active_config_lock);
421 if (!IS_ERR(nodemap))
422 nodemap_putref(nodemap);
426 EXPORT_SYMBOL(nodemap_add_member);
429 * delete a member from a nodemap
431 * \param exp export to remove from a nodemap
433 void nodemap_del_member(struct obd_export *exp)
435 struct lu_nodemap *nodemap;
439 /* using ac lock to prevent nodemap reclassification while deleting */
440 mutex_lock(&active_config_lock);
442 /* use of ted_nodemap is protected by active_config_lock. we take an
443 * extra reference to make sure nodemap isn't destroyed under
446 nodemap = exp->exp_target_data.ted_nodemap;
450 nodemap_getref(nodemap);
452 mutex_lock(&nodemap->nm_member_list_lock);
453 nm_member_del(nodemap, exp);
454 mutex_unlock(&nodemap->nm_member_list_lock);
457 mutex_unlock(&active_config_lock);
460 nodemap_putref(nodemap);
464 EXPORT_SYMBOL(nodemap_del_member);
467 * add an idmap to the proper nodemap trees
469 * \param nodemap nodemap to add idmap to
470 * \param id_type NODEMAP_UID or NODEMAP_GID
471 * \param map array[2] __u32 containing the map values
472 * map[0] is client id
473 * map[1] is the filesystem id
475 * \retval 0 on success
476 * \retval < 0 if error occurs
478 int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
479 enum nodemap_id_type id_type,
482 struct lu_idmap *idmap;
483 struct lu_idmap *temp;
486 idmap = idmap_create(map[0], map[1]);
488 GOTO(out, rc = -ENOMEM);
490 down_write(&nodemap->nm_idmap_lock);
491 temp = idmap_insert(id_type, idmap, nodemap);
492 /* If the new id_client or id_fs is matched, the old idmap and its
493 * index should be deleted according to its id_client before the new
494 * idmap is added again.
497 GOTO(out_insert, rc = PTR_ERR(temp));
501 del_map[0] = temp->id_client;
502 idmap_delete(id_type, temp, nodemap);
503 rc = nodemap_idx_idmap_del(nodemap, id_type, del_map);
504 /* In case there is any corrupted idmap */
505 if (!rc || unlikely(rc == -ENOENT)) {
506 temp = idmap_insert(id_type, idmap, nodemap);
518 up_write(&nodemap->nm_idmap_lock);
519 nm_member_revoke_locks(nodemap);
525 int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
528 struct lu_nodemap *nodemap = NULL;
533 mutex_lock(&active_config_lock);
534 nodemap = nodemap_lookup(name);
535 if (IS_ERR(nodemap)) {
536 mutex_unlock(&active_config_lock);
537 GOTO(out, rc = PTR_ERR(nodemap));
540 if (is_default_nodemap(nodemap)) {
543 rc = nodemap_add_idmap_helper(nodemap, id_type, map);
545 rc = nodemap_idx_idmap_add(nodemap, id_type, map);
547 mutex_unlock(&active_config_lock);
548 nodemap_putref(nodemap);
553 EXPORT_SYMBOL(nodemap_add_idmap);
556 * delete idmap from proper nodemap tree
558 * \param name name of nodemap
559 * \param id_type NODEMAP_UID or NODEMAP_GID
560 * \param map array[2] __u32 containing the mapA values
561 * map[0] is client id
562 * map[1] is the filesystem id
564 * \retval 0 on success
566 int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
569 struct lu_nodemap *nodemap = NULL;
570 struct lu_idmap *idmap = NULL;
575 mutex_lock(&active_config_lock);
576 nodemap = nodemap_lookup(name);
577 if (IS_ERR(nodemap)) {
578 mutex_unlock(&active_config_lock);
579 GOTO(out, rc = PTR_ERR(nodemap));
582 if (is_default_nodemap(nodemap))
583 GOTO(out_putref, rc = -EINVAL);
585 down_write(&nodemap->nm_idmap_lock);
586 idmap = idmap_search(nodemap, NODEMAP_CLIENT_TO_FS, id_type,
591 idmap_delete(id_type, idmap, nodemap);
592 rc = nodemap_idx_idmap_del(nodemap, id_type, map);
594 up_write(&nodemap->nm_idmap_lock);
597 mutex_unlock(&active_config_lock);
599 nm_member_revoke_locks(nodemap);
600 nodemap_putref(nodemap);
605 EXPORT_SYMBOL(nodemap_del_idmap);
608 * Get nodemap assigned to given export. Takes a reference on the nodemap.
610 * Note that this function may return either NULL, or an ERR_PTR()
611 * or a valid nodemap pointer. All of the functions accessing the
612 * returned nodemap can check IS_ERR(nodemap) to see if an error is
613 * returned. NULL is not considered an error, which is OK since this
614 * is a valid case if nodemap are not in use. All nodemap handling
615 * functions must check for nodemap == NULL and do nothing, and the
616 * nodemap returned from this function should not be dereferenced.
618 * \param export export to get nodemap for
620 * \retval pointer to nodemap on success
621 * \retval NULL nodemap subsystem disabled
622 * \retval -EACCES export does not have nodemap assigned
624 struct lu_nodemap *nodemap_get_from_exp(struct obd_export *exp)
626 struct lu_nodemap *nodemap;
633 spin_lock(&exp->exp_target_data.ted_nodemap_lock);
634 nodemap = exp->exp_target_data.ted_nodemap;
636 nodemap_getref(nodemap);
637 spin_unlock(&exp->exp_target_data.ted_nodemap_lock);
640 CDEBUG(D_INFO, "%s: nodemap null on export %s (at %s)\n",
641 exp->exp_obd->obd_name,
642 obd_uuid2str(&exp->exp_client_uuid),
643 obd_export_nid2str(exp));
644 RETURN(ERR_PTR(-EACCES));
649 EXPORT_SYMBOL(nodemap_get_from_exp);
652 * mapping function for nodemap idmaps
654 * \param nodemap lu_nodemap structure defining nodemap
655 * \param node_type NODEMAP_UID or NODEMAP_GID or NODEMAP_PROJID
656 * \param tree_type NODEMAP_CLIENT_TO_FS or
657 * NODEMAP_FS_TO_CLIENT
658 * \param id id to map
660 * \retval mapped id according to the rules below.
662 * if the nodemap_active is false, just return the passed id without mapping
664 * if the id to be looked up is 0, check that root access is allowed and if it
665 * is, return 0. Otherwise, return the squash uid or gid.
667 * if the nodemap is configured to trusted the ids from the client system, just
668 * return the passed id without mapping.
670 * if by this point, we haven't returned and the nodemap in question is the
671 * default nodemap, return the squash uid or gid.
673 * after these checks, search the proper tree for the mapping, and if found
674 * return the mapped value, otherwise return the squash uid or gid.
676 __u32 nodemap_map_id(struct lu_nodemap *nodemap,
677 enum nodemap_id_type id_type,
678 enum nodemap_tree_type tree_type, __u32 id)
680 struct lu_idmap *idmap = NULL;
688 if (unlikely(nodemap == NULL))
692 if (nodemap->nmf_allow_root_access)
697 if (id_type == NODEMAP_UID &&
698 !(nodemap->nmf_map_mode & NODEMAP_MAP_UID))
701 if (id_type == NODEMAP_GID &&
702 !(nodemap->nmf_map_mode & NODEMAP_MAP_GID))
705 if (id_type == NODEMAP_PROJID &&
706 !(nodemap->nmf_map_mode & NODEMAP_MAP_PROJID))
709 if (nodemap->nmf_trust_client_ids)
712 if (is_default_nodemap(nodemap))
715 down_read(&nodemap->nm_idmap_lock);
716 idmap = idmap_search(nodemap, tree_type, id_type, id);
718 up_read(&nodemap->nm_idmap_lock);
722 if (tree_type == NODEMAP_FS_TO_CLIENT)
723 found_id = idmap->id_client;
725 found_id = idmap->id_fs;
726 up_read(&nodemap->nm_idmap_lock);
730 if (id_type == NODEMAP_UID)
731 RETURN(nodemap->nm_squash_uid);
732 if (id_type == NODEMAP_GID)
733 RETURN(nodemap->nm_squash_gid);
734 if (id_type == NODEMAP_PROJID)
735 RETURN(nodemap->nm_squash_projid);
739 EXPORT_SYMBOL(nodemap_map_id);
742 * Map posix ACL entries according to the nodemap membership. Removes any
745 * \param lu_nodemap nodemap
746 * \param buf buffer containing xattr encoded ACLs
747 * \param size size of ACLs in bytes
748 * \param tree_type direction of mapping
749 * \retval size new size of ACLs in bytes
750 * \retval -EINVAL bad \a size param, see posix_acl_xattr_count()
752 ssize_t nodemap_map_acl(struct lu_nodemap *nodemap, void *buf, size_t size,
753 enum nodemap_tree_type tree_type)
755 posix_acl_xattr_header *header = buf;
756 posix_acl_xattr_entry *entry = GET_POSIX_ACL_XATTR_ENTRY(header);
757 posix_acl_xattr_entry *new_entry = entry;
758 posix_acl_xattr_entry *end;
766 if (unlikely(nodemap == NULL))
769 count = posix_acl_xattr_count(size);
773 /* if not proper ACL, do nothing and return initial size */
776 for (end = entry + count; entry != end; entry++) {
777 __u16 tag = le16_to_cpu(entry->e_tag);
778 __u32 id = le32_to_cpu(entry->e_id);
782 id = nodemap_map_id(nodemap, NODEMAP_UID,
784 if (id == nodemap->nm_squash_uid)
786 entry->e_id = cpu_to_le32(id);
789 id = nodemap_map_id(nodemap, NODEMAP_GID,
791 if (id == nodemap->nm_squash_gid)
793 entry->e_id = cpu_to_le32(id);
797 /* if we skip an ACL, copy the following ones over it */
798 if (new_entry != entry)
804 RETURN((void *)new_entry - (void *)header);
806 EXPORT_SYMBOL(nodemap_map_acl);
809 * Add nid range to given nodemap
811 * \param config nodemap config to work on
812 * \param nodemap nodemap to add range to
813 * \param nid nid range to add
814 * \param range_id should be 0 unless loading from disk
819 int nodemap_add_range_helper(struct nodemap_config *config,
820 struct lu_nodemap *nodemap,
821 const struct lnet_nid nid[2],
822 u8 netmask, unsigned int range_id)
824 struct lu_nid_range *range;
827 down_write(&config->nmc_range_tree_lock);
828 range = range_create(config, &nid[0], &nid[1], netmask, nodemap,
831 up_write(&config->nmc_range_tree_lock);
832 GOTO(out, rc = -ENOMEM);
835 rc = range_insert(config, range);
837 CDEBUG_LIMIT(rc == -EEXIST ? D_INFO : D_ERROR,
838 "cannot insert nodemap range into '%s': rc = %d\n",
839 nodemap->nm_name, rc);
840 up_write(&config->nmc_range_tree_lock);
841 list_del(&range->rn_list);
842 range_destroy(range);
846 list_add(&range->rn_list, &nodemap->nm_ranges);
848 /* nodemaps have no members if they aren't on the active config */
849 if (config == active_config)
850 nm_member_reclassify_nodemap(config->nmc_default_nodemap);
852 up_write(&config->nmc_range_tree_lock);
854 /* if range_id is non-zero, we are loading from disk */
856 rc = nodemap_idx_range_add(range);
858 if (config == active_config) {
859 nm_member_revoke_locks(config->nmc_default_nodemap);
860 nm_member_revoke_locks(nodemap);
867 int nodemap_add_range(const char *name, const struct lnet_nid nid[2],
870 struct lu_nodemap *nodemap = NULL;
873 mutex_lock(&active_config_lock);
874 nodemap = nodemap_lookup(name);
875 if (IS_ERR(nodemap)) {
876 mutex_unlock(&active_config_lock);
877 GOTO(out, rc = PTR_ERR(nodemap));
880 if (is_default_nodemap(nodemap))
883 rc = nodemap_add_range_helper(active_config, nodemap, nid,
885 mutex_unlock(&active_config_lock);
886 nodemap_putref(nodemap);
890 EXPORT_SYMBOL(nodemap_add_range);
894 * \param name nodemap name
895 * \param nid nid range
896 * \retval 0 on success
898 * Delete range from global range tree, and remove it
899 * from the list in the associated nodemap.
901 int nodemap_del_range(const char *name, const struct lnet_nid nid[2],
904 struct lu_nodemap *nodemap;
905 struct lu_nid_range *range;
908 mutex_lock(&active_config_lock);
909 nodemap = nodemap_lookup(name);
910 if (IS_ERR(nodemap)) {
911 mutex_unlock(&active_config_lock);
912 GOTO(out, rc = PTR_ERR(nodemap));
915 if (is_default_nodemap(nodemap))
916 GOTO(out_putref, rc = -EINVAL);
918 down_write(&active_config->nmc_range_tree_lock);
919 range = range_find(active_config, &nid[0], &nid[1], netmask);
921 up_write(&active_config->nmc_range_tree_lock);
922 GOTO(out_putref, rc = -EINVAL);
924 if (range->rn_nodemap != nodemap) {
925 up_write(&active_config->nmc_range_tree_lock);
926 GOTO(out_putref, rc = -EINVAL);
928 rc = nodemap_idx_range_del(range);
929 range_delete(active_config, range);
930 nm_member_reclassify_nodemap(nodemap);
931 up_write(&active_config->nmc_range_tree_lock);
933 nm_member_revoke_locks(active_config->nmc_default_nodemap);
934 nm_member_revoke_locks(nodemap);
937 mutex_unlock(&active_config_lock);
938 nodemap_putref(nodemap);
942 EXPORT_SYMBOL(nodemap_del_range);
945 * set fileset on nodemap
946 * \param name nodemap to set fileset on
947 * \param fileset string containing fileset
948 * \retval 0 on success
950 * set a fileset on the named nodemap
952 static int nodemap_set_fileset_helper(struct nodemap_config *config,
953 struct lu_nodemap *nodemap,
958 /* Allow 'fileset=clear' in addition to 'fileset=""' to clear fileset
959 * because either command 'lctl set_param -P *.*.fileset=""' or
960 * 'lctl nodemap_set_fileset --fileset ""' can only work correctly
961 * on MGS, while on other servers, both commands will invoke upcall
962 * "/usr/sbin/lctl set_param nodemap.default.fileset=" by function
963 * process_param2_config(), which will cause "no value" error and
964 * won't clear fileset.
965 * 'fileset=""' is still kept for compatibility reason.
969 else if (fileset[0] == '\0' || strcmp(fileset, "clear") == 0)
970 nodemap->nm_fileset[0] = '\0';
971 else if (fileset[0] != '/')
973 else if (strlcpy(nodemap->nm_fileset, fileset,
974 sizeof(nodemap->nm_fileset)) >=
975 sizeof(nodemap->nm_fileset))
981 int nodemap_set_fileset(const char *name, const char *fileset)
983 struct lu_nodemap *nodemap = NULL;
986 mutex_lock(&active_config_lock);
987 nodemap = nodemap_lookup(name);
988 if (IS_ERR(nodemap)) {
989 mutex_unlock(&active_config_lock);
990 GOTO(out, rc = PTR_ERR(nodemap));
993 rc = nodemap_set_fileset_helper(active_config, nodemap, fileset);
994 mutex_unlock(&active_config_lock);
996 nodemap_putref(nodemap);
1000 EXPORT_SYMBOL(nodemap_set_fileset);
1003 * get fileset defined on nodemap
1004 * \param nodemap nodemap to get fileset from
1005 * \retval fileset name, or NULL if not defined or not activated
1007 * get the fileset defined on the nodemap
1009 char *nodemap_get_fileset(const struct lu_nodemap *nodemap)
1011 if (!nodemap_active)
1014 return (char *)nodemap->nm_fileset;
1016 EXPORT_SYMBOL(nodemap_get_fileset);
1018 static int nodemap_validate_sepol(const char *sepol)
1020 char buf[LUSTRE_NODEMAP_SEPOL_LENGTH + 1];
1021 char *p = (char *)sepol;
1023 char polname[NAME_MAX + 1] = "";
1024 char hash[SELINUX_POLICY_HASH_LEN + 1] = "";
1028 BUILD_BUG_ON(sizeof(buf) != sizeof(((struct lu_nodemap *)0)->nm_sepol));
1033 /* we allow sepol = "" which means clear SELinux policy info */
1034 if (sepol[0] == '\0')
1037 /* make a copy of sepol, by replacing ':' with space
1038 * so that we can use sscanf over the string
1040 while (p-sepol < sizeof(buf)) {
1050 if (p-sepol == sizeof(buf))
1051 return -ENAMETOOLONG;
1053 if (sscanf(buf, "%1hhu %s %hu %s", &mode, polname, &ver, hash) != 4)
1056 if (mode != 0 && mode != 1)
1063 * set SELinux policy on nodemap
1064 * \param name nodemap to set SELinux policy info on
1065 * \param sepol string containing SELinux policy info
1066 * \retval 0 on success
1068 * set SELinux policy info on the named nodemap
1070 int nodemap_set_sepol(const char *name, const char *sepol)
1072 struct lu_nodemap *nodemap = NULL;
1075 rc = nodemap_validate_sepol(sepol);
1079 mutex_lock(&active_config_lock);
1080 nodemap = nodemap_lookup(name);
1081 if (IS_ERR(nodemap)) {
1082 mutex_unlock(&active_config_lock);
1083 GOTO(out, rc = PTR_ERR(nodemap));
1086 if (is_default_nodemap(nodemap)) {
1087 /* We do not want nodes in the default nodemap to have
1088 * SELinux restrictions. Sec admin should create dedicated
1089 * nodemap entries for this.
1091 GOTO(out_putref, rc = -EINVAL);
1094 /* truncation cannot happen, as string length was checked in
1095 * nodemap_validate_sepol()
1097 strlcpy(nodemap->nm_sepol, sepol, sizeof(nodemap->nm_sepol));
1100 mutex_unlock(&active_config_lock);
1101 nodemap_putref(nodemap);
1105 EXPORT_SYMBOL(nodemap_set_sepol);
1108 * get SELinux policy info defined on nodemap
1109 * \param nodemap nodemap to get SELinux policy info from
1110 * \retval SELinux policy info, or NULL if not defined or not activated
1112 * get the SELinux policy info defined on the nodemap
1114 const char *nodemap_get_sepol(const struct lu_nodemap *nodemap)
1116 if (is_default_nodemap(nodemap))
1119 return (char *)nodemap->nm_sepol;
1121 EXPORT_SYMBOL(nodemap_get_sepol);
1124 * Nodemap constructor
1126 * Creates an lu_nodemap structure and assigns sane default
1127 * member values. If this is the default nodemap, the defaults
1128 * are the most restrictive in terms of mapping behavior. Otherwise
1129 * the default flags should be inherited from the default nodemap.
1130 * The adds nodemap to nodemap_hash.
1132 * Requires that the caller take the active_config_lock
1134 * \param name name of nodemap
1135 * \param is_default true if default nodemap
1136 * \retval nodemap success
1137 * \retval -EINVAL invalid nodemap name
1138 * \retval -EEXIST nodemap already exists
1139 * \retval -ENOMEM cannot allocate memory for nodemap
1141 struct lu_nodemap *nodemap_create(const char *name,
1142 struct nodemap_config *config,
1145 struct lu_nodemap *nodemap = NULL;
1146 struct lu_nodemap *default_nodemap;
1147 struct cfs_hash *hash = config->nmc_nodemap_hash;
1151 default_nodemap = config->nmc_default_nodemap;
1153 if (!nodemap_name_is_valid(name))
1154 GOTO(out, rc = -EINVAL);
1157 CERROR("Config nodemap hash is NULL, unable to add %s\n", name);
1158 GOTO(out, rc = -EINVAL);
1161 OBD_ALLOC_PTR(nodemap);
1162 if (nodemap == NULL) {
1163 CERROR("cannot allocate memory (%zu bytes) for nodemap '%s'\n",
1164 sizeof(*nodemap), name);
1165 GOTO(out, rc = -ENOMEM);
1169 * take an extra reference to prevent nodemap from being destroyed
1170 * while it's being created.
1172 atomic_set(&nodemap->nm_refcount, 2);
1173 snprintf(nodemap->nm_name, sizeof(nodemap->nm_name), "%s", name);
1174 rc = cfs_hash_add_unique(hash, name, &nodemap->nm_hash);
1176 OBD_FREE_PTR(nodemap);
1177 GOTO(out, rc = -EEXIST);
1180 INIT_LIST_HEAD(&nodemap->nm_ranges);
1181 INIT_LIST_HEAD(&nodemap->nm_list);
1182 INIT_LIST_HEAD(&nodemap->nm_member_list);
1184 mutex_init(&nodemap->nm_member_list_lock);
1185 init_rwsem(&nodemap->nm_idmap_lock);
1186 nodemap->nm_fs_to_client_uidmap = RB_ROOT;
1187 nodemap->nm_client_to_fs_uidmap = RB_ROOT;
1188 nodemap->nm_fs_to_client_gidmap = RB_ROOT;
1189 nodemap->nm_client_to_fs_gidmap = RB_ROOT;
1190 nodemap->nm_fs_to_client_projidmap = RB_ROOT;
1191 nodemap->nm_client_to_fs_projidmap = RB_ROOT;
1194 nodemap->nm_id = LUSTRE_NODEMAP_DEFAULT_ID;
1195 config->nmc_default_nodemap = nodemap;
1197 config->nmc_nodemap_highest_id++;
1198 nodemap->nm_id = config->nmc_nodemap_highest_id;
1201 if (is_default || default_nodemap == NULL) {
1202 nodemap->nmf_trust_client_ids = 0;
1203 nodemap->nmf_allow_root_access = 0;
1204 nodemap->nmf_deny_unknown = 0;
1205 nodemap->nmf_map_mode = NODEMAP_MAP_ALL;
1206 nodemap->nmf_enable_audit = 1;
1207 nodemap->nmf_forbid_encryption = 0;
1208 nodemap->nmf_readonly_mount = 0;
1209 nodemap->nmf_rbac = NODEMAP_RBAC_ALL;
1211 nodemap->nm_squash_uid = NODEMAP_NOBODY_UID;
1212 nodemap->nm_squash_gid = NODEMAP_NOBODY_GID;
1213 nodemap->nm_squash_projid = NODEMAP_NOBODY_PROJID;
1214 nodemap->nm_fileset[0] = '\0';
1215 nodemap->nm_sepol[0] = '\0';
1217 CWARN("adding nodemap '%s' to config without"
1218 " default nodemap\n", nodemap->nm_name);
1220 nodemap->nmf_trust_client_ids =
1221 default_nodemap->nmf_trust_client_ids;
1222 nodemap->nmf_allow_root_access =
1223 default_nodemap->nmf_allow_root_access;
1224 nodemap->nmf_deny_unknown = default_nodemap->nmf_deny_unknown;
1225 nodemap->nmf_map_mode = default_nodemap->nmf_map_mode;
1226 nodemap->nmf_enable_audit = default_nodemap->nmf_enable_audit;
1227 nodemap->nmf_forbid_encryption =
1228 default_nodemap->nmf_forbid_encryption;
1229 nodemap->nmf_readonly_mount =
1230 default_nodemap->nmf_readonly_mount;
1231 nodemap->nmf_rbac = default_nodemap->nmf_rbac;
1233 nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
1234 nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
1235 nodemap->nm_squash_projid = default_nodemap->nm_squash_projid;
1236 nodemap->nm_fileset[0] = '\0';
1237 nodemap->nm_sepol[0] = '\0';
1243 CERROR("cannot add nodemap: '%s': rc = %d\n", name, rc);
1244 RETURN(ERR_PTR(rc));
1248 * Set the nmf_deny_unknown flag to true or false.
1249 * \param name nodemap name
1250 * \param deny_unknown if true, squashed users will get EACCES
1251 * \retval 0 on success
1254 int nodemap_set_deny_unknown(const char *name, bool deny_unknown)
1256 struct lu_nodemap *nodemap = NULL;
1259 mutex_lock(&active_config_lock);
1260 nodemap = nodemap_lookup(name);
1261 mutex_unlock(&active_config_lock);
1262 if (IS_ERR(nodemap))
1263 GOTO(out, rc = PTR_ERR(nodemap));
1265 nodemap->nmf_deny_unknown = deny_unknown;
1266 rc = nodemap_idx_nodemap_update(nodemap);
1268 nm_member_revoke_locks(nodemap);
1269 nodemap_putref(nodemap);
1273 EXPORT_SYMBOL(nodemap_set_deny_unknown);
1276 * Set the nmf_allow_root_access flag to true or false.
1277 * \param name nodemap name
1278 * \param allow_root if true, nodemap will not squash the root user
1279 * \retval 0 on success
1282 int nodemap_set_allow_root(const char *name, bool allow_root)
1284 struct lu_nodemap *nodemap = NULL;
1287 mutex_lock(&active_config_lock);
1288 nodemap = nodemap_lookup(name);
1289 mutex_unlock(&active_config_lock);
1290 if (IS_ERR(nodemap))
1291 GOTO(out, rc = PTR_ERR(nodemap));
1293 nodemap->nmf_allow_root_access = allow_root;
1294 rc = nodemap_idx_nodemap_update(nodemap);
1296 nm_member_revoke_locks(nodemap);
1297 nodemap_putref(nodemap);
1301 EXPORT_SYMBOL(nodemap_set_allow_root);
1304 * Set the nmf_trust_client_ids flag to true or false.
1306 * \param name nodemap name
1307 * \param trust_client_ids if true, nodemap will not map its IDs
1308 * \retval 0 on success
1311 int nodemap_set_trust_client_ids(const char *name, bool trust_client_ids)
1313 struct lu_nodemap *nodemap = NULL;
1316 mutex_lock(&active_config_lock);
1317 nodemap = nodemap_lookup(name);
1318 mutex_unlock(&active_config_lock);
1319 if (IS_ERR(nodemap))
1320 GOTO(out, rc = PTR_ERR(nodemap));
1322 nodemap->nmf_trust_client_ids = trust_client_ids;
1323 rc = nodemap_idx_nodemap_update(nodemap);
1325 nm_member_revoke_locks(nodemap);
1326 nodemap_putref(nodemap);
1330 EXPORT_SYMBOL(nodemap_set_trust_client_ids);
1332 int nodemap_set_mapping_mode(const char *name,
1333 enum nodemap_mapping_modes map_mode)
1335 struct lu_nodemap *nodemap = NULL;
1338 mutex_lock(&active_config_lock);
1339 nodemap = nodemap_lookup(name);
1340 mutex_unlock(&active_config_lock);
1341 if (IS_ERR(nodemap))
1342 GOTO(out, rc = PTR_ERR(nodemap));
1344 nodemap->nmf_map_mode = map_mode;
1345 rc = nodemap_idx_nodemap_update(nodemap);
1347 nm_member_revoke_locks(nodemap);
1348 nodemap_putref(nodemap);
1352 EXPORT_SYMBOL(nodemap_set_mapping_mode);
1354 int nodemap_set_rbac(const char *name, enum nodemap_rbac_roles rbac)
1356 struct lu_nodemap *nodemap = NULL;
1357 enum nodemap_rbac_roles old_rbac;
1360 mutex_lock(&active_config_lock);
1361 nodemap = nodemap_lookup(name);
1362 mutex_unlock(&active_config_lock);
1363 if (IS_ERR(nodemap))
1364 GOTO(out, rc = PTR_ERR(nodemap));
1366 if (is_default_nodemap(nodemap))
1367 GOTO(put, rc = -EINVAL);
1369 old_rbac = nodemap->nmf_rbac;
1370 /* if value does not change, do nothing */
1371 if (rbac == old_rbac)
1374 nodemap->nmf_rbac = rbac;
1375 if (rbac == NODEMAP_RBAC_ALL)
1376 /* if new value is ALL (default), just delete
1377 * NODEMAP_CLUSTER_ROLES idx
1379 rc = nodemap_idx_cluster_roles_del(nodemap);
1380 else if (old_rbac == NODEMAP_RBAC_ALL)
1381 /* if old value is ALL (default), need to insert
1382 * NODEMAP_CLUSTER_ROLES idx
1384 rc = nodemap_idx_cluster_roles_add(nodemap);
1386 /* otherwise just update existing NODEMAP_CLUSTER_ROLES idx */
1387 rc = nodemap_idx_cluster_roles_update(nodemap);
1389 nm_member_revoke_locks(nodemap);
1391 nodemap_putref(nodemap);
1395 EXPORT_SYMBOL(nodemap_set_rbac);
1398 * Update the squash_uid for a nodemap.
1400 * \param name nodemap name
1401 * \param uid the new uid to squash unknown users to
1402 * \retval 0 on success
1404 * Update the squash_uid for a nodemap. The squash_uid is the uid
1405 * that the all client uids are mapped to if nodemap is active,
1406 * the trust_client_ids flag is not set, and the uid is not in
1409 int nodemap_set_squash_uid(const char *name, uid_t uid)
1411 struct lu_nodemap *nodemap = NULL;
1414 mutex_lock(&active_config_lock);
1415 nodemap = nodemap_lookup(name);
1416 mutex_unlock(&active_config_lock);
1417 if (IS_ERR(nodemap))
1418 GOTO(out, rc = PTR_ERR(nodemap));
1420 nodemap->nm_squash_uid = uid;
1421 rc = nodemap_idx_nodemap_update(nodemap);
1423 nm_member_revoke_locks(nodemap);
1424 nodemap_putref(nodemap);
1428 EXPORT_SYMBOL(nodemap_set_squash_uid);
1431 * Update the squash_gid for a nodemap.
1433 * \param name nodemap name
1434 * \param gid the new gid to squash unknown gids to
1435 * \retval 0 on success
1437 * Update the squash_gid for a nodemap. The squash_gid is the gid
1438 * that the all client gids are mapped to if nodemap is active,
1439 * the trust_client_ids flag is not set, and the gid is not in
1442 int nodemap_set_squash_gid(const char *name, gid_t gid)
1444 struct lu_nodemap *nodemap = NULL;
1447 mutex_lock(&active_config_lock);
1448 nodemap = nodemap_lookup(name);
1449 mutex_unlock(&active_config_lock);
1450 if (IS_ERR(nodemap))
1451 GOTO(out, rc = PTR_ERR(nodemap));
1453 nodemap->nm_squash_gid = gid;
1454 rc = nodemap_idx_nodemap_update(nodemap);
1456 nm_member_revoke_locks(nodemap);
1457 nodemap_putref(nodemap);
1461 EXPORT_SYMBOL(nodemap_set_squash_gid);
1464 * Update the squash_projid for a nodemap.
1466 * \param name nodemap name
1467 * \param gid the new projid to squash unknown projids to
1468 * \retval 0 on success
1470 * Update the squash_projid for a nodemap. The squash_projid is the projid
1471 * that the all client projids are mapped to if nodemap is active,
1472 * the trust_client_ids flag is not set, and the projid is not in
1475 int nodemap_set_squash_projid(const char *name, projid_t projid)
1477 struct lu_nodemap *nodemap = NULL;
1480 mutex_lock(&active_config_lock);
1481 nodemap = nodemap_lookup(name);
1482 mutex_unlock(&active_config_lock);
1483 if (IS_ERR(nodemap))
1484 GOTO(out, rc = PTR_ERR(nodemap));
1486 nodemap->nm_squash_projid = projid;
1487 rc = nodemap_idx_nodemap_update(nodemap);
1489 nm_member_revoke_locks(nodemap);
1490 nodemap_putref(nodemap);
1494 EXPORT_SYMBOL(nodemap_set_squash_projid);
1497 * Check if nodemap allows setting quota.
1499 * If nodemap is not active, always allow.
1500 * For user and group quota, allow if the nodemap allows root access.
1501 * For project quota, allow if project id is not squashed or deny_unknown
1504 * \param nodemap nodemap to check access for
1505 * \param qc_type quota type
1506 * \param id client id to map
1507 * \retval true is setquota is allowed, false otherwise
1509 bool nodemap_can_setquota(struct lu_nodemap *nodemap, __u32 qc_type, __u32 id)
1511 if (!nodemap_active)
1514 if (!nodemap || !nodemap->nmf_allow_root_access ||
1515 !(nodemap->nmf_rbac & NODEMAP_RBAC_QUOTA_OPS))
1518 if (qc_type == PRJQUOTA) {
1519 id = nodemap_map_id(nodemap, NODEMAP_PROJID,
1520 NODEMAP_CLIENT_TO_FS, id);
1522 if (id == nodemap->nm_squash_projid &&
1523 nodemap->nmf_deny_unknown)
1529 EXPORT_SYMBOL(nodemap_can_setquota);
1532 * Set the nmf_enable_audit flag to true or false.
1533 * \param name nodemap name
1534 * \param audit_mode if true, allow audit
1535 * \retval 0 on success
1538 int nodemap_set_audit_mode(const char *name, bool enable_audit)
1540 struct lu_nodemap *nodemap = NULL;
1543 mutex_lock(&active_config_lock);
1544 nodemap = nodemap_lookup(name);
1545 mutex_unlock(&active_config_lock);
1546 if (IS_ERR(nodemap))
1547 GOTO(out, rc = PTR_ERR(nodemap));
1549 nodemap->nmf_enable_audit = enable_audit;
1550 rc = nodemap_idx_nodemap_update(nodemap);
1552 nm_member_revoke_locks(nodemap);
1553 nodemap_putref(nodemap);
1557 EXPORT_SYMBOL(nodemap_set_audit_mode);
1560 * Set the nmf_forbid_encryption flag to true or false.
1561 * \param name nodemap name
1562 * \param forbid_encryption if true, forbid encryption
1563 * \retval 0 on success
1566 int nodemap_set_forbid_encryption(const char *name, bool forbid_encryption)
1568 struct lu_nodemap *nodemap = NULL;
1571 mutex_lock(&active_config_lock);
1572 nodemap = nodemap_lookup(name);
1573 mutex_unlock(&active_config_lock);
1574 if (IS_ERR(nodemap))
1575 GOTO(out, rc = PTR_ERR(nodemap));
1577 nodemap->nmf_forbid_encryption = forbid_encryption;
1578 rc = nodemap_idx_nodemap_update(nodemap);
1580 nm_member_revoke_locks(nodemap);
1581 nodemap_putref(nodemap);
1585 EXPORT_SYMBOL(nodemap_set_forbid_encryption);
1588 * Set the nmf_readonly_mount flag to true or false.
1589 * \param name nodemap name
1590 * \param readonly_mount if true, forbid rw mount
1591 * \retval 0 on success
1594 int nodemap_set_readonly_mount(const char *name, bool readonly_mount)
1596 struct lu_nodemap *nodemap = NULL;
1599 mutex_lock(&active_config_lock);
1600 nodemap = nodemap_lookup(name);
1601 mutex_unlock(&active_config_lock);
1602 if (IS_ERR(nodemap))
1603 GOTO(out, rc = PTR_ERR(nodemap));
1605 nodemap->nmf_readonly_mount = readonly_mount;
1606 rc = nodemap_idx_nodemap_update(nodemap);
1608 nm_member_revoke_locks(nodemap);
1609 nodemap_putref(nodemap);
1613 EXPORT_SYMBOL(nodemap_set_readonly_mount);
1618 * \param name name of nodemap
1620 * \retval -EINVAL invalid nodemap name
1621 * \retval -EEXIST nodemap already exists
1622 * \retval -ENOMEM cannot allocate memory for nodemap
1624 int nodemap_add(const char *nodemap_name)
1626 struct lu_nodemap *nodemap;
1629 mutex_lock(&active_config_lock);
1630 nodemap = nodemap_create(nodemap_name, active_config, 0);
1631 if (IS_ERR(nodemap)) {
1632 mutex_unlock(&active_config_lock);
1633 return PTR_ERR(nodemap);
1636 rc = nodemap_idx_nodemap_add(nodemap);
1638 rc = lprocfs_nodemap_register(nodemap, 0);
1640 mutex_unlock(&active_config_lock);
1641 nodemap_putref(nodemap);
1645 EXPORT_SYMBOL(nodemap_add);
1650 * \param name name of nodemmap
1652 * \retval -EINVAL invalid input
1653 * \retval -ENOENT no existing nodemap
1655 int nodemap_del(const char *nodemap_name)
1657 struct lu_nodemap *nodemap;
1658 struct lu_nid_range *range;
1659 struct lu_nid_range *range_temp;
1663 if (strcmp(nodemap_name, DEFAULT_NODEMAP) == 0)
1666 mutex_lock(&active_config_lock);
1667 nodemap = cfs_hash_del_key(active_config->nmc_nodemap_hash,
1669 if (nodemap == NULL) {
1670 mutex_unlock(&active_config_lock);
1671 GOTO(out, rc = -ENOENT);
1674 /* erase nodemap from active ranges to prevent client assignment */
1675 down_write(&active_config->nmc_range_tree_lock);
1676 list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
1678 rc2 = nodemap_idx_range_del(range);
1682 range_delete(active_config, range);
1684 up_write(&active_config->nmc_range_tree_lock);
1686 rc2 = nodemap_idx_nodemap_del(nodemap);
1691 * remove procfs here in case nodemap_create called with same name
1692 * before nodemap_destroy is run.
1694 lprocfs_nodemap_remove(nodemap->nm_pde_data);
1695 nodemap->nm_pde_data = NULL;
1697 /* reclassify all member exports from nodemap, so they put their refs */
1698 down_read(&active_config->nmc_range_tree_lock);
1699 nm_member_reclassify_nodemap(nodemap);
1700 up_read(&active_config->nmc_range_tree_lock);
1702 if (!list_empty(&nodemap->nm_member_list))
1703 CWARN("nodemap_del failed to reclassify all members\n");
1705 mutex_unlock(&active_config_lock);
1707 nodemap_putref(nodemap);
1712 EXPORT_SYMBOL(nodemap_del);
1715 * activate nodemap functions
1717 * \param value 1 for on, 0 for off
1719 void nodemap_activate(const bool value)
1721 mutex_lock(&active_config_lock);
1722 active_config->nmc_nodemap_is_active = value;
1724 /* copy active value to global to avoid locking in map functions */
1725 nodemap_active = value;
1726 nodemap_idx_nodemap_activate(value);
1727 mutex_unlock(&active_config_lock);
1728 nm_member_revoke_all();
1730 EXPORT_SYMBOL(nodemap_activate);
1733 * Helper iterator to convert nodemap hash to list.
1735 * \param hs hash structure
1736 * \param bd bucket descriptor
1737 * \param hnode hash node
1738 * \param nodemap_list_head list head for list of nodemaps in hash
1740 static int nodemap_cleanup_iter_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
1741 struct hlist_node *hnode,
1742 void *nodemap_list_head)
1744 struct lu_nodemap *nodemap;
1746 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
1747 list_add(&nodemap->nm_list, nodemap_list_head);
1749 cfs_hash_bd_del_locked(hs, bd, hnode);
1754 struct nodemap_config *nodemap_config_alloc(void)
1756 struct nodemap_config *config;
1759 OBD_ALLOC_PTR(config);
1761 return ERR_PTR(-ENOMEM);
1763 rc = nodemap_init_hash(config);
1765 OBD_FREE_PTR(config);
1769 init_rwsem(&config->nmc_range_tree_lock);
1771 INIT_LIST_HEAD(&config->nmc_netmask_setup);
1772 config->nmc_range_tree.nmrt_range_interval_root = INTERVAL_TREE_ROOT;
1776 EXPORT_SYMBOL(nodemap_config_alloc);
1779 * Walk the nodemap_hash and remove all nodemaps.
1781 void nodemap_config_dealloc(struct nodemap_config *config)
1783 struct lu_nodemap *nodemap = NULL;
1784 struct lu_nodemap *nodemap_temp;
1785 struct lu_nid_range *range;
1786 struct lu_nid_range *range_temp;
1787 LIST_HEAD(nodemap_list_head);
1789 cfs_hash_for_each_safe(config->nmc_nodemap_hash,
1790 nodemap_cleanup_iter_cb, &nodemap_list_head);
1791 cfs_hash_putref(config->nmc_nodemap_hash);
1793 /* Because nodemap_destroy might sleep, we can't destroy them
1794 * in cfs_hash_for_each, so we build a list there and destroy here
1796 list_for_each_entry_safe(nodemap, nodemap_temp, &nodemap_list_head,
1798 mutex_lock(&active_config_lock);
1799 down_write(&config->nmc_range_tree_lock);
1801 /* move members to new config, requires ac lock */
1802 nm_member_reclassify_nodemap(nodemap);
1803 list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
1805 range_delete(config, range);
1806 up_write(&config->nmc_range_tree_lock);
1807 mutex_unlock(&active_config_lock);
1809 /* putref must be outside of ac lock if nm could be destroyed */
1810 nodemap_putref(nodemap);
1812 OBD_FREE_PTR(config);
1814 EXPORT_SYMBOL(nodemap_config_dealloc);
1817 * callback for cfs_hash_for_each_safe used to convert a nodemap hash to a
1818 * nodemap list, generally for locking purposes as a hash cb can't sleep.
1820 int nm_hash_list_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
1821 struct hlist_node *hnode,
1822 void *nodemap_list_head)
1824 struct lu_nodemap *nodemap;
1826 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
1827 list_add(&nodemap->nm_list, nodemap_list_head);
1831 void nodemap_config_set_active(struct nodemap_config *config)
1833 struct nodemap_config *old_config = active_config;
1834 struct lu_nodemap *nodemap;
1835 struct lu_nodemap *tmp;
1837 LIST_HEAD(nodemap_list_head);
1841 LASSERT(active_config != config);
1842 LASSERT(config->nmc_default_nodemap);
1844 mutex_lock(&active_config_lock);
1846 /* move proc entries from already existing nms, create for new nms */
1847 cfs_hash_for_each_safe(config->nmc_nodemap_hash,
1848 nm_hash_list_cb, &nodemap_list_head);
1849 list_for_each_entry_safe(nodemap, tmp, &nodemap_list_head, nm_list) {
1850 struct lu_nodemap *old_nm = NULL;
1852 if (active_config != NULL)
1853 old_nm = cfs_hash_lookup(
1854 active_config->nmc_nodemap_hash,
1856 if (old_nm != NULL) {
1857 nodemap->nm_pde_data = old_nm->nm_pde_data;
1858 old_nm->nm_pde_data = NULL;
1859 nodemap_putref(old_nm);
1861 bool is_def = (nodemap == config->nmc_default_nodemap);
1863 lprocfs_nodemap_register(nodemap, is_def);
1868 * We only need to revoke locks if old nodemap was active, and new
1869 * config is now nodemap inactive. nodemap_config_dealloc will
1870 * reclassify exports, triggering a lock revoke if and only if new
1871 * nodemap is active.
1873 revoke_locks = !config->nmc_nodemap_is_active && nodemap_active;
1875 /* if new config is inactive, deactivate live config before switching */
1876 if (!config->nmc_nodemap_is_active)
1877 nodemap_active = false;
1878 active_config = config;
1879 if (config->nmc_nodemap_is_active)
1880 nodemap_active = true;
1882 mutex_unlock(&active_config_lock);
1884 if (old_config != NULL)
1885 nodemap_config_dealloc(old_config);
1888 nm_member_revoke_all();
1894 * Cleanup nodemap module on exit
1896 void nodemap_mod_exit(void)
1898 nodemap_config_dealloc(active_config);
1899 nodemap_procfs_exit();
1903 * Initialize the nodemap module
1905 int nodemap_mod_init(void)
1907 struct nodemap_config *new_config;
1908 struct lu_nodemap *nodemap;
1911 rc = nodemap_procfs_init();
1915 new_config = nodemap_config_alloc();
1916 if (IS_ERR(new_config)) {
1917 nodemap_procfs_exit();
1918 GOTO(out, rc = PTR_ERR(new_config));
1921 nodemap = nodemap_create(DEFAULT_NODEMAP, new_config, 1);
1922 if (IS_ERR(nodemap)) {
1923 nodemap_config_dealloc(new_config);
1924 nodemap_procfs_exit();
1925 GOTO(out, rc = PTR_ERR(nodemap));
1928 nodemap_config_set_active(new_config);
1929 nodemap_putref(nodemap);
1936 * Revoke locks for all nodemaps.
1938 void nm_member_revoke_all(void)
1940 struct lu_nodemap *nodemap;
1941 struct lu_nodemap *tmp;
1942 LIST_HEAD(nodemap_list_head);
1944 mutex_lock(&active_config_lock);
1945 cfs_hash_for_each_safe(active_config->nmc_nodemap_hash,
1946 nm_hash_list_cb, &nodemap_list_head);
1948 /* revoke_locks sleeps, so can't call in cfs hash cb */
1949 list_for_each_entry_safe(nodemap, tmp, &nodemap_list_head, nm_list)
1950 nm_member_revoke_locks_always(nodemap);
1951 mutex_unlock(&active_config_lock);
1955 * Returns the nodemap classification for a given nid into an ioctl buffer.
1956 * Useful for testing the nodemap configuration to make sure it is working as
1959 * \param nid nid to classify
1960 * \param[out] name_buf buffer to write the nodemap name to
1961 * \param name_len length of buffer
1963 void nodemap_test_nid(struct lnet_nid *nid, char *name_buf, size_t name_len)
1965 struct lu_nodemap *nodemap;
1967 mutex_lock(&active_config_lock);
1968 down_read(&active_config->nmc_range_tree_lock);
1969 nodemap = nodemap_classify_nid(nid);
1970 up_read(&active_config->nmc_range_tree_lock);
1971 mutex_unlock(&active_config_lock);
1973 if (IS_ERR(nodemap))
1976 strncpy(name_buf, nodemap->nm_name, name_len);
1978 name_buf[name_len - 1] = '\0';
1980 nodemap_putref(nodemap);
1982 EXPORT_SYMBOL(nodemap_test_nid);
1985 * Passes back the id mapping for a given nid/id pair. Useful for testing the
1986 * nodemap configuration to make sure it is working as expected.
1988 * \param nid nid to classify
1989 * \param idtype uid or gid
1990 * \param client_id id to map to fs
1991 * \param fs_id_buf pointer to save mapped fs_id to
1994 * \retval -EINVAL invalid NID
1996 int nodemap_test_id(struct lnet_nid *nid, enum nodemap_id_type idtype,
1997 u32 client_id, u32 *fs_id)
1999 struct lu_nodemap *nodemap;
2001 mutex_lock(&active_config_lock);
2002 down_read(&active_config->nmc_range_tree_lock);
2003 nodemap = nodemap_classify_nid(nid);
2004 up_read(&active_config->nmc_range_tree_lock);
2005 mutex_unlock(&active_config_lock);
2007 if (IS_ERR(nodemap))
2008 return PTR_ERR(nodemap);
2010 *fs_id = nodemap_map_id(nodemap, idtype, NODEMAP_CLIENT_TO_FS,
2012 nodemap_putref(nodemap);
2016 EXPORT_SYMBOL(nodemap_test_id);