Commit c06ece6b authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner

drbd: Turn connection->volumes into connection->peer_devices

Let connection->peer_devices point to peer devices; connection->volumes was
pointing to devices.
Signed-off-by: default avatarAndreas Gruenbacher <agruen@linbit.com>
Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
parent eb6bea67
...@@ -549,7 +549,7 @@ struct drbd_connection { ...@@ -549,7 +549,7 @@ struct drbd_connection {
struct list_head connections; struct list_head connections;
struct drbd_resource *resource; struct drbd_resource *resource;
struct kref kref; struct kref kref;
struct idr volumes; /* <connection, vnr> to device mapping */ struct idr peer_devices; /* volume number to peer device mapping */
enum drbd_conns cstate; /* Only C_STANDALONE to C_WF_REPORT_PARAMS */ enum drbd_conns cstate; /* Only C_STANDALONE to C_WF_REPORT_PARAMS */
unsigned susp:1; /* IO suspended by user */ unsigned susp:1; /* IO suspended by user */
unsigned susp_nod:1; /* IO suspended because no data */ unsigned susp_nod:1; /* IO suspended because no data */
...@@ -822,7 +822,10 @@ static inline unsigned int device_to_minor(struct drbd_device *device) ...@@ -822,7 +822,10 @@ static inline unsigned int device_to_minor(struct drbd_device *device)
static inline struct drbd_device *vnr_to_device(struct drbd_connection *connection, int vnr) static inline struct drbd_device *vnr_to_device(struct drbd_connection *connection, int vnr)
{ {
return (struct drbd_device *)idr_find(&connection->volumes, vnr); struct drbd_peer_device *peer_device;
peer_device = idr_find(&connection->peer_devices, vnr);
return peer_device ? peer_device->device : NULL;
} }
/* /*
......
...@@ -496,15 +496,16 @@ char *drbd_task_to_thread_name(struct drbd_connection *connection, struct task_s ...@@ -496,15 +496,16 @@ char *drbd_task_to_thread_name(struct drbd_connection *connection, struct task_s
int conn_lowest_minor(struct drbd_connection *connection) int conn_lowest_minor(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr = 0, m; int vnr = 0, minor = -1;
rcu_read_lock(); rcu_read_lock();
device = idr_get_next(&connection->volumes, &vnr); peer_device = idr_get_next(&connection->peer_devices, &vnr);
m = device ? device_to_minor(device) : -1; if (peer_device)
minor = device_to_minor(peer_device->device);
rcu_read_unlock(); rcu_read_unlock();
return m; return minor;
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -2590,7 +2591,7 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts) ...@@ -2590,7 +2591,7 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
spin_lock_init(&connection->req_lock); spin_lock_init(&connection->req_lock);
mutex_init(&connection->conf_update); mutex_init(&connection->conf_update);
init_waitqueue_head(&connection->ping_wait); init_waitqueue_head(&connection->ping_wait);
idr_init(&connection->volumes); idr_init(&connection->peer_devices);
drbd_init_workqueue(&connection->sender_work); drbd_init_workqueue(&connection->sender_work);
mutex_init(&connection->data.mutex); mutex_init(&connection->data.mutex);
...@@ -2632,7 +2633,7 @@ void drbd_destroy_connection(struct kref *kref) ...@@ -2632,7 +2633,7 @@ void drbd_destroy_connection(struct kref *kref)
conn_err(connection, "epoch_size:%d\n", atomic_read(&connection->current_epoch->epoch_size)); conn_err(connection, "epoch_size:%d\n", atomic_read(&connection->current_epoch->epoch_size));
kfree(connection->current_epoch); kfree(connection->current_epoch);
idr_destroy(&connection->volumes); idr_destroy(&connection->peer_devices);
free_cpumask_var(connection->cpu_mask); free_cpumask_var(connection->cpu_mask);
drbd_free_socket(&connection->meta); drbd_free_socket(&connection->meta);
...@@ -2760,7 +2761,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne ...@@ -2760,7 +2761,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne
} }
kref_get(&device->kref); kref_get(&device->kref);
id = idr_alloc(&connection->volumes, device, vnr, vnr + 1, GFP_KERNEL); id = idr_alloc(&connection->peer_devices, peer_device, vnr, vnr + 1, GFP_KERNEL);
if (id < 0) { if (id < 0) {
if (id == -ENOSPC) { if (id == -ENOSPC) {
err = ERR_INVALID_REQUEST; err = ERR_INVALID_REQUEST;
...@@ -2786,7 +2787,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne ...@@ -2786,7 +2787,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne
return NO_ERROR; return NO_ERROR;
out_idr_remove_vol: out_idr_remove_vol:
idr_remove(&connection->volumes, vnr); idr_remove(&connection->peer_devices, vnr);
out_idr_remove_from_resource: out_idr_remove_from_resource:
idr_remove(&resource->devices, vnr); idr_remove(&resource->devices, vnr);
out_idr_remove_minor: out_idr_remove_minor:
...@@ -2815,7 +2816,7 @@ void drbd_delete_minor(struct drbd_device *device) ...@@ -2815,7 +2816,7 @@ void drbd_delete_minor(struct drbd_device *device)
int refs = 3; int refs = 3;
for_each_connection(connection, resource) { for_each_connection(connection, resource) {
idr_remove(&connection->volumes, device->vnr); idr_remove(&connection->peer_devices, device->vnr);
refs++; refs++;
} }
idr_remove(&resource->devices, device->vnr); idr_remove(&resource->devices, device->vnr);
...@@ -2938,11 +2939,13 @@ void drbd_free_sock(struct drbd_connection *connection) ...@@ -2938,11 +2939,13 @@ void drbd_free_sock(struct drbd_connection *connection)
void conn_md_sync(struct drbd_connection *connection) void conn_md_sync(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
kref_get(&device->kref); kref_get(&device->kref);
rcu_read_unlock(); rcu_read_unlock();
drbd_md_sync(device); drbd_md_sync(device);
......
...@@ -415,14 +415,16 @@ static int conn_khelper(struct drbd_connection *connection, char *cmd) ...@@ -415,14 +415,16 @@ static int conn_khelper(struct drbd_connection *connection, char *cmd)
static enum drbd_fencing_p highest_fencing_policy(struct drbd_connection *connection) static enum drbd_fencing_p highest_fencing_policy(struct drbd_connection *connection)
{ {
enum drbd_fencing_p fp = FP_NOT_AVAIL; enum drbd_fencing_p fp = FP_NOT_AVAIL;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (get_ldev_if_state(device, D_CONSISTENT)) { if (get_ldev_if_state(device, D_CONSISTENT)) {
fp = max_t(enum drbd_fencing_p, fp, struct disk_conf *disk_conf =
rcu_dereference(device->ldev->disk_conf)->fencing); rcu_dereference(peer_device->device->ldev->disk_conf);
fp = max_t(enum drbd_fencing_p, fp, disk_conf->fencing);
put_ldev(device); put_ldev(device);
} }
} }
...@@ -1878,12 +1880,13 @@ int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info) ...@@ -1878,12 +1880,13 @@ int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info)
static bool conn_resync_running(struct drbd_connection *connection) static bool conn_resync_running(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
bool rv = false; bool rv = false;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (device->state.conn == C_SYNC_SOURCE || if (device->state.conn == C_SYNC_SOURCE ||
device->state.conn == C_SYNC_TARGET || device->state.conn == C_SYNC_TARGET ||
device->state.conn == C_PAUSED_SYNC_S || device->state.conn == C_PAUSED_SYNC_S ||
...@@ -1899,12 +1902,13 @@ static bool conn_resync_running(struct drbd_connection *connection) ...@@ -1899,12 +1902,13 @@ static bool conn_resync_running(struct drbd_connection *connection)
static bool conn_ov_running(struct drbd_connection *connection) static bool conn_ov_running(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
bool rv = false; bool rv = false;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (device->state.conn == C_VERIFY_S || if (device->state.conn == C_VERIFY_S ||
device->state.conn == C_VERIFY_T) { device->state.conn == C_VERIFY_T) {
rv = true; rv = true;
...@@ -1919,7 +1923,7 @@ static bool conn_ov_running(struct drbd_connection *connection) ...@@ -1919,7 +1923,7 @@ static bool conn_ov_running(struct drbd_connection *connection)
static enum drbd_ret_code static enum drbd_ret_code
_check_net_options(struct drbd_connection *connection, struct net_conf *old_conf, struct net_conf *new_conf) _check_net_options(struct drbd_connection *connection, struct net_conf *old_conf, struct net_conf *new_conf)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
int i; int i;
if (old_conf && connection->cstate == C_WF_REPORT_PARAMS && connection->agreed_pro_version < 100) { if (old_conf && connection->cstate == C_WF_REPORT_PARAMS && connection->agreed_pro_version < 100) {
...@@ -1942,7 +1946,8 @@ _check_net_options(struct drbd_connection *connection, struct net_conf *old_conf ...@@ -1942,7 +1946,8 @@ _check_net_options(struct drbd_connection *connection, struct net_conf *old_conf
(new_conf->wire_protocol != DRBD_PROT_C)) (new_conf->wire_protocol != DRBD_PROT_C))
return ERR_NOT_PROTO_C; return ERR_NOT_PROTO_C;
idr_for_each_entry(&connection->volumes, device, i) { idr_for_each_entry(&connection->peer_devices, peer_device, i) {
struct drbd_device *device = peer_device->device;
if (get_ldev(device)) { if (get_ldev(device)) {
enum drbd_fencing_p fp = rcu_dereference(device->ldev->disk_conf)->fencing; enum drbd_fencing_p fp = rcu_dereference(device->ldev->disk_conf)->fencing;
put_ldev(device); put_ldev(device);
...@@ -1963,7 +1968,7 @@ static enum drbd_ret_code ...@@ -1963,7 +1968,7 @@ static enum drbd_ret_code
check_net_options(struct drbd_connection *connection, struct net_conf *new_conf) check_net_options(struct drbd_connection *connection, struct net_conf *new_conf)
{ {
static enum drbd_ret_code rv; static enum drbd_ret_code rv;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int i; int i;
rcu_read_lock(); rcu_read_lock();
...@@ -1971,7 +1976,8 @@ check_net_options(struct drbd_connection *connection, struct net_conf *new_conf) ...@@ -1971,7 +1976,8 @@ check_net_options(struct drbd_connection *connection, struct net_conf *new_conf)
rcu_read_unlock(); rcu_read_unlock();
/* connection->volumes protected by genl_lock() here */ /* connection->volumes protected by genl_lock() here */
idr_for_each_entry(&connection->volumes, device, i) { idr_for_each_entry(&connection->peer_devices, peer_device, i) {
struct drbd_device *device = peer_device->device;
if (!device->bitmap) { if (!device->bitmap) {
if (drbd_bm_init(device)) if (drbd_bm_init(device))
return ERR_NOMEM; return ERR_NOMEM;
...@@ -2155,7 +2161,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) ...@@ -2155,7 +2161,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
struct net_conf *old_conf, *new_conf = NULL; struct net_conf *old_conf, *new_conf = NULL;
struct crypto crypto = { }; struct crypto crypto = { };
struct drbd_resource *resource; struct drbd_resource *resource;
...@@ -2256,7 +2262,8 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) ...@@ -2256,7 +2262,8 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
mutex_unlock(&connection->conf_update); mutex_unlock(&connection->conf_update);
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, i) { idr_for_each_entry(&connection->peer_devices, peer_device, i) {
struct drbd_device *device = peer_device->device;
device->send_cnt = 0; device->send_cnt = 0;
device->recv_cnt = 0; device->recv_cnt = 0;
} }
...@@ -2915,6 +2922,7 @@ int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info) ...@@ -2915,6 +2922,7 @@ int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info)
static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct drbd_peer_device *peer_device;
struct drbd_device *device; struct drbd_device *device;
struct drbd_genlmsghdr *dh; struct drbd_genlmsghdr *dh;
struct drbd_resource *pos = (struct drbd_resource *)cb->args[0]; struct drbd_resource *pos = (struct drbd_resource *)cb->args[0];
...@@ -2926,7 +2934,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2926,7 +2934,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
/* Open coded, deferred, iteration: /* Open coded, deferred, iteration:
* for_each_resource_safe(resource, tmp, &drbd_resources) { * for_each_resource_safe(resource, tmp, &drbd_resources) {
* connection = "first connection of resource"; * connection = "first connection of resource";
* idr_for_each_entry(&connection->volumes, device, i) { * idr_for_each_entry(&connection->peer_devices, peer_device, i) {
* ... * ...
* } * }
* } * }
...@@ -2962,8 +2970,8 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2962,8 +2970,8 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
if (resource) { if (resource) {
next_resource: next_resource:
connection = first_connection(resource); connection = first_connection(resource);
device = idr_get_next(&connection->volumes, &volume); peer_device = idr_get_next(&connection->peer_devices, &volume);
if (!device) { if (!peer_device) {
/* No more volumes to dump on this resource. /* No more volumes to dump on this resource.
* Advance resource iterator. */ * Advance resource iterator. */
pos = list_entry_rcu(resource->resources.next, pos = list_entry_rcu(resource->resources.next,
...@@ -2987,7 +2995,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2987,7 +2995,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
if (!dh) if (!dh)
goto out; goto out;
if (!device) { if (!peer_device) {
/* This is a connection without a single volume. /* This is a connection without a single volume.
* Suprisingly enough, it may have a network * Suprisingly enough, it may have a network
* configuration. */ * configuration. */
...@@ -3002,6 +3010,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -3002,6 +3010,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
goto done; goto done;
} }
device = peer_device->device;
D_ASSERT(device->vnr == volume); D_ASSERT(device->vnr == volume);
D_ASSERT(first_peer_device(device)->connection == connection); D_ASSERT(first_peer_device(device)->connection == connection);
...@@ -3359,7 +3368,7 @@ int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info) ...@@ -3359,7 +3368,7 @@ int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info)
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
{ {
int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */
struct drbd_device *device; struct drbd_peer_device *peer_device;
unsigned i; unsigned i;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
...@@ -3369,8 +3378,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) ...@@ -3369,8 +3378,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
/* demote */ /* demote */
idr_for_each_entry(&adm_ctx.connection->volumes, device, i) { idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
retcode = drbd_set_role(device, R_SECONDARY, 0); retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0);
if (retcode < SS_SUCCESS) { if (retcode < SS_SUCCESS) {
drbd_msg_put_info("failed to demote"); drbd_msg_put_info("failed to demote");
goto out; goto out;
...@@ -3384,8 +3393,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) ...@@ -3384,8 +3393,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
} }
/* detach */ /* detach */
idr_for_each_entry(&adm_ctx.connection->volumes, device, i) { idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
retcode = adm_detach(device, 0); retcode = adm_detach(peer_device->device, 0);
if (retcode < SS_SUCCESS || retcode > NO_ERROR) { if (retcode < SS_SUCCESS || retcode > NO_ERROR) {
drbd_msg_put_info("failed to detach"); drbd_msg_put_info("failed to detach");
goto out; goto out;
...@@ -3400,8 +3409,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) ...@@ -3400,8 +3409,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
/* Now, nothing can fail anymore */ /* Now, nothing can fail anymore */
/* delete volumes */ /* delete volumes */
idr_for_each_entry(&adm_ctx.connection->volumes, device, i) { idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
retcode = adm_del_minor(device); retcode = adm_del_minor(peer_device->device);
if (retcode != NO_ERROR) { if (retcode != NO_ERROR) {
/* "can not happen" */ /* "can not happen" */
drbd_msg_put_info("failed to delete volume"); drbd_msg_put_info("failed to delete volume");
......
...@@ -867,7 +867,7 @@ int drbd_connected(struct drbd_device *device) ...@@ -867,7 +867,7 @@ int drbd_connected(struct drbd_device *device)
static int conn_connect(struct drbd_connection *connection) static int conn_connect(struct drbd_connection *connection)
{ {
struct drbd_socket sock, msock; struct drbd_socket sock, msock;
struct drbd_device *device; struct drbd_peer_device *peer_device;
struct net_conf *nc; struct net_conf *nc;
int vnr, timeout, h, ok; int vnr, timeout, h, ok;
bool discard_my_data; bool discard_my_data;
...@@ -1038,7 +1038,8 @@ static int conn_connect(struct drbd_connection *connection) ...@@ -1038,7 +1038,8 @@ static int conn_connect(struct drbd_connection *connection)
set_bit(STATE_SENT, &connection->flags); set_bit(STATE_SENT, &connection->flags);
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
kref_get(&device->kref); kref_get(&device->kref);
rcu_read_unlock(); rcu_read_unlock();
...@@ -1145,12 +1146,14 @@ static int drbd_recv_header(struct drbd_connection *connection, struct packet_in ...@@ -1145,12 +1146,14 @@ static int drbd_recv_header(struct drbd_connection *connection, struct packet_in
static void drbd_flush(struct drbd_connection *connection) static void drbd_flush(struct drbd_connection *connection)
{ {
int rv; int rv;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
if (connection->write_ordering >= WO_bdev_flush) { if (connection->write_ordering >= WO_bdev_flush) {
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (!get_ldev(device)) if (!get_ldev(device))
continue; continue;
kref_get(&device->kref); kref_get(&device->kref);
...@@ -1260,7 +1263,7 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *connectio ...@@ -1260,7 +1263,7 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *connectio
void drbd_bump_write_ordering(struct drbd_connection *connection, enum write_ordering_e wo) void drbd_bump_write_ordering(struct drbd_connection *connection, enum write_ordering_e wo)
{ {
struct disk_conf *dc; struct disk_conf *dc;
struct drbd_device *device; struct drbd_peer_device *peer_device;
enum write_ordering_e pwo; enum write_ordering_e pwo;
int vnr; int vnr;
static char *write_ordering_str[] = { static char *write_ordering_str[] = {
...@@ -1272,7 +1275,9 @@ void drbd_bump_write_ordering(struct drbd_connection *connection, enum write_ord ...@@ -1272,7 +1275,9 @@ void drbd_bump_write_ordering(struct drbd_connection *connection, enum write_ord
pwo = connection->write_ordering; pwo = connection->write_ordering;
wo = min(pwo, wo); wo = min(pwo, wo);
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (!get_ldev_if_state(device, D_ATTACHING)) if (!get_ldev_if_state(device, D_ATTACHING))
continue; continue;
dc = rcu_dereference(device->ldev->disk_conf); dc = rcu_dereference(device->ldev->disk_conf);
...@@ -1401,11 +1406,13 @@ static void drbd_remove_epoch_entry_interval(struct drbd_device *device, ...@@ -1401,11 +1406,13 @@ static void drbd_remove_epoch_entry_interval(struct drbd_device *device,
static void conn_wait_active_ee_empty(struct drbd_connection *connection) static void conn_wait_active_ee_empty(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
kref_get(&device->kref); kref_get(&device->kref);
rcu_read_unlock(); rcu_read_unlock();
drbd_wait_ee_list_empty(device, &device->active_ee); drbd_wait_ee_list_empty(device, &device->active_ee);
...@@ -4436,7 +4443,7 @@ void conn_flush_workqueue(struct drbd_connection *connection) ...@@ -4436,7 +4443,7 @@ void conn_flush_workqueue(struct drbd_connection *connection)
static void conn_disconnect(struct drbd_connection *connection) static void conn_disconnect(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
enum drbd_conns oc; enum drbd_conns oc;
int vnr; int vnr;
...@@ -4455,11 +4462,12 @@ static void conn_disconnect(struct drbd_connection *connection) ...@@ -4455,11 +4462,12 @@ static void conn_disconnect(struct drbd_connection *connection)
drbd_free_sock(connection); drbd_free_sock(connection);
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
kref_get(&device->kref); kref_get(&device->kref);
rcu_read_unlock(); rcu_read_unlock();
drbd_disconnected(device); drbd_disconnected(device);
kref_put(&device->kref, &drbd_destroy_device); kref_put(&device->kref, drbd_destroy_device);
rcu_read_lock(); rcu_read_lock();
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -5111,13 +5119,15 @@ static int got_NegRSDReply(struct drbd_connection *connection, struct packet_inf ...@@ -5111,13 +5119,15 @@ static int got_NegRSDReply(struct drbd_connection *connection, struct packet_inf
static int got_BarrierAck(struct drbd_connection *connection, struct packet_info *pi) static int got_BarrierAck(struct drbd_connection *connection, struct packet_info *pi)
{ {
struct p_barrier_ack *p = pi->data; struct p_barrier_ack *p = pi->data;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
tl_release(connection, p->barrier, be32_to_cpu(p->set_size)); tl_release(connection, p->barrier, be32_to_cpu(p->set_size));
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (device->state.conn == C_AHEAD && if (device->state.conn == C_AHEAD &&
atomic_read(&device->ap_in_flight) == 0 && atomic_read(&device->ap_in_flight) == 0 &&
!test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &device->flags)) { !test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &device->flags)) {
...@@ -5187,7 +5197,7 @@ static int got_skip(struct drbd_connection *connection, struct packet_info *pi) ...@@ -5187,7 +5197,7 @@ static int got_skip(struct drbd_connection *connection, struct packet_info *pi)
static int connection_finish_peer_reqs(struct drbd_connection *connection) static int connection_finish_peer_reqs(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr, not_empty = 0; int vnr, not_empty = 0;
do { do {
...@@ -5195,7 +5205,8 @@ static int connection_finish_peer_reqs(struct drbd_connection *connection) ...@@ -5195,7 +5205,8 @@ static int connection_finish_peer_reqs(struct drbd_connection *connection)
flush_signals(current); flush_signals(current);
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
kref_get(&device->kref); kref_get(&device->kref);
rcu_read_unlock(); rcu_read_unlock();
if (drbd_finish_peer_reqs(device)) { if (drbd_finish_peer_reqs(device)) {
...@@ -5208,7 +5219,8 @@ static int connection_finish_peer_reqs(struct drbd_connection *connection) ...@@ -5208,7 +5219,8 @@ static int connection_finish_peer_reqs(struct drbd_connection *connection)
set_bit(SIGNAL_ASENDER, &connection->flags); set_bit(SIGNAL_ASENDER, &connection->flags);
spin_lock_irq(&connection->req_lock); spin_lock_irq(&connection->req_lock);
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
not_empty = !list_empty(&device->done_ee); not_empty = !list_empty(&device->done_ee);
if (not_empty) if (not_empty)
break; break;
......
...@@ -63,12 +63,13 @@ static inline bool is_susp(union drbd_state s) ...@@ -63,12 +63,13 @@ static inline bool is_susp(union drbd_state s)
bool conn_all_vols_unconf(struct drbd_connection *connection) bool conn_all_vols_unconf(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
bool rv = true; bool rv = true;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (device->state.disk != D_DISKLESS || if (device->state.disk != D_DISKLESS ||
device->state.conn != C_STANDALONE || device->state.conn != C_STANDALONE ||
device->state.role != R_SECONDARY) { device->state.role != R_SECONDARY) {
...@@ -103,12 +104,14 @@ static enum drbd_role min_role(enum drbd_role role1, enum drbd_role role2) ...@@ -103,12 +104,14 @@ static enum drbd_role min_role(enum drbd_role role1, enum drbd_role role2)
enum drbd_role conn_highest_role(struct drbd_connection *connection) enum drbd_role conn_highest_role(struct drbd_connection *connection)
{ {
enum drbd_role role = R_UNKNOWN; enum drbd_role role = R_UNKNOWN;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
role = max_role(role, device->state.role); role = max_role(role, device->state.role);
}
rcu_read_unlock(); rcu_read_unlock();
return role; return role;
...@@ -117,12 +120,14 @@ enum drbd_role conn_highest_role(struct drbd_connection *connection) ...@@ -117,12 +120,14 @@ enum drbd_role conn_highest_role(struct drbd_connection *connection)
enum drbd_role conn_highest_peer(struct drbd_connection *connection) enum drbd_role conn_highest_peer(struct drbd_connection *connection)
{ {
enum drbd_role peer = R_UNKNOWN; enum drbd_role peer = R_UNKNOWN;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
peer = max_role(peer, device->state.peer); peer = max_role(peer, device->state.peer);
}
rcu_read_unlock(); rcu_read_unlock();
return peer; return peer;
...@@ -131,12 +136,14 @@ enum drbd_role conn_highest_peer(struct drbd_connection *connection) ...@@ -131,12 +136,14 @@ enum drbd_role conn_highest_peer(struct drbd_connection *connection)
enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection) enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection)
{ {
enum drbd_disk_state ds = D_DISKLESS; enum drbd_disk_state ds = D_DISKLESS;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
ds = max_t(enum drbd_disk_state, ds, device->state.disk); ds = max_t(enum drbd_disk_state, ds, device->state.disk);
}
rcu_read_unlock(); rcu_read_unlock();
return ds; return ds;
...@@ -145,12 +152,14 @@ enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection) ...@@ -145,12 +152,14 @@ enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection)
enum drbd_disk_state conn_lowest_disk(struct drbd_connection *connection) enum drbd_disk_state conn_lowest_disk(struct drbd_connection *connection)
{ {
enum drbd_disk_state ds = D_MASK; enum drbd_disk_state ds = D_MASK;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
ds = min_t(enum drbd_disk_state, ds, device->state.disk); ds = min_t(enum drbd_disk_state, ds, device->state.disk);
}
rcu_read_unlock(); rcu_read_unlock();
return ds; return ds;
...@@ -159,12 +168,14 @@ enum drbd_disk_state conn_lowest_disk(struct drbd_connection *connection) ...@@ -159,12 +168,14 @@ enum drbd_disk_state conn_lowest_disk(struct drbd_connection *connection)
enum drbd_disk_state conn_highest_pdsk(struct drbd_connection *connection) enum drbd_disk_state conn_highest_pdsk(struct drbd_connection *connection)
{ {
enum drbd_disk_state ds = D_DISKLESS; enum drbd_disk_state ds = D_DISKLESS;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
ds = max_t(enum drbd_disk_state, ds, device->state.pdsk); ds = max_t(enum drbd_disk_state, ds, device->state.pdsk);
}
rcu_read_unlock(); rcu_read_unlock();
return ds; return ds;
...@@ -173,12 +184,14 @@ enum drbd_disk_state conn_highest_pdsk(struct drbd_connection *connection) ...@@ -173,12 +184,14 @@ enum drbd_disk_state conn_highest_pdsk(struct drbd_connection *connection)
enum drbd_conns conn_lowest_conn(struct drbd_connection *connection) enum drbd_conns conn_lowest_conn(struct drbd_connection *connection)
{ {
enum drbd_conns conn = C_MASK; enum drbd_conns conn = C_MASK;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
conn = min_t(enum drbd_conns, conn, device->state.conn); conn = min_t(enum drbd_conns, conn, device->state.conn);
}
rcu_read_unlock(); rcu_read_unlock();
return conn; return conn;
...@@ -186,13 +199,13 @@ enum drbd_conns conn_lowest_conn(struct drbd_connection *connection) ...@@ -186,13 +199,13 @@ enum drbd_conns conn_lowest_conn(struct drbd_connection *connection)
static bool no_peer_wf_report_params(struct drbd_connection *connection) static bool no_peer_wf_report_params(struct drbd_connection *connection)
{ {
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
bool rv = true; bool rv = true;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
if (device->state.conn == C_WF_REPORT_PARAMS) { if (peer_device->device->state.conn == C_WF_REPORT_PARAMS) {
rv = false; rv = false;
break; break;
} }
...@@ -1256,12 +1269,12 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1256,12 +1269,12 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
spin_lock_irq(&connection->req_lock); spin_lock_irq(&connection->req_lock);
if (connection->susp_fen && conn_lowest_conn(connection) >= C_CONNECTED) { if (connection->susp_fen && conn_lowest_conn(connection) >= C_CONNECTED) {
/* case2: The connection was established again: */ /* case2: The connection was established again: */
struct drbd_device *odev; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, odev, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
clear_bit(NEW_CUR_UUID, &odev->flags); clear_bit(NEW_CUR_UUID, &peer_device->device->flags);
rcu_read_unlock(); rcu_read_unlock();
_tl_restart(connection, RESEND); _tl_restart(connection, RESEND);
_conn_request_state(connection, _conn_request_state(connection,
...@@ -1530,7 +1543,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused) ...@@ -1530,7 +1543,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
struct drbd_connection *connection = w->connection; struct drbd_connection *connection = w->connection;
enum drbd_conns oc = acscw->oc; enum drbd_conns oc = acscw->oc;
union drbd_state ns_max = acscw->ns_max; union drbd_state ns_max = acscw->ns_max;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
kfree(acscw); kfree(acscw);
...@@ -1558,7 +1571,8 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused) ...@@ -1558,7 +1571,8 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
/* case1: The outdate peer handler is successful: */ /* case1: The outdate peer handler is successful: */
if (ns_max.pdsk <= D_OUTDATED) { if (ns_max.pdsk <= D_OUTDATED) {
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
if (test_bit(NEW_CUR_UUID, &device->flags)) { if (test_bit(NEW_CUR_UUID, &device->flags)) {
drbd_uuid_new_current(device); drbd_uuid_new_current(device);
clear_bit(NEW_CUR_UUID, &device->flags); clear_bit(NEW_CUR_UUID, &device->flags);
...@@ -1584,7 +1598,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused) ...@@ -1584,7 +1598,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
void conn_old_common_state(struct drbd_connection *connection, union drbd_state *pcs, enum chg_state_flags *pf) void conn_old_common_state(struct drbd_connection *connection, union drbd_state *pcs, enum chg_state_flags *pf)
{ {
enum chg_state_flags flags = ~0; enum chg_state_flags flags = ~0;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr, first_vol = 1; int vnr, first_vol = 1;
union drbd_dev_state os, cs = { union drbd_dev_state os, cs = {
{ .role = R_SECONDARY, { .role = R_SECONDARY,
...@@ -1595,7 +1609,8 @@ void conn_old_common_state(struct drbd_connection *connection, union drbd_state ...@@ -1595,7 +1609,8 @@ void conn_old_common_state(struct drbd_connection *connection, union drbd_state
} }; } };
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
os = device->state; os = device->state;
if (first_vol) { if (first_vol) {
...@@ -1632,11 +1647,12 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma ...@@ -1632,11 +1647,12 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma
{ {
enum drbd_state_rv rv = SS_SUCCESS; enum drbd_state_rv rv = SS_SUCCESS;
union drbd_state ns, os; union drbd_state ns, os;
struct drbd_device *device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
os = drbd_read_state(device); os = drbd_read_state(device);
ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL); ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL);
...@@ -1647,10 +1663,8 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma ...@@ -1647,10 +1663,8 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma
continue; continue;
rv = is_valid_transition(os, ns); rv = is_valid_transition(os, ns);
if (rv < SS_SUCCESS)
break;
if (!(flags & CS_HARD)) { if (rv >= SS_SUCCESS && !(flags & CS_HARD)) {
rv = is_valid_state(device, ns); rv = is_valid_state(device, ns);
if (rv < SS_SUCCESS) { if (rv < SS_SUCCESS) {
if (is_valid_state(device, os) == rv) if (is_valid_state(device, os) == rv)
...@@ -1658,14 +1672,15 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma ...@@ -1658,14 +1672,15 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma
} else } else
rv = is_valid_soft_transition(os, ns, connection); rv = is_valid_soft_transition(os, ns, connection);
} }
if (rv < SS_SUCCESS)
if (rv < SS_SUCCESS) {
if (flags & CS_VERBOSE)
print_st_err(device, os, ns, rv);
break; break;
}
} }
rcu_read_unlock(); rcu_read_unlock();
if (rv < SS_SUCCESS && flags & CS_VERBOSE)
print_st_err(device, os, ns, rv);
return rv; return rv;
} }
...@@ -1681,7 +1696,7 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union ...@@ -1681,7 +1696,7 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union
.disk = D_MASK, .disk = D_MASK,
.pdsk = D_MASK .pdsk = D_MASK
} }; } };
struct drbd_device *device; struct drbd_peer_device *peer_device;
enum drbd_state_rv rv; enum drbd_state_rv rv;
int vnr, number_of_volumes = 0; int vnr, number_of_volumes = 0;
...@@ -1696,7 +1711,8 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union ...@@ -1696,7 +1711,8 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union
} }
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
number_of_volumes++; number_of_volumes++;
os = drbd_read_state(device); os = drbd_read_state(device);
ns = apply_mask_val(os, mask, val); ns = apply_mask_val(os, mask, val);
......
...@@ -1890,7 +1890,7 @@ int drbd_worker(struct drbd_thread *thi) ...@@ -1890,7 +1890,7 @@ int drbd_worker(struct drbd_thread *thi)
{ {
struct drbd_connection *connection = thi->connection; struct drbd_connection *connection = thi->connection;
struct drbd_work *w = NULL; struct drbd_work *w = NULL;
struct drbd_device *device; struct drbd_peer_device *peer_device;
LIST_HEAD(work_list); LIST_HEAD(work_list);
int vnr; int vnr;
...@@ -1934,7 +1934,8 @@ int drbd_worker(struct drbd_thread *thi) ...@@ -1934,7 +1934,8 @@ int drbd_worker(struct drbd_thread *thi)
} while (!list_empty(&work_list)); } while (!list_empty(&work_list));
rcu_read_lock(); rcu_read_lock();
idr_for_each_entry(&connection->volumes, device, vnr) { idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
D_ASSERT(device->state.disk == D_DISKLESS && device->state.conn == C_STANDALONE); D_ASSERT(device->state.disk == D_DISKLESS && device->state.conn == C_STANDALONE);
kref_get(&device->kref); kref_get(&device->kref);
rcu_read_unlock(); rcu_read_unlock();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment