+ if (cmd->tc_cmd == NRS_CTL_TBF_START_RULE) {
+ if (cmd->u.tc_start.ts_valid_type & NRS_TBF_FLAG_JOBID)
+ nrs_tbf_jobid_cmd_fini(cmd);
+ else if (cmd->u.tc_start.ts_valid_type & NRS_TBF_FLAG_NID)
+ nrs_tbf_nid_cmd_fini(cmd);
+ }
+}
+
+static bool name_is_valid(const char *name)
+{
+ int i;
+
+ for (i = 0; i < strlen(name); i++) {
+ if ((!isalnum(name[i])) &&
+ (name[i] != '_'))
+ return false;
+ }
+ return true;
+}
+
+static int
+nrs_tbf_parse_value_pair(struct nrs_tbf_cmd *cmd, char *buffer)
+{
+ char *key;
+ char *val;
+ int rc;
+ __u64 rate;
+
+ val = buffer;
+ key = strsep(&val, "=");
+ if (val == NULL || strlen(val) == 0)
+ return -EINVAL;
+
+ /* Key of the value pair */
+ if (strcmp(key, "rate") == 0) {
+ rc = kstrtoull(val, 10, &rate);
+ if (rc)
+ return rc;
+
+ if (rate <= 0 || rate >= LPROCFS_NRS_RATE_MAX)
+ return -EINVAL;
+
+ if (cmd->tc_cmd == NRS_CTL_TBF_START_RULE)
+ cmd->u.tc_start.ts_rpc_rate = rate;
+ else if (cmd->tc_cmd == NRS_CTL_TBF_CHANGE_RULE)
+ cmd->u.tc_change.tc_rpc_rate = rate;
+ else
+ return -EINVAL;
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int
+nrs_tbf_parse_value_pairs(struct nrs_tbf_cmd *cmd, char *buffer)
+{
+ char *val;
+ char *token;
+ int rc;
+
+ val = buffer;
+ while (val != NULL && strlen(val) != 0) {
+ token = strsep(&val, " ");
+ rc = nrs_tbf_parse_value_pair(cmd, token);
+ if (rc)
+ return rc;
+ }
+
+ switch (cmd->tc_cmd) {
+ case NRS_CTL_TBF_START_RULE:
+ if (cmd->u.tc_start.ts_rpc_rate == 0)
+ cmd->u.tc_start.ts_rpc_rate = tbf_rate;
+ break;
+ case NRS_CTL_TBF_CHANGE_RULE:
+ if (cmd->u.tc_change.tc_rpc_rate == 0)
+ return -EINVAL;
+ break;
+ case NRS_CTL_TBF_STOP_RULE:
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;