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

drbd: Remove some fixed header size assumptions

parent da39fec4
Loading
Loading
Loading
Loading
+3 −12
Original line number Diff line number Diff line
@@ -543,19 +543,10 @@ struct p_delay_probe93 {
	u32     offset;  /* usecs the probe got sent after the reference time point */
} __packed;

/* one bitmap packet, including the p_header,
 * should fit within one _architecture independend_ page.
 * so we need to use the fixed size 4KiB page size
 * most architectures have used for a long time.
/*
 * Bitmap packets need to fit within a single page on the sender and receiver,
 * so we are limited to 4 KiB (and not to PAGE_SIZE, which can be bigger).
 */
#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

/**********************************************************************/
+15 −10
Original line number Diff line number Diff line
@@ -1101,6 +1101,7 @@ static void dcbp_set_pad_bits(struct p_compressed_bm *p, int n)

int fill_bitmap_rle_bits(struct drbd_conf *mdev,
			 struct p_compressed_bm *p,
			 unsigned int size,
			 struct bm_xfer_ctx *c)
{
	struct bitstream bs;
@@ -1120,8 +1121,8 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
		return 0; /* nothing to do. */

	/* use at most thus many bytes */
	bitstream_init(&bs, p->code, BM_PACKET_VLI_BYTES_MAX, 0);
	memset(p->code, 0, BM_PACKET_VLI_BYTES_MAX);
	bitstream_init(&bs, p->code, size, 0);
	memset(p->code, 0, size);
	/* plain bits covered in this code string */
	plain_bits = 0;

@@ -1203,11 +1204,11 @@ static int
send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
{
	struct drbd_socket *sock = &mdev->tconn->data;
	unsigned int header_size = drbd_header_size(mdev->tconn);
	struct p_compressed_bm *p = sock->sbuf;
	unsigned long num_words;
	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)
		return -EIO;

@@ -1224,9 +1225,14 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
	} else {
		/* was not compressible.
		 * send a buffer full of plain text bits instead. */
		unsigned int data_size;
		unsigned long num_words;
		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)
			drbd_bm_get_lel(mdev, c->word_offset, num_words,
					(unsigned long *)h->payload);
@@ -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->packets[1]++;
		c->bytes[1] += sizeof(struct p_header80) + len;
		c->bytes[1] += header_size + len;

		if (c->bit_offset > c->bm_bits)
			c->bit_offset = c->bm_bits;
@@ -2550,7 +2556,6 @@ int __init drbd_init(void)
{
	int err;

	BUILD_BUG_ON(sizeof(struct p_header80) != sizeof(struct p_header95));
	BUILD_BUG_ON(sizeof(struct p_connection_features) != 80);

	if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
+17 −12
Original line number Diff line number Diff line
@@ -3660,16 +3660,19 @@ static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
 * code upon failure.
 */
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)
{
	unsigned long *buffer = (unsigned long *)h->payload;
	unsigned num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
	unsigned want = num_words * sizeof(long);
	unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
				 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;

	if (want != data_size) {
		dev_err(DEV, "%s:want (%u) != data_size (%u)\n", __func__, want, data_size);
	if (want != size) {
		dev_err(DEV, "%s:want (%u) != size (%u)\n", __func__, want, size);
		return -EIO;
	}
	if (want == 0)
@@ -3796,11 +3799,13 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
		const char *direction, struct bm_xfer_ctx *c)
{
	/* what would it take to transfer it "plaintext" */
	unsigned plain = sizeof(struct p_header) *
		((c->bm_words+BM_PACKET_WORDS-1)/BM_PACKET_WORDS+1)
		+ c->bm_words * sizeof(long);
	unsigned total = c->bytes[0] + c->bytes[1];
	unsigned r;
	unsigned int header_size = drbd_header_size(mdev->tconn);
	unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
	unsigned int plain =
		header_size * (DIV_ROUND_UP(c->bm_words, data_size) + 1) +
		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: */
	if (total == 0)
@@ -3862,7 +3867,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
			 * and the feature is enabled! */
			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");
				err = -EIO;
				goto out;
@@ -3885,7 +3890,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
		}

		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)