[PATCH] tcm: Convert target_core_dev_pr_store_attr_res_aptpl_metadata() to use parser.h

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch converts the persistent reservations APTPL (activate persistence across
target power loss) parsing logic in target_core_dev_pr_store_attr_res_aptpl_metadata()
to use proper kstrdup(), strsep() and linux/parser.h match_token() logic.

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
Reported-off-by: Christoph Hellwig <hch@xxxxxx>
---
 drivers/target/target_core_configfs.c |  262 +++++++++++++--------------------
 1 files changed, 101 insertions(+), 161 deletions(-)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index bd2d4af..10c8c75 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/unistd.h>
 #include <linux/string.h>
+#include <linux/parser.h>
 #include <linux/syscalls.h>
 #include <linux/configfs.h>
 #include <linux/proc_fs.h>
@@ -1455,6 +1456,30 @@ static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata(
 	return sprintf(page, "Ready to process PR APTPL metadata..\n");
 }
 
+enum {
+	Opt_initiator_fabric, Opt_initiator_node, Opt_initiator_sid,
+	Opt_sa_res_key, Opt_res_holder, Opt_res_type, Opt_res_scope,
+	Opt_res_all_tg_pt, Opt_mapped_lun, Opt_target_fabric,
+	Opt_target_node, Opt_tpgt, Opt_port_rtpi, Opt_target_lun
+};
+
+static match_table_t tokens = {
+	{Opt_initiator_fabric, "initiator_fabric=%s"},
+	{Opt_initiator_node, "initiator_node=%s"},
+	{Opt_initiator_sid, "initiator_sid=%s"},
+	{Opt_sa_res_key, "sa_res_key=%s"},
+	{Opt_res_holder, "res_holder=%d"},
+	{Opt_res_type, "res_type=%d"},
+	{Opt_res_scope, "res_scope=%d"},
+	{Opt_res_all_tg_pt, "res_all_tg_pt=%d"},
+	{Opt_mapped_lun, "mapped_lun=%d"},
+	{Opt_target_fabric, "target_fabric=%s"},
+	{Opt_target_node, "target_node=%s"},
+	{Opt_tpgt, "tpgt=%d"},
+	{Opt_port_rtpi, "port_rtpi=%d"},
+	{Opt_target_lun, "target_lun=%d"},
+};
+
 static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
 	struct se_subsystem_dev *su_dev,
 	const char *page,
@@ -1463,12 +1488,12 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
 	struct se_device *dev;
 	unsigned char *i_fabric, *t_fabric, *i_port = NULL, *t_port = NULL;
 	unsigned char *isid = NULL;
-	char *ptr, *ptr2, *cur, *buf;
+	char *orig, *ptr, *arg_p, *opts;
+	substring_t args[MAX_OPT_ARGS];
 	unsigned long long tmp_ll;
-	unsigned long tmp_l;
 	u64 sa_res_key = 0;
 	u32 mapped_lun = 0, target_lun = 0;
-	int ret = -1, res_holder = 0, all_tg_pt = 0;
+	int ret = -1, res_holder = 0, all_tg_pt = 0, arg, token;
 	u16 port_rpti = 0, tpgt = 0;
 	u8 type = 0, scope;
 
@@ -1484,202 +1509,117 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
 			" active fabric exports exist\n");
 		return -EINVAL;
 	}
-	/*
-	 * Allocate and copy input to our own buffer so that we can setup
-	 * NULL terminators later for incoming PR APTPL metadata..
-	 */
-	buf = kzalloc(count, GFP_KERNEL);
-	memcpy(buf, page, count);
-	cur = &buf[0];
 
-	while (cur) {
-		ptr = strstr(cur, "=");
-		if (!(ptr))
-			goto out;
+	opts = kstrdup(page, GFP_KERNEL);
+	if (!opts)
+		return -ENOMEM;
 
-		*ptr = '\0';
-		ptr++;
-		/*
-		 * PR APTPL Metadata for Initiator Port
-		 */
-		ptr2 = strstr(cur, "initiator_fabric");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			i_fabric = ptr;
+	orig = opts;
+	while ((ptr = strsep(&opts, ",")) != NULL) {
+		if (!*ptr)
 			continue;
-		}
-		ptr2 = strstr(cur, "initiator_node");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			if (strlen(ptr) > PR_APTPL_MAX_IPORT_LEN) {
+
+		token = match_token(ptr, tokens, args);
+		switch (token) {
+		case Opt_initiator_fabric:
+			i_fabric = match_strdup(&args[0]);
+			break;
+		case Opt_initiator_node:
+			i_port = match_strdup(&args[0]);
+			if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
 				printk(KERN_ERR "APTPL metadata initiator_node="
 					" exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
 					PR_APTPL_MAX_IPORT_LEN);
-				ret = -1;
+				ret = -EINVAL;
 				break;
 			}
-			i_port = ptr;
-			continue;
-		}
-		ptr2 = strstr(cur, "initiator_sid");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			if (strlen(ptr) > PR_REG_ISID_LEN) {
+			break;
+		case Opt_initiator_sid:
+			isid = match_strdup(&args[0]);
+			if (strlen(isid) > PR_REG_ISID_LEN) {
 				printk(KERN_ERR "APTPL metadata initiator_isid"
 					"= exceeds PR_REG_ISID_LEN: %d\n",
 					PR_REG_ISID_LEN);
-				ret = -1;
+				ret = -EINVAL;
 				break;
 			}
-			isid = ptr;
-			continue;
-		}
-		ptr2 = strstr(cur, "sa_res_key");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoull(ptr, 0, &tmp_ll);
+			break;
+		case Opt_sa_res_key:
+			arg_p = match_strdup(&args[0]);
+			ret = strict_strtoull(arg_p, 0, &tmp_ll);
 			if (ret < 0) {
 				printk(KERN_ERR "strict_strtoull() failed for"
 					" sa_res_key=\n");
-				break;
+				goto out;
 			}
 			sa_res_key = (u64)tmp_ll;
-			continue;
-		}
+			break;
 		/*
 		 * PR APTPL Metadata for Reservation
 		 */
-		ptr2 = strstr(cur, "res_holder");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" res_holder=\n");
-				break;
-			}
-			res_holder = (int)tmp_l;
-			continue;
-		}
-		ptr2 = strstr(cur, "res_type");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" res_type=\n");
-				break;
-			}
-			type = (u8)tmp_l;
-			continue;
-		}
-		ptr2 = strstr(cur, "res_scope");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" res_scope=\n");
-				break;
-			}
-			scope = (u8)tmp_l;
-			continue;
-		}
-		ptr2 = strstr(cur, "res_all_tg_pt");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" res_all_tg_pt=\n");
-				break;
-			}
-			all_tg_pt = (int)tmp_l;
-			continue;
-		}
-		ptr2 = strstr(cur, "mapped_lun");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" mapped_lun=\n");
-				break;
-			}
-			mapped_lun = (u32)tmp_l;
-			continue;
-		}
+		case Opt_res_holder:
+			match_int(args, &arg);
+			res_holder = arg;
+			break;
+		case Opt_res_type:
+			match_int(args, &arg);
+			type = (u8)arg;
+			break;
+		case Opt_res_scope:
+			match_int(args, &arg);
+			scope = (u8)arg;
+			break;
+		case Opt_res_all_tg_pt:
+			match_int(args, &arg);
+			all_tg_pt = (int)arg;
+			break;
+		case Opt_mapped_lun:
+			match_int(args, &arg);
+			mapped_lun = (u32)arg;
+			break;
 		/*
 		 * PR APTPL Metadata for Target Port
 		 */
-		ptr2 = strstr(cur, "target_fabric");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			t_fabric = ptr;
-			continue;
-		}
-		ptr2 = strstr(cur, "target_node");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			if (strlen(ptr) > PR_APTPL_MAX_TPORT_LEN) {
+		case Opt_target_fabric:
+			t_fabric = match_strdup(&args[0]);
+			break;
+		case Opt_target_node:
+			t_port = match_strdup(&args[0]);
+			if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
 				printk(KERN_ERR "APTPL metadata target_node="
 					" exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
 					PR_APTPL_MAX_TPORT_LEN);
-				ret = -1;
+				ret = -EINVAL;
 				break;
 			}
-			t_port = ptr;
-			continue;
-		}
-		ptr2 = strstr(cur, "tpgt");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" tpgt=\n");
-				break;
-			}
-			tpgt = (u16)tmp_l;
-			continue;
-		}
-		ptr2 = strstr(cur, "port_rtpi");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" port_rtpi=\n");
-				break;
-			}
-			port_rpti = (u16)tmp_l;
-			continue;
+			break;
+		case Opt_tpgt:
+			match_int(args, &arg);
+			tpgt = (u16)arg;
+			break;
+		case Opt_port_rtpi:
+			match_int(args, &arg);
+			port_rpti = (u16)arg;
+			break;
+		case Opt_target_lun:
+			match_int(args, &arg);
+			target_lun = (u32)arg;
+			break;
+		default:
+			break;
 		}
-		ptr2 = strstr(cur, "target_lun");
-		if (ptr2) {
-			transport_check_dev_params_delim(ptr, &cur);
-			ret = strict_strtoul(ptr, 0, &tmp_l);
-			if (ret < 0) {
-				printk(KERN_ERR "strict_strtoul() failed for"
-					" target_lun=\n");
-				break;
-			}
-			target_lun = (u32)tmp_l;
-			continue;
-		} else
-			cur = NULL;
 	}
 
 	if (!(i_port) || !(t_port) || !(sa_res_key)) {
 		printk(KERN_ERR "Illegal parameters for APTPL registration\n");
-		ret = -1;
+		ret = -EINVAL;
 		goto out;
 	}
 
 	if (res_holder && !(type)) {
 		printk(KERN_ERR "Illegal PR type: 0x%02x for reservation"
 				" holder\n", type);
-		ret = -1;
+		ret = -EINVAL;
 		goto out;
 	}
 
@@ -1687,8 +1627,8 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
 			i_port, isid, mapped_lun, t_port, tpgt, target_lun,
 			res_holder, all_tg_pt, type);
 out:
-	kfree(buf);
-	return (ret == 0) ? count : -EINVAL;
+	kfree(orig);
+	return (ret == 0) ? count : ret;
 }
 
 SE_DEV_PR_ATTR(res_aptpl_metadata, S_IRUGO | S_IWUSR);
-- 
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux