diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-03-30 05:53:51 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:45:09 -0500 |
commit | 50d0b1ad78b99aa776c3ddf9b1d45163fff435b9 (patch) | |
tree | 3f7d43397a0e3b049430907919b12bd3786330e2 /drivers/block/drbd | |
parent | da39fec49286d6b44bf441c9707dda2764b4498a (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.h | 15 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 25 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 29 |
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 | ||
1102 | int fill_bitmap_rle_bits(struct drbd_conf *mdev, | 1102 | int 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 | |||
1203 | send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) | 1204 | send_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 | */ |
3662 | static int | 3662 | static int |
3663 | receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size, | 3663 | receive_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) |