Whamcloud - gitweb
LU-13525 sec: better struct sepol_downcall_data
[fs/lustre-release.git] / lustre / ptlrpc / sec_lproc.c
index e3d99ac..41ef7e0 100644 (file)
@@ -69,16 +69,16 @@ static char *sec_flags2str(unsigned long flags, char *buf, int bufsize)
 
 static int sptlrpc_info_lprocfs_seq_show(struct seq_file *seq, void *v)
 {
-        struct obd_device *dev = seq->private;
-        struct client_obd *cli = &dev->u.cli;
-        struct ptlrpc_sec *sec = NULL;
-        char               str[32];
+       struct obd_device *obd = seq->private;
+       struct client_obd *cli = &obd->u.cli;
+       struct ptlrpc_sec *sec = NULL;
+       char               str[32];
 
-       LASSERT(strcmp(dev->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_MGC_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_OSP_NAME) == 0);
+       LASSERT(strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) == 0);
 
         if (cli->cl_import)
                 sec = sptlrpc_import_sec_ref(cli->cl_import);
@@ -111,15 +111,15 @@ LPROC_SEQ_FOPS_RO(sptlrpc_info_lprocfs);
 
 static int sptlrpc_ctxs_lprocfs_seq_show(struct seq_file *seq, void *v)
 {
-        struct obd_device *dev = seq->private;
-        struct client_obd *cli = &dev->u.cli;
-        struct ptlrpc_sec *sec = NULL;
+       struct obd_device *obd = seq->private;
+       struct client_obd *cli = &obd->u.cli;
+       struct ptlrpc_sec *sec = NULL;
 
-       LASSERT(strcmp(dev->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_MGC_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 ||
-               strcmp(dev->obd_type->typ_name, LUSTRE_OSP_NAME) == 0);
+       LASSERT(strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 ||
+               strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) == 0);
 
         if (cli->cl_import)
                 sec = sptlrpc_import_sec_ref(cli->cl_import);
@@ -136,22 +136,23 @@ out:
 
 LPROC_SEQ_FOPS_RO(sptlrpc_ctxs_lprocfs);
 
-static ssize_t
-lprocfs_sptlrpc_sepol_seq_write(struct file *file, const char __user *buffer,
-                               size_t count, void *data)
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
+static ssize_t sepol_seq_write_old(struct obd_device *obd,
+                                  const char __user *buffer,
+                                  size_t count)
 {
-       struct seq_file *seq = file->private_data;
-       struct obd_device *dev = seq->private;
-       struct client_obd *cli = &dev->u.cli;
+       struct client_obd *cli = &obd->u.cli;
        struct obd_import *imp = cli->cl_import;
-       struct sepol_downcall_data *param;
+       struct sepol_downcall_data_old *param;
        int size = sizeof(*param);
+       __u16 len;
        int rc = 0;
 
        if (count < size) {
-               CERROR("%s: invalid data count = %lu, size = %d\n",
-                      dev->obd_name, (unsigned long) count, size);
-               return -EINVAL;
+               rc = -EINVAL;
+               CERROR("%s: invalid data count = %lu, size = %d: rc = %d\n",
+                      obd->obd_name, (unsigned long) count, size, rc);
+               return rc;
        }
 
        OBD_ALLOC(param, size);
@@ -159,42 +160,53 @@ lprocfs_sptlrpc_sepol_seq_write(struct file *file, const char __user *buffer,
                return -ENOMEM;
 
        if (copy_from_user(param, buffer, size)) {
-               CERROR("%s: bad sepol data\n", dev->obd_name);
-               GOTO(out, rc = -EFAULT);
+               rc = -EFAULT;
+               CERROR("%s: bad sepol data: rc = %d\n", obd->obd_name, rc);
+               GOTO(out, rc);
        }
 
-       if (param->sdd_magic != SEPOL_DOWNCALL_MAGIC) {
-               CERROR("%s: sepol downcall bad params\n",
-                      dev->obd_name);
-               GOTO(out, rc = -EINVAL);
+       if (param->sdd_magic != SEPOL_DOWNCALL_MAGIC_OLD) {
+               rc = -EINVAL;
+               CERROR("%s: sepol downcall bad params: rc = %d\n",
+                      obd->obd_name, rc);
+               GOTO(out, rc);
        }
 
        if (param->sdd_sepol_len == 0 ||
            param->sdd_sepol_len >= sizeof(imp->imp_sec->ps_sepol)) {
-               CERROR("%s: invalid sepol data returned\n",
-                      dev->obd_name);
-               GOTO(out, rc = -EINVAL);
+               rc = -EINVAL;
+               CERROR("%s: invalid sepol data returned: rc = %d\n",
+                      obd->obd_name, rc);
+               GOTO(out, rc);
        }
-       rc = param->sdd_sepol_len; /* save sdd_sepol_len */
+       len = param->sdd_sepol_len; /* save sdd_sepol_len */
        OBD_FREE(param, size);
-       size = offsetof(struct sepol_downcall_data,
-                       sdd_sepol[rc]);
+       size = offsetof(struct sepol_downcall_data_old,
+                       sdd_sepol[len]);
+
+       if (count < size) {
+               rc = -EINVAL;
+               CERROR("%s: invalid sepol count = %lu, size = %d: rc = %d\n",
+                      obd->obd_name, (unsigned long) count, size, rc);
+               return rc;
+       }
 
        /* alloc again with real size */
-       rc = 0;
        OBD_ALLOC(param, size);
        if (param == NULL)
                return -ENOMEM;
 
        if (copy_from_user(param, buffer, size)) {
-               CERROR("%s: bad sepol data\n", dev->obd_name);
-               GOTO(out, rc = -EFAULT);
+               rc = -EFAULT;
+               CERROR("%s: cannot copy sepol data: rc = %d\n",
+                      obd->obd_name, rc);
+               GOTO(out, rc);
        }
 
        spin_lock(&imp->imp_sec->ps_lock);
        snprintf(imp->imp_sec->ps_sepol, param->sdd_sepol_len + 1, "%s",
                 param->sdd_sepol);
-       imp->imp_sec->ps_sepol_mtime = param->sdd_sepol_mtime;
+       imp->imp_sec->ps_sepol_mtime = ktime_set(param->sdd_sepol_mtime, 0);
        spin_unlock(&imp->imp_sec->ps_lock);
 
 out:
@@ -203,46 +215,124 @@ out:
 
        return rc ? rc : count;
 }
-LPROC_SEQ_FOPS_WR_ONLY(srpc, sptlrpc_sepol);
+#endif
 
-int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev)
+static ssize_t
+lprocfs_sptlrpc_sepol_seq_write(struct file *file, const char __user *buffer,
+                               size_t count, void *data)
 {
-       int     rc;
+       struct seq_file *seq = file->private_data;
+       struct obd_device *obd = seq->private;
+       struct client_obd *cli = &obd->u.cli;
+       struct obd_import *imp = cli->cl_import;
+       struct sepol_downcall_data *param;
+       __u32 magic;
+       int size = sizeof(magic);
+       __u16 len;
+       int rc = 0;
 
-       if (strcmp(dev->obd_type->typ_name, LUSTRE_OSC_NAME) != 0 &&
-           strcmp(dev->obd_type->typ_name, LUSTRE_MDC_NAME) != 0 &&
-           strcmp(dev->obd_type->typ_name, LUSTRE_MGC_NAME) != 0 &&
-           strcmp(dev->obd_type->typ_name, LUSTRE_LWP_NAME) != 0 &&
-           strcmp(dev->obd_type->typ_name, LUSTRE_OSP_NAME) != 0) {
-               CERROR("can't register lproc for obd type %s\n",
-                      dev->obd_type->typ_name);
-               return -EINVAL;
+       if (count < size) {
+               rc = -EINVAL;
+               CERROR("%s: invalid buffer count = %lu, size = %d: rc = %d\n",
+                      obd->obd_name, (unsigned long) count, size, rc);
+               return rc;
        }
 
-       rc = ldebugfs_seq_create(dev->obd_debugfs_entry, "srpc_info", 0444,
-                                &sptlrpc_info_lprocfs_fops, dev);
-       if (rc) {
-               CERROR("create proc entry srpc_info for %s: %d\n",
-                      dev->obd_name, rc);
+       if (copy_from_user(&magic, buffer, size)) {
+               rc = -EFAULT;
+               CERROR("%s: bad sepol magic: rc = %d\n", obd->obd_name, rc);
                return rc;
        }
 
-       rc = ldebugfs_seq_create(dev->obd_debugfs_entry, "srpc_contexts",
-                                0444, &sptlrpc_ctxs_lprocfs_fops, dev);
-       if (rc) {
-               CERROR("create proc entry srpc_contexts for %s: %d\n",
-                      dev->obd_name, rc);
+       if (magic != SEPOL_DOWNCALL_MAGIC) {
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
+               if (magic == SEPOL_DOWNCALL_MAGIC_OLD) {
+                       return sepol_seq_write_old(obd, buffer, count);
+               }
+#endif
+               rc = -EINVAL;
+               CERROR("%s: sepol downcall bad magic '%#08x': rc = %d\n",
+                      obd->obd_name, magic, rc);
                return rc;
        }
 
-       rc = ldebugfs_seq_create(dev->obd_debugfs_entry, "srpc_sepol",
-                                0200, &srpc_sptlrpc_sepol_fops, dev);
-       if (rc) {
-               CERROR("create proc entry srpc_sepol for %s: %d\n",
-                      dev->obd_name, rc);
+       size = sizeof(*param);
+       if (count < size) {
+               rc = -EINVAL;
+               CERROR("%s: invalid data count = %lu, size = %d: rc = %d\n",
+                      obd->obd_name, (unsigned long) count, size, rc);
                return rc;
        }
 
+       OBD_ALLOC(param, size);
+       if (param == NULL)
+               return -ENOMEM;
+
+       if (copy_from_user(param, buffer, size)) {
+               rc = -EFAULT;
+               CERROR("%s: bad sepol data: rc = %d\n", obd->obd_name, rc);
+               GOTO(out, rc);
+       }
+
+       if (param->sdd_sepol_len == 0 ||
+           param->sdd_sepol_len >= sizeof(imp->imp_sec->ps_sepol)) {
+               rc = -EINVAL;
+               CERROR("%s: invalid sepol data returned: rc = %d\n",
+                      obd->obd_name, rc);
+               GOTO(out, rc);
+       }
+       len = param->sdd_sepol_len; /* save sdd_sepol_len */
+       OBD_FREE(param, size);
+       size = offsetof(struct sepol_downcall_data,
+                       sdd_sepol[len]);
+
+       /* alloc again with real size */
+       OBD_ALLOC(param, size);
+       if (param == NULL)
+               return -ENOMEM;
+
+       if (copy_from_user(param, buffer, size)) {
+               rc = -EFAULT;
+               CERROR("%s: cannot copy sepol data: rc = %d\n",
+                      obd->obd_name, rc);
+               GOTO(out, rc);
+       }
+
+       spin_lock(&imp->imp_sec->ps_lock);
+       snprintf(imp->imp_sec->ps_sepol, param->sdd_sepol_len + 1, "%s",
+                param->sdd_sepol);
+       imp->imp_sec->ps_sepol_mtime = ktime_set(param->sdd_sepol_mtime, 0);
+       spin_unlock(&imp->imp_sec->ps_lock);
+
+out:
+       if (param != NULL)
+               OBD_FREE(param, size);
+
+       return rc ? rc : count;
+}
+LPROC_SEQ_FOPS_WR_ONLY(srpc, sptlrpc_sepol);
+
+int sptlrpc_lprocfs_cliobd_attach(struct obd_device *obd)
+{
+       if (strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) != 0 &&
+           strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) != 0 &&
+           strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME) != 0 &&
+           strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) != 0 &&
+           strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) != 0) {
+               CERROR("can't register lproc for obd type %s\n",
+                      obd->obd_type->typ_name);
+               return -EINVAL;
+       }
+
+       debugfs_create_file("srpc_info", 0444, obd->obd_debugfs_entry, obd,
+                           &sptlrpc_info_lprocfs_fops);
+
+       debugfs_create_file("srpc_contexts", 0444, obd->obd_debugfs_entry, obd,
+                           &sptlrpc_ctxs_lprocfs_fops);
+
+       debugfs_create_file("srpc_sepol", 0200, obd->obd_debugfs_entry, obd,
+                           &srpc_sptlrpc_sepol_fops);
+
        return 0;
 }
 EXPORT_SYMBOL(sptlrpc_lprocfs_cliobd_attach);
@@ -267,14 +357,9 @@ int sptlrpc_lproc_init(void)
 
        LASSERT(sptlrpc_debugfs_dir == NULL);
 
-       sptlrpc_debugfs_dir = ldebugfs_register("sptlrpc", debugfs_lustre_root,
-                                               sptlrpc_lprocfs_vars, NULL);
-       if (IS_ERR_OR_NULL(sptlrpc_debugfs_dir)) {
-               rc = sptlrpc_debugfs_dir ? PTR_ERR(sptlrpc_debugfs_dir)
-                                        : -ENOMEM;
-               sptlrpc_debugfs_dir = NULL;
-               return rc;
-       }
+       sptlrpc_debugfs_dir = debugfs_create_dir("sptlrpc",
+                                                debugfs_lustre_root);
+       ldebugfs_add_vars(sptlrpc_debugfs_dir, sptlrpc_lprocfs_vars, NULL);
 
        sptlrpc_lprocfs_dir = lprocfs_register("sptlrpc", proc_lustre_root,
                                               NULL, NULL);