Commit 50d0b1ad authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner

drbd: Remove some fixed header size assumptions

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent da39fec4
...@@ -543,19 +543,10 @@ struct p_delay_probe93 { ...@@ -543,19 +543,10 @@ struct p_delay_probe93 {
u32 offset; /* usecs the probe got sent after the reference time point */ u32 offset; /* usecs the probe got sent after the reference time point */
} __packed; } __packed;
/* one bitmap packet, including the p_header, /*
* should fit within one _architecture independend_ page. * Bitmap packets need to fit within a single page on the sender and receiver,
* so we need to use the fixed size 4KiB page size * so we are limited to 4 KiB (and not to PAGE_SIZE, which can be bigger).
* most architectures have used for a long time.
*/ */
#define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header))
#define BM_PACKET_WORDS (BM_PACKET_PAYLOAD_BYTES/sizeof(long))
#define BM_PACKET_VLI_BYTES_MAX (4096 - sizeof(struct p_compressed_bm))
#if (PAGE_SIZE < 4096)
/* drbd_send_bitmap / receive_bitmap would break horribly */
#error "PAGE_SIZE too small"
#endif
#define DRBD_SOCKET_BUFFER_SIZE 4096 #define DRBD_SOCKET_BUFFER_SIZE 4096
/**********************************************************************/ /**********************************************************************/
......
...@@ -1100,8 +1100,9 @@ static void dcbp_set_pad_bits(struct p_compressed_bm *p, int n) ...@@ -1100,8 +1100,9 @@ static void dcbp_set_pad_bits(struct p_compressed_bm *p, int n)
} }
int fill_bitmap_rle_bits(struct drbd_conf *mdev, int fill_bitmap_rle_bits(struct drbd_conf *mdev,
struct p_compressed_bm *p, struct p_compressed_bm *p,
struct bm_xfer_ctx *c) unsigned int size,
struct bm_xfer_ctx *c)
{ {
struct bitstream bs; struct bitstream bs;
unsigned long plain_bits; unsigned long plain_bits;
...@@ -1120,8 +1121,8 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev, ...@@ -1120,8 +1121,8 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
return 0; /* nothing to do. */ return 0; /* nothing to do. */
/* use at most thus many bytes */ /* use at most thus many bytes */
bitstream_init(&bs, p->code, BM_PACKET_VLI_BYTES_MAX, 0); bitstream_init(&bs, p->code, size, 0);
memset(p->code, 0, BM_PACKET_VLI_BYTES_MAX); memset(p->code, 0, size);
/* plain bits covered in this code string */ /* plain bits covered in this code string */
plain_bits = 0; plain_bits = 0;
...@@ -1203,11 +1204,11 @@ static int ...@@ -1203,11 +1204,11 @@ static int
send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
{ {
struct drbd_socket *sock = &mdev->tconn->data; struct drbd_socket *sock = &mdev->tconn->data;
unsigned int header_size = drbd_header_size(mdev->tconn);
struct p_compressed_bm *p = sock->sbuf; struct p_compressed_bm *p = sock->sbuf;
unsigned long num_words;
int len, err; int len, err;
len = fill_bitmap_rle_bits(mdev, p, c); len = fill_bitmap_rle_bits(mdev, p, DRBD_SOCKET_BUFFER_SIZE - sizeof(*p) /* FIXME */, c);
if (len < 0) if (len < 0)
return -EIO; return -EIO;
...@@ -1224,9 +1225,14 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) ...@@ -1224,9 +1225,14 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
} else { } else {
/* was not compressible. /* was not compressible.
* send a buffer full of plain text bits instead. */ * send a buffer full of plain text bits instead. */
unsigned int data_size;
unsigned long num_words;
struct p_header *h = sock->sbuf; struct p_header *h = sock->sbuf;
num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
len = num_words * sizeof(long); data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
num_words = min_t(size_t, data_size / sizeof(unsigned long),
c->bm_words - c->word_offset);
len = num_words * sizeof(unsigned long);
if (len) if (len)
drbd_bm_get_lel(mdev, c->word_offset, num_words, drbd_bm_get_lel(mdev, c->word_offset, num_words,
(unsigned long *)h->payload); (unsigned long *)h->payload);
...@@ -1236,7 +1242,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) ...@@ -1236,7 +1242,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
c->bit_offset = c->word_offset * BITS_PER_LONG; c->bit_offset = c->word_offset * BITS_PER_LONG;
c->packets[1]++; c->packets[1]++;
c->bytes[1] += sizeof(struct p_header80) + len; c->bytes[1] += header_size + len;
if (c->bit_offset > c->bm_bits) if (c->bit_offset > c->bm_bits)
c->bit_offset = c->bm_bits; c->bit_offset = c->bm_bits;
...@@ -2550,7 +2556,6 @@ int __init drbd_init(void) ...@@ -2550,7 +2556,6 @@ int __init drbd_init(void)
{ {
int err; int err;
BUILD_BUG_ON(sizeof(struct p_header80) != sizeof(struct p_header95));
BUILD_BUG_ON(sizeof(struct p_connection_features) != 80); BUILD_BUG_ON(sizeof(struct p_connection_features) != 80);
if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) { if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
......
...@@ -3660,16 +3660,19 @@ static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi) ...@@ -3660,16 +3660,19 @@ static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
* code upon failure. * code upon failure.
*/ */
static int static int
receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size, receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size,
struct p_header *h, struct bm_xfer_ctx *c) struct p_header *h, struct bm_xfer_ctx *c)
{ {
unsigned long *buffer = (unsigned long *)h->payload; unsigned long *buffer = (unsigned long *)h->payload;
unsigned num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset); unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
unsigned want = num_words * sizeof(long); drbd_header_size(mdev->tconn);
unsigned int num_words = min_t(size_t, data_size / sizeof(unsigned long),
c->bm_words - c->word_offset);
unsigned int want = num_words * sizeof(unsigned long);
int err; int err;
if (want != data_size) { if (want != size) {
dev_err(DEV, "%s:want (%u) != data_size (%u)\n", __func__, want, data_size); dev_err(DEV, "%s:want (%u) != size (%u)\n", __func__, want, size);
return -EIO; return -EIO;
} }
if (want == 0) if (want == 0)
...@@ -3796,11 +3799,13 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev, ...@@ -3796,11 +3799,13 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
const char *direction, struct bm_xfer_ctx *c) const char *direction, struct bm_xfer_ctx *c)
{ {
/* what would it take to transfer it "plaintext" */ /* what would it take to transfer it "plaintext" */
unsigned plain = sizeof(struct p_header) * unsigned int header_size = drbd_header_size(mdev->tconn);
((c->bm_words+BM_PACKET_WORDS-1)/BM_PACKET_WORDS+1) unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
+ c->bm_words * sizeof(long); unsigned int plain =
unsigned total = c->bytes[0] + c->bytes[1]; header_size * (DIV_ROUND_UP(c->bm_words, data_size) + 1) +
unsigned r; c->bm_words * sizeof(unsigned long);
unsigned int total = c->bytes[0] + c->bytes[1];
unsigned int r;
/* total can not be zero. but just in case: */ /* total can not be zero. but just in case: */
if (total == 0) if (total == 0)
...@@ -3862,7 +3867,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi) ...@@ -3862,7 +3867,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
* and the feature is enabled! */ * and the feature is enabled! */
struct p_compressed_bm *p; struct p_compressed_bm *p;
if (pi->size > BM_PACKET_PAYLOAD_BYTES) { if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(tconn)) {
dev_err(DEV, "ReportCBitmap packet too large\n"); dev_err(DEV, "ReportCBitmap packet too large\n");
err = -EIO; err = -EIO;
goto out; goto out;
...@@ -3885,7 +3890,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi) ...@@ -3885,7 +3890,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
} }
c.packets[pi->cmd == P_BITMAP]++; c.packets[pi->cmd == P_BITMAP]++;
c.bytes[pi->cmd == P_BITMAP] += sizeof(struct p_header) + pi->size; c.bytes[pi->cmd == P_BITMAP] += drbd_header_size(tconn) + pi->size;
if (err <= 0) { if (err <= 0) {
if (err < 0) if (err < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment