提交 69a22773 编写于 作者: A Andreas Gruenbacher 提交者: Philipp Reisner

drbd: Pass a peer device to a number of fuctions

These functions actually operate on a peer device, or
need a peer device.

drbd_prepare_command(), drbd_send_command(), drbd_send_sync_param()
drbd_send_uuids(), drbd_gen_and_send_sync_uuid(), drbd_send_sizes()
drbd_send_state(), drbd_send_current_state(), and drbd_send_state_req()
drbd_send_sr_reply(), drbd_send_ack(), drbd_send_drequest(),
drbd_send_drequest_csum(), drbd_send_ov_request(), drbd_send_dblock()
drbd_send_block(), drbd_send_out_of_sync(), recv_dless_read()
drbd_drain_block(), receive_bitmap_plain(), recv_resync_read()
read_in_block(), read_for_csum(), drbd_alloc_pages(), drbd_alloc_peer_req()
need_peer_seq(), update_peer_seq(), wait_for_and_update_peer_seq()
drbd_sync_handshake(), drbd_asb_recover_{0,1,2}p(), drbd_connected()
drbd_disconnected(), decode_bitmap_c() and recv_bm_rle_bits()
Signed-off-by: NAndreas Gruenbacher <agruen@linbit.com>
Signed-off-by: NPhilipp Reisner <philipp.reisner@linbit.com>
上级 9f4fe9ad
...@@ -887,36 +887,36 @@ extern int drbd_send_all(struct drbd_connection *, struct socket *, void *, size ...@@ -887,36 +887,36 @@ extern int drbd_send_all(struct drbd_connection *, struct socket *, void *, size
extern int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd); extern int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd);
extern int drbd_send_protocol(struct drbd_connection *connection); extern int drbd_send_protocol(struct drbd_connection *connection);
extern int drbd_send_uuids(struct drbd_device *device); extern int drbd_send_uuids(struct drbd_peer_device *);
extern int drbd_send_uuids_skip_initial_sync(struct drbd_device *device); extern int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *);
extern void drbd_gen_and_send_sync_uuid(struct drbd_device *device); extern void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *);
extern int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flags flags); extern int drbd_send_sizes(struct drbd_peer_device *, int trigger_reply, enum dds_flags flags);
extern int drbd_send_state(struct drbd_device *device, union drbd_state s); extern int drbd_send_state(struct drbd_peer_device *, union drbd_state s);
extern int drbd_send_current_state(struct drbd_device *device); extern int drbd_send_current_state(struct drbd_peer_device *);
extern int drbd_send_sync_param(struct drbd_device *device); extern int drbd_send_sync_param(struct drbd_peer_device *);
extern void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr, extern void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr,
u32 set_size); u32 set_size);
extern int drbd_send_ack(struct drbd_device *, enum drbd_packet, extern int drbd_send_ack(struct drbd_peer_device *, enum drbd_packet,
struct drbd_peer_request *); struct drbd_peer_request *);
extern void drbd_send_ack_rp(struct drbd_device *device, enum drbd_packet cmd, extern void drbd_send_ack_rp(struct drbd_peer_device *, enum drbd_packet,
struct p_block_req *rp); struct p_block_req *rp);
extern void drbd_send_ack_dp(struct drbd_device *device, enum drbd_packet cmd, extern void drbd_send_ack_dp(struct drbd_peer_device *, enum drbd_packet,
struct p_data *dp, int data_size); struct p_data *dp, int data_size);
extern int drbd_send_ack_ex(struct drbd_device *device, enum drbd_packet cmd, extern int drbd_send_ack_ex(struct drbd_peer_device *, enum drbd_packet,
sector_t sector, int blksize, u64 block_id); sector_t sector, int blksize, u64 block_id);
extern int drbd_send_out_of_sync(struct drbd_device *, struct drbd_request *); extern int drbd_send_out_of_sync(struct drbd_peer_device *, struct drbd_request *);
extern int drbd_send_block(struct drbd_device *, enum drbd_packet, extern int drbd_send_block(struct drbd_peer_device *, enum drbd_packet,
struct drbd_peer_request *); struct drbd_peer_request *);
extern int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req); extern int drbd_send_dblock(struct drbd_peer_device *, struct drbd_request *req);
extern int drbd_send_drequest(struct drbd_device *device, int cmd, extern int drbd_send_drequest(struct drbd_peer_device *, int cmd,
sector_t sector, int size, u64 block_id); sector_t sector, int size, u64 block_id);
extern int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector, extern int drbd_send_drequest_csum(struct drbd_peer_device *, sector_t sector,
int size, void *digest, int digest_size, int size, void *digest, int digest_size,
enum drbd_packet cmd); enum drbd_packet cmd);
extern int drbd_send_ov_request(struct drbd_device *device, sector_t sector, int size); extern int drbd_send_ov_request(struct drbd_peer_device *, sector_t sector, int size);
extern int drbd_send_bitmap(struct drbd_device *device); extern int drbd_send_bitmap(struct drbd_device *device);
extern void drbd_send_sr_reply(struct drbd_device *device, enum drbd_state_rv retcode); extern void drbd_send_sr_reply(struct drbd_peer_device *, enum drbd_state_rv retcode);
extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode); extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode);
extern void drbd_free_bc(struct drbd_backing_dev *ldev); extern void drbd_free_bc(struct drbd_backing_dev *ldev);
extern void drbd_device_cleanup(struct drbd_device *device); extern void drbd_device_cleanup(struct drbd_device *device);
...@@ -1343,18 +1343,18 @@ extern int drbd_submit_peer_request(struct drbd_device *, ...@@ -1343,18 +1343,18 @@ extern int drbd_submit_peer_request(struct drbd_device *,
struct drbd_peer_request *, const unsigned, struct drbd_peer_request *, const unsigned,
const int); const int);
extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *); extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *);
extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_device *, u64, extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64,
sector_t, unsigned int, sector_t, unsigned int,
gfp_t) __must_hold(local); gfp_t) __must_hold(local);
extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *, extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *,
int); int);
#define drbd_free_peer_req(m,e) __drbd_free_peer_req(m, e, 0) #define drbd_free_peer_req(m,e) __drbd_free_peer_req(m, e, 0)
#define drbd_free_net_peer_req(m,e) __drbd_free_peer_req(m, e, 1) #define drbd_free_net_peer_req(m,e) __drbd_free_peer_req(m, e, 1)
extern struct page *drbd_alloc_pages(struct drbd_device *, unsigned int, bool); extern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool);
extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled); extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);
extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed); extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed);
extern void conn_flush_workqueue(struct drbd_connection *connection); extern void conn_flush_workqueue(struct drbd_connection *connection);
extern int drbd_connected(struct drbd_device *device); extern int drbd_connected(struct drbd_peer_device *);
static inline void drbd_flush_workqueue(struct drbd_device *device) static inline void drbd_flush_workqueue(struct drbd_device *device)
{ {
conn_flush_workqueue(first_peer_device(device)->connection); conn_flush_workqueue(first_peer_device(device)->connection);
...@@ -1726,17 +1726,17 @@ static inline void request_ping(struct drbd_connection *connection) ...@@ -1726,17 +1726,17 @@ static inline void request_ping(struct drbd_connection *connection)
} }
extern void *conn_prepare_command(struct drbd_connection *, struct drbd_socket *); extern void *conn_prepare_command(struct drbd_connection *, struct drbd_socket *);
extern void *drbd_prepare_command(struct drbd_device *, struct drbd_socket *); extern void *drbd_prepare_command(struct drbd_peer_device *, struct drbd_socket *);
extern int conn_send_command(struct drbd_connection *, struct drbd_socket *, extern int conn_send_command(struct drbd_connection *, struct drbd_socket *,
enum drbd_packet, unsigned int, void *, enum drbd_packet, unsigned int, void *,
unsigned int); unsigned int);
extern int drbd_send_command(struct drbd_device *, struct drbd_socket *, extern int drbd_send_command(struct drbd_peer_device *, struct drbd_socket *,
enum drbd_packet, unsigned int, void *, enum drbd_packet, unsigned int, void *,
unsigned int); unsigned int);
extern int drbd_send_ping(struct drbd_connection *connection); extern int drbd_send_ping(struct drbd_connection *connection);
extern int drbd_send_ping_ack(struct drbd_connection *connection); extern int drbd_send_ping_ack(struct drbd_connection *connection);
extern int drbd_send_state_req(struct drbd_device *, union drbd_state, union drbd_state); extern int drbd_send_state_req(struct drbd_peer_device *, union drbd_state, union drbd_state);
extern int conn_send_state_req(struct drbd_connection *, union drbd_state, union drbd_state); extern int conn_send_state_req(struct drbd_connection *, union drbd_state, union drbd_state);
static inline void drbd_thread_stop(struct drbd_thread *thi) static inline void drbd_thread_stop(struct drbd_thread *thi)
......
...@@ -642,9 +642,9 @@ void *conn_prepare_command(struct drbd_connection *connection, struct drbd_socke ...@@ -642,9 +642,9 @@ void *conn_prepare_command(struct drbd_connection *connection, struct drbd_socke
return p; return p;
} }
void *drbd_prepare_command(struct drbd_device *device, struct drbd_socket *sock) void *drbd_prepare_command(struct drbd_peer_device *peer_device, struct drbd_socket *sock)
{ {
return conn_prepare_command(first_peer_device(device)->connection, sock); return conn_prepare_command(peer_device->connection, sock);
} }
static int __send_command(struct drbd_connection *connection, int vnr, static int __send_command(struct drbd_connection *connection, int vnr,
...@@ -691,14 +691,14 @@ int conn_send_command(struct drbd_connection *connection, struct drbd_socket *so ...@@ -691,14 +691,14 @@ int conn_send_command(struct drbd_connection *connection, struct drbd_socket *so
return err; return err;
} }
int drbd_send_command(struct drbd_device *device, struct drbd_socket *sock, int drbd_send_command(struct drbd_peer_device *peer_device, struct drbd_socket *sock,
enum drbd_packet cmd, unsigned int header_size, enum drbd_packet cmd, unsigned int header_size,
void *data, unsigned int size) void *data, unsigned int size)
{ {
int err; int err;
err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, header_size, err = __send_command(peer_device->connection, peer_device->device->vnr,
data, size); sock, cmd, header_size, data, size);
mutex_unlock(&sock->mutex); mutex_unlock(&sock->mutex);
return err; return err;
} }
...@@ -723,23 +723,23 @@ int drbd_send_ping_ack(struct drbd_connection *connection) ...@@ -723,23 +723,23 @@ int drbd_send_ping_ack(struct drbd_connection *connection)
return conn_send_command(connection, sock, P_PING_ACK, 0, NULL, 0); return conn_send_command(connection, sock, P_PING_ACK, 0, NULL, 0);
} }
int drbd_send_sync_param(struct drbd_device *device) int drbd_send_sync_param(struct drbd_peer_device *peer_device)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_rs_param_95 *p; struct p_rs_param_95 *p;
int size; int size;
const int apv = first_peer_device(device)->connection->agreed_pro_version; const int apv = peer_device->connection->agreed_pro_version;
enum drbd_packet cmd; enum drbd_packet cmd;
struct net_conf *nc; struct net_conf *nc;
struct disk_conf *dc; struct disk_conf *dc;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
rcu_read_lock(); rcu_read_lock();
nc = rcu_dereference(first_peer_device(device)->connection->net_conf); nc = rcu_dereference(peer_device->connection->net_conf);
size = apv <= 87 ? sizeof(struct p_rs_param) size = apv <= 87 ? sizeof(struct p_rs_param)
: apv == 88 ? sizeof(struct p_rs_param) : apv == 88 ? sizeof(struct p_rs_param)
...@@ -752,14 +752,14 @@ int drbd_send_sync_param(struct drbd_device *device) ...@@ -752,14 +752,14 @@ int drbd_send_sync_param(struct drbd_device *device)
/* initialize verify_alg and csums_alg */ /* initialize verify_alg and csums_alg */
memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
if (get_ldev(device)) { if (get_ldev(peer_device->device)) {
dc = rcu_dereference(device->ldev->disk_conf); dc = rcu_dereference(peer_device->device->ldev->disk_conf);
p->resync_rate = cpu_to_be32(dc->resync_rate); p->resync_rate = cpu_to_be32(dc->resync_rate);
p->c_plan_ahead = cpu_to_be32(dc->c_plan_ahead); p->c_plan_ahead = cpu_to_be32(dc->c_plan_ahead);
p->c_delay_target = cpu_to_be32(dc->c_delay_target); p->c_delay_target = cpu_to_be32(dc->c_delay_target);
p->c_fill_target = cpu_to_be32(dc->c_fill_target); p->c_fill_target = cpu_to_be32(dc->c_fill_target);
p->c_max_rate = cpu_to_be32(dc->c_max_rate); p->c_max_rate = cpu_to_be32(dc->c_max_rate);
put_ldev(device); put_ldev(peer_device->device);
} else { } else {
p->resync_rate = cpu_to_be32(DRBD_RESYNC_RATE_DEF); p->resync_rate = cpu_to_be32(DRBD_RESYNC_RATE_DEF);
p->c_plan_ahead = cpu_to_be32(DRBD_C_PLAN_AHEAD_DEF); p->c_plan_ahead = cpu_to_be32(DRBD_C_PLAN_AHEAD_DEF);
...@@ -774,7 +774,7 @@ int drbd_send_sync_param(struct drbd_device *device) ...@@ -774,7 +774,7 @@ int drbd_send_sync_param(struct drbd_device *device)
strcpy(p->csums_alg, nc->csums_alg); strcpy(p->csums_alg, nc->csums_alg);
rcu_read_unlock(); rcu_read_unlock();
return drbd_send_command(device, sock, cmd, size, NULL, 0); return drbd_send_command(peer_device, sock, cmd, size, NULL, 0);
} }
int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd) int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd)
...@@ -833,8 +833,9 @@ int drbd_send_protocol(struct drbd_connection *connection) ...@@ -833,8 +833,9 @@ int drbd_send_protocol(struct drbd_connection *connection)
return err; return err;
} }
static int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags) static int _drbd_send_uuids(struct drbd_peer_device *peer_device, u64 uuid_flags)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_uuids *p; struct p_uuids *p;
int i; int i;
...@@ -842,8 +843,8 @@ static int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags) ...@@ -842,8 +843,8 @@ static int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags)
if (!get_ldev_if_state(device, D_NEGOTIATING)) if (!get_ldev_if_state(device, D_NEGOTIATING))
return 0; return 0;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) { if (!p) {
put_ldev(device); put_ldev(device);
return -EIO; return -EIO;
...@@ -856,24 +857,24 @@ static int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags) ...@@ -856,24 +857,24 @@ static int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags)
device->comm_bm_set = drbd_bm_total_weight(device); device->comm_bm_set = drbd_bm_total_weight(device);
p->uuid[UI_SIZE] = cpu_to_be64(device->comm_bm_set); p->uuid[UI_SIZE] = cpu_to_be64(device->comm_bm_set);
rcu_read_lock(); rcu_read_lock();
uuid_flags |= rcu_dereference(first_peer_device(device)->connection->net_conf)->discard_my_data ? 1 : 0; uuid_flags |= rcu_dereference(peer_device->connection->net_conf)->discard_my_data ? 1 : 0;
rcu_read_unlock(); rcu_read_unlock();
uuid_flags |= test_bit(CRASHED_PRIMARY, &device->flags) ? 2 : 0; uuid_flags |= test_bit(CRASHED_PRIMARY, &device->flags) ? 2 : 0;
uuid_flags |= device->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0; uuid_flags |= device->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0;
p->uuid[UI_FLAGS] = cpu_to_be64(uuid_flags); p->uuid[UI_FLAGS] = cpu_to_be64(uuid_flags);
put_ldev(device); put_ldev(device);
return drbd_send_command(device, sock, P_UUIDS, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, P_UUIDS, sizeof(*p), NULL, 0);
} }
int drbd_send_uuids(struct drbd_device *device) int drbd_send_uuids(struct drbd_peer_device *peer_device)
{ {
return _drbd_send_uuids(device, 0); return _drbd_send_uuids(peer_device, 0);
} }
int drbd_send_uuids_skip_initial_sync(struct drbd_device *device) int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *peer_device)
{ {
return _drbd_send_uuids(device, 8); return _drbd_send_uuids(peer_device, 8);
} }
void drbd_print_uuids(struct drbd_device *device, const char *text) void drbd_print_uuids(struct drbd_device *device, const char *text)
...@@ -894,8 +895,9 @@ void drbd_print_uuids(struct drbd_device *device, const char *text) ...@@ -894,8 +895,9 @@ void drbd_print_uuids(struct drbd_device *device, const char *text)
} }
} }
void drbd_gen_and_send_sync_uuid(struct drbd_device *device) void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *peer_device)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_rs_uuid *p; struct p_rs_uuid *p;
u64 uuid; u64 uuid;
...@@ -911,16 +913,17 @@ void drbd_gen_and_send_sync_uuid(struct drbd_device *device) ...@@ -911,16 +913,17 @@ void drbd_gen_and_send_sync_uuid(struct drbd_device *device)
drbd_print_uuids(device, "updated sync UUID"); drbd_print_uuids(device, "updated sync UUID");
drbd_md_sync(device); drbd_md_sync(device);
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (p) { if (p) {
p->uuid = cpu_to_be64(uuid); p->uuid = cpu_to_be64(uuid);
drbd_send_command(device, sock, P_SYNC_UUID, sizeof(*p), NULL, 0); drbd_send_command(peer_device, sock, P_SYNC_UUID, sizeof(*p), NULL, 0);
} }
} }
int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flags flags) int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enum dds_flags flags)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_sizes *p; struct p_sizes *p;
sector_t d_size, u_size; sector_t d_size, u_size;
...@@ -944,14 +947,14 @@ int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flag ...@@ -944,14 +947,14 @@ int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flag
max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */ max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */
} }
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
if (first_peer_device(device)->connection->agreed_pro_version <= 94) if (peer_device->connection->agreed_pro_version <= 94)
max_bio_size = min(max_bio_size, DRBD_MAX_SIZE_H80_PACKET); max_bio_size = min(max_bio_size, DRBD_MAX_SIZE_H80_PACKET);
else if (first_peer_device(device)->connection->agreed_pro_version < 100) else if (peer_device->connection->agreed_pro_version < 100)
max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE_P95); max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE_P95);
p->d_size = cpu_to_be64(d_size); p->d_size = cpu_to_be64(d_size);
...@@ -960,29 +963,29 @@ int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flag ...@@ -960,29 +963,29 @@ int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flag
p->max_bio_size = cpu_to_be32(max_bio_size); p->max_bio_size = cpu_to_be32(max_bio_size);
p->queue_order_type = cpu_to_be16(q_order_type); p->queue_order_type = cpu_to_be16(q_order_type);
p->dds_flags = cpu_to_be16(flags); p->dds_flags = cpu_to_be16(flags);
return drbd_send_command(device, sock, P_SIZES, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, P_SIZES, sizeof(*p), NULL, 0);
} }
/** /**
* drbd_send_current_state() - Sends the drbd state to the peer * drbd_send_current_state() - Sends the drbd state to the peer
* @device: DRBD device. * @peer_device: DRBD peer device.
*/ */
int drbd_send_current_state(struct drbd_device *device) int drbd_send_current_state(struct drbd_peer_device *peer_device)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_state *p; struct p_state *p;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->state = cpu_to_be32(device->state.i); /* Within the send mutex */ p->state = cpu_to_be32(peer_device->device->state.i); /* Within the send mutex */
return drbd_send_command(device, sock, P_STATE, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, P_STATE, sizeof(*p), NULL, 0);
} }
/** /**
* drbd_send_state() - After a state change, sends the new state to the peer * drbd_send_state() - After a state change, sends the new state to the peer
* @device: DRBD device. * @peer_device: DRBD peer device.
* @state: the state to send, not necessarily the current state. * @state: the state to send, not necessarily the current state.
* *
* Each state change queues an "after_state_ch" work, which will eventually * Each state change queues an "after_state_ch" work, which will eventually
...@@ -990,31 +993,31 @@ int drbd_send_current_state(struct drbd_device *device) ...@@ -990,31 +993,31 @@ int drbd_send_current_state(struct drbd_device *device)
* between queuing and processing of the after_state_ch work, we still * between queuing and processing of the after_state_ch work, we still
* want to send each intermediary state in the order it occurred. * want to send each intermediary state in the order it occurred.
*/ */
int drbd_send_state(struct drbd_device *device, union drbd_state state) int drbd_send_state(struct drbd_peer_device *peer_device, union drbd_state state)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_state *p; struct p_state *p;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->state = cpu_to_be32(state.i); /* Within the send mutex */ p->state = cpu_to_be32(state.i); /* Within the send mutex */
return drbd_send_command(device, sock, P_STATE, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, P_STATE, sizeof(*p), NULL, 0);
} }
int drbd_send_state_req(struct drbd_device *device, union drbd_state mask, union drbd_state val) int drbd_send_state_req(struct drbd_peer_device *peer_device, union drbd_state mask, union drbd_state val)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_req_state *p; struct p_req_state *p;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->mask = cpu_to_be32(mask.i); p->mask = cpu_to_be32(mask.i);
p->val = cpu_to_be32(val.i); p->val = cpu_to_be32(val.i);
return drbd_send_command(device, sock, P_STATE_CHG_REQ, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, P_STATE_CHG_REQ, sizeof(*p), NULL, 0);
} }
int conn_send_state_req(struct drbd_connection *connection, union drbd_state mask, union drbd_state val) int conn_send_state_req(struct drbd_connection *connection, union drbd_state mask, union drbd_state val)
...@@ -1033,16 +1036,16 @@ int conn_send_state_req(struct drbd_connection *connection, union drbd_state mas ...@@ -1033,16 +1036,16 @@ int conn_send_state_req(struct drbd_connection *connection, union drbd_state mas
return conn_send_command(connection, sock, cmd, sizeof(*p), NULL, 0); return conn_send_command(connection, sock, cmd, sizeof(*p), NULL, 0);
} }
void drbd_send_sr_reply(struct drbd_device *device, enum drbd_state_rv retcode) void drbd_send_sr_reply(struct drbd_peer_device *peer_device, enum drbd_state_rv retcode)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_req_state_reply *p; struct p_req_state_reply *p;
sock = &first_peer_device(device)->connection->meta; sock = &peer_device->connection->meta;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (p) { if (p) {
p->retcode = cpu_to_be32(retcode); p->retcode = cpu_to_be32(retcode);
drbd_send_command(device, sock, P_STATE_CHG_REPLY, sizeof(*p), NULL, 0); drbd_send_command(peer_device, sock, P_STATE_CHG_REPLY, sizeof(*p), NULL, 0);
} }
} }
...@@ -1311,42 +1314,42 @@ void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr, u32 set ...@@ -1311,42 +1314,42 @@ void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr, u32 set
* @blksize: size in byte, needs to be in big endian byte order * @blksize: size in byte, needs to be in big endian byte order
* @block_id: Id, big endian byte order * @block_id: Id, big endian byte order
*/ */
static int _drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd, static int _drbd_send_ack(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
u64 sector, u32 blksize, u64 block_id) u64 sector, u32 blksize, u64 block_id)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_block_ack *p; struct p_block_ack *p;
if (device->state.conn < C_CONNECTED) if (peer_device->device->state.conn < C_CONNECTED)
return -EIO; return -EIO;
sock = &first_peer_device(device)->connection->meta; sock = &peer_device->connection->meta;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->sector = sector; p->sector = sector;
p->block_id = block_id; p->block_id = block_id;
p->blksize = blksize; p->blksize = blksize;
p->seq_num = cpu_to_be32(atomic_inc_return(&device->packet_seq)); p->seq_num = cpu_to_be32(atomic_inc_return(&peer_device->device->packet_seq));
return drbd_send_command(device, sock, cmd, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, cmd, sizeof(*p), NULL, 0);
} }
/* dp->sector and dp->block_id already/still in network byte order, /* dp->sector and dp->block_id already/still in network byte order,
* data_size is payload size according to dp->head, * data_size is payload size according to dp->head,
* and may need to be corrected for digest size. */ * and may need to be corrected for digest size. */
void drbd_send_ack_dp(struct drbd_device *device, enum drbd_packet cmd, void drbd_send_ack_dp(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct p_data *dp, int data_size) struct p_data *dp, int data_size)
{ {
if (first_peer_device(device)->connection->peer_integrity_tfm) if (peer_device->connection->peer_integrity_tfm)
data_size -= crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm); data_size -= crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm);
_drbd_send_ack(device, cmd, dp->sector, cpu_to_be32(data_size), _drbd_send_ack(peer_device, cmd, dp->sector, cpu_to_be32(data_size),
dp->block_id); dp->block_id);
} }
void drbd_send_ack_rp(struct drbd_device *device, enum drbd_packet cmd, void drbd_send_ack_rp(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct p_block_req *rp) struct p_block_req *rp)
{ {
_drbd_send_ack(device, cmd, rp->sector, rp->blksize, rp->block_id); _drbd_send_ack(peer_device, cmd, rp->sector, rp->blksize, rp->block_id);
} }
/** /**
...@@ -1355,10 +1358,10 @@ void drbd_send_ack_rp(struct drbd_device *device, enum drbd_packet cmd, ...@@ -1355,10 +1358,10 @@ void drbd_send_ack_rp(struct drbd_device *device, enum drbd_packet cmd,
* @cmd: packet command code * @cmd: packet command code
* @peer_req: peer request * @peer_req: peer request
*/ */
int drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd, int drbd_send_ack(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct drbd_peer_request *peer_req) struct drbd_peer_request *peer_req)
{ {
return _drbd_send_ack(device, cmd, return _drbd_send_ack(peer_device, cmd,
cpu_to_be64(peer_req->i.sector), cpu_to_be64(peer_req->i.sector),
cpu_to_be32(peer_req->i.size), cpu_to_be32(peer_req->i.size),
peer_req->block_id); peer_req->block_id);
...@@ -1366,32 +1369,32 @@ int drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd, ...@@ -1366,32 +1369,32 @@ int drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd,
/* This function misuses the block_id field to signal if the blocks /* This function misuses the block_id field to signal if the blocks
* are is sync or not. */ * are is sync or not. */
int drbd_send_ack_ex(struct drbd_device *device, enum drbd_packet cmd, int drbd_send_ack_ex(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
sector_t sector, int blksize, u64 block_id) sector_t sector, int blksize, u64 block_id)
{ {
return _drbd_send_ack(device, cmd, return _drbd_send_ack(peer_device, cmd,
cpu_to_be64(sector), cpu_to_be64(sector),
cpu_to_be32(blksize), cpu_to_be32(blksize),
cpu_to_be64(block_id)); cpu_to_be64(block_id));
} }
int drbd_send_drequest(struct drbd_device *device, int cmd, int drbd_send_drequest(struct drbd_peer_device *peer_device, int cmd,
sector_t sector, int size, u64 block_id) sector_t sector, int size, u64 block_id)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_block_req *p; struct p_block_req *p;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->sector = cpu_to_be64(sector); p->sector = cpu_to_be64(sector);
p->block_id = block_id; p->block_id = block_id;
p->blksize = cpu_to_be32(size); p->blksize = cpu_to_be32(size);
return drbd_send_command(device, sock, cmd, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, cmd, sizeof(*p), NULL, 0);
} }
int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector, int size, int drbd_send_drequest_csum(struct drbd_peer_device *peer_device, sector_t sector, int size,
void *digest, int digest_size, enum drbd_packet cmd) void *digest, int digest_size, enum drbd_packet cmd)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
...@@ -1399,30 +1402,29 @@ int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector, int siz ...@@ -1399,30 +1402,29 @@ int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector, int siz
/* FIXME: Put the digest into the preallocated socket buffer. */ /* FIXME: Put the digest into the preallocated socket buffer. */
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->sector = cpu_to_be64(sector); p->sector = cpu_to_be64(sector);
p->block_id = ID_SYNCER /* unused */; p->block_id = ID_SYNCER /* unused */;
p->blksize = cpu_to_be32(size); p->blksize = cpu_to_be32(size);
return drbd_send_command(device, sock, cmd, sizeof(*p), return drbd_send_command(peer_device, sock, cmd, sizeof(*p), digest, digest_size);
digest, digest_size);
} }
int drbd_send_ov_request(struct drbd_device *device, sector_t sector, int size) int drbd_send_ov_request(struct drbd_peer_device *peer_device, sector_t sector, int size)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_block_req *p; struct p_block_req *p;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->sector = cpu_to_be64(sector); p->sector = cpu_to_be64(sector);
p->block_id = ID_SYNCER /* unused */; p->block_id = ID_SYNCER /* unused */;
p->blksize = cpu_to_be32(size); p->blksize = cpu_to_be32(size);
return drbd_send_command(device, sock, P_OV_REQUEST, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, P_OV_REQUEST, sizeof(*p), NULL, 0);
} }
/* called on sndtimeo /* called on sndtimeo
...@@ -1480,26 +1482,26 @@ static void drbd_update_congested(struct drbd_connection *connection) ...@@ -1480,26 +1482,26 @@ static void drbd_update_congested(struct drbd_connection *connection)
* As a workaround, we disable sendpage on pages * As a workaround, we disable sendpage on pages
* with page_count == 0 or PageSlab. * with page_count == 0 or PageSlab.
*/ */
static int _drbd_no_send_page(struct drbd_device *device, struct page *page, static int _drbd_no_send_page(struct drbd_peer_device *peer_device, struct page *page,
int offset, size_t size, unsigned msg_flags) int offset, size_t size, unsigned msg_flags)
{ {
struct socket *socket; struct socket *socket;
void *addr; void *addr;
int err; int err;
socket = first_peer_device(device)->connection->data.socket; socket = peer_device->connection->data.socket;
addr = kmap(page) + offset; addr = kmap(page) + offset;
err = drbd_send_all(first_peer_device(device)->connection, socket, addr, size, msg_flags); err = drbd_send_all(peer_device->connection, socket, addr, size, msg_flags);
kunmap(page); kunmap(page);
if (!err) if (!err)
device->send_cnt += size >> 9; peer_device->device->send_cnt += size >> 9;
return err; return err;
} }
static int _drbd_send_page(struct drbd_device *device, struct page *page, static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *page,
int offset, size_t size, unsigned msg_flags) int offset, size_t size, unsigned msg_flags)
{ {
struct socket *socket = first_peer_device(device)->connection->data.socket; struct socket *socket = peer_device->connection->data.socket;
mm_segment_t oldfs = get_fs(); mm_segment_t oldfs = get_fs();
int len = size; int len = size;
int err = -EIO; int err = -EIO;
...@@ -1511,10 +1513,10 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page, ...@@ -1511,10 +1513,10 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page,
* __page_cache_release a page that would actually still be referenced * __page_cache_release a page that would actually still be referenced
* by someone, leading to some obscure delayed Oops somewhere else. */ * by someone, leading to some obscure delayed Oops somewhere else. */
if (disable_sendpage || (page_count(page) < 1) || PageSlab(page)) if (disable_sendpage || (page_count(page) < 1) || PageSlab(page))
return _drbd_no_send_page(device, page, offset, size, msg_flags); return _drbd_no_send_page(peer_device, page, offset, size, msg_flags);
msg_flags |= MSG_NOSIGNAL; msg_flags |= MSG_NOSIGNAL;
drbd_update_congested(first_peer_device(device)->connection); drbd_update_congested(peer_device->connection);
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
do { do {
int sent; int sent;
...@@ -1522,11 +1524,11 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page, ...@@ -1522,11 +1524,11 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page,
sent = socket->ops->sendpage(socket, page, offset, len, msg_flags); sent = socket->ops->sendpage(socket, page, offset, len, msg_flags);
if (sent <= 0) { if (sent <= 0) {
if (sent == -EAGAIN) { if (sent == -EAGAIN) {
if (we_should_drop_the_connection(first_peer_device(device)->connection, socket)) if (we_should_drop_the_connection(peer_device->connection, socket))
break; break;
continue; continue;
} }
drbd_warn(device, "%s: size=%d len=%d sent=%d\n", drbd_warn(peer_device->device, "%s: size=%d len=%d sent=%d\n",
__func__, (int)size, len, sent); __func__, (int)size, len, sent);
if (sent < 0) if (sent < 0)
err = sent; err = sent;
...@@ -1536,16 +1538,16 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page, ...@@ -1536,16 +1538,16 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page,
offset += sent; offset += sent;
} while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/); } while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/);
set_fs(oldfs); set_fs(oldfs);
clear_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags); clear_bit(NET_CONGESTED, &peer_device->connection->flags);
if (len == 0) { if (len == 0) {
err = 0; err = 0;
device->send_cnt += size >> 9; peer_device->device->send_cnt += size >> 9;
} }
return err; return err;
} }
static int _drbd_send_bio(struct drbd_device *device, struct bio *bio) static int _drbd_send_bio(struct drbd_peer_device *peer_device, struct bio *bio)
{ {
struct bio_vec bvec; struct bio_vec bvec;
struct bvec_iter iter; struct bvec_iter iter;
...@@ -1554,7 +1556,7 @@ static int _drbd_send_bio(struct drbd_device *device, struct bio *bio) ...@@ -1554,7 +1556,7 @@ static int _drbd_send_bio(struct drbd_device *device, struct bio *bio)
bio_for_each_segment(bvec, bio, iter) { bio_for_each_segment(bvec, bio, iter) {
int err; int err;
err = _drbd_no_send_page(device, bvec.bv_page, err = _drbd_no_send_page(peer_device, bvec.bv_page,
bvec.bv_offset, bvec.bv_len, bvec.bv_offset, bvec.bv_len,
bio_iter_last(bvec, iter) bio_iter_last(bvec, iter)
? 0 : MSG_MORE); ? 0 : MSG_MORE);
...@@ -1564,7 +1566,7 @@ static int _drbd_send_bio(struct drbd_device *device, struct bio *bio) ...@@ -1564,7 +1566,7 @@ static int _drbd_send_bio(struct drbd_device *device, struct bio *bio)
return 0; return 0;
} }
static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio) static int _drbd_send_zc_bio(struct drbd_peer_device *peer_device, struct bio *bio)
{ {
struct bio_vec bvec; struct bio_vec bvec;
struct bvec_iter iter; struct bvec_iter iter;
...@@ -1573,7 +1575,7 @@ static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio) ...@@ -1573,7 +1575,7 @@ static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio)
bio_for_each_segment(bvec, bio, iter) { bio_for_each_segment(bvec, bio, iter) {
int err; int err;
err = _drbd_send_page(device, bvec.bv_page, err = _drbd_send_page(peer_device, bvec.bv_page,
bvec.bv_offset, bvec.bv_len, bvec.bv_offset, bvec.bv_len,
bio_iter_last(bvec, iter) ? 0 : MSG_MORE); bio_iter_last(bvec, iter) ? 0 : MSG_MORE);
if (err) if (err)
...@@ -1582,7 +1584,7 @@ static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio) ...@@ -1582,7 +1584,7 @@ static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio)
return 0; return 0;
} }
static int _drbd_send_zc_ee(struct drbd_device *device, static int _drbd_send_zc_ee(struct drbd_peer_device *peer_device,
struct drbd_peer_request *peer_req) struct drbd_peer_request *peer_req)
{ {
struct page *page = peer_req->pages; struct page *page = peer_req->pages;
...@@ -1593,7 +1595,7 @@ static int _drbd_send_zc_ee(struct drbd_device *device, ...@@ -1593,7 +1595,7 @@ static int _drbd_send_zc_ee(struct drbd_device *device,
page_chain_for_each(page) { page_chain_for_each(page) {
unsigned l = min_t(unsigned, len, PAGE_SIZE); unsigned l = min_t(unsigned, len, PAGE_SIZE);
err = _drbd_send_page(device, page, 0, l, err = _drbd_send_page(peer_device, page, 0, l,
page_chain_next(page) ? MSG_MORE : 0); page_chain_next(page) ? MSG_MORE : 0);
if (err) if (err)
return err; return err;
...@@ -1602,9 +1604,9 @@ static int _drbd_send_zc_ee(struct drbd_device *device, ...@@ -1602,9 +1604,9 @@ static int _drbd_send_zc_ee(struct drbd_device *device,
return 0; return 0;
} }
static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw) static u32 bio_flags_to_wire(struct drbd_connection *connection, unsigned long bi_rw)
{ {
if (first_peer_device(device)->connection->agreed_pro_version >= 95) if (connection->agreed_pro_version >= 95)
return (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) | return (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
(bi_rw & REQ_FUA ? DP_FUA : 0) | (bi_rw & REQ_FUA ? DP_FUA : 0) |
(bi_rw & REQ_FLUSH ? DP_FLUSH : 0) | (bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
...@@ -1616,29 +1618,30 @@ static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw) ...@@ -1616,29 +1618,30 @@ static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw)
/* Used to send write requests /* Used to send write requests
* R_PRIMARY -> Peer (P_DATA) * R_PRIMARY -> Peer (P_DATA)
*/ */
int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *req)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_data *p; struct p_data *p;
unsigned int dp_flags = 0; unsigned int dp_flags = 0;
int dgs; int dgs;
int err; int err;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
dgs = first_peer_device(device)->connection->integrity_tfm ? dgs = peer_device->connection->integrity_tfm ?
crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0; crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;
if (!p) if (!p)
return -EIO; return -EIO;
p->sector = cpu_to_be64(req->i.sector); p->sector = cpu_to_be64(req->i.sector);
p->block_id = (unsigned long)req; p->block_id = (unsigned long)req;
p->seq_num = cpu_to_be32(atomic_inc_return(&device->packet_seq)); p->seq_num = cpu_to_be32(atomic_inc_return(&device->packet_seq));
dp_flags = bio_flags_to_wire(device, req->master_bio->bi_rw); dp_flags = bio_flags_to_wire(peer_device->connection, req->master_bio->bi_rw);
if (device->state.conn >= C_SYNC_SOURCE && if (device->state.conn >= C_SYNC_SOURCE &&
device->state.conn <= C_PAUSED_SYNC_T) device->state.conn <= C_PAUSED_SYNC_T)
dp_flags |= DP_MAY_SET_IN_SYNC; dp_flags |= DP_MAY_SET_IN_SYNC;
if (first_peer_device(device)->connection->agreed_pro_version >= 100) { if (peer_device->connection->agreed_pro_version >= 100) {
if (req->rq_state & RQ_EXP_RECEIVE_ACK) if (req->rq_state & RQ_EXP_RECEIVE_ACK)
dp_flags |= DP_SEND_RECEIVE_ACK; dp_flags |= DP_SEND_RECEIVE_ACK;
if (req->rq_state & RQ_EXP_WRITE_ACK) if (req->rq_state & RQ_EXP_WRITE_ACK)
...@@ -1646,8 +1649,8 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) ...@@ -1646,8 +1649,8 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
} }
p->dp_flags = cpu_to_be32(dp_flags); p->dp_flags = cpu_to_be32(dp_flags);
if (dgs) if (dgs)
drbd_csum_bio(first_peer_device(device)->connection->integrity_tfm, req->master_bio, p + 1); drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, p + 1);
err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size); err = __send_command(peer_device->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
if (!err) { if (!err) {
/* For protocol A, we have to memcpy the payload into /* For protocol A, we have to memcpy the payload into
* socket buffers, as we may complete right away * socket buffers, as we may complete right away
...@@ -1661,16 +1664,16 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) ...@@ -1661,16 +1664,16 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
* receiving side, we sure have detected corruption elsewhere. * receiving side, we sure have detected corruption elsewhere.
*/ */
if (!(req->rq_state & (RQ_EXP_RECEIVE_ACK | RQ_EXP_WRITE_ACK)) || dgs) if (!(req->rq_state & (RQ_EXP_RECEIVE_ACK | RQ_EXP_WRITE_ACK)) || dgs)
err = _drbd_send_bio(device, req->master_bio); err = _drbd_send_bio(peer_device, req->master_bio);
else else
err = _drbd_send_zc_bio(device, req->master_bio); err = _drbd_send_zc_bio(peer_device, req->master_bio);
/* double check digest, sometimes buffers have been modified in flight. */ /* double check digest, sometimes buffers have been modified in flight. */
if (dgs > 0 && dgs <= 64) { if (dgs > 0 && dgs <= 64) {
/* 64 byte, 512 bit, is the largest digest size /* 64 byte, 512 bit, is the largest digest size
* currently supported in kernel crypto. */ * currently supported in kernel crypto. */
unsigned char digest[64]; unsigned char digest[64];
drbd_csum_bio(first_peer_device(device)->connection->integrity_tfm, req->master_bio, digest); drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, digest);
if (memcmp(p + 1, digest, dgs)) { if (memcmp(p + 1, digest, dgs)) {
drbd_warn(device, drbd_warn(device,
"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n", "Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
...@@ -1689,19 +1692,20 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) ...@@ -1689,19 +1692,20 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
* Peer -> (diskless) R_PRIMARY (P_DATA_REPLY) * Peer -> (diskless) R_PRIMARY (P_DATA_REPLY)
* C_SYNC_SOURCE -> C_SYNC_TARGET (P_RS_DATA_REPLY) * C_SYNC_SOURCE -> C_SYNC_TARGET (P_RS_DATA_REPLY)
*/ */
int drbd_send_block(struct drbd_device *device, enum drbd_packet cmd, int drbd_send_block(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct drbd_peer_request *peer_req) struct drbd_peer_request *peer_req)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_data *p; struct p_data *p;
int err; int err;
int dgs; int dgs;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
dgs = first_peer_device(device)->connection->integrity_tfm ? dgs = peer_device->connection->integrity_tfm ?
crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0; crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;
if (!p) if (!p)
return -EIO; return -EIO;
...@@ -1710,27 +1714,27 @@ int drbd_send_block(struct drbd_device *device, enum drbd_packet cmd, ...@@ -1710,27 +1714,27 @@ int drbd_send_block(struct drbd_device *device, enum drbd_packet cmd,
p->seq_num = 0; /* unused */ p->seq_num = 0; /* unused */
p->dp_flags = 0; p->dp_flags = 0;
if (dgs) if (dgs)
drbd_csum_ee(first_peer_device(device)->connection->integrity_tfm, peer_req, p + 1); drbd_csum_ee(peer_device->connection->integrity_tfm, peer_req, p + 1);
err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size); err = __send_command(peer_device->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
if (!err) if (!err)
err = _drbd_send_zc_ee(device, peer_req); err = _drbd_send_zc_ee(peer_device, peer_req);
mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */ mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */
return err; return err;
} }
int drbd_send_out_of_sync(struct drbd_device *device, struct drbd_request *req) int drbd_send_out_of_sync(struct drbd_peer_device *peer_device, struct drbd_request *req)
{ {
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_block_desc *p; struct p_block_desc *p;
sock = &first_peer_device(device)->connection->data; sock = &peer_device->connection->data;
p = drbd_prepare_command(device, sock); p = drbd_prepare_command(peer_device, sock);
if (!p) if (!p)
return -EIO; return -EIO;
p->sector = cpu_to_be64(req->i.sector); p->sector = cpu_to_be64(req->i.sector);
p->blksize = cpu_to_be32(req->i.size); p->blksize = cpu_to_be32(req->i.size);
return drbd_send_command(device, sock, P_OUT_OF_SYNC, sizeof(*p), NULL, 0); return drbd_send_command(peer_device, sock, P_OUT_OF_SYNC, sizeof(*p), NULL, 0);
} }
/* /*
...@@ -2795,8 +2799,10 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i ...@@ -2795,8 +2799,10 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
/* inherit the connection state */ /* inherit the connection state */
device->state.conn = first_connection(resource)->cstate; device->state.conn = first_connection(resource)->cstate;
if (device->state.conn == C_WF_REPORT_PARAMS) if (device->state.conn == C_WF_REPORT_PARAMS) {
drbd_connected(device); for_each_peer_device(peer_device, device)
drbd_connected(peer_device);
}
return NO_ERROR; return NO_ERROR;
......
...@@ -678,8 +678,8 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) ...@@ -678,8 +678,8 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force)
if (device->state.conn >= C_WF_REPORT_PARAMS) { if (device->state.conn >= C_WF_REPORT_PARAMS) {
/* if this was forced, we should consider sync */ /* if this was forced, we should consider sync */
if (forced) if (forced)
drbd_send_uuids(device); drbd_send_uuids(first_peer_device(device));
drbd_send_current_state(device); drbd_send_current_state(first_peer_device(device));
} }
drbd_md_sync(device); drbd_md_sync(device);
...@@ -1364,8 +1364,12 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) ...@@ -1364,8 +1364,12 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
drbd_md_sync(device); drbd_md_sync(device);
if (device->state.conn >= C_CONNECTED) if (device->state.conn >= C_CONNECTED) {
drbd_send_sync_param(device); struct drbd_peer_device *peer_device;
for_each_peer_device(peer_device, device)
drbd_send_sync_param(peer_device);
}
synchronize_rcu(); synchronize_rcu();
kfree(old_disk_conf); kfree(old_disk_conf);
...@@ -2145,8 +2149,13 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) ...@@ -2145,8 +2149,13 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
synchronize_rcu(); synchronize_rcu();
kfree(old_net_conf); kfree(old_net_conf);
if (connection->cstate >= C_WF_REPORT_PARAMS) if (connection->cstate >= C_WF_REPORT_PARAMS) {
drbd_send_sync_param(minor_to_device(conn_lowest_minor(connection))); struct drbd_peer_device *peer_device;
int vnr;
idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
drbd_send_sync_param(peer_device);
}
goto done; goto done;
...@@ -2514,8 +2523,8 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) ...@@ -2514,8 +2523,8 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
if (dd == DS_GREW) if (dd == DS_GREW)
set_bit(RESIZE_PENDING, &device->flags); set_bit(RESIZE_PENDING, &device->flags);
drbd_send_uuids(device); drbd_send_uuids(first_peer_device(device));
drbd_send_sizes(device, 1, ddsf); drbd_send_sizes(first_peer_device(device), 1, ddsf);
} }
fail: fail:
...@@ -3244,7 +3253,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) ...@@ -3244,7 +3253,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
retcode = ERR_IO_MD_DISK; retcode = ERR_IO_MD_DISK;
} }
if (skip_initial_sync) { if (skip_initial_sync) {
drbd_send_uuids_skip_initial_sync(device); drbd_send_uuids_skip_initial_sync(first_peer_device(device));
_drbd_uuid_set(device, UI_BITMAP, 0); _drbd_uuid_set(device, UI_BITMAP, 0);
drbd_print_uuids(device, "cleared bitmap UUID"); drbd_print_uuids(device, "cleared bitmap UUID");
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
......
...@@ -64,7 +64,7 @@ enum finish_epoch { ...@@ -64,7 +64,7 @@ enum finish_epoch {
static int drbd_do_features(struct drbd_connection *connection); static int drbd_do_features(struct drbd_connection *connection);
static int drbd_do_auth(struct drbd_connection *connection); static int drbd_do_auth(struct drbd_connection *connection);
static int drbd_disconnected(struct drbd_device *device); static int drbd_disconnected(struct drbd_peer_device *);
static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *, struct drbd_epoch *, enum epoch_event); static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *, struct drbd_epoch *, enum epoch_event);
static int e_end_block(struct drbd_work *, int); static int e_end_block(struct drbd_work *, int);
...@@ -241,9 +241,10 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device) ...@@ -241,9 +241,10 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
* *
* Returns a page chain linked via page->private. * Returns a page chain linked via page->private.
*/ */
struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number, struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int number,
bool retry) bool retry)
{ {
struct drbd_device *device = peer_device->device;
struct page *page = NULL; struct page *page = NULL;
struct net_conf *nc; struct net_conf *nc;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
...@@ -252,7 +253,7 @@ struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number, ...@@ -252,7 +253,7 @@ struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number,
/* Yes, we may run up to @number over max_buffers. If we /* Yes, we may run up to @number over max_buffers. If we
* follow it strictly, the admin will get it wrong anyways. */ * follow it strictly, the admin will get it wrong anyways. */
rcu_read_lock(); rcu_read_lock();
nc = rcu_dereference(first_peer_device(device)->connection->net_conf); nc = rcu_dereference(peer_device->connection->net_conf);
mxb = nc ? nc->max_buffers : 1000000; mxb = nc ? nc->max_buffers : 1000000;
rcu_read_unlock(); rcu_read_unlock();
...@@ -331,9 +332,10 @@ You must not have the req_lock: ...@@ -331,9 +332,10 @@ You must not have the req_lock:
*/ */
struct drbd_peer_request * struct drbd_peer_request *
drbd_alloc_peer_req(struct drbd_device *device, u64 id, sector_t sector, drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
unsigned int data_size, gfp_t gfp_mask) __must_hold(local) unsigned int data_size, gfp_t gfp_mask) __must_hold(local)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_peer_request *peer_req; struct drbd_peer_request *peer_req;
struct page *page = NULL; struct page *page = NULL;
unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT; unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
...@@ -349,7 +351,7 @@ drbd_alloc_peer_req(struct drbd_device *device, u64 id, sector_t sector, ...@@ -349,7 +351,7 @@ drbd_alloc_peer_req(struct drbd_device *device, u64 id, sector_t sector,
} }
if (data_size) { if (data_size) {
page = drbd_alloc_pages(device, nr_pages, (gfp_mask & __GFP_WAIT)); page = drbd_alloc_pages(peer_device, nr_pages, (gfp_mask & __GFP_WAIT));
if (!page) if (!page)
goto fail; goto fail;
} }
...@@ -831,24 +833,25 @@ static int drbd_socket_okay(struct socket **sock) ...@@ -831,24 +833,25 @@ static int drbd_socket_okay(struct socket **sock)
} }
/* Gets called if a connection is established, or if a new minor gets created /* Gets called if a connection is established, or if a new minor gets created
in a connection */ in a connection */
int drbd_connected(struct drbd_device *device) int drbd_connected(struct drbd_peer_device *peer_device)
{ {
struct drbd_device *device = peer_device->device;
int err; int err;
atomic_set(&device->packet_seq, 0); atomic_set(&device->packet_seq, 0);
device->peer_seq = 0; device->peer_seq = 0;
device->state_mutex = first_peer_device(device)->connection->agreed_pro_version < 100 ? device->state_mutex = peer_device->connection->agreed_pro_version < 100 ?
&first_peer_device(device)->connection->cstate_mutex : &peer_device->connection->cstate_mutex :
&device->own_state_mutex; &device->own_state_mutex;
err = drbd_send_sync_param(device); err = drbd_send_sync_param(peer_device);
if (!err) if (!err)
err = drbd_send_sizes(device, 0, 0); err = drbd_send_sizes(peer_device, 0, 0);
if (!err) if (!err)
err = drbd_send_uuids(device); err = drbd_send_uuids(peer_device);
if (!err) if (!err)
err = drbd_send_current_state(device); err = drbd_send_current_state(peer_device);
clear_bit(USE_DEGR_WFC_T, &device->flags); clear_bit(USE_DEGR_WFC_T, &device->flags);
clear_bit(RESIZE_PENDING, &device->flags); clear_bit(RESIZE_PENDING, &device->flags);
atomic_set(&device->ap_in_flight, 0); atomic_set(&device->ap_in_flight, 0);
...@@ -1058,7 +1061,7 @@ static int conn_connect(struct drbd_connection *connection) ...@@ -1058,7 +1061,7 @@ static int conn_connect(struct drbd_connection *connection)
else else
clear_bit(DISCARD_MY_DATA, &device->flags); clear_bit(DISCARD_MY_DATA, &device->flags);
drbd_connected(device); drbd_connected(peer_device);
kref_put(&device->kref, drbd_destroy_device); kref_put(&device->kref, drbd_destroy_device);
rcu_read_lock(); rcu_read_lock();
} }
...@@ -1498,25 +1501,26 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf ...@@ -1498,25 +1501,26 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf
/* used from receive_RSDataReply (recv_resync_read) /* used from receive_RSDataReply (recv_resync_read)
* and from receive_Data */ * and from receive_Data */
static struct drbd_peer_request * static struct drbd_peer_request *
read_in_block(struct drbd_device *device, u64 id, sector_t sector, read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
int data_size) __must_hold(local) int data_size) __must_hold(local)
{ {
struct drbd_device *device = peer_device->device;
const sector_t capacity = drbd_get_capacity(device->this_bdev); const sector_t capacity = drbd_get_capacity(device->this_bdev);
struct drbd_peer_request *peer_req; struct drbd_peer_request *peer_req;
struct page *page; struct page *page;
int dgs, ds, err; int dgs, ds, err;
void *dig_in = first_peer_device(device)->connection->int_dig_in; void *dig_in = peer_device->connection->int_dig_in;
void *dig_vv = first_peer_device(device)->connection->int_dig_vv; void *dig_vv = peer_device->connection->int_dig_vv;
unsigned long *data; unsigned long *data;
dgs = 0; dgs = 0;
if (first_peer_device(device)->connection->peer_integrity_tfm) { if (peer_device->connection->peer_integrity_tfm) {
dgs = crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm); dgs = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm);
/* /*
* FIXME: Receive the incoming digest into the receive buffer * FIXME: Receive the incoming digest into the receive buffer
* here, together with its struct p_data? * here, together with its struct p_data?
*/ */
err = drbd_recv_all_warn(first_peer_device(device)->connection, dig_in, dgs); err = drbd_recv_all_warn(peer_device->connection, dig_in, dgs);
if (err) if (err)
return NULL; return NULL;
data_size -= dgs; data_size -= dgs;
...@@ -1540,7 +1544,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector, ...@@ -1540,7 +1544,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
* "criss-cross" setup, that might cause write-out on some other DRBD, * "criss-cross" setup, that might cause write-out on some other DRBD,
* which in turn might block on the other node at this very place. */ * which in turn might block on the other node at this very place. */
peer_req = drbd_alloc_peer_req(device, id, sector, data_size, GFP_NOIO); peer_req = drbd_alloc_peer_req(peer_device, id, sector, data_size, GFP_NOIO);
if (!peer_req) if (!peer_req)
return NULL; return NULL;
...@@ -1552,7 +1556,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector, ...@@ -1552,7 +1556,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
page_chain_for_each(page) { page_chain_for_each(page) {
unsigned len = min_t(int, ds, PAGE_SIZE); unsigned len = min_t(int, ds, PAGE_SIZE);
data = kmap(page); data = kmap(page);
err = drbd_recv_all_warn(first_peer_device(device)->connection, data, len); err = drbd_recv_all_warn(peer_device->connection, data, len);
if (drbd_insert_fault(device, DRBD_FAULT_RECEIVE)) { if (drbd_insert_fault(device, DRBD_FAULT_RECEIVE)) {
drbd_err(device, "Fault injection: Corrupting data on receive\n"); drbd_err(device, "Fault injection: Corrupting data on receive\n");
data[0] = data[0] ^ (unsigned long)-1; data[0] = data[0] ^ (unsigned long)-1;
...@@ -1566,7 +1570,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector, ...@@ -1566,7 +1570,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
} }
if (dgs) { if (dgs) {
drbd_csum_ee(first_peer_device(device)->connection->peer_integrity_tfm, peer_req, dig_vv); drbd_csum_ee(peer_device->connection->peer_integrity_tfm, peer_req, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) { if (memcmp(dig_in, dig_vv, dgs)) {
drbd_err(device, "Digest integrity check FAILED: %llus +%u\n", drbd_err(device, "Digest integrity check FAILED: %llus +%u\n",
(unsigned long long)sector, data_size); (unsigned long long)sector, data_size);
...@@ -1581,7 +1585,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector, ...@@ -1581,7 +1585,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
/* drbd_drain_block() just takes a data block /* drbd_drain_block() just takes a data block
* out of the socket input buffer, and discards it. * out of the socket input buffer, and discards it.
*/ */
static int drbd_drain_block(struct drbd_device *device, int data_size) static int drbd_drain_block(struct drbd_peer_device *peer_device, int data_size)
{ {
struct page *page; struct page *page;
int err = 0; int err = 0;
...@@ -1590,36 +1594,36 @@ static int drbd_drain_block(struct drbd_device *device, int data_size) ...@@ -1590,36 +1594,36 @@ static int drbd_drain_block(struct drbd_device *device, int data_size)
if (!data_size) if (!data_size)
return 0; return 0;
page = drbd_alloc_pages(device, 1, 1); page = drbd_alloc_pages(peer_device, 1, 1);
data = kmap(page); data = kmap(page);
while (data_size) { while (data_size) {
unsigned int len = min_t(int, data_size, PAGE_SIZE); unsigned int len = min_t(int, data_size, PAGE_SIZE);
err = drbd_recv_all_warn(first_peer_device(device)->connection, data, len); err = drbd_recv_all_warn(peer_device->connection, data, len);
if (err) if (err)
break; break;
data_size -= len; data_size -= len;
} }
kunmap(page); kunmap(page);
drbd_free_pages(device, page, 0); drbd_free_pages(peer_device->device, page, 0);
return err; return err;
} }
static int recv_dless_read(struct drbd_device *device, struct drbd_request *req, static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_request *req,
sector_t sector, int data_size) sector_t sector, int data_size)
{ {
struct bio_vec bvec; struct bio_vec bvec;
struct bvec_iter iter; struct bvec_iter iter;
struct bio *bio; struct bio *bio;
int dgs, err, expect; int dgs, err, expect;
void *dig_in = first_peer_device(device)->connection->int_dig_in; void *dig_in = peer_device->connection->int_dig_in;
void *dig_vv = first_peer_device(device)->connection->int_dig_vv; void *dig_vv = peer_device->connection->int_dig_vv;
dgs = 0; dgs = 0;
if (first_peer_device(device)->connection->peer_integrity_tfm) { if (peer_device->connection->peer_integrity_tfm) {
dgs = crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm); dgs = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm);
err = drbd_recv_all_warn(first_peer_device(device)->connection, dig_in, dgs); err = drbd_recv_all_warn(peer_device->connection, dig_in, dgs);
if (err) if (err)
return err; return err;
data_size -= dgs; data_size -= dgs;
...@@ -1627,15 +1631,15 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req, ...@@ -1627,15 +1631,15 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req,
/* optimistically update recv_cnt. if receiving fails below, /* optimistically update recv_cnt. if receiving fails below,
* we disconnect anyways, and counters will be reset. */ * we disconnect anyways, and counters will be reset. */
device->recv_cnt += data_size>>9; peer_device->device->recv_cnt += data_size>>9;
bio = req->master_bio; bio = req->master_bio;
D_ASSERT(device, sector == bio->bi_iter.bi_sector); D_ASSERT(peer_device->device, sector == bio->bi_iter.bi_sector);
bio_for_each_segment(bvec, bio, iter) { bio_for_each_segment(bvec, bio, iter) {
void *mapped = kmap(bvec.bv_page) + bvec.bv_offset; void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
expect = min_t(int, data_size, bvec.bv_len); expect = min_t(int, data_size, bvec.bv_len);
err = drbd_recv_all_warn(first_peer_device(device)->connection, mapped, expect); err = drbd_recv_all_warn(peer_device->connection, mapped, expect);
kunmap(bvec.bv_page); kunmap(bvec.bv_page);
if (err) if (err)
return err; return err;
...@@ -1643,14 +1647,14 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req, ...@@ -1643,14 +1647,14 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req,
} }
if (dgs) { if (dgs) {
drbd_csum_bio(first_peer_device(device)->connection->peer_integrity_tfm, bio, dig_vv); drbd_csum_bio(peer_device->connection->peer_integrity_tfm, bio, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) { if (memcmp(dig_in, dig_vv, dgs)) {
drbd_err(device, "Digest integrity check FAILED. Broken NICs?\n"); drbd_err(peer_device, "Digest integrity check FAILED. Broken NICs?\n");
return -EINVAL; return -EINVAL;
} }
} }
D_ASSERT(device, data_size == 0); D_ASSERT(peer_device->device, data_size == 0);
return 0; return 0;
} }
...@@ -1670,23 +1674,25 @@ static int e_end_resync_block(struct drbd_work *w, int unused) ...@@ -1670,23 +1674,25 @@ static int e_end_resync_block(struct drbd_work *w, int unused)
if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) { if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
drbd_set_in_sync(device, sector, peer_req->i.size); drbd_set_in_sync(device, sector, peer_req->i.size);
err = drbd_send_ack(device, P_RS_WRITE_ACK, peer_req); err = drbd_send_ack(first_peer_device(device), P_RS_WRITE_ACK, peer_req);
} else { } else {
/* Record failure to sync */ /* Record failure to sync */
drbd_rs_failed_io(device, sector, peer_req->i.size); drbd_rs_failed_io(device, sector, peer_req->i.size);
err = drbd_send_ack(device, P_NEG_ACK, peer_req); err = drbd_send_ack(first_peer_device(device), P_NEG_ACK, peer_req);
} }
dec_unacked(device); dec_unacked(device);
return err; return err;
} }
static int recv_resync_read(struct drbd_device *device, sector_t sector, int data_size) __releases(local) static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t sector,
int data_size) __releases(local)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_peer_request *peer_req; struct drbd_peer_request *peer_req;
peer_req = read_in_block(device, ID_SYNCER, sector, data_size); peer_req = read_in_block(peer_device, ID_SYNCER, sector, data_size);
if (!peer_req) if (!peer_req)
goto fail; goto fail;
...@@ -1760,7 +1766,7 @@ static int receive_DataReply(struct drbd_connection *connection, struct packet_i ...@@ -1760,7 +1766,7 @@ static int receive_DataReply(struct drbd_connection *connection, struct packet_i
/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid /* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
* special casing it there for the various failure cases. * special casing it there for the various failure cases.
* still no race with drbd_fail_pending_reads */ * still no race with drbd_fail_pending_reads */
err = recv_dless_read(device, req, sector, pi->size); err = recv_dless_read(peer_device, req, sector, pi->size);
if (!err) if (!err)
req_mod(req, DATA_RECEIVED); req_mod(req, DATA_RECEIVED);
/* else: nothing. handled from drbd_disconnect... /* else: nothing. handled from drbd_disconnect...
...@@ -1790,14 +1796,14 @@ static int receive_RSDataReply(struct drbd_connection *connection, struct packet ...@@ -1790,14 +1796,14 @@ static int receive_RSDataReply(struct drbd_connection *connection, struct packet
/* data is submitted to disk within recv_resync_read. /* data is submitted to disk within recv_resync_read.
* corresponding put_ldev done below on error, * corresponding put_ldev done below on error,
* or in drbd_peer_request_endio. */ * or in drbd_peer_request_endio. */
err = recv_resync_read(device, sector, pi->size); err = recv_resync_read(peer_device, sector, pi->size);
} else { } else {
if (__ratelimit(&drbd_ratelimit_state)) if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Can not write resync data to local disk.\n"); drbd_err(device, "Can not write resync data to local disk.\n");
err = drbd_drain_block(device, pi->size); err = drbd_drain_block(peer_device, pi->size);
drbd_send_ack_dp(device, P_NEG_ACK, p, pi->size); drbd_send_ack_dp(peer_device, P_NEG_ACK, p, pi->size);
} }
atomic_add(pi->size >> 9, &device->rs_sect_in); atomic_add(pi->size >> 9, &device->rs_sect_in);
...@@ -1841,11 +1847,11 @@ static int e_end_block(struct drbd_work *w, int cancel) ...@@ -1841,11 +1847,11 @@ static int e_end_block(struct drbd_work *w, int cancel)
device->state.conn <= C_PAUSED_SYNC_T && device->state.conn <= C_PAUSED_SYNC_T &&
peer_req->flags & EE_MAY_SET_IN_SYNC) ? peer_req->flags & EE_MAY_SET_IN_SYNC) ?
P_RS_WRITE_ACK : P_WRITE_ACK; P_RS_WRITE_ACK : P_WRITE_ACK;
err = drbd_send_ack(device, pcmd, peer_req); err = drbd_send_ack(first_peer_device(device), pcmd, peer_req);
if (pcmd == P_RS_WRITE_ACK) if (pcmd == P_RS_WRITE_ACK)
drbd_set_in_sync(device, sector, peer_req->i.size); drbd_set_in_sync(device, sector, peer_req->i.size);
} else { } else {
err = drbd_send_ack(device, P_NEG_ACK, peer_req); err = drbd_send_ack(first_peer_device(device), P_NEG_ACK, peer_req);
/* we expect it to be marked out of sync anyways... /* we expect it to be marked out of sync anyways...
* maybe assert this? */ * maybe assert this? */
} }
...@@ -1875,7 +1881,7 @@ static int e_send_ack(struct drbd_work *w, enum drbd_packet ack) ...@@ -1875,7 +1881,7 @@ static int e_send_ack(struct drbd_work *w, enum drbd_packet ack)
container_of(w, struct drbd_peer_request, w); container_of(w, struct drbd_peer_request, w);
int err; int err;
err = drbd_send_ack(device, ack, peer_req); err = drbd_send_ack(first_peer_device(device), ack, peer_req);
dec_unacked(device); dec_unacked(device);
return err; return err;
...@@ -1909,11 +1915,12 @@ static u32 seq_max(u32 a, u32 b) ...@@ -1909,11 +1915,12 @@ static u32 seq_max(u32 a, u32 b)
return seq_greater(a, b) ? a : b; return seq_greater(a, b) ? a : b;
} }
static void update_peer_seq(struct drbd_device *device, unsigned int peer_seq) static void update_peer_seq(struct drbd_peer_device *peer_device, unsigned int peer_seq)
{ {
struct drbd_device *device = peer_device->device;
unsigned int newest_peer_seq; unsigned int newest_peer_seq;
if (test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)) { if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)) {
spin_lock(&device->peer_seq_lock); spin_lock(&device->peer_seq_lock);
newest_peer_seq = seq_max(device->peer_seq, peer_seq); newest_peer_seq = seq_max(device->peer_seq, peer_seq);
device->peer_seq = newest_peer_seq; device->peer_seq = newest_peer_seq;
...@@ -1969,13 +1976,14 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee ...@@ -1969,13 +1976,14 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee
* *
* returns 0 if we may process the packet, * returns 0 if we may process the packet,
* -ERESTARTSYS if we were interrupted (by disconnect signal). */ * -ERESTARTSYS if we were interrupted (by disconnect signal). */
static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 peer_seq) static int wait_for_and_update_peer_seq(struct drbd_peer_device *peer_device, const u32 peer_seq)
{ {
struct drbd_device *device = peer_device->device;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
long timeout; long timeout;
int ret = 0, tp; int ret = 0, tp;
if (!test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)) if (!test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags))
return 0; return 0;
spin_lock(&device->peer_seq_lock); spin_lock(&device->peer_seq_lock);
...@@ -2001,7 +2009,7 @@ static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 pe ...@@ -2001,7 +2009,7 @@ static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 pe
prepare_to_wait(&device->seq_wait, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(&device->seq_wait, &wait, TASK_INTERRUPTIBLE);
spin_unlock(&device->peer_seq_lock); spin_unlock(&device->peer_seq_lock);
rcu_read_lock(); rcu_read_lock();
timeout = rcu_dereference(first_peer_device(device)->connection->net_conf)->ping_timeo*HZ/10; timeout = rcu_dereference(peer_device->connection->net_conf)->ping_timeo*HZ/10;
rcu_read_unlock(); rcu_read_unlock();
timeout = schedule_timeout(timeout); timeout = schedule_timeout(timeout);
spin_lock(&device->peer_seq_lock); spin_lock(&device->peer_seq_lock);
...@@ -2182,10 +2190,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2182,10 +2190,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
if (!get_ldev(device)) { if (!get_ldev(device)) {
int err2; int err2;
err = wait_for_and_update_peer_seq(device, peer_seq); err = wait_for_and_update_peer_seq(peer_device, peer_seq);
drbd_send_ack_dp(device, P_NEG_ACK, p, pi->size); drbd_send_ack_dp(peer_device, P_NEG_ACK, p, pi->size);
atomic_inc(&connection->current_epoch->epoch_size); atomic_inc(&connection->current_epoch->epoch_size);
err2 = drbd_drain_block(device, pi->size); err2 = drbd_drain_block(peer_device, pi->size);
if (!err) if (!err)
err = err2; err = err2;
return err; return err;
...@@ -2198,7 +2206,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2198,7 +2206,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
*/ */
sector = be64_to_cpu(p->sector); sector = be64_to_cpu(p->sector);
peer_req = read_in_block(device, p->block_id, sector, pi->size); peer_req = read_in_block(peer_device, p->block_id, sector, pi->size);
if (!peer_req) { if (!peer_req) {
put_ldev(device); put_ldev(device);
return -EIO; return -EIO;
...@@ -2227,7 +2235,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2227,7 +2235,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
rcu_read_unlock(); rcu_read_unlock();
if (tp) { if (tp) {
peer_req->flags |= EE_IN_INTERVAL_TREE; peer_req->flags |= EE_IN_INTERVAL_TREE;
err = wait_for_and_update_peer_seq(device, peer_seq); err = wait_for_and_update_peer_seq(peer_device, peer_seq);
if (err) if (err)
goto out_interrupted; goto out_interrupted;
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
...@@ -2241,7 +2249,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2241,7 +2249,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
goto out_interrupted; goto out_interrupted;
} }
} else { } else {
update_peer_seq(device, peer_seq); update_peer_seq(peer_device, peer_seq);
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
} }
list_add(&peer_req->w.list, &device->active_ee); list_add(&peer_req->w.list, &device->active_ee);
...@@ -2273,7 +2281,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2273,7 +2281,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
if (dp_flags & DP_SEND_RECEIVE_ACK) { if (dp_flags & DP_SEND_RECEIVE_ACK) {
/* I really don't like it that the receiver thread /* I really don't like it that the receiver thread
* sends on the msock, but anyways */ * sends on the msock, but anyways */
drbd_send_ack(device, P_RECV_ACK, peer_req); drbd_send_ack(first_peer_device(device), P_RECV_ACK, peer_req);
} }
if (device->state.pdsk < D_INCONSISTENT) { if (device->state.pdsk < D_INCONSISTENT) {
...@@ -2412,17 +2420,17 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2412,17 +2420,17 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
verb = 1; verb = 1;
switch (pi->cmd) { switch (pi->cmd) {
case P_DATA_REQUEST: case P_DATA_REQUEST:
drbd_send_ack_rp(device, P_NEG_DREPLY, p); drbd_send_ack_rp(peer_device, P_NEG_DREPLY, p);
break; break;
case P_RS_DATA_REQUEST: case P_RS_DATA_REQUEST:
case P_CSUM_RS_REQUEST: case P_CSUM_RS_REQUEST:
case P_OV_REQUEST: case P_OV_REQUEST:
drbd_send_ack_rp(device, P_NEG_RS_DREPLY , p); drbd_send_ack_rp(peer_device, P_NEG_RS_DREPLY , p);
break; break;
case P_OV_REPLY: case P_OV_REPLY:
verb = 0; verb = 0;
dec_rs_pending(device); dec_rs_pending(device);
drbd_send_ack_ex(device, P_OV_RESULT, sector, size, ID_IN_SYNC); drbd_send_ack_ex(peer_device, P_OV_RESULT, sector, size, ID_IN_SYNC);
break; break;
default: default:
BUG(); BUG();
...@@ -2432,13 +2440,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2432,13 +2440,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
"no local data.\n"); "no local data.\n");
/* drain possibly payload */ /* drain possibly payload */
return drbd_drain_block(device, pi->size); return drbd_drain_block(peer_device, pi->size);
} }
/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
* "criss-cross" setup, that might cause write-out on some other DRBD, * "criss-cross" setup, that might cause write-out on some other DRBD,
* which in turn might block on the other node at this very place. */ * which in turn might block on the other node at this very place. */
peer_req = drbd_alloc_peer_req(device, p->block_id, sector, size, GFP_NOIO); peer_req = drbd_alloc_peer_req(peer_device, p->block_id, sector, size, GFP_NOIO);
if (!peer_req) { if (!peer_req) {
put_ldev(device); put_ldev(device);
return -ENOMEM; return -ENOMEM;
...@@ -2566,8 +2574,12 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2566,8 +2574,12 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
return -EIO; return -EIO;
} }
static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) /**
* drbd_asb_recover_0p - Recover after split-brain with no remaining primaries
*/
static int drbd_asb_recover_0p(struct drbd_peer_device *peer_device) __must_hold(local)
{ {
struct drbd_device *device = peer_device->device;
int self, peer, rv = -100; int self, peer, rv = -100;
unsigned long ch_self, ch_peer; unsigned long ch_self, ch_peer;
enum drbd_after_sb_p after_sb_0p; enum drbd_after_sb_p after_sb_0p;
...@@ -2579,7 +2591,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) ...@@ -2579,7 +2591,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
ch_self = device->comm_bm_set; ch_self = device->comm_bm_set;
rcu_read_lock(); rcu_read_lock();
after_sb_0p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_0p; after_sb_0p = rcu_dereference(peer_device->connection->net_conf)->after_sb_0p;
rcu_read_unlock(); rcu_read_unlock();
switch (after_sb_0p) { switch (after_sb_0p) {
case ASB_CONSENSUS: case ASB_CONSENSUS:
...@@ -2614,7 +2626,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) ...@@ -2614,7 +2626,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
"Using discard-least-changes instead\n"); "Using discard-least-changes instead\n");
case ASB_DISCARD_ZERO_CHG: case ASB_DISCARD_ZERO_CHG:
if (ch_peer == 0 && ch_self == 0) { if (ch_peer == 0 && ch_self == 0) {
rv = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags) rv = test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)
? -1 : 1; ? -1 : 1;
break; break;
} else { } else {
...@@ -2630,7 +2642,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) ...@@ -2630,7 +2642,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
rv = 1; rv = 1;
else /* ( ch_self == ch_peer ) */ else /* ( ch_self == ch_peer ) */
/* Well, then use something else. */ /* Well, then use something else. */
rv = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags) rv = test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)
? -1 : 1; ? -1 : 1;
break; break;
case ASB_DISCARD_LOCAL: case ASB_DISCARD_LOCAL:
...@@ -2643,13 +2655,17 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) ...@@ -2643,13 +2655,17 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
return rv; return rv;
} }
static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local) /**
* drbd_asb_recover_1p - Recover after split-brain with one remaining primary
*/
static int drbd_asb_recover_1p(struct drbd_peer_device *peer_device) __must_hold(local)
{ {
struct drbd_device *device = peer_device->device;
int hg, rv = -100; int hg, rv = -100;
enum drbd_after_sb_p after_sb_1p; enum drbd_after_sb_p after_sb_1p;
rcu_read_lock(); rcu_read_lock();
after_sb_1p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_1p; after_sb_1p = rcu_dereference(peer_device->connection->net_conf)->after_sb_1p;
rcu_read_unlock(); rcu_read_unlock();
switch (after_sb_1p) { switch (after_sb_1p) {
case ASB_DISCARD_YOUNGER_PRI: case ASB_DISCARD_YOUNGER_PRI:
...@@ -2663,19 +2679,19 @@ static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local) ...@@ -2663,19 +2679,19 @@ static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local)
case ASB_DISCONNECT: case ASB_DISCONNECT:
break; break;
case ASB_CONSENSUS: case ASB_CONSENSUS:
hg = drbd_asb_recover_0p(device); hg = drbd_asb_recover_0p(peer_device);
if (hg == -1 && device->state.role == R_SECONDARY) if (hg == -1 && device->state.role == R_SECONDARY)
rv = hg; rv = hg;
if (hg == 1 && device->state.role == R_PRIMARY) if (hg == 1 && device->state.role == R_PRIMARY)
rv = hg; rv = hg;
break; break;
case ASB_VIOLENTLY: case ASB_VIOLENTLY:
rv = drbd_asb_recover_0p(device); rv = drbd_asb_recover_0p(peer_device);
break; break;
case ASB_DISCARD_SECONDARY: case ASB_DISCARD_SECONDARY:
return device->state.role == R_PRIMARY ? 1 : -1; return device->state.role == R_PRIMARY ? 1 : -1;
case ASB_CALL_HELPER: case ASB_CALL_HELPER:
hg = drbd_asb_recover_0p(device); hg = drbd_asb_recover_0p(peer_device);
if (hg == -1 && device->state.role == R_PRIMARY) { if (hg == -1 && device->state.role == R_PRIMARY) {
enum drbd_state_rv rv2; enum drbd_state_rv rv2;
...@@ -2696,13 +2712,17 @@ static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local) ...@@ -2696,13 +2712,17 @@ static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local)
return rv; return rv;
} }
static int drbd_asb_recover_2p(struct drbd_device *device) __must_hold(local) /**
* drbd_asb_recover_2p - Recover after split-brain with two remaining primaries
*/
static int drbd_asb_recover_2p(struct drbd_peer_device *peer_device) __must_hold(local)
{ {
struct drbd_device *device = peer_device->device;
int hg, rv = -100; int hg, rv = -100;
enum drbd_after_sb_p after_sb_2p; enum drbd_after_sb_p after_sb_2p;
rcu_read_lock(); rcu_read_lock();
after_sb_2p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_2p; after_sb_2p = rcu_dereference(peer_device->connection->net_conf)->after_sb_2p;
rcu_read_unlock(); rcu_read_unlock();
switch (after_sb_2p) { switch (after_sb_2p) {
case ASB_DISCARD_YOUNGER_PRI: case ASB_DISCARD_YOUNGER_PRI:
...@@ -2716,12 +2736,12 @@ static int drbd_asb_recover_2p(struct drbd_device *device) __must_hold(local) ...@@ -2716,12 +2736,12 @@ static int drbd_asb_recover_2p(struct drbd_device *device) __must_hold(local)
drbd_err(device, "Configuration error.\n"); drbd_err(device, "Configuration error.\n");
break; break;
case ASB_VIOLENTLY: case ASB_VIOLENTLY:
rv = drbd_asb_recover_0p(device); rv = drbd_asb_recover_0p(peer_device);
break; break;
case ASB_DISCONNECT: case ASB_DISCONNECT:
break; break;
case ASB_CALL_HELPER: case ASB_CALL_HELPER:
hg = drbd_asb_recover_0p(device); hg = drbd_asb_recover_0p(peer_device);
if (hg == -1) { if (hg == -1) {
enum drbd_state_rv rv2; enum drbd_state_rv rv2;
...@@ -2956,9 +2976,11 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho ...@@ -2956,9 +2976,11 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho
/* drbd_sync_handshake() returns the new conn state on success, or /* drbd_sync_handshake() returns the new conn state on success, or
CONN_MASK (-1) on failure. CONN_MASK (-1) on failure.
*/ */
static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd_role peer_role, static enum drbd_conns drbd_sync_handshake(struct drbd_peer_device *peer_device,
enum drbd_role peer_role,
enum drbd_disk_state peer_disk) __must_hold(local) enum drbd_disk_state peer_disk) __must_hold(local)
{ {
struct drbd_device *device = peer_device->device;
enum drbd_conns rv = C_MASK; enum drbd_conns rv = C_MASK;
enum drbd_disk_state mydisk; enum drbd_disk_state mydisk;
struct net_conf *nc; struct net_conf *nc;
...@@ -3003,7 +3025,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd ...@@ -3003,7 +3025,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd
drbd_khelper(device, "initial-split-brain"); drbd_khelper(device, "initial-split-brain");
rcu_read_lock(); rcu_read_lock();
nc = rcu_dereference(first_peer_device(device)->connection->net_conf); nc = rcu_dereference(peer_device->connection->net_conf);
if (hg == 100 || (hg == -100 && nc->always_asbp)) { if (hg == 100 || (hg == -100 && nc->always_asbp)) {
int pcount = (device->state.role == R_PRIMARY) int pcount = (device->state.role == R_PRIMARY)
...@@ -3012,13 +3034,13 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd ...@@ -3012,13 +3034,13 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd
switch (pcount) { switch (pcount) {
case 0: case 0:
hg = drbd_asb_recover_0p(device); hg = drbd_asb_recover_0p(peer_device);
break; break;
case 1: case 1:
hg = drbd_asb_recover_1p(device); hg = drbd_asb_recover_1p(peer_device);
break; break;
case 2: case 2:
hg = drbd_asb_recover_2p(device); hg = drbd_asb_recover_2p(peer_device);
break; break;
} }
if (abs(hg) < 100) { if (abs(hg) < 100) {
...@@ -3078,7 +3100,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd ...@@ -3078,7 +3100,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd
} }
} }
if (tentative || test_bit(CONN_DRY_RUN, &first_peer_device(device)->connection->flags)) { if (tentative || test_bit(CONN_DRY_RUN, &peer_device->connection->flags)) {
if (hg == 0) if (hg == 0)
drbd_info(device, "dry-run connect: No resync, would become Connected immediately.\n"); drbd_info(device, "dry-run connect: No resync, would become Connected immediately.\n");
else else
...@@ -3665,7 +3687,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info ...@@ -3665,7 +3687,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info
drbd_get_capacity(device->this_bdev) || ldsc) { drbd_get_capacity(device->this_bdev) || ldsc) {
/* we have different sizes, probably peer /* we have different sizes, probably peer
* needs to know my new size... */ * needs to know my new size... */
drbd_send_sizes(device, 0, ddsf); drbd_send_sizes(peer_device, 0, ddsf);
} }
if (test_and_clear_bit(RESIZE_PENDING, &device->flags) || if (test_and_clear_bit(RESIZE_PENDING, &device->flags) ||
(dd == DS_GREW && device->state.conn == C_CONNECTED)) { (dd == DS_GREW && device->state.conn == C_CONNECTED)) {
...@@ -3808,7 +3830,7 @@ static int receive_req_state(struct drbd_connection *connection, struct packet_i ...@@ -3808,7 +3830,7 @@ static int receive_req_state(struct drbd_connection *connection, struct packet_i
if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags) && if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags) &&
mutex_is_locked(device->state_mutex)) { mutex_is_locked(device->state_mutex)) {
drbd_send_sr_reply(device, SS_CONCURRENT_ST_CHG); drbd_send_sr_reply(peer_device, SS_CONCURRENT_ST_CHG);
return 0; return 0;
} }
...@@ -3816,7 +3838,7 @@ static int receive_req_state(struct drbd_connection *connection, struct packet_i ...@@ -3816,7 +3838,7 @@ static int receive_req_state(struct drbd_connection *connection, struct packet_i
val = convert_state(val); val = convert_state(val);
rv = drbd_change_state(device, CS_VERBOSE, mask, val); rv = drbd_change_state(device, CS_VERBOSE, mask, val);
drbd_send_sr_reply(device, rv); drbd_send_sr_reply(peer_device, rv);
drbd_md_sync(device); drbd_md_sync(device);
...@@ -3955,7 +3977,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info ...@@ -3955,7 +3977,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
peer_state.conn <= C_WF_BITMAP_T)); peer_state.conn <= C_WF_BITMAP_T));
if (cr) if (cr)
ns.conn = drbd_sync_handshake(device, peer_state.role, real_peer_disk); ns.conn = drbd_sync_handshake(peer_device, peer_state.role, real_peer_disk);
put_ldev(device); put_ldev(device);
if (ns.conn == C_MASK) { if (ns.conn == C_MASK) {
...@@ -4013,8 +4035,8 @@ static int receive_state(struct drbd_connection *connection, struct packet_info ...@@ -4013,8 +4035,8 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
/* we want resync, peer has not yet decided to sync... */ /* we want resync, peer has not yet decided to sync... */
/* Nowadays only used when forcing a node into primary role and /* Nowadays only used when forcing a node into primary role and
setting its disk to UpToDate with that */ setting its disk to UpToDate with that */
drbd_send_uuids(device); drbd_send_uuids(peer_device);
drbd_send_current_state(device); drbd_send_current_state(peer_device);
} }
} }
...@@ -4067,27 +4089,27 @@ static int receive_sync_uuid(struct drbd_connection *connection, struct packet_i ...@@ -4067,27 +4089,27 @@ static int receive_sync_uuid(struct drbd_connection *connection, struct packet_i
* code upon failure. * code upon failure.
*/ */
static int static int
receive_bitmap_plain(struct drbd_device *device, unsigned int size, receive_bitmap_plain(struct drbd_peer_device *peer_device, unsigned int size,
unsigned long *p, struct bm_xfer_ctx *c) unsigned long *p, struct bm_xfer_ctx *c)
{ {
unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
drbd_header_size(first_peer_device(device)->connection); drbd_header_size(peer_device->connection);
unsigned int num_words = min_t(size_t, data_size / sizeof(*p), unsigned int num_words = min_t(size_t, data_size / sizeof(*p),
c->bm_words - c->word_offset); c->bm_words - c->word_offset);
unsigned int want = num_words * sizeof(*p); unsigned int want = num_words * sizeof(*p);
int err; int err;
if (want != size) { if (want != size) {
drbd_err(device, "%s:want (%u) != size (%u)\n", __func__, want, size); drbd_err(peer_device, "%s:want (%u) != size (%u)\n", __func__, want, size);
return -EIO; return -EIO;
} }
if (want == 0) if (want == 0)
return 0; return 0;
err = drbd_recv_all(first_peer_device(device)->connection, p, want); err = drbd_recv_all(peer_device->connection, p, want);
if (err) if (err)
return err; return err;
drbd_bm_merge_lel(device, c->word_offset, num_words, p); drbd_bm_merge_lel(peer_device->device, c->word_offset, num_words, p);
c->word_offset += num_words; c->word_offset += num_words;
c->bit_offset = c->word_offset * BITS_PER_LONG; c->bit_offset = c->word_offset * BITS_PER_LONG;
...@@ -4119,7 +4141,7 @@ static int dcbp_get_pad_bits(struct p_compressed_bm *p) ...@@ -4119,7 +4141,7 @@ static int dcbp_get_pad_bits(struct p_compressed_bm *p)
* code upon failure. * code upon failure.
*/ */
static int static int
recv_bm_rle_bits(struct drbd_device *device, recv_bm_rle_bits(struct drbd_peer_device *peer_device,
struct p_compressed_bm *p, struct p_compressed_bm *p,
struct bm_xfer_ctx *c, struct bm_xfer_ctx *c,
unsigned int len) unsigned int len)
...@@ -4148,14 +4170,14 @@ recv_bm_rle_bits(struct drbd_device *device, ...@@ -4148,14 +4170,14 @@ recv_bm_rle_bits(struct drbd_device *device,
if (toggle) { if (toggle) {
e = s + rl -1; e = s + rl -1;
if (e >= c->bm_bits) { if (e >= c->bm_bits) {
drbd_err(device, "bitmap overflow (e:%lu) while decoding bm RLE packet\n", e); drbd_err(peer_device, "bitmap overflow (e:%lu) while decoding bm RLE packet\n", e);
return -EIO; return -EIO;
} }
_drbd_bm_set_bits(device, s, e); _drbd_bm_set_bits(peer_device->device, s, e);
} }
if (have < bits) { if (have < bits) {
drbd_err(device, "bitmap decoding error: h:%d b:%d la:0x%08llx l:%u/%u\n", drbd_err(peer_device, "bitmap decoding error: h:%d b:%d la:0x%08llx l:%u/%u\n",
have, bits, look_ahead, have, bits, look_ahead,
(unsigned int)(bs.cur.b - p->code), (unsigned int)(bs.cur.b - p->code),
(unsigned int)bs.buf_len); (unsigned int)bs.buf_len);
...@@ -4188,20 +4210,20 @@ recv_bm_rle_bits(struct drbd_device *device, ...@@ -4188,20 +4210,20 @@ recv_bm_rle_bits(struct drbd_device *device,
* code upon failure. * code upon failure.
*/ */
static int static int
decode_bitmap_c(struct drbd_device *device, decode_bitmap_c(struct drbd_peer_device *peer_device,
struct p_compressed_bm *p, struct p_compressed_bm *p,
struct bm_xfer_ctx *c, struct bm_xfer_ctx *c,
unsigned int len) unsigned int len)
{ {
if (dcbp_get_code(p) == RLE_VLI_Bits) if (dcbp_get_code(p) == RLE_VLI_Bits)
return recv_bm_rle_bits(device, p, c, len - sizeof(*p)); return recv_bm_rle_bits(peer_device, p, c, len - sizeof(*p));
/* other variants had been implemented for evaluation, /* other variants had been implemented for evaluation,
* but have been dropped as this one turned out to be "best" * but have been dropped as this one turned out to be "best"
* during all our tests. */ * during all our tests. */
drbd_err(device, "receive_bitmap_c: unknown encoding %u\n", p->encoding); drbd_err(peer_device, "receive_bitmap_c: unknown encoding %u\n", p->encoding);
conn_request_state(first_peer_device(device)->connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD); conn_request_state(peer_device->connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
return -EIO; return -EIO;
} }
...@@ -4272,7 +4294,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info ...@@ -4272,7 +4294,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info
for(;;) { for(;;) {
if (pi->cmd == P_BITMAP) if (pi->cmd == P_BITMAP)
err = receive_bitmap_plain(device, pi->size, pi->data, &c); err = receive_bitmap_plain(peer_device, pi->size, pi->data, &c);
else if (pi->cmd == P_COMPRESSED_BITMAP) { else if (pi->cmd == P_COMPRESSED_BITMAP) {
/* MAYBE: sanity check that we speak proto >= 90, /* MAYBE: sanity check that we speak proto >= 90,
* and the feature is enabled! */ * and the feature is enabled! */
...@@ -4291,7 +4313,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info ...@@ -4291,7 +4313,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info
err = drbd_recv_all(peer_device->connection, p, pi->size); err = drbd_recv_all(peer_device->connection, p, pi->size);
if (err) if (err)
goto out; goto out;
err = decode_bitmap_c(device, p, &c, pi->size); err = decode_bitmap_c(peer_device, p, &c, pi->size);
} else { } else {
drbd_warn(device, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd); drbd_warn(device, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd);
err = -EIO; err = -EIO;
...@@ -4496,7 +4518,7 @@ static void conn_disconnect(struct drbd_connection *connection) ...@@ -4496,7 +4518,7 @@ static void conn_disconnect(struct drbd_connection *connection)
struct drbd_device *device = peer_device->device; struct drbd_device *device = peer_device->device;
kref_get(&device->kref); kref_get(&device->kref);
rcu_read_unlock(); rcu_read_unlock();
drbd_disconnected(device); drbd_disconnected(peer_device);
kref_put(&device->kref, drbd_destroy_device); kref_put(&device->kref, drbd_destroy_device);
rcu_read_lock(); rcu_read_lock();
} }
...@@ -4524,8 +4546,9 @@ static void conn_disconnect(struct drbd_connection *connection) ...@@ -4524,8 +4546,9 @@ static void conn_disconnect(struct drbd_connection *connection)
conn_request_state(connection, NS(conn, C_STANDALONE), CS_VERBOSE | CS_HARD); conn_request_state(connection, NS(conn, C_STANDALONE), CS_VERBOSE | CS_HARD);
} }
static int drbd_disconnected(struct drbd_device *device) static int drbd_disconnected(struct drbd_peer_device *peer_device)
{ {
struct drbd_device *device = peer_device->device;
unsigned int i; unsigned int i;
/* wait for current activity to cease. */ /* wait for current activity to cease. */
...@@ -4574,7 +4597,7 @@ static int drbd_disconnected(struct drbd_device *device) ...@@ -4574,7 +4597,7 @@ static int drbd_disconnected(struct drbd_device *device)
device->p_uuid = NULL; device->p_uuid = NULL;
if (!drbd_suspended(device)) if (!drbd_suspended(device))
tl_clear(first_peer_device(device)->connection); tl_clear(peer_device->connection);
drbd_md_sync(device); drbd_md_sync(device);
...@@ -4981,7 +5004,7 @@ static int got_IsInSync(struct drbd_connection *connection, struct packet_info * ...@@ -4981,7 +5004,7 @@ static int got_IsInSync(struct drbd_connection *connection, struct packet_info *
D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89); D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
update_peer_seq(device, be32_to_cpu(p->seq_num)); update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (get_ldev(device)) { if (get_ldev(device)) {
drbd_rs_complete_io(device, sector); drbd_rs_complete_io(device, sector);
...@@ -5032,7 +5055,7 @@ static int got_BlockAck(struct drbd_connection *connection, struct packet_info * ...@@ -5032,7 +5055,7 @@ static int got_BlockAck(struct drbd_connection *connection, struct packet_info *
return -EIO; return -EIO;
device = peer_device->device; device = peer_device->device;
update_peer_seq(device, be32_to_cpu(p->seq_num)); update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (p->block_id == ID_SYNCER) { if (p->block_id == ID_SYNCER) {
drbd_set_in_sync(device, sector, blksize); drbd_set_in_sync(device, sector, blksize);
...@@ -5078,7 +5101,7 @@ static int got_NegAck(struct drbd_connection *connection, struct packet_info *pi ...@@ -5078,7 +5101,7 @@ static int got_NegAck(struct drbd_connection *connection, struct packet_info *pi
return -EIO; return -EIO;
device = peer_device->device; device = peer_device->device;
update_peer_seq(device, be32_to_cpu(p->seq_num)); update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (p->block_id == ID_SYNCER) { if (p->block_id == ID_SYNCER) {
dec_rs_pending(device); dec_rs_pending(device);
...@@ -5112,7 +5135,7 @@ static int got_NegDReply(struct drbd_connection *connection, struct packet_info ...@@ -5112,7 +5135,7 @@ static int got_NegDReply(struct drbd_connection *connection, struct packet_info
return -EIO; return -EIO;
device = peer_device->device; device = peer_device->device;
update_peer_seq(device, be32_to_cpu(p->seq_num)); update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
drbd_err(device, "Got NegDReply; Sector %llus, len %u.\n", drbd_err(device, "Got NegDReply; Sector %llus, len %u.\n",
(unsigned long long)sector, be32_to_cpu(p->blksize)); (unsigned long long)sector, be32_to_cpu(p->blksize));
...@@ -5138,7 +5161,7 @@ static int got_NegRSDReply(struct drbd_connection *connection, struct packet_inf ...@@ -5138,7 +5161,7 @@ static int got_NegRSDReply(struct drbd_connection *connection, struct packet_inf
sector = be64_to_cpu(p->sector); sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize); size = be32_to_cpu(p->blksize);
update_peer_seq(device, be32_to_cpu(p->seq_num)); update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
dec_rs_pending(device); dec_rs_pending(device);
...@@ -5199,7 +5222,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info * ...@@ -5199,7 +5222,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info *
sector = be64_to_cpu(p->sector); sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize); size = be32_to_cpu(p->blksize);
update_peer_seq(device, be32_to_cpu(p->seq_num)); update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (be64_to_cpu(p->block_id) == ID_OUT_OF_SYNC) if (be64_to_cpu(p->block_id) == ID_OUT_OF_SYNC)
drbd_ov_out_of_sync_found(device, sector, size); drbd_ov_out_of_sync_found(device, sector, size);
......
...@@ -351,7 +351,7 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask, ...@@ -351,7 +351,7 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
goto abort; goto abort;
} }
if (drbd_send_state_req(device, mask, val)) { if (drbd_send_state_req(first_peer_device(device), mask, val)) {
rv = SS_CW_FAILED_BY_PEER; rv = SS_CW_FAILED_BY_PEER;
if (f & CS_VERBOSE) if (f & CS_VERBOSE)
print_st_err(device, os, ns, rv); print_st_err(device, os, ns, rv);
...@@ -1293,7 +1293,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1293,7 +1293,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) && if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) &&
(ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) && (ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) &&
first_peer_device(device)->connection->agreed_pro_version >= 96 && get_ldev(device)) { first_peer_device(device)->connection->agreed_pro_version >= 96 && get_ldev(device)) {
drbd_gen_and_send_sync_uuid(device); drbd_gen_and_send_sync_uuid(first_peer_device(device));
put_ldev(device); put_ldev(device);
} }
...@@ -1307,8 +1307,8 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1307,8 +1307,8 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
atomic_set(&device->rs_pending_cnt, 0); atomic_set(&device->rs_pending_cnt, 0);
drbd_rs_cancel_all(device); drbd_rs_cancel_all(device);
drbd_send_uuids(device); drbd_send_uuids(first_peer_device(device));
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
} }
/* No point in queuing send_bitmap if we don't have a connection /* No point in queuing send_bitmap if we don't have a connection
* anymore, so check also the _current_ state, not only the new state * anymore, so check also the _current_ state, not only the new state
...@@ -1333,7 +1333,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1333,7 +1333,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
set_bit(NEW_CUR_UUID, &device->flags); set_bit(NEW_CUR_UUID, &device->flags);
} else { } else {
drbd_uuid_new_current(device); drbd_uuid_new_current(device);
drbd_send_uuids(device); drbd_send_uuids(first_peer_device(device));
} }
} }
put_ldev(device); put_ldev(device);
...@@ -1344,7 +1344,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1344,7 +1344,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
if (os.peer == R_SECONDARY && ns.peer == R_PRIMARY && if (os.peer == R_SECONDARY && ns.peer == R_PRIMARY &&
device->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) { device->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
drbd_uuid_new_current(device); drbd_uuid_new_current(device);
drbd_send_uuids(device); drbd_send_uuids(first_peer_device(device));
} }
/* D_DISKLESS Peer becomes secondary */ /* D_DISKLESS Peer becomes secondary */
if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
...@@ -1371,16 +1371,16 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1371,16 +1371,16 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* Last part of the attaching process ... */ /* Last part of the attaching process ... */
if (ns.conn >= C_CONNECTED && if (ns.conn >= C_CONNECTED &&
os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) { os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) {
drbd_send_sizes(device, 0, 0); /* to start sync... */ drbd_send_sizes(first_peer_device(device), 0, 0); /* to start sync... */
drbd_send_uuids(device); drbd_send_uuids(first_peer_device(device));
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
} }
/* We want to pause/continue resync, tell peer. */ /* We want to pause/continue resync, tell peer. */
if (ns.conn >= C_CONNECTED && if (ns.conn >= C_CONNECTED &&
((os.aftr_isp != ns.aftr_isp) || ((os.aftr_isp != ns.aftr_isp) ||
(os.user_isp != ns.user_isp))) (os.user_isp != ns.user_isp)))
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
/* In case one of the isp bits got set, suspend other devices. */ /* In case one of the isp bits got set, suspend other devices. */
if ((!os.aftr_isp && !os.peer_isp && !os.user_isp) && if ((!os.aftr_isp && !os.peer_isp && !os.user_isp) &&
...@@ -1390,10 +1390,10 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1390,10 +1390,10 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* Make sure the peer gets informed about eventual state /* Make sure the peer gets informed about eventual state
changes (ISP bits) while we were in WFReportParams. */ changes (ISP bits) while we were in WFReportParams. */
if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED) if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED)
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
if (os.conn != C_AHEAD && ns.conn == C_AHEAD) if (os.conn != C_AHEAD && ns.conn == C_AHEAD)
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
/* We are in the progress to start a full sync... */ /* We are in the progress to start a full sync... */
if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) || if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
...@@ -1447,7 +1447,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1447,7 +1447,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
drbd_disk_str(device->state.disk)); drbd_disk_str(device->state.disk));
if (ns.conn >= C_CONNECTED) if (ns.conn >= C_CONNECTED)
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
drbd_rs_cancel_all(device); drbd_rs_cancel_all(device);
...@@ -1471,7 +1471,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1471,7 +1471,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
drbd_disk_str(device->state.disk)); drbd_disk_str(device->state.disk));
if (ns.conn >= C_CONNECTED) if (ns.conn >= C_CONNECTED)
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
/* corresponding get_ldev in __drbd_set_state /* corresponding get_ldev in __drbd_set_state
* this may finally trigger drbd_ldev_destroy. */ * this may finally trigger drbd_ldev_destroy. */
put_ldev(device); put_ldev(device);
...@@ -1479,7 +1479,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1479,7 +1479,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* Notify peer that I had a local IO error, and did not detached.. */ /* Notify peer that I had a local IO error, and did not detached.. */
if (os.disk == D_UP_TO_DATE && ns.disk == D_INCONSISTENT && ns.conn >= C_CONNECTED) if (os.disk == D_UP_TO_DATE && ns.disk == D_INCONSISTENT && ns.conn >= C_CONNECTED)
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
/* Disks got bigger while they were detached */ /* Disks got bigger while they were detached */
if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING && if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING &&
...@@ -1497,14 +1497,14 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1497,14 +1497,14 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* sync target done with resync. Explicitly notify peer, even though /* sync target done with resync. Explicitly notify peer, even though
* it should (at least for non-empty resyncs) already know itself. */ * it should (at least for non-empty resyncs) already know itself. */
if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED) if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED)
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
/* Verify finished, or reached stop sector. Peer did not know about /* Verify finished, or reached stop sector. Peer did not know about
* the stop sector, and we may even have changed the stop sector during * the stop sector, and we may even have changed the stop sector during
* verify to interrupt/stop early. Send the new state. */ * verify to interrupt/stop early. Send the new state. */
if (os.conn == C_VERIFY_S && ns.conn == C_CONNECTED if (os.conn == C_VERIFY_S && ns.conn == C_CONNECTED
&& verify_can_do_stop_sector(device)) && verify_can_do_stop_sector(device))
drbd_send_state(device, ns); drbd_send_state(first_peer_device(device), ns);
/* This triggers bitmap writeout of potentially still unwritten pages /* This triggers bitmap writeout of potentially still unwritten pages
* if the resync finished cleanly, or aborted because of peer disk * if the resync finished cleanly, or aborted because of peer disk
......
...@@ -358,7 +358,7 @@ static int w_e_send_csum(struct drbd_work *w, int cancel) ...@@ -358,7 +358,7 @@ static int w_e_send_csum(struct drbd_work *w, int cancel)
drbd_free_peer_req(device, peer_req); drbd_free_peer_req(device, peer_req);
peer_req = NULL; peer_req = NULL;
inc_rs_pending(device); inc_rs_pending(device);
err = drbd_send_drequest_csum(device, sector, size, err = drbd_send_drequest_csum(first_peer_device(device), sector, size,
digest, digest_size, digest, digest_size,
P_CSUM_RS_REQUEST); P_CSUM_RS_REQUEST);
kfree(digest); kfree(digest);
...@@ -378,8 +378,9 @@ static int w_e_send_csum(struct drbd_work *w, int cancel) ...@@ -378,8 +378,9 @@ static int w_e_send_csum(struct drbd_work *w, int cancel)
#define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN) #define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN)
static int read_for_csum(struct drbd_device *device, sector_t sector, int size) static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, int size)
{ {
struct drbd_device *device = peer_device->device;
struct drbd_peer_request *peer_req; struct drbd_peer_request *peer_req;
if (!get_ldev(device)) if (!get_ldev(device))
...@@ -390,7 +391,7 @@ static int read_for_csum(struct drbd_device *device, sector_t sector, int size) ...@@ -390,7 +391,7 @@ static int read_for_csum(struct drbd_device *device, sector_t sector, int size)
/* GFP_TRY, because if there is no memory available right now, this may /* GFP_TRY, because if there is no memory available right now, this may
* be rescheduled for later. It is "only" background resync, after all. */ * be rescheduled for later. It is "only" background resync, after all. */
peer_req = drbd_alloc_peer_req(device, ID_SYNCER /* unused */, sector, peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER /* unused */, sector,
size, GFP_TRY); size, GFP_TRY);
if (!peer_req) if (!peer_req)
goto defer; goto defer;
...@@ -676,7 +677,7 @@ int w_make_resync_request(struct drbd_work *w, int cancel) ...@@ -676,7 +677,7 @@ int w_make_resync_request(struct drbd_work *w, int cancel)
size = (capacity-sector)<<9; size = (capacity-sector)<<9;
if (first_peer_device(device)->connection->agreed_pro_version >= 89 && if (first_peer_device(device)->connection->agreed_pro_version >= 89 &&
first_peer_device(device)->connection->csums_tfm) { first_peer_device(device)->connection->csums_tfm) {
switch (read_for_csum(device, sector, size)) { switch (read_for_csum(first_peer_device(device), sector, size)) {
case -EIO: /* Disk failure */ case -EIO: /* Disk failure */
put_ldev(device); put_ldev(device);
return -EIO; return -EIO;
...@@ -695,7 +696,7 @@ int w_make_resync_request(struct drbd_work *w, int cancel) ...@@ -695,7 +696,7 @@ int w_make_resync_request(struct drbd_work *w, int cancel)
int err; int err;
inc_rs_pending(device); inc_rs_pending(device);
err = drbd_send_drequest(device, P_RS_DATA_REQUEST, err = drbd_send_drequest(first_peer_device(device), P_RS_DATA_REQUEST,
sector, size, ID_SYNCER); sector, size, ID_SYNCER);
if (err) { if (err) {
drbd_err(device, "drbd_send_drequest() failed, aborting...\n"); drbd_err(device, "drbd_send_drequest() failed, aborting...\n");
...@@ -763,7 +764,7 @@ static int w_make_ov_request(struct drbd_work *w, int cancel) ...@@ -763,7 +764,7 @@ static int w_make_ov_request(struct drbd_work *w, int cancel)
size = (capacity-sector)<<9; size = (capacity-sector)<<9;
inc_rs_pending(device); inc_rs_pending(device);
if (drbd_send_ov_request(device, sector, size)) { if (drbd_send_ov_request(first_peer_device(device), sector, size)) {
dec_rs_pending(device); dec_rs_pending(device);
return 0; return 0;
} }
...@@ -997,13 +998,13 @@ int w_e_end_data_req(struct drbd_work *w, int cancel) ...@@ -997,13 +998,13 @@ int w_e_end_data_req(struct drbd_work *w, int cancel)
} }
if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) { if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
err = drbd_send_block(device, P_DATA_REPLY, peer_req); err = drbd_send_block(first_peer_device(device), P_DATA_REPLY, peer_req);
} else { } else {
if (__ratelimit(&drbd_ratelimit_state)) if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Sending NegDReply. sector=%llus.\n", drbd_err(device, "Sending NegDReply. sector=%llus.\n",
(unsigned long long)peer_req->i.sector); (unsigned long long)peer_req->i.sector);
err = drbd_send_ack(device, P_NEG_DREPLY, peer_req); err = drbd_send_ack(first_peer_device(device), P_NEG_DREPLY, peer_req);
} }
dec_unacked(device); dec_unacked(device);
...@@ -1039,11 +1040,11 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel) ...@@ -1039,11 +1040,11 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
} }
if (device->state.conn == C_AHEAD) { if (device->state.conn == C_AHEAD) {
err = drbd_send_ack(device, P_RS_CANCEL, peer_req); err = drbd_send_ack(first_peer_device(device), P_RS_CANCEL, peer_req);
} else if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) { } else if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
if (likely(device->state.pdsk >= D_INCONSISTENT)) { if (likely(device->state.pdsk >= D_INCONSISTENT)) {
inc_rs_pending(device); inc_rs_pending(device);
err = drbd_send_block(device, P_RS_DATA_REPLY, peer_req); err = drbd_send_block(first_peer_device(device), P_RS_DATA_REPLY, peer_req);
} else { } else {
if (__ratelimit(&drbd_ratelimit_state)) if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Not sending RSDataReply, " drbd_err(device, "Not sending RSDataReply, "
...@@ -1055,7 +1056,7 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel) ...@@ -1055,7 +1056,7 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
drbd_err(device, "Sending NegRSDReply. sector %llus.\n", drbd_err(device, "Sending NegRSDReply. sector %llus.\n",
(unsigned long long)peer_req->i.sector); (unsigned long long)peer_req->i.sector);
err = drbd_send_ack(device, P_NEG_RS_DREPLY, peer_req); err = drbd_send_ack(first_peer_device(device), P_NEG_RS_DREPLY, peer_req);
/* update resync data with failure */ /* update resync data with failure */
drbd_rs_failed_io(device, peer_req->i.sector, peer_req->i.size); drbd_rs_failed_io(device, peer_req->i.sector, peer_req->i.size);
...@@ -1111,16 +1112,16 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel) ...@@ -1111,16 +1112,16 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
drbd_set_in_sync(device, peer_req->i.sector, peer_req->i.size); drbd_set_in_sync(device, peer_req->i.sector, peer_req->i.size);
/* rs_same_csums unit is BM_BLOCK_SIZE */ /* rs_same_csums unit is BM_BLOCK_SIZE */
device->rs_same_csum += peer_req->i.size >> BM_BLOCK_SHIFT; device->rs_same_csum += peer_req->i.size >> BM_BLOCK_SHIFT;
err = drbd_send_ack(device, P_RS_IS_IN_SYNC, peer_req); err = drbd_send_ack(first_peer_device(device), P_RS_IS_IN_SYNC, peer_req);
} else { } else {
inc_rs_pending(device); inc_rs_pending(device);
peer_req->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */ peer_req->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */
peer_req->flags &= ~EE_HAS_DIGEST; /* This peer request no longer has a digest pointer */ peer_req->flags &= ~EE_HAS_DIGEST; /* This peer request no longer has a digest pointer */
kfree(di); kfree(di);
err = drbd_send_block(device, P_RS_DATA_REPLY, peer_req); err = drbd_send_block(first_peer_device(device), P_RS_DATA_REPLY, peer_req);
} }
} else { } else {
err = drbd_send_ack(device, P_NEG_RS_DREPLY, peer_req); err = drbd_send_ack(first_peer_device(device), P_NEG_RS_DREPLY, peer_req);
if (__ratelimit(&drbd_ratelimit_state)) if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Sending NegDReply. I guess it gets messy.\n"); drbd_err(device, "Sending NegDReply. I guess it gets messy.\n");
} }
...@@ -1166,7 +1167,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel) ...@@ -1166,7 +1167,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel)
drbd_free_peer_req(device, peer_req); drbd_free_peer_req(device, peer_req);
peer_req = NULL; peer_req = NULL;
inc_rs_pending(device); inc_rs_pending(device);
err = drbd_send_drequest_csum(device, sector, size, digest, digest_size, P_OV_REPLY); err = drbd_send_drequest_csum(first_peer_device(device), sector, size, digest, digest_size, P_OV_REPLY);
if (err) if (err)
dec_rs_pending(device); dec_rs_pending(device);
kfree(digest); kfree(digest);
...@@ -1239,7 +1240,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel) ...@@ -1239,7 +1240,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel)
else else
ov_out_of_sync_print(device); ov_out_of_sync_print(device);
err = drbd_send_ack_ex(device, P_OV_RESULT, sector, size, err = drbd_send_ack_ex(first_peer_device(device), P_OV_RESULT, sector, size,
eq ? ID_IN_SYNC : ID_OUT_OF_SYNC); eq ? ID_IN_SYNC : ID_OUT_OF_SYNC);
dec_unacked(device); dec_unacked(device);
...@@ -1298,9 +1299,9 @@ int w_send_write_hint(struct drbd_work *w, int cancel) ...@@ -1298,9 +1299,9 @@ int w_send_write_hint(struct drbd_work *w, int cancel)
if (cancel) if (cancel)
return 0; return 0;
sock = &first_peer_device(device)->connection->data; sock = &first_peer_device(device)->connection->data;
if (!drbd_prepare_command(device, sock)) if (!drbd_prepare_command(first_peer_device(device), sock))
return -EIO; return -EIO;
return drbd_send_command(device, sock, P_UNPLUG_REMOTE, 0, NULL, 0); return drbd_send_command(first_peer_device(device), sock, P_UNPLUG_REMOTE, 0, NULL, 0);
} }
static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch) static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch)
...@@ -1342,7 +1343,7 @@ int w_send_out_of_sync(struct drbd_work *w, int cancel) ...@@ -1342,7 +1343,7 @@ int w_send_out_of_sync(struct drbd_work *w, int cancel)
* No more barriers will be sent, until we leave AHEAD mode again. */ * No more barriers will be sent, until we leave AHEAD mode again. */
maybe_send_barrier(connection, req->epoch); maybe_send_barrier(connection, req->epoch);
err = drbd_send_out_of_sync(device, req); err = drbd_send_out_of_sync(first_peer_device(device), req);
req_mod(req, OOS_HANDED_TO_NETWORK); req_mod(req, OOS_HANDED_TO_NETWORK);
return err; return err;
...@@ -1370,7 +1371,7 @@ int w_send_dblock(struct drbd_work *w, int cancel) ...@@ -1370,7 +1371,7 @@ int w_send_dblock(struct drbd_work *w, int cancel)
maybe_send_barrier(connection, req->epoch); maybe_send_barrier(connection, req->epoch);
connection->send.current_epoch_writes++; connection->send.current_epoch_writes++;
err = drbd_send_dblock(device, req); err = drbd_send_dblock(first_peer_device(device), req);
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK); req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
return err; return err;
...@@ -1398,7 +1399,7 @@ int w_send_read_req(struct drbd_work *w, int cancel) ...@@ -1398,7 +1399,7 @@ int w_send_read_req(struct drbd_work *w, int cancel)
* if there was any yet. */ * if there was any yet. */
maybe_send_barrier(connection, req->epoch); maybe_send_barrier(connection, req->epoch);
err = drbd_send_drequest(device, P_DATA_REQUEST, req->i.sector, req->i.size, err = drbd_send_drequest(first_peer_device(device), P_DATA_REQUEST, req->i.sector, req->i.size,
(unsigned long)req); (unsigned long)req);
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK); req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
...@@ -1730,7 +1731,7 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) ...@@ -1730,7 +1731,7 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
* and from after_state_ch otherwise. */ * and from after_state_ch otherwise. */
if (side == C_SYNC_SOURCE && if (side == C_SYNC_SOURCE &&
first_peer_device(device)->connection->agreed_pro_version < 96) first_peer_device(device)->connection->agreed_pro_version < 96)
drbd_gen_and_send_sync_uuid(device); drbd_gen_and_send_sync_uuid(first_peer_device(device));
if (first_peer_device(device)->connection->agreed_pro_version < 95 && if (first_peer_device(device)->connection->agreed_pro_version < 95 &&
device->rs_total == 0) { device->rs_total == 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册