scsi: nvme: Added a new sysfs attribute appid_store

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>
This commit is contained in:
Muneendra Kumar 2021-06-08 10:05:46 +05:30 committed by Martin K. Petersen
parent d2bcbeab42
commit 3dbbca75ed
1 changed files with 71 additions and 1 deletions

View 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
};