aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_int.h
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-02-21 20:15:32 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-10-14 10:47:51 -0400
commit7be8da0798f08fb9564d4f64fe4a7d6fb4fab20b (patch)
treecdcc85b5152562bd40065cecec7f571098851881 /drivers/block/drbd/drbd_int.h
parent71b1c1eb9c544141e743c4d14b3c576fd4c31a5a (diff)
drbd: Improve how conflicting writes are handled
The previous algorithm for dealing with overlapping concurrent writes was generating unnecessary warnings for scenarios which could be legitimate, and did not always handle partially overlapping requests correctly. Improve it algorithm as follows: * While local or remote write requests are in progress, conflicting new local write requests will be delayed (commit 82172f7). * When a conflict between a local and remote write request is detected, the node with the discard flag decides how to resolve the conflict: It will ask its peer to discard conflicting requests which are fully contained in the local request and retry requests which overlap only partially. This involves a protocol change. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_int.h')
-rw-r--r--drivers/block/drbd/drbd_int.h15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 3213808a898a..17e905d0582d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -200,7 +200,7 @@ enum drbd_packet {
200 P_RECV_ACK = 0x15, /* Used in protocol B */ 200 P_RECV_ACK = 0x15, /* Used in protocol B */
201 P_WRITE_ACK = 0x16, /* Used in protocol C */ 201 P_WRITE_ACK = 0x16, /* Used in protocol C */
202 P_RS_WRITE_ACK = 0x17, /* Is a P_WRITE_ACK, additionally call set_in_sync(). */ 202 P_RS_WRITE_ACK = 0x17, /* Is a P_WRITE_ACK, additionally call set_in_sync(). */
203 P_DISCARD_ACK = 0x18, /* Used in proto C, two-primaries conflict detection */ 203 P_DISCARD_WRITE = 0x18, /* Used in proto C, two-primaries conflict detection */
204 P_NEG_ACK = 0x19, /* Sent if local disk is unusable */ 204 P_NEG_ACK = 0x19, /* Sent if local disk is unusable */
205 P_NEG_DREPLY = 0x1a, /* Local disk is broken... */ 205 P_NEG_DREPLY = 0x1a, /* Local disk is broken... */
206 P_NEG_RS_DREPLY = 0x1b, /* Local disk is broken... */ 206 P_NEG_RS_DREPLY = 0x1b, /* Local disk is broken... */
@@ -223,8 +223,9 @@ enum drbd_packet {
223 P_RS_CANCEL = 0x29, /* meta: Used to cancel RS_DATA_REQUEST packet by SyncSource */ 223 P_RS_CANCEL = 0x29, /* meta: Used to cancel RS_DATA_REQUEST packet by SyncSource */
224 P_CONN_ST_CHG_REQ = 0x2a, /* data sock: Connection wide state request */ 224 P_CONN_ST_CHG_REQ = 0x2a, /* data sock: Connection wide state request */
225 P_CONN_ST_CHG_REPLY = 0x2b, /* meta sock: Connection side state req reply */ 225 P_CONN_ST_CHG_REPLY = 0x2b, /* meta sock: Connection side state req reply */
226 P_RETRY_WRITE = 0x2c, /* Protocol C: retry conflicting write request */
226 227
227 P_MAX_CMD = 0x2c, 228 P_MAX_CMD = 0x2d,
228 P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */ 229 P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */
229 P_MAX_OPT_CMD = 0x101, 230 P_MAX_OPT_CMD = 0x101,
230 231
@@ -350,7 +351,7 @@ struct p_data {
350 * commands which share a struct: 351 * commands which share a struct:
351 * p_block_ack: 352 * p_block_ack:
352 * P_RECV_ACK (proto B), P_WRITE_ACK (proto C), 353 * P_RECV_ACK (proto B), P_WRITE_ACK (proto C),
353 * P_DISCARD_ACK (proto C, two-primaries conflict detection) 354 * P_DISCARD_WRITE (proto C, two-primaries conflict detection)
354 * p_block_req: 355 * p_block_req:
355 * P_DATA_REQUEST, P_RS_DATA_REQUEST 356 * P_DATA_REQUEST, P_RS_DATA_REQUEST
356 */ 357 */
@@ -362,7 +363,6 @@ struct p_block_ack {
362 u32 seq_num; 363 u32 seq_num;
363} __packed; 364} __packed;
364 365
365
366struct p_block_req { 366struct p_block_req {
367 struct p_header head; 367 struct p_header head;
368 u64 sector; 368 u64 sector;
@@ -655,6 +655,8 @@ struct drbd_work {
655 655
656#include "drbd_interval.h" 656#include "drbd_interval.h"
657 657
658extern int drbd_wait_misc(struct drbd_conf *, struct drbd_interval *);
659
658struct drbd_request { 660struct drbd_request {
659 struct drbd_work w; 661 struct drbd_work w;
660 662
@@ -752,12 +754,16 @@ enum {
752 754
753 /* This ee has a pointer to a digest instead of a block id */ 755 /* This ee has a pointer to a digest instead of a block id */
754 __EE_HAS_DIGEST, 756 __EE_HAS_DIGEST,
757
758 /* Conflicting local requests need to be restarted after this request */
759 __EE_RESTART_REQUESTS,
755}; 760};
756#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) 761#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)
757#define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) 762#define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC)
758#define EE_RESUBMITTED (1<<__EE_RESUBMITTED) 763#define EE_RESUBMITTED (1<<__EE_RESUBMITTED)
759#define EE_WAS_ERROR (1<<__EE_WAS_ERROR) 764#define EE_WAS_ERROR (1<<__EE_WAS_ERROR)
760#define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) 765#define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST)
766#define EE_RESTART_REQUESTS (1<<__EE_RESTART_REQUESTS)
761 767
762/* flag bits per mdev */ 768/* flag bits per mdev */
763enum { 769enum {
@@ -1478,6 +1484,7 @@ extern void drbd_free_tconn(struct drbd_tconn *tconn);
1478extern int proc_details; 1484extern int proc_details;
1479 1485
1480/* drbd_req */ 1486/* drbd_req */
1487extern int __drbd_make_request(struct drbd_conf *, struct bio *, unsigned long);
1481extern int drbd_make_request(struct request_queue *q, struct bio *bio); 1488extern int drbd_make_request(struct request_queue *q, struct bio *bio);
1482extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req); 1489extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req);
1483extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec); 1490extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec);