+ struct ptlrpc_svc_ctx *ctx)
+{
+ struct ptlrpc_sec_policy *policy = ctx->sc_policy;
+
+ if (!policy->sp_sops->install_rctx)
+ return 0;
+ return policy->sp_sops->install_rctx(imp, ctx);
+}
+
+/* Get SELinux policy info from userspace */
+static int sepol_helper(struct obd_import *imp)
+{
+ char mtime_str[21] = { 0 }, mode_str[2] = { 0 };
+ char *argv[] = {
+ [0] = "/usr/sbin/l_getsepol",
+ [1] = "-o",
+ [2] = NULL, /* obd type */
+ [3] = "-n",
+ [4] = NULL, /* obd name */
+ [5] = "-t",
+ [6] = mtime_str, /* policy mtime */
+ [7] = "-m",
+ [8] = mode_str, /* enforcing mode */
+ [9] = NULL
+ };
+ char *envp[] = {
+ [0] = "HOME=/",
+ [1] = "PATH=/sbin:/usr/sbin",
+ [2] = NULL
+ };
+ signed short ret;
+ int rc = 0;
+
+ if (imp == NULL || imp->imp_obd == NULL ||
+ imp->imp_obd->obd_type == NULL) {
+ rc = -EINVAL;
+ } else {
+ argv[2] = (char *)imp->imp_obd->obd_type->typ_name;
+ argv[4] = imp->imp_obd->obd_name;
+ spin_lock(&imp->imp_sec->ps_lock);
+ if (imp->imp_sec->ps_sepol_mtime == 0 &&
+ imp->imp_sec->ps_sepol[0] == '\0') {
+ /* ps_sepol has not been initialized */
+ argv[5] = NULL;
+ argv[7] = NULL;
+ } else {
+ snprintf(mtime_str, sizeof(mtime_str), "%lu",
+ imp->imp_sec->ps_sepol_mtime);
+ mode_str[0] = imp->imp_sec->ps_sepol[0];
+ }
+ spin_unlock(&imp->imp_sec->ps_lock);
+ ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+ rc = ret>>8;
+ }
+
+ return rc;
+}
+
+static inline int sptlrpc_sepol_needs_check(struct ptlrpc_sec *imp_sec)
+{
+ ktime_t checknext;
+
+ if (send_sepol == 0 || !selinux_is_enabled())
+ return 0;
+
+ if (send_sepol == -1)
+ /* send_sepol == -1 means fetch sepol status every time */
+ return 1;
+
+ spin_lock(&imp_sec->ps_lock);
+ checknext = imp_sec->ps_sepol_checknext;
+ spin_unlock(&imp_sec->ps_lock);
+
+ /* next check is too far in time, please update */
+ if (ktime_after(checknext,
+ ktime_add(ktime_get(), ktime_set(send_sepol, 0))))
+ goto setnext;
+
+ if (ktime_before(ktime_get(), checknext))
+ /* too early to fetch sepol status */
+ return 0;
+
+setnext:
+ /* define new sepol_checknext time */
+ spin_lock(&imp_sec->ps_lock);
+ imp_sec->ps_sepol_checknext = ktime_add(ktime_get(),
+ ktime_set(send_sepol, 0));
+ spin_unlock(&imp_sec->ps_lock);
+
+ return 1;
+}
+
+int sptlrpc_get_sepol(struct ptlrpc_request *req)