/* index features supported by the quota slave indexes */
extern const struct dt_index_features dt_quota_slv_features;
+/* index features supported by the nodemap index */
+extern const struct dt_index_features dt_nodemap_features;
+
/**
* This is a general purpose dt allocation hint.
* It now contains the parent object.
*/
};
+/* nodemap records, uses 32 byte record length */
+#define LUSTRE_NODEMAP_NAME_LENGTH 16
+struct nodemap_cluster_rec {
+ char ncr_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+ __u8 ncr_flags;
+ __u16 ncr_padding1;
+ __u32 ncr_padding2;
+ __u32 ncr_squash_uid;
+ __u32 ncr_squash_gid;
+};
+
+/* lnet_nid_t is 8 bytes */
+struct nodemap_range_rec {
+ lnet_nid_t nrr_start_nid;
+ lnet_nid_t nrr_end_nid;
+ __u64 nrr_padding1;
+ __u64 nrr_padding2;
+};
+
+struct nodemap_id_rec {
+ __u32 nir_id_fs;
+ __u32 nir_padding1;
+ __u64 nir_padding2;
+ __u64 nir_padding3;
+ __u64 nir_padding4;
+};
+
+struct nodemap_global_rec {
+ __u8 ngr_is_active;
+ __u8 ngr_padding1;
+ __u16 ngr_padding2;
+ __u32 ngr_padding3;
+ __u64 ngr_padding4;
+ __u64 ngr_padding5;
+ __u64 ngr_padding6;
+};
+
+union nodemap_rec {
+ struct nodemap_cluster_rec ncr;
+ struct nodemap_range_rec nrr;
+ struct nodemap_id_rec nir;
+ struct nodemap_global_rec ngr;
+};
#endif
/** @} lustreidl */
#ifndef _LUSTRE_NODEMAP_H
#define _LUSTRE_NODEMAP_H
+#include <lustre/lustre_idl.h>
+
#define LUSTRE_NODEMAP_NAME "nodemap"
-#define LUSTRE_NODEMAP_NAME_LENGTH 16
#define LUSTRE_NODEMAP_DEFAULT_ID 0
char nm_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
/* flags to govern nodemap behavior */
bool nmf_trust_client_ids:1,
- nmf_allow_root_access:1,
- nmf_block_lookups:1,
- nmf_hmac_required:1,
- nmf_encryption_required:1;
+ nmf_allow_root_access:1;
/* unique ID set by MGS */
unsigned int nm_id;
/* nodemap ref counter */
struct hlist_node nm_hash;
struct nodemap_pde *nm_pde_data;
- /* used when unloading nodemaps */
+ /* used when loading/unloading nodemaps */
struct list_head nm_list;
};
+/* Store handles to local MGC storage to save config locally. In future
+ * versions of nodemap, mgc will receive the config directly and so this might
+ * not be needed.
+ */
+struct nm_config_file {
+ struct dt_object *ncf_obj;
+ struct list_head ncf_list;
+};
+
void nodemap_activate(const bool value);
int nodemap_add(const char *nodemap_name);
int nodemap_del(const char *nodemap_name);
void nodemap_test_nid(lnet_nid_t nid, char *name_buf, size_t name_len);
__u32 nodemap_test_id(lnet_nid_t nid, enum nodemap_id_type idtype,
__u32 client_id);
+struct nm_config_file *nm_config_file_register(const struct lu_env *env,
+ struct dt_object *obj);
+void nm_config_file_deregister(const struct lu_env *env,
+ struct nm_config_file *ncf);
#endif /* _LUSTRE_NODEMAP_H */
struct lu_target *obt_lut;
__u64 obt_mount_count;
struct obd_job_stats obt_jobstats;
+ struct nm_config_file *obt_nodemap_config_file;
};
#define OBJ_SUBDIR_COUNT 32 /* set to zero for no subdirs */
struct dt_object *o;
struct lu_fid rfid;
struct dt_object *root;
+ struct dt_object *nm_config_file_obj;
+ struct nm_config_file *nm_config_file;
int rc;
ENTRY;
mgs->mgs_configs_dir = o;
+ nm_config_file_obj = local_index_find_or_create(env, mgs->mgs_los,
+ mgs->mgs_configs_dir,
+ LUSTRE_NODEMAP_NAME,
+ S_IFREG | S_IRUGO |
+ S_IWUSR,
+ &dt_nodemap_features);
+ if (IS_ERR(nm_config_file_obj))
+ GOTO(out_configs, rc = PTR_ERR(nm_config_file_obj));
+
+ if (nm_config_file_obj->do_index_ops == NULL) {
+ rc = nm_config_file_obj->do_ops->do_index_try(env,
+ nm_config_file_obj,
+ &dt_nodemap_features);
+ if (rc < 0) {
+ lu_object_put(env, &nm_config_file_obj->do_lu);
+ GOTO(out_configs, rc);
+ }
+ }
+ nm_config_file = nm_config_file_register(env, nm_config_file_obj);
+ if (IS_ERR(nm_config_file)) {
+ lu_object_put(env, &nm_config_file_obj->do_lu);
+ CERROR("%s: error loading nodemap config file, file must be "
+ "removed via ldiskfs: rc = %ld\n",
+ mgs->mgs_obd->obd_name, PTR_ERR(nm_config_file));
+ GOTO(out_configs, rc = PTR_ERR(nm_config_file));
+ }
+ mgs->mgs_obd->u.obt.obt_nodemap_config_file = nm_config_file;
+
/* create directory to store nid table versions */
o = local_file_find_or_create(env, mgs->mgs_los, root, MGS_NIDTBL_DIR,
S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
- if (IS_ERR(o)) {
- lu_object_put(env, &mgs->mgs_configs_dir->do_lu);
- mgs->mgs_configs_dir = NULL;
- GOTO(out_root, rc = PTR_ERR(o));
- }
+ if (IS_ERR(o))
+ GOTO(out_nm, rc = PTR_ERR(o));
mgs->mgs_nidtbl_dir = o;
+out_nm:
+ if (rc < 0) {
+ nm_config_file_deregister(env, nm_config_file);
+ mgs->mgs_obd->u.obt.obt_nodemap_config_file = NULL;
+ }
+out_configs:
+ if (rc < 0) {
+ lu_object_put(env, &mgs->mgs_configs_dir->do_lu);
+ mgs->mgs_configs_dir = NULL;
+ }
out_root:
lu_object_put(env, &root->do_lu);
out_los:
lu_object_put(env, &mgs->mgs_nidtbl_dir->do_lu);
mgs->mgs_nidtbl_dir = NULL;
}
+ if (mgs->mgs_obd->u.obt.obt_nodemap_config_file != NULL) {
+ nm_config_file_deregister(env,
+ mgs->mgs_obd->u.obt.obt_nodemap_config_file);
+ mgs->mgs_obd->u.obt.obt_nodemap_config_file = NULL;
+ }
+
if (mgs->mgs_los) {
local_oid_storage_fini(env, mgs->mgs_los);
mgs->mgs_los = NULL;
#include <libcfs/list.h>
/* fid_be_to_cpu() */
#include <lustre_fid.h>
-
+#include <lustre_nodemap.h>
#include <lustre_quota.h>
/* context key constructor/destructor: dt_global_key_init, dt_global_key_fini */
};
EXPORT_SYMBOL(dt_quota_slv_features);
+/* nodemap files, nodemap_rec size asserted in nodemap_storage.c */
+const struct dt_index_features dt_nodemap_features = {
+ .dif_flags = DT_IND_UPDATE,
+ .dif_keysize_min = sizeof(__u64), /* 64-bit nodemap/record id */
+ .dif_keysize_max = sizeof(__u64), /* 64-bit nodemap/record id */
+ .dif_recsize_min = sizeof(union nodemap_rec), /* 32 bytes */
+ .dif_recsize_max = sizeof(union nodemap_rec), /* 32 bytes */
+ .dif_ptrsize = 4
+};
+EXPORT_SYMBOL(dt_nodemap_features);
+
/* helper function returning what dt_index_features structure should be used
* based on the FID sequence. This is used by OBD_IDX_READ RPC */
static inline const struct dt_index_features *dt_index_feat_select(__u64 seq,
nodemap_objs := nodemap_handler.o nodemap_lproc.o nodemap_range.o
nodemap_objs += nodemap_idmap.o nodemap_rbtree.o nodemap_member.o
+nodemap_objs += nodemap_storage.o
ptlrpc-objs := $(ldlm_objs) $(ptlrpc_objs)
@SERVER_TRUE@ptlrpc-objs += $(target_objs) $(nodemap_objs)
*/
static void nodemap_destroy(struct lu_nodemap *nodemap)
{
+ ENTRY;
+
if (nodemap->nm_pde_data != NULL)
lprocfs_nodemap_remove(nodemap->nm_pde_data);
nm_member_delete_list(nodemap);
OBD_FREE_PTR(nodemap);
+
+ EXIT;
}
/**
*
* \retval 0 on success
*/
-static int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
- enum nodemap_id_type id_type,
- const __u32 map[2])
+int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
+ enum nodemap_id_type id_type,
+ const __u32 map[2])
{
struct lu_idmap *idmap;
int rc = 0;
out:
return rc;
}
+
int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
const __u32 map[2])
{
GOTO(out, rc = PTR_ERR(nodemap));
}
- if (is_default_nodemap(nodemap))
+ if (is_default_nodemap(nodemap)) {
rc = -EINVAL;
- else
+ } else {
rc = nodemap_add_idmap_helper(nodemap, id_type, map);
-
+ if (rc == 0)
+ rc = nodemap_idx_idmap_add(nodemap, id_type, map);
+ }
mutex_unlock(&active_config_lock);
-
nodemap_putref(nodemap);
out:
write_lock(&nodemap->nm_idmap_lock);
idmap = idmap_search(nodemap, NODEMAP_CLIENT_TO_FS, id_type,
map[0]);
- if (idmap == NULL)
+ if (idmap == NULL) {
rc = -EINVAL;
- else
+ } else {
idmap_delete(id_type, idmap, nodemap);
+ rc = nodemap_idx_idmap_del(nodemap, id_type, map);
+ }
write_unlock(&nodemap->nm_idmap_lock);
out_putref:
EXPORT_SYMBOL(nodemap_map_acl);
/*
- * add nid range to nodemap
+ * Add nid range to given nodemap
+ *
+ * \param config nodemap config to work on
* \param nodemap nodemap to add range to
- * \param range_st string containing nid range
- * \retval 0 on success
+ * \param nid nid range to add
+ * \param range_id should be 0 unless loading from disk
+ * \retval 0 success
+ * \retval -ENOMEM
*
- * add an range to the global range tree and attached the
- * range to the named nodemap.
*/
-static int nodemap_add_range_helper(struct nodemap_config *config,
- struct lu_nodemap *nodemap,
- const lnet_nid_t nid[2])
+int nodemap_add_range_helper(struct nodemap_config *config,
+ struct lu_nodemap *nodemap,
+ const lnet_nid_t nid[2],
+ unsigned int range_id)
{
struct lu_nid_range *range;
int rc;
down_write(&config->nmc_range_tree_lock);
- range = range_create(&config->nmc_range_tree, nid[0], nid[1], nodemap);
+ range = range_create(&config->nmc_range_tree, nid[0], nid[1],
+ nodemap, range_id);
if (range == NULL) {
up_write(&config->nmc_range_tree_lock);
GOTO(out, rc = -ENOMEM);
nm_member_reclassify_nodemap(config->nmc_default_nodemap);
up_write(&config->nmc_range_tree_lock);
+ /* if range_id is non-zero, we are loading from disk */
+ if (range_id == 0)
+ rc = nodemap_idx_range_add(range, nid);
+
nm_member_revoke_locks(config->nmc_default_nodemap);
nm_member_revoke_locks(nodemap);
if (is_default_nodemap(nodemap))
rc = -EINVAL;
else
- rc = nodemap_add_range_helper(active_config, nodemap, nid);
+ rc = nodemap_add_range_helper(active_config, nodemap, nid, 0);
mutex_unlock(&active_config_lock);
-
nodemap_putref(nodemap);
out:
return rc;
up_write(&active_config->nmc_range_tree_lock);
GOTO(out_putref, rc = -EINVAL);
}
+ rc = nodemap_idx_range_del(range);
range_delete(&active_config->nmc_range_tree, range);
nm_member_reclassify_nodemap(nodemap);
up_write(&active_config->nmc_range_tree_lock);
bool is_default)
{
struct lu_nodemap *nodemap = NULL;
+ struct lu_nodemap *default_nodemap;
struct cfs_hash *hash = config->nmc_nodemap_hash;
int rc = 0;
+ default_nodemap = config->nmc_default_nodemap;
+
if (!nodemap_name_is_valid(name))
GOTO(out, rc = -EINVAL);
if (is_default) {
nodemap->nm_id = LUSTRE_NODEMAP_DEFAULT_ID;
+ config->nmc_default_nodemap = nodemap;
+ } else {
+ config->nmc_nodemap_highest_id++;
+ nodemap->nm_id = config->nmc_nodemap_highest_id;
+ }
+
+ if (is_default || default_nodemap == NULL) {
nodemap->nmf_trust_client_ids = 0;
nodemap->nmf_allow_root_access = 0;
- nodemap->nmf_block_lookups = 0;
nodemap->nm_squash_uid = NODEMAP_NOBODY_UID;
nodemap->nm_squash_gid = NODEMAP_NOBODY_GID;
-
- config->nmc_default_nodemap = nodemap;
+ if (!is_default)
+ CWARN("adding nodemap '%s' to config without"
+ " default nodemap\n", nodemap->nm_name);
} else {
- struct lu_nodemap *default_nodemap =
- config->nmc_default_nodemap;
-
- config->nmc_nodemap_highest_id++;
- nodemap->nm_id = config->nmc_nodemap_highest_id;
nodemap->nmf_trust_client_ids =
default_nodemap->nmf_trust_client_ids;
nodemap->nmf_allow_root_access =
default_nodemap->nmf_allow_root_access;
- nodemap->nmf_block_lookups =
- default_nodemap->nmf_block_lookups;
nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
GOTO(out, rc = PTR_ERR(nodemap));
nodemap->nmf_allow_root_access = allow_root;
+ rc = nodemap_idx_nodemap_update(nodemap);
nm_member_revoke_locks(nodemap);
nodemap_putref(nodemap);
GOTO(out, rc = PTR_ERR(nodemap));
nodemap->nmf_trust_client_ids = trust_client_ids;
+ rc = nodemap_idx_nodemap_update(nodemap);
nm_member_revoke_locks(nodemap);
nodemap_putref(nodemap);
GOTO(out, rc = PTR_ERR(nodemap));
nodemap->nm_squash_uid = uid;
+ rc = nodemap_idx_nodemap_update(nodemap);
nm_member_revoke_locks(nodemap);
nodemap_putref(nodemap);
GOTO(out, rc = PTR_ERR(nodemap));
nodemap->nm_squash_gid = gid;
+ rc = nodemap_idx_nodemap_update(nodemap);
nm_member_revoke_locks(nodemap);
nodemap_putref(nodemap);
return PTR_ERR(nodemap);
}
- rc = lprocfs_nodemap_register(nodemap, 0);
+ rc = nodemap_idx_nodemap_add(nodemap);
+ if (rc == 0)
+ rc = lprocfs_nodemap_register(nodemap, 0);
+
mutex_unlock(&active_config_lock);
nodemap_putref(nodemap);
struct lu_nid_range *range;
struct lu_nid_range *range_temp;
int rc = 0;
+ int rc2 = 0;
if (strcmp(nodemap_name, DEFAULT_NODEMAP) == 0)
RETURN(-EINVAL);
/* erase nodemap from active ranges to prevent client assignment */
down_write(&active_config->nmc_range_tree_lock);
list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
- rn_list)
+ rn_list) {
+ rc2 = nodemap_idx_range_del(range);
+ if (rc2 < 0)
+ rc = rc2;
+
range_delete(&active_config->nmc_range_tree, range);
+ }
up_write(&active_config->nmc_range_tree_lock);
+ rc2 = nodemap_idx_nodemap_del(nodemap);
+ if (rc2 < 0)
+ rc = rc2;
+
/*
* remove procfs here in case nodemap_create called with same name
* before nodemap_destroy is run.
/* copy active value to global to avoid locking in map functions */
nodemap_active = value;
+ nodemap_idx_nodemap_activate(value);
mutex_unlock(&active_config_lock);
nm_member_revoke_all();
}
#include <lustre_nodemap.h>
#include <interval_tree.h>
-#define MODULE_STRING "nodemap"
+#define DEFAULT_NODEMAP "default"
/* Default nobody uid and gid values */
struct cfs_hash *nmc_nodemap_hash;
};
+/* first 4 bits of the nodemap_id is the index type */
+struct nodemap_key {
+ __u32 nk_nodemap_id;
+ union {
+ __u32 nk_range_id;
+ __u32 nk_id_client;
+ __u32 nk_unused;
+ };
+};
+
+enum nodemap_idx_type {
+ NODEMAP_EMPTY_IDX = 0, /* index created with blank record */
+ NODEMAP_CLUSTER_IDX = 1, /* a nodemap cluster of nodes */
+ NODEMAP_RANGE_IDX = 2, /* nid range assigned to a nm cluster */
+ NODEMAP_UIDMAP_IDX = 3, /* uid map assigned to a nm cluster */
+ NODEMAP_GIDMAP_IDX = 4, /* gid map assigned to a nm cluster */
+ NODEMAP_GLOBAL_IDX = 15, /* stores nodemap activation status */
+};
+
+#define NM_TYPE_MASK 0x0FFFFFFF
+#define NM_TYPE_SHIFT 28
+
+static inline enum nodemap_idx_type nm_idx_get_type(unsigned int id)
+{
+ return id >> NM_TYPE_SHIFT;
+}
+
+static inline __u32 nm_idx_set_type(unsigned int id, enum nodemap_idx_type t)
+{
+ return (id & NM_TYPE_MASK) | (t << NM_TYPE_SHIFT);
+}
+
struct nodemap_config *nodemap_config_alloc(void);
void nodemap_config_dealloc(struct nodemap_config *config);
void nodemap_config_set_active(struct nodemap_config *config);
lnet_nid_t end_nid);
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);
+ struct lu_nodemap *nodemap,
+ unsigned int range_id);
void range_destroy(struct lu_nid_range *range);
int range_insert(struct nodemap_range_tree *nm_range_tree,
struct lu_nid_range *data);
void nm_member_revoke_locks(struct lu_nodemap *nodemap);
void nm_member_revoke_all(void);
+int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
+ enum nodemap_id_type id_type,
+ const __u32 map[2]);
+int nodemap_add_range_helper(struct nodemap_config *config,
+ struct lu_nodemap *nodemap,
+ const lnet_nid_t nid[2],
+ unsigned int range_id);
+
struct rb_node *nm_rb_next_postorder(const struct rb_node *node);
struct rb_node *nm_rb_first_postorder(const struct rb_root *root);
void nodemap_putref(struct lu_nodemap *nodemap);
n = (pos && nm_rb_next_postorder(&pos->field)) ? \
rb_entry(nm_rb_next_postorder(&pos->field), \
typeof(*pos), field) : NULL)
+
+int nodemap_idx_nodemap_add(const struct lu_nodemap *nodemap);
+int nodemap_idx_nodemap_update(const struct lu_nodemap *nodemap);
+int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap);
+int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
+ enum nodemap_id_type id_type,
+ const __u32 map[2]);
+int nodemap_idx_idmap_del(const struct lu_nodemap *nodemap,
+ enum nodemap_id_type id_type,
+ const __u32 map[2]);
+int nodemap_idx_range_add(const struct lu_nid_range *range,
+ const lnet_nid_t nid[2]);
+int nodemap_idx_range_del(const struct lu_nid_range *range);
+int nodemap_idx_nodemap_activate(bool value);
#endif /* _NODEMAP_INTERNAL_H */
*/
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)
+ struct lu_nodemap *nodemap, unsigned range_id)
{
struct lu_nid_range *range;
return NULL;
}
- nm_range_tree->nmrt_range_highest_id++;
- range->rn_id = nm_range_tree->nmrt_range_highest_id;
+ /* if we are loading from save, use on disk id num */
+ if (range_id != 0) {
+ if (nm_range_tree->nmrt_range_highest_id < range_id)
+ nm_range_tree->nmrt_range_highest_id = range_id;
+ range->rn_id = range_id;
+ } else {
+ nm_range_tree->nmrt_range_highest_id++;
+ range->rn_id = nm_range_tree->nmrt_range_highest_id;
+ }
range->rn_nodemap = nodemap;
interval_set(&range->rn_node, start_nid, end_nid);
INIT_LIST_HEAD(&range->rn_list);
--- /dev/null
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (C) 2015, Trustees of Indiana University
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * Author: Joshua Walgenbach <jjw@iu.edu>
+ * Author: Kit Westneat <cwestnea@iu.edu>
+ *
+ * Implements the storage functionality for the nodemap configuration. Functions
+ * in this file prepare, store, and load nodemap configuration data. Targets
+ * using nodemap services should register a configuration file object. Nodemap
+ * configuration changes that need to persist should call the appropriate
+ * storage function for the data being modified.
+ *
+ * There are several index types as defined in enum nodemap_idx_type:
+ * NODEMAP_CLUSTER_IDX stores the data found on the lu_nodemap struct,
+ * like root squash and config flags, as well as
+ * the name.
+ * NODEMAP_RANGE_IDX stores NID range information for a nodemap
+ * NODEMAP_UIDMAP_IDX stores a fs/client UID mapping pair
+ * NODEMAP_GIDMAP_IDX stores a fs/client GID mapping pair
+ * NODEMAP_GLOBAL_IDX stores whether or not nodemaps are active
+ */
+
+#include <libcfs/libcfs.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <lnet/types.h>
+#include <lustre/lustre_idl.h>
+#include <dt_object.h>
+#include <lu_object.h>
+#include <lustre_net.h>
+#include <lustre_nodemap.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include "nodemap_internal.h"
+
+/* list of registered nodemap index files */
+static LIST_HEAD(ncf_list_head);
+static DEFINE_MUTEX(ncf_list_lock);
+
+/* lu_nodemap flags */
+enum nm_flag_shifts {
+ NM_FL_ALLOW_ROOT_ACCESS = 0x1,
+ NM_FL_TRUST_CLIENT_IDS = 0x2,
+};
+
+static void nodemap_cluster_key_init(struct nodemap_key *nk, unsigned int nm_id)
+{
+ nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
+ NODEMAP_CLUSTER_IDX));
+ nk->nk_unused = 0;
+}
+
+static void nodemap_cluster_rec_init(union nodemap_rec *nr,
+ const struct lu_nodemap *nodemap)
+{
+ CLASSERT(sizeof(nr->ncr.ncr_name) == sizeof(nodemap->nm_name));
+
+ strncpy(nr->ncr.ncr_name, nodemap->nm_name, sizeof(nodemap->nm_name));
+ nr->ncr.ncr_squash_uid = cpu_to_le32(nodemap->nm_squash_uid);
+ nr->ncr.ncr_squash_gid = cpu_to_le32(nodemap->nm_squash_gid);
+ nr->ncr.ncr_flags = cpu_to_le32(
+ (nodemap->nmf_trust_client_ids ? NM_FL_TRUST_CLIENT_IDS : 0) |
+ (nodemap->nmf_allow_root_access ? NM_FL_ALLOW_ROOT_ACCESS : 0));
+}
+
+static void nodemap_idmap_key_init(struct nodemap_key *nk, unsigned int nm_id,
+ enum nodemap_id_type id_type,
+ u32 id_client)
+{
+ enum nodemap_idx_type idx_type;
+
+ if (id_type == NODEMAP_UID)
+ idx_type = NODEMAP_UIDMAP_IDX;
+ else
+ idx_type = NODEMAP_GIDMAP_IDX;
+
+ nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id, idx_type));
+ nk->nk_id_client = cpu_to_le32(id_client);
+}
+
+static void nodemap_idmap_rec_init(union nodemap_rec *nr, u32 id_fs)
+{
+ nr->nir.nir_id_fs = cpu_to_le32(id_fs);
+}
+
+static void nodemap_range_key_init(struct nodemap_key *nk, unsigned int nm_id,
+ unsigned int rn_id)
+{
+ nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
+ NODEMAP_RANGE_IDX));
+ nk->nk_range_id = cpu_to_le32(rn_id);
+}
+
+static void nodemap_range_rec_init(union nodemap_rec *nr,
+ const lnet_nid_t nid[2])
+{
+ nr->nrr.nrr_start_nid = cpu_to_le64(nid[0]);
+ nr->nrr.nrr_end_nid = cpu_to_le64(nid[1]);
+}
+
+static void nodemap_global_key_init(struct nodemap_key *nk)
+{
+ nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(0, NODEMAP_GLOBAL_IDX));
+ nk->nk_unused = 0;
+}
+
+static void nodemap_global_rec_init(union nodemap_rec *nr, bool active)
+{
+ nr->ngr.ngr_is_active = active;
+}
+
+/* should be called with dt_write lock */
+static void nodemap_inc_version(const struct lu_env *env,
+ struct dt_object *nodemap_idx,
+ struct thandle *th)
+{
+ u64 ver = dt_version_get(env, nodemap_idx);
+ dt_version_set(env, nodemap_idx, ver + 1, th);
+}
+
+static int nodemap_idx_insert(struct lu_env *env,
+ struct dt_object *idx,
+ const struct nodemap_key *nk,
+ const union nodemap_rec *nr)
+{
+ struct thandle *th;
+ struct dt_device *dev = lu2dt_dev(idx->do_lu.lo_dev);
+ int rc;
+
+ CLASSERT(sizeof(union nodemap_rec) == 32);
+
+ th = dt_trans_create(env, dev);
+
+ if (IS_ERR(th))
+ GOTO(out, rc = PTR_ERR(th));
+
+ rc = dt_declare_insert(env, idx,
+ (const struct dt_rec *)nr,
+ (const struct dt_key *)nk, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_declare_version_set(env, idx, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ dt_write_lock(env, idx, 0);
+
+ rc = dt_insert(env, idx, (const struct dt_rec *)nr,
+ (const struct dt_key *)nk, th, 1);
+
+ nodemap_inc_version(env, idx, th);
+ dt_write_unlock(env, idx);
+out:
+ dt_trans_stop(env, dev, th);
+
+ return rc;
+}
+
+static int nodemap_idx_update(struct lu_env *env,
+ struct dt_object *idx,
+ const struct nodemap_key *nk,
+ const union nodemap_rec *nr)
+{
+ struct thandle *th;
+ struct dt_device *dev = lu2dt_dev(idx->do_lu.lo_dev);
+ int rc = 0;
+
+ th = dt_trans_create(env, dev);
+
+ if (IS_ERR(th))
+ GOTO(out, rc = PTR_ERR(th));
+
+ rc = dt_declare_delete(env, idx, (const struct dt_key *)nk, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_declare_insert(env, idx, (const struct dt_rec *)nr,
+ (const struct dt_key *)nk, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_declare_version_set(env, idx, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ dt_write_lock(env, idx, 0);
+
+ rc = dt_delete(env, idx, (const struct dt_key *)nk, th);
+ if (rc != 0)
+ GOTO(out_lock, rc);
+
+ rc = dt_insert(env, idx, (const struct dt_rec *)nr,
+ (const struct dt_key *)nk, th, 1);
+ if (rc != 0)
+ GOTO(out_lock, rc);
+
+ nodemap_inc_version(env, idx, th);
+out_lock:
+ dt_write_unlock(env, idx);
+out:
+ dt_trans_stop(env, dev, th);
+
+ return rc;
+}
+
+static int nodemap_idx_delete(struct lu_env *env,
+ struct dt_object *idx,
+ const struct nodemap_key *nk,
+ const union nodemap_rec *unused)
+{
+ struct thandle *th;
+ struct dt_device *dev = lu2dt_dev(idx->do_lu.lo_dev);
+ int rc = 0;
+
+ th = dt_trans_create(env, dev);
+
+ if (IS_ERR(th))
+ GOTO(out, rc = PTR_ERR(th));
+
+ rc = dt_declare_delete(env, idx, (const struct dt_key *)nk, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_declare_version_set(env, idx, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ dt_write_lock(env, idx, 0);
+
+ rc = dt_delete(env, idx, (const struct dt_key *)nk, th);
+
+ nodemap_inc_version(env, idx, th);
+
+ dt_write_unlock(env, idx);
+out:
+ dt_trans_stop(env, dev, th);
+
+ return rc;
+}
+
+typedef int (*nm_idx_cb_t)(struct lu_env *env,
+ struct dt_object *idx,
+ const struct nodemap_key *nk,
+ const union nodemap_rec *nr);
+
+/**
+ * Iterates through all the registered nodemap_config_files and calls the
+ * given callback with the ncf as a parameter, as well as the given key and rec.
+ *
+ * \param cb_f callback function to call
+ * \param nk key of the record to act upon
+ * \param nr record to act upon, NULL for the delete action
+ */
+static int nodemap_idx_action(nm_idx_cb_t cb_f, struct nodemap_key *nk,
+ union nodemap_rec *nr)
+{
+ struct nm_config_file *ncf;
+ struct lu_env env;
+ int rc = 0;
+ int rc2 = 0;
+
+ rc = lu_env_init(&env, LCT_LOCAL);
+ if (rc != 0)
+ return rc;
+
+ mutex_lock(&ncf_list_lock);
+ list_for_each_entry(ncf, &ncf_list_head, ncf_list) {
+ rc2 = cb_f(&env, ncf->ncf_obj, nk, nr);
+ if (rc2 < 0) {
+ CWARN("%s: error writing to nodemap config: rc = %d\n",
+ ncf->ncf_obj->do_lu.lo_dev->ld_obd->obd_name, rc);
+ rc = rc2;
+ }
+ }
+ mutex_unlock(&ncf_list_lock);
+ lu_env_fini(&env);
+
+ return 0;
+}
+
+enum nm_add_update {
+ NM_ADD = 0,
+ NM_UPDATE = 1,
+};
+
+static int nodemap_idx_nodemap_add_update(const struct lu_nodemap *nodemap,
+ enum nm_add_update update)
+{
+ struct nodemap_key nk;
+ union nodemap_rec nr;
+ int rc = 0;
+
+ ENTRY;
+
+ nodemap_cluster_key_init(&nk, nodemap->nm_id);
+ nodemap_cluster_rec_init(&nr, nodemap);
+
+ if (update == NM_UPDATE)
+ rc = nodemap_idx_action(nodemap_idx_update, &nk, &nr);
+ else
+ rc = nodemap_idx_action(nodemap_idx_insert, &nk, &nr);
+
+ RETURN(rc);
+}
+
+int nodemap_idx_nodemap_add(const struct lu_nodemap *nodemap)
+{
+ return nodemap_idx_nodemap_add_update(nodemap, NM_ADD);
+}
+
+int nodemap_idx_nodemap_update(const struct lu_nodemap *nodemap)
+{
+ return nodemap_idx_nodemap_add_update(nodemap, NM_UPDATE);
+}
+
+int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
+{
+ struct rb_root root;
+ struct lu_idmap *idmap;
+ struct lu_idmap *temp;
+ struct lu_nid_range *range;
+ struct lu_nid_range *range_temp;
+ struct nodemap_key nk;
+ int rc = 0;
+ int rc2 = 0;
+
+ ENTRY;
+
+ root = nodemap->nm_fs_to_client_uidmap;
+ nm_rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
+ id_fs_to_client) {
+ nodemap_idmap_key_init(&nk, nodemap->nm_id, NODEMAP_UID,
+ idmap->id_client);
+ rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+ if (rc2 < 0)
+ rc = rc2;
+ }
+
+ root = nodemap->nm_client_to_fs_gidmap;
+ nm_rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
+ id_client_to_fs) {
+ nodemap_idmap_key_init(&nk, nodemap->nm_id, NODEMAP_GID,
+ idmap->id_client);
+ rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+ if (rc2 < 0)
+ rc = rc2;
+ }
+
+ list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
+ rn_list) {
+ nodemap_range_key_init(&nk, nodemap->nm_id, range->rn_id);
+ rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+ if (rc2 < 0)
+ rc = rc2;
+ }
+
+ nodemap_cluster_key_init(&nk, nodemap->nm_id);
+ rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+ if (rc2 < 0)
+ rc = rc2;
+
+ RETURN(rc);
+}
+
+int nodemap_idx_range_add(const struct lu_nid_range *range,
+ const lnet_nid_t nid[2])
+{
+ struct nodemap_key nk;
+ union nodemap_rec nr;
+ ENTRY;
+
+ nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
+ nodemap_range_rec_init(&nr, nid);
+
+ RETURN(nodemap_idx_action(nodemap_idx_insert, &nk, &nr));
+}
+
+int nodemap_idx_range_del(const struct lu_nid_range *range)
+{
+ struct nodemap_key nk;
+ ENTRY;
+
+ nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
+
+ RETURN(nodemap_idx_action(nodemap_idx_delete, &nk, NULL));
+}
+
+int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
+ enum nodemap_id_type id_type,
+ const u32 map[2])
+{
+ struct nodemap_key nk;
+ union nodemap_rec nr;
+ ENTRY;
+
+ nodemap_idmap_key_init(&nk, nodemap->nm_id, id_type, map[0]);
+ nodemap_idmap_rec_init(&nr, map[1]);
+
+ RETURN(nodemap_idx_action(nodemap_idx_insert, &nk, &nr));
+}
+
+int nodemap_idx_idmap_del(const struct lu_nodemap *nodemap,
+ enum nodemap_id_type id_type,
+ const u32 map[2])
+{
+ struct nodemap_key nk;
+ ENTRY;
+
+ nodemap_idmap_key_init(&nk, nodemap->nm_id, id_type, map[0]);
+
+ RETURN(nodemap_idx_action(nodemap_idx_delete, &nk, NULL));
+}
+
+static int nodemap_idx_global_add_update(bool value, enum nm_add_update update)
+{
+ struct nodemap_key nk;
+ union nodemap_rec nr;
+ ENTRY;
+
+ nodemap_global_key_init(&nk);
+ nodemap_global_rec_init(&nr, value);
+
+ if (update == NM_UPDATE)
+ RETURN(nodemap_idx_action(nodemap_idx_update, &nk, &nr));
+ else
+ RETURN(nodemap_idx_action(nodemap_idx_insert, &nk, &nr));
+}
+
+int nodemap_idx_nodemap_activate(bool value)
+{
+ return nodemap_idx_global_add_update(value, NM_UPDATE);
+}
+
+/**
+ * Process a key/rec pair and modify the new configuration.
+ *
+ * \param config configuration to update with this key/rec data
+ * \param key key of the record that was loaded
+ * \param rec record that was loaded
+ * \param recent_nodemap last referenced nodemap
+ * \retval type of record processed, see enum #nodemap_idx_type
+ * \retval -ENOENT range or map loaded before nodemap record
+ * \retval -EINVAL duplicate nodemap cluster records found with
+ * different IDs, or nodemap has invalid name
+ * \retval -ENOMEM
+ */
+static int nodemap_process_keyrec(struct nodemap_config *config,
+ const struct nodemap_key *key,
+ const union nodemap_rec *rec,
+ struct lu_nodemap **recent_nodemap)
+{
+ struct lu_nodemap *nodemap = NULL;
+ enum nodemap_idx_type type;
+ enum nodemap_id_type id_type;
+ u8 flags;
+ u32 nodemap_id;
+ lnet_nid_t nid[2];
+ u32 map[2];
+ int rc;
+
+ CLASSERT(sizeof(union nodemap_rec) == 32);
+
+ nodemap_id = le32_to_cpu(key->nk_nodemap_id);
+ type = nm_idx_get_type(nodemap_id);
+ nodemap_id = nm_idx_set_type(nodemap_id, 0);
+
+ /* find the correct nodemap in the load list */
+ if (type == NODEMAP_RANGE_IDX || type == NODEMAP_UIDMAP_IDX ||
+ type == NODEMAP_GIDMAP_IDX) {
+ struct lu_nodemap *tmp = NULL;
+
+ nodemap = *recent_nodemap;
+
+ if (nodemap == NULL)
+ GOTO(out, rc = -ENOENT);
+
+ if (nodemap->nm_id != nodemap_id) {
+ list_for_each_entry(tmp, &nodemap->nm_list, nm_list)
+ if (tmp->nm_id == nodemap_id) {
+ nodemap = tmp;
+ break;
+ }
+
+ if (nodemap->nm_id != nodemap_id)
+ GOTO(out, rc = -ENOENT);
+ }
+
+ /* update most recently used nodemap if necessay */
+ if (nodemap != *recent_nodemap)
+ *recent_nodemap = nodemap;
+ }
+
+ switch (type) {
+ case NODEMAP_EMPTY_IDX:
+ if (nodemap_id != 0)
+ CWARN("Found nodemap config record without type field, "
+ " nodemap_id=%d. nodemap config file corrupt?\n",
+ nodemap_id);
+ break;
+ case NODEMAP_CLUSTER_IDX:
+ nodemap = cfs_hash_lookup(config->nmc_nodemap_hash,
+ rec->ncr.ncr_name);
+ if (nodemap == NULL) {
+ if (nodemap_id == LUSTRE_NODEMAP_DEFAULT_ID) {
+ nodemap = nodemap_create(rec->ncr.ncr_name,
+ config, 1);
+ config->nmc_default_nodemap = nodemap;
+ } else {
+ nodemap = nodemap_create(rec->ncr.ncr_name,
+ config, 0);
+ }
+ if (IS_ERR(nodemap))
+ GOTO(out, rc = PTR_ERR(nodemap));
+
+ /* we need to override the local ID with the saved ID */
+ nodemap->nm_id = nodemap_id;
+ if (nodemap_id > config->nmc_nodemap_highest_id)
+ config->nmc_nodemap_highest_id = nodemap_id;
+
+ } else if (nodemap->nm_id != nodemap_id) {
+ nodemap_putref(nodemap);
+ GOTO(out, rc = -EINVAL);
+ }
+
+ nodemap->nm_squash_uid =
+ le32_to_cpu(rec->ncr.ncr_squash_uid);
+ nodemap->nm_squash_gid =
+ le32_to_cpu(rec->ncr.ncr_squash_gid);
+
+ flags = le32_to_cpu(rec->ncr.ncr_flags);
+ nodemap->nmf_allow_root_access =
+ flags & NM_FL_ALLOW_ROOT_ACCESS;
+ nodemap->nmf_trust_client_ids =
+ flags & NM_FL_TRUST_CLIENT_IDS;
+
+ if (*recent_nodemap == NULL) {
+ *recent_nodemap = nodemap;
+ INIT_LIST_HEAD(&nodemap->nm_list);
+ } else {
+ list_add(&nodemap->nm_list,
+ &(*recent_nodemap)->nm_list);
+ }
+ nodemap_putref(nodemap);
+ break;
+ case NODEMAP_RANGE_IDX:
+ nid[0] = le64_to_cpu(rec->nrr.nrr_start_nid);
+ nid[1] = le64_to_cpu(rec->nrr.nrr_end_nid);
+
+ rc = nodemap_add_range_helper(config, nodemap, nid,
+ le32_to_cpu(key->nk_range_id));
+ if (rc != 0)
+ GOTO(out, rc);
+ break;
+ case NODEMAP_UIDMAP_IDX:
+ case NODEMAP_GIDMAP_IDX:
+ map[0] = le32_to_cpu(key->nk_id_client);
+ map[1] = le32_to_cpu(rec->nir.nir_id_fs);
+
+ if (type == NODEMAP_UIDMAP_IDX)
+ id_type = NODEMAP_UID;
+ else
+ id_type = NODEMAP_GID;
+
+ rc = nodemap_add_idmap_helper(nodemap, id_type, map);
+ if (rc != 0)
+ GOTO(out, rc);
+ break;
+ case NODEMAP_GLOBAL_IDX:
+ config->nmc_nodemap_is_active = rec->ngr.ngr_is_active;
+ break;
+ default:
+ CERROR("got keyrec pair for unknown type %d\n", type);
+ break;
+ }
+ rc = type;
+
+out:
+ return rc;
+}
+
+static int nodemap_load_entries(const struct lu_env *env,
+ struct dt_object *nodemap_idx)
+{
+ const struct dt_it_ops *iops;
+ struct dt_it *it;
+ struct lu_nodemap *recent_nodemap = NULL;
+ struct nodemap_config *new_config = NULL;
+ u64 hash = 0;
+ bool activate_nodemap = false;
+ bool loaded_global_idx = false;
+ int rc = 0;
+
+ ENTRY;
+
+ iops = &nodemap_idx->do_index_ops->dio_it;
+
+ dt_read_lock(env, nodemap_idx, 0);
+ it = iops->init(env, nodemap_idx, 0);
+ if (IS_ERR(it))
+ GOTO(out, rc = PTR_ERR(it));
+
+ rc = iops->load(env, it, hash);
+ if (rc == 0) {
+ rc = iops->next(env, it);
+ if (rc != 0)
+ GOTO(out_iops, rc = 0);
+ }
+
+ /* acquires active config lock */
+ new_config = nodemap_config_alloc();
+
+ if (IS_ERR(new_config)) {
+ rc = PTR_ERR(new_config);
+ new_config = NULL;
+ GOTO(out_lock, rc);
+ }
+
+ do {
+ struct nodemap_key *key;
+ union nodemap_rec rec;
+
+ key = (struct nodemap_key *)iops->key(env, it);
+ rc = iops->rec(env, it, (struct dt_rec *)&rec, 0);
+ if (rc != -ESTALE) {
+ if (rc != 0)
+ GOTO(out_lock, rc);
+ rc = nodemap_process_keyrec(new_config, key, &rec,
+ &recent_nodemap);
+ if (rc < 0)
+ GOTO(out_lock, rc);
+ if (rc == NODEMAP_GLOBAL_IDX)
+ loaded_global_idx = true;
+ }
+
+ do
+ rc = iops->next(env, it);
+ while (rc == -ESTALE);
+ } while (rc == 0);
+
+ if (rc > 0)
+ rc = 0;
+
+out_lock:
+ if (rc != 0)
+ nodemap_config_dealloc(new_config);
+ else
+ /* creating new default needs to be done outside dt read lock */
+ activate_nodemap = true;
+out_iops:
+ iops->put(env, it);
+ iops->fini(env, it);
+out:
+ dt_read_unlock(env, nodemap_idx);
+
+ if (rc != 0)
+ CWARN("%s: failed to load nodemap configuration: rc = %d\n",
+ nodemap_idx->do_lu.lo_dev->ld_obd->obd_name, rc);
+
+ if (!activate_nodemap)
+ RETURN(rc);
+
+ if (new_config->nmc_default_nodemap == NULL) {
+ /* new MGS won't have a default nm on disk, so create it here */
+ new_config->nmc_default_nodemap =
+ nodemap_create(DEFAULT_NODEMAP, new_config, 1);
+ if (IS_ERR(new_config->nmc_default_nodemap)) {
+ rc = PTR_ERR(new_config->nmc_default_nodemap);
+ } else {
+ rc = nodemap_idx_nodemap_add_update(
+ new_config->nmc_default_nodemap, 0);
+ nodemap_putref(new_config->nmc_default_nodemap);
+ }
+ }
+
+ /* new nodemap config won't have an active/inactive record */
+ if (rc == 0 && loaded_global_idx == false)
+ rc = nodemap_idx_global_add_update(false, NM_ADD);
+
+ if (rc == 0)
+ nodemap_config_set_active(new_config);
+ else
+ nodemap_config_dealloc(new_config);
+
+ RETURN(rc);
+}
+
+/**
+ * Register a dt_object representing the config index file. This should be
+ * called by targets in order to load the nodemap configuration from disk. The
+ * dt_object should be created with local_index_find_or_create and the index
+ * features should be enabled with do_index_try.
+ *
+ * \param obj dt_object returned by local_index_find_or_create
+ *
+ * \retval on success: nm_config_file handle for later deregistration
+ * \retval -ENOMEM memory allocation failure
+ * \retval -ENOENT error loading nodemap config
+ * \retval -EINVAL error loading nodemap config
+ */
+struct nm_config_file *nm_config_file_register(const struct lu_env *env,
+ struct dt_object *obj)
+{
+ struct nm_config_file *ncf;
+ bool load_entries = false;
+ int rc;
+ ENTRY;
+
+ OBD_ALLOC_PTR(ncf);
+ if (ncf == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
+
+ ncf->ncf_obj = obj;
+ mutex_lock(&ncf_list_lock);
+
+ /* if this is first config file, we load it from disk */
+ if (list_empty(&ncf_list_head))
+ load_entries = true;
+
+ list_add(&ncf->ncf_list, &ncf_list_head);
+ mutex_unlock(&ncf_list_lock);
+
+ if (load_entries) {
+ rc = nodemap_load_entries(env, obj);
+ if (rc < 0) {
+ mutex_lock(&ncf_list_lock);
+ list_del(&ncf->ncf_list);
+ mutex_unlock(&ncf_list_lock);
+ OBD_FREE_PTR(ncf);
+ RETURN(ERR_PTR(rc));
+ }
+ }
+
+ RETURN(ncf);
+}
+EXPORT_SYMBOL(nm_config_file_register);
+
+/**
+ * Deregister a nm_config_file. Should be called by targets during cleanup.
+ *
+ * \param ncf config file to deregister
+ */
+void nm_config_file_deregister(const struct lu_env *env,
+ struct nm_config_file *ncf)
+{
+ ENTRY;
+
+ lu_object_put(env, &ncf->ncf_obj->do_lu);
+
+ mutex_lock(&ncf_list_lock);
+ list_del(&ncf->ncf_list);
+ mutex_unlock(&ncf_list_lock);
+ OBD_FREE_PTR(ncf);
+
+ EXIT;
+}
+EXPORT_SYMBOL(nm_config_file_deregister);
LASSERTF((int)sizeof(((struct out_update_buffer *)0)->oub_padding) == 4, "found %lld\n",
(long long)(int)sizeof(((struct out_update_buffer *)0)->oub_padding));
+ /* Checks for struct nodemap_cluster_rec */
+ LASSERTF((int)sizeof(struct nodemap_cluster_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_cluster_rec));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_name) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_name));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name) == 17, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_flags) == 17, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_flags));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding1) == 18, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1) == 2, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding2) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid) == 28, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid));
+
+ /* Checks for struct nodemap_range_rec */
+ LASSERTF((int)sizeof(struct nodemap_range_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_range_rec));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_start_nid) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_start_nid));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_end_nid) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_end_nid));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding1) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding2) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2));
+
+ /* Checks for struct nodemap_id_rec */
+ LASSERTF((int)sizeof(struct nodemap_id_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_id_rec));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_id_fs) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_id_fs));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding1) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding2) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding3) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding3));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding4) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding4));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4));
+
+ /* Checks for struct nodemap_global_rec */
+ LASSERTF((int)sizeof(struct nodemap_global_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_global_rec));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_is_active) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_is_active));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding1) == 1, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding2) == 2, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2) == 2, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding3) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding3));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding4) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding4));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding5) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding5));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding6) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding6));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6));
+
+ /* Checks for union nodemap_rec */
+ LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(union nodemap_rec));
+
/* Checks for struct lfsck_request */
LASSERTF((int)sizeof(struct lfsck_request) == 96, "found %lld\n",
(long long)(int)sizeof(struct lfsck_request));
ALWAYS_EXCEPT=" 2 5 6 $SANITY_SEC_EXCEPT"
# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
-[ "$ALWAYS_EXCEPT$EXCEPT" ] && echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT"
-
SRCDIR=$(dirname $0)
export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
export NAME=${NAME:-local}
. ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
init_logging
+[ "$SLOW" = "no" ] && EXCEPT_SLOW="26"
+
+[ "$ALWAYS_EXCEPT$EXCEPT$EXCEPT_SLOW" ] &&
+ echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT $EXCEPT_SLOW"
+
RUNAS_CMD=${RUNAS_CMD:-runas}
WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
local rc=0
## nodemap deactivated
- if ! do_facet mgs lctl nodemap_activate 0; then
+ if ! do_facet mgs $LCTL nodemap_activate 0; then
return 1
fi
for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
done
## nodemap activated
- if ! do_facet mgs lctl nodemap_activate 1; then
+ if ! do_facet mgs $LCTL nodemap_activate 1; then
return 2
fi
do_servers_not_mgs $LCTL set_param nodemap.c0.trusted_nodemap=$trust
# flush MDT locks to make sure they are reacquired before test
- do_node ${clients_arr[0]} lctl set_param \
+ do_node ${clients_arr[0]} $LCTL set_param \
ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
}
}
run_test 24 "check nodemap proc files for LBUGs and Oopses"
+test_25() {
+ nodemap_version_check || return 0
+ nodemap_test_setup
+
+ trap nodemap_test_cleanup EXIT
+ local tmpfile=$(mktemp)
+ do_facet mgs $LCTL nodemap_info > $tmpfile
+ cleanup_and_setup_lustre
+ diff -q <(do_facet mgs $LCTL nodemap_info) $tmpfile >& /dev/null ||
+ error "nodemap_info diff after remount"
+
+ nodemap_test_cleanup
+ rm -f $tmpfile
+}
+run_test 25 "test save and reload nodemap config"
+
+test_26() {
+ nodemap_version_check || return 0
+
+ local large_i=13000
+
+ for ((i = 0; i < large_i; i++)); do
+ ((i % 1000 == 0)) && echo $i
+ do_facet mgs $LCTL nodemap_add c$i ||
+ error "cannot add nodemap $i to config"
+ done
+
+ for ((i = 0; i < large_i; i++)); do
+ ((i % 1000 == 0)) && echo $i
+ do_facet mgs $LCTL nodemap_del c$i ||
+ error "cannot delete nodemap $i from config"
+ done
+}
+run_test 26 "test transferring very large nodemap"
+
log "cleanup: ======================================================"
sec_unsetup() {
## nodemap deactivated
- do_facet mgs lctl nodemap_activate 0
+ do_facet mgs $LCTL nodemap_activate 0
for num in $(seq $MDSCOUNT); do
if [ "${identity_old[$num]}" = 1 ]; then
CHECK_MEMBER(out_update_buffer, oub_padding);
}
+static void check_nodemap_cluster_rec(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(nodemap_cluster_rec);
+ CHECK_MEMBER(nodemap_cluster_rec, ncr_name);
+ CHECK_MEMBER(nodemap_cluster_rec, ncr_flags);
+ CHECK_MEMBER(nodemap_cluster_rec, ncr_padding1);
+ CHECK_MEMBER(nodemap_cluster_rec, ncr_padding2);
+ CHECK_MEMBER(nodemap_cluster_rec, ncr_squash_uid);
+ CHECK_MEMBER(nodemap_cluster_rec, ncr_squash_gid);
+}
+
+static void check_nodemap_range_rec(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(nodemap_range_rec);
+ CHECK_MEMBER(nodemap_range_rec, nrr_start_nid);
+ CHECK_MEMBER(nodemap_range_rec, nrr_end_nid);
+ CHECK_MEMBER(nodemap_range_rec, nrr_padding1);
+ CHECK_MEMBER(nodemap_range_rec, nrr_padding2);
+}
+
+static void check_nodemap_id_rec(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(nodemap_id_rec);
+ CHECK_MEMBER(nodemap_id_rec, nir_id_fs);
+ CHECK_MEMBER(nodemap_id_rec, nir_padding1);
+ CHECK_MEMBER(nodemap_id_rec, nir_padding2);
+ CHECK_MEMBER(nodemap_id_rec, nir_padding3);
+ CHECK_MEMBER(nodemap_id_rec, nir_padding4);
+}
+
+static void check_nodemap_global_rec(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(nodemap_global_rec);
+ CHECK_MEMBER(nodemap_global_rec, ngr_is_active);
+ CHECK_MEMBER(nodemap_global_rec, ngr_padding1);
+ CHECK_MEMBER(nodemap_global_rec, ngr_padding2);
+ CHECK_MEMBER(nodemap_global_rec, ngr_padding3);
+ CHECK_MEMBER(nodemap_global_rec, ngr_padding4);
+ CHECK_MEMBER(nodemap_global_rec, ngr_padding5);
+ CHECK_MEMBER(nodemap_global_rec, ngr_padding6);
+}
+
+static void check_nodemap_rec(void)
+{
+ BLANK_LINE();
+ CHECK_UNION(nodemap_rec);
+}
+
static void check_lfsck_request(void)
{
BLANK_LINE();
check_out_update_header();
check_out_update_buffer();
+ check_nodemap_cluster_rec();
+ check_nodemap_range_rec();
+ check_nodemap_id_rec();
+ check_nodemap_global_rec();
+ check_nodemap_rec();
+
check_lfsck_request();
check_lfsck_reply();
LASSERTF((int)sizeof(((struct out_update_buffer *)0)->oub_padding) == 4, "found %lld\n",
(long long)(int)sizeof(((struct out_update_buffer *)0)->oub_padding));
+ /* Checks for struct nodemap_cluster_rec */
+ LASSERTF((int)sizeof(struct nodemap_cluster_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_cluster_rec));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_name) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_name));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name) == 17, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_flags) == 17, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_flags));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding1) == 18, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1) == 2, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding2) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid));
+ LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid) == 28, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid));
+ LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid));
+
+ /* Checks for struct nodemap_range_rec */
+ LASSERTF((int)sizeof(struct nodemap_range_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_range_rec));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_start_nid) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_start_nid));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_end_nid) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_end_nid));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding1) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding2) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2));
+
+ /* Checks for struct nodemap_id_rec */
+ LASSERTF((int)sizeof(struct nodemap_id_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_id_rec));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_id_fs) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_id_fs));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding1) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding2) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding3) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding3));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3));
+ LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding4) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_id_rec, nir_padding4));
+ LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4));
+
+ /* Checks for struct nodemap_global_rec */
+ LASSERTF((int)sizeof(struct nodemap_global_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_global_rec));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_is_active) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_is_active));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding1) == 1, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding2) == 2, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2) == 2, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding3) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding3));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding4) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding4));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding5) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding5));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5));
+ LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding6) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding6));
+ LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6));
+
+ /* Checks for union nodemap_rec */
+ LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(union nodemap_rec));
+
/* Checks for struct lfsck_request */
LASSERTF((int)sizeof(struct lfsck_request) == 96, "found %lld\n",
(long long)(int)sizeof(struct lfsck_request));