drbd: Introduce "peer_device" object between "device" and "connection"
In a setup where a device (aka volume) can replicate to multiple peers and one
connection can be shared between multiple devices, we need separate objects to
represent devices on peer nodes and network connections.
As a first step to introduce multiple connections per device, give each
drbd_device object a single drbd_peer_device object which connects it to a
drbd_connection object.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 8b50745..4af4dc1 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -315,7 +315,7 @@
{
bool locked = false;
- BUG_ON(delegate && current == device->connection->worker.task);
+ BUG_ON(delegate && current == first_peer_device(device)->connection->worker.task);
/* Serialize multiple transactions.
* This uses test_and_set_bit, memory barrier is implicit.
@@ -354,7 +354,7 @@
*/
void drbd_al_begin_io(struct drbd_device *device, struct drbd_interval *i, bool delegate)
{
- BUG_ON(delegate && current == device->connection->worker.task);
+ BUG_ON(delegate && current == first_peer_device(device)->connection->worker.task);
if (drbd_al_begin_io_prepare(device, i))
drbd_al_begin_io_commit(device, delegate);
@@ -614,7 +614,7 @@
init_completion(&al_work.event);
al_work.w.cb = w_al_write_transaction;
al_work.w.device = device;
- drbd_queue_work_front(&device->connection->sender_work, &al_work.w);
+ drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &al_work.w);
wait_for_completion(&al_work.event);
return al_work.err;
} else
@@ -796,7 +796,7 @@
udw->enr = ext->lce.lc_number;
udw->w.cb = w_update_odbm;
udw->w.device = device;
- drbd_queue_work_front(&device->connection->sender_work, &udw->w);
+ drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &udw->w);
} else {
dev_warn(DEV, "Could not kmalloc an udw\n");
}
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index cd3e0de..cb8e649 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -119,9 +119,9 @@
if (!__ratelimit(&drbd_ratelimit_state))
return;
dev_err(DEV, "FIXME %s in %s, bitmap locked for '%s' by %s\n",
- drbd_task_to_thread_name(device->connection, current),
+ drbd_task_to_thread_name(first_peer_device(device)->connection, current),
func, b->bm_why ?: "?",
- drbd_task_to_thread_name(device->connection, b->bm_task));
+ drbd_task_to_thread_name(first_peer_device(device)->connection, b->bm_task));
}
void drbd_bm_lock(struct drbd_device *device, char *why, enum bm_flag flags)
@@ -138,9 +138,9 @@
if (trylock_failed) {
dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
- drbd_task_to_thread_name(device->connection, current),
+ drbd_task_to_thread_name(first_peer_device(device)->connection, current),
why, b->bm_why ?: "?",
- drbd_task_to_thread_name(device->connection, b->bm_task));
+ drbd_task_to_thread_name(first_peer_device(device)->connection, b->bm_task));
mutex_lock(&b->bm_change);
}
if (BM_LOCKED_MASK & b->bm_flags)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 32517a0..85e2f4b 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -483,7 +483,7 @@
struct block_device *backing_bdev;
struct block_device *md_bdev;
struct drbd_md md;
- struct disk_conf *disk_conf; /* RCU, for updates: device->connection->conf_update */
+ struct disk_conf *disk_conf; /* RCU, for updates: first_peer_device(device)->connection->conf_update */
sector_t known_size; /* last known size of that backing device */
};
@@ -617,8 +617,14 @@
struct list_head writes;
};
-struct drbd_device {
+struct drbd_peer_device {
+ struct list_head peer_devices;
+ struct drbd_device *device;
struct drbd_connection *connection;
+};
+
+struct drbd_device {
+ struct list_head peer_devices;
int vnr; /* volume number within the connection */
struct kref kref;
@@ -744,7 +750,7 @@
struct bm_io_work bm_io_work;
u64 ed_uuid; /* UUID of the exposed data */
struct mutex own_state_mutex;
- struct mutex *state_mutex; /* either own_state_mutex or device->connection->cstate_mutex */
+ struct mutex *state_mutex; /* either own_state_mutex or first_peer_device(device)->connection->cstate_mutex */
char congestion_reason; /* Why we where congested... */
atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */
atomic_t rs_sect_ev; /* for submitted resync data rate, both */
@@ -768,6 +774,20 @@
return (struct drbd_device *)idr_find(&minors, minor);
}
+static inline struct drbd_peer_device *first_peer_device(struct drbd_device *device)
+{
+ return list_first_entry(&device->peer_devices, struct drbd_peer_device, peer_devices);
+}
+
+#define for_each_peer_device(peer_device, device) \
+ list_for_each_entry(peer_device, &device->peer_devices, peer_devices)
+
+#define for_each_peer_device_rcu(peer_device, device) \
+ list_for_each_entry_rcu(peer_device, &device->peer_devices, peer_devices)
+
+#define for_each_peer_device_safe(peer_device, tmp, device) \
+ list_for_each_entry_safe(peer_device, tmp, &device->peer_devices, peer_devices)
+
static inline unsigned int device_to_minor(struct drbd_device *device)
{
return device->minor;
@@ -1154,7 +1174,7 @@
extern rwlock_t global_state_lock;
extern int conn_lowest_minor(struct drbd_connection *connection);
-enum drbd_ret_code conn_new_minor(struct drbd_connection *connection, unsigned int minor, int vnr);
+enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigned int minor, int vnr);
extern void drbd_minor_destroy(struct kref *kref);
extern int set_resource_options(struct drbd_connection *connection, struct res_opts *res_opts);
@@ -1275,7 +1295,7 @@
extern int drbd_connected(struct drbd_device *device);
static inline void drbd_flush_workqueue(struct drbd_device *device)
{
- conn_flush_workqueue(device->connection);
+ conn_flush_workqueue(first_peer_device(device)->connection);
}
/* Yes, there is kernel_setsockopt, but only since 2.6.18.
@@ -1421,9 +1441,9 @@
union drbd_state rv;
rv.i = device->state.i;
- rv.susp = device->connection->susp;
- rv.susp_nod = device->connection->susp_nod;
- rv.susp_fen = device->connection->susp_fen;
+ rv.susp = first_peer_device(device)->connection->susp;
+ rv.susp_nod = first_peer_device(device)->connection->susp_nod;
+ rv.susp_fen = first_peer_device(device)->connection->susp_fen;
return rv;
}
@@ -1505,9 +1525,9 @@
{
if (error) {
unsigned long flags;
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
__drbd_chk_io_error_(device, forcedetach, where);
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
}
}
@@ -1783,7 +1803,7 @@
if (device->state.disk == D_FAILED) {
/* all application IO references gone. */
if (!test_and_set_bit(GO_DISKLESS, &device->flags))
- drbd_queue_work(&device->connection->sender_work, &device->go_diskless);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->go_diskless);
}
wake_up(&device->misc_wait);
}
@@ -1865,7 +1885,7 @@
int mxb;
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
mxb = nc ? nc->max_buffers : 1000000; /* arbitrary limit on open requests */
rcu_read_unlock();
@@ -1908,7 +1928,7 @@
/* Allow IO in BM exchange states with new protocols */
case C_WF_BITMAP_S:
- if (device->connection->agreed_pro_version < 96)
+ if (first_peer_device(device)->connection->agreed_pro_version < 96)
return 0;
break;
@@ -1944,7 +1964,7 @@
static inline int drbd_suspended(struct drbd_device *device)
{
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
return connection->susp || connection->susp_fen || connection->susp_nod;
}
@@ -1979,11 +1999,11 @@
{
bool rv = false;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
rv = may_inc_ap_bio(device);
if (rv)
atomic_inc(&device->ap_bio_cnt);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
return rv;
}
@@ -2010,7 +2030,7 @@
if (ap_bio == 0 && test_bit(BITMAP_IO, &device->flags)) {
if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
- drbd_queue_work(&device->connection->sender_work, &device->bm_io_work.w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w);
}
/* this currently does wake_up for every dec_ap_bio!
@@ -2022,8 +2042,8 @@
static inline bool verify_can_do_stop_sector(struct drbd_device *device)
{
- return device->connection->agreed_pro_version >= 97 &&
- device->connection->agreed_pro_version != 100;
+ return first_peer_device(device)->connection->agreed_pro_version >= 97 &&
+ first_peer_device(device)->connection->agreed_pro_version != 100;
}
static inline int drbd_set_ed_uuid(struct drbd_device *device, u64 val)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e4fd180..b7c858f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -308,7 +308,7 @@
*/
void tl_abort_disk_io(struct drbd_device *device)
{
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
struct drbd_request *req, *r;
spin_lock_irq(&connection->req_lock);
@@ -633,7 +633,7 @@
void *drbd_prepare_command(struct drbd_device *device, struct drbd_socket *sock)
{
- return conn_prepare_command(device->connection, sock);
+ return conn_prepare_command(first_peer_device(device)->connection, sock);
}
static int __send_command(struct drbd_connection *connection, int vnr,
@@ -686,7 +686,7 @@
{
int err;
- err = __send_command(device->connection, device->vnr, sock, cmd, header_size,
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, header_size,
data, size);
mutex_unlock(&sock->mutex);
return err;
@@ -717,18 +717,18 @@
struct drbd_socket *sock;
struct p_rs_param_95 *p;
int size;
- const int apv = device->connection->agreed_pro_version;
+ const int apv = first_peer_device(device)->connection->agreed_pro_version;
enum drbd_packet cmd;
struct net_conf *nc;
struct disk_conf *dc;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
size = apv <= 87 ? sizeof(struct p_rs_param)
: apv == 88 ? sizeof(struct p_rs_param)
@@ -831,7 +831,7 @@
if (!get_ldev_if_state(device, D_NEGOTIATING))
return 0;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p) {
put_ldev(device);
@@ -845,7 +845,7 @@
device->comm_bm_set = drbd_bm_total_weight(device);
p->uuid[UI_SIZE] = cpu_to_be64(device->comm_bm_set);
rcu_read_lock();
- uuid_flags |= rcu_dereference(device->connection->net_conf)->discard_my_data ? 1 : 0;
+ uuid_flags |= rcu_dereference(first_peer_device(device)->connection->net_conf)->discard_my_data ? 1 : 0;
rcu_read_unlock();
uuid_flags |= test_bit(CRASHED_PRIMARY, &device->flags) ? 2 : 0;
uuid_flags |= device->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0;
@@ -900,7 +900,7 @@
drbd_print_uuids(device, "updated sync UUID");
drbd_md_sync(device);
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (p) {
p->uuid = cpu_to_be64(uuid);
@@ -933,14 +933,14 @@
max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */
}
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
- if (device->connection->agreed_pro_version <= 94)
+ if (first_peer_device(device)->connection->agreed_pro_version <= 94)
max_bio_size = min(max_bio_size, DRBD_MAX_SIZE_H80_PACKET);
- else if (device->connection->agreed_pro_version < 100)
+ else if (first_peer_device(device)->connection->agreed_pro_version < 100)
max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE_P95);
p->d_size = cpu_to_be64(d_size);
@@ -961,7 +961,7 @@
struct drbd_socket *sock;
struct p_state *p;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -984,7 +984,7 @@
struct drbd_socket *sock;
struct p_state *p;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -997,7 +997,7 @@
struct drbd_socket *sock;
struct p_req_state *p;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -1027,7 +1027,7 @@
struct drbd_socket *sock;
struct p_req_state_reply *p;
- sock = &device->connection->meta;
+ sock = &first_peer_device(device)->connection->meta;
p = drbd_prepare_command(device, sock);
if (p) {
p->retcode = cpu_to_be32(retcode);
@@ -1081,9 +1081,9 @@
/* may we use this feature? */
rcu_read_lock();
- use_rle = rcu_dereference(device->connection->net_conf)->use_rle;
+ use_rle = rcu_dereference(first_peer_device(device)->connection->net_conf)->use_rle;
rcu_read_unlock();
- if (!use_rle || device->connection->agreed_pro_version < 90)
+ if (!use_rle || first_peer_device(device)->connection->agreed_pro_version < 90)
return 0;
if (c->bit_offset >= c->bm_bits)
@@ -1172,8 +1172,8 @@
static int
send_bitmap_rle_or_plain(struct drbd_device *device, struct bm_xfer_ctx *c)
{
- struct drbd_socket *sock = &device->connection->data;
- unsigned int header_size = drbd_header_size(device->connection);
+ struct drbd_socket *sock = &first_peer_device(device)->connection->data;
+ unsigned int header_size = drbd_header_size(first_peer_device(device)->connection);
struct p_compressed_bm *p = sock->sbuf + header_size;
int len, err;
@@ -1184,7 +1184,7 @@
if (len) {
dcbp_set_code(p, RLE_VLI_Bits);
- err = __send_command(device->connection, device->vnr, sock,
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock,
P_COMPRESSED_BITMAP, sizeof(*p) + len,
NULL, 0);
c->packets[0]++;
@@ -1205,7 +1205,7 @@
len = num_words * sizeof(*p);
if (len)
drbd_bm_get_lel(device, c->word_offset, num_words, p);
- err = __send_command(device->connection, device->vnr, sock, P_BITMAP, len, NULL, 0);
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_BITMAP, len, NULL, 0);
c->word_offset += num_words;
c->bit_offset = c->word_offset * BITS_PER_LONG;
@@ -1265,7 +1265,7 @@
int drbd_send_bitmap(struct drbd_device *device)
{
- struct drbd_socket *sock = &device->connection->data;
+ struct drbd_socket *sock = &first_peer_device(device)->connection->data;
int err = -1;
mutex_lock(&sock->mutex);
@@ -1309,7 +1309,7 @@
if (device->state.conn < C_CONNECTED)
return -EIO;
- sock = &device->connection->meta;
+ sock = &first_peer_device(device)->connection->meta;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -1326,8 +1326,8 @@
void drbd_send_ack_dp(struct drbd_device *device, enum drbd_packet cmd,
struct p_data *dp, int data_size)
{
- if (device->connection->peer_integrity_tfm)
- data_size -= crypto_hash_digestsize(device->connection->peer_integrity_tfm);
+ if (first_peer_device(device)->connection->peer_integrity_tfm)
+ data_size -= crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
_drbd_send_ack(device, cmd, dp->sector, cpu_to_be32(data_size),
dp->block_id);
}
@@ -1370,7 +1370,7 @@
struct drbd_socket *sock;
struct p_block_req *p;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -1388,7 +1388,7 @@
/* FIXME: Put the digest into the preallocated socket buffer. */
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -1404,7 +1404,7 @@
struct drbd_socket *sock;
struct p_block_req *p;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -1476,9 +1476,9 @@
void *addr;
int err;
- socket = device->connection->data.socket;
+ socket = first_peer_device(device)->connection->data.socket;
addr = kmap(page) + offset;
- err = drbd_send_all(device->connection, socket, addr, size, msg_flags);
+ err = drbd_send_all(first_peer_device(device)->connection, socket, addr, size, msg_flags);
kunmap(page);
if (!err)
device->send_cnt += size >> 9;
@@ -1488,7 +1488,7 @@
static int _drbd_send_page(struct drbd_device *device, struct page *page,
int offset, size_t size, unsigned msg_flags)
{
- struct socket *socket = device->connection->data.socket;
+ struct socket *socket = first_peer_device(device)->connection->data.socket;
mm_segment_t oldfs = get_fs();
int len = size;
int err = -EIO;
@@ -1503,7 +1503,7 @@
return _drbd_no_send_page(device, page, offset, size, msg_flags);
msg_flags |= MSG_NOSIGNAL;
- drbd_update_congested(device->connection);
+ drbd_update_congested(first_peer_device(device)->connection);
set_fs(KERNEL_DS);
do {
int sent;
@@ -1511,7 +1511,7 @@
sent = socket->ops->sendpage(socket, page, offset, len, msg_flags);
if (sent <= 0) {
if (sent == -EAGAIN) {
- if (we_should_drop_the_connection(device->connection, socket))
+ if (we_should_drop_the_connection(first_peer_device(device)->connection, socket))
break;
continue;
}
@@ -1525,7 +1525,7 @@
offset += sent;
} while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/);
set_fs(oldfs);
- clear_bit(NET_CONGESTED, &device->connection->flags);
+ clear_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags);
if (len == 0) {
err = 0;
@@ -1593,7 +1593,7 @@
static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw)
{
- if (device->connection->agreed_pro_version >= 95)
+ if (first_peer_device(device)->connection->agreed_pro_version >= 95)
return (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
(bi_rw & REQ_FUA ? DP_FUA : 0) |
(bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
@@ -1613,9 +1613,10 @@
int dgs;
int err;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
- dgs = device->connection->integrity_tfm ? crypto_hash_digestsize(device->connection->integrity_tfm) : 0;
+ dgs = first_peer_device(device)->connection->integrity_tfm ?
+ crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
if (!p)
return -EIO;
@@ -1626,7 +1627,7 @@
if (device->state.conn >= C_SYNC_SOURCE &&
device->state.conn <= C_PAUSED_SYNC_T)
dp_flags |= DP_MAY_SET_IN_SYNC;
- if (device->connection->agreed_pro_version >= 100) {
+ if (first_peer_device(device)->connection->agreed_pro_version >= 100) {
if (req->rq_state & RQ_EXP_RECEIVE_ACK)
dp_flags |= DP_SEND_RECEIVE_ACK;
if (req->rq_state & RQ_EXP_WRITE_ACK)
@@ -1634,8 +1635,8 @@
}
p->dp_flags = cpu_to_be32(dp_flags);
if (dgs)
- drbd_csum_bio(device, device->connection->integrity_tfm, req->master_bio, p + 1);
- err = __send_command(device->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
+ drbd_csum_bio(device, first_peer_device(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);
if (!err) {
/* For protocol A, we have to memcpy the payload into
* socket buffers, as we may complete right away
@@ -1658,7 +1659,7 @@
/* 64 byte, 512 bit, is the largest digest size
* currently supported in kernel crypto. */
unsigned char digest[64];
- drbd_csum_bio(device, device->connection->integrity_tfm, req->master_bio, digest);
+ drbd_csum_bio(device, first_peer_device(device)->connection->integrity_tfm, req->master_bio, digest);
if (memcmp(p + 1, digest, dgs)) {
dev_warn(DEV,
"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
@@ -1685,10 +1686,11 @@
int err;
int dgs;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
- dgs = device->connection->integrity_tfm ? crypto_hash_digestsize(device->connection->integrity_tfm) : 0;
+ dgs = first_peer_device(device)->connection->integrity_tfm ?
+ crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
if (!p)
return -EIO;
@@ -1697,8 +1699,8 @@
p->seq_num = 0; /* unused */
p->dp_flags = 0;
if (dgs)
- drbd_csum_ee(device, device->connection->integrity_tfm, peer_req, p + 1);
- err = __send_command(device->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
+ drbd_csum_ee(device, first_peer_device(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);
if (!err)
err = _drbd_send_zc_ee(device, peer_req);
mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */
@@ -1711,7 +1713,7 @@
struct drbd_socket *sock;
struct p_block_desc *p;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
@@ -1832,7 +1834,7 @@
int rv = 0;
mutex_lock(&drbd_main_mutex);
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
/* to have a stable device->state.role
* and no race with updating open_cnt */
@@ -1845,7 +1847,7 @@
if (!rv)
device->open_cnt++;
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
mutex_unlock(&drbd_main_mutex);
return rv;
@@ -1950,9 +1952,9 @@
void drbd_device_cleanup(struct drbd_device *device)
{
int i;
- if (device->connection->receiver.t_state != NONE)
+ if (first_peer_device(device)->connection->receiver.t_state != NONE)
dev_err(DEV, "ASSERT FAILED: receiver t_state == %d expected 0.\n",
- device->connection->receiver.t_state);
+ first_peer_device(device)->connection->receiver.t_state);
device->al_writ_cnt =
device->bm_writ_cnt =
@@ -1970,7 +1972,7 @@
device->rs_mark_left[i] = 0;
device->rs_mark_time[i] = 0;
}
- D_ASSERT(device->connection->net_conf == NULL);
+ D_ASSERT(first_peer_device(device)->connection->net_conf == NULL);
drbd_set_my_capacity(device, 0);
if (device->bitmap) {
@@ -1990,7 +1992,7 @@
D_ASSERT(list_empty(&device->read_ee));
D_ASSERT(list_empty(&device->net_ee));
D_ASSERT(list_empty(&device->resync_reads));
- D_ASSERT(list_empty(&device->connection->sender_work.q));
+ D_ASSERT(list_empty(&first_peer_device(device)->connection->sender_work.q));
D_ASSERT(list_empty(&device->resync_work.list));
D_ASSERT(list_empty(&device->unplug_work.list));
D_ASSERT(list_empty(&device->go_diskless.list));
@@ -2159,7 +2161,7 @@
void drbd_minor_destroy(struct kref *kref)
{
struct drbd_device *device = container_of(kref, struct drbd_device, kref);
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
del_timer_sync(&device->request_timer);
@@ -2190,6 +2192,7 @@
put_disk(device->vdisk);
blk_cleanup_queue(device->rq_queue);
kfree(device->rs_plan_s);
+ kfree(first_peer_device(device));
kfree(device);
kref_put(&connection->kref, &conn_destroy);
@@ -2300,7 +2303,7 @@
idr_for_each_entry(&minors, device, i) {
idr_remove(&minors, device_to_minor(device));
- idr_remove(&device->connection->volumes, device->vnr);
+ idr_remove(&first_peer_device(device)->connection->volumes, device->vnr);
destroy_workqueue(device->submit.wq);
del_gendisk(device->vdisk);
/* synchronize_rcu(); No other threads running at this point */
@@ -2343,7 +2346,7 @@
goto out;
}
- if (test_bit(CALLBACK_PENDING, &device->connection->flags)) {
+ if (test_bit(CALLBACK_PENDING, &first_peer_device(device)->connection->flags)) {
r |= (1 << BDI_async_congested);
/* Without good local data, we would need to read from remote,
* and that would need the worker thread as well, which is
@@ -2367,7 +2370,8 @@
reason = 'b';
}
- if (bdi_bits & (1 << BDI_async_congested) && test_bit(NET_CONGESTED, &device->connection->flags)) {
+ if (bdi_bits & (1 << BDI_async_congested) &&
+ test_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags)) {
r |= (1 << BDI_async_congested);
reason = reason == 'b' ? 'a' : 'n';
}
@@ -2606,9 +2610,10 @@
return 0;
}
-enum drbd_ret_code conn_new_minor(struct drbd_connection *connection, unsigned int minor, int vnr)
+enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigned int minor, int vnr)
{
struct drbd_device *device;
+ struct drbd_peer_device *peer_device;
struct gendisk *disk;
struct request_queue *q;
int vnr_got = vnr;
@@ -2623,9 +2628,15 @@
device = kzalloc(sizeof(struct drbd_device), GFP_KERNEL);
if (!device)
return ERR_NOMEM;
+ peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL);
+ if (!peer_device)
+ goto out_no_peer_device;
+ INIT_LIST_HEAD(&device->peer_devices);
+ list_add(&peer_device->peer_devices, &device->peer_devices);
kref_get(&connection->kref);
- device->connection = connection;
+ peer_device->connection = connection;
+ peer_device->device = device;
device->minor = minor;
device->vnr = vnr;
@@ -2666,7 +2677,7 @@
blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
blk_queue_merge_bvec(q, drbd_merge_bvec);
- q->queue_lock = &device->connection->req_lock; /* needed since we use */
+ q->queue_lock = &first_peer_device(device)->connection->req_lock; /* needed since we use */
device->md_io_page = alloc_page(GFP_KERNEL);
if (!device->md_io_page)
@@ -2725,8 +2736,9 @@
out_no_disk:
blk_cleanup_queue(q);
out_no_q:
- kfree(device);
kref_put(&connection->kref, &conn_destroy);
+out_no_peer_device:
+ kfree(device);
return err;
}
@@ -3172,14 +3184,14 @@
rv = NO_ERROR;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
if (device->state.conn < C_CONNECTED) {
unsigned int peer;
peer = be32_to_cpu(buffer->la_peer_max_bio_size);
peer = max(peer, DRBD_MAX_BIO_SIZE_SAFE);
device->peer_max_bio_size = peer;
}
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
err:
drbd_md_put_buffer(device);
@@ -3454,7 +3466,7 @@
void (*done)(struct drbd_device *, int),
char *why, enum bm_flag flags)
{
- D_ASSERT(current == device->connection->worker.task);
+ D_ASSERT(current == first_peer_device(device)->connection->worker.task);
D_ASSERT(!test_bit(BITMAP_IO_QUEUED, &device->flags));
D_ASSERT(!test_bit(BITMAP_IO, &device->flags));
@@ -3468,13 +3480,13 @@
device->bm_io_work.why = why;
device->bm_io_work.flags = flags;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
set_bit(BITMAP_IO, &device->flags);
if (atomic_read(&device->ap_bio_cnt) == 0) {
if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
- drbd_queue_work(&device->connection->sender_work, &device->bm_io_work.w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w);
}
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
}
/**
@@ -3491,7 +3503,7 @@
{
int rv;
- D_ASSERT(current != device->connection->worker.task);
+ D_ASSERT(current != first_peer_device(device)->connection->worker.task);
if ((flags & BM_LOCKED_SET_ALLOWED) == 0)
drbd_suspend_io(device);
@@ -3532,7 +3544,7 @@
/* must not double-queue! */
if (list_empty(&device->md_sync_work.list))
- drbd_queue_work_front(&device->connection->sender_work, &device->md_sync_work);
+ drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &device->md_sync_work);
}
static int w_md_sync(struct drbd_work *w, int unused)
@@ -3631,7 +3643,7 @@
long timeout;
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
if (!nc) {
rcu_read_unlock();
return -ETIMEDOUT;
@@ -3642,10 +3654,10 @@
/* Indicate to wake up device->misc_wait on progress. */
i->waiting = true;
prepare_to_wait(&device->misc_wait, &wait, TASK_INTERRUPTIBLE);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
timeout = schedule_timeout(timeout);
finish_wait(&device->misc_wait, &wait);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
if (!timeout || device->state.conn < C_CONNECTED)
return -ETIMEDOUT;
if (signal_pending(current))
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 1b5b7ea..a8c9c86 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -246,10 +246,10 @@
/* some more paranoia, if the request was over-determined */
if (adm_ctx.device && adm_ctx.connection &&
- adm_ctx.device->connection != adm_ctx.connection) {
+ first_peer_device(adm_ctx.device)->connection != adm_ctx.connection) {
pr_warning("request: minor=%u, resource=%s; but that minor belongs to connection %s\n",
adm_ctx.minor, adm_ctx.resource_name,
- adm_ctx.device->connection->name);
+ first_peer_device(adm_ctx.device)->connection->name);
drbd_msg_put_info("minor exists in different resource");
return ERR_INVALID_REQUEST;
}
@@ -258,7 +258,7 @@
adm_ctx.volume != adm_ctx.device->vnr) {
pr_warning("request: minor=%u, volume=%u; but that minor is volume %u in %s\n",
adm_ctx.minor, adm_ctx.volume,
- adm_ctx.device->vnr, adm_ctx.device->connection->name);
+ adm_ctx.device->vnr, first_peer_device(adm_ctx.device)->connection->name);
drbd_msg_put_info("minor exists as different volume");
return ERR_INVALID_REQUEST;
}
@@ -323,7 +323,7 @@
NULL };
char mb[12];
char *argv[] = {usermode_helper, cmd, mb, NULL };
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
struct sib_info sib;
int ret;
@@ -544,7 +544,7 @@
union drbd_state mask, val;
if (new_role == R_PRIMARY)
- request_ping(device->connection); /* Detect a dead peer ASAP */
+ request_ping(first_peer_device(device)->connection); /* Detect a dead peer ASAP */
mutex_lock(device->state_mutex);
@@ -575,7 +575,7 @@
device->state.disk == D_CONSISTENT && mask.pdsk == 0) {
D_ASSERT(device->state.pdsk == D_UNKNOWN);
- if (conn_try_outdate_peer(device->connection)) {
+ if (conn_try_outdate_peer(first_peer_device(device)->connection)) {
val.disk = D_UP_TO_DATE;
mask.disk = D_MASK;
}
@@ -585,7 +585,7 @@
if (rv == SS_NOTHING_TO_DO)
goto out;
if (rv == SS_PRIMARY_NOP && mask.pdsk == 0) {
- if (!conn_try_outdate_peer(device->connection) && force) {
+ if (!conn_try_outdate_peer(first_peer_device(device)->connection) && force) {
dev_warn(DEV, "Forced into split brain situation!\n");
mask.pdsk = D_MASK;
val.pdsk = D_OUTDATED;
@@ -598,7 +598,7 @@
retry at most once more in this case. */
int timeo;
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
timeo = nc ? (nc->ping_timeo + 1) * HZ / 10 : 1;
rcu_read_unlock();
schedule_timeout_interruptible(timeo);
@@ -633,11 +633,11 @@
put_ldev(device);
}
} else {
- mutex_lock(&device->connection->conf_update);
- nc = device->connection->net_conf;
+ mutex_lock(&first_peer_device(device)->connection->conf_update);
+ nc = first_peer_device(device)->connection->net_conf;
if (nc)
nc->discard_my_data = 0; /* without copy; single bit op is atomic */
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
set_disk_ro(device->vdisk, false);
if (get_ldev(device)) {
@@ -1134,12 +1134,12 @@
Because new from 8.3.8 onwards the peer can use multiple
BIOs for a single peer_request */
if (device->state.conn >= C_WF_REPORT_PARAMS) {
- if (device->connection->agreed_pro_version < 94)
+ if (first_peer_device(device)->connection->agreed_pro_version < 94)
peer = min(device->peer_max_bio_size, DRBD_MAX_SIZE_H80_PACKET);
/* Correct old drbd (up to 8.3.7) if it believes it can do more than 32KiB */
- else if (device->connection->agreed_pro_version == 94)
+ else if (first_peer_device(device)->connection->agreed_pro_version == 94)
peer = DRBD_MAX_SIZE_H80_PACKET;
- else if (device->connection->agreed_pro_version < 100)
+ else if (first_peer_device(device)->connection->agreed_pro_version < 100)
peer = DRBD_MAX_BIO_SIZE_P95; /* drbd 8.3.8 onwards, before 8.4.0 */
else
peer = DRBD_MAX_BIO_SIZE;
@@ -1190,10 +1190,10 @@
}
drbd_al_shrink(device);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
if (device->state.conn < C_CONNECTED)
s = !test_and_set_bit(AL_SUSPENDED, &device->flags);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
lc_unlock(device->act_log);
if (s)
@@ -1264,7 +1264,7 @@
goto fail;
}
- mutex_lock(&device->connection->conf_update);
+ mutex_lock(&first_peer_device(device)->connection->conf_update);
old_disk_conf = device->ldev->disk_conf;
*new_disk_conf = *old_disk_conf;
if (should_set_defaults(info))
@@ -1327,7 +1327,7 @@
rcu_assign_pointer(device->rs_plan_s, new_plan);
}
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
if (new_disk_conf->al_updates)
device->ldev->md.flags &= ~MDF_AL_DISABLED;
@@ -1339,7 +1339,7 @@
else
set_bit(MD_NO_FUA, &device->flags);
- drbd_bump_write_ordering(device->connection, WO_bdev_flush);
+ drbd_bump_write_ordering(first_peer_device(device)->connection, WO_bdev_flush);
drbd_md_sync(device);
@@ -1353,7 +1353,7 @@
goto success;
fail_unlock:
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
fail:
kfree(new_disk_conf);
kfree(new_plan);
@@ -1388,7 +1388,7 @@
goto finish;
device = adm_ctx.device;
- conn_reconfig_start(device->connection);
+ conn_reconfig_start(first_peer_device(device)->connection);
/* if you want to reconfigure, please tear down first */
if (device->state.disk > D_DISKLESS) {
@@ -1455,7 +1455,7 @@
goto fail;
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
if (nc) {
if (new_disk_conf->fencing == FP_STONITH && nc->wire_protocol == DRBD_PROT_A) {
rcu_read_unlock();
@@ -1636,7 +1636,7 @@
new_disk_conf = NULL;
new_plan = NULL;
- drbd_bump_write_ordering(device->connection, WO_bdev_flush);
+ drbd_bump_write_ordering(first_peer_device(device)->connection, WO_bdev_flush);
if (drbd_md_test_flag(device->ldev, MDF_CRASHED_PRIMARY))
set_bit(CRASHED_PRIMARY, &device->flags);
@@ -1644,7 +1644,8 @@
clear_bit(CRASHED_PRIMARY, &device->flags);
if (drbd_md_test_flag(device->ldev, MDF_PRIMARY_IND) &&
- !(device->state.role == R_PRIMARY && device->connection->susp_nod))
+ !(device->state.role == R_PRIMARY &&
+ first_peer_device(device)->connection->susp_nod))
set_bit(CRASHED_PRIMARY, &device->flags);
device->send_cnt = 0;
@@ -1702,7 +1703,7 @@
if (_drbd_bm_total_weight(device) == drbd_bm_bits(device))
drbd_suspend_al(device); /* IO is still suspended here... */
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
os = drbd_read_state(device);
ns = os;
/* If MDF_CONSISTENT is not set go into inconsistent state,
@@ -1754,7 +1755,7 @@
}
rv = _drbd_set_state(device, ns, CS_VERBOSE, NULL);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (rv < SS_SUCCESS)
goto force_diskless_dec;
@@ -1771,7 +1772,7 @@
kobject_uevent(&disk_to_dev(device->vdisk)->kobj, KOBJ_CHANGE);
put_ldev(device);
- conn_reconfig_done(device->connection);
+ conn_reconfig_done(first_peer_device(device)->connection);
drbd_adm_finish(info, retcode);
return 0;
@@ -1781,7 +1782,7 @@
drbd_force_state(device, NS(disk, D_DISKLESS));
drbd_md_sync(device);
fail:
- conn_reconfig_done(device->connection);
+ conn_reconfig_done(first_peer_device(device)->connection);
if (nbc) {
if (nbc->backing_bdev)
blkdev_put(nbc->backing_bdev,
@@ -2357,7 +2358,7 @@
if (device->state.role != device->state.peer)
iass = (device->state.role == R_PRIMARY);
else
- iass = test_bit(RESOLVE_CONFLICTS, &device->connection->flags);
+ iass = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags);
if (iass)
drbd_start_resync(device, C_SYNC_SOURCE);
@@ -2412,7 +2413,7 @@
goto fail_ldev;
}
- if (rs.no_resync && device->connection->agreed_pro_version < 93) {
+ if (rs.no_resync && first_peer_device(device)->connection->agreed_pro_version < 93) {
retcode = ERR_NEED_APV_93;
goto fail_ldev;
}
@@ -2454,12 +2455,12 @@
device->ldev->known_size = drbd_get_capacity(device->ldev->backing_bdev);
if (new_disk_conf) {
- mutex_lock(&device->connection->conf_update);
+ mutex_lock(&first_peer_device(device)->connection->conf_update);
old_disk_conf = device->ldev->disk_conf;
*new_disk_conf = *old_disk_conf;
new_disk_conf->disk_size = (sector_t)rs.resize_size;
rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
synchronize_rcu();
kfree(old_disk_conf);
}
@@ -2710,9 +2711,9 @@
retcode = drbd_request_state(device, NS3(susp, 0, susp_nod, 0, susp_fen, 0));
if (retcode == SS_SUCCESS) {
if (device->state.conn < C_CONNECTED)
- tl_clear(device->connection);
+ tl_clear(first_peer_device(device)->connection);
if (device->state.disk == D_DISKLESS || device->state.disk == D_FAILED)
- tl_restart(device->connection, FAIL_FROZEN_DISK_IO);
+ tl_restart(first_peer_device(device)->connection, FAIL_FROZEN_DISK_IO);
}
drbd_resume_io(device);
@@ -2778,10 +2779,10 @@
/* We need to add connection name and volume number information still.
* Minor number is in drbd_genlmsghdr. */
- if (nla_put_drbd_cfg_context(skb, device->connection, device->vnr))
+ if (nla_put_drbd_cfg_context(skb, first_peer_device(device)->connection, device->vnr))
goto nla_put_failure;
- if (res_opts_to_skb(skb, &device->connection->res_opts, exclude_sensitive))
+ if (res_opts_to_skb(skb, &first_peer_device(device)->connection->res_opts, exclude_sensitive))
goto nla_put_failure;
rcu_read_lock();
@@ -2794,7 +2795,7 @@
if (!err) {
struct net_conf *nc;
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
if (nc)
err = net_conf_to_skb(skb, nc, exclude_sensitive);
}
@@ -2981,7 +2982,7 @@
}
D_ASSERT(device->vnr == volume);
- D_ASSERT(device->connection == connection);
+ D_ASSERT(first_peer_device(device)->connection == connection);
dh->minor = device_to_minor(device);
dh->ret_code = NO_ERROR;
@@ -3168,7 +3169,8 @@
}
/* this is "skip initial sync", assume to be clean */
- if (device->state.conn == C_CONNECTED && device->connection->agreed_pro_version >= 90 &&
+ if (device->state.conn == C_CONNECTED &&
+ first_peer_device(device)->connection->agreed_pro_version >= 90 &&
device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED && args.clear_bm) {
dev_info(DEV, "Preparing to skip initial sync\n");
skip_initial_sync = 1;
@@ -3191,10 +3193,10 @@
drbd_send_uuids_skip_initial_sync(device);
_drbd_uuid_set(device, UI_BITMAP, 0);
drbd_print_uuids(device, "cleared bitmap UUID");
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
_drbd_set_state(_NS2(device, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
CS_VERBOSE, NULL);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
}
}
@@ -3287,7 +3289,7 @@
}
/* drbd_adm_prepare made sure already
- * that device->connection and device->vnr match the request. */
+ * that first_peer_device(device)->connection and device->vnr match the request. */
if (adm_ctx.device) {
if (info->nlhdr->nlmsg_flags & NLM_F_EXCL)
retcode = ERR_MINOR_EXISTS;
@@ -3295,7 +3297,7 @@
goto out;
}
- retcode = conn_new_minor(adm_ctx.connection, dh->minor, adm_ctx.volume);
+ retcode = drbd_create_minor(adm_ctx.connection, dh->minor, adm_ctx.volume);
out:
drbd_adm_finish(info, retcode);
return 0;
@@ -3310,7 +3312,7 @@
device->state.role == R_SECONDARY) {
_drbd_request_state(device, NS(conn, C_WF_REPORT_PARAMS),
CS_VERBOSE + CS_WAIT_COMPLETE);
- idr_remove(&device->connection->volumes, device->vnr);
+ idr_remove(&first_peer_device(device)->connection->volumes, device->vnr);
idr_remove(&minors, device_to_minor(device));
destroy_workqueue(device->submit.wq);
del_gendisk(device->vdisk);
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c
index 9c4d413..f1c81c1 100644
--- a/drivers/block/drbd/drbd_proc.c
+++ b/drivers/block/drbd/drbd_proc.c
@@ -251,7 +251,7 @@
/* reset device->congestion_reason */
bdi_rw_congested(&device->rq_queue->backing_dev_info);
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
seq_printf(seq,
"%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
@@ -280,8 +280,8 @@
atomic_read(&device->rs_pending_cnt),
atomic_read(&device->unacked_cnt),
atomic_read(&device->ap_bio_cnt),
- device->connection->epochs,
- write_ordering_chars[device->connection->write_ordering]
+ first_peer_device(device)->connection->epochs,
+ write_ordering_chars[first_peer_device(device)->connection->write_ordering]
);
seq_printf(seq, " oos:%llu\n",
Bit2KB((unsigned long long)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 42dbf5d..e08e99f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -221,9 +221,9 @@
LIST_HEAD(reclaimed);
struct drbd_peer_request *peer_req, *t;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
reclaim_finished_net_peer_reqs(device, &reclaimed);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
drbd_free_net_peer_req(device, peer_req);
@@ -252,7 +252,7 @@
/* Yes, we may run up to @number over max_buffers. If we
* follow it strictly, the admin will get it wrong anyways. */
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
mxb = nc ? nc->max_buffers : 1000000;
rcu_read_unlock();
@@ -288,7 +288,7 @@
}
/* Must not be used from irq, as that may deadlock: see drbd_alloc_pages.
- * Is also used from inside an other spin_lock_irq(&device->connection->req_lock);
+ * Is also used from inside an other spin_lock_irq(&first_peer_device(device)->connection->req_lock);
* Either links the page chain back to the global pool,
* or returns all pages to the system. */
static void drbd_free_pages(struct drbd_device *device, struct page *page, int is_net)
@@ -396,9 +396,9 @@
int count = 0;
int is_net = list == &device->net_ee;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_splice_init(list, &work_list);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
__drbd_free_peer_req(device, peer_req, is_net);
@@ -417,10 +417,10 @@
struct drbd_peer_request *peer_req, *t;
int err = 0;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
reclaim_finished_net_peer_reqs(device, &reclaimed);
list_splice_init(&device->done_ee, &work_list);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
drbd_free_net_peer_req(device, peer_req);
@@ -452,19 +452,19 @@
* and calling prepare_to_wait in the fast path */
while (!list_empty(head)) {
prepare_to_wait(&device->ee_wait, &wait, TASK_UNINTERRUPTIBLE);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
io_schedule();
finish_wait(&device->ee_wait, &wait);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
}
}
static void drbd_wait_ee_list_empty(struct drbd_device *device,
struct list_head *head)
{
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
_drbd_wait_ee_list_empty(device, head);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
}
static int drbd_recv_short(struct socket *sock, void *buf, size_t size, int flags)
@@ -838,8 +838,8 @@
atomic_set(&device->packet_seq, 0);
device->peer_seq = 0;
- device->state_mutex = device->connection->agreed_pro_version < 100 ?
- &device->connection->cstate_mutex :
+ device->state_mutex = first_peer_device(device)->connection->agreed_pro_version < 100 ?
+ &first_peer_device(device)->connection->cstate_mutex :
&device->own_state_mutex;
err = drbd_send_sync_param(device);
@@ -1492,18 +1492,18 @@
struct drbd_peer_request *peer_req;
struct page *page;
int dgs, ds, err;
- void *dig_in = device->connection->int_dig_in;
- void *dig_vv = device->connection->int_dig_vv;
+ void *dig_in = first_peer_device(device)->connection->int_dig_in;
+ void *dig_vv = first_peer_device(device)->connection->int_dig_vv;
unsigned long *data;
dgs = 0;
- if (device->connection->peer_integrity_tfm) {
- dgs = crypto_hash_digestsize(device->connection->peer_integrity_tfm);
+ if (first_peer_device(device)->connection->peer_integrity_tfm) {
+ dgs = crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
/*
* FIXME: Receive the incoming digest into the receive buffer
* here, together with its struct p_data?
*/
- err = drbd_recv_all_warn(device->connection, dig_in, dgs);
+ err = drbd_recv_all_warn(first_peer_device(device)->connection, dig_in, dgs);
if (err)
return NULL;
data_size -= dgs;
@@ -1539,7 +1539,7 @@
page_chain_for_each(page) {
unsigned len = min_t(int, ds, PAGE_SIZE);
data = kmap(page);
- err = drbd_recv_all_warn(device->connection, data, len);
+ err = drbd_recv_all_warn(first_peer_device(device)->connection, data, len);
if (drbd_insert_fault(device, DRBD_FAULT_RECEIVE)) {
dev_err(DEV, "Fault injection: Corrupting data on receive\n");
data[0] = data[0] ^ (unsigned long)-1;
@@ -1553,7 +1553,7 @@
}
if (dgs) {
- drbd_csum_ee(device, device->connection->peer_integrity_tfm, peer_req, dig_vv);
+ drbd_csum_ee(device, first_peer_device(device)->connection->peer_integrity_tfm, peer_req, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
dev_err(DEV, "Digest integrity check FAILED: %llus +%u\n",
(unsigned long long)sector, data_size);
@@ -1583,7 +1583,7 @@
while (data_size) {
unsigned int len = min_t(int, data_size, PAGE_SIZE);
- err = drbd_recv_all_warn(device->connection, data, len);
+ err = drbd_recv_all_warn(first_peer_device(device)->connection, data, len);
if (err)
break;
data_size -= len;
@@ -1600,13 +1600,13 @@
struct bvec_iter iter;
struct bio *bio;
int dgs, err, expect;
- void *dig_in = device->connection->int_dig_in;
- void *dig_vv = device->connection->int_dig_vv;
+ void *dig_in = first_peer_device(device)->connection->int_dig_in;
+ void *dig_vv = first_peer_device(device)->connection->int_dig_vv;
dgs = 0;
- if (device->connection->peer_integrity_tfm) {
- dgs = crypto_hash_digestsize(device->connection->peer_integrity_tfm);
- err = drbd_recv_all_warn(device->connection, dig_in, dgs);
+ if (first_peer_device(device)->connection->peer_integrity_tfm) {
+ dgs = crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
+ err = drbd_recv_all_warn(first_peer_device(device)->connection, dig_in, dgs);
if (err)
return err;
data_size -= dgs;
@@ -1622,7 +1622,7 @@
bio_for_each_segment(bvec, bio, iter) {
void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
expect = min_t(int, data_size, bvec.bv_len);
- err = drbd_recv_all_warn(device->connection, mapped, expect);
+ err = drbd_recv_all_warn(first_peer_device(device)->connection, mapped, expect);
kunmap(bvec.bv_page);
if (err)
return err;
@@ -1630,7 +1630,7 @@
}
if (dgs) {
- drbd_csum_bio(device, device->connection->peer_integrity_tfm, bio, dig_vv);
+ drbd_csum_bio(device, first_peer_device(device)->connection->peer_integrity_tfm, bio, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
dev_err(DEV, "Digest integrity check FAILED. Broken NICs?\n");
return -EINVAL;
@@ -1685,9 +1685,9 @@
peer_req->w.cb = e_end_resync_block;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_add(&peer_req->w.list, &device->sync_ee);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
atomic_add(data_size >> 9, &device->rs_sect_ev);
if (drbd_submit_peer_request(device, peer_req, WRITE, DRBD_FAULT_RS_WR) == 0)
@@ -1695,9 +1695,9 @@
/* don't care for the reason here */
dev_err(DEV, "submit failed, triggering re-connect\n");
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_del(&peer_req->w.list);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
drbd_free_peer_req(device, peer_req);
fail:
@@ -1736,9 +1736,9 @@
sector = be64_to_cpu(p->sector);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
req = find_request(device, &device->read_requests, p->block_id, sector, false, __func__);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (unlikely(!req))
return -EIO;
@@ -1837,16 +1837,16 @@
/* we delete from the conflict detection hash _after_ we sent out the
* P_WRITE_ACK / P_NEG_ACK, to get the sequence number right. */
if (peer_req->flags & EE_IN_INTERVAL_TREE) {
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
D_ASSERT(!drbd_interval_empty(&peer_req->i));
drbd_remove_epoch_entry_interval(device, peer_req);
if (peer_req->flags & EE_RESTART_REQUESTS)
restart_conflicting_writes(device, sector, peer_req->i.size);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
} else
D_ASSERT(drbd_interval_empty(&peer_req->i));
- drbd_may_finish_epoch(device->connection, peer_req->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
+ drbd_may_finish_epoch(first_peer_device(device)->connection, peer_req->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
return err;
}
@@ -1871,7 +1871,7 @@
static int e_send_retry_write(struct drbd_work *w, int unused)
{
- struct drbd_connection *connection = w->device->connection;
+ struct drbd_connection *connection = first_peer_device(w->device)->connection;
return e_send_ack(w, connection->agreed_pro_version >= 100 ?
P_RETRY_WRITE : P_SUPERSEDED);
@@ -1896,7 +1896,7 @@
{
unsigned int newest_peer_seq;
- if (test_bit(RESOLVE_CONFLICTS, &device->connection->flags)) {
+ if (test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)) {
spin_lock(&device->peer_seq_lock);
newest_peer_seq = seq_max(device->peer_seq, peer_seq);
device->peer_seq = newest_peer_seq;
@@ -1918,7 +1918,7 @@
struct drbd_peer_request *rs_req;
bool rv = 0;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_for_each_entry(rs_req, &device->sync_ee, w.list) {
if (overlaps(peer_req->i.sector, peer_req->i.size,
rs_req->i.sector, rs_req->i.size)) {
@@ -1926,7 +1926,7 @@
break;
}
}
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
return rv;
}
@@ -1958,7 +1958,7 @@
long timeout;
int ret = 0, tp;
- if (!test_bit(RESOLVE_CONFLICTS, &device->connection->flags))
+ if (!test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags))
return 0;
spin_lock(&device->peer_seq_lock);
@@ -1974,7 +1974,7 @@
}
rcu_read_lock();
- tp = rcu_dereference(device->connection->net_conf)->two_primaries;
+ tp = rcu_dereference(first_peer_device(device)->connection->net_conf)->two_primaries;
rcu_read_unlock();
if (!tp)
@@ -1984,7 +1984,7 @@
prepare_to_wait(&device->seq_wait, &wait, TASK_INTERRUPTIBLE);
spin_unlock(&device->peer_seq_lock);
rcu_read_lock();
- timeout = rcu_dereference(device->connection->net_conf)->ping_timeo*HZ/10;
+ timeout = rcu_dereference(first_peer_device(device)->connection->net_conf)->ping_timeo*HZ/10;
rcu_read_unlock();
timeout = schedule_timeout(timeout);
spin_lock(&device->peer_seq_lock);
@@ -2027,10 +2027,10 @@
continue;
req->rq_state &= ~RQ_POSTPONED;
__req_mod(req, NEG_ACKED, &m);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (m.bio)
complete_master_bio(device, &m);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
goto repeat;
}
}
@@ -2038,7 +2038,7 @@
static int handle_write_conflicts(struct drbd_device *device,
struct drbd_peer_request *peer_req)
{
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
bool resolve_conflicts = test_bit(RESOLVE_CONFLICTS, &connection->flags);
sector_t sector = peer_req->i.sector;
const unsigned int size = peer_req->i.size;
@@ -2092,7 +2092,7 @@
peer_req->w.cb = superseded ? e_send_superseded :
e_send_retry_write;
list_add_tail(&peer_req->w.list, &device->done_ee);
- wake_asender(device->connection);
+ wake_asender(first_peer_device(device)->connection);
err = -ENOENT;
goto out;
@@ -2121,7 +2121,7 @@
*/
err = drbd_wait_misc(device, &req->i);
if (err) {
- _conn_request_state(device->connection,
+ _conn_request_state(first_peer_device(device)->connection,
NS(conn, C_TIMEOUT),
CS_HARD);
fail_postponed_requests(device, sector, size);
@@ -2204,17 +2204,17 @@
spin_unlock(&connection->epoch_lock);
rcu_read_lock();
- tp = rcu_dereference(device->connection->net_conf)->two_primaries;
+ tp = rcu_dereference(first_peer_device(device)->connection->net_conf)->two_primaries;
rcu_read_unlock();
if (tp) {
peer_req->flags |= EE_IN_INTERVAL_TREE;
err = wait_for_and_update_peer_seq(device, peer_seq);
if (err)
goto out_interrupted;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
err = handle_write_conflicts(device, peer_req);
if (err) {
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (err == -ENOENT) {
put_ldev(device);
return 0;
@@ -2223,17 +2223,17 @@
}
} else {
update_peer_seq(device, peer_seq);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
}
list_add(&peer_req->w.list, &device->active_ee);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (device->state.conn == C_SYNC_TARGET)
wait_event(device->ee_wait, !overlapping_resync_write(device, peer_req));
- if (device->connection->agreed_pro_version < 100) {
+ if (first_peer_device(device)->connection->agreed_pro_version < 100) {
rcu_read_lock();
- switch (rcu_dereference(device->connection->net_conf)->wire_protocol) {
+ switch (rcu_dereference(first_peer_device(device)->connection->net_conf)->wire_protocol) {
case DRBD_PROT_C:
dp_flags |= DP_SEND_WRITE_ACK;
break;
@@ -2271,10 +2271,10 @@
/* don't care for the reason here */
dev_err(DEV, "submit failed, triggering re-connect\n");
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_del(&peer_req->w.list);
drbd_remove_epoch_entry_interval(device, peer_req);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (peer_req->flags & EE_CALL_AL_COMPLETE_IO)
drbd_al_complete_io(device, &peer_req->i);
@@ -2450,11 +2450,11 @@
peer_req->digest = di;
peer_req->flags |= EE_HAS_DIGEST;
- if (drbd_recv_all(device->connection, di->digest, pi->size))
+ if (drbd_recv_all(first_peer_device(device)->connection, di->digest, pi->size))
goto out_free_e;
if (pi->cmd == P_CSUM_RS_REQUEST) {
- D_ASSERT(device->connection->agreed_pro_version >= 89);
+ D_ASSERT(first_peer_device(device)->connection->agreed_pro_version >= 89);
peer_req->w.cb = w_e_end_csum_rs_req;
/* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector);
@@ -2471,7 +2471,7 @@
case P_OV_REQUEST:
if (device->ov_start_sector == ~(sector_t)0 &&
- device->connection->agreed_pro_version >= 90) {
+ first_peer_device(device)->connection->agreed_pro_version >= 90) {
unsigned long now = jiffies;
int i;
device->ov_start_sector = sector;
@@ -2525,18 +2525,18 @@
submit:
inc_unacked(device);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_add_tail(&peer_req->w.list, &device->read_ee);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (drbd_submit_peer_request(device, peer_req, READ, fault_type) == 0)
return 0;
/* don't care for the reason here */
dev_err(DEV, "submit failed, triggering re-connect\n");
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_del(&peer_req->w.list);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
/* no drbd_rs_complete_io(), we are dropping the connection anyways */
out_free_e:
@@ -2558,7 +2558,7 @@
ch_self = device->comm_bm_set;
rcu_read_lock();
- after_sb_0p = rcu_dereference(device->connection->net_conf)->after_sb_0p;
+ after_sb_0p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_0p;
rcu_read_unlock();
switch (after_sb_0p) {
case ASB_CONSENSUS:
@@ -2593,7 +2593,7 @@
"Using discard-least-changes instead\n");
case ASB_DISCARD_ZERO_CHG:
if (ch_peer == 0 && ch_self == 0) {
- rv = test_bit(RESOLVE_CONFLICTS, &device->connection->flags)
+ rv = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)
? -1 : 1;
break;
} else {
@@ -2609,7 +2609,7 @@
rv = 1;
else /* ( ch_self == ch_peer ) */
/* Well, then use something else. */
- rv = test_bit(RESOLVE_CONFLICTS, &device->connection->flags)
+ rv = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)
? -1 : 1;
break;
case ASB_DISCARD_LOCAL:
@@ -2628,7 +2628,7 @@
enum drbd_after_sb_p after_sb_1p;
rcu_read_lock();
- after_sb_1p = rcu_dereference(device->connection->net_conf)->after_sb_1p;
+ after_sb_1p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_1p;
rcu_read_unlock();
switch (after_sb_1p) {
case ASB_DISCARD_YOUNGER_PRI:
@@ -2681,7 +2681,7 @@
enum drbd_after_sb_p after_sb_2p;
rcu_read_lock();
- after_sb_2p = rcu_dereference(device->connection->net_conf)->after_sb_2p;
+ after_sb_2p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_2p;
rcu_read_unlock();
switch (after_sb_2p) {
case ASB_DISCARD_YOUNGER_PRI:
@@ -2777,7 +2777,7 @@
if (device->p_uuid[UI_BITMAP] == (u64)0 && device->ldev->md.uuid[UI_BITMAP] != (u64)0) {
- if (device->connection->agreed_pro_version < 91)
+ if (first_peer_device(device)->connection->agreed_pro_version < 91)
return -1091;
if ((device->ldev->md.uuid[UI_BITMAP] & ~((u64)1)) == (device->p_uuid[UI_HISTORY_START] & ~((u64)1)) &&
@@ -2800,7 +2800,7 @@
if (device->ldev->md.uuid[UI_BITMAP] == (u64)0 && device->p_uuid[UI_BITMAP] != (u64)0) {
- if (device->connection->agreed_pro_version < 91)
+ if (first_peer_device(device)->connection->agreed_pro_version < 91)
return -1091;
if ((device->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (device->p_uuid[UI_BITMAP] & ~((u64)1)) &&
@@ -2833,7 +2833,7 @@
case 1: /* self_pri && !peer_pri */ return 1;
case 2: /* !self_pri && peer_pri */ return -1;
case 3: /* self_pri && peer_pri */
- dc = test_bit(RESOLVE_CONFLICTS, &device->connection->flags);
+ dc = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags);
return dc ? -1 : 1;
}
}
@@ -2846,14 +2846,14 @@
*rule_nr = 51;
peer = device->p_uuid[UI_HISTORY_START] & ~((u64)1);
if (self == peer) {
- if (device->connection->agreed_pro_version < 96 ?
+ if (first_peer_device(device)->connection->agreed_pro_version < 96 ?
(device->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) ==
(device->p_uuid[UI_HISTORY_START + 1] & ~((u64)1)) :
peer + UUID_NEW_BM_OFFSET == (device->p_uuid[UI_BITMAP] & ~((u64)1))) {
/* The last P_SYNC_UUID did not get though. Undo the last start of
resync as sync source modifications of the peer's UUIDs. */
- if (device->connection->agreed_pro_version < 91)
+ if (first_peer_device(device)->connection->agreed_pro_version < 91)
return -1091;
device->p_uuid[UI_BITMAP] = device->p_uuid[UI_HISTORY_START];
@@ -2883,14 +2883,14 @@
*rule_nr = 71;
self = device->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1);
if (self == peer) {
- if (device->connection->agreed_pro_version < 96 ?
+ if (first_peer_device(device)->connection->agreed_pro_version < 96 ?
(device->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1)) ==
(device->p_uuid[UI_HISTORY_START] & ~((u64)1)) :
self + UUID_NEW_BM_OFFSET == (device->ldev->md.uuid[UI_BITMAP] & ~((u64)1))) {
/* The last P_SYNC_UUID did not get though. Undo the last start of
resync as sync source modifications of our UUIDs. */
- if (device->connection->agreed_pro_version < 91)
+ if (first_peer_device(device)->connection->agreed_pro_version < 91)
return -1091;
__drbd_uuid_set(device, UI_BITMAP, device->ldev->md.uuid[UI_HISTORY_START]);
@@ -2982,7 +2982,7 @@
drbd_khelper(device, "initial-split-brain");
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
if (hg == 100 || (hg == -100 && nc->always_asbp)) {
int pcount = (device->state.role == R_PRIMARY)
@@ -3057,7 +3057,7 @@
}
}
- if (tentative || test_bit(CONN_DRY_RUN, &device->connection->flags)) {
+ if (tentative || test_bit(CONN_DRY_RUN, &first_peer_device(device)->connection->flags)) {
if (hg == 0)
dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n");
else
@@ -3361,17 +3361,17 @@
p = pi->data;
memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
- err = drbd_recv_all(device->connection, p, header_size);
+ err = drbd_recv_all(first_peer_device(device)->connection, p, header_size);
if (err)
return err;
- mutex_lock(&device->connection->conf_update);
- old_net_conf = device->connection->net_conf;
+ mutex_lock(&first_peer_device(device)->connection->conf_update);
+ old_net_conf = first_peer_device(device)->connection->net_conf;
if (get_ldev(device)) {
new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
if (!new_disk_conf) {
put_ldev(device);
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
dev_err(DEV, "Allocation of new disk_conf failed\n");
return -ENOMEM;
}
@@ -3392,7 +3392,7 @@
goto reconnect;
}
- err = drbd_recv_all(device->connection, p->verify_alg, data_size);
+ err = drbd_recv_all(first_peer_device(device)->connection, p->verify_alg, data_size);
if (err)
goto reconnect;
/* we expect NUL terminated string */
@@ -3466,15 +3466,15 @@
if (verify_tfm) {
strcpy(new_net_conf->verify_alg, p->verify_alg);
new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1;
- crypto_free_hash(device->connection->verify_tfm);
- device->connection->verify_tfm = verify_tfm;
+ crypto_free_hash(first_peer_device(device)->connection->verify_tfm);
+ first_peer_device(device)->connection->verify_tfm = verify_tfm;
dev_info(DEV, "using verify-alg: \"%s\"\n", p->verify_alg);
}
if (csums_tfm) {
strcpy(new_net_conf->csums_alg, p->csums_alg);
new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1;
- crypto_free_hash(device->connection->csums_tfm);
- device->connection->csums_tfm = csums_tfm;
+ crypto_free_hash(first_peer_device(device)->connection->csums_tfm);
+ first_peer_device(device)->connection->csums_tfm = csums_tfm;
dev_info(DEV, "using csums-alg: \"%s\"\n", p->csums_alg);
}
rcu_assign_pointer(connection->net_conf, new_net_conf);
@@ -3491,7 +3491,7 @@
rcu_assign_pointer(device->rs_plan_s, new_plan);
}
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
synchronize_rcu();
if (new_net_conf)
kfree(old_net_conf);
@@ -3505,7 +3505,7 @@
put_ldev(device);
kfree(new_disk_conf);
}
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
return -EIO;
disconnect:
@@ -3514,13 +3514,13 @@
put_ldev(device);
kfree(new_disk_conf);
}
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
/* just for completeness: actually not needed,
* as this is not reached if csums_tfm was ok. */
crypto_free_hash(csums_tfm);
/* but free the verify_tfm again, if csums_tfm did not work out */
crypto_free_hash(verify_tfm);
- conn_request_state(device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
@@ -3579,7 +3579,7 @@
device->state.disk >= D_OUTDATED &&
device->state.conn < C_CONNECTED) {
dev_err(DEV, "The peer's disk size is too small!\n");
- conn_request_state(device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
put_ldev(device);
return -EIO;
}
@@ -3594,13 +3594,13 @@
return -ENOMEM;
}
- mutex_lock(&device->connection->conf_update);
+ mutex_lock(&first_peer_device(device)->connection->conf_update);
old_disk_conf = device->ldev->disk_conf;
*new_disk_conf = *old_disk_conf;
new_disk_conf->disk_size = p_usize;
rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
- mutex_unlock(&device->connection->conf_update);
+ mutex_unlock(&first_peer_device(device)->connection->conf_update);
synchronize_rcu();
kfree(old_disk_conf);
@@ -3687,14 +3687,14 @@
(device->ed_uuid & ~((u64)1)) != (p_uuid[UI_CURRENT] & ~((u64)1))) {
dev_err(DEV, "Can only connect to data with current UUID=%016llX\n",
(unsigned long long)device->ed_uuid);
- conn_request_state(device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
if (get_ldev(device)) {
int skip_initial_sync =
device->state.conn == C_CONNECTED &&
- device->connection->agreed_pro_version >= 90 &&
+ first_peer_device(device)->connection->agreed_pro_version >= 90 &&
device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
(p_uuid[UI_FLAGS] & 8);
if (skip_initial_sync) {
@@ -3777,7 +3777,7 @@
mask.i = be32_to_cpu(p->mask);
val.i = be32_to_cpu(p->val);
- if (test_bit(RESOLVE_CONFLICTS, &device->connection->flags) &&
+ if (test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags) &&
mutex_is_locked(device->state_mutex)) {
drbd_send_sr_reply(device, SS_CONCURRENT_ST_CHG);
return 0;
@@ -3839,10 +3839,10 @@
dev_info(DEV, "real peer disk state = %s\n", drbd_disk_str(real_peer_disk));
}
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
retry:
os = ns = drbd_read_state(device);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
/* If some other part of the code (asender thread, timeout)
* already decided to close the connection again,
@@ -3936,16 +3936,16 @@
peer_state.disk = D_DISKLESS;
real_peer_disk = D_DISKLESS;
} else {
- if (test_and_clear_bit(CONN_DRY_RUN, &device->connection->flags))
+ if (test_and_clear_bit(CONN_DRY_RUN, &first_peer_device(device)->connection->flags))
return -EIO;
D_ASSERT(os.conn == C_WF_REPORT_PARAMS);
- conn_request_state(device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
}
}
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
if (os.i != drbd_read_state(device).i)
goto retry;
clear_bit(CONSIDER_RESYNC, &device->flags);
@@ -3959,20 +3959,20 @@
test_bit(NEW_CUR_UUID, &device->flags)) {
/* Do not allow tl_restart(RESEND) for a rebooted peer. We can only allow this
for temporal network outages! */
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
dev_err(DEV, "Aborting Connect, can not thaw IO with an only Consistent peer\n");
- tl_clear(device->connection);
+ tl_clear(first_peer_device(device)->connection);
drbd_uuid_new_current(device);
clear_bit(NEW_CUR_UUID, &device->flags);
- conn_request_state(device->connection, NS2(conn, C_PROTOCOL_ERROR, susp, 0), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS2(conn, C_PROTOCOL_ERROR, susp, 0), CS_HARD);
return -EIO;
}
rv = _drbd_set_state(device, ns, cs_flags, NULL);
ns = drbd_read_state(device);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (rv < SS_SUCCESS) {
- conn_request_state(device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
@@ -4038,7 +4038,7 @@
unsigned long *p, struct bm_xfer_ctx *c)
{
unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
- drbd_header_size(device->connection);
+ drbd_header_size(first_peer_device(device)->connection);
unsigned int num_words = min_t(size_t, data_size / sizeof(*p),
c->bm_words - c->word_offset);
unsigned int want = num_words * sizeof(*p);
@@ -4050,7 +4050,7 @@
}
if (want == 0)
return 0;
- err = drbd_recv_all(device->connection, p, want);
+ err = drbd_recv_all(first_peer_device(device)->connection, p, want);
if (err)
return err;
@@ -4168,7 +4168,7 @@
* during all our tests. */
dev_err(DEV, "receive_bitmap_c: unknown encoding %u\n", p->encoding);
- conn_request_state(device->connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
return -EIO;
}
@@ -4176,7 +4176,7 @@
const char *direction, struct bm_xfer_ctx *c)
{
/* what would it take to transfer it "plaintext" */
- unsigned int header_size = drbd_header_size(device->connection);
+ unsigned int header_size = drbd_header_size(first_peer_device(device)->connection);
unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
unsigned int plain =
header_size * (DIV_ROUND_UP(c->bm_words, data_size) + 1) +
@@ -4253,7 +4253,7 @@
err = -EIO;
goto out;
}
- err = drbd_recv_all(device->connection, p, pi->size);
+ err = drbd_recv_all(first_peer_device(device)->connection, p, pi->size);
if (err)
goto out;
err = decode_bitmap_c(device, p, &c, pi->size);
@@ -4271,7 +4271,7 @@
goto out;
break;
}
- err = drbd_recv_header(device->connection, pi);
+ err = drbd_recv_header(first_peer_device(device)->connection, pi);
if (err)
goto out;
}
@@ -4491,11 +4491,11 @@
unsigned int i;
/* wait for current activity to cease. */
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
_drbd_wait_ee_list_empty(device, &device->active_ee);
_drbd_wait_ee_list_empty(device, &device->sync_ee);
_drbd_wait_ee_list_empty(device, &device->read_ee);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
/* We do not have data structures that would allow us to
* get the rs_pending_cnt down to 0 again.
@@ -4536,7 +4536,7 @@
device->p_uuid = NULL;
if (!drbd_suspended(device))
- tl_clear(device->connection);
+ tl_clear(first_peer_device(device)->connection);
drbd_md_sync(device);
@@ -4937,7 +4937,7 @@
if (!device)
return -EIO;
- D_ASSERT(device->connection->agreed_pro_version >= 89);
+ D_ASSERT(first_peer_device(device)->connection->agreed_pro_version >= 89);
update_peer_seq(device, be32_to_cpu(p->seq_num));
@@ -4962,14 +4962,14 @@
struct drbd_request *req;
struct bio_and_error m;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
req = find_request(device, root, id, sector, missing_ok, func);
if (unlikely(!req)) {
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
return -EIO;
}
__req_mod(req, what, &m);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (m.bio)
complete_master_bio(device, &m);
@@ -5169,7 +5169,7 @@
if (w) {
w->cb = w_ov_finished;
w->device = device;
- drbd_queue_work(&device->connection->sender_work, w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, w);
} else {
dev_err(DEV, "kmalloc(w) failed.");
ov_out_of_sync_print(device);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index a33a35e..dd10334 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -274,8 +274,8 @@
* and reset the transfer log epoch write_cnt.
*/
if (rw == WRITE &&
- req->epoch == atomic_read(&device->connection->current_tle_nr))
- start_new_tl_epoch(device->connection);
+ req->epoch == atomic_read(&first_peer_device(device)->connection->current_tle_nr))
+ start_new_tl_epoch(first_peer_device(device)->connection);
/* Update disk stats */
_drbd_end_io_acct(device, req);
@@ -477,7 +477,7 @@
* and from w_read_retry_remote */
D_ASSERT(!(req->rq_state & RQ_NET_MASK));
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
p = nc->wire_protocol;
rcu_read_unlock();
req->rq_state |=
@@ -542,7 +542,7 @@
D_ASSERT((req->rq_state & RQ_LOCAL_MASK) == 0);
mod_rq_state(req, m, 0, RQ_NET_QUEUED);
req->w.cb = w_send_read_req;
- drbd_queue_work(&device->connection->sender_work, &req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w);
break;
case QUEUE_FOR_NET_WRITE:
@@ -577,22 +577,22 @@
D_ASSERT(req->rq_state & RQ_NET_PENDING);
mod_rq_state(req, m, 0, RQ_NET_QUEUED|RQ_EXP_BARR_ACK);
req->w.cb = w_send_dblock;
- drbd_queue_work(&device->connection->sender_work, &req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w);
/* close the epoch, in case it outgrew the limit */
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
p = nc->max_epoch_size;
rcu_read_unlock();
- if (device->connection->current_tle_writes >= p)
- start_new_tl_epoch(device->connection);
+ if (first_peer_device(device)->connection->current_tle_writes >= p)
+ start_new_tl_epoch(first_peer_device(device)->connection);
break;
case QUEUE_FOR_SEND_OOS:
mod_rq_state(req, m, 0, RQ_NET_QUEUED);
req->w.cb = w_send_out_of_sync;
- drbd_queue_work(&device->connection->sender_work, &req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w);
break;
case READ_RETRY_REMOTE_CANCELED:
@@ -704,7 +704,7 @@
get_ldev(device); /* always succeeds in this call path */
req->w.cb = w_restart_disk_io;
- drbd_queue_work(&device->connection->sender_work, &req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w);
break;
case RESEND:
@@ -725,7 +725,7 @@
mod_rq_state(req, m, RQ_COMPLETION_SUSP, RQ_NET_QUEUED|RQ_NET_PENDING);
if (req->w.cb) {
- drbd_queue_work(&device->connection->sender_work, &req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w);
rv = req->rq_state & RQ_WRITE ? MR_WRITE : MR_READ;
} /* else: FIXME can this happen? */
break;
@@ -757,7 +757,7 @@
break;
case QUEUE_AS_DRBD_BARRIER:
- start_new_tl_epoch(device->connection);
+ start_new_tl_epoch(first_peer_device(device)->connection);
mod_rq_state(req, m, 0, RQ_NET_OK|RQ_NET_DONE);
break;
};
@@ -851,9 +851,9 @@
break;
/* Indicate to wake up device->misc_wait on progress. */
i->waiting = true;
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
schedule();
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
}
finish_wait(&device->misc_wait, &wait);
}
@@ -861,7 +861,7 @@
/* called within req_lock and rcu_read_lock() */
static void maybe_pull_ahead(struct drbd_device *device)
{
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
struct net_conf *nc;
bool congested = false;
enum drbd_on_congestion on_congestion;
@@ -894,7 +894,7 @@
if (congested) {
/* start a new epoch for non-mirrored writes */
- start_new_tl_epoch(device->connection);
+ start_new_tl_epoch(first_peer_device(device)->connection);
if (on_congestion == OC_PULL_AHEAD)
_drbd_set_state(_NS(device, conn, C_AHEAD), 0, NULL);
@@ -1078,7 +1078,7 @@
struct bio_and_error m = { NULL, };
bool no_remote = false;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
if (rw == WRITE) {
/* This may temporarily give up the req_lock,
* but will re-aquire it before it returns here.
@@ -1112,15 +1112,15 @@
}
/* which transfer log epoch does this belong to? */
- req->epoch = atomic_read(&device->connection->current_tle_nr);
+ req->epoch = atomic_read(&first_peer_device(device)->connection->current_tle_nr);
/* no point in adding empty flushes to the transfer log,
* they are mapped to drbd barriers already. */
if (likely(req->i.size!=0)) {
if (rw == WRITE)
- device->connection->current_tle_writes++;
+ first_peer_device(device)->connection->current_tle_writes++;
- list_add_tail(&req->tl_requests, &device->connection->transfer_log);
+ list_add_tail(&req->tl_requests, &first_peer_device(device)->connection->transfer_log);
}
if (rw == WRITE) {
@@ -1140,9 +1140,9 @@
/* needs to be marked within the same spinlock */
_req_mod(req, TO_BE_SUBMITTED);
/* but we need to give up the spinlock to submit */
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
drbd_submit_req_private_bio(req);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
} else if (no_remote) {
nodata:
if (__ratelimit(&drbd_ratelimit_state))
@@ -1155,7 +1155,7 @@
out:
if (drbd_req_put_completion_ref(req, &m, 1))
kref_put(&req->kref, drbd_req_destroy);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
if (m.bio)
complete_master_bio(device, &m);
@@ -1336,7 +1336,7 @@
void request_timer_fn(unsigned long data)
{
struct drbd_device *device = (struct drbd_device *) data;
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
struct drbd_request *req; /* oldest request */
struct net_conf *nc;
unsigned long ent = 0, dt = 0, et, nt; /* effective timeout = ko_count * timeout */
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 407404b..27283e6 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -318,9 +318,9 @@
struct bio_and_error m;
int rv;
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
rv = __req_mod(req, what, &m);
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
if (m.bio)
complete_master_bio(device, &m);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index ecc63cf..22c4e7d 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -237,10 +237,10 @@
union drbd_state ns;
enum drbd_state_rv rv;
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
ns = apply_mask_val(drbd_read_state(device), mask, val);
rv = _drbd_set_state(device, ns, f, NULL);
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
return rv;
}
@@ -271,7 +271,7 @@
if (test_and_clear_bit(CL_ST_CHG_FAIL, &device->flags))
return SS_CW_FAILED_BY_PEER;
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
os = drbd_read_state(device);
ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL);
rv = is_valid_transition(os, ns);
@@ -283,12 +283,12 @@
if (rv == SS_UNKNOWN_ERROR) {
rv = is_valid_state(device, ns);
if (rv >= SS_SUCCESS) {
- rv = is_valid_soft_transition(os, ns, device->connection);
+ rv = is_valid_soft_transition(os, ns, first_peer_device(device)->connection);
if (rv >= SS_SUCCESS)
rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
}
}
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
return rv;
}
@@ -317,20 +317,20 @@
if (f & CS_SERIALIZE)
mutex_lock(device->state_mutex);
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
os = drbd_read_state(device);
ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL);
rv = is_valid_transition(os, ns);
if (rv < SS_SUCCESS) {
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
goto abort;
}
if (cl_wide_st_chg(device, os, ns)) {
rv = is_valid_state(device, ns);
if (rv == SS_SUCCESS)
- rv = is_valid_soft_transition(os, ns, device->connection);
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ rv = is_valid_soft_transition(os, ns, first_peer_device(device)->connection);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
if (rv < SS_SUCCESS) {
if (f & CS_VERBOSE)
@@ -353,17 +353,17 @@
print_st_err(device, os, ns, rv);
goto abort;
}
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
ns = apply_mask_val(drbd_read_state(device), mask, val);
rv = _drbd_set_state(device, ns, f, &done);
} else {
rv = _drbd_set_state(device, ns, f, &done);
}
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
if (f & CS_WAIT_COMPLETE && rv == SS_SUCCESS) {
- D_ASSERT(current != device->connection->worker.task);
+ D_ASSERT(current != first_peer_device(device)->connection->worker.task);
wait_for_completion(&done);
}
@@ -519,12 +519,12 @@
put_ldev(device);
}
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
if (nc) {
if (!nc->two_primaries && ns.role == R_PRIMARY) {
if (ns.peer == R_PRIMARY)
rv = SS_TWO_PRIMARIES;
- else if (conn_highest_peer(device->connection) == R_PRIMARY)
+ else if (conn_highest_peer(first_peer_device(device)->connection) == R_PRIMARY)
rv = SS_O_VOL_PEER_PRI;
}
}
@@ -565,7 +565,7 @@
rv = SS_NO_VERIFY_ALG;
else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
- device->connection->agreed_pro_version < 88)
+ first_peer_device(device)->connection->agreed_pro_version < 88)
rv = SS_NOT_SUPPORTED;
else if (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE)
@@ -871,7 +871,7 @@
(ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED))
ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */
- if (device->connection->res_opts.on_no_data == OND_SUSPEND_IO &&
+ if (first_peer_device(device)->connection->res_opts.on_no_data == OND_SUSPEND_IO &&
(ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE))
ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */
@@ -899,7 +899,7 @@
/* helper for __drbd_set_state */
static void set_ov_position(struct drbd_device *device, enum drbd_conns cs)
{
- if (device->connection->agreed_pro_version < 90)
+ if (first_peer_device(device)->connection->agreed_pro_version < 90)
device->ov_start_sector = 0;
device->rs_total = drbd_bm_bits(device);
device->ov_position = 0;
@@ -962,9 +962,9 @@
this happen...*/
if (is_valid_state(device, os) == rv)
- rv = is_valid_soft_transition(os, ns, device->connection);
+ rv = is_valid_soft_transition(os, ns, first_peer_device(device)->connection);
} else
- rv = is_valid_soft_transition(os, ns, device->connection);
+ rv = is_valid_soft_transition(os, ns, first_peer_device(device)->connection);
}
if (rv < SS_SUCCESS) {
@@ -981,7 +981,8 @@
sanitize_state(). Only display it here if we where not called from
_conn_request_state() */
if (!(flags & CS_DC_SUSP))
- conn_pr_state_change(device->connection, os, ns, (flags & ~CS_DC_MASK) | CS_DC_SUSP);
+ conn_pr_state_change(first_peer_device(device)->connection, os, ns,
+ (flags & ~CS_DC_MASK) | CS_DC_SUSP);
/* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference
* on the ldev here, to be sure the transition -> D_DISKLESS resp.
@@ -994,25 +995,25 @@
did_remote = drbd_should_do_remote(device->state);
device->state.i = ns.i;
should_do_remote = drbd_should_do_remote(device->state);
- device->connection->susp = ns.susp;
- device->connection->susp_nod = ns.susp_nod;
- device->connection->susp_fen = ns.susp_fen;
+ first_peer_device(device)->connection->susp = ns.susp;
+ first_peer_device(device)->connection->susp_nod = ns.susp_nod;
+ first_peer_device(device)->connection->susp_fen = ns.susp_fen;
/* put replicated vs not-replicated requests in seperate epochs */
if (did_remote != should_do_remote)
- start_new_tl_epoch(device->connection);
+ start_new_tl_epoch(first_peer_device(device)->connection);
if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING)
drbd_print_uuids(device, "attached to UUIDs");
/* Wake up role changes, that were delayed because of connection establishing */
if (os.conn == C_WF_REPORT_PARAMS && ns.conn != C_WF_REPORT_PARAMS &&
- no_peer_wf_report_params(device->connection))
- clear_bit(STATE_SENT, &device->connection->flags);
+ no_peer_wf_report_params(first_peer_device(device)->connection))
+ clear_bit(STATE_SENT, &first_peer_device(device)->connection->flags);
wake_up(&device->misc_wait);
wake_up(&device->state_wait);
- wake_up(&device->connection->ping_wait);
+ wake_up(&first_peer_device(device)->connection->ping_wait);
/* Aborted verify run, or we reached the stop sector.
* Log the last position, unless end-of-device. */
@@ -1101,21 +1102,21 @@
/* Receiver should clean up itself */
if (os.conn != C_DISCONNECTING && ns.conn == C_DISCONNECTING)
- drbd_thread_stop_nowait(&device->connection->receiver);
+ drbd_thread_stop_nowait(&first_peer_device(device)->connection->receiver);
/* Now the receiver finished cleaning up itself, it should die */
if (os.conn != C_STANDALONE && ns.conn == C_STANDALONE)
- drbd_thread_stop_nowait(&device->connection->receiver);
+ drbd_thread_stop_nowait(&first_peer_device(device)->connection->receiver);
/* Upon network failure, we need to restart the receiver. */
if (os.conn > C_WF_CONNECTION &&
ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT)
- drbd_thread_restart_nowait(&device->connection->receiver);
+ drbd_thread_restart_nowait(&first_peer_device(device)->connection->receiver);
/* Resume AL writing if we get a connection */
if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
drbd_resume_al(device);
- device->connection->connect_cnt++;
+ first_peer_device(device)->connection->connect_cnt++;
}
/* remember last attach time so request_timer_fn() won't
@@ -1133,7 +1134,7 @@
ascw->w.cb = w_after_state_ch;
ascw->w.device = device;
ascw->done = done;
- drbd_queue_work(&device->connection->sender_work, &ascw->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &ascw->w);
} else {
dev_err(DEV, "Could not kmalloc an ascw\n");
}
@@ -1181,7 +1182,7 @@
{
int rv;
- D_ASSERT(current == device->connection->worker.task);
+ D_ASSERT(current == first_peer_device(device)->connection->worker.task);
/* open coded non-blocking drbd_suspend_io(device); */
set_bit(SUSPEND_IO, &device->flags);
@@ -1228,7 +1229,7 @@
state change. This function might sleep */
if (ns.susp_nod) {
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
enum drbd_req_event what = NOTHING;
spin_lock_irq(&connection->req_lock);
@@ -1250,7 +1251,7 @@
}
if (ns.susp_fen) {
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
spin_lock_irq(&connection->req_lock);
if (connection->susp_fen && conn_lowest_conn(connection) >= C_CONNECTED) {
@@ -1277,7 +1278,7 @@
* which is unexpected. */
if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) &&
(ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) &&
- 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);
put_ldev(device);
}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 5b3f12a..aa1ad7f 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -102,16 +102,16 @@
unsigned long flags = 0;
struct drbd_device *device = peer_req->w.device;
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
device->read_cnt += peer_req->i.size >> 9;
list_del(&peer_req->w.list);
if (list_empty(&device->read_ee))
wake_up(&device->ee_wait);
if (test_bit(__EE_WAS_ERROR, &peer_req->flags))
__drbd_chk_io_error(device, DRBD_READ_ERROR);
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
- drbd_queue_work(&device->connection->sender_work, &peer_req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &peer_req->w);
put_ldev(device);
}
@@ -134,7 +134,7 @@
do_al_complete_io = peer_req->flags & EE_CALL_AL_COMPLETE_IO;
block_id = peer_req->block_id;
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
device->writ_cnt += peer_req->i.size >> 9;
list_move_tail(&peer_req->w.list, &device->done_ee);
@@ -150,7 +150,7 @@
if (test_bit(__EE_WAS_ERROR, &peer_req->flags))
__drbd_chk_io_error(device, DRBD_WRITE_ERROR);
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
if (block_id == ID_SYNCER)
drbd_rs_complete_io(device, i.sector);
@@ -161,7 +161,7 @@
if (do_al_complete_io)
drbd_al_complete_io(device, &i);
- wake_asender(device->connection);
+ wake_asender(first_peer_device(device)->connection);
put_ldev(device);
}
@@ -273,9 +273,9 @@
req->private_bio = ERR_PTR(error);
/* not req_mod(), we need irqsave here! */
- spin_lock_irqsave(&device->connection->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
__req_mod(req, what, &m);
- spin_unlock_irqrestore(&device->connection->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
put_ldev(device);
if (m.bio)
@@ -345,12 +345,12 @@
if (unlikely((peer_req->flags & EE_WAS_ERROR) != 0))
goto out;
- digest_size = crypto_hash_digestsize(device->connection->csums_tfm);
+ digest_size = crypto_hash_digestsize(first_peer_device(device)->connection->csums_tfm);
digest = kmalloc(digest_size, GFP_NOIO);
if (digest) {
sector_t sector = peer_req->i.sector;
unsigned int size = peer_req->i.size;
- drbd_csum_ee(device, device->connection->csums_tfm, peer_req, digest);
+ drbd_csum_ee(device, first_peer_device(device)->connection->csums_tfm, peer_req, digest);
/* Free peer_req and pages before send.
* In case we block on congestion, we could otherwise run into
* some distributed deadlock, if the other side blocks on
@@ -397,9 +397,9 @@
goto defer;
peer_req->w.cb = w_e_send_csum;
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_add(&peer_req->w.list, &device->read_ee);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
atomic_add(size >> 9, &device->rs_sect_ev);
if (drbd_submit_peer_request(device, peer_req, READ, DRBD_FAULT_RS_RD) == 0)
@@ -409,9 +409,9 @@
* because bio_add_page failed (probably broken lower level driver),
* retry may or may not help.
* If it does not, you may need to force disconnect. */
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_del(&peer_req->w.list);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
drbd_free_peer_req(device, peer_req);
defer:
@@ -439,7 +439,7 @@
struct drbd_device *device = (struct drbd_device *) data;
if (list_empty(&device->resync_work.list))
- drbd_queue_work(&device->connection->sender_work, &device->resync_work);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->resync_work);
}
static void fifo_set(struct fifo_buffer *fb, int value)
@@ -597,15 +597,15 @@
for (i = 0; i < number; i++) {
/* Stop generating RS requests, when half of the send buffer is filled */
- mutex_lock(&device->connection->data.mutex);
- if (device->connection->data.socket) {
- queued = device->connection->data.socket->sk->sk_wmem_queued;
- sndbuf = device->connection->data.socket->sk->sk_sndbuf;
+ mutex_lock(&first_peer_device(device)->connection->data.mutex);
+ if (first_peer_device(device)->connection->data.socket) {
+ queued = first_peer_device(device)->connection->data.socket->sk->sk_wmem_queued;
+ sndbuf = first_peer_device(device)->connection->data.socket->sk->sk_sndbuf;
} else {
queued = 1;
sndbuf = 0;
}
- mutex_unlock(&device->connection->data.mutex);
+ mutex_unlock(&first_peer_device(device)->connection->data.mutex);
if (queued > sndbuf / 2)
goto requeue;
@@ -675,7 +675,8 @@
/* adjust very last sectors, in case we are oddly sized */
if (sector + (size>>9) > capacity)
size = (capacity-sector)<<9;
- if (device->connection->agreed_pro_version >= 89 && device->connection->csums_tfm) {
+ if (first_peer_device(device)->connection->agreed_pro_version >= 89 &&
+ first_peer_device(device)->connection->csums_tfm) {
switch (read_for_csum(device, sector, size)) {
case -EIO: /* Disk failure */
put_ldev(device);
@@ -800,7 +801,7 @@
static void ping_peer(struct drbd_device *device)
{
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
clear_bit(GOT_PING_ACK, &connection->flags);
request_ping(connection);
@@ -831,7 +832,7 @@
if (w) {
w->cb = w_resync_finished;
w->device = device;
- drbd_queue_work(&device->connection->sender_work, w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, w);
return 1;
}
dev_err(DEV, "Warn failed to drbd_rs_del_all() and to kmalloc(w).\n");
@@ -854,7 +855,7 @@
ping_peer(device);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
os = drbd_read_state(device);
verify_done = (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T);
@@ -885,7 +886,7 @@
if (os.conn == C_SYNC_TARGET || os.conn == C_PAUSED_SYNC_T)
khelper_cmd = "after-resync-target";
- if (device->connection->csums_tfm && device->rs_total) {
+ if (first_peer_device(device)->connection->csums_tfm && device->rs_total) {
const unsigned long s = device->rs_same_csum;
const unsigned long t = device->rs_total;
const int ratio =
@@ -943,7 +944,7 @@
_drbd_set_state(device, ns, CS_VERBOSE, NULL);
out_unlock:
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
put_ldev(device);
out:
device->rs_total = 0;
@@ -970,9 +971,9 @@
int i = (peer_req->i.size + PAGE_SIZE -1) >> PAGE_SHIFT;
atomic_add(i, &device->pp_in_use_by_net);
atomic_sub(i, &device->pp_in_use);
- spin_lock_irq(&device->connection->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
list_add_tail(&peer_req->w.list, &device->net_ee);
- spin_unlock_irq(&device->connection->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
wake_up(&drbd_pp_wait);
} else
drbd_free_peer_req(device, peer_req);
@@ -1096,13 +1097,13 @@
/* quick hack to try to avoid a race against reconfiguration.
* a real fix would be much more involved,
* introducing more locking mechanisms */
- if (device->connection->csums_tfm) {
- digest_size = crypto_hash_digestsize(device->connection->csums_tfm);
+ if (first_peer_device(device)->connection->csums_tfm) {
+ digest_size = crypto_hash_digestsize(first_peer_device(device)->connection->csums_tfm);
D_ASSERT(digest_size == di->digest_size);
digest = kmalloc(digest_size, GFP_NOIO);
}
if (digest) {
- drbd_csum_ee(device, device->connection->csums_tfm, peer_req, digest);
+ drbd_csum_ee(device, first_peer_device(device)->connection->csums_tfm, peer_req, digest);
eq = !memcmp(digest, di->digest, digest_size);
kfree(digest);
}
@@ -1146,7 +1147,7 @@
if (unlikely(cancel))
goto out;
- digest_size = crypto_hash_digestsize(device->connection->verify_tfm);
+ digest_size = crypto_hash_digestsize(first_peer_device(device)->connection->verify_tfm);
digest = kmalloc(digest_size, GFP_NOIO);
if (!digest) {
err = 1; /* terminate the connection in case the allocation failed */
@@ -1154,7 +1155,7 @@
}
if (likely(!(peer_req->flags & EE_WAS_ERROR)))
- drbd_csum_ee(device, device->connection->verify_tfm, peer_req, digest);
+ drbd_csum_ee(device, first_peer_device(device)->connection->verify_tfm, peer_req, digest);
else
memset(digest, 0, digest_size);
@@ -1217,10 +1218,10 @@
di = peer_req->digest;
if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
- digest_size = crypto_hash_digestsize(device->connection->verify_tfm);
+ digest_size = crypto_hash_digestsize(first_peer_device(device)->connection->verify_tfm);
digest = kmalloc(digest_size, GFP_NOIO);
if (digest) {
- drbd_csum_ee(device, device->connection->verify_tfm, peer_req, digest);
+ drbd_csum_ee(device, first_peer_device(device)->connection->verify_tfm, peer_req, digest);
D_ASSERT(digest_size == di->digest_size);
eq = !memcmp(digest, di->digest, digest_size);
@@ -1297,7 +1298,7 @@
if (cancel)
return 0;
- sock = &device->connection->data;
+ sock = &first_peer_device(device)->connection->data;
if (!drbd_prepare_command(device, sock))
return -EIO;
return drbd_send_command(device, sock, P_UNPLUG_REMOTE, 0, NULL, 0);
@@ -1328,7 +1329,7 @@
{
struct drbd_request *req = container_of(w, struct drbd_request, w);
struct drbd_device *device = w->device;
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
int err;
if (unlikely(cancel)) {
@@ -1358,7 +1359,7 @@
{
struct drbd_request *req = container_of(w, struct drbd_request, w);
struct drbd_device *device = w->device;
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
int err;
if (unlikely(cancel)) {
@@ -1386,7 +1387,7 @@
{
struct drbd_request *req = container_of(w, struct drbd_request, w);
struct drbd_device *device = w->device;
- struct drbd_connection *connection = device->connection;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
int err;
if (unlikely(cancel)) {
@@ -1581,7 +1582,7 @@
{
struct drbd_device *device = (struct drbd_device *) data;
- drbd_queue_work(&device->connection->sender_work, &device->start_resync_work);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->start_resync_work);
}
int w_start_resync(struct drbd_work *w, int cancel)
@@ -1628,7 +1629,7 @@
if (r > 0) {
dev_info(DEV, "before-resync-target handler returned %d, "
"dropping connection.\n", r);
- conn_request_state(device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return;
}
} else /* C_SYNC_SOURCE */ {
@@ -1641,14 +1642,15 @@
} else {
dev_info(DEV, "before-resync-source handler returned %d, "
"dropping connection.\n", r);
- conn_request_state(device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(first_peer_device(device)->connection,
+ NS(conn, C_DISCONNECTING), CS_HARD);
return;
}
}
}
}
- if (current == device->connection->worker.task) {
+ if (current == first_peer_device(device)->connection->worker.task) {
/* The worker should not sleep waiting for state_mutex,
that can take long */
if (!mutex_trylock(device->state_mutex)) {
@@ -1727,10 +1729,12 @@
* drbd_resync_finished from here in that case.
* We drbd_gen_and_send_sync_uuid here for protocol < 96,
* and from after_state_ch otherwise. */
- if (side == C_SYNC_SOURCE && device->connection->agreed_pro_version < 96)
+ if (side == C_SYNC_SOURCE &&
+ first_peer_device(device)->connection->agreed_pro_version < 96)
drbd_gen_and_send_sync_uuid(device);
- if (device->connection->agreed_pro_version < 95 && device->rs_total == 0) {
+ if (first_peer_device(device)->connection->agreed_pro_version < 95 &&
+ device->rs_total == 0) {
/* This still has a race (about when exactly the peers
* detect connection loss) that can lead to a full sync
* on next handshake. In 8.3.9 we fixed this with explicit
@@ -1746,7 +1750,7 @@
int timeo;
rcu_read_lock();
- nc = rcu_dereference(device->connection->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
timeo = nc->ping_int * HZ + nc->ping_timeo * HZ / 9;
rcu_read_unlock();
schedule_timeout_interruptible(timeo);