scsi: nvme: Added a new sysfs attribute appid_store
authorMuneendra Kumar <muneendra.kumar@broadcom.com>
Tue, 8 Jun 2021 04:35:46 +0000 (10:05 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 10 Jun 2021 14:01:32 +0000 (10:01 -0400)
Add a new sysfs attribute, appid_store, which can be used to set the
application identifier in the blkcg associated with a cgroup id.

Below is the interface provided to set the app_id:

  echo "<cgroupid>:<appid>" >> /sys/class/fc/fc_udev_device/appid_store

  echo "457E:100000109b521d27" >> /sys/class/fc/fc_udev_device/appid_store

Link: https://lore.kernel.org/r/20210608043556.274139-4-muneendra.kumar@broadcom.com
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Muneendra Kumar <muneendra.kumar@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/nvme/host/fc.c

index d9ab9e7..835b563 100644 (file)
@@ -9,7 +9,7 @@
 #include <uapi/scsi/fc/fc_els.h>
 #include <linux/delay.h>
 #include <linux/overflow.h>
-
+#include <linux/blk-cgroup.h>
 #include "nvme.h"
 #include "fabrics.h"
 #include <linux/nvme-fc-driver.h>
@@ -3787,10 +3787,80 @@ process_local_list:
 
        return count;
 }
+
+/* Parse the cgroup id from a buf and return the length of cgrpid */
+static int fc_parse_cgrpid(const char *buf, u64 *id)
+{
+       char cgrp_id[16+1];
+       int cgrpid_len, j;
+
+       memset(cgrp_id, 0x0, sizeof(cgrp_id));
+       for (cgrpid_len = 0, j = 0; cgrpid_len < 17; cgrpid_len++) {
+               if (buf[cgrpid_len] != ':')
+                       cgrp_id[cgrpid_len] = buf[cgrpid_len];
+               else {
+                       j = 1;
+                       break;
+               }
+       }
+       if (!j)
+               return -EINVAL;
+       if (kstrtou64(cgrp_id, 16, id) < 0)
+               return -EINVAL;
+       return cgrpid_len;
+}
+
+/*
+ * fc_update_appid: Parse and update the appid in the blkcg associated with
+ * cgroupid.
+ * @buf: buf contains both cgrpid and appid info
+ * @count: size of the buffer
+ */
+static int fc_update_appid(const char *buf, size_t count)
+{
+       u64 cgrp_id;
+       int appid_len = 0;
+       int cgrpid_len = 0;
+       char app_id[FC_APPID_LEN];
+       int ret = 0;
+
+       if (buf[count-1] == '\n')
+               count--;
+
+       if ((count > (16+1+FC_APPID_LEN)) || (!strchr(buf, ':')))
+               return -EINVAL;
+
+       cgrpid_len = fc_parse_cgrpid(buf, &cgrp_id);
+       if (cgrpid_len < 0)
+               return -EINVAL;
+       appid_len = count - cgrpid_len - 1;
+       if (appid_len > FC_APPID_LEN)
+               return -EINVAL;
+
+       memset(app_id, 0x0, sizeof(app_id));
+       memcpy(app_id, &buf[cgrpid_len+1], appid_len);
+       ret = blkcg_set_fc_appid(app_id, cgrp_id, sizeof(app_id));
+       if (ret < 0)
+               return ret;
+       return count;
+}
+
+static ssize_t fc_appid_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       int ret  = 0;
+
+       ret = fc_update_appid(buf, count);
+       if (ret < 0)
+               return -EINVAL;
+       return count;
+}
 static DEVICE_ATTR(nvme_discovery, 0200, NULL, nvme_fc_nvme_discovery_store);
+static DEVICE_ATTR(appid_store, 0200, NULL, fc_appid_store);
 
 static struct attribute *nvme_fc_attrs[] = {
        &dev_attr_nvme_discovery.attr,
+       &dev_attr_appid_store.attr,
        NULL
 };