Skip to content

Commit

Permalink
drbd: Turn connection->volumes into connection->peer_devices
Browse files Browse the repository at this point in the history
Let connection->peer_devices point to peer devices; connection->volumes was
pointing to devices.

Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
  • Loading branch information
Andreas Gruenbacher authored and Philipp Reisner committed Feb 17, 2014
1 parent eb6bea6 commit c06ece6
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 92 deletions.
7 changes: 5 additions & 2 deletions drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ struct drbd_connection {
struct list_head connections;
struct drbd_resource *resource;
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 */
unsigned susp:1; /* IO suspended by user */
unsigned susp_nod:1; /* IO suspended because no data */
Expand Down Expand Up @@ -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)
{
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;
}

/*
Expand Down
27 changes: 15 additions & 12 deletions drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct drbd_device *device;
int vnr = 0, m;
struct drbd_peer_device *peer_device;
int vnr = 0, minor = -1;

rcu_read_lock();
device = idr_get_next(&connection->volumes, &vnr);
m = device ? device_to_minor(device) : -1;
peer_device = idr_get_next(&connection->peer_devices, &vnr);
if (peer_device)
minor = device_to_minor(peer_device->device);
rcu_read_unlock();

return m;
return minor;
}

#ifdef CONFIG_SMP
Expand Down Expand Up @@ -2590,7 +2591,7 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
spin_lock_init(&connection->req_lock);
mutex_init(&connection->conf_update);
init_waitqueue_head(&connection->ping_wait);
idr_init(&connection->volumes);
idr_init(&connection->peer_devices);

drbd_init_workqueue(&connection->sender_work);
mutex_init(&connection->data.mutex);
Expand Down Expand Up @@ -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));
kfree(connection->current_epoch);

idr_destroy(&connection->volumes);
idr_destroy(&connection->peer_devices);

free_cpumask_var(connection->cpu_mask);
drbd_free_socket(&connection->meta);
Expand Down Expand Up @@ -2760,7 +2761,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne
}
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 == -ENOSPC) {
err = ERR_INVALID_REQUEST;
Expand All @@ -2786,7 +2787,7 @@ enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigne
return NO_ERROR;

out_idr_remove_vol:
idr_remove(&connection->volumes, vnr);
idr_remove(&connection->peer_devices, vnr);
out_idr_remove_from_resource:
idr_remove(&resource->devices, vnr);
out_idr_remove_minor:
Expand Down Expand Up @@ -2815,7 +2816,7 @@ void drbd_delete_minor(struct drbd_device *device)
int refs = 3;

for_each_connection(connection, resource) {
idr_remove(&connection->volumes, device->vnr);
idr_remove(&connection->peer_devices, device->vnr);
refs++;
}
idr_remove(&resource->devices, device->vnr);
Expand Down Expand Up @@ -2938,11 +2939,13 @@ void drbd_free_sock(struct drbd_connection *connection)

void conn_md_sync(struct drbd_connection *connection)
{
struct drbd_device *device;
struct drbd_peer_device *peer_device;
int vnr;

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);
rcu_read_unlock();
drbd_md_sync(device);
Expand Down
59 changes: 34 additions & 25 deletions drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
enum drbd_fencing_p fp = FP_NOT_AVAIL;
struct drbd_device *device;
struct drbd_peer_device *peer_device;
int vnr;

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)) {
fp = max_t(enum drbd_fencing_p, fp,
rcu_dereference(device->ldev->disk_conf)->fencing);
struct disk_conf *disk_conf =
rcu_dereference(peer_device->device->ldev->disk_conf);
fp = max_t(enum drbd_fencing_p, fp, disk_conf->fencing);
put_ldev(device);
}
}
Expand Down Expand Up @@ -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)
{
struct drbd_device *device;
struct drbd_peer_device *peer_device;
bool rv = false;
int vnr;

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 ||
device->state.conn == C_SYNC_TARGET ||
device->state.conn == C_PAUSED_SYNC_S ||
Expand All @@ -1899,12 +1902,13 @@ static bool conn_resync_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;
int vnr;

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 ||
device->state.conn == C_VERIFY_T) {
rv = true;
Expand All @@ -1919,7 +1923,7 @@ static bool conn_ov_running(struct drbd_connection *connection)
static enum drbd_ret_code
_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;

if (old_conf && connection->cstate == C_WF_REPORT_PARAMS && connection->agreed_pro_version < 100) {
Expand All @@ -1942,7 +1946,8 @@ _check_net_options(struct drbd_connection *connection, struct net_conf *old_conf
(new_conf->wire_protocol != DRBD_PROT_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)) {
enum drbd_fencing_p fp = rcu_dereference(device->ldev->disk_conf)->fencing;
put_ldev(device);
Expand All @@ -1963,15 +1968,16 @@ static enum drbd_ret_code
check_net_options(struct drbd_connection *connection, struct net_conf *new_conf)
{
static enum drbd_ret_code rv;
struct drbd_device *device;
struct drbd_peer_device *peer_device;
int i;

rcu_read_lock();
rv = _check_net_options(connection, rcu_dereference(connection->net_conf), new_conf);
rcu_read_unlock();

/* 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 (drbd_bm_init(device))
return ERR_NOMEM;
Expand Down Expand Up @@ -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)
{
struct drbd_device *device;
struct drbd_peer_device *peer_device;
struct net_conf *old_conf, *new_conf = NULL;
struct crypto crypto = { };
struct drbd_resource *resource;
Expand Down Expand Up @@ -2256,7 +2262,8 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
mutex_unlock(&connection->conf_update);

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->recv_cnt = 0;
}
Expand Down Expand Up @@ -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)
{
struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct drbd_genlmsghdr *dh;
struct drbd_resource *pos = (struct drbd_resource *)cb->args[0];
Expand All @@ -2926,7 +2934,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
/* Open coded, deferred, iteration:
* for_each_resource_safe(resource, tmp, &drbd_resources) {
* connection = "first connection of resource";
* idr_for_each_entry(&connection->volumes, device, i) {
* idr_for_each_entry(&connection->peer_devices, peer_device, i) {
* ...
* }
* }
Expand Down Expand Up @@ -2962,8 +2970,8 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
if (resource) {
next_resource:
connection = first_connection(resource);
device = idr_get_next(&connection->volumes, &volume);
if (!device) {
peer_device = idr_get_next(&connection->peer_devices, &volume);
if (!peer_device) {
/* No more volumes to dump on this resource.
* Advance resource iterator. */
pos = list_entry_rcu(resource->resources.next,
Expand All @@ -2987,7 +2995,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
if (!dh)
goto out;

if (!device) {
if (!peer_device) {
/* This is a connection without a single volume.
* Suprisingly enough, it may have a network
* configuration. */
Expand All @@ -3002,6 +3010,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
goto done;
}

device = peer_device->device;
D_ASSERT(device->vnr == volume);
D_ASSERT(first_peer_device(device)->connection == connection);

Expand Down Expand Up @@ -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 retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */
struct drbd_device *device;
struct drbd_peer_device *peer_device;
unsigned i;

retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
Expand All @@ -3369,8 +3378,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
goto out;

/* demote */
idr_for_each_entry(&adm_ctx.connection->volumes, device, i) {
retcode = drbd_set_role(device, R_SECONDARY, 0);
idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0);
if (retcode < SS_SUCCESS) {
drbd_msg_put_info("failed to demote");
goto out;
Expand All @@ -3384,8 +3393,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
}

/* detach */
idr_for_each_entry(&adm_ctx.connection->volumes, device, i) {
retcode = adm_detach(device, 0);
idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
retcode = adm_detach(peer_device->device, 0);
if (retcode < SS_SUCCESS || retcode > NO_ERROR) {
drbd_msg_put_info("failed to detach");
goto out;
Expand All @@ -3400,8 +3409,8 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
/* Now, nothing can fail anymore */

/* delete volumes */
idr_for_each_entry(&adm_ctx.connection->volumes, device, i) {
retcode = adm_del_minor(device);
idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
retcode = adm_del_minor(peer_device->device);
if (retcode != NO_ERROR) {
/* "can not happen" */
drbd_msg_put_info("failed to delete volume");
Expand Down
Loading

0 comments on commit c06ece6

Please sign in to comment.