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