diff options
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 8 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_bitmap.c | 8 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 58 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 156 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 90 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_proc.c | 6 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 246 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 48 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_req.h | 4 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_state.c | 73 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 96 |
11 files changed, 416 insertions, 377 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 8b507455f71e..4af4dc166373 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -315,7 +315,7 @@ void drbd_al_begin_io_commit(struct drbd_device *device, bool delegate) { 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_commit(struct drbd_device *device, bool delegate) */ 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 @@ static int al_write_transaction(struct drbd_device *device, bool delegate) 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 @@ static void drbd_try_clear_on_disk_bm(struct drbd_device *device, sector_t secto 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 cd3e0dea7a5d..cb8e64978b8e 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -119,9 +119,9 @@ static void __bm_print_lock_info(struct drbd_device *device, const char *func) 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 @@ void drbd_bm_lock(struct drbd_device *device, char *why, enum bm_flag flags) 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 32517a0cbc62..85e2f4b56a06 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -483,7 +483,7 @@ struct drbd_backing_dev { 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 submit_worker { 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 drbd_device { 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 @@ static inline struct drbd_device *minor_to_device(unsigned int minor) 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 struct bio *bio_alloc_drbd(gfp_t gfp_mask); 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 void conn_flush_workqueue(struct drbd_connection *connection); 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 @@ static inline union drbd_state drbd_read_state(struct drbd_device *device) 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 @@ static inline void drbd_chk_io_error_(struct drbd_device *device, { 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 @@ static inline void put_ldev(struct drbd_device *device) 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 @@ static inline int drbd_get_max_buffers(struct drbd_device *device) 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 @@ static inline int drbd_state_is_stable(struct drbd_device *device) /* 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_state_is_stable(struct drbd_device *device) 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 @@ static inline bool inc_ap_bio_cond(struct drbd_device *device) { 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 @@ static inline void dec_ap_bio(struct drbd_device *device) 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 void dec_ap_bio(struct drbd_device *device) 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 e4fd1806dc25..b7c858f51fa6 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -308,7 +308,7 @@ void tl_clear(struct drbd_connection *connection) */ 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 *conn_prepare_command(struct drbd_connection *connection, struct drbd_socke 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 drbd_send_command(struct drbd_device *device, struct drbd_socket *sock, { 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 @@ int drbd_send_sync_param(struct drbd_device *device) 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 @@ static int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags) 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 @@ static int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags) 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 @@ void drbd_gen_and_send_sync_uuid(struct drbd_device *device) 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 @@ int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flag max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */ } - 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 @@ int drbd_send_current_state(struct drbd_device *device) 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 @@ int drbd_send_state(struct drbd_device *device, union drbd_state state) 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 @@ int drbd_send_state_req(struct drbd_device *device, union drbd_state mask, union 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 @@ void drbd_send_sr_reply(struct drbd_device *device, enum drbd_state_rv retcode) 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 @@ static int fill_bitmap_rle_bits(struct drbd_device *device, /* 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 fill_bitmap_rle_bits(struct drbd_device *device, 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 @@ send_bitmap_rle_or_plain(struct drbd_device *device, struct bm_xfer_ctx *c) 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 @@ send_bitmap_rle_or_plain(struct drbd_device *device, struct bm_xfer_ctx *c) 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 @@ static int _drbd_send_bitmap(struct drbd_device *device) 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 @@ static int _drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd, 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 @@ static int _drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd, 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 @@ int drbd_send_drequest(struct drbd_device *device, int cmd, 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 @@ int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector, int siz /* 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 @@ int drbd_send_ov_request(struct drbd_device *device, sector_t sector, int size) 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 @@ static int _drbd_no_send_page(struct drbd_device *device, struct page *page, 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_no_send_page(struct drbd_device *device, struct page *page, 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 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page, 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 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page, 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 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page, 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 int _drbd_send_zc_ee(struct drbd_device *device, 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 drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) 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 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) 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 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) } 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 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req) /* 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 drbd_send_block(struct drbd_device *device, enum drbd_packet cmd, 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 @@ int drbd_send_block(struct drbd_device *device, enum drbd_packet cmd, 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 @@ int drbd_send_out_of_sync(struct drbd_device *device, struct drbd_request *req) 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 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) 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 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) 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_init_set_defaults(struct drbd_device *device) 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 @@ void drbd_device_cleanup(struct drbd_device *device) 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 @@ void drbd_device_cleanup(struct drbd_device *device) 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 @@ static void drbd_release_all_peer_reqs(struct drbd_device *device) 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 @@ void drbd_minor_destroy(struct kref *kref) 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 @@ static void drbd_cleanup(void) 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 @@ static int drbd_congested(void *congested_data, int bdi_bits) 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 @@ static int drbd_congested(void *congested_data, int bdi_bits) 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 @@ static int init_submitter(struct drbd_device *device) 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 @@ enum drbd_ret_code conn_new_minor(struct drbd_connection *connection, unsigned i 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 @@ enum drbd_ret_code conn_new_minor(struct drbd_connection *connection, unsigned i 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_io_page: 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 @@ int drbd_md_read(struct drbd_device *device, struct drbd_backing_dev *bdev) 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 drbd_queue_bitmap_io(struct drbd_device *device, 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 @@ void drbd_queue_bitmap_io(struct drbd_device *device, 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 drbd_bitmap_io(struct drbd_device *device, int (*io_fn)(struct drbd_device * { 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 @@ static void md_sync_timer_fn(unsigned long data) /* 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 @@ int drbd_wait_misc(struct drbd_device *device, struct drbd_interval *i) 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 @@ int drbd_wait_misc(struct drbd_device *device, struct drbd_interval *i) /* 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 1b5b7ea7f7cc..a8c9c86e29f5 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -246,10 +246,10 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, /* 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 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, 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 @@ int drbd_khelper(struct drbd_device *device, char *cmd) 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 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) 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 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) 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 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) 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 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) 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 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) 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 @@ void drbd_reconsider_max_bio_size(struct drbd_device *device) 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 @@ static void drbd_suspend_al(struct drbd_device *device) } 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 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) } 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) 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 @@ void resync_after_online_grow(struct drbd_device *device) 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 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info) 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 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, /* 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 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, 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 @@ next_connection: } 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 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) } /* 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 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info) 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 @@ int drbd_adm_add_minor(struct sk_buff *skb, struct genl_info *info) } /* 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 @@ int drbd_adm_add_minor(struct sk_buff *skb, struct genl_info *info) 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 @@ static enum drbd_ret_code adm_delete_minor(struct drbd_device *device) 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 9c4d413655e3..f1c81c101fad 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -251,7 +251,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v) /* 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 @@ static int drbd_seq_show(struct seq_file *seq, void *v) 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 42dbf5d86a43..e08e99f756a5 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -221,9 +221,9 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device) 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 @@ struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number, /* 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 @@ struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number, } /* 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 drbd_free_peer_reqs(struct drbd_device *device, struct list_head *list) 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 @@ static int drbd_finish_peer_reqs(struct drbd_device *device) 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 @@ static void _drbd_wait_ee_list_empty(struct drbd_device *device, * 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 @@ int drbd_connected(struct drbd_device *device) 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 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector, 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 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector, 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 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector, } 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 @@ static int drbd_drain_block(struct drbd_device *device, int data_size) 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 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req, 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 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req, 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 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req, } 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 @@ static int recv_resync_read(struct drbd_device *device, sector_t sector, int dat 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 @@ static int recv_resync_read(struct drbd_device *device, sector_t sector, int dat /* 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 @@ static int receive_DataReply(struct drbd_connection *connection, struct packet_i 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 @@ static int e_end_block(struct drbd_work *w, int cancel) /* 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_superseded(struct drbd_work *w, int unused) 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 @@ static void update_peer_seq(struct drbd_device *device, unsigned int peer_seq) { 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 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee 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 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee break; } } - spin_unlock_irq(&device->connection->req_lock); + spin_unlock_irq(&first_peer_device(device)->connection->req_lock); return rv; } @@ -1958,7 +1958,7 @@ static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 pe 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 @@ static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 pe } 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 @@ static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 pe 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 @@ static void fail_postponed_requests(struct drbd_device *device, sector_t sector, 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 void fail_postponed_requests(struct drbd_device *device, sector_t sector, 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 @@ static int handle_write_conflicts(struct drbd_device *device, 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 @@ static int handle_write_conflicts(struct drbd_device *device, */ 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 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * 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 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * } } 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 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * /* 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 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet 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 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet 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_for_resync: 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 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) 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 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) "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 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local) 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 @@ static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local) 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 @@ static int drbd_asb_recover_2p(struct drbd_device *device) __must_hold(local) 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 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho 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 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho 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 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho 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 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho *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 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho *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 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd 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 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd } } - 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 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i 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 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i 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 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i 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 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i 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 @@ reconnect: 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 @@ disconnect: 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 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info 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 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info 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 @@ static int receive_uuids(struct drbd_connection *connection, struct packet_info (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 @@ static int receive_req_state(struct drbd_connection *connection, struct packet_i 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 @@ static int receive_state(struct drbd_connection *connection, struct packet_info 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 @@ static int receive_state(struct drbd_connection *connection, struct packet_info 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 @@ static int receive_state(struct drbd_connection *connection, struct packet_info 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 @@ receive_bitmap_plain(struct drbd_device *device, unsigned int size, 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 @@ receive_bitmap_plain(struct drbd_device *device, unsigned int size, } 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 @@ decode_bitmap_c(struct drbd_device *device, * 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 @@ void INFO_bm_xfer_stats(struct drbd_device *device, 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 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info 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 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info 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 @@ static int drbd_disconnected(struct drbd_device *device) 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 @@ static int drbd_disconnected(struct drbd_device *device) 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 @@ static int got_IsInSync(struct drbd_connection *connection, struct packet_info * 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 @@ validate_req_change_req_state(struct drbd_device *device, u64 id, sector_t secto 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 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info * 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 a33a35e4655d..dd1033472763 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -274,8 +274,8 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m) * 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 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, * 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 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, 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 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, 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 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, 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 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, 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 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, 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 @@ static void complete_conflicting_writes(struct drbd_request *req) 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 @@ static void complete_conflicting_writes(struct drbd_request *req) /* 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 @@ static void maybe_pull_ahead(struct drbd_device *device) 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 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request 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 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request } /* 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 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request /* 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 @@ nodata: 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 @@ static struct drbd_request *find_oldest_request(struct drbd_connection *connecti 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 407404bb8807..27283e619a07 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h @@ -318,9 +318,9 @@ static inline int req_mod(struct drbd_request *req, 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 ecc63cf85d85..22c4e7d57a80 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -237,10 +237,10 @@ drbd_change_state(struct drbd_device *device, enum chg_state_flags f, 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 @@ _req_st_cond(struct drbd_device *device, union drbd_state mask, 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 @@ _req_st_cond(struct drbd_device *device, union drbd_state mask, 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 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask, 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 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask, 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 @@ is_valid_state(struct drbd_device *device, union drbd_state ns) 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 @@ is_valid_state(struct drbd_device *device, union drbd_state ns) 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 @@ static union drbd_state sanitize_state(struct drbd_device *device, union drbd_st (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 @@ void drbd_resume_al(struct drbd_device *device) /* 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 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, 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 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, 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 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, 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 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, /* 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 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, 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 drbd_bitmap_io_from_worker(struct drbd_device *device, { 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 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, 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 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, } 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 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, * 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 5b3f12a42230..aa1ad7f39786 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -102,16 +102,16 @@ static void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __rele 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 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel 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 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel 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 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel 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 @@ void drbd_request_endio(struct bio *bio, int error) 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 @@ static int w_e_send_csum(struct drbd_work *w, int cancel) 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 @@ static int read_for_csum(struct drbd_device *device, sector_t sector, int size) 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 @@ static int read_for_csum(struct drbd_device *device, sector_t sector, int size) * 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 @@ void resync_timer_fn(unsigned long data) 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 @@ int w_make_resync_request(struct drbd_work *w, int cancel) 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 @@ next_sector: /* 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 int w_resync_finished(struct drbd_work *w, int cancel) 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 @@ int drbd_resync_finished(struct drbd_device *device) 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 @@ int drbd_resync_finished(struct drbd_device *device) 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 @@ int drbd_resync_finished(struct drbd_device *device) 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 @@ int drbd_resync_finished(struct drbd_device *device) _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 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_ 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 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel) /* 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 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel) 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 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel) } 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 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel) 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 @@ int w_send_write_hint(struct drbd_work *w, int cancel) 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 @@ int w_send_out_of_sync(struct drbd_work *w, int cancel) { 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 @@ int w_send_dblock(struct drbd_work *w, int cancel) { 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 @@ int w_send_read_req(struct drbd_work *w, int cancel) { 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 @@ void start_resync_timer_fn(unsigned long data) { 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 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) 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 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) } 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 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) * 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 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) 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); |