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

drbd: Introduce "peer_device" object between "device" and "connection"

In a setup where a device (aka volume) can replicate to multiple peers and one
connection can be shared between multiple devices, we need separate objects to
represent devices on peer nodes and network connections.

As a first step to introduce multiple connections per device, give each
drbd_device object a single drbd_peer_device object which connects it to a
drbd_connection object.
Signed-off-by: NAndreas Gruenbacher <agruen@linbit.com>
Signed-off-by: NPhilipp Reisner <philipp.reisner@linbit.com>
上级 bde89a9e
......@@ -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");
}
......
......@@ -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)
......
......@@ -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)
......
此差异已折叠。
......@@ -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 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
}
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);
......
......@@ -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)
......
此差异已折叠。
......@@ -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 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request
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 */
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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 @@ int w_make_resync_request(struct drbd_work *w, int cancel)
/* 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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册