2024-04-22 07:55:14

by Dongsheng Yang

[permalink] [raw]
Subject: [PATCH 4/7] cbd: introduce cbd_host

From: Dongsheng Yang <[email protected]>

The "cbd_host" represents a host node. Each node needs to be registered
before it can use the "cbd_transport". After registration, the node's
information, such as its hostname, will be recorded in the "hosts" area
of this transport. Through this mechanism, we can know which nodes are
currently using each transport.

Signed-off-by: Dongsheng Yang <[email protected]>
---
drivers/block/cbd/Makefile | 2 +-
drivers/block/cbd/cbd_host.c | 123 ++++++++++++++++++++++++++++++
drivers/block/cbd/cbd_transport.c | 8 ++
3 files changed, 132 insertions(+), 1 deletion(-)
create mode 100644 drivers/block/cbd/cbd_host.c

diff --git a/drivers/block/cbd/Makefile b/drivers/block/cbd/Makefile
index c581ae96732b..2389a738b12b 100644
--- a/drivers/block/cbd/Makefile
+++ b/drivers/block/cbd/Makefile
@@ -1,3 +1,3 @@
-cbd-y := cbd_main.o cbd_transport.o cbd_channel.o
+cbd-y := cbd_main.o cbd_transport.o cbd_channel.o cbd_host.o

obj-$(CONFIG_BLK_DEV_CBD) += cbd.o
diff --git a/drivers/block/cbd/cbd_host.c b/drivers/block/cbd/cbd_host.c
new file mode 100644
index 000000000000..892961f5f1b2
--- /dev/null
+++ b/drivers/block/cbd/cbd_host.c
@@ -0,0 +1,123 @@
+#include "cbd_internal.h"
+
+static ssize_t cbd_host_name_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct cbd_host_device *host;
+ struct cbd_host_info *host_info;
+
+ host = container_of(dev, struct cbd_host_device, dev);
+ host_info = host->host_info;
+
+ cbdt_flush_range(host->cbdt, host_info, sizeof(*host_info));
+
+ if (host_info->state == cbd_host_state_none)
+ return 0;
+
+ if (strlen(host_info->hostname) == 0)
+ return 0;
+
+ return sprintf(buf, "%s\n", host_info->hostname);
+}
+
+static DEVICE_ATTR(hostname, 0400, cbd_host_name_show, NULL);
+
+CBD_OBJ_HEARTBEAT(host);
+
+static struct attribute *cbd_host_attrs[] = {
+ &dev_attr_hostname.attr,
+ &dev_attr_alive.attr,
+ NULL
+};
+
+static struct attribute_group cbd_host_attr_group = {
+ .attrs = cbd_host_attrs,
+};
+
+static const struct attribute_group *cbd_host_attr_groups[] = {
+ &cbd_host_attr_group,
+ NULL
+};
+
+static void cbd_host_release(struct device *dev)
+{
+}
+
+struct device_type cbd_host_type = {
+ .name = "cbd_host",
+ .groups = cbd_host_attr_groups,
+ .release = cbd_host_release,
+};
+
+struct device_type cbd_hosts_type = {
+ .name = "cbd_hosts",
+ .release = cbd_host_release,
+};
+
+int cbd_host_register(struct cbd_transport *cbdt, char *hostname)
+{
+ struct cbd_host *host;
+ struct cbd_host_info *host_info;
+ u32 host_id;
+ int ret;
+
+ if (cbdt->host) {
+ return -EEXIST;
+ }
+
+ if (strlen(hostname) == 0) {
+ return -EINVAL;
+ }
+
+ ret = cbdt_get_empty_host_id(cbdt, &host_id);
+ if (ret < 0) {
+ return ret;
+ }
+
+ host = kzalloc(sizeof(struct cbd_host), GFP_KERNEL);
+ if (!host) {
+ return -ENOMEM;
+ }
+
+ host->host_id = host_id;
+ host->cbdt = cbdt;
+ INIT_DELAYED_WORK(&host->hb_work, host_hb_workfn);
+
+ host_info = cbdt_get_host_info(cbdt, host_id);
+ host_info->state = cbd_host_state_running;
+ memcpy(host_info->hostname, hostname, CBD_NAME_LEN);
+
+ cbdt_flush_range(cbdt, host_info, sizeof(*host_info));
+
+ host->host_info = host_info;
+ cbdt->host = host;
+
+ queue_delayed_work(cbd_wq, &host->hb_work, 0);
+
+ return 0;
+}
+
+int cbd_host_unregister(struct cbd_transport *cbdt)
+{
+ struct cbd_host *host = cbdt->host;
+ struct cbd_host_info *host_info;
+
+ if (!host) {
+ cbd_err("This host is not registered.");
+ return 0;
+ }
+
+ cancel_delayed_work_sync(&host->hb_work);
+ host_info = host->host_info;
+ memset(host_info->hostname, 0, CBD_NAME_LEN);
+ host_info->alive_ts = 0;
+ host_info->state = cbd_host_state_none;
+
+ cbdt_flush_range(cbdt, host_info, sizeof(*host_info));
+
+ cbdt->host = NULL;
+ kfree(cbdt->host);
+
+ return 0;
+}
diff --git a/drivers/block/cbd/cbd_transport.c b/drivers/block/cbd/cbd_transport.c
index 3a4887afab08..682d0f45ce9e 100644
--- a/drivers/block/cbd/cbd_transport.c
+++ b/drivers/block/cbd/cbd_transport.c
@@ -571,6 +571,7 @@ int cbdt_unregister(u32 tid)
}
mutex_unlock(&cbdt->lock);

+ cbd_host_unregister(cbdt);
device_unregister(&cbdt->device);
cbdt_dax_release(cbdt);
cbdt_destroy(cbdt);
@@ -624,8 +625,15 @@ int cbdt_register(struct cbdt_register_options *opts)
goto dax_release;
}

+ ret = cbd_host_register(cbdt, opts->hostname);
+ if (ret) {
+ goto dev_unregister;
+ }
+
return 0;

+devs_exit:
+ cbd_host_unregister(cbdt);
dev_unregister:
device_unregister(&cbdt->device);
dax_release:
--
2.34.1



2024-04-25 05:52:16

by Bharat Bhushan

[permalink] [raw]
Subject: RE: [EXTERNAL] [PATCH 4/7] cbd: introduce cbd_host



> -----Original Message-----
> From: Dongsheng Yang <[email protected]>
> Sent: Monday, April 22, 2024 12:46 PM
> To: [email protected]; [email protected]
> Cc: [email protected]; [email protected]; linux-
> [email protected]; Dongsheng Yang <[email protected]>
> Subject: [EXTERNAL] [PATCH 4/7] cbd: introduce cbd_host
>
> Prioritize security for external emails: Confirm sender and content safety
> before clicking links or opening attachments
>
> ----------------------------------------------------------------------
> From: Dongsheng Yang <[email protected]>
>
> The "cbd_host" represents a host node. Each node needs to be registered
> before it can use the "cbd_transport". After registration, the node's
> information, such as its hostname, will be recorded in the "hosts" area of this
> transport. Through this mechanism, we can know which nodes are currently
> using each transport.
>
> Signed-off-by: Dongsheng Yang <[email protected]>
> ---
> drivers/block/cbd/Makefile | 2 +-
> drivers/block/cbd/cbd_host.c | 123
> ++++++++++++++++++++++++++++++
> drivers/block/cbd/cbd_transport.c | 8 ++
> 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644
> drivers/block/cbd/cbd_host.c
>
> diff --git a/drivers/block/cbd/Makefile b/drivers/block/cbd/Makefile index
> c581ae96732b..2389a738b12b 100644
> --- a/drivers/block/cbd/Makefile
> +++ b/drivers/block/cbd/Makefile
> @@ -1,3 +1,3 @@
> -cbd-y := cbd_main.o cbd_transport.o cbd_channel.o
> +cbd-y := cbd_main.o cbd_transport.o cbd_channel.o cbd_host.o
>
> obj-$(CONFIG_BLK_DEV_CBD) += cbd.o
> diff --git a/drivers/block/cbd/cbd_host.c b/drivers/block/cbd/cbd_host.c new
> file mode 100644 index 000000000000..892961f5f1b2
> --- /dev/null
> +++ b/drivers/block/cbd/cbd_host.c
> @@ -0,0 +1,123 @@
> +#include "cbd_internal.h"
> +
> +static ssize_t cbd_host_name_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct cbd_host_device *host;
> + struct cbd_host_info *host_info;
> +
> + host = container_of(dev, struct cbd_host_device, dev);
> + host_info = host->host_info;
> +
> + cbdt_flush_range(host->cbdt, host_info, sizeof(*host_info));
> +
> + if (host_info->state == cbd_host_state_none)
> + return 0;
> +
> + if (strlen(host_info->hostname) == 0)
> + return 0;

Sprintf is safe to provide zero length source buffer. Maybe this check can be removed.

> +
> + return sprintf(buf, "%s\n", host_info->hostname); }
> +
> +static DEVICE_ATTR(hostname, 0400, cbd_host_name_show, NULL);
> +
> +CBD_OBJ_HEARTBEAT(host);
> +
> +static struct attribute *cbd_host_attrs[] = {
> + &dev_attr_hostname.attr,
> + &dev_attr_alive.attr,
> + NULL
> +};
> +
> +static struct attribute_group cbd_host_attr_group = {
> + .attrs = cbd_host_attrs,
> +};
> +
> +static const struct attribute_group *cbd_host_attr_groups[] = {
> + &cbd_host_attr_group,
> + NULL
> +};
> +
> +static void cbd_host_release(struct device *dev) { }
> +
> +struct device_type cbd_host_type = {
> + .name = "cbd_host",
> + .groups = cbd_host_attr_groups,
> + .release = cbd_host_release,
> +};
> +
> +struct device_type cbd_hosts_type = {
> + .name = "cbd_hosts",
> + .release = cbd_host_release,
> +};
> +
> +int cbd_host_register(struct cbd_transport *cbdt, char *hostname) {
> + struct cbd_host *host;
> + struct cbd_host_info *host_info;
> + u32 host_id;
> + int ret;
> +
> + if (cbdt->host) {
> + return -EEXIST;
> + }
> +
> + if (strlen(hostname) == 0) {
> + return -EINVAL;
> + }

Un-necessary braces

Thanks
-Bharat

> +
> + ret = cbdt_get_empty_host_id(cbdt, &host_id);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + host = kzalloc(sizeof(struct cbd_host), GFP_KERNEL);
> + if (!host) {
> + return -ENOMEM;
> + }
> +
> + host->host_id = host_id;
> + host->cbdt = cbdt;
> + INIT_DELAYED_WORK(&host->hb_work, host_hb_workfn);
> +
> + host_info = cbdt_get_host_info(cbdt, host_id);
> + host_info->state = cbd_host_state_running;
> + memcpy(host_info->hostname, hostname, CBD_NAME_LEN);
> +
> + cbdt_flush_range(cbdt, host_info, sizeof(*host_info));
> +
> + host->host_info = host_info;
> + cbdt->host = host;
> +
> + queue_delayed_work(cbd_wq, &host->hb_work, 0);
> +
> + return 0;
> +}
> +
> +int cbd_host_unregister(struct cbd_transport *cbdt) {
> + struct cbd_host *host = cbdt->host;
> + struct cbd_host_info *host_info;
> +
> + if (!host) {
> + cbd_err("This host is not registered.");
> + return 0;
> + }
> +
> + cancel_delayed_work_sync(&host->hb_work);
> + host_info = host->host_info;
> + memset(host_info->hostname, 0, CBD_NAME_LEN);
> + host_info->alive_ts = 0;
> + host_info->state = cbd_host_state_none;
> +
> + cbdt_flush_range(cbdt, host_info, sizeof(*host_info));
> +
> + cbdt->host = NULL;
> + kfree(cbdt->host);
> +
> + return 0;
> +}
> diff --git a/drivers/block/cbd/cbd_transport.c
> b/drivers/block/cbd/cbd_transport.c
> index 3a4887afab08..682d0f45ce9e 100644
> --- a/drivers/block/cbd/cbd_transport.c
> +++ b/drivers/block/cbd/cbd_transport.c
> @@ -571,6 +571,7 @@ int cbdt_unregister(u32 tid)
> }
> mutex_unlock(&cbdt->lock);
>
> + cbd_host_unregister(cbdt);
> device_unregister(&cbdt->device);
> cbdt_dax_release(cbdt);
> cbdt_destroy(cbdt);
> @@ -624,8 +625,15 @@ int cbdt_register(struct cbdt_register_options
> *opts)
> goto dax_release;
> }
>
> + ret = cbd_host_register(cbdt, opts->hostname);
> + if (ret) {
> + goto dev_unregister;
> + }
> +
> return 0;
>
> +devs_exit:
> + cbd_host_unregister(cbdt);
> dev_unregister:
> device_unregister(&cbdt->device);
> dax_release:
> --
> 2.34.1
>