Simplified distributed block storage with strong consistency, like in Ceph
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

176 lines
4.1 KiB

  1. // Copyright (c) Vitaliy Filippov, 2019+
  2. // License: VNPL-1.1 or GNU GPL-2.0+ (see README.md for details)
  3. #pragma once
  4. #include <sys/uio.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include "osd_ops.h"
  10. #define OSD_OP_IN 0
  11. #define OSD_OP_OUT 1
  12. #define OSD_OP_INLINE_BUF_COUNT 16
  13. // Kind of a vector with small-list-optimisation
  14. struct osd_op_buf_list_t
  15. {
  16. int count = 0, alloc = OSD_OP_INLINE_BUF_COUNT, done = 0;
  17. iovec *buf = NULL;
  18. iovec inline_buf[OSD_OP_INLINE_BUF_COUNT];
  19. inline osd_op_buf_list_t()
  20. {
  21. buf = inline_buf;
  22. }
  23. inline osd_op_buf_list_t(const osd_op_buf_list_t & other)
  24. {
  25. buf = inline_buf;
  26. append(other);
  27. }
  28. inline osd_op_buf_list_t & operator = (const osd_op_buf_list_t & other)
  29. {
  30. reset();
  31. append(other);
  32. return *this;
  33. }
  34. inline ~osd_op_buf_list_t()
  35. {
  36. if (buf && buf != inline_buf)
  37. {
  38. free(buf);
  39. }
  40. }
  41. inline void reset()
  42. {
  43. count = 0;
  44. done = 0;
  45. }
  46. inline iovec* get_iovec()
  47. {
  48. return buf + done;
  49. }
  50. inline int get_size()
  51. {
  52. return count - done;
  53. }
  54. inline void append(const osd_op_buf_list_t & other)
  55. {
  56. if (count+other.count > alloc)
  57. {
  58. if (buf == inline_buf)
  59. {
  60. int old = alloc;
  61. alloc = (((count+other.count+15)/16)*16);
  62. buf = (iovec*)malloc(sizeof(iovec) * alloc);
  63. if (!buf)
  64. {
  65. fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
  66. exit(1);
  67. }
  68. memcpy(buf, inline_buf, sizeof(iovec) * old);
  69. }
  70. else
  71. {
  72. alloc = (((count+other.count+15)/16)*16);
  73. buf = (iovec*)realloc(buf, sizeof(iovec) * alloc);
  74. if (!buf)
  75. {
  76. fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
  77. exit(1);
  78. }
  79. }
  80. }
  81. for (int i = 0; i < other.count; i++)
  82. {
  83. buf[count++] = other.buf[i];
  84. }
  85. }
  86. inline void push_back(void *nbuf, size_t len)
  87. {
  88. if (count >= alloc)
  89. {
  90. if (buf == inline_buf)
  91. {
  92. int old = alloc;
  93. alloc = ((alloc/16)*16 + 1);
  94. buf = (iovec*)malloc(sizeof(iovec) * alloc);
  95. if (!buf)
  96. {
  97. fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
  98. exit(1);
  99. }
  100. memcpy(buf, inline_buf, sizeof(iovec)*old);
  101. }
  102. else
  103. {
  104. alloc = alloc < 16 ? 16 : (alloc+16);
  105. buf = (iovec*)realloc(buf, sizeof(iovec) * alloc);
  106. if (!buf)
  107. {
  108. fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
  109. exit(1);
  110. }
  111. }
  112. }
  113. buf[count++] = { .iov_base = nbuf, .iov_len = len };
  114. }
  115. inline void eat(int result)
  116. {
  117. while (result > 0 && done < count)
  118. {
  119. iovec & iov = buf[done];
  120. if (iov.iov_len <= result)
  121. {
  122. result -= iov.iov_len;
  123. done++;
  124. }
  125. else
  126. {
  127. iov.iov_len -= result;
  128. iov.iov_base += result;
  129. break;
  130. }
  131. }
  132. }
  133. };
  134. struct blockstore_op_t;
  135. struct osd_primary_op_data_t;
  136. struct osd_op_t
  137. {
  138. timespec tv_begin = { 0 }, tv_end = { 0 };
  139. uint64_t op_type = OSD_OP_IN;
  140. int peer_fd;
  141. osd_any_op_t req;
  142. osd_any_reply_t reply;
  143. blockstore_op_t *bs_op = NULL;
  144. void *buf = NULL;
  145. // bitmap, bitmap_len, bmp_data are only meaningful for reads
  146. void *bitmap = NULL;
  147. unsigned bitmap_len = 0;
  148. unsigned bmp_data = 0;
  149. void *rmw_buf = NULL;
  150. osd_primary_op_data_t* op_data = NULL;
  151. std::function<void(osd_op_t*)> callback;
  152. osd_op_buf_list_t iov;
  153. ~osd_op_t();
  154. };