[v3,12/15] rbd: introduce rbd_journal_allocate_tag to allocate journal tag for rbd client
diff mbox series

Message ID 1564393377-28949-13-git-send-email-dongsheng.yang@easystack.cn
State New
Headers show
Series
  • rbd journaling feature
Related show

Commit Message

Dongsheng Yang July 29, 2019, 9:42 a.m. UTC
rbd_journal_allocate_tag() get the client by client id and allocate an uniq tag
for this client.

All journal events from this client will be tagged by this tag.

Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
---
 drivers/block/rbd.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

Comments

Ilya Dryomov Aug. 19, 2019, 10:37 a.m. UTC | #1
On Mon, Jul 29, 2019 at 11:43 AM Dongsheng Yang
<dongsheng.yang@easystack.cn> wrote:
>
> rbd_journal_allocate_tag() get the client by client id and allocate an uniq tag
> for this client.
>
> All journal events from this client will be tagged by this tag.
>
> Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
> ---
>  drivers/block/rbd.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 112 insertions(+)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 337a20f..86008f2 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -28,16 +28,19 @@
>
>   */
>
> +#include <linux/crc32c.h>

What is this include for?

>  #include <linux/ceph/libceph.h>
>  #include <linux/ceph/osd_client.h>
>  #include <linux/ceph/mon_client.h>
>  #include <linux/ceph/cls_lock_client.h>
>  #include <linux/ceph/striper.h>
>  #include <linux/ceph/decode.h>
> +#include <linux/ceph/journaler.h>
>  #include <linux/parser.h>
>  #include <linux/bsearch.h>
>
>  #include <linux/kernel.h>
> +#include <linux/bio.h>

Same here.

>  #include <linux/device.h>
>  #include <linux/module.h>
>  #include <linux/blk-mq.h>
> @@ -470,6 +473,14 @@ enum rbd_dev_flags {
>         RBD_DEV_FLAG_REMOVING,  /* this mapping is being removed */
>  };
>
> +#define        LOCAL_MIRROR_UUID       ""
> +#define        LOCAL_CLIENT_ID         ""
> +
> +struct rbd_journal {
> +       struct ceph_journaler *journaler;
> +       uint64_t                tag_tid;
> +};

I think these two fields can be embedded into struct rbd_device
directly.

> +
>  static DEFINE_MUTEX(client_mutex);     /* Serialize client creation */
>
>  static LIST_HEAD(rbd_dev_list);    /* devices */
> @@ -6916,6 +6927,107 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev)
>         return ret;
>  }
>
> +typedef struct rbd_journal_tag_predecessor {
> +       bool commit_valid;
> +       uint64_t tag_tid;
> +       uint64_t entry_tid;
> +       uint32_t uuid_len;
> +       char *mirror_uuid;
> +} rbd_journal_tag_predecessor;
> +
> +typedef struct rbd_journal_tag_data {
> +       struct rbd_journal_tag_predecessor predecessor;
> +       uint32_t uuid_len;
> +       char *mirror_uuid;
> +} rbd_journal_tag_data;

Why typedef these structs?

> +
> +static uint32_t tag_data_encoding_size(struct rbd_journal_tag_data *tag_data)
> +{
> +       // sizeof(uuid_len) 4 + uuid_len + 1 commit_valid + 8 tag_tid +
> +       // 8 entry_tid + 4 sizeof(uuid_len) + uuid_len
> +       return (4 + tag_data->uuid_len + 1 + 8 + 8 + 4 +
> +               tag_data->predecessor.uuid_len);
> +}
> +
> +static void predecessor_encode(void **p, void *end,
> +                              struct rbd_journal_tag_predecessor *predecessor)
> +{
> +       ceph_encode_string(p, end, predecessor->mirror_uuid,
> +                          predecessor->uuid_len);
> +       ceph_encode_8(p, predecessor->commit_valid);
> +       ceph_encode_64(p, predecessor->tag_tid);
> +       ceph_encode_64(p, predecessor->entry_tid);
> +}
> +
> +static int rbd_journal_encode_tag_data(void **p, void *end,
> +                                      struct rbd_journal_tag_data *tag_data)
> +{
> +       struct rbd_journal_tag_predecessor *predecessor = &tag_data->predecessor;
> +
> +       ceph_encode_string(p, end, tag_data->mirror_uuid, tag_data->uuid_len);
> +       predecessor_encode(p, end, predecessor);
> +
> +       return 0;
> +}
> +
> +static int rbd_journal_allocate_tag(struct rbd_journal *journal)
> +{
> +       struct ceph_journaler_tag tag = {};
> +       struct rbd_journal_tag_data tag_data = {};
> +       struct ceph_journaler *journaler = journal->journaler;
> +       struct ceph_journaler_client *client;
> +       struct rbd_journal_tag_predecessor *predecessor;
> +       struct ceph_journaler_object_pos *position;
> +       void *orig_buf, *buf, *p, *end;
> +       uint32_t buf_len;
> +       int ret;
> +
> +       ret = ceph_journaler_get_cached_client(journaler, LOCAL_CLIENT_ID, &client);
> +       if (ret)
> +               goto out;
> +
> +       position = list_first_entry(&client->object_positions,
> +                                   struct ceph_journaler_object_pos, node);
> +
> +       predecessor = &tag_data.predecessor;
> +       predecessor->commit_valid = true;
> +       predecessor->tag_tid = position->tag_tid;
> +       predecessor->entry_tid = position->entry_tid;
> +       predecessor->uuid_len = 0;
> +       predecessor->mirror_uuid = LOCAL_MIRROR_UUID;
> +
> +       tag_data.uuid_len = 0;
> +       tag_data.mirror_uuid = LOCAL_MIRROR_UUID;

If ->mirror_uuid is always "" (and ->uuid_len is always 0), drop them
and encode 0 directly instead of using ceph_encode_string().

Thanks,

                Ilya
Dongsheng Yang Aug. 26, 2019, 3:04 a.m. UTC | #2
On 08/19/2019 06:37 PM, Ilya Dryomov wrote:
> On Mon, Jul 29, 2019 at 11:43 AM Dongsheng Yang
> <dongsheng.yang@easystack.cn> wrote:
>> rbd_journal_allocate_tag() get the client by client id and allocate an uniq tag
>> for this client.
>>
>> All journal events from this client will be tagged by this tag.
>>
>> Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
>> ---
>>   drivers/block/rbd.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 112 insertions(+)
>>
>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>> index 337a20f..86008f2 100644
>> --- a/drivers/block/rbd.c
>> +++ b/drivers/block/rbd.c
>> @@ -28,16 +28,19 @@
>>
>>    */
>>
>> +#include <linux/crc32c.h>
> What is this include for?
>
>>   #include <linux/ceph/libceph.h>
>>   #include <linux/ceph/osd_client.h>
>>   #include <linux/ceph/mon_client.h>
>>   #include <linux/ceph/cls_lock_client.h>
>>   #include <linux/ceph/striper.h>
>>   #include <linux/ceph/decode.h>
>> +#include <linux/ceph/journaler.h>
>>   #include <linux/parser.h>
>>   #include <linux/bsearch.h>
>>
>>   #include <linux/kernel.h>
>> +#include <linux/bio.h>
> Same here.

These include is not necessary for this patch, I will move them later.
>
>>   #include <linux/device.h>
>>   #include <linux/module.h>
>>   #include <linux/blk-mq.h>
>> @@ -470,6 +473,14 @@ enum rbd_dev_flags {
>>          RBD_DEV_FLAG_REMOVING,  /* this mapping is being removed */
>>   };
>>
>> +#define        LOCAL_MIRROR_UUID       ""
>> +#define        LOCAL_CLIENT_ID         ""
>> +
>> +struct rbd_journal {
>> +       struct ceph_journaler *journaler;
>> +       uint64_t                tag_tid;
>> +};
> I think these two fields can be embedded into struct rbd_device
> directly.


>
>> +
>>   static DEFINE_MUTEX(client_mutex);     /* Serialize client creation */
>>
>>   static LIST_HEAD(rbd_dev_list);    /* devices */
>> @@ -6916,6 +6927,107 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev)
>>          return ret;
>>   }
>>
>> +typedef struct rbd_journal_tag_predecessor {
>> +       bool commit_valid;
>> +       uint64_t tag_tid;
>> +       uint64_t entry_tid;
>> +       uint32_t uuid_len;
>> +       char *mirror_uuid;
>> +} rbd_journal_tag_predecessor;
>> +
>> +typedef struct rbd_journal_tag_data {
>> +       struct rbd_journal_tag_predecessor predecessor;
>> +       uint32_t uuid_len;
>> +       char *mirror_uuid;
>> +} rbd_journal_tag_data;
> Why typedef these structs?

There was a reference to same struct when introduce them. But now this 
typedef looks
not necessary.
>
>> +
>> +static uint32_t tag_data_encoding_size(struct rbd_journal_tag_data *tag_data)
>> +{
>> +       // sizeof(uuid_len) 4 + uuid_len + 1 commit_valid + 8 tag_tid +
>> +       // 8 entry_tid + 4 sizeof(uuid_len) + uuid_len
>> +       return (4 + tag_data->uuid_len + 1 + 8 + 8 + 4 +
>> +               tag_data->predecessor.uuid_len);
>> +}
>> +
>> +static void predecessor_encode(void **p, void *end,
>> +                              struct rbd_journal_tag_predecessor *predecessor)
>> +{
>> +       ceph_encode_string(p, end, predecessor->mirror_uuid,
>> +                          predecessor->uuid_len);
>> +       ceph_encode_8(p, predecessor->commit_valid);
>> +       ceph_encode_64(p, predecessor->tag_tid);
>> +       ceph_encode_64(p, predecessor->entry_tid);
>> +}
>> +
>> +static int rbd_journal_encode_tag_data(void **p, void *end,
>> +                                      struct rbd_journal_tag_data *tag_data)
>> +{
>> +       struct rbd_journal_tag_predecessor *predecessor = &tag_data->predecessor;
>> +
>> +       ceph_encode_string(p, end, tag_data->mirror_uuid, tag_data->uuid_len);
>> +       predecessor_encode(p, end, predecessor);
>> +
>> +       return 0;
>> +}
>> +
>> +static int rbd_journal_allocate_tag(struct rbd_journal *journal)
>> +{
>> +       struct ceph_journaler_tag tag = {};
>> +       struct rbd_journal_tag_data tag_data = {};
>> +       struct ceph_journaler *journaler = journal->journaler;
>> +       struct ceph_journaler_client *client;
>> +       struct rbd_journal_tag_predecessor *predecessor;
>> +       struct ceph_journaler_object_pos *position;
>> +       void *orig_buf, *buf, *p, *end;
>> +       uint32_t buf_len;
>> +       int ret;
>> +
>> +       ret = ceph_journaler_get_cached_client(journaler, LOCAL_CLIENT_ID, &client);
>> +       if (ret)
>> +               goto out;
>> +
>> +       position = list_first_entry(&client->object_positions,
>> +                                   struct ceph_journaler_object_pos, node);
>> +
>> +       predecessor = &tag_data.predecessor;
>> +       predecessor->commit_valid = true;
>> +       predecessor->tag_tid = position->tag_tid;
>> +       predecessor->entry_tid = position->entry_tid;
>> +       predecessor->uuid_len = 0;
>> +       predecessor->mirror_uuid = LOCAL_MIRROR_UUID;
>> +
>> +       tag_data.uuid_len = 0;
>> +       tag_data.mirror_uuid = LOCAL_MIRROR_UUID;
> If ->mirror_uuid is always "" (and ->uuid_len is always 0), drop them
> and encode 0 directly instead of using ceph_encode_string().

I use these name to represent the meaning for each encoding. But I am
am okey to drop them and add a comment here.

Thanx
>
> Thanks,
>
>                  Ilya
>

Patch
diff mbox series

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 337a20f..86008f2 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -28,16 +28,19 @@ 
 
  */
 
+#include <linux/crc32c.h>
 #include <linux/ceph/libceph.h>
 #include <linux/ceph/osd_client.h>
 #include <linux/ceph/mon_client.h>
 #include <linux/ceph/cls_lock_client.h>
 #include <linux/ceph/striper.h>
 #include <linux/ceph/decode.h>
+#include <linux/ceph/journaler.h>
 #include <linux/parser.h>
 #include <linux/bsearch.h>
 
 #include <linux/kernel.h>
+#include <linux/bio.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/blk-mq.h>
@@ -470,6 +473,14 @@  enum rbd_dev_flags {
 	RBD_DEV_FLAG_REMOVING,	/* this mapping is being removed */
 };
 
+#define	LOCAL_MIRROR_UUID	""
+#define	LOCAL_CLIENT_ID		""
+
+struct rbd_journal {
+	struct ceph_journaler *journaler;
+	uint64_t		tag_tid;
+};
+
 static DEFINE_MUTEX(client_mutex);	/* Serialize client creation */
 
 static LIST_HEAD(rbd_dev_list);    /* devices */
@@ -6916,6 +6927,107 @@  static int rbd_dev_header_name(struct rbd_device *rbd_dev)
 	return ret;
 }
 
+typedef struct rbd_journal_tag_predecessor {
+	bool commit_valid;
+	uint64_t tag_tid;
+	uint64_t entry_tid;
+	uint32_t uuid_len;
+	char *mirror_uuid;
+} rbd_journal_tag_predecessor;
+
+typedef struct rbd_journal_tag_data {
+	struct rbd_journal_tag_predecessor predecessor;
+	uint32_t uuid_len;
+	char *mirror_uuid;
+} rbd_journal_tag_data;
+
+static uint32_t tag_data_encoding_size(struct rbd_journal_tag_data *tag_data)
+{
+	// sizeof(uuid_len) 4 + uuid_len + 1 commit_valid + 8 tag_tid +
+	// 8 entry_tid + 4 sizeof(uuid_len) + uuid_len
+	return (4 + tag_data->uuid_len + 1 + 8 + 8 + 4 +
+		tag_data->predecessor.uuid_len);
+}
+
+static void predecessor_encode(void **p, void *end,
+			       struct rbd_journal_tag_predecessor *predecessor)
+{
+	ceph_encode_string(p, end, predecessor->mirror_uuid,
+			   predecessor->uuid_len);
+	ceph_encode_8(p, predecessor->commit_valid);
+	ceph_encode_64(p, predecessor->tag_tid);
+	ceph_encode_64(p, predecessor->entry_tid);
+}
+
+static int rbd_journal_encode_tag_data(void **p, void *end,
+				       struct rbd_journal_tag_data *tag_data)
+{
+	struct rbd_journal_tag_predecessor *predecessor = &tag_data->predecessor;
+
+	ceph_encode_string(p, end, tag_data->mirror_uuid, tag_data->uuid_len);
+	predecessor_encode(p, end, predecessor);
+
+	return 0;
+}
+
+static int rbd_journal_allocate_tag(struct rbd_journal *journal)
+{
+	struct ceph_journaler_tag tag = {};
+	struct rbd_journal_tag_data tag_data = {};
+	struct ceph_journaler *journaler = journal->journaler;
+	struct ceph_journaler_client *client;
+	struct rbd_journal_tag_predecessor *predecessor;
+	struct ceph_journaler_object_pos *position;
+	void *orig_buf, *buf, *p, *end;
+	uint32_t buf_len;
+	int ret;
+
+	ret = ceph_journaler_get_cached_client(journaler, LOCAL_CLIENT_ID, &client);
+	if (ret)
+		goto out;
+
+	position = list_first_entry(&client->object_positions,
+				    struct ceph_journaler_object_pos, node);
+
+	predecessor = &tag_data.predecessor;
+	predecessor->commit_valid = true;
+	predecessor->tag_tid = position->tag_tid;
+	predecessor->entry_tid = position->entry_tid;
+	predecessor->uuid_len = 0;
+	predecessor->mirror_uuid = LOCAL_MIRROR_UUID;
+
+	tag_data.uuid_len = 0;
+	tag_data.mirror_uuid = LOCAL_MIRROR_UUID;
+
+	buf_len = tag_data_encoding_size(&tag_data);
+	p = kmalloc(buf_len, GFP_KERNEL);
+	if (!p) {
+		pr_err("failed to allocate tag data");
+		return -ENOMEM;
+	}
+
+	end = p + buf_len;
+	orig_buf = buf = p;
+	ret = rbd_journal_encode_tag_data(&p, end, &tag_data);
+	if (ret) {
+		pr_err("error in tag data");
+		goto free_buf;
+	}
+
+	ret = ceph_journaler_allocate_tag(journaler, 0, buf, buf_len, &tag);
+	if (ret)
+		goto free_data;
+
+	journal->tag_tid = tag.tid;
+free_data:
+	if(tag.data)
+		kfree(tag.data);
+free_buf:
+	kfree(orig_buf);
+out:
+	return ret;
+}
+
 static void rbd_dev_image_release(struct rbd_device *rbd_dev)
 {
 	rbd_dev_unprobe(rbd_dev);