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) 2015, Trustees of Indiana University
25 * Copyright (c) 2014, Intel Corporation.
27 * Author: Joshua Walgenbach <jjw@iu.edu>
28 * Author: Kit Westneat <cwestnea@iu.edu>
30 * Implements the storage functionality for the nodemap configuration. Functions
31 * in this file prepare, store, and load nodemap configuration data. Targets
32 * using nodemap services should register a configuration file object. Nodemap
33 * configuration changes that need to persist should call the appropriate
34 * storage function for the data being modified.
36 * There are several index types as defined in enum nodemap_idx_type:
37 * NODEMAP_CLUSTER_IDX stores the data found on the lu_nodemap struct,
38 * like root squash and config flags, as well as
40 * NODEMAP_RANGE_IDX stores NID range information for a nodemap
41 * NODEMAP_UIDMAP_IDX stores a fs/client UID mapping pair
42 * NODEMAP_GIDMAP_IDX stores a fs/client GID mapping pair
43 * NODEMAP_GLOBAL_IDX stores whether or not nodemaps are active
46 #include <libcfs/libcfs.h>
47 #include <linux/err.h>
48 #include <linux/kernel.h>
49 #include <linux/list.h>
50 #include <linux/mutex.h>
51 #include <linux/string.h>
52 #include <linux/types.h>
53 #include <lnet/types.h>
54 #include <lustre/lustre_idl.h>
55 #include <dt_object.h>
56 #include <lu_object.h>
57 #include <lustre_net.h>
58 #include <lustre_nodemap.h>
59 #include <obd_class.h>
60 #include <obd_support.h>
61 #include "nodemap_internal.h"
63 /* list of registered nodemap index files, except MGS */
64 static LIST_HEAD(ncf_list_head);
65 static DEFINE_MUTEX(ncf_list_lock);
67 /* MGS index is different than others, others are listeners to MGS idx */
68 static struct nm_config_file *nodemap_mgs_ncf;
70 /* lu_nodemap flags */
72 NM_FL_ALLOW_ROOT_ACCESS = 0x1,
73 NM_FL_TRUST_CLIENT_IDS = 0x2,
74 NM_FL_DENY_UNKNOWN = 0x4,
77 static void nodemap_cluster_key_init(struct nodemap_key *nk, unsigned int nm_id)
79 nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
80 NODEMAP_CLUSTER_IDX));
84 static void nodemap_cluster_rec_init(union nodemap_rec *nr,
85 const struct lu_nodemap *nodemap)
87 CLASSERT(sizeof(nr->ncr.ncr_name) == sizeof(nodemap->nm_name));
89 strncpy(nr->ncr.ncr_name, nodemap->nm_name, sizeof(nodemap->nm_name));
90 nr->ncr.ncr_squash_uid = cpu_to_le32(nodemap->nm_squash_uid);
91 nr->ncr.ncr_squash_gid = cpu_to_le32(nodemap->nm_squash_gid);
92 nr->ncr.ncr_flags = cpu_to_le32(
93 (nodemap->nmf_trust_client_ids ?
94 NM_FL_TRUST_CLIENT_IDS : 0) |
95 (nodemap->nmf_allow_root_access ?
96 NM_FL_ALLOW_ROOT_ACCESS : 0) |
97 (nodemap->nmf_deny_unknown ?
98 NM_FL_DENY_UNKNOWN : 0));
101 static void nodemap_idmap_key_init(struct nodemap_key *nk, unsigned int nm_id,
102 enum nodemap_id_type id_type,
105 enum nodemap_idx_type idx_type;
107 if (id_type == NODEMAP_UID)
108 idx_type = NODEMAP_UIDMAP_IDX;
110 idx_type = NODEMAP_GIDMAP_IDX;
112 nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id, idx_type));
113 nk->nk_id_client = cpu_to_le32(id_client);
116 static void nodemap_idmap_rec_init(union nodemap_rec *nr, u32 id_fs)
118 nr->nir.nir_id_fs = cpu_to_le32(id_fs);
121 static void nodemap_range_key_init(struct nodemap_key *nk, unsigned int nm_id,
124 nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
126 nk->nk_range_id = cpu_to_le32(rn_id);
129 static void nodemap_range_rec_init(union nodemap_rec *nr,
130 const lnet_nid_t nid[2])
132 nr->nrr.nrr_start_nid = cpu_to_le64(nid[0]);
133 nr->nrr.nrr_end_nid = cpu_to_le64(nid[1]);
136 static void nodemap_global_key_init(struct nodemap_key *nk)
138 nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(0, NODEMAP_GLOBAL_IDX));
142 static void nodemap_global_rec_init(union nodemap_rec *nr, bool active)
144 nr->ngr.ngr_is_active = active;
147 /* should be called with dt_write lock */
148 static void nodemap_inc_version(const struct lu_env *env,
149 struct dt_object *nodemap_idx,
152 u64 ver = dt_version_get(env, nodemap_idx);
153 dt_version_set(env, nodemap_idx, ver + 1, th);
156 static int nodemap_idx_insert(const struct lu_env *env,
157 struct dt_object *idx,
158 const struct nodemap_key *nk,
159 const union nodemap_rec *nr)
162 struct dt_device *dev = lu2dt_dev(idx->do_lu.lo_dev);
165 CLASSERT(sizeof(union nodemap_rec) == 32);
167 th = dt_trans_create(env, dev);
170 GOTO(out, rc = PTR_ERR(th));
172 rc = dt_declare_insert(env, idx,
173 (const struct dt_rec *)nr,
174 (const struct dt_key *)nk, th);
178 rc = dt_declare_version_set(env, idx, th);
182 rc = dt_trans_start_local(env, dev, th);
186 dt_write_lock(env, idx, 0);
188 rc = dt_insert(env, idx, (const struct dt_rec *)nr,
189 (const struct dt_key *)nk, th, 1);
191 nodemap_inc_version(env, idx, th);
192 dt_write_unlock(env, idx);
194 dt_trans_stop(env, dev, th);
199 static int nodemap_idx_update(const struct lu_env *env,
200 struct dt_object *idx,
201 const struct nodemap_key *nk,
202 const union nodemap_rec *nr)
205 struct dt_device *dev = lu2dt_dev(idx->do_lu.lo_dev);
208 th = dt_trans_create(env, dev);
211 GOTO(out, rc = PTR_ERR(th));
213 rc = dt_declare_delete(env, idx, (const struct dt_key *)nk, th);
217 rc = dt_declare_insert(env, idx, (const struct dt_rec *)nr,
218 (const struct dt_key *)nk, th);
222 rc = dt_declare_version_set(env, idx, th);
226 rc = dt_trans_start_local(env, dev, th);
230 dt_write_lock(env, idx, 0);
232 rc = dt_delete(env, idx, (const struct dt_key *)nk, th);
236 rc = dt_insert(env, idx, (const struct dt_rec *)nr,
237 (const struct dt_key *)nk, th, 1);
241 nodemap_inc_version(env, idx, th);
243 dt_write_unlock(env, idx);
245 dt_trans_stop(env, dev, th);
250 static int nodemap_idx_delete(const struct lu_env *env,
251 struct dt_object *idx,
252 const struct nodemap_key *nk,
253 const union nodemap_rec *unused)
256 struct dt_device *dev = lu2dt_dev(idx->do_lu.lo_dev);
259 th = dt_trans_create(env, dev);
262 GOTO(out, rc = PTR_ERR(th));
264 rc = dt_declare_delete(env, idx, (const struct dt_key *)nk, th);
268 rc = dt_declare_version_set(env, idx, th);
272 rc = dt_trans_start_local(env, dev, th);
276 dt_write_lock(env, idx, 0);
278 rc = dt_delete(env, idx, (const struct dt_key *)nk, th);
280 nodemap_inc_version(env, idx, th);
282 dt_write_unlock(env, idx);
284 dt_trans_stop(env, dev, th);
294 static int nodemap_idx_nodemap_add_update(const struct lu_nodemap *nodemap,
295 enum nm_add_update update)
297 struct nodemap_key nk;
298 union nodemap_rec nr;
304 if (nodemap_mgs_ncf == NULL) {
305 CERROR("cannot add nodemap config to non-existing MGS.\n");
309 rc = lu_env_init(&env, LCT_LOCAL);
313 nodemap_cluster_key_init(&nk, nodemap->nm_id);
314 nodemap_cluster_rec_init(&nr, nodemap);
316 if (update == NM_UPDATE)
317 rc = nodemap_idx_update(&env, nodemap_mgs_ncf->ncf_obj,
320 rc = nodemap_idx_insert(&env, nodemap_mgs_ncf->ncf_obj,
328 int nodemap_idx_nodemap_add(const struct lu_nodemap *nodemap)
330 return nodemap_idx_nodemap_add_update(nodemap, NM_ADD);
333 int nodemap_idx_nodemap_update(const struct lu_nodemap *nodemap)
335 return nodemap_idx_nodemap_add_update(nodemap, NM_UPDATE);
338 int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
341 struct lu_idmap *idmap;
342 struct lu_idmap *temp;
343 struct lu_nid_range *range;
344 struct lu_nid_range *range_temp;
345 struct nodemap_key nk;
352 if (nodemap_mgs_ncf == NULL) {
353 CERROR("cannot add nodemap config to non-existing MGS.\n");
357 rc = lu_env_init(&env, LCT_LOCAL);
361 root = nodemap->nm_fs_to_client_uidmap;
362 nm_rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
364 nodemap_idmap_key_init(&nk, nodemap->nm_id, NODEMAP_UID,
366 rc2 = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj,
372 root = nodemap->nm_client_to_fs_gidmap;
373 nm_rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
375 nodemap_idmap_key_init(&nk, nodemap->nm_id, NODEMAP_GID,
377 rc2 = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj,
383 list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
385 nodemap_range_key_init(&nk, nodemap->nm_id, range->rn_id);
386 rc2 = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj,
392 nodemap_cluster_key_init(&nk, nodemap->nm_id);
393 rc2 = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj, &nk, NULL);
402 int nodemap_idx_range_add(const struct lu_nid_range *range,
403 const lnet_nid_t nid[2])
405 struct nodemap_key nk;
406 union nodemap_rec nr;
411 if (nodemap_mgs_ncf == NULL) {
412 CERROR("cannot add nodemap config to non-existing MGS.\n");
416 rc = lu_env_init(&env, LCT_LOCAL);
420 nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
421 nodemap_range_rec_init(&nr, nid);
423 rc = nodemap_idx_insert(&env, nodemap_mgs_ncf->ncf_obj, &nk, &nr);
429 int nodemap_idx_range_del(const struct lu_nid_range *range)
431 struct nodemap_key nk;
436 if (nodemap_mgs_ncf == NULL) {
437 CERROR("cannot add nodemap config to non-existing MGS.\n");
441 rc = lu_env_init(&env, LCT_LOCAL);
445 nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
447 rc = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj, &nk, NULL);
453 int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
454 enum nodemap_id_type id_type,
457 struct nodemap_key nk;
458 union nodemap_rec nr;
463 if (nodemap_mgs_ncf == NULL) {
464 CERROR("cannot add nodemap config to non-existing MGS.\n");
468 rc = lu_env_init(&env, LCT_LOCAL);
472 nodemap_idmap_key_init(&nk, nodemap->nm_id, id_type, map[0]);
473 nodemap_idmap_rec_init(&nr, map[1]);
475 rc = nodemap_idx_insert(&env, nodemap_mgs_ncf->ncf_obj, &nk, &nr);
481 int nodemap_idx_idmap_del(const struct lu_nodemap *nodemap,
482 enum nodemap_id_type id_type,
485 struct nodemap_key nk;
490 if (nodemap_mgs_ncf == NULL) {
491 CERROR("cannot add nodemap config to non-existing MGS.\n");
495 rc = lu_env_init(&env, LCT_LOCAL);
499 nodemap_idmap_key_init(&nk, nodemap->nm_id, id_type, map[0]);
501 rc = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj, &nk, NULL);
507 static int nodemap_idx_global_add_update(bool value, enum nm_add_update update)
509 struct nodemap_key nk;
510 union nodemap_rec nr;
515 if (nodemap_mgs_ncf == NULL) {
516 CERROR("cannot add nodemap config to non-existing MGS.\n");
520 rc = lu_env_init(&env, LCT_LOCAL);
524 nodemap_global_key_init(&nk);
525 nodemap_global_rec_init(&nr, value);
527 if (update == NM_UPDATE)
528 rc = nodemap_idx_update(&env, nodemap_mgs_ncf->ncf_obj,
531 rc = nodemap_idx_insert(&env, nodemap_mgs_ncf->ncf_obj,
539 int nodemap_idx_nodemap_activate(bool value)
541 return nodemap_idx_global_add_update(value, NM_UPDATE);
545 * Process a key/rec pair and modify the new configuration.
547 * \param config configuration to update with this key/rec data
548 * \param key key of the record that was loaded
549 * \param rec record that was loaded
550 * \param recent_nodemap last referenced nodemap
551 * \retval type of record processed, see enum #nodemap_idx_type
552 * \retval -ENOENT range or map loaded before nodemap record
553 * \retval -EINVAL duplicate nodemap cluster records found with
554 * different IDs, or nodemap has invalid name
557 static int nodemap_process_keyrec(struct nodemap_config *config,
558 const struct nodemap_key *key,
559 const union nodemap_rec *rec,
560 struct lu_nodemap **recent_nodemap)
562 struct lu_nodemap *nodemap = NULL;
563 enum nodemap_idx_type type;
564 enum nodemap_id_type id_type;
571 CLASSERT(sizeof(union nodemap_rec) == 32);
573 nodemap_id = le32_to_cpu(key->nk_nodemap_id);
574 type = nm_idx_get_type(nodemap_id);
575 nodemap_id = nm_idx_set_type(nodemap_id, 0);
577 CDEBUG(D_INFO, "found config entry, nm_id %d type %d\n",
580 /* find the correct nodemap in the load list */
581 if (type == NODEMAP_RANGE_IDX || type == NODEMAP_UIDMAP_IDX ||
582 type == NODEMAP_GIDMAP_IDX) {
583 struct lu_nodemap *tmp = NULL;
585 nodemap = *recent_nodemap;
588 GOTO(out, rc = -ENOENT);
590 if (nodemap->nm_id != nodemap_id) {
591 list_for_each_entry(tmp, &nodemap->nm_list, nm_list)
592 if (tmp->nm_id == nodemap_id) {
597 if (nodemap->nm_id != nodemap_id)
598 GOTO(out, rc = -ENOENT);
601 /* update most recently used nodemap if necessay */
602 if (nodemap != *recent_nodemap)
603 *recent_nodemap = nodemap;
607 case NODEMAP_EMPTY_IDX:
609 CWARN("Found nodemap config record without type field, "
610 " nodemap_id=%d. nodemap config file corrupt?\n",
613 case NODEMAP_CLUSTER_IDX:
614 nodemap = cfs_hash_lookup(config->nmc_nodemap_hash,
616 if (nodemap == NULL) {
617 if (nodemap_id == LUSTRE_NODEMAP_DEFAULT_ID) {
618 nodemap = nodemap_create(rec->ncr.ncr_name,
620 config->nmc_default_nodemap = nodemap;
622 nodemap = nodemap_create(rec->ncr.ncr_name,
626 GOTO(out, rc = PTR_ERR(nodemap));
628 /* we need to override the local ID with the saved ID */
629 nodemap->nm_id = nodemap_id;
630 if (nodemap_id > config->nmc_nodemap_highest_id)
631 config->nmc_nodemap_highest_id = nodemap_id;
633 } else if (nodemap->nm_id != nodemap_id) {
634 nodemap_putref(nodemap);
635 GOTO(out, rc = -EINVAL);
638 nodemap->nm_squash_uid =
639 le32_to_cpu(rec->ncr.ncr_squash_uid);
640 nodemap->nm_squash_gid =
641 le32_to_cpu(rec->ncr.ncr_squash_gid);
643 flags = le32_to_cpu(rec->ncr.ncr_flags);
644 nodemap->nmf_allow_root_access =
645 flags & NM_FL_ALLOW_ROOT_ACCESS;
646 nodemap->nmf_trust_client_ids =
647 flags & NM_FL_TRUST_CLIENT_IDS;
648 nodemap->nmf_deny_unknown =
649 flags & NM_FL_DENY_UNKNOWN;
651 if (*recent_nodemap == NULL) {
652 *recent_nodemap = nodemap;
653 INIT_LIST_HEAD(&nodemap->nm_list);
655 list_add(&nodemap->nm_list,
656 &(*recent_nodemap)->nm_list);
658 nodemap_putref(nodemap);
660 case NODEMAP_RANGE_IDX:
661 nid[0] = le64_to_cpu(rec->nrr.nrr_start_nid);
662 nid[1] = le64_to_cpu(rec->nrr.nrr_end_nid);
664 rc = nodemap_add_range_helper(config, nodemap, nid,
665 le32_to_cpu(key->nk_range_id));
669 case NODEMAP_UIDMAP_IDX:
670 case NODEMAP_GIDMAP_IDX:
671 map[0] = le32_to_cpu(key->nk_id_client);
672 map[1] = le32_to_cpu(rec->nir.nir_id_fs);
674 if (type == NODEMAP_UIDMAP_IDX)
675 id_type = NODEMAP_UID;
677 id_type = NODEMAP_GID;
679 rc = nodemap_add_idmap_helper(nodemap, id_type, map);
683 case NODEMAP_GLOBAL_IDX:
684 config->nmc_nodemap_is_active = rec->ngr.ngr_is_active;
687 CERROR("got keyrec pair for unknown type %d\n", type);
697 static int nodemap_load_entries(const struct lu_env *env,
698 struct dt_object *nodemap_idx)
700 const struct dt_it_ops *iops;
702 struct lu_nodemap *recent_nodemap = NULL;
703 struct nodemap_config *new_config = NULL;
705 bool activate_nodemap = false;
706 bool loaded_global_idx = false;
711 iops = &nodemap_idx->do_index_ops->dio_it;
713 dt_read_lock(env, nodemap_idx, 0);
714 it = iops->init(env, nodemap_idx, 0);
716 GOTO(out, rc = PTR_ERR(it));
718 rc = iops->load(env, it, hash);
720 rc = iops->next(env, it);
722 GOTO(out_iops, rc = 0);
725 new_config = nodemap_config_alloc();
726 if (IS_ERR(new_config)) {
727 rc = PTR_ERR(new_config);
733 struct nodemap_key *key;
734 union nodemap_rec rec;
736 key = (struct nodemap_key *)iops->key(env, it);
737 rc = iops->rec(env, it, (struct dt_rec *)&rec, 0);
741 rc = nodemap_process_keyrec(new_config, key, &rec,
745 if (rc == NODEMAP_GLOBAL_IDX)
746 loaded_global_idx = true;
750 rc = iops->next(env, it);
751 while (rc == -ESTALE);
759 nodemap_config_dealloc(new_config);
761 /* creating new default needs to be done outside dt read lock */
762 activate_nodemap = true;
767 dt_read_unlock(env, nodemap_idx);
770 CWARN("%s: failed to load nodemap configuration: rc = %d\n",
771 nodemap_idx->do_lu.lo_dev->ld_obd->obd_name, rc);
773 if (!activate_nodemap)
776 if (new_config->nmc_default_nodemap == NULL) {
777 /* new MGS won't have a default nm on disk, so create it here */
778 new_config->nmc_default_nodemap =
779 nodemap_create(DEFAULT_NODEMAP, new_config, 1);
780 if (IS_ERR(new_config->nmc_default_nodemap)) {
781 rc = PTR_ERR(new_config->nmc_default_nodemap);
783 rc = nodemap_idx_nodemap_add_update(
784 new_config->nmc_default_nodemap,
786 nodemap_putref(new_config->nmc_default_nodemap);
790 /* new nodemap config won't have an active/inactive record */
791 if (rc == 0 && loaded_global_idx == false) {
792 struct nodemap_key nk;
793 union nodemap_rec nr;
795 nodemap_global_key_init(&nk);
796 nodemap_global_rec_init(&nr, false);
797 rc = nodemap_idx_insert(env, nodemap_idx, &nk, &nr);
801 nodemap_config_set_active(new_config);
803 nodemap_config_dealloc(new_config);
808 /* tracks if config still needs to be loaded, either from disk or network */
809 static bool nodemap_config_loaded;
810 static DEFINE_MUTEX(nodemap_config_loaded_lock);
813 * Ensures that configs loaded over the wire are prioritized over those loaded
816 * \param config config to set as the active config
818 void nodemap_config_set_active_mgc(struct nodemap_config *config)
820 mutex_lock(&nodemap_config_loaded_lock);
821 nodemap_config_set_active(config);
822 nodemap_config_loaded = true;
823 mutex_unlock(&nodemap_config_loaded_lock);
825 EXPORT_SYMBOL(nodemap_config_set_active_mgc);
828 * Register a dt_object representing the config index file. This should be
829 * called by targets in order to load the nodemap configuration from disk. The
830 * dt_object should be created with local_index_find_or_create and the index
831 * features should be enabled with do_index_try.
833 * \param obj dt_object returned by local_index_find_or_create
835 * \retval on success: nm_config_file handle for later deregistration
836 * \retval -ENOMEM memory allocation failure
837 * \retval -ENOENT error loading nodemap config
838 * \retval -EINVAL error loading nodemap config
840 struct nm_config_file *nm_config_file_register(const struct lu_env *env,
841 struct dt_object *obj,
842 struct local_oid_storage *los,
843 enum nm_config_file_type ncf_type)
845 struct nm_config_file *ncf;
851 RETURN(ERR_PTR(-ENOMEM));
856 if (ncf_type == NCFT_MGS) {
857 nodemap_mgs_ncf = ncf;
859 mutex_lock(&ncf_list_lock);
860 list_add(&ncf->ncf_list, &ncf_list_head);
861 mutex_unlock(&ncf_list_lock);
864 /* prevent activation of config loaded from MGS until disk is loaded
865 * so disk config is overwritten by MGS config.
867 mutex_lock(&nodemap_config_loaded_lock);
868 if (ncf_type == NCFT_MGS || !nodemap_config_loaded)
869 rc = nodemap_load_entries(env, obj);
870 nodemap_config_loaded = true;
871 mutex_unlock(&nodemap_config_loaded_lock);
874 if (ncf_type == NCFT_MGS) {
875 nodemap_mgs_ncf = NULL;
877 mutex_lock(&ncf_list_lock);
878 list_del(&ncf->ncf_list);
879 mutex_unlock(&ncf_list_lock);
888 EXPORT_SYMBOL(nm_config_file_register);
891 * Deregister a nm_config_file. Should be called by targets during cleanup.
893 * \param ncf config file to deregister
895 void nm_config_file_deregister(const struct lu_env *env,
896 struct nm_config_file *ncf,
897 enum nm_config_file_type ncf_type)
902 lu_object_put(env, &ncf->ncf_obj->do_lu);
904 if (ncf_type == NCFT_TGT) {
905 mutex_lock(&ncf_list_lock);
906 list_del(&ncf->ncf_list);
907 mutex_unlock(&ncf_list_lock);
909 nodemap_mgs_ncf = NULL;
915 EXPORT_SYMBOL(nm_config_file_deregister);
917 int nodemap_process_idx_pages(struct nodemap_config *config, union lu_page *lip,
918 struct lu_nodemap **recent_nodemap)
920 struct nodemap_key *key;
921 union nodemap_rec *rec;
926 int size = dt_nodemap_features.dif_keysize_max +
927 dt_nodemap_features.dif_recsize_max;
930 for (j = 0; j < LU_PAGE_COUNT; j++) {
931 if (lip->lp_idx.lip_magic != LIP_MAGIC)
934 /* get and process keys and records from page */
935 for (k = 0; k < lip->lp_idx.lip_nr; k++) {
936 entry = lip->lp_idx.lip_entries + k * size;
937 key = (struct nodemap_key *)entry;
939 entry += dt_nodemap_features.dif_keysize_max;
940 rec = (union nodemap_rec *)entry;
942 rc = nodemap_process_keyrec(config, key, rec,
953 EXPORT_SYMBOL(nodemap_process_idx_pages);
955 int nodemap_index_read(struct lu_env *env,
956 struct nm_config_file *ncf,
958 const struct lu_rdpg *rdpg)
960 struct dt_object *nodemap_idx = ncf->ncf_obj;
964 ii->ii_keysize = dt_nodemap_features.dif_keysize_max;
965 ii->ii_recsize = dt_nodemap_features.dif_recsize_max;
967 dt_read_lock(env, nodemap_idx, 0);
968 version = dt_version_get(env, nodemap_idx);
969 if (rdpg->rp_hash != 0 && ii->ii_version != version) {
970 CDEBUG(D_INFO, "nodemap config changed while sending, "
971 "old "LPU64", new "LPU64"\n",
976 rc = dt_index_walk(env, nodemap_idx, rdpg, NULL, ii);
977 CDEBUG(D_INFO, "walked index, hashend %llx\n", ii->ii_hash_end);
981 ii->ii_version = version;
983 dt_read_unlock(env, nodemap_idx);
986 EXPORT_SYMBOL(nodemap_index_read);
989 * Returns the current nodemap configuration to MGC by walking the nodemap
990 * config index and storing it in the response buffer.
992 * \param req incoming MGS_CONFIG_READ request
994 * \retval -EINVAL malformed request
995 * \retval -ENOTCONN client evicted/reconnected already
996 * \retval -ETIMEDOUT client timeout or network error
999 int nodemap_get_config_req(struct obd_device *mgs_obd,
1000 struct ptlrpc_request *req)
1002 struct mgs_config_body *body;
1003 struct mgs_config_res *res;
1004 struct lu_rdpg rdpg;
1005 struct idx_info nodemap_ii;
1006 struct ptlrpc_bulk_desc *desc;
1007 struct l_wait_info lwi;
1008 struct tg_export_data *rqexp_ted = &req->rq_export->exp_target_data;
1014 body = req_capsule_client_get(&req->rq_pill, &RMF_MGS_CONFIG_BODY);
1018 if (body->mcb_type != CONFIG_T_NODEMAP)
1021 rdpg.rp_count = (body->mcb_units << body->mcb_bits);
1022 rdpg.rp_npages = (rdpg.rp_count + PAGE_CACHE_SIZE - 1) >>
1024 if (rdpg.rp_npages > PTLRPC_MAX_BRW_PAGES)
1027 CDEBUG(D_INFO, "reading nodemap log, name '%s', size = %u\n",
1028 body->mcb_name, rdpg.rp_count);
1030 /* allocate pages to store the containers */
1031 OBD_ALLOC(rdpg.rp_pages, sizeof(*rdpg.rp_pages) * rdpg.rp_npages);
1032 if (rdpg.rp_pages == NULL)
1034 for (i = 0; i < rdpg.rp_npages; i++) {
1035 rdpg.rp_pages[i] = alloc_page(GFP_IOFS);
1036 if (rdpg.rp_pages[i] == NULL)
1037 GOTO(out, rc = -ENOMEM);
1040 rdpg.rp_hash = body->mcb_offset;
1041 nodemap_ii.ii_magic = IDX_INFO_MAGIC;
1042 nodemap_ii.ii_flags = II_FL_NOHASH;
1043 nodemap_ii.ii_version = rqexp_ted->ted_nodemap_version;
1045 bytes = nodemap_index_read(req->rq_svc_thread->t_env,
1046 mgs_obd->u.obt.obt_nodemap_config_file,
1047 &nodemap_ii, &rdpg);
1049 GOTO(out, rc = bytes);
1051 rqexp_ted->ted_nodemap_version = nodemap_ii.ii_version;
1053 res = req_capsule_server_get(&req->rq_pill, &RMF_MGS_CONFIG_RES);
1055 GOTO(out, rc = -EINVAL);
1056 res->mcr_offset = nodemap_ii.ii_hash_end;
1057 res->mcr_size = bytes;
1059 page_count = (bytes + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
1060 LASSERT(page_count <= rdpg.rp_count);
1061 desc = ptlrpc_prep_bulk_exp(req, page_count, 1,
1062 PTLRPC_BULK_PUT_SOURCE |
1063 PTLRPC_BULK_BUF_KIOV,
1065 &ptlrpc_bulk_kiov_pin_ops);
1067 GOTO(out, rc = -ENOMEM);
1069 for (i = 0; i < page_count && bytes > 0; i++) {
1070 ptlrpc_prep_bulk_page_pin(desc, rdpg.rp_pages[i], 0,
1071 min_t(int, bytes, PAGE_CACHE_SIZE));
1072 bytes -= PAGE_CACHE_SIZE;
1075 rc = target_bulk_io(req->rq_export, desc, &lwi);
1076 ptlrpc_free_bulk(desc);
1079 if (rdpg.rp_pages != NULL) {
1080 for (i = 0; i < rdpg.rp_npages; i++)
1081 if (rdpg.rp_pages[i] != NULL)
1082 __free_page(rdpg.rp_pages[i]);
1083 OBD_FREE(rdpg.rp_pages,
1084 rdpg.rp_npages * sizeof(rdpg.rp_pages[0]));
1088 EXPORT_SYMBOL(nodemap_get_config_req);