Whamcloud - gitweb
LU-17431 ptlrpc: move nodemap related ioctls to ptlrpc 02/54502/6
authorSebastien Buisson <sbuisson@ddn.com>
Tue, 19 Mar 2024 16:04:20 +0000 (17:04 +0100)
committerOleg Drokin <green@whamcloud.com>
Mon, 15 Apr 2024 16:53:28 +0000 (16:53 +0000)
Move to ptlrpc the functions designed to handle nodemap specific
ioctls, as they should not be accessible to MGS only.

Test-Parameters: trivial
Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I7a9651ea8484c540d18d6813ab96dc95a0871245
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54502
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_nodemap.h
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_internal.h
lustre/mgs/mgs_llog.c
lustre/ptlrpc/nodemap_handler.c

index ccdc8ab..e421c3b 100644 (file)
@@ -31,6 +31,7 @@
 #define _LUSTRE_NODEMAP_H
 
 #include <uapi/linux/lustre/lustre_disk.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
 
 #define LUSTRE_NODEMAP_NAME "nodemap"
 
@@ -170,6 +171,10 @@ void nodemap_test_nid(struct lnet_nid *nid, char *name_buf, size_t name_len);
 int nodemap_test_id(struct lnet_nid *nid, enum nodemap_id_type idtype,
                    u32 client_id, u32 *fs_id);
 
+int server_iocontrol_nodemap(struct obd_device *obd,
+                            struct obd_ioctl_data *data, bool dynamic);
+
+
 struct nm_config_file *nm_config_file_register_mgs(const struct lu_env *env,
                                                   struct dt_object *obj,
                                                   struct local_oid_storage *l);
index 0e15af1..3d2d4cb 100644 (file)
@@ -763,21 +763,8 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                                 struct mgs_device *mgs,
                                 struct obd_ioctl_data *data)
 {
-       struct lustre_cfg       *lcfg = NULL;
-       struct fs_db            *fsdb;
-       struct lnet_nid nid;
-       const char              *nodemap_name = NULL;
-       const char              *nidstr = NULL;
-       const char              *client_idstr = NULL;
-       const char              *idtype_str = NULL;
-       char                    *param = NULL;
-       char                    fs_idstr[16];
-       char                    name_buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
-       int                     rc = 0;
-       unsigned long           client_id;
-       __u32                   fs_id;
-       __u32                   cmd;
-       int                     idtype;
+       struct fs_db *fsdb;
+       int rc;
 
        ENTRY;
 
@@ -787,130 +774,9 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                GOTO(out, rc = -EINVAL);
        }
 
-       if (data->ioc_plen1 > PAGE_SIZE)
-               GOTO(out, rc = -E2BIG);
-
-       OBD_ALLOC(lcfg, data->ioc_plen1);
-       if (lcfg == NULL)
-               GOTO(out, rc = -ENOMEM);
-
-       if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
-               GOTO(out_lcfg, rc = -EFAULT);
-
-       cmd = lcfg->lcfg_command;
-
-       switch (cmd) {
-       case LCFG_NODEMAP_ACTIVATE:
-               if (lcfg->lcfg_bufcount != 2)
-                       GOTO(out_lcfg, rc = -EINVAL);
-               param = lustre_cfg_string(lcfg, 1);
-               if (strcmp(param, "1") == 0)
-                       nodemap_activate(1);
-               else
-                       nodemap_activate(0);
-               break;
-       case LCFG_NODEMAP_ADD:
-       case LCFG_NODEMAP_DEL:
-               if (lcfg->lcfg_bufcount != 2)
-                       GOTO(out_lcfg, rc = -EINVAL);
-               nodemap_name = lustre_cfg_string(lcfg, 1);
-               rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param);
-               break;
-       case LCFG_NODEMAP_TEST_NID:
-               if (lcfg->lcfg_bufcount != 2)
-                       GOTO(out_lcfg, rc = -EINVAL);
-               nidstr = lustre_cfg_string(lcfg, 1);
-               rc = libcfs_strnid(&nid, nidstr);
-               if (rc < 0)
-                       GOTO(out_lcfg, rc);
-
-               nodemap_test_nid(&nid, name_buf, sizeof(name_buf));
-               rc = copy_to_user(data->ioc_pbuf1, name_buf,
-                                 min_t(size_t, data->ioc_plen1,
-                                       sizeof(name_buf)));
-               if (rc != 0)
-                       GOTO(out_lcfg, rc = -EFAULT);
-               break;
-       case LCFG_NODEMAP_TEST_ID:
-               if (lcfg->lcfg_bufcount != 4)
-                       GOTO(out_lcfg, rc = -EINVAL);
-               nidstr = lustre_cfg_string(lcfg, 1);
-               idtype_str = lustre_cfg_string(lcfg, 2);
-               client_idstr = lustre_cfg_string(lcfg, 3);
-
-               rc = libcfs_strnid(&nid, nidstr);
-               if (rc < 0)
-                       GOTO(out_lcfg, rc);
-
-               if (strcmp(idtype_str, "uid") == 0)
-                       idtype = NODEMAP_UID;
-               else if (strcmp(idtype_str, "gid") == 0)
-                       idtype = NODEMAP_GID;
-               else if (strcmp(idtype_str, "projid") == 0)
-                       idtype = NODEMAP_PROJID;
-               else
-                       GOTO(out_lcfg, rc = -EINVAL);
-
-               rc = kstrtoul(client_idstr, 10, &client_id);
-               if (rc != 0)
-                       GOTO(out_lcfg, rc = -EINVAL);
-
-               rc = nodemap_test_id(&nid, idtype, client_id, &fs_id);
-               if (rc < 0)
-                       GOTO(out_lcfg, rc = -EINVAL);
-
-               if (data->ioc_plen1 < sizeof(fs_idstr))
-                       GOTO(out_lcfg, rc = -EINVAL);
-
-               snprintf(fs_idstr, sizeof(fs_idstr), "%u", fs_id);
-               if (copy_to_user(data->ioc_pbuf1, fs_idstr,
-                                sizeof(fs_idstr)) != 0)
-                       GOTO(out_lcfg, rc = -EINVAL);
-               break;
-       case LCFG_NODEMAP_ADD_RANGE:
-       case LCFG_NODEMAP_DEL_RANGE:
-       case LCFG_NODEMAP_ADD_UIDMAP:
-       case LCFG_NODEMAP_DEL_UIDMAP:
-       case LCFG_NODEMAP_ADD_GIDMAP:
-       case LCFG_NODEMAP_DEL_GIDMAP:
-       case LCFG_NODEMAP_ADD_PROJIDMAP:
-       case LCFG_NODEMAP_DEL_PROJIDMAP:
-       case LCFG_NODEMAP_SET_FILESET:
-       case LCFG_NODEMAP_SET_SEPOL:
-               if (lcfg->lcfg_bufcount != 3)
-                       GOTO(out_lcfg, rc = -EINVAL);
-               nodemap_name = lustre_cfg_string(lcfg, 1);
-               param = lustre_cfg_string(lcfg, 2);
-               rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param);
-               break;
-       case LCFG_NODEMAP_ADMIN:
-       case LCFG_NODEMAP_TRUSTED:
-       case LCFG_NODEMAP_DENY_UNKNOWN:
-       case LCFG_NODEMAP_SQUASH_UID:
-       case LCFG_NODEMAP_SQUASH_GID:
-       case LCFG_NODEMAP_SQUASH_PROJID:
-       case LCFG_NODEMAP_MAP_MODE:
-       case LCFG_NODEMAP_AUDIT_MODE:
-       case LCFG_NODEMAP_FORBID_ENCRYPT:
-       case LCFG_NODEMAP_READONLY_MOUNT:
-       case LCFG_NODEMAP_RBAC:
-               if (lcfg->lcfg_bufcount != 4)
-                       GOTO(out_lcfg, rc = -EINVAL);
-               nodemap_name = lustre_cfg_string(lcfg, 1);
-               param = lustre_cfg_string(lcfg, 3);
-               rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param);
-               break;
-       default:
-               rc = -ENOTTY;
-       }
-
-       if (rc) {
-               CDEBUG_LIMIT(rc == -EEXIST ? D_INFO : D_ERROR,
-                            "%s: OBD_IOC_NODEMAP command %X for %s: rc = %d\n",
-                            mgs->mgs_obd->obd_name, lcfg->lcfg_command,
-                            nodemap_name, rc);
-               GOTO(out_lcfg, rc);
-       }
+       rc = server_iocontrol_nodemap(mgs->mgs_obd, data, false);
+       if (rc)
+               GOTO(out, rc);
 
        /* revoke nodemap lock */
        rc = mgs_find_or_make_fsdb(env, mgs, LUSTRE_NODEMAP_NAME, &fsdb);
@@ -922,8 +788,6 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                mgs_put_fsdb(mgs, fsdb);
        }
 
-out_lcfg:
-       OBD_FREE(lcfg, data->ioc_plen1);
 out:
        RETURN(rc);
 }
index 4b36cac..2d109c5 100644 (file)
@@ -227,9 +227,6 @@ int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
                 enum lcfg_command_type cmd, char *poolname, char *fsname,
                 char *ostname);
-int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
-                   enum lcfg_command_type cmd, const char *nodemap_name,
-                   char *param);
 
 /* mgs_handler.c */
 int  mgs_get_lock(struct obd_device *obd, struct ldlm_res_id *res,
index 20887d4..ea349b4 100644 (file)
@@ -5648,219 +5648,6 @@ out:
        return rc;
 }
 
-int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
-                   enum lcfg_command_type cmd, const char *nodemap_name,
-                   char *param)
-{
-       struct lnet_nid nid[2];
-       u32 idmap[2];
-       bool bool_switch;
-       u8 netmask = 0;
-       u32 int_id;
-       int rc = 0;
-
-       ENTRY;
-       switch (cmd) {
-       case LCFG_NODEMAP_ADD:
-               rc = nodemap_add(nodemap_name);
-               break;
-       case LCFG_NODEMAP_DEL:
-               rc = nodemap_del(nodemap_name);
-               break;
-       case LCFG_NODEMAP_ADD_RANGE:
-               rc = nodemap_parse_range(param, nid, &netmask);
-               if (rc != 0)
-                       break;
-               rc = nodemap_add_range(nodemap_name, nid, netmask);
-               break;
-       case LCFG_NODEMAP_DEL_RANGE:
-               rc = nodemap_parse_range(param, nid, &netmask);
-               if (rc != 0)
-                       break;
-               rc = nodemap_del_range(nodemap_name, nid, netmask);
-               break;
-       case LCFG_NODEMAP_ADMIN:
-               rc = kstrtobool(param, &bool_switch);
-               if (rc)
-                       break;
-               rc = nodemap_set_allow_root(nodemap_name, bool_switch);
-               break;
-       case LCFG_NODEMAP_DENY_UNKNOWN:
-               rc = kstrtobool(param, &bool_switch);
-               if (rc)
-                       break;
-               rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
-               break;
-       case LCFG_NODEMAP_AUDIT_MODE:
-               rc = kstrtobool(param, &bool_switch);
-               if (rc == 0)
-                       rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
-               break;
-       case LCFG_NODEMAP_FORBID_ENCRYPT:
-               rc = kstrtobool(param, &bool_switch);
-               if (rc == 0)
-                       rc = nodemap_set_forbid_encryption(nodemap_name,
-                                                          bool_switch);
-               break;
-       case LCFG_NODEMAP_READONLY_MOUNT:
-               rc = kstrtobool(param, &bool_switch);
-               if (rc == 0)
-                       rc = nodemap_set_readonly_mount(nodemap_name,
-                                                       bool_switch);
-               break;
-       case LCFG_NODEMAP_MAP_MODE:
-       {
-               char *p;
-               __u8 map_mode = 0;
-
-               if ((p = strstr(param, "all")) != NULL) {
-                       if ((p == param || *(p-1) == ',') &&
-                           (*(p+3) == '\0' || *(p+3) == ',')) {
-                               map_mode = NODEMAP_MAP_ALL;
-                       } else {
-                               rc = -EINVAL;
-                               break;
-                       }
-               } else {
-                       while ((p = strsep(&param, ",")) != NULL) {
-                               if (!*p)
-                                       break;
-
-                               if (strcmp("both", p) == 0)
-                                       map_mode |= NODEMAP_MAP_BOTH;
-                               else if (strcmp("uid_only", p) == 0 ||
-                                        strcmp("uid", p) == 0)
-                                       map_mode |= NODEMAP_MAP_UID;
-                               else if (strcmp("gid_only", p) == 0 ||
-                                        strcmp("gid", p) == 0)
-                                       map_mode |= NODEMAP_MAP_GID;
-                               else if (strcmp("projid_only", p) == 0 ||
-                                        strcmp("projid", p) == 0)
-                                       map_mode |= NODEMAP_MAP_PROJID;
-                               else
-                                       break;
-                       }
-                       if (p) {
-                               rc = -EINVAL;
-                               break;
-                       }
-               }
-
-               rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
-               break;
-       }
-       case LCFG_NODEMAP_RBAC:
-       {
-               enum nodemap_rbac_roles rbac;
-               char *p;
-
-               if (strcmp(param, "all") == 0) {
-                       rbac = NODEMAP_RBAC_ALL;
-               } else if (strcmp(param, "none") == 0) {
-                       rbac = NODEMAP_RBAC_NONE;
-               } else {
-                       rbac = NODEMAP_RBAC_NONE;
-                       while ((p = strsep(&param, ",")) != NULL) {
-                               int i;
-
-                               if (!*p)
-                                       break;
-
-                               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
-                                    i++) {
-                                       if (strcmp(p,
-                                                nodemap_rbac_names[i].nrn_name)
-                                           == 0) {
-                                               rbac |=
-                                                nodemap_rbac_names[i].nrn_mode;
-                                               break;
-                                       }
-                               }
-                               if (i == ARRAY_SIZE(nodemap_rbac_names))
-                                       break;
-                       }
-                       if (p) {
-                               rc = -EINVAL;
-                               break;
-                       }
-               }
-
-               rc = nodemap_set_rbac(nodemap_name, rbac);
-               break;
-       }
-       case LCFG_NODEMAP_TRUSTED:
-               rc = kstrtobool(param, &bool_switch);
-               if (rc)
-                       break;
-               rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
-               break;
-       case LCFG_NODEMAP_SQUASH_UID:
-               rc = kstrtouint(param, 10, &int_id);
-               if (rc)
-                       break;
-               rc = nodemap_set_squash_uid(nodemap_name, int_id);
-               break;
-       case LCFG_NODEMAP_SQUASH_GID:
-               rc = kstrtouint(param, 10, &int_id);
-               if (rc)
-                       break;
-               rc = nodemap_set_squash_gid(nodemap_name, int_id);
-               break;
-       case LCFG_NODEMAP_SQUASH_PROJID:
-               rc = kstrtouint(param, 10, &int_id);
-               if (rc)
-                       break;
-               rc = nodemap_set_squash_projid(nodemap_name, int_id);
-               break;
-       case LCFG_NODEMAP_ADD_UIDMAP:
-       case LCFG_NODEMAP_ADD_GIDMAP:
-       case LCFG_NODEMAP_ADD_PROJIDMAP:
-               rc = nodemap_parse_idmap(param, idmap);
-               if (rc != 0)
-                       break;
-               if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
-                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
-                                              idmap);
-               else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
-                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
-                                              idmap);
-               else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
-                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
-                                              idmap);
-               else
-                       rc = -EINVAL;
-               break;
-       case LCFG_NODEMAP_DEL_UIDMAP:
-       case LCFG_NODEMAP_DEL_GIDMAP:
-       case LCFG_NODEMAP_DEL_PROJIDMAP:
-               rc = nodemap_parse_idmap(param, idmap);
-               if (rc != 0)
-                       break;
-               if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
-                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
-                                              idmap);
-               else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
-                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
-                                              idmap);
-               else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
-                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
-                                              idmap);
-               else
-                       rc = -EINVAL;
-               break;
-       case LCFG_NODEMAP_SET_FILESET:
-               rc = nodemap_set_fileset(nodemap_name, param);
-               break;
-       case LCFG_NODEMAP_SET_SEPOL:
-               rc = nodemap_set_sepol(nodemap_name, param);
-               break;
-       default:
-               rc = -EINVAL;
-       }
-
-       RETURN(rc);
-}
-
 static inline
 int mgs_pool_check_ostname(struct fs_db *fsdb, char *fsname, char *ostname)
 {
index a6da068..f2cf2de 100644 (file)
@@ -2015,3 +2015,366 @@ int nodemap_test_id(struct lnet_nid *nid, enum nodemap_id_type idtype,
        return 0;
 }
 EXPORT_SYMBOL(nodemap_test_id);
+
+static int cfg_nodemap_cmd(enum lcfg_command_type cmd, const char *nodemap_name,
+                          char *param, bool dynamic)
+{
+       struct lnet_nid nid[2];
+       bool bool_switch;
+       u8 netmask = 0;
+       u32 idmap[2];
+       u32 int_id;
+       int rc = 0;
+
+       ENTRY;
+       switch (cmd) {
+       case LCFG_NODEMAP_ADD:
+               rc = nodemap_add(nodemap_name);
+               break;
+       case LCFG_NODEMAP_DEL:
+               rc = nodemap_del(nodemap_name);
+               break;
+       case LCFG_NODEMAP_ADD_RANGE:
+               rc = nodemap_parse_range(param, nid, &netmask);
+               if (rc != 0)
+                       break;
+               rc = nodemap_add_range(nodemap_name, nid, netmask);
+               break;
+       case LCFG_NODEMAP_DEL_RANGE:
+               rc = nodemap_parse_range(param, nid, &netmask);
+               if (rc != 0)
+                       break;
+               rc = nodemap_del_range(nodemap_name, nid, netmask);
+               break;
+       case LCFG_NODEMAP_ADMIN:
+               rc = kstrtobool(param, &bool_switch);
+               if (rc)
+                       break;
+               rc = nodemap_set_allow_root(nodemap_name, bool_switch);
+               break;
+       case LCFG_NODEMAP_DENY_UNKNOWN:
+               rc = kstrtobool(param, &bool_switch);
+               if (rc)
+                       break;
+               rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
+               break;
+       case LCFG_NODEMAP_AUDIT_MODE:
+               rc = kstrtobool(param, &bool_switch);
+               if (rc == 0)
+                       rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
+               break;
+       case LCFG_NODEMAP_FORBID_ENCRYPT:
+               rc = kstrtobool(param, &bool_switch);
+               if (rc == 0)
+                       rc = nodemap_set_forbid_encryption(nodemap_name,
+                                                          bool_switch);
+               break;
+       case LCFG_NODEMAP_READONLY_MOUNT:
+               rc = kstrtobool(param, &bool_switch);
+               if (rc == 0)
+                       rc = nodemap_set_readonly_mount(nodemap_name,
+                                                       bool_switch);
+               break;
+       case LCFG_NODEMAP_MAP_MODE:
+       {
+               char *p;
+               __u8 map_mode = 0;
+
+               if ((p = strstr(param, "all")) != NULL) {
+                       if ((p == param || *(p-1) == ',') &&
+                           (*(p+3) == '\0' || *(p+3) == ',')) {
+                               map_mode = NODEMAP_MAP_ALL;
+                       } else {
+                               rc = -EINVAL;
+                               break;
+                       }
+               } else {
+                       while ((p = strsep(&param, ",")) != NULL) {
+                               if (!*p)
+                                       break;
+
+                               if (strcmp("both", p) == 0)
+                                       map_mode |= NODEMAP_MAP_BOTH;
+                               else if (strcmp("uid_only", p) == 0 ||
+                                        strcmp("uid", p) == 0)
+                                       map_mode |= NODEMAP_MAP_UID;
+                               else if (strcmp("gid_only", p) == 0 ||
+                                        strcmp("gid", p) == 0)
+                                       map_mode |= NODEMAP_MAP_GID;
+                               else if (strcmp("projid_only", p) == 0 ||
+                                        strcmp("projid", p) == 0)
+                                       map_mode |= NODEMAP_MAP_PROJID;
+                               else
+                                       break;
+                       }
+                       if (p) {
+                               rc = -EINVAL;
+                               break;
+                       }
+               }
+
+               rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
+               break;
+       }
+       case LCFG_NODEMAP_RBAC:
+       {
+               enum nodemap_rbac_roles rbac;
+               char *p;
+
+               if (strcmp(param, "all") == 0) {
+                       rbac = NODEMAP_RBAC_ALL;
+               } else if (strcmp(param, "none") == 0) {
+                       rbac = NODEMAP_RBAC_NONE;
+               } else {
+                       rbac = NODEMAP_RBAC_NONE;
+                       while ((p = strsep(&param, ",")) != NULL) {
+                               int i;
+
+                               if (!*p)
+                                       break;
+
+                               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
+                                    i++) {
+                                       if (strcmp(p,
+                                                nodemap_rbac_names[i].nrn_name)
+                                           == 0) {
+                                               rbac |=
+                                                nodemap_rbac_names[i].nrn_mode;
+                                               break;
+                                       }
+                               }
+                               if (i == ARRAY_SIZE(nodemap_rbac_names))
+                                       break;
+                       }
+                       if (p) {
+                               rc = -EINVAL;
+                               break;
+                       }
+               }
+
+               rc = nodemap_set_rbac(nodemap_name, rbac);
+               break;
+       }
+       case LCFG_NODEMAP_TRUSTED:
+               rc = kstrtobool(param, &bool_switch);
+               if (rc)
+                       break;
+               rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
+               break;
+       case LCFG_NODEMAP_SQUASH_UID:
+               rc = kstrtouint(param, 10, &int_id);
+               if (rc)
+                       break;
+               rc = nodemap_set_squash_uid(nodemap_name, int_id);
+               break;
+       case LCFG_NODEMAP_SQUASH_GID:
+               rc = kstrtouint(param, 10, &int_id);
+               if (rc)
+                       break;
+               rc = nodemap_set_squash_gid(nodemap_name, int_id);
+               break;
+       case LCFG_NODEMAP_SQUASH_PROJID:
+               rc = kstrtouint(param, 10, &int_id);
+               if (rc)
+                       break;
+               rc = nodemap_set_squash_projid(nodemap_name, int_id);
+               break;
+       case LCFG_NODEMAP_ADD_UIDMAP:
+       case LCFG_NODEMAP_ADD_GIDMAP:
+       case LCFG_NODEMAP_ADD_PROJIDMAP:
+               rc = nodemap_parse_idmap(param, idmap);
+               if (rc != 0)
+                       break;
+               if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
+                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
+                                              idmap);
+               else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
+                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
+                                              idmap);
+               else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
+                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
+                                              idmap);
+               else
+                       rc = -EINVAL;
+               break;
+       case LCFG_NODEMAP_DEL_UIDMAP:
+       case LCFG_NODEMAP_DEL_GIDMAP:
+       case LCFG_NODEMAP_DEL_PROJIDMAP:
+               rc = nodemap_parse_idmap(param, idmap);
+               if (rc != 0)
+                       break;
+               if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
+                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
+                                              idmap);
+               else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
+                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
+                                              idmap);
+               else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
+                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
+                                              idmap);
+               else
+                       rc = -EINVAL;
+               break;
+       case LCFG_NODEMAP_SET_FILESET:
+               rc = nodemap_set_fileset(nodemap_name, param);
+               break;
+       case LCFG_NODEMAP_SET_SEPOL:
+               rc = nodemap_set_sepol(nodemap_name, param);
+               break;
+       default:
+               rc = -EINVAL;
+       }
+
+       RETURN(rc);
+}
+
+int server_iocontrol_nodemap(struct obd_device *obd,
+                            struct obd_ioctl_data *data, bool dynamic)
+{
+       char name_buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+       struct lustre_cfg *lcfg = NULL;
+       const char *nodemap_name = NULL;
+       const char *client_idstr = NULL;
+       const char *idtype_str = NULL;
+       const char *nidstr = NULL;
+       unsigned long client_id;
+       struct lnet_nid nid;
+       char *param = NULL;
+       char fs_idstr[16];
+       __u32 fs_id, cmd;
+       int idtype;
+       int rc = 0;
+
+       ENTRY;
+
+       if (data->ioc_plen1 > PAGE_SIZE)
+               GOTO(out, rc = -E2BIG);
+
+       OBD_ALLOC(lcfg, data->ioc_plen1);
+       if (lcfg == NULL)
+               GOTO(out, rc = -ENOMEM);
+
+       if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
+               GOTO(out_lcfg, rc = -EFAULT);
+
+       cmd = lcfg->lcfg_command;
+
+       switch (cmd) {
+       case LCFG_NODEMAP_ACTIVATE:
+               if (lcfg->lcfg_bufcount != 2)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               param = lustre_cfg_string(lcfg, 1);
+               if (strcmp(param, "1") == 0)
+                       nodemap_activate(1);
+               else
+                       nodemap_activate(0);
+               break;
+       case LCFG_NODEMAP_ADD:
+       case LCFG_NODEMAP_DEL:
+               if (lcfg->lcfg_bufcount != 2)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nodemap_name = lustre_cfg_string(lcfg, 1);
+               rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
+               break;
+       case LCFG_NODEMAP_TEST_NID:
+               if (lcfg->lcfg_bufcount != 2)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nidstr = lustre_cfg_string(lcfg, 1);
+               rc = libcfs_strnid(&nid, nidstr);
+               if (rc < 0)
+                       GOTO(out_lcfg, rc);
+
+               nodemap_test_nid(&nid, name_buf, sizeof(name_buf));
+               rc = copy_to_user(data->ioc_pbuf1, name_buf,
+                                 min_t(size_t, data->ioc_plen1,
+                                       sizeof(name_buf)));
+               if (rc != 0)
+                       GOTO(out_lcfg, rc = -EFAULT);
+               break;
+       case LCFG_NODEMAP_TEST_ID:
+               if (lcfg->lcfg_bufcount != 4)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nidstr = lustre_cfg_string(lcfg, 1);
+               idtype_str = lustre_cfg_string(lcfg, 2);
+               client_idstr = lustre_cfg_string(lcfg, 3);
+
+               rc = libcfs_strnid(&nid, nidstr);
+               if (rc < 0)
+                       GOTO(out_lcfg, rc);
+
+               if (strcmp(idtype_str, "uid") == 0)
+                       idtype = NODEMAP_UID;
+               else if (strcmp(idtype_str, "gid") == 0)
+                       idtype = NODEMAP_GID;
+               else if (strcmp(idtype_str, "projid") == 0)
+                       idtype = NODEMAP_PROJID;
+               else
+                       GOTO(out_lcfg, rc = -EINVAL);
+
+               rc = kstrtoul(client_idstr, 10, &client_id);
+               if (rc != 0)
+                       GOTO(out_lcfg, rc = -EINVAL);
+
+               rc = nodemap_test_id(&nid, idtype, client_id, &fs_id);
+               if (rc < 0)
+                       GOTO(out_lcfg, rc = -EINVAL);
+
+               if (data->ioc_plen1 < sizeof(fs_idstr))
+                       GOTO(out_lcfg, rc = -EINVAL);
+
+               snprintf(fs_idstr, sizeof(fs_idstr), "%u", fs_id);
+               if (copy_to_user(data->ioc_pbuf1, fs_idstr,
+                                sizeof(fs_idstr)) != 0)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               break;
+       case LCFG_NODEMAP_ADD_RANGE:
+       case LCFG_NODEMAP_DEL_RANGE:
+       case LCFG_NODEMAP_ADD_UIDMAP:
+       case LCFG_NODEMAP_DEL_UIDMAP:
+       case LCFG_NODEMAP_ADD_GIDMAP:
+       case LCFG_NODEMAP_DEL_GIDMAP:
+       case LCFG_NODEMAP_ADD_PROJIDMAP:
+       case LCFG_NODEMAP_DEL_PROJIDMAP:
+       case LCFG_NODEMAP_SET_FILESET:
+       case LCFG_NODEMAP_SET_SEPOL:
+               if (lcfg->lcfg_bufcount != 3)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nodemap_name = lustre_cfg_string(lcfg, 1);
+               param = lustre_cfg_string(lcfg, 2);
+               rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
+               break;
+       case LCFG_NODEMAP_ADMIN:
+       case LCFG_NODEMAP_TRUSTED:
+       case LCFG_NODEMAP_DENY_UNKNOWN:
+       case LCFG_NODEMAP_SQUASH_UID:
+       case LCFG_NODEMAP_SQUASH_GID:
+       case LCFG_NODEMAP_SQUASH_PROJID:
+       case LCFG_NODEMAP_MAP_MODE:
+       case LCFG_NODEMAP_AUDIT_MODE:
+       case LCFG_NODEMAP_FORBID_ENCRYPT:
+       case LCFG_NODEMAP_READONLY_MOUNT:
+       case LCFG_NODEMAP_RBAC:
+               if (lcfg->lcfg_bufcount != 4)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nodemap_name = lustre_cfg_string(lcfg, 1);
+               param = lustre_cfg_string(lcfg, 3);
+               rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
+               break;
+       default:
+               rc = -ENOTTY;
+       }
+
+       if (rc) {
+               CDEBUG_LIMIT(rc == -EEXIST ? D_INFO : D_ERROR,
+                            "%s: OBD_IOC_NODEMAP command %X for %s: rc = %d\n",
+                            obd->obd_name, lcfg->lcfg_command,
+                            nodemap_name, rc);
+               GOTO(out_lcfg, rc);
+       }
+
+out_lcfg:
+       OBD_FREE(lcfg, data->ioc_plen1);
+out:
+       RETURN(rc);
+}
+EXPORT_SYMBOL(server_iocontrol_nodemap);