* [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd
@ 2011-09-07 14:17 Philipp Reisner
2011-09-07 14:17 ` [PATCH 01/14] drbd: drbd_connected(): Return an error code upon failure Philipp Reisner
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
This the first request for review of drbd-8.4. The complete set has
492 patches. This is the sixth installment containing 54 patches.
The whole set is available here:
git://git.drbd.org/linux-2.6-drbd.git for-jens
and is jens_for-3.2_drivers...for-jens
and this part is f6833a3...0f44265
This patch series contains:
* Use a pre-allocated page as send buffer
* Use a pre-allocated page as receive buffer
* Cleanups and renames
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 01/14] drbd: drbd_connected(): Return an error code upon failure.
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 02/14] drbd: Always use the same protocol version for the same peer Philipp Reisner
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 17 +++++++++--------
1 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 49dc08a..2253423 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -781,7 +781,7 @@ static int drbd_socket_okay(struct socket **sock)
int drbd_connected(int vnr, void *p, void *data)
{
struct drbd_conf *mdev = (struct drbd_conf *)p;
- int ok = 1;
+ int err;
atomic_set(&mdev->packet_seq, 0);
mdev->peer_seq = 0;
@@ -790,15 +790,16 @@ int drbd_connected(int vnr, void *p, void *data)
&mdev->tconn->cstate_mutex :
&mdev->own_state_mutex;
- ok &= !drbd_send_sync_param(mdev);
- ok &= !drbd_send_sizes(mdev, 0, 0);
- ok &= !drbd_send_uuids(mdev);
- ok &= !drbd_send_state(mdev);
+ err = drbd_send_sync_param(mdev);
+ if (!err)
+ err = drbd_send_sizes(mdev, 0, 0);
+ if (!err)
+ err = drbd_send_uuids(mdev);
+ if (!err)
+ err = drbd_send_state(mdev);
clear_bit(USE_DEGR_WFC_T, &mdev->flags);
clear_bit(RESIZE_PENDING, &mdev->flags);
-
-
- return !ok;
+ return err;
}
/*
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 02/14] drbd: Always use the same protocol version for the same peer
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
2011-09-07 14:17 ` [PATCH 01/14] drbd: drbd_connected(): Return an error code upon failure Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 03/14] drbd: Move drbd_send_ping() and drbd_send_ping_ack() to drbd_main.c Philipp Reisner
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
There is no need to send protocol 80 headers to peers that understand
protocol 95 headers. Make sure that we don't send protocol 95 headers
until we have agreed upon a protocol version with our peer, though.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_main.c | 2 +-
drivers/block/drbd/drbd_receiver.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e36d32c..0028b60ca 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -706,7 +706,7 @@ static void prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int siz
static void _prepare_header(struct drbd_tconn *tconn, int vnr, struct p_header *h,
enum drbd_packet cmd, int size)
{
- if (tconn->agreed_pro_version >= 100 || size > DRBD_MAX_SIZE_H80_PACKET)
+ if (tconn->agreed_pro_version >= 95)
prepare_header95(&h->h95, cmd, size, vnr);
else
prepare_header80(&h->h80, cmd, size);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 2253423..48e073a 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -819,9 +819,9 @@ static int drbd_connect(struct drbd_tconn *tconn)
return -2;
clear_bit(DISCARD_CONCURRENT, &tconn->flags);
- tconn->agreed_pro_version = 99;
- /* agreed_pro_version must be smaller than 100 so we send the old
- header (h80) in the first packet and in the handshake packet. */
+
+ /* Assume that the peer only understands protocol 80 until we know better. */
+ tconn->agreed_pro_version = 80;
sock = NULL;
msock = NULL;
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 03/14] drbd: Move drbd_send_ping() and drbd_send_ping_ack() to drbd_main.c
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
2011-09-07 14:17 ` [PATCH 01/14] drbd: drbd_connected(): Return an error code upon failure Philipp Reisner
2011-09-07 14:17 ` [PATCH 02/14] drbd: Always use the same protocol version for the same peer Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 04/14] drbd: Make _drbd_send_bitmap() static Philipp Reisner
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 13 ++-----------
drivers/block/drbd/drbd_main.c | 12 ++++++++++++
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 72df107..1aec096 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1939,17 +1939,8 @@ static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
return drbd_send_cmd(mdev, &mdev->tconn->data, cmd, &h, sizeof(h));
}
-static inline int drbd_send_ping(struct drbd_tconn *tconn)
-{
- struct p_header h;
- return !conn_send_cmd(tconn, 0, &tconn->meta, P_PING, &h, sizeof(h));
-}
-
-static inline int drbd_send_ping_ack(struct drbd_tconn *tconn)
-{
- struct p_header h;
- return !conn_send_cmd(tconn, 0, &tconn->meta, P_PING_ACK, &h, sizeof(h));
-}
+extern int drbd_send_ping(struct drbd_tconn *tconn);
+extern int drbd_send_ping_ack(struct drbd_tconn *tconn);
static inline int drbd_send_state_req(struct drbd_conf *mdev,
union drbd_state mask, union drbd_state val)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0028b60ca..34627ae 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -765,6 +765,18 @@ int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd, char *data,
return err;
}
+int drbd_send_ping(struct drbd_tconn *tconn)
+{
+ struct p_header h;
+ return !conn_send_cmd(tconn, 0, &tconn->meta, P_PING, &h, sizeof(h));
+}
+
+int drbd_send_ping_ack(struct drbd_tconn *tconn)
+{
+ struct p_header h;
+ return !conn_send_cmd(tconn, 0, &tconn->meta, P_PING_ACK, &h, sizeof(h));
+}
+
int drbd_send_sync_param(struct drbd_conf *mdev)
{
struct p_rs_param_95 *p;
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 04/14] drbd: Make _drbd_send_bitmap() static
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (2 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 03/14] drbd: Move drbd_send_ping() and drbd_send_ping_ack() to drbd_main.c Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 05/14] drbd: Rename the DCBP_* functions to dcbp_* and move them to where they are used Philipp Reisner
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 1 -
drivers/block/drbd/drbd_main.c | 2 +-
2 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 1aec096..077aa0c 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1201,7 +1201,6 @@ extern int drbd_send_drequest_csum(struct drbd_conf *mdev, sector_t sector,
extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size);
extern int drbd_send_bitmap(struct drbd_conf *mdev);
-extern int _drbd_send_bitmap(struct drbd_conf *mdev);
extern void drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode);
extern int conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode);
extern void drbd_free_bc(struct drbd_backing_dev *ldev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 34627ae..53e887d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1182,7 +1182,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
}
/* See the comment at receive_bitmap() */
-int _drbd_send_bitmap(struct drbd_conf *mdev)
+static int _drbd_send_bitmap(struct drbd_conf *mdev)
{
struct bm_xfer_ctx c;
struct p_header *p;
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 05/14] drbd: Rename the DCBP_* functions to dcbp_* and move them to where they are used
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (3 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 04/14] drbd: Make _drbd_send_bitmap() static Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 06/14] drbd: Converted drbd_try_outdate_peer() from mdev to tconn Philipp Reisner
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 39 ------------------------------------
drivers/block/drbd/drbd_main.c | 25 +++++++++++++++++++---
drivers/block/drbd/drbd_receiver.c | 21 ++++++++++++++++--
3 files changed, 39 insertions(+), 46 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 077aa0c..04716df 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -541,45 +541,6 @@ struct p_delay_probe93 {
u32 offset; /* usecs the probe got sent after the reference time point */
} __packed;
-/* DCBP: Drbd Compressed Bitmap Packet ... */
-static inline enum drbd_bitmap_code
-DCBP_get_code(struct p_compressed_bm *p)
-{
- return (enum drbd_bitmap_code)(p->encoding & 0x0f);
-}
-
-static inline void
-DCBP_set_code(struct p_compressed_bm *p, enum drbd_bitmap_code code)
-{
- BUG_ON(code & ~0xf);
- p->encoding = (p->encoding & ~0xf) | code;
-}
-
-static inline int
-DCBP_get_start(struct p_compressed_bm *p)
-{
- return (p->encoding & 0x80) != 0;
-}
-
-static inline void
-DCBP_set_start(struct p_compressed_bm *p, int set)
-{
- p->encoding = (p->encoding & ~0x80) | (set ? 0x80 : 0);
-}
-
-static inline int
-DCBP_get_pad_bits(struct p_compressed_bm *p)
-{
- return (p->encoding >> 4) & 0x7;
-}
-
-static inline void
-DCBP_set_pad_bits(struct p_compressed_bm *p, int n)
-{
- BUG_ON(n & ~0x7);
- p->encoding = (p->encoding & (~0x7 << 4)) | (n << 4);
-}
-
/* 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
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 53e887d..54778e9 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1029,6 +1029,23 @@ int conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode)
return !conn_send_cmd(tconn, 0, &tconn->meta, cmd, &p.head, sizeof(p));
}
+static void dcbp_set_code(struct p_compressed_bm *p, enum drbd_bitmap_code code)
+{
+ BUG_ON(code & ~0xf);
+ p->encoding = (p->encoding & ~0xf) | code;
+}
+
+static void dcbp_set_start(struct p_compressed_bm *p, int set)
+{
+ p->encoding = (p->encoding & ~0x80) | (set ? 0x80 : 0);
+}
+
+static void dcbp_set_pad_bits(struct p_compressed_bm *p, int n)
+{
+ BUG_ON(n & ~0x7);
+ p->encoding = (p->encoding & (~0x7 << 4)) | (n << 4);
+}
+
int fill_bitmap_rle_bits(struct drbd_conf *mdev,
struct p_compressed_bm *p,
struct bm_xfer_ctx *c)
@@ -1073,12 +1090,12 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
if (rl == 0) {
/* the first checked bit was set,
* store start value, */
- DCBP_set_start(p, 1);
+ dcbp_set_start(p, 1);
/* but skip encoding of zero run length */
toggle = !toggle;
continue;
}
- DCBP_set_start(p, 0);
+ dcbp_set_start(p, 0);
}
/* paranoia: catch zero runlength.
@@ -1118,7 +1135,7 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
bm_xfer_ctx_bit_to_word_offset(c);
/* store pad_bits */
- DCBP_set_pad_bits(p, (8 - bs.cur.bit) & 0x7);
+ dcbp_set_pad_bits(p, (8 - bs.cur.bit) & 0x7);
return len;
}
@@ -1143,7 +1160,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
return -EIO;
if (len) {
- DCBP_set_code(p, RLE_VLI_Bits);
+ dcbp_set_code(p, RLE_VLI_Bits);
err = _drbd_send_cmd(mdev, mdev->tconn->data.socket,
P_COMPRESSED_BITMAP, h,
sizeof(*p) + len, 0);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 48e073a..449637f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3598,6 +3598,21 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size,
return 1;
}
+static enum drbd_bitmap_code dcbp_get_code(struct p_compressed_bm *p)
+{
+ return (enum drbd_bitmap_code)(p->encoding & 0x0f);
+}
+
+static int dcbp_get_start(struct p_compressed_bm *p)
+{
+ return (p->encoding & 0x80) != 0;
+}
+
+static int dcbp_get_pad_bits(struct p_compressed_bm *p)
+{
+ return (p->encoding >> 4) & 0x7;
+}
+
/**
* recv_bm_rle_bits
*
@@ -3616,11 +3631,11 @@ recv_bm_rle_bits(struct drbd_conf *mdev,
u64 tmp;
unsigned long s = c->bit_offset;
unsigned long e;
- int toggle = DCBP_get_start(p);
+ int toggle = dcbp_get_start(p);
int have;
int bits;
- bitstream_init(&bs, p->code, len, DCBP_get_pad_bits(p));
+ bitstream_init(&bs, p->code, len, dcbp_get_pad_bits(p));
bits = bitstream_get_bits(&bs, &look_ahead, 64);
if (bits < 0)
@@ -3675,7 +3690,7 @@ decode_bitmap_c(struct drbd_conf *mdev,
struct bm_xfer_ctx *c,
unsigned int len)
{
- if (DCBP_get_code(p) == RLE_VLI_Bits)
+ if (dcbp_get_code(p) == RLE_VLI_Bits)
return recv_bm_rle_bits(mdev, p, c, len);
/* other variants had been implemented for evaluation,
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 06/14] drbd: Converted drbd_try_outdate_peer() from mdev to tconn
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (4 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 05/14] drbd: Rename the DCBP_* functions to dcbp_* and move them to where they are used Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 07/14] drbd: Preallocate one page per drbd_socket as a receive buffer Philipp Reisner
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 4 +-
drivers/block/drbd/drbd_nl.c | 139 ++++++++++++++++--------------------
drivers/block/drbd/drbd_receiver.c | 7 +-
drivers/block/drbd/drbd_state.c | 62 +++++++++++++----
drivers/block/drbd/drbd_state.h | 5 ++
include/linux/drbd.h | 3 +-
6 files changed, 124 insertions(+), 96 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 04716df..47a435a 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1472,8 +1472,8 @@ extern void drbd_reconsider_max_bio_size(struct drbd_conf *mdev);
extern enum drbd_state_rv drbd_set_role(struct drbd_conf *mdev,
enum drbd_role new_role,
int force);
-extern enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev);
-extern void drbd_try_outdate_peer_async(struct drbd_conf *mdev);
+extern bool conn_try_outdate_peer(struct drbd_tconn *tconn);
+extern void conn_try_outdate_peer_async(struct drbd_tconn *tconn);
extern int drbd_khelper(struct drbd_conf *mdev, char *cmd);
/* drbd_worker.c */
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 9a0e446..931ffc4 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -401,116 +401,113 @@ int conn_khelper(struct drbd_tconn *tconn, char *cmd)
return ret;
}
-enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev)
+static enum drbd_fencing_p highest_fencing_policy(struct drbd_tconn *tconn)
{
+ enum drbd_fencing_p fp = FP_NOT_AVAIL;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr) {
+ if (get_ldev_if_state(mdev, D_CONSISTENT)) {
+ fp = max_t(enum drbd_fencing_p, fp, mdev->ldev->dc.fencing);
+ put_ldev(mdev);
+ }
+ }
+
+ return fp;
+}
+
+bool conn_try_outdate_peer(struct drbd_tconn *tconn)
+{
+ union drbd_state mask = { { .susp_fen = 1 } };
+ union drbd_state val = { };
+ enum drbd_fencing_p fp;
char *ex_to_string;
int r;
- enum drbd_disk_state nps;
- enum drbd_fencing_p fp;
- D_ASSERT(mdev->state.pdsk == D_UNKNOWN);
+ if (tconn->cstate >= C_WF_REPORT_PARAMS) {
+ conn_err(tconn, "Expected cstate < C_WF_REPORT_PARAMS\n");
+ return false;
+ }
- if (get_ldev_if_state(mdev, D_CONSISTENT)) {
- fp = mdev->ldev->dc.fencing;
- put_ldev(mdev);
- } else {
- dev_warn(DEV, "Not fencing peer, I'm not even Consistent myself.\n");
- nps = mdev->state.pdsk;
+ fp = highest_fencing_policy(tconn);
+ switch (fp) {
+ case FP_NOT_AVAIL:
+ conn_warn(tconn, "Not fencing peer, I'm not even Consistent myself.\n");
goto out;
+ case FP_DONT_CARE:
+ return true;
+ default: ;
}
- r = drbd_khelper(mdev, "fence-peer");
+ r = conn_khelper(tconn, "fence-peer");
switch ((r>>8) & 0xff) {
case 3: /* peer is inconsistent */
ex_to_string = "peer is inconsistent or worse";
- nps = D_INCONSISTENT;
+ mask.pdsk = D_MASK;
+ val.pdsk = D_INCONSISTENT;
break;
case 4: /* peer got outdated, or was already outdated */
ex_to_string = "peer was fenced";
- nps = D_OUTDATED;
+ mask.pdsk = D_MASK;
+ val.pdsk = D_OUTDATED;
break;
case 5: /* peer was down */
- if (mdev->state.disk == D_UP_TO_DATE) {
+ if (conn_highest_disk(tconn) == D_UP_TO_DATE) {
/* we will(have) create(d) a new UUID anyways... */
ex_to_string = "peer is unreachable, assumed to be dead";
- nps = D_OUTDATED;
+ mask.pdsk = D_MASK;
+ val.pdsk = D_OUTDATED;
} else {
ex_to_string = "peer unreachable, doing nothing since disk != UpToDate";
- nps = mdev->state.pdsk;
}
break;
case 6: /* Peer is primary, voluntarily outdate myself.
* This is useful when an unconnected R_SECONDARY is asked to
* become R_PRIMARY, but finds the other peer being active. */
ex_to_string = "peer is active";
- dev_warn(DEV, "Peer is primary, outdating myself.\n");
- nps = D_UNKNOWN;
- _drbd_request_state(mdev, NS(disk, D_OUTDATED), CS_WAIT_COMPLETE);
+ conn_warn(tconn, "Peer is primary, outdating myself.\n");
+ mask.disk = D_MASK;
+ val.disk = D_OUTDATED;
break;
case 7:
if (fp != FP_STONITH)
- dev_err(DEV, "fence-peer() = 7 && fencing != Stonith !!!\n");
+ conn_err(tconn, "fence-peer() = 7 && fencing != Stonith !!!\n");
ex_to_string = "peer was stonithed";
- nps = D_OUTDATED;
+ mask.pdsk = D_MASK;
+ val.pdsk = D_OUTDATED;
break;
default:
/* The script is broken ... */
- nps = D_UNKNOWN;
- dev_err(DEV, "fence-peer helper broken, returned %d\n", (r>>8)&0xff);
- return nps;
+ conn_err(tconn, "fence-peer helper broken, returned %d\n", (r>>8)&0xff);
+ return false; /* Eventually leave IO frozen */
}
- dev_info(DEV, "fence-peer helper returned %d (%s)\n",
- (r>>8) & 0xff, ex_to_string);
-
-out:
- if (mdev->state.susp_fen && nps >= D_UNKNOWN) {
- /* The handler was not successful... unfreeze here, the
- state engine can not unfreeze... */
- _drbd_request_state(mdev, NS(susp_fen, 0), CS_VERBOSE);
- }
+ conn_info(tconn, "fence-peer helper returned %d (%s)\n",
+ (r>>8) & 0xff, ex_to_string);
- return nps;
+ out:
+ conn_request_state(tconn, mask, val, CS_VERBOSE);
+ return conn_highest_pdsk(tconn) <= D_OUTDATED;
}
static int _try_outdate_peer_async(void *data)
{
- struct drbd_conf *mdev = (struct drbd_conf *)data;
- enum drbd_disk_state nps;
- union drbd_state ns;
-
- nps = drbd_try_outdate_peer(mdev);
-
- /* Not using
- drbd_request_state(mdev, NS(pdsk, nps));
- here, because we might were able to re-establish the connection
- in the meantime. This can only partially be solved in the state's
- engine is_valid_state() and is_valid_state_transition()
- functions.
+ struct drbd_tconn *tconn = (struct drbd_tconn *)data;
- nps can be D_INCONSISTENT, D_OUTDATED or D_UNKNOWN.
- pdsk == D_INCONSISTENT while conn >= C_CONNECTED is valid,
- therefore we have to have the pre state change check here.
- */
- spin_lock_irq(&mdev->tconn->req_lock);
- ns = mdev->state;
- if (ns.conn < C_WF_REPORT_PARAMS) {
- ns.pdsk = nps;
- _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
- }
- spin_unlock_irq(&mdev->tconn->req_lock);
+ conn_try_outdate_peer(tconn);
return 0;
}
-void drbd_try_outdate_peer_async(struct drbd_conf *mdev)
+void conn_try_outdate_peer_async(struct drbd_tconn *tconn)
{
struct task_struct *opa;
- opa = kthread_run(_try_outdate_peer_async, mdev, "drbd%d_a_helper", mdev_to_minor(mdev));
+ opa = kthread_run(_try_outdate_peer_async, tconn, "drbd_async_h");
if (IS_ERR(opa))
- dev_err(DEV, "out of mem, failed to invoke fence-peer helper\n");
+ conn_err(tconn, "out of mem, failed to invoke fence-peer helper\n");
}
enum drbd_state_rv
@@ -521,7 +518,6 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
int try = 0;
int forced = 0;
union drbd_state mask, val;
- enum drbd_disk_state nps;
if (new_role == R_PRIMARY)
request_ping(mdev->tconn); /* Detect a dead peer ASAP */
@@ -554,32 +550,23 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
if (rv == SS_NO_UP_TO_DATE_DISK &&
mdev->state.disk == D_CONSISTENT && mask.pdsk == 0) {
D_ASSERT(mdev->state.pdsk == D_UNKNOWN);
- nps = drbd_try_outdate_peer(mdev);
- if (nps == D_OUTDATED || nps == D_INCONSISTENT) {
+ if (conn_try_outdate_peer(mdev->tconn)) {
val.disk = D_UP_TO_DATE;
mask.disk = D_MASK;
}
-
- val.pdsk = nps;
- mask.pdsk = D_MASK;
-
continue;
}
if (rv == SS_NOTHING_TO_DO)
goto out;
if (rv == SS_PRIMARY_NOP && mask.pdsk == 0) {
- nps = drbd_try_outdate_peer(mdev);
-
- if (force && nps > D_OUTDATED) {
+ if (!conn_try_outdate_peer(mdev->tconn) && force) {
dev_warn(DEV, "Forced into split brain situation!\n");
- nps = D_OUTDATED;
- }
-
- mask.pdsk = D_MASK;
- val.pdsk = nps;
+ mask.pdsk = D_MASK;
+ val.pdsk = D_OUTDATED;
+ }
continue;
}
if (rv == SS_TWO_PRIMARIES) {
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 449637f..08140d9 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4028,9 +4028,11 @@ static void drbd_disconnect(struct drbd_tconn *tconn)
drbd_free_sock(tconn);
idr_for_each(&tconn->volumes, drbd_disconnected, tconn);
-
conn_info(tconn, "Connection closed\n");
+ if (conn_highest_role(tconn) == R_PRIMARY && conn_highest_pdsk(tconn) >= D_UNKNOWN)
+ conn_try_outdate_peer_async(tconn);
+
spin_lock_irq(&tconn->req_lock);
oc = tconn->cstate;
if (oc >= C_UNCONNECTED)
@@ -4107,9 +4109,6 @@ static int drbd_disconnected(int vnr, void *p, void *data)
put_ldev(mdev);
}
- if (mdev->state.role == R_PRIMARY && fp >= FP_RESOURCE && mdev->state.pdsk >= D_UNKNOWN)
- drbd_try_outdate_peer_async(mdev);
-
/* serialize with bitmap writeout triggered by the state change,
* if any. */
wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index a14511b..280b31c 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -62,6 +62,54 @@ bool conn_all_vols_unconf(struct drbd_tconn *tconn)
return true;
}
+enum drbd_role conn_highest_role(struct drbd_tconn *tconn)
+{
+ enum drbd_role role = R_UNKNOWN;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ role = max_t(enum drbd_role, role, mdev->state.role);
+
+ return role;
+}
+
+enum drbd_role conn_highest_peer(struct drbd_tconn *tconn)
+{
+ enum drbd_role peer = R_UNKNOWN;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ peer = max_t(enum drbd_role, peer, mdev->state.role);
+
+ return peer;
+}
+
+enum drbd_disk_state conn_highest_disk(struct drbd_tconn *tconn)
+{
+ enum drbd_disk_state ds = D_DISKLESS;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ ds = max_t(enum drbd_disk_state, ds, mdev->state.disk);
+
+ return ds;
+}
+
+enum drbd_disk_state conn_highest_pdsk(struct drbd_tconn *tconn)
+{
+ enum drbd_disk_state ds = D_DISKLESS;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ ds = max_t(enum drbd_disk_state, ds, mdev->state.pdsk);
+
+ return ds;
+}
+
/**
* cl_wide_st_chg() - true if the state change is a cluster wide one
* @mdev: DRBD device.
@@ -330,18 +378,6 @@ static void print_state_change(struct drbd_conf *mdev, union drbd_state os, unio
dev_info(DEV, "%s\n", pb);
}
-static bool vol_has_primary_peer(struct drbd_tconn *tconn)
-{
- struct drbd_conf *mdev;
- int vnr;
-
- idr_for_each_entry(&tconn->volumes, mdev, vnr) {
- if (mdev->state.peer == R_PRIMARY)
- return true;
- }
- return false;
-}
-
/**
* is_valid_state() - Returns an SS_ error code if ns is not valid
* @mdev: DRBD device.
@@ -365,7 +401,7 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
if (!mdev->tconn->net_conf->two_primaries && ns.role == R_PRIMARY) {
if (ns.peer == R_PRIMARY)
rv = SS_TWO_PRIMARIES;
- else if (vol_has_primary_peer(mdev->tconn))
+ else if (conn_highest_peer(mdev->tconn) == R_PRIMARY)
rv = SS_O_VOL_PEER_PRI;
}
put_net_conf(mdev->tconn);
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index 55df072..394a199 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -110,4 +110,9 @@ static inline int drbd_request_state(struct drbd_conf *mdev,
return _drbd_request_state(mdev, mask, val, CS_VERBOSE + CS_ORDERED);
}
+enum drbd_role conn_highest_role(struct drbd_tconn *tconn);
+enum drbd_role conn_highest_peer(struct drbd_tconn *tconn);
+enum drbd_disk_state conn_highest_disk(struct drbd_tconn *tconn);
+enum drbd_disk_state conn_highest_pdsk(struct drbd_tconn *tconn);
+
#endif
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 9cdb888..60d3088 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -65,7 +65,8 @@ enum drbd_io_error_p {
};
enum drbd_fencing_p {
- FP_DONT_CARE,
+ FP_NOT_AVAIL = -1, /* Not a policy */
+ FP_DONT_CARE = 0,
FP_RESOURCE,
FP_STONITH
};
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 07/14] drbd: Preallocate one page per drbd_socket as a receive buffer
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (5 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 06/14] drbd: Converted drbd_try_outdate_peer() from mdev to tconn Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 08/14] drbd: receive_bitmap(): Use the pre-allocated " Philipp Reisner
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 4 ++-
drivers/block/drbd/drbd_main.c | 22 ++++++++++++
drivers/block/drbd/drbd_receiver.c | 65 ++++++++++++++++--------------------
3 files changed, 54 insertions(+), 37 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 47a435a..4a4ecec 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -554,6 +554,8 @@ struct p_delay_probe93 {
#error "PAGE_SIZE too small"
#endif
+#define DRBD_SOCKET_BUFFER_SIZE 4096
+
union p_polymorph {
struct p_header header;
struct p_handshake handshake;
@@ -803,7 +805,7 @@ struct drbd_socket {
/* this way we get our
* send/receive buffers off the stack */
union p_polymorph sbuf;
- union p_polymorph rbuf;
+ void *rbuf;
};
struct drbd_md {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 54778e9..7b6da0e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2274,6 +2274,19 @@ found:
return tconn;
}
+static int drbd_alloc_socket(struct drbd_socket *socket)
+{
+ socket->rbuf = (void *) __get_free_page(GFP_KERNEL);
+ if (!socket->rbuf)
+ return -ENOMEM;
+ return 0;
+}
+
+static void drbd_free_socket(struct drbd_socket *socket)
+{
+ free_page((unsigned long) socket->rbuf);
+}
+
struct drbd_tconn *drbd_new_tconn(const char *name)
{
struct drbd_tconn *tconn;
@@ -2286,6 +2299,11 @@ struct drbd_tconn *drbd_new_tconn(const char *name)
if (!tconn->name)
goto fail;
+ if (drbd_alloc_socket(&tconn->data))
+ goto fail;
+ if (drbd_alloc_socket(&tconn->meta))
+ goto fail;
+
if (!zalloc_cpumask_var(&tconn->cpu_mask, GFP_KERNEL))
goto fail;
@@ -2324,6 +2342,8 @@ struct drbd_tconn *drbd_new_tconn(const char *name)
fail:
tl_cleanup(tconn);
free_cpumask_var(tconn->cpu_mask);
+ drbd_free_socket(&tconn->meta);
+ drbd_free_socket(&tconn->data);
kfree(tconn->name);
kfree(tconn);
@@ -2336,6 +2356,8 @@ void drbd_free_tconn(struct drbd_tconn *tconn)
idr_destroy(&tconn->volumes);
free_cpumask_var(tconn->cpu_mask);
+ drbd_free_socket(&tconn->meta);
+ drbd_free_socket(&tconn->data);
kfree(tconn->name);
kfree(tconn->int_dig_out);
kfree(tconn->int_dig_in);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 08140d9..3738d56 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -743,7 +743,7 @@ static int drbd_send_fp(struct drbd_tconn *tconn, struct socket *sock, enum drbd
static enum drbd_packet drbd_recv_fp(struct drbd_tconn *tconn, struct socket *sock)
{
- struct p_header80 *h = &tconn->data.rbuf.header.h80;
+ struct p_header80 *h = tconn->data.rbuf;
int rr;
rr = drbd_recv_short(sock, h, sizeof(*h), 0);
@@ -997,7 +997,7 @@ static int decode_header(struct drbd_tconn *tconn, struct p_header *h, struct pa
static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_header *h = &tconn->data.rbuf.header;
+ struct p_header *h = tconn->data.rbuf;
int err;
err = drbd_recv_all_warn(tconn, h, sizeof(*h));
@@ -1239,7 +1239,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
int rv;
- struct p_barrier *p = &mdev->tconn->data.rbuf.barrier;
+ struct p_barrier *p = mdev->tconn->data.rbuf;
struct drbd_epoch *epoch;
inc_unacked(mdev);
@@ -1549,7 +1549,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
struct drbd_request *req;
sector_t sector;
int err;
- struct p_data *p = &mdev->tconn->data.rbuf.data;
+ struct p_data *p = mdev->tconn->data.rbuf;
sector = be64_to_cpu(p->sector);
@@ -1577,7 +1577,7 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
{
sector_t sector;
int err;
- struct p_data *p = &mdev->tconn->data.rbuf.data;
+ struct p_data *p = mdev->tconn->data.rbuf;
sector = be64_to_cpu(p->sector);
D_ASSERT(p->block_id == ID_SYNCER);
@@ -1966,7 +1966,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
{
sector_t sector;
struct drbd_peer_request *peer_req;
- struct p_data *p = &mdev->tconn->data.rbuf.data;
+ struct p_data *p = mdev->tconn->data.rbuf;
u32 peer_seq = be32_to_cpu(p->seq_num);
int rw = WRITE;
u32 dp_flags;
@@ -2150,7 +2150,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
struct digest_info *di = NULL;
int size, verb;
unsigned int fault_type;
- struct p_block_req *p = &mdev->tconn->data.rbuf.block_req;
+ struct p_block_req *p = mdev->tconn->data.rbuf;
sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize);
@@ -2870,7 +2870,7 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self)
static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_protocol *p = &tconn->data.rbuf.protocol;
+ struct p_protocol *p = tconn->data.rbuf;
int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
int p_want_lose, p_two_primaries, cf;
char p_integrity_alg[SHARED_SECRET_MAX] = "";
@@ -2972,7 +2972,7 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int packet_size)
{
- struct p_rs_param_95 *p = &mdev->tconn->data.rbuf.rs_param_95;
+ struct p_rs_param_95 *p = mdev->tconn->data.rbuf;
unsigned int header_size, data_size, exp_max_sz;
struct crypto_hash *verify_tfm = NULL;
struct crypto_hash *csums_tfm = NULL;
@@ -3139,7 +3139,7 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev,
static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_sizes *p = &mdev->tconn->data.rbuf.sizes;
+ struct p_sizes *p = mdev->tconn->data.rbuf;
enum determine_dev_size dd = unchanged;
sector_t p_size, p_usize, my_usize;
int ldsc = 0; /* local disk size changed */
@@ -3237,7 +3237,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_uuids *p = &mdev->tconn->data.rbuf.uuids;
+ struct p_uuids *p = mdev->tconn->data.rbuf;
u64 *p_uuid;
int i, updated_uuids = 0;
@@ -3333,7 +3333,7 @@ static union drbd_state convert_state(union drbd_state ps)
static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_req_state *p = &mdev->tconn->data.rbuf.req_state;
+ struct p_req_state *p = mdev->tconn->data.rbuf;
union drbd_state mask, val;
enum drbd_state_rv rv;
@@ -3360,7 +3360,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_req_state *p = &tconn->data.rbuf.req_state;
+ struct p_req_state *p = tconn->data.rbuf;
union drbd_state mask, val;
enum drbd_state_rv rv;
@@ -3385,7 +3385,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd
static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_state *p = &mdev->tconn->data.rbuf.state;
+ struct p_state *p = mdev->tconn->data.rbuf;
union drbd_state os, ns, peer_state;
enum drbd_disk_state real_peer_disk;
enum chg_state_flags cs_flags;
@@ -3538,7 +3538,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_rs_uuid *p = &mdev->tconn->data.rbuf.rs_uuid;
+ struct p_rs_uuid *p = mdev->tconn->data.rbuf;
wait_event(mdev->misc_wait,
mdev->state.conn == C_WF_SYNC_UUID ||
@@ -3750,7 +3750,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
struct bm_xfer_ctx c;
void *buffer;
int err;
- struct p_header *h = &mdev->tconn->data.rbuf.header;
+ struct p_header *h = mdev->tconn->data.rbuf;
struct packet_info pi;
drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
@@ -3891,7 +3891,7 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd,
static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
- struct p_block_desc *p = &mdev->tconn->data.rbuf.block_desc;
+ struct p_block_desc *p = mdev->tconn->data.rbuf;
switch (mdev->state.conn) {
case C_WF_SYNC_UUID:
@@ -3946,16 +3946,9 @@ static struct data_cmd drbd_cmd_handler[] = {
[P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), CONN, { .conn_fn = receive_req_conn_state } },
};
-/* All handler functions that expect a sub-header get that sub-heder in
- mdev->tconn->data.rbuf.header.head.payload.
-
- Usually in mdev->tconn->data.rbuf.header.head the callback can find the usual
- p_header, but they may not rely on that. Since there is also p_header95 !
- */
-
static void drbdd(struct drbd_tconn *tconn)
{
- struct p_header *header = &tconn->data.rbuf.header;
+ struct p_header *header = tconn->data.rbuf;
struct packet_info pi;
size_t shs; /* sub header size */
int err;
@@ -4186,7 +4179,7 @@ static int drbd_send_handshake(struct drbd_tconn *tconn)
static int drbd_do_handshake(struct drbd_tconn *tconn)
{
/* ASSERT current == tconn->receiver ... */
- struct p_handshake *p = &tconn->data.rbuf.handshake;
+ struct p_handshake *p = tconn->data.rbuf;
const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
struct packet_info pi;
int err;
@@ -4433,7 +4426,7 @@ int drbdd_init(struct drbd_thread *thi)
static int got_conn_RqSReply(struct drbd_tconn *tconn, enum drbd_packet cmd)
{
- struct p_req_state_reply *p = &tconn->meta.rbuf.req_state_reply;
+ struct p_req_state_reply *p = tconn->meta.rbuf;
int retcode = be32_to_cpu(p->retcode);
if (retcode >= SS_SUCCESS) {
@@ -4450,7 +4443,7 @@ static int got_conn_RqSReply(struct drbd_tconn *tconn, enum drbd_packet cmd)
static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packet cmd)
{
- struct p_req_state_reply *p = &mdev->tconn->meta.rbuf.req_state_reply;
+ struct p_req_state_reply *p = mdev->tconn->meta.rbuf;
int retcode = be32_to_cpu(p->retcode);
if (retcode >= SS_SUCCESS) {
@@ -4483,7 +4476,7 @@ static int got_PingAck(struct drbd_tconn *tconn, enum drbd_packet cmd)
static int got_IsInSync(struct drbd_conf *mdev, enum drbd_packet cmd)
{
- struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
+ struct p_block_ack *p = mdev->tconn->meta.rbuf;
sector_t sector = be64_to_cpu(p->sector);
int blksize = be32_to_cpu(p->blksize);
@@ -4528,7 +4521,7 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector,
static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packet cmd)
{
- struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
+ struct p_block_ack *p = mdev->tconn->meta.rbuf;
sector_t sector = be64_to_cpu(p->sector);
int blksize = be32_to_cpu(p->blksize);
enum drbd_req_event what;
@@ -4573,7 +4566,7 @@ static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packet cmd)
static int got_NegAck(struct drbd_conf *mdev, enum drbd_packet cmd)
{
- struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
+ struct p_block_ack *p = mdev->tconn->meta.rbuf;
sector_t sector = be64_to_cpu(p->sector);
int size = be32_to_cpu(p->blksize);
bool missing_ok = mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A ||
@@ -4606,7 +4599,7 @@ static int got_NegAck(struct drbd_conf *mdev, enum drbd_packet cmd)
static int got_NegDReply(struct drbd_conf *mdev, enum drbd_packet cmd)
{
- struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
+ struct p_block_ack *p = mdev->tconn->meta.rbuf;
sector_t sector = be64_to_cpu(p->sector);
update_peer_seq(mdev, be32_to_cpu(p->seq_num));
@@ -4623,7 +4616,7 @@ static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packet cmd)
{
sector_t sector;
int size;
- struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
+ struct p_block_ack *p = mdev->tconn->meta.rbuf;
sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize);
@@ -4652,7 +4645,7 @@ static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packet cmd)
static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packet cmd)
{
- struct p_barrier_ack *p = &mdev->tconn->meta.rbuf.barrier_ack;
+ struct p_barrier_ack *p = mdev->tconn->meta.rbuf;
tl_release(mdev->tconn, p->barrier, be32_to_cpu(p->set_size));
@@ -4668,7 +4661,7 @@ static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packet cmd)
static int got_OVResult(struct drbd_conf *mdev, enum drbd_packet cmd)
{
- struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
+ struct p_block_ack *p = mdev->tconn->meta.rbuf;
struct drbd_work *w;
sector_t sector;
int size;
@@ -4774,7 +4767,7 @@ static struct asender_cmd asender_tbl[] = {
int drbd_asender(struct drbd_thread *thi)
{
struct drbd_tconn *tconn = thi->tconn;
- struct p_header *h = &tconn->meta.rbuf.header;
+ struct p_header *h = tconn->meta.rbuf;
struct asender_cmd *cmd = NULL;
struct packet_info pi;
int rv;
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 08/14] drbd: receive_bitmap(): Use the pre-allocated receive buffer
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (6 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 07/14] drbd: Preallocate one page per drbd_socket as a receive buffer Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 09/14] drbd: Preallocate one page per drbd_socket as a send buffer Philipp Reisner
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 21 +++++----------------
1 files changed, 5 insertions(+), 16 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 3738d56..e5099db 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3572,8 +3572,9 @@ static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd,
*/
static int
receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size,
- unsigned long *buffer, struct bm_xfer_ctx *c)
+ 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);
int err;
@@ -3748,7 +3749,6 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size)
{
struct bm_xfer_ctx c;
- void *buffer;
int err;
struct p_header *h = mdev->tconn->data.rbuf;
struct packet_info pi;
@@ -3757,15 +3757,6 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
/* you are supposed to send additional out-of-sync information
* if you actually set bits during this phase */
- /* maybe we should use some per thread scratch page,
- * and allocate that during initial device creation? */
- buffer = (unsigned long *) __get_free_page(GFP_NOIO);
- if (!buffer) {
- dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__);
- err = -ENOMEM;
- goto out;
- }
-
c = (struct bm_xfer_ctx) {
.bm_bits = drbd_bm_bits(mdev),
.bm_words = drbd_bm_words(mdev),
@@ -3773,7 +3764,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
for(;;) {
if (cmd == P_BITMAP) {
- err = receive_bitmap_plain(mdev, data_size, buffer, &c);
+ err = receive_bitmap_plain(mdev, data_size, h, &c);
} else if (cmd == P_COMPRESSED_BITMAP) {
/* MAYBE: sanity check that we speak proto >= 90,
* and the feature is enabled! */
@@ -3784,9 +3775,8 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
err = -EIO;
goto out;
}
- /* use the page buff */
- p = buffer;
- memcpy(p, h, sizeof(*h));
+
+ p = mdev->tconn->data.rbuf;
err = drbd_recv_all(mdev->tconn, p->head.payload, data_size);
if (err)
goto out;
@@ -3840,7 +3830,6 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_bm_unlock(mdev);
if (!err && mdev->state.conn == C_WF_BITMAP_S)
drbd_start_resync(mdev, C_SYNC_SOURCE);
- free_page((unsigned long) buffer);
return err;
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 09/14] drbd: Preallocate one page per drbd_socket as a send buffer
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (7 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 08/14] drbd: receive_bitmap(): Use the pre-allocated " Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 10/14] drbd: _drbd_send_bitmap(): Use the pre-allocated " Philipp Reisner
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 23 +----------------------
drivers/block/drbd/drbd_main.c | 6 +++++-
drivers/block/drbd/drbd_receiver.c | 4 ++--
drivers/block/drbd/drbd_worker.c | 2 +-
4 files changed, 9 insertions(+), 26 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4a4ecec..984b2a3 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -556,27 +556,6 @@ struct p_delay_probe93 {
#define DRBD_SOCKET_BUFFER_SIZE 4096
-union p_polymorph {
- struct p_header header;
- struct p_handshake handshake;
- struct p_data data;
- struct p_block_ack block_ack;
- struct p_barrier barrier;
- struct p_barrier_ack barrier_ack;
- struct p_rs_param_89 rs_param_89;
- struct p_rs_param_95 rs_param_95;
- struct p_protocol protocol;
- struct p_sizes sizes;
- struct p_uuids uuids;
- struct p_state state;
- struct p_req_state req_state;
- struct p_req_state_reply req_state_reply;
- struct p_block_req block_req;
- struct p_delay_probe93 delay_probe93;
- struct p_rs_uuid rs_uuid;
- struct p_block_desc block_desc;
-} __packed;
-
/**********************************************************************/
enum drbd_thread_state {
NONE,
@@ -804,7 +783,7 @@ struct drbd_socket {
struct socket *socket;
/* this way we get our
* send/receive buffers off the stack */
- union p_polymorph sbuf;
+ void *sbuf;
void *rbuf;
};
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 7b6da0e..6c2a51f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -800,7 +800,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev)
enum drbd_packet cmd =
apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM;
- p = &mdev->tconn->data.sbuf.rs_param_95;
+ p = mdev->tconn->data.sbuf;
/* initialize verify_alg and csums_alg */
memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
@@ -2279,11 +2279,15 @@ static int drbd_alloc_socket(struct drbd_socket *socket)
socket->rbuf = (void *) __get_free_page(GFP_KERNEL);
if (!socket->rbuf)
return -ENOMEM;
+ socket->sbuf = (void *) __get_free_page(GFP_KERNEL);
+ if (!socket->sbuf)
+ return -ENOMEM;
return 0;
}
static void drbd_free_socket(struct drbd_socket *socket)
{
+ free_page((unsigned long) socket->sbuf);
free_page((unsigned long) socket->rbuf);
}
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index e5099db..57e65ac 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -736,7 +736,7 @@ out:
static int drbd_send_fp(struct drbd_tconn *tconn, struct socket *sock, enum drbd_packet cmd)
{
- struct p_header *h = &tconn->data.sbuf.header;
+ struct p_header *h = tconn->data.sbuf;
return !_conn_send_cmd(tconn, 0, sock, cmd, h, sizeof(*h), 0);
}
@@ -4136,7 +4136,7 @@ static int drbd_disconnected(int vnr, void *p, void *data)
static int drbd_send_handshake(struct drbd_tconn *tconn)
{
/* ASSERT current == mdev->tconn->receiver ... */
- struct p_handshake *p = &tconn->data.sbuf.handshake;
+ struct p_handshake *p = tconn->data.sbuf;
int err;
if (mutex_lock_interruptible(&tconn->data.mutex)) {
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index e96a816..ed12cdf 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1195,7 +1195,7 @@ int w_send_barrier(struct drbd_work *w, int cancel)
{
struct drbd_tl_epoch *b = container_of(w, struct drbd_tl_epoch, w);
struct drbd_conf *mdev = w->mdev;
- struct p_barrier *p = &mdev->tconn->data.sbuf.barrier;
+ struct p_barrier *p = mdev->tconn->data.sbuf;
int err = 0;
/* really avoid racing with tl_clear. w.cb may have been referenced
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 10/14] drbd: _drbd_send_bitmap(): Use the pre-allocated send buffer
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (8 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 09/14] drbd: Preallocate one page per drbd_socket as a send buffer Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 11/14] drbd: A small cleanup in drbdd() Philipp Reisner
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_main.c | 26 +++++++-------------------
1 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 6c2a51f..36b2b56 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -790,9 +790,6 @@ int drbd_send_sync_param(struct drbd_conf *mdev)
: apv <= 94 ? sizeof(struct p_rs_param_89)
: /* apv >= 95 */ sizeof(struct p_rs_param_95);
- /* used from admin command context and receiver/worker context.
- * to avoid kmalloc, grab the socket right here,
- * then use the pre-allocated sbuf there */
mutex_lock(&mdev->tconn->data.mutex);
sock = mdev->tconn->data.socket;
@@ -1147,10 +1144,9 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
* code upon failure.
*/
static int
-send_bitmap_rle_or_plain(struct drbd_conf *mdev,
- struct p_header *h, struct bm_xfer_ctx *c)
+send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
{
- struct p_compressed_bm *p = (void*)h;
+ struct p_compressed_bm *p = mdev->tconn->data.sbuf;
unsigned long num_words;
int len, err;
@@ -1162,7 +1158,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
if (len) {
dcbp_set_code(p, RLE_VLI_Bits);
err = _drbd_send_cmd(mdev, mdev->tconn->data.socket,
- P_COMPRESSED_BITMAP, h,
+ P_COMPRESSED_BITMAP, &p->head,
sizeof(*p) + len, 0);
c->packets[0]++;
@@ -1173,10 +1169,12 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
} else {
/* was not compressible.
* send a buffer full of plain text bits instead. */
+ struct p_header *h = mdev->tconn->data.sbuf;
num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
len = num_words * sizeof(long);
if (len)
- drbd_bm_get_lel(mdev, c->word_offset, num_words, (unsigned long*)h->payload);
+ drbd_bm_get_lel(mdev, c->word_offset, num_words,
+ (unsigned long *)h->payload);
err = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_BITMAP,
h, sizeof(struct p_header80) + len, 0);
c->word_offset += num_words;
@@ -1202,20 +1200,11 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
static int _drbd_send_bitmap(struct drbd_conf *mdev)
{
struct bm_xfer_ctx c;
- struct p_header *p;
int err;
if (!expect(mdev->bitmap))
return false;
- /* maybe we should use some per thread scratch page,
- * and allocate that during initial device creation? */
- p = (struct p_header *) __get_free_page(GFP_NOIO);
- if (!p) {
- dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__);
- return false;
- }
-
if (get_ldev(mdev)) {
if (drbd_md_test_flag(mdev->ldev, MDF_FULL_SYNC)) {
dev_info(DEV, "Writing the whole bitmap, MDF_FullSync was set.\n");
@@ -1239,10 +1228,9 @@ static int _drbd_send_bitmap(struct drbd_conf *mdev)
};
do {
- err = send_bitmap_rle_or_plain(mdev, p, &c);
+ err = send_bitmap_rle_or_plain(mdev, &c);
} while (err > 0);
- free_page((unsigned long) p);
return err == 0;
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 11/14] drbd: A small cleanup in drbdd()
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (9 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 10/14] drbd: _drbd_send_bitmap(): Use the pre-allocated " Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 12/14] drbd: Remove useless error messages Philipp Reisner
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 57e65ac..a4b24f9 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3943,18 +3943,20 @@ static void drbdd(struct drbd_tconn *tconn)
int err;
while (get_t_state(&tconn->receiver) == RUNNING) {
+ struct data_cmd *cmd;
+
drbd_thread_current_set_cpu(&tconn->receiver);
if (drbd_recv_header(tconn, &pi))
goto err_out;
- if (unlikely(pi.cmd >= ARRAY_SIZE(drbd_cmd_handler) ||
- !drbd_cmd_handler[pi.cmd].mdev_fn)) {
+ cmd = &drbd_cmd_handler[pi.cmd];
+ if (unlikely(pi.cmd >= ARRAY_SIZE(drbd_cmd_handler) || !cmd->mdev_fn)) {
conn_err(tconn, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size);
goto err_out;
}
- shs = drbd_cmd_handler[pi.cmd].pkt_size - sizeof(struct p_header);
- if (pi.size - shs > 0 && !drbd_cmd_handler[pi.cmd].expect_payload) {
+ shs = cmd->pkt_size - sizeof(struct p_header);
+ if (pi.size - shs > 0 && !cmd->expect_payload) {
conn_err(tconn, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size);
goto err_out;
}
@@ -3965,12 +3967,12 @@ static void drbdd(struct drbd_tconn *tconn)
goto err_out;
}
- if (drbd_cmd_handler[pi.cmd].fa_type == CONN) {
- err = drbd_cmd_handler[pi.cmd].conn_fn(tconn, pi.cmd, pi.size - shs);
+ if (cmd->fa_type == CONN) {
+ err = cmd->conn_fn(tconn, pi.cmd, pi.size - shs);
} else {
struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr);
err = mdev ?
- drbd_cmd_handler[pi.cmd].mdev_fn(mdev, pi.cmd, pi.size - shs) :
+ cmd->mdev_fn(mdev, pi.cmd, pi.size - shs) :
tconn_receive_skip(tconn, pi.cmd, pi.size - shs);
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 12/14] drbd: Remove useless error messages
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (10 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 11/14] drbd: A small cleanup in drbdd() Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 13/14] drbd: Pass struct packet_info down to the receive functions Philipp Reisner
2011-09-07 14:17 ` [PATCH 14/14] drbd: Map from (connection, volume number) to device in the receive handlers Philipp Reisner
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
These messages can only trigger in case there is a pretty obvious
internal programming error.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index a4b24f9..227cddc 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2183,8 +2183,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_send_ack_ex(mdev, P_OV_RESULT, sector, size, ID_IN_SYNC);
break;
default:
- dev_err(DEV, "unexpected command (%s) in receive_DataRequest\n",
- cmdname(cmd));
+ BUG();
}
if (verb && __ratelimit(&drbd_ratelimit_state))
dev_err(DEV, "Can not satisfy peer's read request, "
@@ -2270,10 +2269,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
break;
default:
- dev_err(DEV, "unexpected command (%s) in receive_DataRequest\n",
- cmdname(cmd));
- fault_type = DRBD_FAULT_MAX;
- goto out_free_e;
+ BUG();
}
/* Throttle, drbd_rs_begin_io and submit should become asynchronous
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 13/14] drbd: Pass struct packet_info down to the receive functions
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (11 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 12/14] drbd: Remove useless error messages Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
2011-09-07 14:17 ` [PATCH 14/14] drbd: Map from (connection, volume number) to device in the receive handlers Philipp Reisner
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 150 ++++++++++++++++--------------------
1 files changed, 65 insertions(+), 85 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 227cddc..856ac23 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -50,8 +50,8 @@
struct packet_info {
enum drbd_packet cmd;
- int size;
- int vnr;
+ unsigned int size;
+ unsigned int vnr;
};
enum finish_epoch {
@@ -1543,8 +1543,7 @@ find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id,
return NULL;
}
-static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_DataReply(struct drbd_conf *mdev, struct packet_info *pi)
{
struct drbd_request *req;
sector_t sector;
@@ -1562,7 +1561,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
* special casing it there for the various failure cases.
* still no race with drbd_fail_pending_reads */
- err = recv_dless_read(mdev, req, sector, data_size);
+ err = recv_dless_read(mdev, req, sector, pi->size);
if (!err)
req_mod(req, DATA_RECEIVED);
/* else: nothing. handled from drbd_disconnect...
@@ -1572,8 +1571,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
return err;
}
-static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_RSDataReply(struct drbd_conf *mdev, struct packet_info *pi)
{
sector_t sector;
int err;
@@ -1586,17 +1584,17 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
/* data is submitted to disk within recv_resync_read.
* corresponding put_ldev done below on error,
* or in drbd_peer_request_endio. */
- err = recv_resync_read(mdev, sector, data_size);
+ err = recv_resync_read(mdev, sector, pi->size);
} else {
if (__ratelimit(&drbd_ratelimit_state))
dev_err(DEV, "Can not write resync data to local disk.\n");
- err = drbd_drain_block(mdev, data_size);
+ err = drbd_drain_block(mdev, pi->size);
- drbd_send_ack_dp(mdev, P_NEG_ACK, p, data_size);
+ drbd_send_ack_dp(mdev, P_NEG_ACK, p, pi->size);
}
- atomic_add(data_size >> 9, &mdev->rs_sect_in);
+ atomic_add(pi->size >> 9, &mdev->rs_sect_in);
return err;
}
@@ -1961,8 +1959,7 @@ static int handle_write_conflicts(struct drbd_conf *mdev,
}
/* mirrored write */
-static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_Data(struct drbd_conf *mdev, struct packet_info *pi)
{
sector_t sector;
struct drbd_peer_request *peer_req;
@@ -1976,9 +1973,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
int err2;
err = wait_for_and_update_peer_seq(mdev, peer_seq);
- drbd_send_ack_dp(mdev, P_NEG_ACK, p, data_size);
+ drbd_send_ack_dp(mdev, P_NEG_ACK, p, pi->size);
atomic_inc(&mdev->current_epoch->epoch_size);
- err2 = drbd_drain_block(mdev, data_size);
+ err2 = drbd_drain_block(mdev, pi->size);
if (!err)
err = err2;
return err;
@@ -1991,7 +1988,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
*/
sector = be64_to_cpu(p->sector);
- peer_req = read_in_block(mdev, p->block_id, sector, data_size);
+ peer_req = read_in_block(mdev, p->block_id, sector, pi->size);
if (!peer_req) {
put_ldev(mdev);
return -EIO;
@@ -2141,8 +2138,7 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector)
}
-static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int digest_size)
+static int receive_DataRequest(struct drbd_conf *mdev, struct packet_info *pi)
{
sector_t sector;
const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
@@ -2168,7 +2164,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) {
verb = 1;
- switch (cmd) {
+ switch (pi->cmd) {
case P_DATA_REQUEST:
drbd_send_ack_rp(mdev, P_NEG_DREPLY, p);
break;
@@ -2190,7 +2186,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
"no local data.\n");
/* drain possibly payload */
- return drbd_drain_block(mdev, digest_size);
+ return drbd_drain_block(mdev, pi->size);
}
/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
@@ -2202,7 +2198,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
return -ENOMEM;
}
- switch (cmd) {
+ switch (pi->cmd) {
case P_DATA_REQUEST:
peer_req->w.cb = w_e_end_data_req;
fault_type = DRBD_FAULT_DT_RD;
@@ -2219,25 +2215,25 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
case P_OV_REPLY:
case P_CSUM_RS_REQUEST:
fault_type = DRBD_FAULT_RS_RD;
- di = kmalloc(sizeof(*di) + digest_size, GFP_NOIO);
+ di = kmalloc(sizeof(*di) + pi->size, GFP_NOIO);
if (!di)
goto out_free_e;
- di->digest_size = digest_size;
+ di->digest_size = pi->size;
di->digest = (((char *)di)+sizeof(struct digest_info));
peer_req->digest = di;
peer_req->flags |= EE_HAS_DIGEST;
- if (drbd_recv(mdev->tconn, di->digest, digest_size) != digest_size)
+ if (drbd_recv_all(mdev->tconn, di->digest, pi->size))
goto out_free_e;
- if (cmd == P_CSUM_RS_REQUEST) {
+ if (pi->cmd == P_CSUM_RS_REQUEST) {
D_ASSERT(mdev->tconn->agreed_pro_version >= 89);
peer_req->w.cb = w_e_end_csum_rs_req;
/* used in the sector offset progress display */
mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
- } else if (cmd == P_OV_REPLY) {
+ } else if (pi->cmd == P_OV_REPLY) {
/* track progress, we may need to throttle */
atomic_add(size >> 9, &mdev->rs_sect_in);
peer_req->w.cb = w_e_end_ov_reply;
@@ -2863,8 +2859,7 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self)
return 1;
}
-static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
{
struct p_protocol *p = tconn->data.rbuf;
int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
@@ -2918,7 +2913,7 @@ static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd,
unsigned char *my_alg = tconn->net_conf->integrity_alg;
int err;
- err = drbd_recv_all(tconn, p_integrity_alg, data_size);
+ err = drbd_recv_all(tconn, p_integrity_alg, pi->size);
if (err)
return err;
@@ -2965,8 +2960,7 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
return tfm;
}
-static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int packet_size)
+static int receive_SyncParam(struct drbd_conf *mdev, struct packet_info *pi)
{
struct p_rs_param_95 *p = mdev->tconn->data.rbuf;
unsigned int header_size, data_size, exp_max_sz;
@@ -2983,22 +2977,22 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
: apv <= 94 ? sizeof(struct p_rs_param_89)
: /* apv >= 95 */ sizeof(struct p_rs_param_95);
- if (packet_size > exp_max_sz) {
+ if (pi->size > exp_max_sz) {
dev_err(DEV, "SyncParam packet too long: received %u, expected <= %u bytes\n",
- packet_size, exp_max_sz);
+ pi->size, exp_max_sz);
return -EIO;
}
if (apv <= 88) {
header_size = sizeof(struct p_rs_param) - sizeof(struct p_header);
- data_size = packet_size - header_size;
+ data_size = pi->size - header_size;
} else if (apv <= 94) {
header_size = sizeof(struct p_rs_param_89) - sizeof(struct p_header);
- data_size = packet_size - header_size;
+ data_size = pi->size - header_size;
D_ASSERT(data_size == 0);
} else {
header_size = sizeof(struct p_rs_param_95) - sizeof(struct p_header);
- data_size = packet_size - header_size;
+ data_size = pi->size - header_size;
D_ASSERT(data_size == 0);
}
@@ -3132,8 +3126,7 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev,
(unsigned long long)a, (unsigned long long)b);
}
-static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_sizes(struct drbd_conf *mdev, struct packet_info *pi)
{
struct p_sizes *p = mdev->tconn->data.rbuf;
enum determine_dev_size dd = unchanged;
@@ -3230,8 +3223,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
return 0;
}
-static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_uuids(struct drbd_conf *mdev, struct packet_info *pi)
{
struct p_uuids *p = mdev->tconn->data.rbuf;
u64 *p_uuid;
@@ -3326,8 +3318,7 @@ static union drbd_state convert_state(union drbd_state ps)
return ms;
}
-static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_req_state(struct drbd_conf *mdev, struct packet_info *pi)
{
struct p_req_state *p = mdev->tconn->data.rbuf;
union drbd_state mask, val;
@@ -3353,8 +3344,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
return 0;
}
-static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *pi)
{
struct p_req_state *p = tconn->data.rbuf;
union drbd_state mask, val;
@@ -3378,8 +3368,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd
return 0;
}
-static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_state(struct drbd_conf *mdev, struct packet_info *pi)
{
struct p_state *p = mdev->tconn->data.rbuf;
union drbd_state os, ns, peer_state;
@@ -3531,8 +3520,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
return 0;
}
-static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_sync_uuid(struct drbd_conf *mdev, struct packet_info *pi)
{
struct p_rs_uuid *p = mdev->tconn->data.rbuf;
@@ -3741,13 +3729,11 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
in order to be agnostic to the 32 vs 64 bits issue.
returns 0 on failure, 1 if we successfully received it. */
-static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_bitmap(struct drbd_conf *mdev, struct packet_info *pi)
{
struct bm_xfer_ctx c;
int err;
struct p_header *h = mdev->tconn->data.rbuf;
- struct packet_info pi;
drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
/* you are supposed to send additional out-of-sync information
@@ -3759,48 +3745,46 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
};
for(;;) {
- if (cmd == P_BITMAP) {
- err = receive_bitmap_plain(mdev, data_size, h, &c);
- } else if (cmd == P_COMPRESSED_BITMAP) {
+ if (pi->cmd == P_BITMAP) {
+ err = receive_bitmap_plain(mdev, pi->size, h, &c);
+ } else if (pi->cmd == P_COMPRESSED_BITMAP) {
/* MAYBE: sanity check that we speak proto >= 90,
* and the feature is enabled! */
struct p_compressed_bm *p;
- if (data_size > BM_PACKET_PAYLOAD_BYTES) {
+ if (pi->size > BM_PACKET_PAYLOAD_BYTES) {
dev_err(DEV, "ReportCBitmap packet too large\n");
err = -EIO;
goto out;
}
p = mdev->tconn->data.rbuf;
- err = drbd_recv_all(mdev->tconn, p->head.payload, data_size);
+ err = drbd_recv_all(mdev->tconn, p->head.payload, pi->size);
if (err)
goto out;
- if (data_size <= (sizeof(*p) - sizeof(p->head))) {
- dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", data_size);
+ if (pi->size <= (sizeof(*p) - sizeof(p->head))) {
+ dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", pi->size);
err = -EIO;
goto out;
}
- err = decode_bitmap_c(mdev, p, &c, data_size);
+ err = decode_bitmap_c(mdev, p, &c, pi->size);
} else {
- dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", cmd);
+ dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd);
err = -EIO;
goto out;
}
- c.packets[cmd == P_BITMAP]++;
- c.bytes[cmd == P_BITMAP] += sizeof(struct p_header) + data_size;
+ c.packets[pi->cmd == P_BITMAP]++;
+ c.bytes[pi->cmd == P_BITMAP] += sizeof(struct p_header) + pi->size;
if (err <= 0) {
if (err < 0)
goto out;
break;
}
- err = drbd_recv_header(mdev->tconn, &pi);
+ err = drbd_recv_header(mdev->tconn, pi);
if (err)
goto out;
- cmd = pi.cmd;
- data_size = pi.size;
}
INFO_bm_xfer_stats(mdev, "receive", &c);
@@ -3846,25 +3830,23 @@ static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size)
return size ? -EIO : 0;
}
-static int receive_skip(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_skip(struct drbd_conf *mdev, struct packet_info *pi)
{
dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n",
- cmd, data_size);
+ pi->cmd, pi->size);
- return _tconn_receive_skip(mdev->tconn, data_size);
+ return _tconn_receive_skip(mdev->tconn, pi->size);
}
-static int tconn_receive_skip(struct drbd_tconn *tconn, enum drbd_packet cmd, unsigned int data_size)
+static int tconn_receive_skip(struct drbd_tconn *tconn, struct packet_info *pi)
{
conn_warn(tconn, "skipping packet for non existing volume type %d, l: %d!\n",
- cmd, data_size);
+ pi->cmd, pi->size);
- return _tconn_receive_skip(tconn, data_size);
+ return _tconn_receive_skip(tconn, pi->size);
}
-static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_UnplugRemote(struct drbd_conf *mdev, struct packet_info *pi)
{
/* Make sure we've acked all the TCP data associated
* with the data requests being unplugged */
@@ -3873,8 +3855,7 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd,
return 0;
}
-static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_out_of_sync(struct drbd_conf *mdev, struct packet_info *pi)
{
struct p_block_desc *p = mdev->tconn->data.rbuf;
@@ -3898,10 +3879,8 @@ struct data_cmd {
size_t pkt_size;
enum mdev_or_conn fa_type; /* first argument's type */
union {
- int (*mdev_fn)(struct drbd_conf *, enum drbd_packet cmd,
- unsigned int to_receive);
- int (*conn_fn)(struct drbd_tconn *, enum drbd_packet cmd,
- unsigned int to_receive);
+ int (*mdev_fn)(struct drbd_conf *, struct packet_info *);
+ int (*conn_fn)(struct drbd_tconn *, struct packet_info *);
};
};
@@ -3961,15 +3940,16 @@ static void drbdd(struct drbd_tconn *tconn)
err = drbd_recv_all_warn(tconn, &header->payload, shs);
if (err)
goto err_out;
+ pi.size -= shs;
}
- if (cmd->fa_type == CONN) {
- err = cmd->conn_fn(tconn, pi.cmd, pi.size - shs);
- } else {
+ if (cmd->fa_type == CONN)
+ err = cmd->conn_fn(tconn, &pi);
+ else {
struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr);
err = mdev ?
- cmd->mdev_fn(mdev, pi.cmd, pi.size - shs) :
- tconn_receive_skip(tconn, pi.cmd, pi.size - shs);
+ cmd->mdev_fn(mdev, &pi) :
+ tconn_receive_skip(tconn, &pi);
}
if (unlikely(err)) {
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 14/14] drbd: Map from (connection, volume number) to device in the receive handlers
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
` (12 preceding siblings ...)
2011-09-07 14:17 ` [PATCH 13/14] drbd: Pass struct packet_info down to the receive functions Philipp Reisner
@ 2011-09-07 14:17 ` Philipp Reisner
13 siblings, 0 replies; 15+ messages in thread
From: Philipp Reisner @ 2011-09-07 14:17 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
The receive handlers do not all handle unknown volume numbers the same
way.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 262 ++++++++++++++++++++++--------------
1 files changed, 164 insertions(+), 98 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 856ac23..218d97d7 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1235,13 +1235,17 @@ static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev,
wake_up(&mdev->misc_wait);
}
-static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
- unsigned int data_size)
+static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
{
+ struct drbd_conf *mdev;
int rv;
- struct p_barrier *p = mdev->tconn->data.rbuf;
+ struct p_barrier *p = tconn->data.rbuf;
struct drbd_epoch *epoch;
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
+
inc_unacked(mdev);
mdev->current_epoch->barrier_nr = p->barrier;
@@ -1543,12 +1547,17 @@ find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id,
return NULL;
}
-static int receive_DataReply(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_DataReply(struct drbd_tconn *tconn, struct packet_info *pi)
{
+ struct drbd_conf *mdev;
struct drbd_request *req;
sector_t sector;
int err;
- struct p_data *p = mdev->tconn->data.rbuf;
+ struct p_data *p = tconn->data.rbuf;
+
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
sector = be64_to_cpu(p->sector);
@@ -1571,11 +1580,16 @@ static int receive_DataReply(struct drbd_conf *mdev, struct packet_info *pi)
return err;
}
-static int receive_RSDataReply(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_RSDataReply(struct drbd_tconn *tconn, struct packet_info *pi)
{
+ struct drbd_conf *mdev;
sector_t sector;
int err;
- struct p_data *p = mdev->tconn->data.rbuf;
+ struct p_data *p = tconn->data.rbuf;
+
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
sector = be64_to_cpu(p->sector);
D_ASSERT(p->block_id == ID_SYNCER);
@@ -1959,16 +1973,21 @@ static int handle_write_conflicts(struct drbd_conf *mdev,
}
/* mirrored write */
-static int receive_Data(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_Data(struct drbd_tconn *tconn, struct packet_info *pi)
{
+ struct drbd_conf *mdev;
sector_t sector;
struct drbd_peer_request *peer_req;
- struct p_data *p = mdev->tconn->data.rbuf;
+ struct p_data *p = tconn->data.rbuf;
u32 peer_seq = be32_to_cpu(p->seq_num);
int rw = WRITE;
u32 dp_flags;
int err;
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
+
if (!get_ldev(mdev)) {
int err2;
@@ -2138,15 +2157,21 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector)
}
-static int receive_DataRequest(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_DataRequest(struct drbd_tconn *tconn, struct packet_info *pi)
{
+ struct drbd_conf *mdev;
sector_t sector;
- const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
+ sector_t capacity;
struct drbd_peer_request *peer_req;
struct digest_info *di = NULL;
int size, verb;
unsigned int fault_type;
- struct p_block_req *p = mdev->tconn->data.rbuf;
+ struct p_block_req *p = tconn->data.rbuf;
+
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
+ capacity = drbd_get_capacity(mdev->this_bdev);
sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize);
@@ -2960,17 +2985,60 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
return tfm;
}
-static int receive_SyncParam(struct drbd_conf *mdev, struct packet_info *pi)
+static int ignore_remaining_packet(struct drbd_tconn *tconn, struct packet_info *pi)
+{
+ void *buffer = tconn->data.rbuf;
+ int size = pi->size;
+
+ while (size) {
+ int s = min_t(int, size, DRBD_SOCKET_BUFFER_SIZE);
+ s = drbd_recv(tconn, buffer, s);
+ if (s <= 0) {
+ if (s < 0)
+ return s;
+ break;
+ }
+ size -= s;
+ }
+ if (size)
+ return -EIO;
+ return 0;
+}
+
+/*
+ * config_unknown_volume - device configuration command for unknown volume
+ *
+ * When a device is added to an existing connection, the node on which the
+ * device is added first will send configuration commands to its peer but the
+ * peer will not know about the device yet. It will warn and ignore these
+ * commands. Once the device is added on the second node, the second node will
+ * send the same device configuration commands, but in the other direction.
+ *
+ * (We can also end up here if drbd is misconfigured.)
+ */
+static int config_unknown_volume(struct drbd_tconn *tconn, struct packet_info *pi)
+{
+ conn_warn(tconn, "Volume %u unknown; ignoring %s packet\n",
+ pi->vnr, cmdname(pi->cmd));
+ return ignore_remaining_packet(tconn, pi);
+}
+
+static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_rs_param_95 *p = mdev->tconn->data.rbuf;
+ struct drbd_conf *mdev;
+ struct p_rs_param_95 *p = tconn->data.rbuf;
unsigned int header_size, data_size, exp_max_sz;
struct crypto_hash *verify_tfm = NULL;
struct crypto_hash *csums_tfm = NULL;
- const int apv = mdev->tconn->agreed_pro_version;
+ const int apv = tconn->agreed_pro_version;
int *rs_plan_s = NULL;
int fifo_size = 0;
int err;
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return config_unknown_volume(tconn, pi);
+
exp_max_sz = apv <= 87 ? sizeof(struct p_rs_param)
: apv == 88 ? sizeof(struct p_rs_param)
+ SHARED_SECRET_MAX
@@ -3126,14 +3194,19 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev,
(unsigned long long)a, (unsigned long long)b);
}
-static int receive_sizes(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_sizes *p = mdev->tconn->data.rbuf;
+ struct drbd_conf *mdev;
+ struct p_sizes *p = tconn->data.rbuf;
enum determine_dev_size dd = unchanged;
sector_t p_size, p_usize, my_usize;
int ldsc = 0; /* local disk size changed */
enum dds_flags ddsf;
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return config_unknown_volume(tconn, pi);
+
p_size = be64_to_cpu(p->d_size);
p_usize = be64_to_cpu(p->u_size);
@@ -3223,12 +3296,17 @@ static int receive_sizes(struct drbd_conf *mdev, struct packet_info *pi)
return 0;
}
-static int receive_uuids(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_uuids(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_uuids *p = mdev->tconn->data.rbuf;
+ struct drbd_conf *mdev;
+ struct p_uuids *p = tconn->data.rbuf;
u64 *p_uuid;
int i, updated_uuids = 0;
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return config_unknown_volume(tconn, pi);
+
p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO);
for (i = UI_CURRENT; i < UI_EXTENDED_SIZE; i++)
@@ -3318,12 +3396,17 @@ static union drbd_state convert_state(union drbd_state ps)
return ms;
}
-static int receive_req_state(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_req_state *p = mdev->tconn->data.rbuf;
+ struct drbd_conf *mdev;
+ struct p_req_state *p = tconn->data.rbuf;
union drbd_state mask, val;
enum drbd_state_rv rv;
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
+
mask.i = be32_to_cpu(p->mask);
val.i = be32_to_cpu(p->val);
@@ -3368,14 +3451,19 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *
return 0;
}
-static int receive_state(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_state *p = mdev->tconn->data.rbuf;
+ struct drbd_conf *mdev;
+ struct p_state *p = tconn->data.rbuf;
union drbd_state os, ns, peer_state;
enum drbd_disk_state real_peer_disk;
enum chg_state_flags cs_flags;
int rv;
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return config_unknown_volume(tconn, pi);
+
peer_state.i = be32_to_cpu(p->state);
real_peer_disk = peer_state.disk;
@@ -3520,9 +3608,14 @@ static int receive_state(struct drbd_conf *mdev, struct packet_info *pi)
return 0;
}
-static int receive_sync_uuid(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_rs_uuid *p = mdev->tconn->data.rbuf;
+ struct drbd_conf *mdev;
+ struct p_rs_uuid *p = tconn->data.rbuf;
+
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
wait_event(mdev->misc_wait,
mdev->state.conn == C_WF_SYNC_UUID ||
@@ -3729,11 +3822,16 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
in order to be agnostic to the 32 vs 64 bits issue.
returns 0 on failure, 1 if we successfully received it. */
-static int receive_bitmap(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
{
+ struct drbd_conf *mdev;
struct bm_xfer_ctx c;
int err;
- struct p_header *h = mdev->tconn->data.rbuf;
+ struct p_header *h = tconn->data.rbuf;
+
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
/* you are supposed to send additional out-of-sync information
@@ -3813,51 +3911,31 @@ static int receive_bitmap(struct drbd_conf *mdev, struct packet_info *pi)
return err;
}
-static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size)
-{
- /* TODO zero copy sink :) */
- static char sink[128];
- int size, want, r;
-
- size = data_size;
- while (size > 0) {
- want = min_t(int, size, sizeof(sink));
- r = drbd_recv(tconn, sink, want);
- if (r <= 0)
- break;
- size -= r;
- }
- return size ? -EIO : 0;
-}
-
-static int receive_skip(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_skip(struct drbd_tconn *tconn, struct packet_info *pi)
{
- dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n",
+ conn_warn(tconn, "skipping unknown optional packet type %d, l: %d!\n",
pi->cmd, pi->size);
- return _tconn_receive_skip(mdev->tconn, pi->size);
+ return ignore_remaining_packet(tconn, pi);
}
-static int tconn_receive_skip(struct drbd_tconn *tconn, struct packet_info *pi)
-{
- conn_warn(tconn, "skipping packet for non existing volume type %d, l: %d!\n",
- pi->cmd, pi->size);
-
- return _tconn_receive_skip(tconn, pi->size);
-}
-
-static int receive_UnplugRemote(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_UnplugRemote(struct drbd_tconn *tconn, struct packet_info *pi)
{
/* Make sure we've acked all the TCP data associated
* with the data requests being unplugged */
- drbd_tcp_quickack(mdev->tconn->data.socket);
+ drbd_tcp_quickack(tconn->data.socket);
return 0;
}
-static int receive_out_of_sync(struct drbd_conf *mdev, struct packet_info *pi)
+static int receive_out_of_sync(struct drbd_tconn *tconn, struct packet_info *pi)
{
- struct p_block_desc *p = mdev->tconn->data.rbuf;
+ struct drbd_conf *mdev;
+ struct p_block_desc *p = tconn->data.rbuf;
+
+ mdev = vnr_to_mdev(tconn, pi->vnr);
+ if (!mdev)
+ return -EIO;
switch (mdev->state.conn) {
case C_WF_SYNC_UUID:
@@ -3877,37 +3955,33 @@ static int receive_out_of_sync(struct drbd_conf *mdev, struct packet_info *pi)
struct data_cmd {
int expect_payload;
size_t pkt_size;
- enum mdev_or_conn fa_type; /* first argument's type */
- union {
- int (*mdev_fn)(struct drbd_conf *, struct packet_info *);
- int (*conn_fn)(struct drbd_tconn *, struct packet_info *);
- };
+ int (*fn)(struct drbd_tconn *, struct packet_info *);
};
static struct data_cmd drbd_cmd_handler[] = {
- [P_DATA] = { 1, sizeof(struct p_data), MDEV, { receive_Data } },
- [P_DATA_REPLY] = { 1, sizeof(struct p_data), MDEV, { receive_DataReply } },
- [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), MDEV, { receive_RSDataReply } } ,
- [P_BARRIER] = { 0, sizeof(struct p_barrier), MDEV, { receive_Barrier } } ,
- [P_BITMAP] = { 1, sizeof(struct p_header), MDEV, { receive_bitmap } } ,
- [P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), MDEV, { receive_bitmap } } ,
- [P_UNPLUG_REMOTE] = { 0, sizeof(struct p_header), MDEV, { receive_UnplugRemote } },
- [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), MDEV, { receive_DataRequest } },
- [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), MDEV, { receive_DataRequest } },
- [P_SYNC_PARAM] = { 1, sizeof(struct p_header), MDEV, { receive_SyncParam } },
- [P_SYNC_PARAM89] = { 1, sizeof(struct p_header), MDEV, { receive_SyncParam } },
- [P_PROTOCOL] = { 1, sizeof(struct p_protocol), CONN, { .conn_fn = receive_protocol } },
- [P_UUIDS] = { 0, sizeof(struct p_uuids), MDEV, { receive_uuids } },
- [P_SIZES] = { 0, sizeof(struct p_sizes), MDEV, { receive_sizes } },
- [P_STATE] = { 0, sizeof(struct p_state), MDEV, { receive_state } },
- [P_STATE_CHG_REQ] = { 0, sizeof(struct p_req_state), MDEV, { receive_req_state } },
- [P_SYNC_UUID] = { 0, sizeof(struct p_rs_uuid), MDEV, { receive_sync_uuid } },
- [P_OV_REQUEST] = { 0, sizeof(struct p_block_req), MDEV, { receive_DataRequest } },
- [P_OV_REPLY] = { 1, sizeof(struct p_block_req), MDEV, { receive_DataRequest } },
- [P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), MDEV, { receive_DataRequest } },
- [P_DELAY_PROBE] = { 0, sizeof(struct p_delay_probe93), MDEV, { receive_skip } },
- [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), MDEV, { receive_out_of_sync } },
- [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), CONN, { .conn_fn = receive_req_conn_state } },
+ [P_DATA] = { 1, sizeof(struct p_data), receive_Data },
+ [P_DATA_REPLY] = { 1, sizeof(struct p_data), receive_DataReply },
+ [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), receive_RSDataReply } ,
+ [P_BARRIER] = { 0, sizeof(struct p_barrier), receive_Barrier } ,
+ [P_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } ,
+ [P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } ,
+ [P_UNPLUG_REMOTE] = { 0, sizeof(struct p_header), receive_UnplugRemote },
+ [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
+ [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
+ [P_SYNC_PARAM] = { 1, sizeof(struct p_header), receive_SyncParam },
+ [P_SYNC_PARAM89] = { 1, sizeof(struct p_header), receive_SyncParam },
+ [P_PROTOCOL] = { 1, sizeof(struct p_protocol), receive_protocol },
+ [P_UUIDS] = { 0, sizeof(struct p_uuids), receive_uuids },
+ [P_SIZES] = { 0, sizeof(struct p_sizes), receive_sizes },
+ [P_STATE] = { 0, sizeof(struct p_state), receive_state },
+ [P_STATE_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_state },
+ [P_SYNC_UUID] = { 0, sizeof(struct p_rs_uuid), receive_sync_uuid },
+ [P_OV_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
+ [P_OV_REPLY] = { 1, sizeof(struct p_block_req), receive_DataRequest },
+ [P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), receive_DataRequest },
+ [P_DELAY_PROBE] = { 0, sizeof(struct p_delay_probe93), receive_skip },
+ [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), receive_out_of_sync },
+ [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_conn_state },
};
static void drbdd(struct drbd_tconn *tconn)
@@ -3925,7 +3999,7 @@ static void drbdd(struct drbd_tconn *tconn)
goto err_out;
cmd = &drbd_cmd_handler[pi.cmd];
- if (unlikely(pi.cmd >= ARRAY_SIZE(drbd_cmd_handler) || !cmd->mdev_fn)) {
+ if (unlikely(pi.cmd >= ARRAY_SIZE(drbd_cmd_handler) || !cmd->fn)) {
conn_err(tconn, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size);
goto err_out;
}
@@ -3943,16 +4017,8 @@ static void drbdd(struct drbd_tconn *tconn)
pi.size -= shs;
}
- if (cmd->fa_type == CONN)
- err = cmd->conn_fn(tconn, &pi);
- else {
- struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr);
- err = mdev ?
- cmd->mdev_fn(mdev, &pi) :
- tconn_receive_skip(tconn, &pi);
- }
-
- if (unlikely(err)) {
+ err = cmd->fn(tconn, &pi);
+ if (err) {
conn_err(tconn, "error receiving %s, l: %d!\n",
cmdname(pi.cmd), pi.size);
goto err_out;
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2011-09-07 16:51 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-07 14:17 [RFC 00/14] drbd: part 7 of adding multiple volume support to drbd Philipp Reisner
2011-09-07 14:17 ` [PATCH 01/14] drbd: drbd_connected(): Return an error code upon failure Philipp Reisner
2011-09-07 14:17 ` [PATCH 02/14] drbd: Always use the same protocol version for the same peer Philipp Reisner
2011-09-07 14:17 ` [PATCH 03/14] drbd: Move drbd_send_ping() and drbd_send_ping_ack() to drbd_main.c Philipp Reisner
2011-09-07 14:17 ` [PATCH 04/14] drbd: Make _drbd_send_bitmap() static Philipp Reisner
2011-09-07 14:17 ` [PATCH 05/14] drbd: Rename the DCBP_* functions to dcbp_* and move them to where they are used Philipp Reisner
2011-09-07 14:17 ` [PATCH 06/14] drbd: Converted drbd_try_outdate_peer() from mdev to tconn Philipp Reisner
2011-09-07 14:17 ` [PATCH 07/14] drbd: Preallocate one page per drbd_socket as a receive buffer Philipp Reisner
2011-09-07 14:17 ` [PATCH 08/14] drbd: receive_bitmap(): Use the pre-allocated " Philipp Reisner
2011-09-07 14:17 ` [PATCH 09/14] drbd: Preallocate one page per drbd_socket as a send buffer Philipp Reisner
2011-09-07 14:17 ` [PATCH 10/14] drbd: _drbd_send_bitmap(): Use the pre-allocated " Philipp Reisner
2011-09-07 14:17 ` [PATCH 11/14] drbd: A small cleanup in drbdd() Philipp Reisner
2011-09-07 14:17 ` [PATCH 12/14] drbd: Remove useless error messages Philipp Reisner
2011-09-07 14:17 ` [PATCH 13/14] drbd: Pass struct packet_info down to the receive functions Philipp Reisner
2011-09-07 14:17 ` [PATCH 14/14] drbd: Map from (connection, volume number) to device in the receive handlers Philipp Reisner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®