aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-03-30 05:53:51 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:45:09 -0500
commit50d0b1ad78b99aa776c3ddf9b1d45163fff435b9 (patch)
tree3f7d43397a0e3b049430907919b12bd3786330e2 /drivers/block/drbd
parentda39fec49286d6b44bf441c9707dda2764b4498a (diff)
drbd: Remove some fixed header size assumptions
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r--drivers/block/drbd/drbd_int.h15
-rw-r--r--drivers/block/drbd/drbd_main.c25
-rw-r--r--drivers/block/drbd/drbd_receiver.c29
3 files changed, 35 insertions, 34 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ccc374cc7eaa..cb16783e78df 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -543,19 +543,10 @@ struct p_delay_probe93 {
543 u32 offset; /* usecs the probe got sent after the reference time point */ 543 u32 offset; /* usecs the probe got sent after the reference time point */
544} __packed; 544} __packed;
545 545
546/* one bitmap packet, including the p_header, 546/*
547 * should fit within one _architecture independend_ page. 547 * Bitmap packets need to fit within a single page on the sender and receiver,
548 * so we need to use the fixed size 4KiB page size 548 * so we are limited to 4 KiB (and not to PAGE_SIZE, which can be bigger).
549 * most architectures have used for a long time.
550 */ 549 */
551#define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header))
552#define BM_PACKET_WORDS (BM_PACKET_PAYLOAD_BYTES/sizeof(long))
553#define BM_PACKET_VLI_BYTES_MAX (4096 - sizeof(struct p_compressed_bm))
554#if (PAGE_SIZE < 4096)
555/* drbd_send_bitmap / receive_bitmap would break horribly */
556#error "PAGE_SIZE too small"
557#endif
558
559#define DRBD_SOCKET_BUFFER_SIZE 4096 550#define DRBD_SOCKET_BUFFER_SIZE 4096
560 551
561/**********************************************************************/ 552/**********************************************************************/
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e3dc84dcd67e..3ecbd4908cdc 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1100,8 +1100,9 @@ static void dcbp_set_pad_bits(struct p_compressed_bm *p, int n)
1100} 1100}
1101 1101
1102int fill_bitmap_rle_bits(struct drbd_conf *mdev, 1102int fill_bitmap_rle_bits(struct drbd_conf *mdev,
1103 struct p_compressed_bm *p, 1103 struct p_compressed_bm *p,
1104 struct bm_xfer_ctx *c) 1104 unsigned int size,
1105 struct bm_xfer_ctx *c)
1105{ 1106{
1106 struct bitstream bs; 1107 struct bitstream bs;
1107 unsigned long plain_bits; 1108 unsigned long plain_bits;
@@ -1120,8 +1121,8 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
1120 return 0; /* nothing to do. */ 1121 return 0; /* nothing to do. */
1121 1122
1122 /* use at most thus many bytes */ 1123 /* use at most thus many bytes */
1123 bitstream_init(&bs, p->code, BM_PACKET_VLI_BYTES_MAX, 0); 1124 bitstream_init(&bs, p->code, size, 0);
1124 memset(p->code, 0, BM_PACKET_VLI_BYTES_MAX); 1125 memset(p->code, 0, size);
1125 /* plain bits covered in this code string */ 1126 /* plain bits covered in this code string */
1126 plain_bits = 0; 1127 plain_bits = 0;
1127 1128
@@ -1203,11 +1204,11 @@ static int
1203send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) 1204send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
1204{ 1205{
1205 struct drbd_socket *sock = &mdev->tconn->data; 1206 struct drbd_socket *sock = &mdev->tconn->data;
1207 unsigned int header_size = drbd_header_size(mdev->tconn);
1206 struct p_compressed_bm *p = sock->sbuf; 1208 struct p_compressed_bm *p = sock->sbuf;
1207 unsigned long num_words;
1208 int len, err; 1209 int len, err;
1209 1210
1210 len = fill_bitmap_rle_bits(mdev, p, c); 1211 len = fill_bitmap_rle_bits(mdev, p, DRBD_SOCKET_BUFFER_SIZE - sizeof(*p) /* FIXME */, c);
1211 if (len < 0) 1212 if (len < 0)
1212 return -EIO; 1213 return -EIO;
1213 1214
@@ -1224,9 +1225,14 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
1224 } else { 1225 } else {
1225 /* was not compressible. 1226 /* was not compressible.
1226 * send a buffer full of plain text bits instead. */ 1227 * send a buffer full of plain text bits instead. */
1228 unsigned int data_size;
1229 unsigned long num_words;
1227 struct p_header *h = sock->sbuf; 1230 struct p_header *h = sock->sbuf;
1228 num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset); 1231
1229 len = num_words * sizeof(long); 1232 data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
1233 num_words = min_t(size_t, data_size / sizeof(unsigned long),
1234 c->bm_words - c->word_offset);
1235 len = num_words * sizeof(unsigned long);
1230 if (len) 1236 if (len)
1231 drbd_bm_get_lel(mdev, c->word_offset, num_words, 1237 drbd_bm_get_lel(mdev, c->word_offset, num_words,
1232 (unsigned long *)h->payload); 1238 (unsigned long *)h->payload);
@@ -1236,7 +1242,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
1236 c->bit_offset = c->word_offset * BITS_PER_LONG; 1242 c->bit_offset = c->word_offset * BITS_PER_LONG;
1237 1243
1238 c->packets[1]++; 1244 c->packets[1]++;
1239 c->bytes[1] += sizeof(struct p_header80) + len; 1245 c->bytes[1] += header_size + len;
1240 1246
1241 if (c->bit_offset > c->bm_bits) 1247 if (c->bit_offset > c->bm_bits)
1242 c->bit_offset = c->bm_bits; 1248 c->bit_offset = c->bm_bits;
@@ -2550,7 +2556,6 @@ int __init drbd_init(void)
2550{ 2556{
2551 int err; 2557 int err;
2552 2558
2553 BUILD_BUG_ON(sizeof(struct p_header80) != sizeof(struct p_header95));
2554 BUILD_BUG_ON(sizeof(struct p_connection_features) != 80); 2559 BUILD_BUG_ON(sizeof(struct p_connection_features) != 80);
2555 2560
2556 if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) { 2561 if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 40fe7199d5f7..74ed3ac263f3 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3660,16 +3660,19 @@ static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
3660 * code upon failure. 3660 * code upon failure.
3661 */ 3661 */
3662static int 3662static int
3663receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size, 3663receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size,
3664 struct p_header *h, struct bm_xfer_ctx *c) 3664 struct p_header *h, struct bm_xfer_ctx *c)
3665{ 3665{
3666 unsigned long *buffer = (unsigned long *)h->payload; 3666 unsigned long *buffer = (unsigned long *)h->payload;
3667 unsigned num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset); 3667 unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
3668 unsigned want = num_words * sizeof(long); 3668 drbd_header_size(mdev->tconn);
3669 unsigned int num_words = min_t(size_t, data_size / sizeof(unsigned long),
3670 c->bm_words - c->word_offset);
3671 unsigned int want = num_words * sizeof(unsigned long);
3669 int err; 3672 int err;
3670 3673
3671 if (want != data_size) { 3674 if (want != size) {
3672 dev_err(DEV, "%s:want (%u) != data_size (%u)\n", __func__, want, data_size); 3675 dev_err(DEV, "%s:want (%u) != size (%u)\n", __func__, want, size);
3673 return -EIO; 3676 return -EIO;
3674 } 3677 }
3675 if (want == 0) 3678 if (want == 0)
@@ -3796,11 +3799,13 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
3796 const char *direction, struct bm_xfer_ctx *c) 3799 const char *direction, struct bm_xfer_ctx *c)
3797{ 3800{
3798 /* what would it take to transfer it "plaintext" */ 3801 /* what would it take to transfer it "plaintext" */
3799 unsigned plain = sizeof(struct p_header) * 3802 unsigned int header_size = drbd_header_size(mdev->tconn);
3800 ((c->bm_words+BM_PACKET_WORDS-1)/BM_PACKET_WORDS+1) 3803 unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
3801 + c->bm_words * sizeof(long); 3804 unsigned int plain =
3802 unsigned total = c->bytes[0] + c->bytes[1]; 3805 header_size * (DIV_ROUND_UP(c->bm_words, data_size) + 1) +
3803 unsigned r; 3806 c->bm_words * sizeof(unsigned long);
3807 unsigned int total = c->bytes[0] + c->bytes[1];
3808 unsigned int r;
3804 3809
3805 /* total can not be zero. but just in case: */ 3810 /* total can not be zero. but just in case: */
3806 if (total == 0) 3811 if (total == 0)
@@ -3862,7 +3867,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
3862 * and the feature is enabled! */ 3867 * and the feature is enabled! */
3863 struct p_compressed_bm *p; 3868 struct p_compressed_bm *p;
3864 3869
3865 if (pi->size > BM_PACKET_PAYLOAD_BYTES) { 3870 if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(tconn)) {
3866 dev_err(DEV, "ReportCBitmap packet too large\n"); 3871 dev_err(DEV, "ReportCBitmap packet too large\n");
3867 err = -EIO; 3872 err = -EIO;
3868 goto out; 3873 goto out;
@@ -3885,7 +3890,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
3885 } 3890 }
3886 3891
3887 c.packets[pi->cmd == P_BITMAP]++; 3892 c.packets[pi->cmd == P_BITMAP]++;
3888 c.bytes[pi->cmd == P_BITMAP] += sizeof(struct p_header) + pi->size; 3893 c.bytes[pi->cmd == P_BITMAP] += drbd_header_size(tconn) + pi->size;
3889 3894
3890 if (err <= 0) { 3895 if (err <= 0) {
3891 if (err < 0) 3896 if (err < 0)