Commit 3dbbca75 authored by Muneendra Kumar's avatar Muneendra Kumar Committed by Martin K. Petersen
Browse files

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: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarMuneendra Kumar <muneendra.kumar@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d2bcbeab
Loading
Loading
Loading
Loading
+71 −1
Original line number Diff line number Diff line
@@ -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 @@ static ssize_t nvme_fc_nvme_discovery_store(struct device *dev,

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