+ * set fileset on nodemap
+ * \param name nodemap to set fileset on
+ * \param fileset string containing fileset
+ * \retval 0 on success
+ *
+ * set a fileset on the named nodemap
+ */
+static int nodemap_set_fileset_helper(struct nodemap_config *config,
+ struct lu_nodemap *nodemap,
+ const char *fileset)
+{
+ int rc = 0;
+
+ /* Allow 'fileset=clear' in addition to 'fileset=""' to clear fileset
+ * because either command 'lctl set_param -P *.*.fileset=""' or
+ * 'lctl nodemap_set_fileset --fileset ""' can only work correctly
+ * on MGS, while on other servers, both commands will invoke upcall
+ * "/usr/sbin/lctl set_param nodemap.default.fileset=" by function
+ * process_param2_config(), which will cause "no value" error and
+ * won't clear fileset.
+ * 'fileset=""' is still kept for compatibility reason.
+ */
+ if (fileset == NULL)
+ rc = -EINVAL;
+ else if (fileset[0] == '\0' || strcmp(fileset, "clear") == 0)
+ nodemap->nm_fileset[0] = '\0';
+ else if (fileset[0] != '/')
+ rc = -EINVAL;
+ else if (strlcpy(nodemap->nm_fileset, fileset,
+ sizeof(nodemap->nm_fileset)) >=
+ sizeof(nodemap->nm_fileset))
+ rc = -ENAMETOOLONG;
+
+ return rc;
+}
+
+int nodemap_set_fileset(const char *name, const char *fileset)
+{
+ struct lu_nodemap *nodemap = NULL;
+ int rc = 0;
+
+ mutex_lock(&active_config_lock);
+ nodemap = nodemap_lookup(name);
+ if (IS_ERR(nodemap)) {
+ mutex_unlock(&active_config_lock);
+ GOTO(out, rc = PTR_ERR(nodemap));
+ }
+
+ rc = nodemap_set_fileset_helper(active_config, nodemap, fileset);
+ mutex_unlock(&active_config_lock);
+
+ nodemap_putref(nodemap);
+out:
+ return rc;
+}
+EXPORT_SYMBOL(nodemap_set_fileset);
+
+/**
+ * get fileset defined on nodemap
+ * \param nodemap nodemap to get fileset from
+ * \retval fileset name, or NULL if not defined or not activated
+ *
+ * get the fileset defined on the nodemap
+ */
+char *nodemap_get_fileset(const struct lu_nodemap *nodemap)
+{
+ if (!nodemap_active)
+ return NULL;
+
+ return (char *)nodemap->nm_fileset;
+}
+EXPORT_SYMBOL(nodemap_get_fileset);
+
+static int nodemap_validate_sepol(const char *sepol)
+{
+ char buf[LUSTRE_NODEMAP_SEPOL_LENGTH + 1];
+ char *p = (char *)sepol;
+ char *q = buf;
+ char polname[NAME_MAX + 1] = "";
+ char hash[SELINUX_POLICY_HASH_LEN + 1] = "";
+ unsigned char mode;
+ unsigned short ver;
+
+ BUILD_BUG_ON(sizeof(buf) != sizeof(((struct lu_nodemap *)0)->nm_sepol));
+
+ if (sepol == NULL)
+ return -EINVAL;
+
+ /* we allow sepol = "" which means clear SELinux policy info */
+ if (sepol[0] == '\0')
+ return 0;
+
+ /* make a copy of sepol, by replacing ':' with space
+ * so that we can use sscanf over the string
+ */
+ while (p-sepol < sizeof(buf)) {
+ if (*p == ':')
+ *q = ' ';
+ else
+ *q = *p;
+ if (*p == '\0')
+ break;
+ p++;
+ q++;
+ }
+ if (p-sepol == sizeof(buf))
+ return -ENAMETOOLONG;
+
+ if (sscanf(buf, "%1hhu %s %hu %s", &mode, polname, &ver, hash) != 4)
+ return -EINVAL;
+
+ if (mode != 0 && mode != 1)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * set SELinux policy on nodemap
+ * \param name nodemap to set SELinux policy info on
+ * \param sepol string containing SELinux policy info
+ * \retval 0 on success
+ *
+ * set SELinux policy info on the named nodemap
+ */
+int nodemap_set_sepol(const char *name, const char *sepol)
+{
+ struct lu_nodemap *nodemap = NULL;
+ int rc;
+
+ rc = nodemap_validate_sepol(sepol);
+ if (rc < 0)
+ GOTO(out, rc);
+
+ mutex_lock(&active_config_lock);
+ nodemap = nodemap_lookup(name);
+ if (IS_ERR(nodemap)) {
+ mutex_unlock(&active_config_lock);
+ GOTO(out, rc = PTR_ERR(nodemap));
+ }
+
+ if (is_default_nodemap(nodemap)) {
+ /* We do not want nodes in the default nodemap to have
+ * SELinux restrictions. Sec admin should create dedicated
+ * nodemap entries for this.
+ */
+ GOTO(out_putref, rc = -EINVAL);
+ }
+
+ /* truncation cannot happen, as string length was checked in
+ * nodemap_validate_sepol()
+ */
+ strlcpy(nodemap->nm_sepol, sepol, sizeof(nodemap->nm_sepol));
+
+out_putref:
+ mutex_unlock(&active_config_lock);
+ nodemap_putref(nodemap);
+out:
+ return rc;
+}
+EXPORT_SYMBOL(nodemap_set_sepol);
+
+/**
+ * get SELinux policy info defined on nodemap
+ * \param nodemap nodemap to get SELinux policy info from
+ * \retval SELinux policy info, or NULL if not defined or not activated
+ *
+ * get the SELinux policy info defined on the nodemap
+ */
+const char *nodemap_get_sepol(const struct lu_nodemap *nodemap)
+{
+ if (is_default_nodemap(nodemap))
+ return NULL;
+ else
+ return (char *)nodemap->nm_sepol;
+}
+EXPORT_SYMBOL(nodemap_get_sepol);
+
+/**