From 72734cf178f1c4cd9dfe16a8f5800a0f1ab14e52 Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Tue, 19 Mar 2024 17:04:20 +0100 Subject: [PATCH] LU-17431 ptlrpc: move nodemap related ioctls to ptlrpc 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 Change-Id: I7a9651ea8484c540d18d6813ab96dc95a0871245 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54502 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/include/lustre_nodemap.h | 5 + lustre/mgs/mgs_handler.c | 146 +--------------- lustre/mgs/mgs_internal.h | 3 - lustre/mgs/mgs_llog.c | 213 ----------------------- lustre/ptlrpc/nodemap_handler.c | 363 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 373 insertions(+), 357 deletions(-) diff --git a/lustre/include/lustre_nodemap.h b/lustre/include/lustre_nodemap.h index ccdc8ab..e421c3b 100644 --- a/lustre/include/lustre_nodemap.h +++ b/lustre/include/lustre_nodemap.h @@ -31,6 +31,7 @@ #define _LUSTRE_NODEMAP_H #include +#include #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); diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 0e15af1..3d2d4cb 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -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); } diff --git a/lustre/mgs/mgs_internal.h b/lustre/mgs/mgs_internal.h index 4b36cac..2d109c5 100644 --- a/lustre/mgs/mgs_internal.h +++ b/lustre/mgs/mgs_internal.h @@ -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, diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 20887d4..ea349b4 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -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(¶m, ",")) != 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(¶m, ",")) != 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) { diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index a6da068..f2cf2de 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -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(¶m, ",")) != 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(¶m, ",")) != 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); -- 1.8.3.1