* [PATCH 01/27] drbd: Rename net_conf variables old_conf -> old_net_conf and new_conf -> new_net_conf
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 02/27] drbd: Iterate over all connections Philipp Reisner
` (25 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 92 +++++++++++++++++++++---------------------
1 file changed, 46 insertions(+), 46 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index abe96b0..a07b65a 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1921,29 +1921,29 @@ 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)
+_check_net_options(struct drbd_connection *connection, struct net_conf *old_net_conf, struct net_conf *new_net_conf)
{
struct drbd_peer_device *peer_device;
int i;
- if (old_conf && connection->cstate == C_WF_REPORT_PARAMS && connection->agreed_pro_version < 100) {
- if (new_conf->wire_protocol != old_conf->wire_protocol)
+ if (old_net_conf && connection->cstate == C_WF_REPORT_PARAMS && connection->agreed_pro_version < 100) {
+ if (new_net_conf->wire_protocol != old_net_conf->wire_protocol)
return ERR_NEED_APV_100;
- if (new_conf->two_primaries != old_conf->two_primaries)
+ if (new_net_conf->two_primaries != old_net_conf->two_primaries)
return ERR_NEED_APV_100;
- if (strcmp(new_conf->integrity_alg, old_conf->integrity_alg))
+ if (strcmp(new_net_conf->integrity_alg, old_net_conf->integrity_alg))
return ERR_NEED_APV_100;
}
- if (!new_conf->two_primaries &&
+ if (!new_net_conf->two_primaries &&
conn_highest_role(connection) == R_PRIMARY &&
conn_highest_peer(connection) == R_PRIMARY)
return ERR_NEED_ALLOW_TWO_PRI;
- if (new_conf->two_primaries &&
- (new_conf->wire_protocol != DRBD_PROT_C))
+ if (new_net_conf->two_primaries &&
+ (new_net_conf->wire_protocol != DRBD_PROT_C))
return ERR_NOT_PROTO_C;
idr_for_each_entry(&connection->peer_devices, peer_device, i) {
@@ -1951,28 +1951,28 @@ _check_net_options(struct drbd_connection *connection, struct net_conf *old_conf
if (get_ldev(device)) {
enum drbd_fencing_p fp = rcu_dereference(device->ldev->disk_conf)->fencing;
put_ldev(device);
- if (new_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH)
+ if (new_net_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH)
return ERR_STONITH_AND_PROT_A;
}
- if (device->state.role == R_PRIMARY && new_conf->discard_my_data)
+ if (device->state.role == R_PRIMARY && new_net_conf->discard_my_data)
return ERR_DISCARD_IMPOSSIBLE;
}
- if (new_conf->on_congestion != OC_BLOCK && new_conf->wire_protocol != DRBD_PROT_A)
+ if (new_net_conf->on_congestion != OC_BLOCK && new_net_conf->wire_protocol != DRBD_PROT_A)
return ERR_CONG_NOT_PROTO_A;
return NO_ERROR;
}
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_net_conf)
{
static enum drbd_ret_code rv;
struct drbd_peer_device *peer_device;
int i;
rcu_read_lock();
- rv = _check_net_options(connection, rcu_dereference(connection->net_conf), new_conf);
+ rv = _check_net_options(connection, rcu_dereference(connection->net_conf), new_net_conf);
rcu_read_unlock();
/* connection->volumes protected by genl_lock() here */
@@ -2010,26 +2010,26 @@ alloc_hash(struct crypto_hash **tfm, char *tfm_name, int err_alg)
}
static enum drbd_ret_code
-alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
+alloc_crypto(struct crypto *crypto, struct net_conf *new_net_conf)
{
char hmac_name[CRYPTO_MAX_ALG_NAME];
enum drbd_ret_code rv;
- rv = alloc_hash(&crypto->csums_tfm, new_conf->csums_alg,
+ rv = alloc_hash(&crypto->csums_tfm, new_net_conf->csums_alg,
ERR_CSUMS_ALG);
if (rv != NO_ERROR)
return rv;
- rv = alloc_hash(&crypto->verify_tfm, new_conf->verify_alg,
+ rv = alloc_hash(&crypto->verify_tfm, new_net_conf->verify_alg,
ERR_VERIFY_ALG);
if (rv != NO_ERROR)
return rv;
- rv = alloc_hash(&crypto->integrity_tfm, new_conf->integrity_alg,
+ rv = alloc_hash(&crypto->integrity_tfm, new_net_conf->integrity_alg,
ERR_INTEGRITY_ALG);
if (rv != NO_ERROR)
return rv;
- if (new_conf->cram_hmac_alg[0] != 0) {
+ if (new_net_conf->cram_hmac_alg[0] != 0) {
snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
- new_conf->cram_hmac_alg);
+ new_net_conf->cram_hmac_alg);
rv = alloc_hash(&crypto->cram_hmac_tfm, hmac_name,
ERR_AUTH_ALG);
@@ -2050,7 +2050,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
{
enum drbd_ret_code retcode;
struct drbd_connection *connection;
- struct net_conf *old_conf, *new_conf = NULL;
+ struct net_conf *old_net_conf, *new_net_conf = NULL;
int err;
int ovr; /* online verify running */
int rsr; /* re-sync running */
@@ -2064,8 +2064,8 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
connection = adm_ctx.connection;
- new_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL);
- if (!new_conf) {
+ new_net_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL);
+ if (!new_net_conf) {
retcode = ERR_NOMEM;
goto out;
}
@@ -2074,48 +2074,48 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
mutex_lock(&connection->data.mutex);
mutex_lock(&connection->conf_update);
- old_conf = connection->net_conf;
+ old_net_conf = connection->net_conf;
- if (!old_conf) {
+ if (!old_net_conf) {
drbd_msg_put_info("net conf missing, try connect");
retcode = ERR_INVALID_REQUEST;
goto fail;
}
- *new_conf = *old_conf;
+ *new_net_conf = *old_net_conf;
if (should_set_defaults(info))
- set_net_conf_defaults(new_conf);
+ set_net_conf_defaults(new_net_conf);
- err = net_conf_from_attrs_for_change(new_conf, info);
+ err = net_conf_from_attrs_for_change(new_net_conf, info);
if (err && err != -ENOMSG) {
retcode = ERR_MANDATORY_TAG;
drbd_msg_put_info(from_attrs_err_to_txt(err));
goto fail;
}
- retcode = check_net_options(connection, new_conf);
+ retcode = check_net_options(connection, new_net_conf);
if (retcode != NO_ERROR)
goto fail;
/* re-sync running */
rsr = conn_resync_running(connection);
- if (rsr && strcmp(new_conf->csums_alg, old_conf->csums_alg)) {
+ if (rsr && strcmp(new_net_conf->csums_alg, old_net_conf->csums_alg)) {
retcode = ERR_CSUMS_RESYNC_RUNNING;
goto fail;
}
/* online verify running */
ovr = conn_ov_running(connection);
- if (ovr && strcmp(new_conf->verify_alg, old_conf->verify_alg)) {
+ if (ovr && strcmp(new_net_conf->verify_alg, old_net_conf->verify_alg)) {
retcode = ERR_VERIFY_RUNNING;
goto fail;
}
- retcode = alloc_crypto(&crypto, new_conf);
+ retcode = alloc_crypto(&crypto, new_net_conf);
if (retcode != NO_ERROR)
goto fail;
- rcu_assign_pointer(connection->net_conf, new_conf);
+ rcu_assign_pointer(connection->net_conf, new_net_conf);
if (!rsr) {
crypto_free_hash(connection->csums_tfm);
@@ -2140,7 +2140,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
mutex_unlock(&connection->conf_update);
mutex_unlock(&connection->data.mutex);
synchronize_rcu();
- kfree(old_conf);
+ kfree(old_net_conf);
if (connection->cstate >= C_WF_REPORT_PARAMS)
drbd_send_sync_param(minor_to_device(conn_lowest_minor(connection)));
@@ -2151,7 +2151,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
mutex_unlock(&connection->conf_update);
mutex_unlock(&connection->data.mutex);
free_crypto(&crypto);
- kfree(new_conf);
+ kfree(new_net_conf);
done:
conn_reconfig_done(connection);
out:
@@ -2162,7 +2162,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_peer_device *peer_device;
- struct net_conf *old_conf, *new_conf = NULL;
+ struct net_conf *old_net_conf, *new_net_conf = NULL;
struct crypto crypto = { };
struct drbd_resource *resource;
struct drbd_connection *connection;
@@ -2212,41 +2212,41 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
}
/* allocation not in the IO path, drbdsetup / netlink process context */
- new_conf = kzalloc(sizeof(*new_conf), GFP_KERNEL);
- if (!new_conf) {
+ new_net_conf = kzalloc(sizeof(*new_net_conf), GFP_KERNEL);
+ if (!new_net_conf) {
retcode = ERR_NOMEM;
goto fail;
}
- set_net_conf_defaults(new_conf);
+ set_net_conf_defaults(new_net_conf);
- err = net_conf_from_attrs(new_conf, info);
+ err = net_conf_from_attrs(new_net_conf, info);
if (err && err != -ENOMSG) {
retcode = ERR_MANDATORY_TAG;
drbd_msg_put_info(from_attrs_err_to_txt(err));
goto fail;
}
- retcode = check_net_options(connection, new_conf);
+ retcode = check_net_options(connection, new_net_conf);
if (retcode != NO_ERROR)
goto fail;
- retcode = alloc_crypto(&crypto, new_conf);
+ retcode = alloc_crypto(&crypto, new_net_conf);
if (retcode != NO_ERROR)
goto fail;
- ((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
+ ((char *)new_net_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
conn_flush_workqueue(connection);
mutex_lock(&connection->conf_update);
- old_conf = connection->net_conf;
- if (old_conf) {
+ old_net_conf = connection->net_conf;
+ if (old_net_conf) {
retcode = ERR_NET_CONFIGURED;
mutex_unlock(&connection->conf_update);
goto fail;
}
- rcu_assign_pointer(connection->net_conf, new_conf);
+ rcu_assign_pointer(connection->net_conf, new_net_conf);
conn_free_crypto(connection);
connection->cram_hmac_tfm = crypto.cram_hmac_tfm;
@@ -2277,7 +2277,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
fail:
free_crypto(&crypto);
- kfree(new_conf);
+ kfree(new_net_conf);
conn_reconfig_done(connection);
out:
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 02/27] drbd: Iterate over all connections
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
2013-12-23 21:50 ` [PATCH 01/27] drbd: Rename net_conf variables old_conf -> old_net_conf and new_conf -> new_net_conf Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 03/27] drbd: drbd_adm_prepare(): Only set adm_ctx.connection when a connection is requested Philipp Reisner
` (24 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
in drbd_adm_down(), drbd_create_device() and drbd_set_role()
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_main.c | 55 +++++++++++++++++++-------------
drivers/block/drbd/drbd_nl.c | 68 ++++++++++++++++++++++------------------
2 files changed, 70 insertions(+), 53 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 6ed09d5..c4aec68 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2663,9 +2663,9 @@ int init_submitter(struct drbd_device *device)
enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr)
{
- struct drbd_connection *connection = first_connection(resource);
+ struct drbd_connection *connection;
struct drbd_device *device;
- struct drbd_peer_device *peer_device;
+ struct drbd_peer_device *peer_device, *tmp_peer_device;
struct gendisk *disk;
struct request_queue *q;
int id;
@@ -2681,18 +2681,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
return ERR_NOMEM;
kref_init(&device->kref);
- peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL);
- if (!peer_device)
- goto out_no_peer_device;
-
- INIT_LIST_HEAD(&device->peer_devices);
- list_add(&peer_device->peer_devices, &device->peer_devices);
kref_get(&resource->kref);
device->resource = resource;
- kref_get(&connection->kref);
- peer_device->connection = connection;
- peer_device->device = device;
-
device->minor = minor;
device->vnr = vnr;
@@ -2763,15 +2753,27 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
}
kref_get(&device->kref);
- id = idr_alloc(&connection->peer_devices, peer_device, vnr, vnr + 1, GFP_KERNEL);
- if (id < 0) {
- if (id == -ENOSPC) {
- err = ERR_INVALID_REQUEST;
- drbd_msg_put_info("requested volume exists already");
+ INIT_LIST_HEAD(&device->peer_devices);
+ for_each_connection(connection, resource) {
+ peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL);
+ if (!peer_device)
+ goto out_idr_remove_from_resource;
+ peer_device->connection = connection;
+ peer_device->device = device;
+
+ list_add(&peer_device->peer_devices, &device->peer_devices);
+ kref_get(&device->kref);
+
+ id = idr_alloc(&connection->peer_devices, peer_device, vnr, vnr + 1, GFP_KERNEL);
+ if (id < 0) {
+ if (id == -ENOSPC) {
+ err = ERR_INVALID_REQUEST;
+ drbd_msg_put_info("requested volume exists already");
+ }
+ goto out_idr_remove_from_resource;
}
- goto out_idr_remove_from_resource;
+ kref_get(&connection->kref);
}
- kref_get(&device->kref);
if (init_submitter(device)) {
err = ERR_NOMEM;
@@ -2782,7 +2784,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
add_disk(disk);
/* inherit the connection state */
- device->state.conn = connection->cstate;
+ device->state.conn = first_connection(resource)->cstate;
if (device->state.conn == C_WF_REPORT_PARAMS)
drbd_connected(device);
@@ -2791,6 +2793,17 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
out_idr_remove_vol:
idr_remove(&connection->peer_devices, vnr);
out_idr_remove_from_resource:
+ for_each_connection(connection, resource) {
+ peer_device = idr_find(&connection->peer_devices, vnr);
+ if (peer_device) {
+ idr_remove(&connection->peer_devices, vnr);
+ kref_put(&connection->kref, drbd_destroy_connection);
+ }
+ }
+ for_each_peer_device_safe(peer_device, tmp_peer_device, device) {
+ list_del(&peer_device->peer_devices);
+ kfree(peer_device);
+ }
idr_remove(&resource->devices, vnr);
out_idr_remove_minor:
idr_remove(&drbd_devices, minor);
@@ -2804,9 +2817,7 @@ out_no_io_page:
out_no_disk:
blk_cleanup_queue(q);
out_no_q:
- kref_put(&connection->kref, drbd_destroy_connection);
kref_put(&resource->kref, drbd_destroy_resource);
-out_no_peer_device:
kfree(device);
return err;
}
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index a07b65a..26051c6 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -560,8 +560,16 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force)
int forced = 0;
union drbd_state mask, val;
- if (new_role == R_PRIMARY)
- request_ping(first_peer_device(device)->connection); /* Detect a dead peer ASAP */
+ if (new_role == R_PRIMARY) {
+ struct drbd_connection *connection;
+
+ /* Detect dead peers as soon as possible. */
+
+ rcu_read_lock();
+ for_each_connection(connection, device->resource)
+ request_ping(connection);
+ rcu_read_unlock();
+ }
mutex_lock(device->state_mutex);
@@ -3387,8 +3395,10 @@ out:
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
{
+ struct drbd_resource *resource;
+ struct drbd_connection *connection;
+ struct drbd_device *device;
int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */
- struct drbd_peer_device *peer_device;
unsigned i;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
@@ -3397,24 +3407,29 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
if (retcode != NO_ERROR)
goto out;
+ resource = adm_ctx.resource;
/* demote */
- idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
- retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0);
+ for_each_connection(connection, resource) {
+ struct drbd_peer_device *peer_device;
+
+ idr_for_each_entry(&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;
+ }
+ }
+
+ retcode = conn_try_disconnect(connection, 0);
if (retcode < SS_SUCCESS) {
- drbd_msg_put_info("failed to demote");
+ drbd_msg_put_info("failed to disconnect");
goto out;
}
}
- retcode = conn_try_disconnect(adm_ctx.connection, 0);
- if (retcode < SS_SUCCESS) {
- drbd_msg_put_info("failed to disconnect");
- goto out;
- }
-
/* detach */
- idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
- retcode = adm_detach(peer_device->device, 0);
+ idr_for_each_entry(&resource->devices, device, i) {
+ retcode = adm_detach(device, 0);
if (retcode < SS_SUCCESS || retcode > NO_ERROR) {
drbd_msg_put_info("failed to detach");
goto out;
@@ -3424,13 +3439,14 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
/* If we reach this, all volumes (of this connection) are Secondary,
* Disconnected, Diskless, aka Unconfigured. Make sure all threads have
* actually stopped, state handling only does drbd_thread_stop_nowait(). */
- drbd_thread_stop(&adm_ctx.connection->worker);
+ for_each_connection(connection, resource)
+ drbd_thread_stop(&connection->worker);
/* Now, nothing can fail anymore */
/* delete volumes */
- idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
- retcode = adm_del_minor(peer_device->device);
+ idr_for_each_entry(&resource->devices, device, i) {
+ retcode = adm_del_minor(device);
if (retcode != NO_ERROR) {
/* "can not happen" */
drbd_msg_put_info("failed to delete volume");
@@ -3438,21 +3454,11 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
}
}
- /* delete connection */
- if (conn_lowest_minor(adm_ctx.connection) < 0) {
- struct drbd_resource *resource = adm_ctx.connection->resource;
-
- list_del_rcu(&resource->resources);
- synchronize_rcu();
- drbd_free_resource(resource);
+ list_del_rcu(&resource->resources);
+ synchronize_rcu();
+ drbd_free_resource(resource);
+ retcode = NO_ERROR;
- retcode = NO_ERROR;
- } else {
- /* "can not happen" */
- retcode = ERR_RES_IN_USE;
- drbd_msg_put_info("failed to delete connection");
- }
- goto out;
out:
drbd_adm_finish(info, retcode);
return 0;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 03/27] drbd: drbd_adm_prepare(): Only set adm_ctx.connection when a connection is requested
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
2013-12-23 21:50 ` [PATCH 01/27] drbd: Rename net_conf variables old_conf -> old_net_conf and new_conf -> new_net_conf Philipp Reisner
2013-12-23 21:50 ` [PATCH 02/27] drbd: Iterate over all connections Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 04/27] drbd: Move conf_mutex from connection to resource Philipp Reisner
` (23 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Also change drbd_adm_connect() to expect a resource after it requested one.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 26051c6..372efd5 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -216,10 +216,6 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info,
adm_ctx.device = minor_to_device(d_in->minor);
if (adm_ctx.resource_name) {
adm_ctx.resource = drbd_find_resource(adm_ctx.resource_name);
- if (adm_ctx.resource) {
- adm_ctx.connection = first_connection(adm_ctx.resource);
- kref_get(&adm_ctx.connection->kref);
- }
}
if (!adm_ctx.device && (flags & DRBD_ADM_NEED_MINOR)) {
@@ -234,7 +230,7 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info,
}
if (flags & DRBD_ADM_NEED_CONNECTION) {
- if (adm_ctx.connection && !(flags & DRBD_ADM_NEED_RESOURCE)) {
+ if (adm_ctx.resource) {
drbd_msg_put_info("no resource name expected");
return ERR_INVALID_REQUEST;
}
@@ -2211,7 +2207,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
}
}
- connection = adm_ctx.connection;
+ connection = first_connection(adm_ctx.resource);
conn_reconfig_start(connection);
if (connection->cstate > C_STANDALONE) {
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 04/27] drbd: Move conf_mutex from connection to resource
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (2 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 03/27] drbd: drbd_adm_prepare(): Only set adm_ctx.connection when a connection is requested Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 05/27] drbd: Move susp, susp_nod, susp_fen " Philipp Reisner
` (22 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 15 +++--
drivers/block/drbd/drbd_main.c | 36 +++++------
drivers/block/drbd/drbd_nl.c | 50 ++++++++--------
drivers/block/drbd/drbd_receiver.c | 116 ++++++++++++++++++------------------
drivers/block/drbd/drbd_req.c | 18 +++---
drivers/block/drbd/drbd_req.h | 4 +-
drivers/block/drbd/drbd_state.c | 48 +++++++--------
drivers/block/drbd/drbd_worker.c | 34 +++++------
8 files changed, 160 insertions(+), 161 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e0b42f0..bdfa1de 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -513,7 +513,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: first_peer_device(device)->connection->conf_update */
+ struct disk_conf *disk_conf; /* RCU, for updates: resource->conf_update */
sector_t known_size; /* last known size of that backing device */
};
@@ -573,6 +573,8 @@ struct drbd_resource {
struct list_head connections;
struct list_head resources;
struct res_opts res_opts;
+ struct mutex conf_update; /* mutex for ready-copy-update of net_conf and disk_conf */
+ spinlock_t req_lock;
};
struct drbd_connection {
@@ -589,7 +591,6 @@ struct drbd_connection {
unsigned long flags;
struct net_conf *net_conf; /* content protected by rcu */
- struct mutex conf_update; /* mutex for ready-copy-update of net_conf and disk_conf */
wait_queue_head_t ping_wait; /* Woken upon reception of a ping, and a state change */
struct sockaddr_storage my_addr;
@@ -603,8 +604,6 @@ struct drbd_connection {
unsigned long last_received; /* in jiffies, either socket */
unsigned int ko_count;
- spinlock_t req_lock;
-
struct list_head transfer_log; /* all requests not yet fully processed */
struct crypto_hash *cram_hmac_tfm;
@@ -1590,9 +1589,9 @@ static inline void drbd_chk_io_error_(struct drbd_device *device,
{
if (error) {
unsigned long flags;
- spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->req_lock, flags);
__drbd_chk_io_error_(device, forcedetach, where);
- spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
}
}
@@ -2064,11 +2063,11 @@ static inline bool inc_ap_bio_cond(struct drbd_device *device)
{
bool rv = false;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
rv = may_inc_ap_bio(device);
if (rv)
atomic_inc(&device->ap_bio_cnt);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
return rv;
}
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c4aec68..43b9141 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -200,7 +200,7 @@ void tl_release(struct drbd_connection *connection, unsigned int barrier_nr,
int expect_epoch = 0;
int expect_size = 0;
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
/* find oldest not yet barrier-acked write request,
* count writes in its epoch. */
@@ -257,12 +257,12 @@ void tl_release(struct drbd_connection *connection, unsigned int barrier_nr,
break;
_req_mod(req, BARRIER_ACKED);
}
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
return;
bail:
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
conn_request_state(connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
}
@@ -286,9 +286,9 @@ void _tl_restart(struct drbd_connection *connection, enum drbd_req_event what)
void tl_restart(struct drbd_connection *connection, enum drbd_req_event what)
{
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
_tl_restart(connection, what);
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
}
/**
@@ -313,7 +313,7 @@ void tl_abort_disk_io(struct drbd_device *device)
struct drbd_connection *connection = first_peer_device(device)->connection;
struct drbd_request *req, *r;
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
list_for_each_entry_safe(req, r, &connection->transfer_log, tl_requests) {
if (!(req->rq_state & RQ_LOCAL_PENDING))
continue;
@@ -321,7 +321,7 @@ void tl_abort_disk_io(struct drbd_device *device)
continue;
_req_mod(req, ABORT_DISK_IO);
}
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
}
static int drbd_thread_setup(void *arg)
@@ -1838,7 +1838,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
int rv = 0;
mutex_lock(&drbd_main_mutex);
- spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->req_lock, flags);
/* to have a stable device->state.role
* and no race with updating open_cnt */
@@ -1851,7 +1851,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
if (!rv)
device->open_cnt++;
- spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
mutex_unlock(&drbd_main_mutex);
return rv;
@@ -2548,6 +2548,8 @@ struct drbd_resource *drbd_create_resource(const char *name)
idr_init(&resource->devices);
INIT_LIST_HEAD(&resource->connections);
list_add_tail_rcu(&resource->resources, &drbd_resources);
+ mutex_init(&resource->conf_update);
+ spin_lock_init(&resource->req_lock);
return resource;
}
@@ -2590,8 +2592,6 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
connection->cstate = C_STANDALONE;
mutex_init(&connection->cstate_mutex);
- spin_lock_init(&connection->req_lock);
- mutex_init(&connection->conf_update);
init_waitqueue_head(&connection->ping_wait);
idr_init(&connection->peer_devices);
@@ -2722,7 +2722,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
blk_queue_merge_bvec(q, drbd_merge_bvec);
- q->queue_lock = &connection->req_lock;
+ q->queue_lock = &resource->req_lock;
device->md_io_page = alloc_page(GFP_KERNEL);
if (!device->md_io_page)
@@ -3283,14 +3283,14 @@ int drbd_md_read(struct drbd_device *device, struct drbd_backing_dev *bdev)
rv = NO_ERROR;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
if (device->state.conn < C_CONNECTED) {
unsigned int peer;
peer = be32_to_cpu(buffer->la_peer_max_bio_size);
peer = max(peer, DRBD_MAX_BIO_SIZE_SAFE);
device->peer_max_bio_size = peer;
}
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
err:
drbd_md_put_buffer(device);
@@ -3579,13 +3579,13 @@ void drbd_queue_bitmap_io(struct drbd_device *device,
device->bm_io_work.why = why;
device->bm_io_work.flags = flags;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
set_bit(BITMAP_IO, &device->flags);
if (atomic_read(&device->ap_bio_cnt) == 0) {
if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w);
}
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
}
/**
@@ -3753,10 +3753,10 @@ int drbd_wait_misc(struct drbd_device *device, struct drbd_interval *i)
/* Indicate to wake up device->misc_wait on progress. */
i->waiting = true;
prepare_to_wait(&device->misc_wait, &wait, TASK_INTERRUPTIBLE);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
timeout = schedule_timeout(timeout);
finish_wait(&device->misc_wait, &wait);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
if (!timeout || device->state.conn < C_CONNECTED)
return -ETIMEDOUT;
if (signal_pending(current))
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 372efd5..5ccfebb 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -443,9 +443,9 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
return false;
}
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
connect_cnt = connection->connect_cnt;
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
fp = highest_fencing_policy(connection);
switch (fp) {
@@ -510,7 +510,7 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
conn_request_state(connection, mask, val, CS_VERBOSE);
here, because we might were able to re-establish the connection in the
meantime. */
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
if (connection->cstate < C_WF_REPORT_PARAMS && !test_bit(STATE_SENT, &connection->flags)) {
if (connection->connect_cnt != connect_cnt)
/* In case the connection was established and droped
@@ -519,7 +519,7 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
else
_conn_request_state(connection, mask, val, CS_VERBOSE);
}
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
return conn_highest_pdsk(connection) <= D_OUTDATED;
}
@@ -654,11 +654,11 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force)
put_ldev(device);
}
} else {
- mutex_lock(&first_peer_device(device)->connection->conf_update);
+ mutex_lock(&device->resource->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(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&device->resource->conf_update);
set_disk_ro(device->vdisk, false);
if (get_ldev(device)) {
@@ -1188,10 +1188,10 @@ static void conn_reconfig_start(struct drbd_connection *connection)
static void conn_reconfig_done(struct drbd_connection *connection)
{
bool stop_threads;
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
stop_threads = conn_all_vols_unconf(connection) &&
connection->cstate == C_STANDALONE;
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
if (stop_threads) {
/* asender is implicitly stopped by receiver
* in conn_disconnect() */
@@ -1211,10 +1211,10 @@ static void drbd_suspend_al(struct drbd_device *device)
}
drbd_al_shrink(device);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
if (device->state.conn < C_CONNECTED)
s = !test_and_set_bit(AL_SUSPENDED, &device->flags);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
lc_unlock(device->act_log);
if (s)
@@ -1285,7 +1285,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- mutex_lock(&first_peer_device(device)->connection->conf_update);
+ mutex_lock(&device->resource->conf_update);
old_disk_conf = device->ldev->disk_conf;
*new_disk_conf = *old_disk_conf;
if (should_set_defaults(info))
@@ -1348,7 +1348,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(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&device->resource->conf_update);
if (new_disk_conf->al_updates)
device->ldev->md.flags &= ~MDF_AL_DISABLED;
@@ -1374,7 +1374,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
goto success;
fail_unlock:
- mutex_unlock(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&device->resource->conf_update);
fail:
kfree(new_disk_conf);
kfree(new_plan);
@@ -1724,7 +1724,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(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
os = drbd_read_state(device);
ns = os;
/* If MDF_CONSISTENT is not set go into inconsistent state,
@@ -1776,7 +1776,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(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (rv < SS_SUCCESS)
goto force_diskless_dec;
@@ -2077,7 +2077,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
conn_reconfig_start(connection);
mutex_lock(&connection->data.mutex);
- mutex_lock(&connection->conf_update);
+ mutex_lock(&connection->resource->conf_update);
old_net_conf = connection->net_conf;
if (!old_net_conf) {
@@ -2141,7 +2141,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
crypto_free_hash(connection->cram_hmac_tfm);
connection->cram_hmac_tfm = crypto.cram_hmac_tfm;
- mutex_unlock(&connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
mutex_unlock(&connection->data.mutex);
synchronize_rcu();
kfree(old_net_conf);
@@ -2152,7 +2152,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
goto done;
fail:
- mutex_unlock(&connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
mutex_unlock(&connection->data.mutex);
free_crypto(&crypto);
kfree(new_net_conf);
@@ -2243,11 +2243,11 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
conn_flush_workqueue(connection);
- mutex_lock(&connection->conf_update);
+ mutex_lock(&adm_ctx.resource->conf_update);
old_net_conf = connection->net_conf;
if (old_net_conf) {
retcode = ERR_NET_CONFIGURED;
- mutex_unlock(&connection->conf_update);
+ mutex_unlock(&adm_ctx.resource->conf_update);
goto fail;
}
rcu_assign_pointer(connection->net_conf, new_net_conf);
@@ -2263,7 +2263,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
connection->peer_addr_len = nla_len(adm_ctx.peer_addr);
memcpy(&connection->peer_addr, nla_data(adm_ctx.peer_addr), connection->peer_addr_len);
- mutex_unlock(&connection->conf_update);
+ mutex_unlock(&adm_ctx.resource->conf_update);
rcu_read_lock();
idr_for_each_entry(&connection->peer_devices, peer_device, i) {
@@ -2486,12 +2486,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(&first_peer_device(device)->connection->conf_update);
+ mutex_lock(&device->resource->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(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&device->resource->conf_update);
synchronize_rcu();
kfree(old_disk_conf);
}
@@ -3248,10 +3248,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(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
_drbd_set_state(_NS2(device, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
CS_VERBOSE, NULL);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
}
}
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 90aa3aa..217ed11 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -221,9 +221,9 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
LIST_HEAD(reclaimed);
struct drbd_peer_request *peer_req, *t;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
reclaim_finished_net_peer_reqs(device, &reclaimed);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
drbd_free_net_peer_req(device, peer_req);
@@ -288,7 +288,7 @@ struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number,
}
/* Must not be used from irq, as that may deadlock: see drbd_alloc_pages.
- * Is also used from inside an other spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ * Is also used from inside an other spin_lock_irq(&resource->req_lock);
* Either links the page chain back to the global pool,
* or returns all pages to the system. */
static void drbd_free_pages(struct drbd_device *device, struct page *page, int is_net)
@@ -396,9 +396,9 @@ int drbd_free_peer_reqs(struct drbd_device *device, struct list_head *list)
int count = 0;
int is_net = list == &device->net_ee;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_splice_init(list, &work_list);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
__drbd_free_peer_req(device, peer_req, is_net);
@@ -417,10 +417,10 @@ static int drbd_finish_peer_reqs(struct drbd_device *device)
struct drbd_peer_request *peer_req, *t;
int err = 0;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
reclaim_finished_net_peer_reqs(device, &reclaimed);
list_splice_init(&device->done_ee, &work_list);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
drbd_free_net_peer_req(device, peer_req);
@@ -452,19 +452,19 @@ static void _drbd_wait_ee_list_empty(struct drbd_device *device,
* and calling prepare_to_wait in the fast path */
while (!list_empty(head)) {
prepare_to_wait(&device->ee_wait, &wait, TASK_UNINTERRUPTIBLE);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
io_schedule();
finish_wait(&device->ee_wait, &wait);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
}
}
static void drbd_wait_ee_list_empty(struct drbd_device *device,
struct list_head *head)
{
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
_drbd_wait_ee_list_empty(device, head);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
}
static int drbd_recv_short(struct socket *sock, void *buf, size_t size, int flags)
@@ -1072,13 +1072,13 @@ randomize:
drbd_thread_start(&connection->asender);
- mutex_lock(&connection->conf_update);
+ mutex_lock(&connection->resource->conf_update);
/* The discard_my_data flag is a single-shot modifier to the next
* connection attempt, the handshake of which is now well underway.
* No need for rcu style copying of the whole struct
* just to clear a single value. */
connection->net_conf->discard_my_data = 0;
- mutex_unlock(&connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
return h;
@@ -1692,9 +1692,9 @@ static int recv_resync_read(struct drbd_device *device, sector_t sector, int dat
peer_req->w.cb = e_end_resync_block;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_add(&peer_req->w.list, &device->sync_ee);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
atomic_add(data_size >> 9, &device->rs_sect_ev);
if (drbd_submit_peer_request(device, peer_req, WRITE, DRBD_FAULT_RS_WR) == 0)
@@ -1702,9 +1702,9 @@ static int recv_resync_read(struct drbd_device *device, sector_t sector, int dat
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req);
fail:
@@ -1743,9 +1743,9 @@ static int receive_DataReply(struct drbd_connection *connection, struct packet_i
sector = be64_to_cpu(p->sector);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
req = find_request(device, &device->read_requests, p->block_id, sector, false, __func__);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (unlikely(!req))
return -EIO;
@@ -1844,12 +1844,12 @@ static int e_end_block(struct drbd_work *w, int cancel)
/* we delete from the conflict detection hash _after_ we sent out the
* P_WRITE_ACK / P_NEG_ACK, to get the sequence number right. */
if (peer_req->flags & EE_IN_INTERVAL_TREE) {
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
D_ASSERT(device, !drbd_interval_empty(&peer_req->i));
drbd_remove_epoch_entry_interval(device, peer_req);
if (peer_req->flags & EE_RESTART_REQUESTS)
restart_conflicting_writes(device, sector, peer_req->i.size);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
} else
D_ASSERT(device, drbd_interval_empty(&peer_req->i));
@@ -1925,7 +1925,7 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee
struct drbd_peer_request *rs_req;
bool rv = 0;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_for_each_entry(rs_req, &device->sync_ee, w.list) {
if (overlaps(peer_req->i.sector, peer_req->i.size,
rs_req->i.sector, rs_req->i.size)) {
@@ -1933,7 +1933,7 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee
break;
}
}
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
return rv;
}
@@ -2034,10 +2034,10 @@ static void fail_postponed_requests(struct drbd_device *device, sector_t sector,
continue;
req->rq_state &= ~RQ_POSTPONED;
__req_mod(req, NEG_ACKED, &m);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (m.bio)
complete_master_bio(device, &m);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
goto repeat;
}
}
@@ -2218,10 +2218,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
err = wait_for_and_update_peer_seq(device, peer_seq);
if (err)
goto out_interrupted;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
err = handle_write_conflicts(device, peer_req);
if (err) {
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (err == -ENOENT) {
put_ldev(device);
return 0;
@@ -2230,10 +2230,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
}
} else {
update_peer_seq(device, peer_seq);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
}
list_add(&peer_req->w.list, &device->active_ee);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (device->state.conn == C_SYNC_TARGET)
wait_event(device->ee_wait, !overlapping_resync_write(device, peer_req));
@@ -2278,10 +2278,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list);
drbd_remove_epoch_entry_interval(device, peer_req);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (peer_req->flags & EE_CALL_AL_COMPLETE_IO)
drbd_al_complete_io(device, &peer_req->i);
@@ -2532,18 +2532,18 @@ submit_for_resync:
submit:
inc_unacked(device);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_add_tail(&peer_req->w.list, &device->read_ee);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (drbd_submit_peer_request(device, peer_req, READ, fault_type) == 0)
return 0;
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
/* no drbd_rs_complete_io(), we are dropping the connection anyways */
out_free_e:
@@ -3221,7 +3221,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in
}
mutex_lock(&connection->data.mutex);
- mutex_lock(&connection->conf_update);
+ mutex_lock(&connection->resource->conf_update);
old_net_conf = connection->net_conf;
*new_net_conf = *old_net_conf;
@@ -3232,7 +3232,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in
new_net_conf->two_primaries = p_two_primaries;
rcu_assign_pointer(connection->net_conf, new_net_conf);
- mutex_unlock(&connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
mutex_unlock(&connection->data.mutex);
crypto_free_hash(connection->peer_integrity_tfm);
@@ -3371,13 +3371,13 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
if (err)
return err;
- mutex_lock(&first_peer_device(device)->connection->conf_update);
+ mutex_lock(&connection->resource->conf_update);
old_net_conf = first_peer_device(device)->connection->net_conf;
if (get_ldev(device)) {
new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
if (!new_disk_conf) {
put_ldev(device);
- mutex_unlock(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
drbd_err(device, "Allocation of new disk_conf failed\n");
return -ENOMEM;
}
@@ -3497,7 +3497,7 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
rcu_assign_pointer(device->rs_plan_s, new_plan);
}
- mutex_unlock(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
synchronize_rcu();
if (new_net_conf)
kfree(old_net_conf);
@@ -3511,7 +3511,7 @@ reconnect:
put_ldev(device);
kfree(new_disk_conf);
}
- mutex_unlock(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
return -EIO;
disconnect:
@@ -3520,7 +3520,7 @@ disconnect:
put_ldev(device);
kfree(new_disk_conf);
}
- mutex_unlock(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
/* just for completeness: actually not needed,
* as this is not reached if csums_tfm was ok. */
crypto_free_hash(csums_tfm);
@@ -3600,13 +3600,13 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info
return -ENOMEM;
}
- mutex_lock(&first_peer_device(device)->connection->conf_update);
+ mutex_lock(&connection->resource->conf_update);
old_disk_conf = device->ldev->disk_conf;
*new_disk_conf = *old_disk_conf;
new_disk_conf->disk_size = p_usize;
rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
- mutex_unlock(&first_peer_device(device)->connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
synchronize_rcu();
kfree(old_disk_conf);
@@ -3845,10 +3845,10 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
drbd_info(device, "real peer disk state = %s\n", drbd_disk_str(real_peer_disk));
}
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
retry:
os = ns = drbd_read_state(device);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
/* If some other part of the code (asender thread, timeout)
* already decided to close the connection again,
@@ -3951,7 +3951,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
}
}
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
if (os.i != drbd_read_state(device).i)
goto retry;
clear_bit(CONSIDER_RESYNC, &device->flags);
@@ -3965,7 +3965,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
test_bit(NEW_CUR_UUID, &device->flags)) {
/* Do not allow tl_restart(RESEND) for a rebooted peer. We can only allow this
for temporal network outages! */
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
drbd_err(device, "Aborting Connect, can not thaw IO with an only Consistent peer\n");
tl_clear(first_peer_device(device)->connection);
drbd_uuid_new_current(device);
@@ -3975,7 +3975,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
}
rv = _drbd_set_state(device, ns, cs_flags, NULL);
ns = drbd_read_state(device);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (rv < SS_SUCCESS) {
conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
@@ -4482,12 +4482,12 @@ static void conn_disconnect(struct drbd_connection *connection)
if (conn_highest_role(connection) == R_PRIMARY && conn_highest_pdsk(connection) >= D_UNKNOWN)
conn_try_outdate_peer_async(connection);
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
oc = connection->cstate;
if (oc >= C_UNCONNECTED)
_conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE);
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
if (oc == C_DISCONNECTING)
conn_request_state(connection, NS(conn, C_STANDALONE), CS_VERBOSE | CS_HARD);
@@ -4498,11 +4498,11 @@ static int drbd_disconnected(struct drbd_device *device)
unsigned int i;
/* wait for current activity to cease. */
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
_drbd_wait_ee_list_empty(device, &device->active_ee);
_drbd_wait_ee_list_empty(device, &device->sync_ee);
_drbd_wait_ee_list_empty(device, &device->read_ee);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
/* We do not have data structures that would allow us to
* get the rs_pending_cnt down to 0 again.
@@ -4969,14 +4969,14 @@ validate_req_change_req_state(struct drbd_device *device, u64 id, sector_t secto
struct drbd_request *req;
struct bio_and_error m;
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
req = find_request(device, root, id, sector, missing_ok, func);
if (unlikely(!req)) {
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
return -EIO;
}
__req_mod(req, what, &m);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (m.bio)
complete_master_bio(device, &m);
@@ -5217,14 +5217,14 @@ static int connection_finish_peer_reqs(struct drbd_connection *connection)
}
set_bit(SIGNAL_ASENDER, &connection->flags);
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
struct drbd_device *device = peer_device->device;
not_empty = !list_empty(&device->done_ee);
if (not_empty)
break;
}
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
rcu_read_unlock();
} while (not_empty);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index a4b46741..daf7861 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -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(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
schedule();
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
}
finish_wait(&device->misc_wait, &wait);
}
@@ -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(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
if (rw == WRITE) {
/* This may temporarily give up the req_lock,
* but will re-aquire it before it returns here.
@@ -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(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
drbd_submit_req_private_bio(req);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
} else if (no_remote) {
nodata:
if (__ratelimit(&drbd_ratelimit_state))
@@ -1155,7 +1155,7 @@ nodata:
out:
if (drbd_req_put_completion_ref(req, &m, 1))
kref_put(&req->kref, drbd_req_destroy);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
if (m.bio)
complete_master_bio(device, &m);
@@ -1360,10 +1360,10 @@ void request_timer_fn(unsigned long data)
now = jiffies;
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
req = find_oldest_request(connection);
if (!req) {
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
mod_timer(&device->request_timer, now + et);
return;
}
@@ -1397,6 +1397,6 @@ void request_timer_fn(unsigned long data)
__drbd_chk_io_error(device, DRBD_FORCE_DETACH);
}
nt = (time_after(now, req->start_time + et) ? now : req->start_time) + et;
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
mod_timer(&device->request_timer, nt);
}
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 27283e6..5ce6dc5 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -318,9 +318,9 @@ static inline int req_mod(struct drbd_request *req,
struct bio_and_error m;
int rv;
- spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->req_lock, flags);
rv = __req_mod(req, what, &m);
- spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
if (m.bio)
complete_master_bio(device, &m);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index cbd287a..0e69bb1 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -253,10 +253,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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->req_lock, flags);
ns = apply_mask_val(drbd_read_state(device), mask, val);
rv = _drbd_set_state(device, ns, f, NULL);
- spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
return rv;
}
@@ -287,7 +287,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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->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);
@@ -304,7 +304,7 @@ _req_st_cond(struct drbd_device *device, union drbd_state mask,
rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
}
}
- spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
return rv;
}
@@ -333,12 +333,12 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
if (f & CS_SERIALIZE)
mutex_lock(device->state_mutex);
- spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
goto abort;
}
@@ -346,7 +346,7 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
rv = is_valid_state(device, ns);
if (rv == SS_SUCCESS)
rv = is_valid_soft_transition(os, ns, first_peer_device(device)->connection);
- spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
if (rv < SS_SUCCESS) {
if (f & CS_VERBOSE)
@@ -369,14 +369,14 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
print_st_err(device, os, ns, rv);
goto abort;
}
- spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
if (f & CS_WAIT_COMPLETE && rv == SS_SUCCESS) {
D_ASSERT(device, current != first_peer_device(device)->connection->worker.task);
@@ -1248,7 +1248,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
struct drbd_connection *connection = first_peer_device(device)->connection;
enum drbd_req_event what = NOTHING;
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
if (os.conn < C_CONNECTED && conn_lowest_conn(connection) >= C_CONNECTED)
what = RESEND;
@@ -1263,13 +1263,13 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
(union drbd_state) { { .susp_nod = 0 } },
CS_VERBOSE);
}
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
}
if (ns.susp_fen) {
struct drbd_connection *connection = first_peer_device(device)->connection;
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
if (connection->susp_fen && conn_lowest_conn(connection) >= C_CONNECTED) {
/* case2: The connection was established again: */
struct drbd_peer_device *peer_device;
@@ -1285,7 +1285,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
(union drbd_state) { { .susp_fen = 0 } },
CS_VERBOSE);
}
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
}
/* Became sync source. With protocol >= 96, we still need to send out
@@ -1558,13 +1558,13 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
if (oc == C_DISCONNECTING && ns_max.conn == C_STANDALONE) {
struct net_conf *old_conf;
- mutex_lock(&connection->conf_update);
+ mutex_lock(&connection->resource->conf_update);
old_conf = connection->net_conf;
connection->my_addr_len = 0;
connection->peer_addr_len = 0;
rcu_assign_pointer(connection->net_conf, NULL);
conn_free_crypto(connection);
- mutex_unlock(&connection->conf_update);
+ mutex_unlock(&connection->resource->conf_update);
synchronize_rcu();
kfree(old_conf);
@@ -1582,13 +1582,13 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
}
}
rcu_read_unlock();
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
_tl_restart(connection, CONNECTION_LOST_WHILE_PENDING);
_conn_request_state(connection,
(union drbd_state) { { .susp_fen = 1 } },
(union drbd_state) { { .susp_fen = 0 } },
CS_VERBOSE);
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
}
}
kref_put(&connection->kref, drbd_destroy_connection);
@@ -1805,7 +1805,7 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
/* This will be a cluster-wide state change.
* Need to give up the spinlock, grab the mutex,
* then send the state change request, ... */
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
mutex_lock(&connection->cstate_mutex);
have_mutex = true;
@@ -1824,10 +1824,10 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
/* ... and re-aquire the spinlock.
* If _conn_rq_cond() returned >= SS_SUCCESS, we must call
* conn_set_state() within the same spinlock. */
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
wait_event_lock_irq(connection->ping_wait,
(rv = _conn_rq_cond(connection, mask, val)),
- connection->req_lock);
+ connection->resource->req_lock);
clear_bit(CONN_WD_ST_CHG_REQ, &connection->flags);
if (rv < SS_SUCCESS)
goto abort;
@@ -1856,10 +1856,10 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
if (have_mutex) {
/* mutex_unlock() "... must not be used in interrupt context.",
* so give up the spinlock, then re-aquire it */
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
abort_unlocked:
mutex_unlock(&connection->cstate_mutex);
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
}
if (rv < SS_SUCCESS && flags & CS_VERBOSE) {
drbd_err(connection, "State change failed: %s\n", drbd_set_st_err_str(rv));
@@ -1875,9 +1875,9 @@ conn_request_state(struct drbd_connection *connection, union drbd_state mask, un
{
enum drbd_state_rv rv;
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
rv = _conn_request_state(connection, mask, val, flags);
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
return rv;
}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 560ebfd..167c198 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -102,14 +102,14 @@ void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(lo
unsigned long flags = 0;
struct drbd_device *device = peer_req->w.device;
- spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
if (block_id == ID_SYNCER)
drbd_rs_complete_io(device, i.sector);
@@ -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(&first_peer_device(device)->connection->req_lock, flags);
+ spin_lock_irqsave(&device->resource->req_lock, flags);
__req_mod(req, what, &m);
- spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
+ spin_unlock_irqrestore(&device->resource->req_lock, flags);
put_ldev(device);
if (m.bio)
@@ -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(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_add(&peer_req->w.list, &device->read_ee);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->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(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req);
defer:
@@ -855,7 +855,7 @@ int drbd_resync_finished(struct drbd_device *device)
ping_peer(device);
- spin_lock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
os = drbd_read_state(device);
verify_done = (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T);
@@ -944,7 +944,7 @@ int drbd_resync_finished(struct drbd_device *device)
_drbd_set_state(device, ns, CS_VERBOSE, NULL);
out_unlock:
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
put_ldev(device);
out:
device->rs_total = 0;
@@ -971,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(&first_peer_device(device)->connection->req_lock);
+ spin_lock_irq(&device->resource->req_lock);
list_add_tail(&peer_req->w.list, &device->net_ee);
- spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
+ spin_unlock_irq(&device->resource->req_lock);
wake_up(&drbd_pp_wait);
} else
drbd_free_peer_req(device, peer_req);
@@ -1847,7 +1847,7 @@ void wait_for_work(struct drbd_connection *connection, struct list_head *work_li
for (;;) {
int send_barrier;
prepare_to_wait(&connection->sender_work.q_wait, &wait, TASK_INTERRUPTIBLE);
- spin_lock_irq(&connection->req_lock);
+ spin_lock_irq(&connection->resource->req_lock);
spin_lock(&connection->sender_work.q_lock); /* FIXME get rid of this one? */
/* dequeue single item only,
* we still use drbd_queue_work_front() in some places */
@@ -1855,11 +1855,11 @@ void wait_for_work(struct drbd_connection *connection, struct list_head *work_li
list_move(connection->sender_work.q.next, work_list);
spin_unlock(&connection->sender_work.q_lock); /* FIXME get rid of this one? */
if (!list_empty(work_list) || signal_pending(current)) {
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
break;
}
send_barrier = need_to_send_barrier(connection);
- spin_unlock_irq(&connection->req_lock);
+ spin_unlock_irq(&connection->resource->req_lock);
if (send_barrier) {
drbd_send_barrier(connection);
connection->send.current_epoch_nr++;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 05/27] drbd: Move susp, susp_nod, susp_fen from connection to resource
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (3 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 04/27] drbd: Move conf_mutex from connection to resource Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 06/27] drbd: Define the size of res_opts->cpu_mask in a single place Philipp Reisner
` (21 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 18 ++++++++++--------
drivers/block/drbd/drbd_main.c | 2 +-
drivers/block/drbd/drbd_nl.c | 3 +--
drivers/block/drbd/drbd_state.c | 17 +++++++++--------
4 files changed, 21 insertions(+), 19 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index bdfa1de..d0defe8 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -575,6 +575,10 @@ struct drbd_resource {
struct res_opts res_opts;
struct mutex conf_update; /* mutex for ready-copy-update of net_conf and disk_conf */
spinlock_t req_lock;
+
+ unsigned susp:1; /* IO suspended by user */
+ unsigned susp_nod:1; /* IO suspended because no data */
+ unsigned susp_fen:1; /* IO suspended because fence peer handler runs */
};
struct drbd_connection {
@@ -583,9 +587,6 @@ struct drbd_connection {
struct kref kref;
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 */
- unsigned susp_fen:1; /* IO suspended because fence peer handler runs */
struct mutex cstate_mutex; /* Protects graceful disconnects */
unsigned int connect_cnt; /* Inc each time a connection is established */
@@ -1502,12 +1503,13 @@ _drbd_set_state(struct drbd_device *device, union drbd_state ns,
static inline union drbd_state drbd_read_state(struct drbd_device *device)
{
+ struct drbd_resource *resource = device->resource;
union drbd_state rv;
rv.i = device->state.i;
- 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;
+ rv.susp = resource->susp;
+ rv.susp_nod = resource->susp_nod;
+ rv.susp_fen = resource->susp_fen;
return rv;
}
@@ -2028,9 +2030,9 @@ static inline int drbd_state_is_stable(struct drbd_device *device)
static inline int drbd_suspended(struct drbd_device *device)
{
- struct drbd_connection *connection = first_peer_device(device)->connection;
+ struct drbd_resource *resource = device->resource;
- return connection->susp || connection->susp_fen || connection->susp_nod;
+ return resource->susp || resource->susp_fen || resource->susp_nod;
}
static inline bool may_inc_ap_bio(struct drbd_device *device)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 43b9141..824bc7a 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2536,7 +2536,7 @@ struct drbd_resource *drbd_create_resource(const char *name)
{
struct drbd_resource *resource;
- resource = kmalloc(sizeof(struct drbd_resource), GFP_KERNEL);
+ resource = kzalloc(sizeof(struct drbd_resource), GFP_KERNEL);
if (!resource)
return NULL;
resource->name = kstrdup(name, GFP_KERNEL);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 5ccfebb..a84f1e2 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1665,8 +1665,7 @@ 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 &&
- first_peer_device(device)->connection->susp_nod))
+ !(device->state.role == R_PRIMARY && device->resource->susp_nod))
set_bit(CRASHED_PRIMARY, &device->flags);
device->send_cnt = 0;
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 0e69bb1..56b4aee 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1011,9 +1011,9 @@ __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);
- 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;
+ device->resource->susp = ns.susp;
+ device->resource->susp_nod = ns.susp_nod;
+ device->resource->susp_fen = ns.susp_fen;
/* put replicated vs not-replicated requests in seperate epochs */
if (did_remote != should_do_remote)
@@ -1222,6 +1222,7 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device,
static void after_state_ch(struct drbd_device *device, union drbd_state os,
union drbd_state ns, enum chg_state_flags flags)
{
+ struct drbd_resource *resource = device->resource;
struct sib_info sib;
sib.sib_reason = SIB_STATE_CHANGE;
@@ -1256,7 +1257,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
conn_lowest_disk(connection) > D_NEGOTIATING)
what = RESTART_FROZEN_DISK_IO;
- if (connection->susp_nod && what != NOTHING) {
+ if (resource->susp_nod && what != NOTHING) {
_tl_restart(connection, what);
_conn_request_state(connection,
(union drbd_state) { { .susp_nod = 1 } },
@@ -1270,7 +1271,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
struct drbd_connection *connection = first_peer_device(device)->connection;
spin_lock_irq(&device->resource->req_lock);
- if (connection->susp_fen && conn_lowest_conn(connection) >= C_CONNECTED) {
+ if (resource->susp_fen && conn_lowest_conn(connection) >= C_CONNECTED) {
/* case2: The connection was established again: */
struct drbd_peer_device *peer_device;
int vnr;
@@ -1753,9 +1754,9 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union
} };
}
- ns_min.susp = ns_max.susp = connection->susp;
- ns_min.susp_nod = ns_max.susp_nod = connection->susp_nod;
- ns_min.susp_fen = ns_max.susp_fen = connection->susp_fen;
+ ns_min.susp = ns_max.susp = connection->resource->susp;
+ ns_min.susp_nod = ns_max.susp_nod = connection->resource->susp_nod;
+ ns_min.susp_fen = ns_max.susp_fen = connection->resource->susp_fen;
*pns_min = ns_min;
*pns_max = ns_max;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 06/27] drbd: Define the size of res_opts->cpu_mask in a single place
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (4 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 05/27] drbd: Move susp, susp_nod, susp_fen " Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 07/27] drbd: Move cpu_mask from connection to resource Philipp Reisner
` (20 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_main.c | 3 +--
include/linux/drbd.h | 2 ++
include/linux/drbd_genl.h | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 824bc7a..cab0641 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2505,8 +2505,7 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op
/* silently ignore cpu mask on UP kernel */
if (nr_cpu_ids > 1 && res_opts->cpu_mask[0] != 0) {
- /* FIXME: Get rid of constant 32 here */
- err = bitmap_parse(res_opts->cpu_mask, 32,
+ err = bitmap_parse(res_opts->cpu_mask, DRBD_CPU_MASK_SIZE,
cpumask_bits(new_cpu_mask), nr_cpu_ids);
if (err) {
drbd_warn(resource, "bitmap_parse() failed with %d\n", err);
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index de7d74a..6f60136 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -382,4 +382,6 @@ enum drbd_timeout_flag {
#define DRBD_MD_INDEX_FLEX_EXT -2
#define DRBD_MD_INDEX_FLEX_INT -3
+#define DRBD_CPU_MASK_SIZE 32
+
#endif
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index b14a2e8..4193f5f 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -135,7 +135,7 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
)
GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts,
- __str_field_def(1, DRBD_GENLA_F_MANDATORY, cpu_mask, 32)
+ __str_field_def(1, DRBD_GENLA_F_MANDATORY, cpu_mask, DRBD_CPU_MASK_SIZE)
__u32_field_def(2, DRBD_GENLA_F_MANDATORY, on_no_data, DRBD_ON_NO_DATA_DEF)
)
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 07/27] drbd: Move cpu_mask from connection to resource
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (5 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 06/27] drbd: Define the size of res_opts->cpu_mask in a single place Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 08/27] drbd: Rename drbdd_init() -> drbd_receiver() Philipp Reisner
` (19 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Also fix drbd_calc_cpu_mask() to spread resources equally over all online cpus
independent of device minor numbers.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 5 ++-
drivers/block/drbd/drbd_main.c | 74 ++++++++++++++++++++++++----------------
2 files changed, 47 insertions(+), 32 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d0defe8..d7eade8 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -579,6 +579,8 @@ struct drbd_resource {
unsigned susp:1; /* IO suspended by user */
unsigned susp_nod:1; /* IO suspended because no data */
unsigned susp_fen:1; /* IO suspended because fence peer handler runs */
+
+ cpumask_var_t cpu_mask;
};
struct drbd_connection {
@@ -627,7 +629,6 @@ struct drbd_connection {
struct drbd_thread receiver;
struct drbd_thread worker;
struct drbd_thread asender;
- cpumask_var_t cpu_mask;
/* sender side */
struct drbd_work_queue sender_work;
@@ -875,10 +876,8 @@ extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
extern char *drbd_task_to_thread_name(struct drbd_connection *connection, struct task_struct *task);
#ifdef CONFIG_SMP
extern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
-extern void drbd_calc_cpu_mask(struct drbd_connection *connection);
#else
#define drbd_thread_current_set_cpu(A) ({})
-#define drbd_calc_cpu_mask(A) ({})
#endif
extern void tl_release(struct drbd_connection *, unsigned int barrier_nr,
unsigned int set_size);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index cab0641..718c3bd 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -513,28 +513,38 @@ int conn_lowest_minor(struct drbd_connection *connection)
#ifdef CONFIG_SMP
/**
* drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
- * @device: DRBD device.
*
- * Forces all threads of a device onto the same CPU. This is beneficial for
+ * Forces all threads of a resource onto the same CPU. This is beneficial for
* DRBD's performance. May be overwritten by user's configuration.
*/
-void drbd_calc_cpu_mask(struct drbd_connection *connection)
+static void drbd_calc_cpu_mask(cpumask_var_t *cpu_mask)
{
- int ord, cpu;
+ unsigned int *resources_per_cpu, min_index = ~0;
- /* user override. */
- if (cpumask_weight(connection->cpu_mask))
- return;
+ resources_per_cpu = kzalloc(nr_cpu_ids * sizeof(*resources_per_cpu), GFP_KERNEL);
+ if (resources_per_cpu) {
+ struct drbd_resource *resource;
+ unsigned int cpu, min = ~0;
- ord = conn_lowest_minor(connection) % cpumask_weight(cpu_online_mask);
- for_each_online_cpu(cpu) {
- if (ord-- == 0) {
- cpumask_set_cpu(cpu, connection->cpu_mask);
- return;
+ rcu_read_lock();
+ for_each_resource_rcu(resource, &drbd_resources) {
+ for_each_cpu(cpu, resource->cpu_mask)
+ resources_per_cpu[cpu]++;
}
+ rcu_read_unlock();
+ for_each_online_cpu(cpu) {
+ if (resources_per_cpu[cpu] < min) {
+ min = resources_per_cpu[cpu];
+ min_index = cpu;
+ }
+ }
+ kfree(resources_per_cpu);
+ }
+ if (min_index == ~0) {
+ cpumask_setall(*cpu_mask);
+ return;
}
- /* should not be reached */
- cpumask_setall(connection->cpu_mask);
+ cpumask_set_cpu(min_index, *cpu_mask);
}
/**
@@ -552,8 +562,10 @@ void drbd_thread_current_set_cpu(struct drbd_thread *thi)
if (!thi->reset_cpu_mask)
return;
thi->reset_cpu_mask = 0;
- set_cpus_allowed_ptr(p, thi->connection->cpu_mask);
+ set_cpus_allowed_ptr(p, thi->connection->resource->cpu_mask);
}
+#else
+#define drbd_calc_cpu_mask(A) ({})
#endif
/**
@@ -2289,6 +2301,7 @@ void drbd_destroy_resource(struct kref *kref)
container_of(kref, struct drbd_resource, kref);
idr_destroy(&resource->devices);
+ free_cpumask_var(resource->cpu_mask);
kfree(resource->name);
kfree(resource);
}
@@ -2514,10 +2527,11 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op
}
}
resource->res_opts = *res_opts;
- for_each_connection_rcu(connection, resource) {
- if (!cpumask_equal(connection->cpu_mask, new_cpu_mask)) {
- cpumask_copy(connection->cpu_mask, new_cpu_mask);
- drbd_calc_cpu_mask(connection);
+ if (cpumask_empty(new_cpu_mask))
+ drbd_calc_cpu_mask(&new_cpu_mask);
+ if (!cpumask_equal(resource->cpu_mask, new_cpu_mask)) {
+ cpumask_copy(resource->cpu_mask, new_cpu_mask);
+ for_each_connection_rcu(connection, resource) {
connection->receiver.reset_cpu_mask = 1;
connection->asender.reset_cpu_mask = 1;
connection->worker.reset_cpu_mask = 1;
@@ -2537,12 +2551,12 @@ struct drbd_resource *drbd_create_resource(const char *name)
resource = kzalloc(sizeof(struct drbd_resource), GFP_KERNEL);
if (!resource)
- return NULL;
+ goto fail;
resource->name = kstrdup(name, GFP_KERNEL);
- if (!resource->name) {
- kfree(resource);
- return NULL;
- }
+ if (!resource->name)
+ goto fail_free_resource;
+ if (!zalloc_cpumask_var(&resource->cpu_mask, GFP_KERNEL))
+ goto fail_free_name;
kref_init(&resource->kref);
idr_init(&resource->devices);
INIT_LIST_HEAD(&resource->connections);
@@ -2550,6 +2564,13 @@ struct drbd_resource *drbd_create_resource(const char *name)
mutex_init(&resource->conf_update);
spin_lock_init(&resource->req_lock);
return resource;
+
+fail_free_name:
+ kfree(resource->name);
+fail_free_resource:
+ kfree(resource);
+fail:
+ return NULL;
}
/* caller must be under genl_lock() */
@@ -2567,9 +2588,6 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
if (drbd_alloc_socket(&connection->meta))
goto fail;
- if (!zalloc_cpumask_var(&connection->cpu_mask, GFP_KERNEL))
- goto fail;
-
connection->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL);
if (!connection->current_epoch)
goto fail;
@@ -2618,7 +2636,6 @@ fail_resource:
drbd_free_resource(resource);
fail:
kfree(connection->current_epoch);
- free_cpumask_var(connection->cpu_mask);
drbd_free_socket(&connection->meta);
drbd_free_socket(&connection->data);
kfree(connection);
@@ -2636,7 +2653,6 @@ void drbd_destroy_connection(struct kref *kref)
idr_destroy(&connection->peer_devices);
- free_cpumask_var(connection->cpu_mask);
drbd_free_socket(&connection->meta);
drbd_free_socket(&connection->data);
kfree(connection->int_dig_in);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 08/27] drbd: Rename drbdd_init() -> drbd_receiver()
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (6 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 07/27] drbd: Move cpu_mask from connection to resource Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 09/27] drbd: Function prototype cleanups Philipp Reisner
` (18 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_main.c | 4 ++--
drivers/block/drbd/drbd_nl.c | 2 +-
drivers/block/drbd/drbd_receiver.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 718c3bd..a2003cd 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -58,7 +58,7 @@
#include "drbd_vli.h"
static DEFINE_MUTEX(drbd_main_mutex);
-int drbdd_init(struct drbd_thread *);
+int drbd_receiver(struct drbd_thread *);
int drbd_worker(struct drbd_thread *);
int drbd_asender(struct drbd_thread *);
@@ -2616,7 +2616,7 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
mutex_init(&connection->data.mutex);
mutex_init(&connection->meta.mutex);
- drbd_thread_init(connection, &connection->receiver, drbdd_init, "receiver");
+ drbd_thread_init(connection, &connection->receiver, drbd_receiver, "receiver");
drbd_thread_init(connection, &connection->worker, drbd_worker, "worker");
drbd_thread_init(connection, &connection->asender, drbd_asender, "asender");
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index a84f1e2..f7d62ff 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2332,7 +2332,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection
/* Race breaker. This additional state change request may be
* necessary, if this was a forced disconnect during a receiver
* restart. We may have "killed" the receiver thread just
- * after drbdd_init() returned. Typically, we should be
+ * after drbd_receiver() returned. Typically, we should be
* C_STANDALONE already, now, and this becomes a no-op.
*/
rv2 = conn_request_state(connection, NS(conn, C_STANDALONE),
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 217ed11..9349113 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4843,7 +4843,7 @@ static int drbd_do_auth(struct drbd_connection *connection)
}
#endif
-int drbdd_init(struct drbd_thread *thi)
+int drbd_receiver(struct drbd_thread *thi)
{
struct drbd_connection *connection = thi->connection;
int h;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 09/27] drbd: Function prototype cleanups
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (7 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 08/27] drbd: Rename drbdd_init() -> drbd_receiver() Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 10/27] drbd: drbd_csum_bio(), drbd_csum_ee(): Remove unused device argument Philipp Reisner
` (17 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 2 ++
drivers/block/drbd/drbd_main.c | 5 -----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d7eade8..c9eea4d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1340,6 +1340,8 @@ extern void resync_timer_fn(unsigned long data);
extern void start_resync_timer_fn(unsigned long data);
/* drbd_receiver.c */
+extern int drbd_receiver(struct drbd_thread *thi);
+extern int drbd_asender(struct drbd_thread *thi);
extern int drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector);
extern int drbd_submit_peer_request(struct drbd_device *,
struct drbd_peer_request *, const unsigned,
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a2003cd..a7f992f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -58,11 +58,6 @@
#include "drbd_vli.h"
static DEFINE_MUTEX(drbd_main_mutex);
-int drbd_receiver(struct drbd_thread *);
-int drbd_worker(struct drbd_thread *);
-int drbd_asender(struct drbd_thread *);
-
-int drbd_init(void);
static int drbd_open(struct block_device *bdev, fmode_t mode);
static void drbd_release(struct gendisk *gd, fmode_t mode);
static int w_md_sync(struct drbd_work *w, int unused);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 10/27] drbd: drbd_csum_bio(), drbd_csum_ee(): Remove unused device argument
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (8 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 09/27] drbd: Function prototype cleanups Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 11/27] drbd: Replace vnr_to_mdev() with conn_peer_device() Philipp Reisner
` (16 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 5 ++---
drivers/block/drbd/drbd_main.c | 6 +++---
drivers/block/drbd/drbd_receiver.c | 4 ++--
drivers/block/drbd/drbd_worker.c | 13 ++++++-------
4 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c9eea4d..7ba1db8 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1315,9 +1315,8 @@ static inline void ov_out_of_sync_print(struct drbd_device *device)
}
-extern void drbd_csum_bio(struct drbd_device *, struct crypto_hash *, struct bio *, void *);
-extern void drbd_csum_ee(struct drbd_device *, struct crypto_hash *,
- struct drbd_peer_request *, void *);
+extern void drbd_csum_bio(struct crypto_hash *, struct bio *, void *);
+extern void drbd_csum_ee(struct crypto_hash *, struct drbd_peer_request *, void *);
/* worker callbacks */
extern int w_e_end_data_req(struct drbd_work *, int);
extern int w_e_end_rsdata_req(struct drbd_work *, int);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a7f992f..7df2de8 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1646,7 +1646,7 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
}
p->dp_flags = cpu_to_be32(dp_flags);
if (dgs)
- drbd_csum_bio(device, first_peer_device(device)->connection->integrity_tfm, req->master_bio, p + 1);
+ drbd_csum_bio(first_peer_device(device)->connection->integrity_tfm, req->master_bio, p + 1);
err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
if (!err) {
/* For protocol A, we have to memcpy the payload into
@@ -1670,7 +1670,7 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
/* 64 byte, 512 bit, is the largest digest size
* currently supported in kernel crypto. */
unsigned char digest[64];
- drbd_csum_bio(device, first_peer_device(device)->connection->integrity_tfm, req->master_bio, digest);
+ drbd_csum_bio(first_peer_device(device)->connection->integrity_tfm, req->master_bio, digest);
if (memcmp(p + 1, digest, dgs)) {
drbd_warn(device,
"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
@@ -1710,7 +1710,7 @@ int drbd_send_block(struct drbd_device *device, enum drbd_packet cmd,
p->seq_num = 0; /* unused */
p->dp_flags = 0;
if (dgs)
- drbd_csum_ee(device, first_peer_device(device)->connection->integrity_tfm, peer_req, p + 1);
+ drbd_csum_ee(first_peer_device(device)->connection->integrity_tfm, peer_req, p + 1);
err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
if (!err)
err = _drbd_send_zc_ee(device, peer_req);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 9349113..cb37e23 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1560,7 +1560,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
}
if (dgs) {
- drbd_csum_ee(device, first_peer_device(device)->connection->peer_integrity_tfm, peer_req, dig_vv);
+ drbd_csum_ee(first_peer_device(device)->connection->peer_integrity_tfm, peer_req, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
drbd_err(device, "Digest integrity check FAILED: %llus +%u\n",
(unsigned long long)sector, data_size);
@@ -1637,7 +1637,7 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req,
}
if (dgs) {
- drbd_csum_bio(device, first_peer_device(device)->connection->peer_integrity_tfm, bio, dig_vv);
+ drbd_csum_bio(first_peer_device(device)->connection->peer_integrity_tfm, bio, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
drbd_err(device, "Digest integrity check FAILED. Broken NICs?\n");
return -EINVAL;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 167c198..cf40a8a 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -282,8 +282,7 @@ void drbd_request_endio(struct bio *bio, int error)
complete_master_bio(device, &m);
}
-void drbd_csum_ee(struct drbd_device *device, struct crypto_hash *tfm,
- struct drbd_peer_request *peer_req, void *digest)
+void drbd_csum_ee(struct crypto_hash *tfm, struct drbd_peer_request *peer_req, void *digest)
{
struct hash_desc desc;
struct scatterlist sg;
@@ -310,7 +309,7 @@ void drbd_csum_ee(struct drbd_device *device, struct crypto_hash *tfm,
crypto_hash_final(&desc, digest);
}
-void drbd_csum_bio(struct drbd_device *device, struct crypto_hash *tfm, struct bio *bio, void *digest)
+void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest)
{
struct hash_desc desc;
struct scatterlist sg;
@@ -350,7 +349,7 @@ static int w_e_send_csum(struct drbd_work *w, int cancel)
if (digest) {
sector_t sector = peer_req->i.sector;
unsigned int size = peer_req->i.size;
- drbd_csum_ee(device, first_peer_device(device)->connection->csums_tfm, peer_req, digest);
+ drbd_csum_ee(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
@@ -1103,7 +1102,7 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
digest = kmalloc(digest_size, GFP_NOIO);
}
if (digest) {
- drbd_csum_ee(device, first_peer_device(device)->connection->csums_tfm, peer_req, digest);
+ drbd_csum_ee(first_peer_device(device)->connection->csums_tfm, peer_req, digest);
eq = !memcmp(digest, di->digest, digest_size);
kfree(digest);
}
@@ -1155,7 +1154,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, first_peer_device(device)->connection->verify_tfm, peer_req, digest);
+ drbd_csum_ee(first_peer_device(device)->connection->verify_tfm, peer_req, digest);
else
memset(digest, 0, digest_size);
@@ -1221,7 +1220,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel)
digest_size = crypto_hash_digestsize(first_peer_device(device)->connection->verify_tfm);
digest = kmalloc(digest_size, GFP_NOIO);
if (digest) {
- drbd_csum_ee(device, first_peer_device(device)->connection->verify_tfm, peer_req, digest);
+ drbd_csum_ee(first_peer_device(device)->connection->verify_tfm, peer_req, digest);
D_ASSERT(device, digest_size == di->digest_size);
eq = !memcmp(digest, di->digest, digest_size);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 11/27] drbd: Replace vnr_to_mdev() with conn_peer_device()
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (9 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 10/27] drbd: drbd_csum_bio(), drbd_csum_ee(): Remove unused device argument Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 12/27] drbd: Pass a peer device to a number of fuctions Philipp Reisner
` (15 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
The new function returns a peer device, which allows us to eliminate a few
instances of first_peer_device().
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 8 --
drivers/block/drbd/drbd_receiver.c | 174 ++++++++++++++++++++++--------------
2 files changed, 109 insertions(+), 73 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 7ba1db8..461cf8d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -851,14 +851,6 @@ static inline unsigned int device_to_minor(struct drbd_device *device)
return device->minor;
}
-static inline struct drbd_device *vnr_to_device(struct drbd_connection *connection, int vnr)
-{
- struct drbd_peer_device *peer_device;
-
- peer_device = idr_find(&connection->peer_devices, vnr);
- return peer_device ? peer_device->device : NULL;
-}
-
/*
* function declarations
*************************/
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index cb37e23..edd5cac 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1422,6 +1422,12 @@ void conn_wait_active_ee_empty(struct drbd_connection *connection)
rcu_read_unlock();
}
+static struct drbd_peer_device *
+conn_peer_device(struct drbd_connection *connection, int volume_number)
+{
+ return idr_find(&connection->peer_devices, volume_number);
+}
+
static int receive_Barrier(struct drbd_connection *connection, struct packet_info *pi)
{
int rv;
@@ -1731,15 +1737,17 @@ find_request(struct drbd_device *device, struct rb_root *root, u64 id,
static int receive_DataReply(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct drbd_request *req;
sector_t sector;
int err;
struct p_data *p = pi->data;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
sector = be64_to_cpu(p->sector);
@@ -1764,14 +1772,16 @@ static int receive_DataReply(struct drbd_connection *connection, struct packet_i
static int receive_RSDataReply(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
sector_t sector;
int err;
struct p_data *p = pi->data;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
sector = be64_to_cpu(p->sector);
D_ASSERT(device, p->block_id == ID_SYNCER);
@@ -2154,6 +2164,7 @@ static int handle_write_conflicts(struct drbd_device *device,
/* mirrored write */
static int receive_Data(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
sector_t sector;
struct drbd_peer_request *peer_req;
@@ -2163,9 +2174,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
u32 dp_flags;
int err, tp;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
if (!get_ldev(device)) {
int err2;
@@ -2211,7 +2223,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
spin_unlock(&connection->epoch_lock);
rcu_read_lock();
- tp = rcu_dereference(first_peer_device(device)->connection->net_conf)->two_primaries;
+ tp = rcu_dereference(peer_device->connection->net_conf)->two_primaries;
rcu_read_unlock();
if (tp) {
peer_req->flags |= EE_IN_INTERVAL_TREE;
@@ -2238,9 +2250,9 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
if (device->state.conn == C_SYNC_TARGET)
wait_event(device->ee_wait, !overlapping_resync_write(device, peer_req));
- if (first_peer_device(device)->connection->agreed_pro_version < 100) {
+ if (peer_device->connection->agreed_pro_version < 100) {
rcu_read_lock();
- switch (rcu_dereference(first_peer_device(device)->connection->net_conf)->wire_protocol) {
+ switch (rcu_dereference(peer_device->connection->net_conf)->wire_protocol) {
case DRBD_PROT_C:
dp_flags |= DP_SEND_WRITE_ACK;
break;
@@ -2366,6 +2378,7 @@ int drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector)
static int receive_DataRequest(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
sector_t sector;
sector_t capacity;
@@ -2375,9 +2388,10 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
unsigned int fault_type;
struct p_block_req *p = pi->data;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
capacity = drbd_get_capacity(device->this_bdev);
sector = be64_to_cpu(p->sector);
@@ -2457,11 +2471,11 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
peer_req->digest = di;
peer_req->flags |= EE_HAS_DIGEST;
- if (drbd_recv_all(first_peer_device(device)->connection, di->digest, pi->size))
+ if (drbd_recv_all(peer_device->connection, di->digest, pi->size))
goto out_free_e;
if (pi->cmd == P_CSUM_RS_REQUEST) {
- D_ASSERT(device, first_peer_device(device)->connection->agreed_pro_version >= 89);
+ D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
peer_req->w.cb = w_e_end_csum_rs_req;
/* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector);
@@ -2478,7 +2492,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
case P_OV_REQUEST:
if (device->ov_start_sector == ~(sector_t)0 &&
- first_peer_device(device)->connection->agreed_pro_version >= 90) {
+ peer_device->connection->agreed_pro_version >= 90) {
unsigned long now = jiffies;
int i;
device->ov_start_sector = sector;
@@ -3322,6 +3336,7 @@ static int config_unknown_volume(struct drbd_connection *connection, struct pack
static int receive_SyncParam(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_rs_param_95 *p;
unsigned int header_size, data_size, exp_max_sz;
@@ -3334,9 +3349,10 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
int fifo_size = 0;
int err;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return config_unknown_volume(connection, pi);
+ device = peer_device->device;
exp_max_sz = apv <= 87 ? sizeof(struct p_rs_param)
: apv == 88 ? sizeof(struct p_rs_param)
@@ -3367,12 +3383,12 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
p = pi->data;
memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
- err = drbd_recv_all(first_peer_device(device)->connection, p, header_size);
+ err = drbd_recv_all(peer_device->connection, p, header_size);
if (err)
return err;
mutex_lock(&connection->resource->conf_update);
- old_net_conf = first_peer_device(device)->connection->net_conf;
+ old_net_conf = peer_device->connection->net_conf;
if (get_ldev(device)) {
new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
if (!new_disk_conf) {
@@ -3398,7 +3414,7 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
goto reconnect;
}
- err = drbd_recv_all(first_peer_device(device)->connection, p->verify_alg, data_size);
+ err = drbd_recv_all(peer_device->connection, p->verify_alg, data_size);
if (err)
goto reconnect;
/* we expect NUL terminated string */
@@ -3472,15 +3488,15 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
if (verify_tfm) {
strcpy(new_net_conf->verify_alg, p->verify_alg);
new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1;
- crypto_free_hash(first_peer_device(device)->connection->verify_tfm);
- first_peer_device(device)->connection->verify_tfm = verify_tfm;
+ crypto_free_hash(peer_device->connection->verify_tfm);
+ peer_device->connection->verify_tfm = verify_tfm;
drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg);
}
if (csums_tfm) {
strcpy(new_net_conf->csums_alg, p->csums_alg);
new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1;
- crypto_free_hash(first_peer_device(device)->connection->csums_tfm);
- first_peer_device(device)->connection->csums_tfm = csums_tfm;
+ crypto_free_hash(peer_device->connection->csums_tfm);
+ peer_device->connection->csums_tfm = csums_tfm;
drbd_info(device, "using csums-alg: \"%s\"\n", p->csums_alg);
}
rcu_assign_pointer(connection->net_conf, new_net_conf);
@@ -3526,7 +3542,7 @@ disconnect:
crypto_free_hash(csums_tfm);
/* but free the verify_tfm again, if csums_tfm did not work out */
crypto_free_hash(verify_tfm);
- conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
@@ -3545,6 +3561,7 @@ static void warn_if_differ_considerably(struct drbd_device *device,
static int receive_sizes(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_sizes *p = pi->data;
enum determine_dev_size dd = DS_UNCHANGED;
@@ -3552,9 +3569,10 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info
int ldsc = 0; /* local disk size changed */
enum dds_flags ddsf;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return config_unknown_volume(connection, pi);
+ device = peer_device->device;
p_size = be64_to_cpu(p->d_size);
p_usize = be64_to_cpu(p->u_size);
@@ -3585,7 +3603,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info
device->state.disk >= D_OUTDATED &&
device->state.conn < C_CONNECTED) {
drbd_err(device, "The peer's disk size is too small!\n");
- conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
put_ldev(device);
return -EIO;
}
@@ -3666,14 +3684,16 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info
static int receive_uuids(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_uuids *p = pi->data;
u64 *p_uuid;
int i, updated_uuids = 0;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return config_unknown_volume(connection, pi);
+ device = peer_device->device;
p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO);
if (!p_uuid) {
@@ -3693,14 +3713,14 @@ static int receive_uuids(struct drbd_connection *connection, struct packet_info
(device->ed_uuid & ~((u64)1)) != (p_uuid[UI_CURRENT] & ~((u64)1))) {
drbd_err(device, "Can only connect to data with current UUID=%016llX\n",
(unsigned long long)device->ed_uuid);
- conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
if (get_ldev(device)) {
int skip_initial_sync =
device->state.conn == C_CONNECTED &&
- first_peer_device(device)->connection->agreed_pro_version >= 90 &&
+ peer_device->connection->agreed_pro_version >= 90 &&
device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
(p_uuid[UI_FLAGS] & 8);
if (skip_initial_sync) {
@@ -3771,19 +3791,21 @@ static union drbd_state convert_state(union drbd_state ps)
static int receive_req_state(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_req_state *p = pi->data;
union drbd_state mask, val;
enum drbd_state_rv rv;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
mask.i = be32_to_cpu(p->mask);
val.i = be32_to_cpu(p->val);
- if (test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags) &&
+ if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags) &&
mutex_is_locked(device->state_mutex)) {
drbd_send_sr_reply(device, SS_CONCURRENT_ST_CHG);
return 0;
@@ -3826,6 +3848,7 @@ static int receive_req_conn_state(struct drbd_connection *connection, struct pac
static int receive_state(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_state *p = pi->data;
union drbd_state os, ns, peer_state;
@@ -3833,9 +3856,10 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
enum chg_state_flags cs_flags;
int rv;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return config_unknown_volume(connection, pi);
+ device = peer_device->device;
peer_state.i = be32_to_cpu(p->state);
@@ -3942,10 +3966,10 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
peer_state.disk = D_DISKLESS;
real_peer_disk = D_DISKLESS;
} else {
- if (test_and_clear_bit(CONN_DRY_RUN, &first_peer_device(device)->connection->flags))
+ if (test_and_clear_bit(CONN_DRY_RUN, &peer_device->connection->flags))
return -EIO;
D_ASSERT(device, os.conn == C_WF_REPORT_PARAMS);
- conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
}
@@ -3967,10 +3991,10 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
for temporal network outages! */
spin_unlock_irq(&device->resource->req_lock);
drbd_err(device, "Aborting Connect, can not thaw IO with an only Consistent peer\n");
- tl_clear(first_peer_device(device)->connection);
+ tl_clear(peer_device->connection);
drbd_uuid_new_current(device);
clear_bit(NEW_CUR_UUID, &device->flags);
- conn_request_state(first_peer_device(device)->connection, NS2(conn, C_PROTOCOL_ERROR, susp, 0), CS_HARD);
+ conn_request_state(peer_device->connection, NS2(conn, C_PROTOCOL_ERROR, susp, 0), CS_HARD);
return -EIO;
}
rv = _drbd_set_state(device, ns, cs_flags, NULL);
@@ -3978,7 +4002,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
spin_unlock_irq(&device->resource->req_lock);
if (rv < SS_SUCCESS) {
- conn_request_state(first_peer_device(device)->connection, NS(conn, C_DISCONNECTING), CS_HARD);
+ conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
return -EIO;
}
@@ -4002,12 +4026,14 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
static int receive_sync_uuid(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_rs_uuid *p = pi->data;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
wait_event(device->misc_wait,
device->state.conn == C_WF_SYNC_UUID ||
@@ -4224,13 +4250,15 @@ void INFO_bm_xfer_stats(struct drbd_device *device,
returns 0 on failure, 1 if we successfully received it. */
static int receive_bitmap(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct bm_xfer_ctx c;
int err;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
drbd_bm_lock(device, "receive bitmap", BM_LOCKED_SET_ALLOWED);
/* you are supposed to send additional out-of-sync information
@@ -4259,7 +4287,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info
err = -EIO;
goto out;
}
- err = drbd_recv_all(first_peer_device(device)->connection, p, pi->size);
+ err = drbd_recv_all(peer_device->connection, p, pi->size);
if (err)
goto out;
err = decode_bitmap_c(device, p, &c, pi->size);
@@ -4277,7 +4305,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info
goto out;
break;
}
- err = drbd_recv_header(first_peer_device(device)->connection, pi);
+ err = drbd_recv_header(peer_device->connection, pi);
if (err)
goto out;
}
@@ -4327,12 +4355,14 @@ static int receive_UnplugRemote(struct drbd_connection *connection, struct packe
static int receive_out_of_sync(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_block_desc *p = pi->data;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
switch (device->state.conn) {
case C_WF_SYNC_UUID:
@@ -4892,13 +4922,15 @@ static int got_conn_RqSReply(struct drbd_connection *connection, struct packet_i
static int got_RqSReply(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_req_state_reply *p = pi->data;
int retcode = be32_to_cpu(p->retcode);
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
if (test_bit(CONN_WD_ST_CHG_REQ, &connection->flags)) {
D_ASSERT(device, connection->agreed_pro_version < 100);
@@ -4935,16 +4967,18 @@ static int got_PingAck(struct drbd_connection *connection, struct packet_info *p
static int got_IsInSync(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_block_ack *p = pi->data;
sector_t sector = be64_to_cpu(p->sector);
int blksize = be32_to_cpu(p->blksize);
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
- D_ASSERT(device, first_peer_device(device)->connection->agreed_pro_version >= 89);
+ D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
update_peer_seq(device, be32_to_cpu(p->seq_num));
@@ -4985,15 +5019,17 @@ validate_req_change_req_state(struct drbd_device *device, u64 id, sector_t secto
static int got_BlockAck(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_block_ack *p = pi->data;
sector_t sector = be64_to_cpu(p->sector);
int blksize = be32_to_cpu(p->blksize);
enum drbd_req_event what;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
update_peer_seq(device, be32_to_cpu(p->seq_num));
@@ -5029,15 +5065,17 @@ static int got_BlockAck(struct drbd_connection *connection, struct packet_info *
static int got_NegAck(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_block_ack *p = pi->data;
sector_t sector = be64_to_cpu(p->sector);
int size = be32_to_cpu(p->blksize);
int err;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
update_peer_seq(device, be32_to_cpu(p->seq_num));
@@ -5063,13 +5101,15 @@ static int got_NegAck(struct drbd_connection *connection, struct packet_info *pi
static int got_NegDReply(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_block_ack *p = pi->data;
sector_t sector = be64_to_cpu(p->sector);
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
update_peer_seq(device, be32_to_cpu(p->seq_num));
@@ -5083,14 +5123,16 @@ static int got_NegDReply(struct drbd_connection *connection, struct packet_info
static int got_NegRSDReply(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
sector_t sector;
int size;
struct p_block_ack *p = pi->data;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize);
@@ -5141,15 +5183,17 @@ static int got_BarrierAck(struct drbd_connection *connection, struct packet_info
static int got_OVResult(struct drbd_connection *connection, struct packet_info *pi)
{
+ struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_block_ack *p = pi->data;
struct drbd_work *w;
sector_t sector;
int size;
- device = vnr_to_device(connection, pi->vnr);
- if (!device)
+ peer_device = conn_peer_device(connection, pi->vnr);
+ if (!peer_device)
return -EIO;
+ device = peer_device->device;
sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize);
@@ -5178,7 +5222,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info *
if (w) {
w->cb = w_ov_finished;
w->device = device;
- drbd_queue_work(&first_peer_device(device)->connection->sender_work, w);
+ drbd_queue_work(&peer_device->connection->sender_work, w);
} else {
drbd_err(device, "kmalloc(w) failed.");
ov_out_of_sync_print(device);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 12/27] drbd: Pass a peer device to a number of fuctions
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (10 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 11/27] drbd: Replace vnr_to_mdev() with conn_peer_device() Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 13/27] drbd: Kill drbd_task_to_thread_name() Philipp Reisner
` (14 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
These functions actually operate on a peer device, or
need a peer device.
drbd_prepare_command(), drbd_send_command(), drbd_send_sync_param()
drbd_send_uuids(), drbd_gen_and_send_sync_uuid(), drbd_send_sizes()
drbd_send_state(), drbd_send_current_state(), and drbd_send_state_req()
drbd_send_sr_reply(), drbd_send_ack(), drbd_send_drequest(),
drbd_send_drequest_csum(), drbd_send_ov_request(), drbd_send_dblock()
drbd_send_block(), drbd_send_out_of_sync(), recv_dless_read()
drbd_drain_block(), receive_bitmap_plain(), recv_resync_read()
read_in_block(), read_for_csum(), drbd_alloc_pages(), drbd_alloc_peer_req()
need_peer_seq(), update_peer_seq(), wait_for_and_update_peer_seq()
drbd_sync_handshake(), drbd_asb_recover_{0,1,2}p(), drbd_connected()
drbd_disconnected(), decode_bitmap_c() and recv_bm_rle_bits()
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 48 +++----
drivers/block/drbd/drbd_main.c | 260 ++++++++++++++++++------------------
drivers/block/drbd/drbd_nl.c | 27 ++--
drivers/block/drbd/drbd_receiver.c | 253 +++++++++++++++++++----------------
drivers/block/drbd/drbd_state.c | 34 ++---
drivers/block/drbd/drbd_worker.c | 45 ++++---
6 files changed, 353 insertions(+), 314 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 461cf8d..b89e7ed 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -882,36 +882,36 @@ extern int drbd_send_all(struct drbd_connection *, struct socket *, void *, size
extern int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd);
extern int drbd_send_protocol(struct drbd_connection *connection);
-extern int drbd_send_uuids(struct drbd_device *device);
-extern int drbd_send_uuids_skip_initial_sync(struct drbd_device *device);
-extern void drbd_gen_and_send_sync_uuid(struct drbd_device *device);
-extern int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flags flags);
-extern int drbd_send_state(struct drbd_device *device, union drbd_state s);
-extern int drbd_send_current_state(struct drbd_device *device);
-extern int drbd_send_sync_param(struct drbd_device *device);
+extern int drbd_send_uuids(struct drbd_peer_device *);
+extern int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *);
+extern void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *);
+extern int drbd_send_sizes(struct drbd_peer_device *, int trigger_reply, enum dds_flags flags);
+extern int drbd_send_state(struct drbd_peer_device *, union drbd_state s);
+extern int drbd_send_current_state(struct drbd_peer_device *);
+extern int drbd_send_sync_param(struct drbd_peer_device *);
extern void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr,
u32 set_size);
-extern int drbd_send_ack(struct drbd_device *, enum drbd_packet,
+extern int drbd_send_ack(struct drbd_peer_device *, enum drbd_packet,
struct drbd_peer_request *);
-extern void drbd_send_ack_rp(struct drbd_device *device, enum drbd_packet cmd,
+extern void drbd_send_ack_rp(struct drbd_peer_device *, enum drbd_packet,
struct p_block_req *rp);
-extern void drbd_send_ack_dp(struct drbd_device *device, enum drbd_packet cmd,
+extern void drbd_send_ack_dp(struct drbd_peer_device *, enum drbd_packet,
struct p_data *dp, int data_size);
-extern int drbd_send_ack_ex(struct drbd_device *device, enum drbd_packet cmd,
+extern int drbd_send_ack_ex(struct drbd_peer_device *, enum drbd_packet,
sector_t sector, int blksize, u64 block_id);
-extern int drbd_send_out_of_sync(struct drbd_device *, struct drbd_request *);
-extern int drbd_send_block(struct drbd_device *, enum drbd_packet,
+extern int drbd_send_out_of_sync(struct drbd_peer_device *, struct drbd_request *);
+extern int drbd_send_block(struct drbd_peer_device *, enum drbd_packet,
struct drbd_peer_request *);
-extern int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req);
-extern int drbd_send_drequest(struct drbd_device *device, int cmd,
+extern int drbd_send_dblock(struct drbd_peer_device *, struct drbd_request *req);
+extern int drbd_send_drequest(struct drbd_peer_device *, int cmd,
sector_t sector, int size, u64 block_id);
-extern int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector,
+extern int drbd_send_drequest_csum(struct drbd_peer_device *, sector_t sector,
int size, void *digest, int digest_size,
enum drbd_packet cmd);
-extern int drbd_send_ov_request(struct drbd_device *device, sector_t sector, int size);
+extern int drbd_send_ov_request(struct drbd_peer_device *, sector_t sector, int size);
extern int drbd_send_bitmap(struct drbd_device *device);
-extern void drbd_send_sr_reply(struct drbd_device *device, enum drbd_state_rv retcode);
+extern void drbd_send_sr_reply(struct drbd_peer_device *, enum drbd_state_rv retcode);
extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode);
extern void drbd_free_bc(struct drbd_backing_dev *ldev);
extern void drbd_device_cleanup(struct drbd_device *device);
@@ -1338,18 +1338,18 @@ extern int drbd_submit_peer_request(struct drbd_device *,
struct drbd_peer_request *, const unsigned,
const int);
extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *);
-extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_device *, u64,
+extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64,
sector_t, unsigned int,
gfp_t) __must_hold(local);
extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *,
int);
#define drbd_free_peer_req(m,e) __drbd_free_peer_req(m, e, 0)
#define drbd_free_net_peer_req(m,e) __drbd_free_peer_req(m, e, 1)
-extern struct page *drbd_alloc_pages(struct drbd_device *, unsigned int, bool);
+extern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool);
extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);
extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed);
extern void conn_flush_workqueue(struct drbd_connection *connection);
-extern int drbd_connected(struct drbd_device *device);
+extern int drbd_connected(struct drbd_peer_device *);
static inline void drbd_flush_workqueue(struct drbd_device *device)
{
conn_flush_workqueue(first_peer_device(device)->connection);
@@ -1721,17 +1721,17 @@ static inline void request_ping(struct drbd_connection *connection)
}
extern void *conn_prepare_command(struct drbd_connection *, struct drbd_socket *);
-extern void *drbd_prepare_command(struct drbd_device *, struct drbd_socket *);
+extern void *drbd_prepare_command(struct drbd_peer_device *, struct drbd_socket *);
extern int conn_send_command(struct drbd_connection *, struct drbd_socket *,
enum drbd_packet, unsigned int, void *,
unsigned int);
-extern int drbd_send_command(struct drbd_device *, struct drbd_socket *,
+extern int drbd_send_command(struct drbd_peer_device *, struct drbd_socket *,
enum drbd_packet, unsigned int, void *,
unsigned int);
extern int drbd_send_ping(struct drbd_connection *connection);
extern int drbd_send_ping_ack(struct drbd_connection *connection);
-extern int drbd_send_state_req(struct drbd_device *, union drbd_state, union drbd_state);
+extern int drbd_send_state_req(struct drbd_peer_device *, union drbd_state, union drbd_state);
extern int conn_send_state_req(struct drbd_connection *, union drbd_state, union drbd_state);
static inline void drbd_thread_stop(struct drbd_thread *thi)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 7df2de8..f18a5d5 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -642,9 +642,9 @@ void *conn_prepare_command(struct drbd_connection *connection, struct drbd_socke
return p;
}
-void *drbd_prepare_command(struct drbd_device *device, struct drbd_socket *sock)
+void *drbd_prepare_command(struct drbd_peer_device *peer_device, struct drbd_socket *sock)
{
- return conn_prepare_command(first_peer_device(device)->connection, sock);
+ return conn_prepare_command(peer_device->connection, sock);
}
static int __send_command(struct drbd_connection *connection, int vnr,
@@ -691,14 +691,14 @@ int conn_send_command(struct drbd_connection *connection, struct drbd_socket *so
return err;
}
-int drbd_send_command(struct drbd_device *device, struct drbd_socket *sock,
+int drbd_send_command(struct drbd_peer_device *peer_device, struct drbd_socket *sock,
enum drbd_packet cmd, unsigned int header_size,
void *data, unsigned int size)
{
int err;
- err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, header_size,
- data, size);
+ err = __send_command(peer_device->connection, peer_device->device->vnr,
+ sock, cmd, header_size, data, size);
mutex_unlock(&sock->mutex);
return err;
}
@@ -723,23 +723,23 @@ int drbd_send_ping_ack(struct drbd_connection *connection)
return conn_send_command(connection, sock, P_PING_ACK, 0, NULL, 0);
}
-int drbd_send_sync_param(struct drbd_device *device)
+int drbd_send_sync_param(struct drbd_peer_device *peer_device)
{
struct drbd_socket *sock;
struct p_rs_param_95 *p;
int size;
- const int apv = first_peer_device(device)->connection->agreed_pro_version;
+ const int apv = peer_device->connection->agreed_pro_version;
enum drbd_packet cmd;
struct net_conf *nc;
struct disk_conf *dc;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
rcu_read_lock();
- nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
+ nc = rcu_dereference(peer_device->connection->net_conf);
size = apv <= 87 ? sizeof(struct p_rs_param)
: apv == 88 ? sizeof(struct p_rs_param)
@@ -752,14 +752,14 @@ int drbd_send_sync_param(struct drbd_device *device)
/* initialize verify_alg and csums_alg */
memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
- if (get_ldev(device)) {
- dc = rcu_dereference(device->ldev->disk_conf);
+ if (get_ldev(peer_device->device)) {
+ dc = rcu_dereference(peer_device->device->ldev->disk_conf);
p->resync_rate = cpu_to_be32(dc->resync_rate);
p->c_plan_ahead = cpu_to_be32(dc->c_plan_ahead);
p->c_delay_target = cpu_to_be32(dc->c_delay_target);
p->c_fill_target = cpu_to_be32(dc->c_fill_target);
p->c_max_rate = cpu_to_be32(dc->c_max_rate);
- put_ldev(device);
+ put_ldev(peer_device->device);
} else {
p->resync_rate = cpu_to_be32(DRBD_RESYNC_RATE_DEF);
p->c_plan_ahead = cpu_to_be32(DRBD_C_PLAN_AHEAD_DEF);
@@ -774,7 +774,7 @@ int drbd_send_sync_param(struct drbd_device *device)
strcpy(p->csums_alg, nc->csums_alg);
rcu_read_unlock();
- return drbd_send_command(device, sock, cmd, size, NULL, 0);
+ return drbd_send_command(peer_device, sock, cmd, size, NULL, 0);
}
int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd)
@@ -833,8 +833,9 @@ int drbd_send_protocol(struct drbd_connection *connection)
return err;
}
-int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags)
+static int _drbd_send_uuids(struct drbd_peer_device *peer_device, u64 uuid_flags)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_socket *sock;
struct p_uuids *p;
int i;
@@ -842,8 +843,8 @@ int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags)
if (!get_ldev_if_state(device, D_NEGOTIATING))
return 0;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p) {
put_ldev(device);
return -EIO;
@@ -856,24 +857,24 @@ int _drbd_send_uuids(struct drbd_device *device, u64 uuid_flags)
device->comm_bm_set = drbd_bm_total_weight(device);
p->uuid[UI_SIZE] = cpu_to_be64(device->comm_bm_set);
rcu_read_lock();
- uuid_flags |= rcu_dereference(first_peer_device(device)->connection->net_conf)->discard_my_data ? 1 : 0;
+ uuid_flags |= rcu_dereference(peer_device->connection->net_conf)->discard_my_data ? 1 : 0;
rcu_read_unlock();
uuid_flags |= test_bit(CRASHED_PRIMARY, &device->flags) ? 2 : 0;
uuid_flags |= device->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0;
p->uuid[UI_FLAGS] = cpu_to_be64(uuid_flags);
put_ldev(device);
- return drbd_send_command(device, sock, P_UUIDS, sizeof(*p), NULL, 0);
+ return drbd_send_command(peer_device, sock, P_UUIDS, sizeof(*p), NULL, 0);
}
-int drbd_send_uuids(struct drbd_device *device)
+int drbd_send_uuids(struct drbd_peer_device *peer_device)
{
- return _drbd_send_uuids(device, 0);
+ return _drbd_send_uuids(peer_device, 0);
}
-int drbd_send_uuids_skip_initial_sync(struct drbd_device *device)
+int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *peer_device)
{
- return _drbd_send_uuids(device, 8);
+ return _drbd_send_uuids(peer_device, 8);
}
void drbd_print_uuids(struct drbd_device *device, const char *text)
@@ -894,8 +895,9 @@ void drbd_print_uuids(struct drbd_device *device, const char *text)
}
}
-void drbd_gen_and_send_sync_uuid(struct drbd_device *device)
+void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *peer_device)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_socket *sock;
struct p_rs_uuid *p;
u64 uuid;
@@ -911,16 +913,17 @@ void drbd_gen_and_send_sync_uuid(struct drbd_device *device)
drbd_print_uuids(device, "updated sync UUID");
drbd_md_sync(device);
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (p) {
p->uuid = cpu_to_be64(uuid);
- drbd_send_command(device, sock, P_SYNC_UUID, sizeof(*p), NULL, 0);
+ drbd_send_command(peer_device, sock, P_SYNC_UUID, sizeof(*p), NULL, 0);
}
}
-int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flags flags)
+int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enum dds_flags flags)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_socket *sock;
struct p_sizes *p;
sector_t d_size, u_size;
@@ -944,14 +947,14 @@ int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flag
max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */
}
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
- if (first_peer_device(device)->connection->agreed_pro_version <= 94)
+ if (peer_device->connection->agreed_pro_version <= 94)
max_bio_size = min(max_bio_size, DRBD_MAX_SIZE_H80_PACKET);
- else if (first_peer_device(device)->connection->agreed_pro_version < 100)
+ else if (peer_device->connection->agreed_pro_version < 100)
max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE_P95);
p->d_size = cpu_to_be64(d_size);
@@ -960,29 +963,29 @@ int drbd_send_sizes(struct drbd_device *device, int trigger_reply, enum dds_flag
p->max_bio_size = cpu_to_be32(max_bio_size);
p->queue_order_type = cpu_to_be16(q_order_type);
p->dds_flags = cpu_to_be16(flags);
- return drbd_send_command(device, sock, P_SIZES, sizeof(*p), NULL, 0);
+ return drbd_send_command(peer_device, sock, P_SIZES, sizeof(*p), NULL, 0);
}
/**
* drbd_send_current_state() - Sends the drbd state to the peer
- * @device: DRBD device.
+ * @peer_device: DRBD peer device.
*/
-int drbd_send_current_state(struct drbd_device *device)
+int drbd_send_current_state(struct drbd_peer_device *peer_device)
{
struct drbd_socket *sock;
struct p_state *p;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
- p->state = cpu_to_be32(device->state.i); /* Within the send mutex */
- return drbd_send_command(device, sock, P_STATE, sizeof(*p), NULL, 0);
+ p->state = cpu_to_be32(peer_device->device->state.i); /* Within the send mutex */
+ return drbd_send_command(peer_device, sock, P_STATE, sizeof(*p), NULL, 0);
}
/**
* drbd_send_state() - After a state change, sends the new state to the peer
- * @device: DRBD device.
+ * @peer_device: DRBD peer device.
* @state: the state to send, not necessarily the current state.
*
* Each state change queues an "after_state_ch" work, which will eventually
@@ -990,31 +993,31 @@ int drbd_send_current_state(struct drbd_device *device)
* between queuing and processing of the after_state_ch work, we still
* want to send each intermediary state in the order it occurred.
*/
-int drbd_send_state(struct drbd_device *device, union drbd_state state)
+int drbd_send_state(struct drbd_peer_device *peer_device, union drbd_state state)
{
struct drbd_socket *sock;
struct p_state *p;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
p->state = cpu_to_be32(state.i); /* Within the send mutex */
- return drbd_send_command(device, sock, P_STATE, sizeof(*p), NULL, 0);
+ return drbd_send_command(peer_device, sock, P_STATE, sizeof(*p), NULL, 0);
}
-int drbd_send_state_req(struct drbd_device *device, union drbd_state mask, union drbd_state val)
+int drbd_send_state_req(struct drbd_peer_device *peer_device, union drbd_state mask, union drbd_state val)
{
struct drbd_socket *sock;
struct p_req_state *p;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
p->mask = cpu_to_be32(mask.i);
p->val = cpu_to_be32(val.i);
- return drbd_send_command(device, sock, P_STATE_CHG_REQ, sizeof(*p), NULL, 0);
+ return drbd_send_command(peer_device, sock, P_STATE_CHG_REQ, sizeof(*p), NULL, 0);
}
int conn_send_state_req(struct drbd_connection *connection, union drbd_state mask, union drbd_state val)
@@ -1033,16 +1036,16 @@ int conn_send_state_req(struct drbd_connection *connection, union drbd_state mas
return conn_send_command(connection, sock, cmd, sizeof(*p), NULL, 0);
}
-void drbd_send_sr_reply(struct drbd_device *device, enum drbd_state_rv retcode)
+void drbd_send_sr_reply(struct drbd_peer_device *peer_device, enum drbd_state_rv retcode)
{
struct drbd_socket *sock;
struct p_req_state_reply *p;
- sock = &first_peer_device(device)->connection->meta;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->meta;
+ p = drbd_prepare_command(peer_device, sock);
if (p) {
p->retcode = cpu_to_be32(retcode);
- drbd_send_command(device, sock, P_STATE_CHG_REPLY, sizeof(*p), NULL, 0);
+ drbd_send_command(peer_device, sock, P_STATE_CHG_REPLY, sizeof(*p), NULL, 0);
}
}
@@ -1311,42 +1314,42 @@ void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr, u32 set
* @blksize: size in byte, needs to be in big endian byte order
* @block_id: Id, big endian byte order
*/
-static int _drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd,
+static int _drbd_send_ack(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
u64 sector, u32 blksize, u64 block_id)
{
struct drbd_socket *sock;
struct p_block_ack *p;
- if (device->state.conn < C_CONNECTED)
+ if (peer_device->device->state.conn < C_CONNECTED)
return -EIO;
- sock = &first_peer_device(device)->connection->meta;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->meta;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
p->sector = sector;
p->block_id = block_id;
p->blksize = blksize;
- p->seq_num = cpu_to_be32(atomic_inc_return(&device->packet_seq));
- return drbd_send_command(device, sock, cmd, sizeof(*p), NULL, 0);
+ p->seq_num = cpu_to_be32(atomic_inc_return(&peer_device->device->packet_seq));
+ return drbd_send_command(peer_device, sock, cmd, sizeof(*p), NULL, 0);
}
/* dp->sector and dp->block_id already/still in network byte order,
* data_size is payload size according to dp->head,
* and may need to be corrected for digest size. */
-void drbd_send_ack_dp(struct drbd_device *device, enum drbd_packet cmd,
+void drbd_send_ack_dp(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct p_data *dp, int data_size)
{
- if (first_peer_device(device)->connection->peer_integrity_tfm)
- data_size -= crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
- _drbd_send_ack(device, cmd, dp->sector, cpu_to_be32(data_size),
+ if (peer_device->connection->peer_integrity_tfm)
+ data_size -= crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm);
+ _drbd_send_ack(peer_device, cmd, dp->sector, cpu_to_be32(data_size),
dp->block_id);
}
-void drbd_send_ack_rp(struct drbd_device *device, enum drbd_packet cmd,
+void drbd_send_ack_rp(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct p_block_req *rp)
{
- _drbd_send_ack(device, cmd, rp->sector, rp->blksize, rp->block_id);
+ _drbd_send_ack(peer_device, cmd, rp->sector, rp->blksize, rp->block_id);
}
/**
@@ -1355,10 +1358,10 @@ void drbd_send_ack_rp(struct drbd_device *device, enum drbd_packet cmd,
* @cmd: packet command code
* @peer_req: peer request
*/
-int drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd,
+int drbd_send_ack(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct drbd_peer_request *peer_req)
{
- return _drbd_send_ack(device, cmd,
+ return _drbd_send_ack(peer_device, cmd,
cpu_to_be64(peer_req->i.sector),
cpu_to_be32(peer_req->i.size),
peer_req->block_id);
@@ -1366,32 +1369,32 @@ int drbd_send_ack(struct drbd_device *device, enum drbd_packet cmd,
/* This function misuses the block_id field to signal if the blocks
* are is sync or not. */
-int drbd_send_ack_ex(struct drbd_device *device, enum drbd_packet cmd,
+int drbd_send_ack_ex(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
sector_t sector, int blksize, u64 block_id)
{
- return _drbd_send_ack(device, cmd,
+ return _drbd_send_ack(peer_device, cmd,
cpu_to_be64(sector),
cpu_to_be32(blksize),
cpu_to_be64(block_id));
}
-int drbd_send_drequest(struct drbd_device *device, int cmd,
+int drbd_send_drequest(struct drbd_peer_device *peer_device, int cmd,
sector_t sector, int size, u64 block_id)
{
struct drbd_socket *sock;
struct p_block_req *p;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
p->sector = cpu_to_be64(sector);
p->block_id = block_id;
p->blksize = cpu_to_be32(size);
- return drbd_send_command(device, sock, cmd, sizeof(*p), NULL, 0);
+ return drbd_send_command(peer_device, sock, cmd, sizeof(*p), NULL, 0);
}
-int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector, int size,
+int drbd_send_drequest_csum(struct drbd_peer_device *peer_device, sector_t sector, int size,
void *digest, int digest_size, enum drbd_packet cmd)
{
struct drbd_socket *sock;
@@ -1399,30 +1402,29 @@ int drbd_send_drequest_csum(struct drbd_device *device, sector_t sector, int siz
/* FIXME: Put the digest into the preallocated socket buffer. */
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
p->sector = cpu_to_be64(sector);
p->block_id = ID_SYNCER /* unused */;
p->blksize = cpu_to_be32(size);
- return drbd_send_command(device, sock, cmd, sizeof(*p),
- digest, digest_size);
+ return drbd_send_command(peer_device, sock, cmd, sizeof(*p), digest, digest_size);
}
-int drbd_send_ov_request(struct drbd_device *device, sector_t sector, int size)
+int drbd_send_ov_request(struct drbd_peer_device *peer_device, sector_t sector, int size)
{
struct drbd_socket *sock;
struct p_block_req *p;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
p->sector = cpu_to_be64(sector);
p->block_id = ID_SYNCER /* unused */;
p->blksize = cpu_to_be32(size);
- return drbd_send_command(device, sock, P_OV_REQUEST, sizeof(*p), NULL, 0);
+ return drbd_send_command(peer_device, sock, P_OV_REQUEST, sizeof(*p), NULL, 0);
}
/* called on sndtimeo
@@ -1480,26 +1482,26 @@ static void drbd_update_congested(struct drbd_connection *connection)
* As a workaround, we disable sendpage on pages
* with page_count == 0 or PageSlab.
*/
-static int _drbd_no_send_page(struct drbd_device *device, struct page *page,
+static int _drbd_no_send_page(struct drbd_peer_device *peer_device, struct page *page,
int offset, size_t size, unsigned msg_flags)
{
struct socket *socket;
void *addr;
int err;
- socket = first_peer_device(device)->connection->data.socket;
+ socket = peer_device->connection->data.socket;
addr = kmap(page) + offset;
- err = drbd_send_all(first_peer_device(device)->connection, socket, addr, size, msg_flags);
+ err = drbd_send_all(peer_device->connection, socket, addr, size, msg_flags);
kunmap(page);
if (!err)
- device->send_cnt += size >> 9;
+ peer_device->device->send_cnt += size >> 9;
return err;
}
-static int _drbd_send_page(struct drbd_device *device, struct page *page,
+static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *page,
int offset, size_t size, unsigned msg_flags)
{
- struct socket *socket = first_peer_device(device)->connection->data.socket;
+ struct socket *socket = peer_device->connection->data.socket;
mm_segment_t oldfs = get_fs();
int len = size;
int err = -EIO;
@@ -1511,10 +1513,10 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page,
* __page_cache_release a page that would actually still be referenced
* by someone, leading to some obscure delayed Oops somewhere else. */
if (disable_sendpage || (page_count(page) < 1) || PageSlab(page))
- return _drbd_no_send_page(device, page, offset, size, msg_flags);
+ return _drbd_no_send_page(peer_device, page, offset, size, msg_flags);
msg_flags |= MSG_NOSIGNAL;
- drbd_update_congested(first_peer_device(device)->connection);
+ drbd_update_congested(peer_device->connection);
set_fs(KERNEL_DS);
do {
int sent;
@@ -1522,11 +1524,11 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page,
sent = socket->ops->sendpage(socket, page, offset, len, msg_flags);
if (sent <= 0) {
if (sent == -EAGAIN) {
- if (we_should_drop_the_connection(first_peer_device(device)->connection, socket))
+ if (we_should_drop_the_connection(peer_device->connection, socket))
break;
continue;
}
- drbd_warn(device, "%s: size=%d len=%d sent=%d\n",
+ drbd_warn(peer_device->device, "%s: size=%d len=%d sent=%d\n",
__func__, (int)size, len, sent);
if (sent < 0)
err = sent;
@@ -1536,16 +1538,16 @@ static int _drbd_send_page(struct drbd_device *device, struct page *page,
offset += sent;
} while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/);
set_fs(oldfs);
- clear_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags);
+ clear_bit(NET_CONGESTED, &peer_device->connection->flags);
if (len == 0) {
err = 0;
- device->send_cnt += size >> 9;
+ peer_device->device->send_cnt += size >> 9;
}
return err;
}
-static int _drbd_send_bio(struct drbd_device *device, struct bio *bio)
+static int _drbd_send_bio(struct drbd_peer_device *peer_device, struct bio *bio)
{
struct bio_vec bvec;
struct bvec_iter iter;
@@ -1554,7 +1556,7 @@ static int _drbd_send_bio(struct drbd_device *device, struct bio *bio)
bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_no_send_page(device, bvec.bv_page,
+ err = _drbd_no_send_page(peer_device, bvec.bv_page,
bvec.bv_offset, bvec.bv_len,
bio_iter_last(bvec, iter)
? 0 : MSG_MORE);
@@ -1564,7 +1566,7 @@ static int _drbd_send_bio(struct drbd_device *device, struct bio *bio)
return 0;
}
-static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio)
+static int _drbd_send_zc_bio(struct drbd_peer_device *peer_device, struct bio *bio)
{
struct bio_vec bvec;
struct bvec_iter iter;
@@ -1573,7 +1575,7 @@ static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio)
bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_send_page(device, bvec.bv_page,
+ err = _drbd_send_page(peer_device, bvec.bv_page,
bvec.bv_offset, bvec.bv_len,
bio_iter_last(bvec, iter) ? 0 : MSG_MORE);
if (err)
@@ -1582,7 +1584,7 @@ static int _drbd_send_zc_bio(struct drbd_device *device, struct bio *bio)
return 0;
}
-static int _drbd_send_zc_ee(struct drbd_device *device,
+static int _drbd_send_zc_ee(struct drbd_peer_device *peer_device,
struct drbd_peer_request *peer_req)
{
struct page *page = peer_req->pages;
@@ -1593,7 +1595,7 @@ static int _drbd_send_zc_ee(struct drbd_device *device,
page_chain_for_each(page) {
unsigned l = min_t(unsigned, len, PAGE_SIZE);
- err = _drbd_send_page(device, page, 0, l,
+ err = _drbd_send_page(peer_device, page, 0, l,
page_chain_next(page) ? MSG_MORE : 0);
if (err)
return err;
@@ -1602,9 +1604,9 @@ static int _drbd_send_zc_ee(struct drbd_device *device,
return 0;
}
-static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw)
+static u32 bio_flags_to_wire(struct drbd_connection *connection, unsigned long bi_rw)
{
- if (first_peer_device(device)->connection->agreed_pro_version >= 95)
+ if (connection->agreed_pro_version >= 95)
return (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
(bi_rw & REQ_FUA ? DP_FUA : 0) |
(bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
@@ -1616,29 +1618,30 @@ static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw)
/* Used to send write requests
* R_PRIMARY -> Peer (P_DATA)
*/
-int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
+int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *req)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_socket *sock;
struct p_data *p;
unsigned int dp_flags = 0;
int dgs;
int err;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
- dgs = first_peer_device(device)->connection->integrity_tfm ?
- crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
+ dgs = peer_device->connection->integrity_tfm ?
+ crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;
if (!p)
return -EIO;
p->sector = cpu_to_be64(req->i.sector);
p->block_id = (unsigned long)req;
p->seq_num = cpu_to_be32(atomic_inc_return(&device->packet_seq));
- dp_flags = bio_flags_to_wire(device, req->master_bio->bi_rw);
+ dp_flags = bio_flags_to_wire(peer_device->connection, req->master_bio->bi_rw);
if (device->state.conn >= C_SYNC_SOURCE &&
device->state.conn <= C_PAUSED_SYNC_T)
dp_flags |= DP_MAY_SET_IN_SYNC;
- if (first_peer_device(device)->connection->agreed_pro_version >= 100) {
+ if (peer_device->connection->agreed_pro_version >= 100) {
if (req->rq_state & RQ_EXP_RECEIVE_ACK)
dp_flags |= DP_SEND_RECEIVE_ACK;
if (req->rq_state & RQ_EXP_WRITE_ACK)
@@ -1646,8 +1649,8 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
}
p->dp_flags = cpu_to_be32(dp_flags);
if (dgs)
- drbd_csum_bio(first_peer_device(device)->connection->integrity_tfm, req->master_bio, p + 1);
- err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
+ drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, p + 1);
+ err = __send_command(peer_device->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
if (!err) {
/* For protocol A, we have to memcpy the payload into
* socket buffers, as we may complete right away
@@ -1661,16 +1664,16 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
* receiving side, we sure have detected corruption elsewhere.
*/
if (!(req->rq_state & (RQ_EXP_RECEIVE_ACK | RQ_EXP_WRITE_ACK)) || dgs)
- err = _drbd_send_bio(device, req->master_bio);
+ err = _drbd_send_bio(peer_device, req->master_bio);
else
- err = _drbd_send_zc_bio(device, req->master_bio);
+ err = _drbd_send_zc_bio(peer_device, req->master_bio);
/* double check digest, sometimes buffers have been modified in flight. */
if (dgs > 0 && dgs <= 64) {
/* 64 byte, 512 bit, is the largest digest size
* currently supported in kernel crypto. */
unsigned char digest[64];
- drbd_csum_bio(first_peer_device(device)->connection->integrity_tfm, req->master_bio, digest);
+ drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, digest);
if (memcmp(p + 1, digest, dgs)) {
drbd_warn(device,
"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
@@ -1689,19 +1692,20 @@ int drbd_send_dblock(struct drbd_device *device, struct drbd_request *req)
* Peer -> (diskless) R_PRIMARY (P_DATA_REPLY)
* C_SYNC_SOURCE -> C_SYNC_TARGET (P_RS_DATA_REPLY)
*/
-int drbd_send_block(struct drbd_device *device, enum drbd_packet cmd,
+int drbd_send_block(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct drbd_peer_request *peer_req)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_socket *sock;
struct p_data *p;
int err;
int dgs;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
- dgs = first_peer_device(device)->connection->integrity_tfm ?
- crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
+ dgs = peer_device->connection->integrity_tfm ?
+ crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;
if (!p)
return -EIO;
@@ -1710,27 +1714,27 @@ int drbd_send_block(struct drbd_device *device, enum drbd_packet cmd,
p->seq_num = 0; /* unused */
p->dp_flags = 0;
if (dgs)
- drbd_csum_ee(first_peer_device(device)->connection->integrity_tfm, peer_req, p + 1);
- err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
+ drbd_csum_ee(peer_device->connection->integrity_tfm, peer_req, p + 1);
+ err = __send_command(peer_device->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
if (!err)
- err = _drbd_send_zc_ee(device, peer_req);
+ err = _drbd_send_zc_ee(peer_device, peer_req);
mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */
return err;
}
-int drbd_send_out_of_sync(struct drbd_device *device, struct drbd_request *req)
+int drbd_send_out_of_sync(struct drbd_peer_device *peer_device, struct drbd_request *req)
{
struct drbd_socket *sock;
struct p_block_desc *p;
- sock = &first_peer_device(device)->connection->data;
- p = drbd_prepare_command(device, sock);
+ sock = &peer_device->connection->data;
+ p = drbd_prepare_command(peer_device, sock);
if (!p)
return -EIO;
p->sector = cpu_to_be64(req->i.sector);
p->blksize = cpu_to_be32(req->i.size);
- return drbd_send_command(device, sock, P_OUT_OF_SYNC, sizeof(*p), NULL, 0);
+ return drbd_send_command(peer_device, sock, P_OUT_OF_SYNC, sizeof(*p), NULL, 0);
}
/*
@@ -2795,8 +2799,10 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
/* inherit the connection state */
device->state.conn = first_connection(resource)->cstate;
- if (device->state.conn == C_WF_REPORT_PARAMS)
- drbd_connected(device);
+ if (device->state.conn == C_WF_REPORT_PARAMS) {
+ for_each_peer_device(peer_device, device)
+ drbd_connected(peer_device);
+ }
return NO_ERROR;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index f7d62ff..f613ba9 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -678,8 +678,8 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force)
if (device->state.conn >= C_WF_REPORT_PARAMS) {
/* if this was forced, we should consider sync */
if (forced)
- drbd_send_uuids(device);
- drbd_send_current_state(device);
+ drbd_send_uuids(first_peer_device(device));
+ drbd_send_current_state(first_peer_device(device));
}
drbd_md_sync(device);
@@ -1364,8 +1364,12 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
drbd_md_sync(device);
- if (device->state.conn >= C_CONNECTED)
- drbd_send_sync_param(device);
+ if (device->state.conn >= C_CONNECTED) {
+ struct drbd_peer_device *peer_device;
+
+ for_each_peer_device(peer_device, device)
+ drbd_send_sync_param(peer_device);
+ }
synchronize_rcu();
kfree(old_disk_conf);
@@ -2145,8 +2149,13 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
synchronize_rcu();
kfree(old_net_conf);
- if (connection->cstate >= C_WF_REPORT_PARAMS)
- drbd_send_sync_param(minor_to_device(conn_lowest_minor(connection)));
+ if (connection->cstate >= C_WF_REPORT_PARAMS) {
+ struct drbd_peer_device *peer_device;
+ int vnr;
+
+ idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
+ drbd_send_sync_param(peer_device);
+ }
goto done;
@@ -2514,8 +2523,8 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
if (dd == DS_GREW)
set_bit(RESIZE_PENDING, &device->flags);
- drbd_send_uuids(device);
- drbd_send_sizes(device, 1, ddsf);
+ drbd_send_uuids(first_peer_device(device));
+ drbd_send_sizes(first_peer_device(device), 1, ddsf);
}
fail:
@@ -3244,7 +3253,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
retcode = ERR_IO_MD_DISK;
}
if (skip_initial_sync) {
- drbd_send_uuids_skip_initial_sync(device);
+ drbd_send_uuids_skip_initial_sync(first_peer_device(device));
_drbd_uuid_set(device, UI_BITMAP, 0);
drbd_print_uuids(device, "cleared bitmap UUID");
spin_lock_irq(&device->resource->req_lock);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index edd5cac..9ccb856 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -64,7 +64,7 @@ enum finish_epoch {
static int drbd_do_features(struct drbd_connection *connection);
static int drbd_do_auth(struct drbd_connection *connection);
-static int drbd_disconnected(struct drbd_device *device);
+static int drbd_disconnected(struct drbd_peer_device *);
static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *, struct drbd_epoch *, enum epoch_event);
static int e_end_block(struct drbd_work *, int);
@@ -241,9 +241,10 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
*
* Returns a page chain linked via page->private.
*/
-struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number,
+struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int number,
bool retry)
{
+ struct drbd_device *device = peer_device->device;
struct page *page = NULL;
struct net_conf *nc;
DEFINE_WAIT(wait);
@@ -252,7 +253,7 @@ struct page *drbd_alloc_pages(struct drbd_device *device, unsigned int number,
/* Yes, we may run up to @number over max_buffers. If we
* follow it strictly, the admin will get it wrong anyways. */
rcu_read_lock();
- nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
+ nc = rcu_dereference(peer_device->connection->net_conf);
mxb = nc ? nc->max_buffers : 1000000;
rcu_read_unlock();
@@ -331,9 +332,10 @@ You must not have the req_lock:
*/
struct drbd_peer_request *
-drbd_alloc_peer_req(struct drbd_device *device, u64 id, sector_t sector,
+drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
unsigned int data_size, gfp_t gfp_mask) __must_hold(local)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_peer_request *peer_req;
struct page *page = NULL;
unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
@@ -349,7 +351,7 @@ drbd_alloc_peer_req(struct drbd_device *device, u64 id, sector_t sector,
}
if (data_size) {
- page = drbd_alloc_pages(device, nr_pages, (gfp_mask & __GFP_WAIT));
+ page = drbd_alloc_pages(peer_device, nr_pages, (gfp_mask & __GFP_WAIT));
if (!page)
goto fail;
}
@@ -831,24 +833,25 @@ static int drbd_socket_okay(struct socket **sock)
}
/* Gets called if a connection is established, or if a new minor gets created
in a connection */
-int drbd_connected(struct drbd_device *device)
+int drbd_connected(struct drbd_peer_device *peer_device)
{
+ struct drbd_device *device = peer_device->device;
int err;
atomic_set(&device->packet_seq, 0);
device->peer_seq = 0;
- device->state_mutex = first_peer_device(device)->connection->agreed_pro_version < 100 ?
- &first_peer_device(device)->connection->cstate_mutex :
+ device->state_mutex = peer_device->connection->agreed_pro_version < 100 ?
+ &peer_device->connection->cstate_mutex :
&device->own_state_mutex;
- err = drbd_send_sync_param(device);
+ err = drbd_send_sync_param(peer_device);
if (!err)
- err = drbd_send_sizes(device, 0, 0);
+ err = drbd_send_sizes(peer_device, 0, 0);
if (!err)
- err = drbd_send_uuids(device);
+ err = drbd_send_uuids(peer_device);
if (!err)
- err = drbd_send_current_state(device);
+ err = drbd_send_current_state(peer_device);
clear_bit(USE_DEGR_WFC_T, &device->flags);
clear_bit(RESIZE_PENDING, &device->flags);
atomic_set(&device->ap_in_flight, 0);
@@ -1058,7 +1061,7 @@ randomize:
else
clear_bit(DISCARD_MY_DATA, &device->flags);
- drbd_connected(device);
+ drbd_connected(peer_device);
kref_put(&device->kref, drbd_destroy_device);
rcu_read_lock();
}
@@ -1498,25 +1501,26 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf
/* used from receive_RSDataReply (recv_resync_read)
* and from receive_Data */
static struct drbd_peer_request *
-read_in_block(struct drbd_device *device, u64 id, sector_t sector,
+read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
int data_size) __must_hold(local)
{
+ struct drbd_device *device = peer_device->device;
const sector_t capacity = drbd_get_capacity(device->this_bdev);
struct drbd_peer_request *peer_req;
struct page *page;
int dgs, ds, err;
- void *dig_in = first_peer_device(device)->connection->int_dig_in;
- void *dig_vv = first_peer_device(device)->connection->int_dig_vv;
+ void *dig_in = peer_device->connection->int_dig_in;
+ void *dig_vv = peer_device->connection->int_dig_vv;
unsigned long *data;
dgs = 0;
- if (first_peer_device(device)->connection->peer_integrity_tfm) {
- dgs = crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
+ if (peer_device->connection->peer_integrity_tfm) {
+ dgs = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm);
/*
* FIXME: Receive the incoming digest into the receive buffer
* here, together with its struct p_data?
*/
- err = drbd_recv_all_warn(first_peer_device(device)->connection, dig_in, dgs);
+ err = drbd_recv_all_warn(peer_device->connection, dig_in, dgs);
if (err)
return NULL;
data_size -= dgs;
@@ -1540,7 +1544,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
* "criss-cross" setup, that might cause write-out on some other DRBD,
* which in turn might block on the other node at this very place. */
- peer_req = drbd_alloc_peer_req(device, id, sector, data_size, GFP_NOIO);
+ peer_req = drbd_alloc_peer_req(peer_device, id, sector, data_size, GFP_NOIO);
if (!peer_req)
return NULL;
@@ -1552,7 +1556,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
page_chain_for_each(page) {
unsigned len = min_t(int, ds, PAGE_SIZE);
data = kmap(page);
- err = drbd_recv_all_warn(first_peer_device(device)->connection, data, len);
+ err = drbd_recv_all_warn(peer_device->connection, data, len);
if (drbd_insert_fault(device, DRBD_FAULT_RECEIVE)) {
drbd_err(device, "Fault injection: Corrupting data on receive\n");
data[0] = data[0] ^ (unsigned long)-1;
@@ -1566,7 +1570,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
}
if (dgs) {
- drbd_csum_ee(first_peer_device(device)->connection->peer_integrity_tfm, peer_req, dig_vv);
+ drbd_csum_ee(peer_device->connection->peer_integrity_tfm, peer_req, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
drbd_err(device, "Digest integrity check FAILED: %llus +%u\n",
(unsigned long long)sector, data_size);
@@ -1581,7 +1585,7 @@ read_in_block(struct drbd_device *device, u64 id, sector_t sector,
/* drbd_drain_block() just takes a data block
* out of the socket input buffer, and discards it.
*/
-static int drbd_drain_block(struct drbd_device *device, int data_size)
+static int drbd_drain_block(struct drbd_peer_device *peer_device, int data_size)
{
struct page *page;
int err = 0;
@@ -1590,36 +1594,36 @@ static int drbd_drain_block(struct drbd_device *device, int data_size)
if (!data_size)
return 0;
- page = drbd_alloc_pages(device, 1, 1);
+ page = drbd_alloc_pages(peer_device, 1, 1);
data = kmap(page);
while (data_size) {
unsigned int len = min_t(int, data_size, PAGE_SIZE);
- err = drbd_recv_all_warn(first_peer_device(device)->connection, data, len);
+ err = drbd_recv_all_warn(peer_device->connection, data, len);
if (err)
break;
data_size -= len;
}
kunmap(page);
- drbd_free_pages(device, page, 0);
+ drbd_free_pages(peer_device->device, page, 0);
return err;
}
-static int recv_dless_read(struct drbd_device *device, struct drbd_request *req,
+static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_request *req,
sector_t sector, int data_size)
{
struct bio_vec bvec;
struct bvec_iter iter;
struct bio *bio;
int dgs, err, expect;
- void *dig_in = first_peer_device(device)->connection->int_dig_in;
- void *dig_vv = first_peer_device(device)->connection->int_dig_vv;
+ void *dig_in = peer_device->connection->int_dig_in;
+ void *dig_vv = peer_device->connection->int_dig_vv;
dgs = 0;
- if (first_peer_device(device)->connection->peer_integrity_tfm) {
- dgs = crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
- err = drbd_recv_all_warn(first_peer_device(device)->connection, dig_in, dgs);
+ if (peer_device->connection->peer_integrity_tfm) {
+ dgs = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm);
+ err = drbd_recv_all_warn(peer_device->connection, dig_in, dgs);
if (err)
return err;
data_size -= dgs;
@@ -1627,15 +1631,15 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req,
/* optimistically update recv_cnt. if receiving fails below,
* we disconnect anyways, and counters will be reset. */
- device->recv_cnt += data_size>>9;
+ peer_device->device->recv_cnt += data_size>>9;
bio = req->master_bio;
- D_ASSERT(device, sector == bio->bi_iter.bi_sector);
+ D_ASSERT(peer_device->device, sector == bio->bi_iter.bi_sector);
bio_for_each_segment(bvec, bio, iter) {
void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
expect = min_t(int, data_size, bvec.bv_len);
- err = drbd_recv_all_warn(first_peer_device(device)->connection, mapped, expect);
+ err = drbd_recv_all_warn(peer_device->connection, mapped, expect);
kunmap(bvec.bv_page);
if (err)
return err;
@@ -1643,14 +1647,14 @@ static int recv_dless_read(struct drbd_device *device, struct drbd_request *req,
}
if (dgs) {
- drbd_csum_bio(first_peer_device(device)->connection->peer_integrity_tfm, bio, dig_vv);
+ drbd_csum_bio(peer_device->connection->peer_integrity_tfm, bio, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
- drbd_err(device, "Digest integrity check FAILED. Broken NICs?\n");
+ drbd_err(peer_device, "Digest integrity check FAILED. Broken NICs?\n");
return -EINVAL;
}
}
- D_ASSERT(device, data_size == 0);
+ D_ASSERT(peer_device->device, data_size == 0);
return 0;
}
@@ -1670,23 +1674,25 @@ static int e_end_resync_block(struct drbd_work *w, int unused)
if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
drbd_set_in_sync(device, sector, peer_req->i.size);
- err = drbd_send_ack(device, P_RS_WRITE_ACK, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_RS_WRITE_ACK, peer_req);
} else {
/* Record failure to sync */
drbd_rs_failed_io(device, sector, peer_req->i.size);
- err = drbd_send_ack(device, P_NEG_ACK, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_NEG_ACK, peer_req);
}
dec_unacked(device);
return err;
}
-static int recv_resync_read(struct drbd_device *device, sector_t sector, int data_size) __releases(local)
+static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t sector,
+ int data_size) __releases(local)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_peer_request *peer_req;
- peer_req = read_in_block(device, ID_SYNCER, sector, data_size);
+ peer_req = read_in_block(peer_device, ID_SYNCER, sector, data_size);
if (!peer_req)
goto fail;
@@ -1760,7 +1766,7 @@ static int receive_DataReply(struct drbd_connection *connection, struct packet_i
/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
* special casing it there for the various failure cases.
* still no race with drbd_fail_pending_reads */
- err = recv_dless_read(device, req, sector, pi->size);
+ err = recv_dless_read(peer_device, req, sector, pi->size);
if (!err)
req_mod(req, DATA_RECEIVED);
/* else: nothing. handled from drbd_disconnect...
@@ -1790,14 +1796,14 @@ static int receive_RSDataReply(struct drbd_connection *connection, struct packet
/* data is submitted to disk within recv_resync_read.
* corresponding put_ldev done below on error,
* or in drbd_peer_request_endio. */
- err = recv_resync_read(device, sector, pi->size);
+ err = recv_resync_read(peer_device, sector, pi->size);
} else {
if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Can not write resync data to local disk.\n");
- err = drbd_drain_block(device, pi->size);
+ err = drbd_drain_block(peer_device, pi->size);
- drbd_send_ack_dp(device, P_NEG_ACK, p, pi->size);
+ drbd_send_ack_dp(peer_device, P_NEG_ACK, p, pi->size);
}
atomic_add(pi->size >> 9, &device->rs_sect_in);
@@ -1841,11 +1847,11 @@ static int e_end_block(struct drbd_work *w, int cancel)
device->state.conn <= C_PAUSED_SYNC_T &&
peer_req->flags & EE_MAY_SET_IN_SYNC) ?
P_RS_WRITE_ACK : P_WRITE_ACK;
- err = drbd_send_ack(device, pcmd, peer_req);
+ err = drbd_send_ack(first_peer_device(device), pcmd, peer_req);
if (pcmd == P_RS_WRITE_ACK)
drbd_set_in_sync(device, sector, peer_req->i.size);
} else {
- err = drbd_send_ack(device, P_NEG_ACK, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_NEG_ACK, peer_req);
/* we expect it to be marked out of sync anyways...
* maybe assert this? */
}
@@ -1875,7 +1881,7 @@ static int e_send_ack(struct drbd_work *w, enum drbd_packet ack)
container_of(w, struct drbd_peer_request, w);
int err;
- err = drbd_send_ack(device, ack, peer_req);
+ err = drbd_send_ack(first_peer_device(device), ack, peer_req);
dec_unacked(device);
return err;
@@ -1909,11 +1915,12 @@ static u32 seq_max(u32 a, u32 b)
return seq_greater(a, b) ? a : b;
}
-static void update_peer_seq(struct drbd_device *device, unsigned int peer_seq)
+static void update_peer_seq(struct drbd_peer_device *peer_device, unsigned int peer_seq)
{
+ struct drbd_device *device = peer_device->device;
unsigned int newest_peer_seq;
- if (test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)) {
+ if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)) {
spin_lock(&device->peer_seq_lock);
newest_peer_seq = seq_max(device->peer_seq, peer_seq);
device->peer_seq = newest_peer_seq;
@@ -1969,13 +1976,14 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee
*
* returns 0 if we may process the packet,
* -ERESTARTSYS if we were interrupted (by disconnect signal). */
-static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 peer_seq)
+static int wait_for_and_update_peer_seq(struct drbd_peer_device *peer_device, const u32 peer_seq)
{
+ struct drbd_device *device = peer_device->device;
DEFINE_WAIT(wait);
long timeout;
int ret = 0, tp;
- if (!test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags))
+ if (!test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags))
return 0;
spin_lock(&device->peer_seq_lock);
@@ -2001,7 +2009,7 @@ static int wait_for_and_update_peer_seq(struct drbd_device *device, const u32 pe
prepare_to_wait(&device->seq_wait, &wait, TASK_INTERRUPTIBLE);
spin_unlock(&device->peer_seq_lock);
rcu_read_lock();
- timeout = rcu_dereference(first_peer_device(device)->connection->net_conf)->ping_timeo*HZ/10;
+ timeout = rcu_dereference(peer_device->connection->net_conf)->ping_timeo*HZ/10;
rcu_read_unlock();
timeout = schedule_timeout(timeout);
spin_lock(&device->peer_seq_lock);
@@ -2182,10 +2190,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
if (!get_ldev(device)) {
int err2;
- err = wait_for_and_update_peer_seq(device, peer_seq);
- drbd_send_ack_dp(device, P_NEG_ACK, p, pi->size);
+ err = wait_for_and_update_peer_seq(peer_device, peer_seq);
+ drbd_send_ack_dp(peer_device, P_NEG_ACK, p, pi->size);
atomic_inc(&connection->current_epoch->epoch_size);
- err2 = drbd_drain_block(device, pi->size);
+ err2 = drbd_drain_block(peer_device, pi->size);
if (!err)
err = err2;
return err;
@@ -2198,7 +2206,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
*/
sector = be64_to_cpu(p->sector);
- peer_req = read_in_block(device, p->block_id, sector, pi->size);
+ peer_req = read_in_block(peer_device, p->block_id, sector, pi->size);
if (!peer_req) {
put_ldev(device);
return -EIO;
@@ -2227,7 +2235,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
rcu_read_unlock();
if (tp) {
peer_req->flags |= EE_IN_INTERVAL_TREE;
- err = wait_for_and_update_peer_seq(device, peer_seq);
+ err = wait_for_and_update_peer_seq(peer_device, peer_seq);
if (err)
goto out_interrupted;
spin_lock_irq(&device->resource->req_lock);
@@ -2241,7 +2249,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
goto out_interrupted;
}
} else {
- update_peer_seq(device, peer_seq);
+ update_peer_seq(peer_device, peer_seq);
spin_lock_irq(&device->resource->req_lock);
}
list_add(&peer_req->w.list, &device->active_ee);
@@ -2273,7 +2281,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
if (dp_flags & DP_SEND_RECEIVE_ACK) {
/* I really don't like it that the receiver thread
* sends on the msock, but anyways */
- drbd_send_ack(device, P_RECV_ACK, peer_req);
+ drbd_send_ack(first_peer_device(device), P_RECV_ACK, peer_req);
}
if (device->state.pdsk < D_INCONSISTENT) {
@@ -2412,17 +2420,17 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
verb = 1;
switch (pi->cmd) {
case P_DATA_REQUEST:
- drbd_send_ack_rp(device, P_NEG_DREPLY, p);
+ drbd_send_ack_rp(peer_device, P_NEG_DREPLY, p);
break;
case P_RS_DATA_REQUEST:
case P_CSUM_RS_REQUEST:
case P_OV_REQUEST:
- drbd_send_ack_rp(device, P_NEG_RS_DREPLY , p);
+ drbd_send_ack_rp(peer_device, P_NEG_RS_DREPLY , p);
break;
case P_OV_REPLY:
verb = 0;
dec_rs_pending(device);
- drbd_send_ack_ex(device, P_OV_RESULT, sector, size, ID_IN_SYNC);
+ drbd_send_ack_ex(peer_device, P_OV_RESULT, sector, size, ID_IN_SYNC);
break;
default:
BUG();
@@ -2432,13 +2440,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
"no local data.\n");
/* drain possibly payload */
- return drbd_drain_block(device, pi->size);
+ return drbd_drain_block(peer_device, pi->size);
}
/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
* "criss-cross" setup, that might cause write-out on some other DRBD,
* which in turn might block on the other node at this very place. */
- peer_req = drbd_alloc_peer_req(device, p->block_id, sector, size, GFP_NOIO);
+ peer_req = drbd_alloc_peer_req(peer_device, p->block_id, sector, size, GFP_NOIO);
if (!peer_req) {
put_ldev(device);
return -ENOMEM;
@@ -2566,8 +2574,12 @@ out_free_e:
return -EIO;
}
-static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
+/**
+ * drbd_asb_recover_0p - Recover after split-brain with no remaining primaries
+ */
+static int drbd_asb_recover_0p(struct drbd_peer_device *peer_device) __must_hold(local)
{
+ struct drbd_device *device = peer_device->device;
int self, peer, rv = -100;
unsigned long ch_self, ch_peer;
enum drbd_after_sb_p after_sb_0p;
@@ -2579,7 +2591,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
ch_self = device->comm_bm_set;
rcu_read_lock();
- after_sb_0p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_0p;
+ after_sb_0p = rcu_dereference(peer_device->connection->net_conf)->after_sb_0p;
rcu_read_unlock();
switch (after_sb_0p) {
case ASB_CONSENSUS:
@@ -2614,7 +2626,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
"Using discard-least-changes instead\n");
case ASB_DISCARD_ZERO_CHG:
if (ch_peer == 0 && ch_self == 0) {
- rv = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)
+ rv = test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)
? -1 : 1;
break;
} else {
@@ -2630,7 +2642,7 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
rv = 1;
else /* ( ch_self == ch_peer ) */
/* Well, then use something else. */
- rv = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags)
+ rv = test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)
? -1 : 1;
break;
case ASB_DISCARD_LOCAL:
@@ -2643,13 +2655,17 @@ static int drbd_asb_recover_0p(struct drbd_device *device) __must_hold(local)
return rv;
}
-static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local)
+/**
+ * drbd_asb_recover_1p - Recover after split-brain with one remaining primary
+ */
+static int drbd_asb_recover_1p(struct drbd_peer_device *peer_device) __must_hold(local)
{
+ struct drbd_device *device = peer_device->device;
int hg, rv = -100;
enum drbd_after_sb_p after_sb_1p;
rcu_read_lock();
- after_sb_1p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_1p;
+ after_sb_1p = rcu_dereference(peer_device->connection->net_conf)->after_sb_1p;
rcu_read_unlock();
switch (after_sb_1p) {
case ASB_DISCARD_YOUNGER_PRI:
@@ -2663,19 +2679,19 @@ static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local)
case ASB_DISCONNECT:
break;
case ASB_CONSENSUS:
- hg = drbd_asb_recover_0p(device);
+ hg = drbd_asb_recover_0p(peer_device);
if (hg == -1 && device->state.role == R_SECONDARY)
rv = hg;
if (hg == 1 && device->state.role == R_PRIMARY)
rv = hg;
break;
case ASB_VIOLENTLY:
- rv = drbd_asb_recover_0p(device);
+ rv = drbd_asb_recover_0p(peer_device);
break;
case ASB_DISCARD_SECONDARY:
return device->state.role == R_PRIMARY ? 1 : -1;
case ASB_CALL_HELPER:
- hg = drbd_asb_recover_0p(device);
+ hg = drbd_asb_recover_0p(peer_device);
if (hg == -1 && device->state.role == R_PRIMARY) {
enum drbd_state_rv rv2;
@@ -2696,13 +2712,17 @@ static int drbd_asb_recover_1p(struct drbd_device *device) __must_hold(local)
return rv;
}
-static int drbd_asb_recover_2p(struct drbd_device *device) __must_hold(local)
+/**
+ * drbd_asb_recover_2p - Recover after split-brain with two remaining primaries
+ */
+static int drbd_asb_recover_2p(struct drbd_peer_device *peer_device) __must_hold(local)
{
+ struct drbd_device *device = peer_device->device;
int hg, rv = -100;
enum drbd_after_sb_p after_sb_2p;
rcu_read_lock();
- after_sb_2p = rcu_dereference(first_peer_device(device)->connection->net_conf)->after_sb_2p;
+ after_sb_2p = rcu_dereference(peer_device->connection->net_conf)->after_sb_2p;
rcu_read_unlock();
switch (after_sb_2p) {
case ASB_DISCARD_YOUNGER_PRI:
@@ -2716,12 +2736,12 @@ static int drbd_asb_recover_2p(struct drbd_device *device) __must_hold(local)
drbd_err(device, "Configuration error.\n");
break;
case ASB_VIOLENTLY:
- rv = drbd_asb_recover_0p(device);
+ rv = drbd_asb_recover_0p(peer_device);
break;
case ASB_DISCONNECT:
break;
case ASB_CALL_HELPER:
- hg = drbd_asb_recover_0p(device);
+ hg = drbd_asb_recover_0p(peer_device);
if (hg == -1) {
enum drbd_state_rv rv2;
@@ -2956,9 +2976,11 @@ static int drbd_uuid_compare(struct drbd_device *device, int *rule_nr) __must_ho
/* drbd_sync_handshake() returns the new conn state on success, or
CONN_MASK (-1) on failure.
*/
-static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd_role peer_role,
+static enum drbd_conns drbd_sync_handshake(struct drbd_peer_device *peer_device,
+ enum drbd_role peer_role,
enum drbd_disk_state peer_disk) __must_hold(local)
{
+ struct drbd_device *device = peer_device->device;
enum drbd_conns rv = C_MASK;
enum drbd_disk_state mydisk;
struct net_conf *nc;
@@ -3003,7 +3025,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd
drbd_khelper(device, "initial-split-brain");
rcu_read_lock();
- nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
+ nc = rcu_dereference(peer_device->connection->net_conf);
if (hg == 100 || (hg == -100 && nc->always_asbp)) {
int pcount = (device->state.role == R_PRIMARY)
@@ -3012,13 +3034,13 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd
switch (pcount) {
case 0:
- hg = drbd_asb_recover_0p(device);
+ hg = drbd_asb_recover_0p(peer_device);
break;
case 1:
- hg = drbd_asb_recover_1p(device);
+ hg = drbd_asb_recover_1p(peer_device);
break;
case 2:
- hg = drbd_asb_recover_2p(device);
+ hg = drbd_asb_recover_2p(peer_device);
break;
}
if (abs(hg) < 100) {
@@ -3078,7 +3100,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_device *device, enum drbd
}
}
- if (tentative || test_bit(CONN_DRY_RUN, &first_peer_device(device)->connection->flags)) {
+ if (tentative || test_bit(CONN_DRY_RUN, &peer_device->connection->flags)) {
if (hg == 0)
drbd_info(device, "dry-run connect: No resync, would become Connected immediately.\n");
else
@@ -3664,7 +3686,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info
drbd_get_capacity(device->this_bdev) || ldsc) {
/* we have different sizes, probably peer
* needs to know my new size... */
- drbd_send_sizes(device, 0, ddsf);
+ drbd_send_sizes(peer_device, 0, ddsf);
}
if (test_and_clear_bit(RESIZE_PENDING, &device->flags) ||
(dd == DS_GREW && device->state.conn == C_CONNECTED)) {
@@ -3807,7 +3829,7 @@ static int receive_req_state(struct drbd_connection *connection, struct packet_i
if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags) &&
mutex_is_locked(device->state_mutex)) {
- drbd_send_sr_reply(device, SS_CONCURRENT_ST_CHG);
+ drbd_send_sr_reply(peer_device, SS_CONCURRENT_ST_CHG);
return 0;
}
@@ -3815,7 +3837,7 @@ static int receive_req_state(struct drbd_connection *connection, struct packet_i
val = convert_state(val);
rv = drbd_change_state(device, CS_VERBOSE, mask, val);
- drbd_send_sr_reply(device, rv);
+ drbd_send_sr_reply(peer_device, rv);
drbd_md_sync(device);
@@ -3954,7 +3976,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
peer_state.conn <= C_WF_BITMAP_T));
if (cr)
- ns.conn = drbd_sync_handshake(device, peer_state.role, real_peer_disk);
+ ns.conn = drbd_sync_handshake(peer_device, peer_state.role, real_peer_disk);
put_ldev(device);
if (ns.conn == C_MASK) {
@@ -4012,8 +4034,8 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
/* we want resync, peer has not yet decided to sync... */
/* Nowadays only used when forcing a node into primary role and
setting its disk to UpToDate with that */
- drbd_send_uuids(device);
- drbd_send_current_state(device);
+ drbd_send_uuids(peer_device);
+ drbd_send_current_state(peer_device);
}
}
@@ -4066,27 +4088,27 @@ static int receive_sync_uuid(struct drbd_connection *connection, struct packet_i
* code upon failure.
*/
static int
-receive_bitmap_plain(struct drbd_device *device, unsigned int size,
+receive_bitmap_plain(struct drbd_peer_device *peer_device, unsigned int size,
unsigned long *p, struct bm_xfer_ctx *c)
{
unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
- drbd_header_size(first_peer_device(device)->connection);
+ drbd_header_size(peer_device->connection);
unsigned int num_words = min_t(size_t, data_size / sizeof(*p),
c->bm_words - c->word_offset);
unsigned int want = num_words * sizeof(*p);
int err;
if (want != size) {
- drbd_err(device, "%s:want (%u) != size (%u)\n", __func__, want, size);
+ drbd_err(peer_device, "%s:want (%u) != size (%u)\n", __func__, want, size);
return -EIO;
}
if (want == 0)
return 0;
- err = drbd_recv_all(first_peer_device(device)->connection, p, want);
+ err = drbd_recv_all(peer_device->connection, p, want);
if (err)
return err;
- drbd_bm_merge_lel(device, c->word_offset, num_words, p);
+ drbd_bm_merge_lel(peer_device->device, c->word_offset, num_words, p);
c->word_offset += num_words;
c->bit_offset = c->word_offset * BITS_PER_LONG;
@@ -4118,7 +4140,7 @@ static int dcbp_get_pad_bits(struct p_compressed_bm *p)
* code upon failure.
*/
static int
-recv_bm_rle_bits(struct drbd_device *device,
+recv_bm_rle_bits(struct drbd_peer_device *peer_device,
struct p_compressed_bm *p,
struct bm_xfer_ctx *c,
unsigned int len)
@@ -4147,14 +4169,14 @@ recv_bm_rle_bits(struct drbd_device *device,
if (toggle) {
e = s + rl -1;
if (e >= c->bm_bits) {
- drbd_err(device, "bitmap overflow (e:%lu) while decoding bm RLE packet\n", e);
+ drbd_err(peer_device, "bitmap overflow (e:%lu) while decoding bm RLE packet\n", e);
return -EIO;
}
- _drbd_bm_set_bits(device, s, e);
+ _drbd_bm_set_bits(peer_device->device, s, e);
}
if (have < bits) {
- drbd_err(device, "bitmap decoding error: h:%d b:%d la:0x%08llx l:%u/%u\n",
+ drbd_err(peer_device, "bitmap decoding error: h:%d b:%d la:0x%08llx l:%u/%u\n",
have, bits, look_ahead,
(unsigned int)(bs.cur.b - p->code),
(unsigned int)bs.buf_len);
@@ -4187,20 +4209,20 @@ recv_bm_rle_bits(struct drbd_device *device,
* code upon failure.
*/
static int
-decode_bitmap_c(struct drbd_device *device,
+decode_bitmap_c(struct drbd_peer_device *peer_device,
struct p_compressed_bm *p,
struct bm_xfer_ctx *c,
unsigned int len)
{
if (dcbp_get_code(p) == RLE_VLI_Bits)
- return recv_bm_rle_bits(device, p, c, len - sizeof(*p));
+ return recv_bm_rle_bits(peer_device, p, c, len - sizeof(*p));
/* other variants had been implemented for evaluation,
* but have been dropped as this one turned out to be "best"
* during all our tests. */
- drbd_err(device, "receive_bitmap_c: unknown encoding %u\n", p->encoding);
- conn_request_state(first_peer_device(device)->connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
+ drbd_err(peer_device, "receive_bitmap_c: unknown encoding %u\n", p->encoding);
+ conn_request_state(peer_device->connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
return -EIO;
}
@@ -4271,7 +4293,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info
for(;;) {
if (pi->cmd == P_BITMAP)
- err = receive_bitmap_plain(device, pi->size, pi->data, &c);
+ err = receive_bitmap_plain(peer_device, pi->size, pi->data, &c);
else if (pi->cmd == P_COMPRESSED_BITMAP) {
/* MAYBE: sanity check that we speak proto >= 90,
* and the feature is enabled! */
@@ -4290,7 +4312,7 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info
err = drbd_recv_all(peer_device->connection, p, pi->size);
if (err)
goto out;
- err = decode_bitmap_c(device, p, &c, pi->size);
+ err = decode_bitmap_c(peer_device, p, &c, pi->size);
} else {
drbd_warn(device, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd);
err = -EIO;
@@ -4495,7 +4517,7 @@ static void conn_disconnect(struct drbd_connection *connection)
struct drbd_device *device = peer_device->device;
kref_get(&device->kref);
rcu_read_unlock();
- drbd_disconnected(device);
+ drbd_disconnected(peer_device);
kref_put(&device->kref, drbd_destroy_device);
rcu_read_lock();
}
@@ -4523,8 +4545,9 @@ static void conn_disconnect(struct drbd_connection *connection)
conn_request_state(connection, NS(conn, C_STANDALONE), CS_VERBOSE | CS_HARD);
}
-static int drbd_disconnected(struct drbd_device *device)
+static int drbd_disconnected(struct drbd_peer_device *peer_device)
{
+ struct drbd_device *device = peer_device->device;
unsigned int i;
/* wait for current activity to cease. */
@@ -4573,7 +4596,7 @@ static int drbd_disconnected(struct drbd_device *device)
device->p_uuid = NULL;
if (!drbd_suspended(device))
- tl_clear(first_peer_device(device)->connection);
+ tl_clear(peer_device->connection);
drbd_md_sync(device);
@@ -4980,7 +5003,7 @@ static int got_IsInSync(struct drbd_connection *connection, struct packet_info *
D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
- update_peer_seq(device, be32_to_cpu(p->seq_num));
+ update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (get_ldev(device)) {
drbd_rs_complete_io(device, sector);
@@ -5031,7 +5054,7 @@ static int got_BlockAck(struct drbd_connection *connection, struct packet_info *
return -EIO;
device = peer_device->device;
- update_peer_seq(device, be32_to_cpu(p->seq_num));
+ update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (p->block_id == ID_SYNCER) {
drbd_set_in_sync(device, sector, blksize);
@@ -5077,7 +5100,7 @@ static int got_NegAck(struct drbd_connection *connection, struct packet_info *pi
return -EIO;
device = peer_device->device;
- update_peer_seq(device, be32_to_cpu(p->seq_num));
+ update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (p->block_id == ID_SYNCER) {
dec_rs_pending(device);
@@ -5111,7 +5134,7 @@ static int got_NegDReply(struct drbd_connection *connection, struct packet_info
return -EIO;
device = peer_device->device;
- update_peer_seq(device, be32_to_cpu(p->seq_num));
+ update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
drbd_err(device, "Got NegDReply; Sector %llus, len %u.\n",
(unsigned long long)sector, be32_to_cpu(p->blksize));
@@ -5137,7 +5160,7 @@ static int got_NegRSDReply(struct drbd_connection *connection, struct packet_inf
sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize);
- update_peer_seq(device, be32_to_cpu(p->seq_num));
+ update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
dec_rs_pending(device);
@@ -5198,7 +5221,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info *
sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize);
- update_peer_seq(device, be32_to_cpu(p->seq_num));
+ update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
if (be64_to_cpu(p->block_id) == ID_OUT_OF_SYNC)
drbd_ov_out_of_sync_found(device, sector, size);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 56b4aee..1aef152 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -354,7 +354,7 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
goto abort;
}
- if (drbd_send_state_req(device, mask, val)) {
+ if (drbd_send_state_req(first_peer_device(device), mask, val)) {
rv = SS_CW_FAILED_BY_PEER;
if (f & CS_VERBOSE)
print_st_err(device, os, ns, rv);
@@ -1296,7 +1296,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) &&
(ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) &&
first_peer_device(device)->connection->agreed_pro_version >= 96 && get_ldev(device)) {
- drbd_gen_and_send_sync_uuid(device);
+ drbd_gen_and_send_sync_uuid(first_peer_device(device));
put_ldev(device);
}
@@ -1310,8 +1310,8 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
atomic_set(&device->rs_pending_cnt, 0);
drbd_rs_cancel_all(device);
- drbd_send_uuids(device);
- drbd_send_state(device, ns);
+ drbd_send_uuids(first_peer_device(device));
+ drbd_send_state(first_peer_device(device), ns);
}
/* No point in queuing send_bitmap if we don't have a connection
* anymore, so check also the _current_ state, not only the new state
@@ -1336,7 +1336,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
set_bit(NEW_CUR_UUID, &device->flags);
} else {
drbd_uuid_new_current(device);
- drbd_send_uuids(device);
+ drbd_send_uuids(first_peer_device(device));
}
}
put_ldev(device);
@@ -1347,7 +1347,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
if (os.peer == R_SECONDARY && ns.peer == R_PRIMARY &&
device->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
drbd_uuid_new_current(device);
- drbd_send_uuids(device);
+ drbd_send_uuids(first_peer_device(device));
}
/* D_DISKLESS Peer becomes secondary */
if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
@@ -1374,16 +1374,16 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* Last part of the attaching process ... */
if (ns.conn >= C_CONNECTED &&
os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) {
- drbd_send_sizes(device, 0, 0); /* to start sync... */
- drbd_send_uuids(device);
- drbd_send_state(device, ns);
+ drbd_send_sizes(first_peer_device(device), 0, 0); /* to start sync... */
+ drbd_send_uuids(first_peer_device(device));
+ drbd_send_state(first_peer_device(device), ns);
}
/* We want to pause/continue resync, tell peer. */
if (ns.conn >= C_CONNECTED &&
((os.aftr_isp != ns.aftr_isp) ||
(os.user_isp != ns.user_isp)))
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
/* In case one of the isp bits got set, suspend other devices. */
if ((!os.aftr_isp && !os.peer_isp && !os.user_isp) &&
@@ -1393,10 +1393,10 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* Make sure the peer gets informed about eventual state
changes (ISP bits) while we were in WFReportParams. */
if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED)
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
if (os.conn != C_AHEAD && ns.conn == C_AHEAD)
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
/* We are in the progress to start a full sync... */
if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
@@ -1450,7 +1450,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
drbd_disk_str(device->state.disk));
if (ns.conn >= C_CONNECTED)
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
drbd_rs_cancel_all(device);
@@ -1474,7 +1474,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
drbd_disk_str(device->state.disk));
if (ns.conn >= C_CONNECTED)
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
/* corresponding get_ldev in __drbd_set_state
* this may finally trigger drbd_ldev_destroy. */
put_ldev(device);
@@ -1482,7 +1482,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* Notify peer that I had a local IO error, and did not detached.. */
if (os.disk == D_UP_TO_DATE && ns.disk == D_INCONSISTENT && ns.conn >= C_CONNECTED)
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
/* Disks got bigger while they were detached */
if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING &&
@@ -1500,14 +1500,14 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
/* sync target done with resync. Explicitly notify peer, even though
* it should (at least for non-empty resyncs) already know itself. */
if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED)
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
/* Verify finished, or reached stop sector. Peer did not know about
* the stop sector, and we may even have changed the stop sector during
* verify to interrupt/stop early. Send the new state. */
if (os.conn == C_VERIFY_S && ns.conn == C_CONNECTED
&& verify_can_do_stop_sector(device))
- drbd_send_state(device, ns);
+ drbd_send_state(first_peer_device(device), ns);
/* This triggers bitmap writeout of potentially still unwritten pages
* if the resync finished cleanly, or aborted because of peer disk
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index cf40a8a..8aaec6c 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -358,7 +358,7 @@ static int w_e_send_csum(struct drbd_work *w, int cancel)
drbd_free_peer_req(device, peer_req);
peer_req = NULL;
inc_rs_pending(device);
- err = drbd_send_drequest_csum(device, sector, size,
+ err = drbd_send_drequest_csum(first_peer_device(device), sector, size,
digest, digest_size,
P_CSUM_RS_REQUEST);
kfree(digest);
@@ -378,8 +378,9 @@ out:
#define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN)
-static int read_for_csum(struct drbd_device *device, sector_t sector, int size)
+static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, int size)
{
+ struct drbd_device *device = peer_device->device;
struct drbd_peer_request *peer_req;
if (!get_ldev(device))
@@ -390,7 +391,7 @@ static int read_for_csum(struct drbd_device *device, sector_t sector, int size)
/* GFP_TRY, because if there is no memory available right now, this may
* be rescheduled for later. It is "only" background resync, after all. */
- peer_req = drbd_alloc_peer_req(device, ID_SYNCER /* unused */, sector,
+ peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER /* unused */, sector,
size, GFP_TRY);
if (!peer_req)
goto defer;
@@ -676,7 +677,7 @@ next_sector:
size = (capacity-sector)<<9;
if (first_peer_device(device)->connection->agreed_pro_version >= 89 &&
first_peer_device(device)->connection->csums_tfm) {
- switch (read_for_csum(device, sector, size)) {
+ switch (read_for_csum(first_peer_device(device), sector, size)) {
case -EIO: /* Disk failure */
put_ldev(device);
return -EIO;
@@ -695,7 +696,7 @@ next_sector:
int err;
inc_rs_pending(device);
- err = drbd_send_drequest(device, P_RS_DATA_REQUEST,
+ err = drbd_send_drequest(first_peer_device(device), P_RS_DATA_REQUEST,
sector, size, ID_SYNCER);
if (err) {
drbd_err(device, "drbd_send_drequest() failed, aborting...\n");
@@ -763,7 +764,7 @@ static int w_make_ov_request(struct drbd_work *w, int cancel)
size = (capacity-sector)<<9;
inc_rs_pending(device);
- if (drbd_send_ov_request(device, sector, size)) {
+ if (drbd_send_ov_request(first_peer_device(device), sector, size)) {
dec_rs_pending(device);
return 0;
}
@@ -997,13 +998,13 @@ int w_e_end_data_req(struct drbd_work *w, int cancel)
}
if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
- err = drbd_send_block(device, P_DATA_REPLY, peer_req);
+ err = drbd_send_block(first_peer_device(device), P_DATA_REPLY, peer_req);
} else {
if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Sending NegDReply. sector=%llus.\n",
(unsigned long long)peer_req->i.sector);
- err = drbd_send_ack(device, P_NEG_DREPLY, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_NEG_DREPLY, peer_req);
}
dec_unacked(device);
@@ -1039,11 +1040,11 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
}
if (device->state.conn == C_AHEAD) {
- err = drbd_send_ack(device, P_RS_CANCEL, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_RS_CANCEL, peer_req);
} else if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
if (likely(device->state.pdsk >= D_INCONSISTENT)) {
inc_rs_pending(device);
- err = drbd_send_block(device, P_RS_DATA_REPLY, peer_req);
+ err = drbd_send_block(first_peer_device(device), P_RS_DATA_REPLY, peer_req);
} else {
if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Not sending RSDataReply, "
@@ -1055,7 +1056,7 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
drbd_err(device, "Sending NegRSDReply. sector %llus.\n",
(unsigned long long)peer_req->i.sector);
- err = drbd_send_ack(device, P_NEG_RS_DREPLY, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_NEG_RS_DREPLY, peer_req);
/* update resync data with failure */
drbd_rs_failed_io(device, peer_req->i.sector, peer_req->i.size);
@@ -1111,16 +1112,16 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
drbd_set_in_sync(device, peer_req->i.sector, peer_req->i.size);
/* rs_same_csums unit is BM_BLOCK_SIZE */
device->rs_same_csum += peer_req->i.size >> BM_BLOCK_SHIFT;
- err = drbd_send_ack(device, P_RS_IS_IN_SYNC, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_RS_IS_IN_SYNC, peer_req);
} else {
inc_rs_pending(device);
peer_req->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */
peer_req->flags &= ~EE_HAS_DIGEST; /* This peer request no longer has a digest pointer */
kfree(di);
- err = drbd_send_block(device, P_RS_DATA_REPLY, peer_req);
+ err = drbd_send_block(first_peer_device(device), P_RS_DATA_REPLY, peer_req);
}
} else {
- err = drbd_send_ack(device, P_NEG_RS_DREPLY, peer_req);
+ err = drbd_send_ack(first_peer_device(device), P_NEG_RS_DREPLY, peer_req);
if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Sending NegDReply. I guess it gets messy.\n");
}
@@ -1166,7 +1167,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel)
drbd_free_peer_req(device, peer_req);
peer_req = NULL;
inc_rs_pending(device);
- err = drbd_send_drequest_csum(device, sector, size, digest, digest_size, P_OV_REPLY);
+ err = drbd_send_drequest_csum(first_peer_device(device), sector, size, digest, digest_size, P_OV_REPLY);
if (err)
dec_rs_pending(device);
kfree(digest);
@@ -1239,7 +1240,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel)
else
ov_out_of_sync_print(device);
- err = drbd_send_ack_ex(device, P_OV_RESULT, sector, size,
+ err = drbd_send_ack_ex(first_peer_device(device), P_OV_RESULT, sector, size,
eq ? ID_IN_SYNC : ID_OUT_OF_SYNC);
dec_unacked(device);
@@ -1298,9 +1299,9 @@ int w_send_write_hint(struct drbd_work *w, int cancel)
if (cancel)
return 0;
sock = &first_peer_device(device)->connection->data;
- if (!drbd_prepare_command(device, sock))
+ if (!drbd_prepare_command(first_peer_device(device), sock))
return -EIO;
- return drbd_send_command(device, sock, P_UNPLUG_REMOTE, 0, NULL, 0);
+ return drbd_send_command(first_peer_device(device), sock, P_UNPLUG_REMOTE, 0, NULL, 0);
}
static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch)
@@ -1342,7 +1343,7 @@ int w_send_out_of_sync(struct drbd_work *w, int cancel)
* No more barriers will be sent, until we leave AHEAD mode again. */
maybe_send_barrier(connection, req->epoch);
- err = drbd_send_out_of_sync(device, req);
+ err = drbd_send_out_of_sync(first_peer_device(device), req);
req_mod(req, OOS_HANDED_TO_NETWORK);
return err;
@@ -1370,7 +1371,7 @@ int w_send_dblock(struct drbd_work *w, int cancel)
maybe_send_barrier(connection, req->epoch);
connection->send.current_epoch_writes++;
- err = drbd_send_dblock(device, req);
+ err = drbd_send_dblock(first_peer_device(device), req);
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
return err;
@@ -1398,7 +1399,7 @@ int w_send_read_req(struct drbd_work *w, int cancel)
* if there was any yet. */
maybe_send_barrier(connection, req->epoch);
- err = drbd_send_drequest(device, P_DATA_REQUEST, req->i.sector, req->i.size,
+ err = drbd_send_drequest(first_peer_device(device), P_DATA_REQUEST, req->i.sector, req->i.size,
(unsigned long)req);
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
@@ -1730,7 +1731,7 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
* and from after_state_ch otherwise. */
if (side == C_SYNC_SOURCE &&
first_peer_device(device)->connection->agreed_pro_version < 96)
- drbd_gen_and_send_sync_uuid(device);
+ drbd_gen_and_send_sync_uuid(first_peer_device(device));
if (first_peer_device(device)->connection->agreed_pro_version < 95 &&
device->rs_total == 0) {
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 13/27] drbd: Kill drbd_task_to_thread_name()
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (11 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 12/27] drbd: Pass a peer device to a number of fuctions Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 14/27] drbd: Remove useless assertion Philipp Reisner
` (13 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_bitmap.c | 16 ++++++++--------
drivers/block/drbd/drbd_int.h | 3 +--
drivers/block/drbd/drbd_main.c | 20 ++------------------
3 files changed, 11 insertions(+), 28 deletions(-)
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index b2dc168..bfa2658 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -118,10 +118,10 @@ static void __bm_print_lock_info(struct drbd_device *device, const char *func)
struct drbd_bitmap *b = device->bitmap;
if (!__ratelimit(&drbd_ratelimit_state))
return;
- drbd_err(device, "FIXME %s in %s, bitmap locked for '%s' by %s\n",
- drbd_task_to_thread_name(first_peer_device(device)->connection, current),
- func, b->bm_why ?: "?",
- drbd_task_to_thread_name(first_peer_device(device)->connection, b->bm_task));
+ drbd_err(device, "FIXME %s[%d] in %s, bitmap locked for '%s' by %s[%d]\n",
+ current->comm, task_pid_nr(current),
+ func, b->bm_why ?: "?",
+ b->bm_task->comm, task_pid_nr(b->bm_task));
}
void drbd_bm_lock(struct drbd_device *device, char *why, enum bm_flag flags)
@@ -137,10 +137,10 @@ void drbd_bm_lock(struct drbd_device *device, char *why, enum bm_flag flags)
trylock_failed = !mutex_trylock(&b->bm_change);
if (trylock_failed) {
- drbd_warn(device, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
- drbd_task_to_thread_name(first_peer_device(device)->connection, current),
- why, b->bm_why ?: "?",
- drbd_task_to_thread_name(first_peer_device(device)->connection, b->bm_task));
+ drbd_warn(device, "%s[%d] going to '%s' but bitmap already locked for '%s' by %s[%d]\n",
+ current->comm, task_pid_nr(current),
+ why, b->bm_why ?: "?",
+ b->bm_task->comm, task_pid_nr(b->bm_task));
mutex_lock(&b->bm_change);
}
if (BM_LOCKED_MASK & b->bm_flags)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index b89e7ed..ef4c621 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -263,7 +263,7 @@ struct drbd_thread {
int (*function) (struct drbd_thread *);
struct drbd_connection *connection;
int reset_cpu_mask;
- char name[9];
+ const char *name;
};
static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
@@ -865,7 +865,6 @@ enum dds_flags {
extern void drbd_init_set_defaults(struct drbd_device *device);
extern int drbd_thread_start(struct drbd_thread *thi);
extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
-extern char *drbd_task_to_thread_name(struct drbd_connection *connection, struct task_struct *task);
#ifdef CONFIG_SMP
extern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
#else
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index f18a5d5..7f178dc 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -368,14 +368,14 @@ restart:
}
static void drbd_thread_init(struct drbd_connection *connection, struct drbd_thread *thi,
- int (*func) (struct drbd_thread *), char *name)
+ int (*func) (struct drbd_thread *), const char *name)
{
spin_lock_init(&thi->t_lock);
thi->task = NULL;
thi->t_state = NONE;
thi->function = func;
thi->connection = connection;
- strncpy(thi->name, name, ARRAY_SIZE(thi->name));
+ thi->name = name;
}
int drbd_thread_start(struct drbd_thread *thi)
@@ -475,22 +475,6 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait)
wait_for_completion(&thi->stop);
}
-static struct drbd_thread *drbd_task_to_thread(struct drbd_connection *connection, struct task_struct *task)
-{
- struct drbd_thread *thi =
- task == connection->receiver.task ? &connection->receiver :
- task == connection->asender.task ? &connection->asender :
- task == connection->worker.task ? &connection->worker : NULL;
-
- return thi;
-}
-
-char *drbd_task_to_thread_name(struct drbd_connection *connection, struct task_struct *task)
-{
- struct drbd_thread *thi = drbd_task_to_thread(connection, task);
- return thi ? thi->name : task->comm;
-}
-
int conn_lowest_minor(struct drbd_connection *connection)
{
struct drbd_peer_device *peer_device;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 14/27] drbd: Remove useless assertion
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (12 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 13/27] drbd: Kill drbd_task_to_thread_name() Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 15/27] drbd: Move string function prototypes from linux/drbd.h to drbd_string.h Philipp Reisner
` (12 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_state.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 1aef152..3f5c5a5 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1165,10 +1165,8 @@ static int w_after_state_ch(struct drbd_work *w, int unused)
struct drbd_device *device = w->device;
after_state_ch(device, ascw->os, ascw->ns, ascw->flags);
- if (ascw->flags & CS_WAIT_COMPLETE) {
- D_ASSERT(device, ascw->done != NULL);
+ if (ascw->flags & CS_WAIT_COMPLETE)
complete(ascw->done);
- }
kfree(ascw);
return 0;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 15/27] drbd: Move string function prototypes from linux/drbd.h to drbd_string.h
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (13 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 14/27] drbd: Remove useless assertion Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 16/27] drbd: Rename w_prev_work_done -> w_complete Philipp Reisner
` (11 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 1 +
drivers/block/drbd/drbd_strings.c | 1 +
drivers/block/drbd/drbd_strings.h | 9 +++++++++
include/linux/drbd.h | 6 ------
4 files changed, 11 insertions(+), 6 deletions(-)
create mode 100644 drivers/block/drbd/drbd_strings.h
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ef4c621..2b0fdfd 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -45,6 +45,7 @@
#include <linux/prefetch.h>
#include <linux/drbd_genl_api.h>
#include <linux/drbd.h>
+#include "drbd_strings.h"
#include "drbd_state.h"
#include "drbd_protocol.h"
diff --git a/drivers/block/drbd/drbd_strings.c b/drivers/block/drbd/drbd_strings.c
index 58e08ff..80b0f63 100644
--- a/drivers/block/drbd/drbd_strings.c
+++ b/drivers/block/drbd/drbd_strings.c
@@ -24,6 +24,7 @@
*/
#include <linux/drbd.h>
+#include "drbd_strings.h"
static const char *drbd_conn_s_names[] = {
[C_STANDALONE] = "StandAlone",
diff --git a/drivers/block/drbd/drbd_strings.h b/drivers/block/drbd/drbd_strings.h
new file mode 100644
index 0000000..f9923cc
--- /dev/null
+++ b/drivers/block/drbd/drbd_strings.h
@@ -0,0 +1,9 @@
+#ifndef __DRBD_STRINGS_H
+#define __DRBD_STRINGS_H
+
+extern const char *drbd_conn_str(enum drbd_conns);
+extern const char *drbd_role_str(enum drbd_role);
+extern const char *drbd_disk_str(enum drbd_disk_state);
+extern const char *drbd_set_st_err_str(enum drbd_state_rv);
+
+#endif /* __DRBD_STRINGS_H */
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 6f60136..3dbe9bd 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -327,12 +327,6 @@ enum drbd_state_rv {
SS_AFTER_LAST_ERROR = -22, /* Keep this at bottom */
};
-/* from drbd_strings.c */
-extern const char *drbd_conn_str(enum drbd_conns);
-extern const char *drbd_role_str(enum drbd_role);
-extern const char *drbd_disk_str(enum drbd_disk_state);
-extern const char *drbd_set_st_err_str(enum drbd_state_rv);
-
#define SHARED_SECRET_MAX 64
#define MDF_CONSISTENT (1 << 0)
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 16/27] drbd: Rename w_prev_work_done -> w_complete
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (14 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 15/27] drbd: Move string function prototypes from linux/drbd.h to drbd_string.h Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 17/27] drbd: Create a dedicated struct drbd_device_work Philipp Reisner
` (10 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Also move it to drbd_receiver.c and make it static.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 1 -
drivers/block/drbd/drbd_receiver.c | 10 +++++++++-
drivers/block/drbd/drbd_worker.c | 8 --------
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 2b0fdfd..5cf496d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1321,7 +1321,6 @@ extern int w_send_write_hint(struct drbd_work *, int);
extern int w_make_resync_request(struct drbd_work *, int);
extern int w_send_dblock(struct drbd_work *, int);
extern int w_send_read_req(struct drbd_work *, int);
-extern int w_prev_work_done(struct drbd_work *, int);
extern int w_e_reissue(struct drbd_work *, int);
extern int w_restart_disk_io(struct drbd_work *, int);
extern int w_send_out_of_sync(struct drbd_work *, int);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 9ccb856..250c8d4 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4481,11 +4481,19 @@ static void drbdd(struct drbd_connection *connection)
conn_request_state(connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
}
+static int w_complete(struct drbd_work *w, int cancel)
+{
+ struct drbd_wq_barrier *b = container_of(w, struct drbd_wq_barrier, w);
+
+ complete(&b->done);
+ return 0;
+}
+
void conn_flush_workqueue(struct drbd_connection *connection)
{
struct drbd_wq_barrier barr;
- barr.w.cb = w_prev_work_done;
+ barr.w.cb = w_complete;
barr.w.connection = connection;
init_completion(&barr.done);
drbd_queue_work(&connection->sender_work, &barr.w);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 8aaec6c..7d68227 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1262,14 +1262,6 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel)
return err;
}
-int w_prev_work_done(struct drbd_work *w, int cancel)
-{
- struct drbd_wq_barrier *b = container_of(w, struct drbd_wq_barrier, w);
-
- complete(&b->done);
- return 0;
-}
-
/* FIXME
* We need to track the number of pending barrier acks,
* and to be able to wait for them.
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 17/27] drbd: Create a dedicated struct drbd_device_work
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (15 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 16/27] drbd: Rename w_prev_work_done -> w_complete Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 18/27] drbd: Turn conn_flush_workqueue() into drbd_flush_workqueue() Philipp Reisner
` (9 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
drbd_device_work is a work item that has a reference to a device,
while drbd_work is a more generic work item that does not carry
a reference to a device.
All callbacks get a pointer to a drbd_work instance, those callbacks
that expect a drbd_device_work use the container_of macro to get it.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_actlog.c | 16 +++--
drivers/block/drbd/drbd_int.h | 29 ++++----
drivers/block/drbd/drbd_main.c | 32 ++++-----
drivers/block/drbd/drbd_receiver.c | 84 +++++++++++-----------
drivers/block/drbd/drbd_req.c | 41 ++++++-----
drivers/block/drbd/drbd_req.h | 4 +-
drivers/block/drbd/drbd_state.c | 21 +++---
drivers/block/drbd/drbd_worker.c | 134 ++++++++++++++++++++----------------
8 files changed, 197 insertions(+), 164 deletions(-)
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index cacd47a..d971cb2 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -95,11 +95,13 @@ struct __packed al_transaction_on_disk {
struct update_odbm_work {
struct drbd_work w;
+ struct drbd_device *device;
unsigned int enr;
};
struct update_al_work {
struct drbd_work w;
+ struct drbd_device *device;
struct completion event;
int err;
};
@@ -593,7 +595,7 @@ _al_write_transaction(struct drbd_device *device)
static int w_al_write_transaction(struct drbd_work *w, int unused)
{
struct update_al_work *aw = container_of(w, struct update_al_work, w);
- struct drbd_device *device = w->device;
+ struct drbd_device *device = aw->device;
int err;
err = _al_write_transaction(device);
@@ -612,8 +614,9 @@ static int al_write_transaction(struct drbd_device *device, bool delegate)
struct update_al_work al_work;
init_completion(&al_work.event);
al_work.w.cb = w_al_write_transaction;
- al_work.w.device = device;
- drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &al_work.w);
+ al_work.device = device;
+ 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
@@ -683,7 +686,7 @@ int drbd_initialize_al(struct drbd_device *device, void *buffer)
static int w_update_odbm(struct drbd_work *w, int unused)
{
struct update_odbm_work *udw = container_of(w, struct update_odbm_work, w);
- struct drbd_device *device = w->device;
+ struct drbd_device *device = udw->device;
struct sib_info sib = { .sib_reason = SIB_SYNC_PROGRESS, };
if (!get_ldev(device)) {
@@ -794,8 +797,9 @@ static void drbd_try_clear_on_disk_bm(struct drbd_device *device, sector_t secto
if (udw) {
udw->enr = ext->lce.lc_number;
udw->w.cb = w_update_odbm;
- udw->w.device = device;
- drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &udw->w);
+ udw->device = device;
+ drbd_queue_work_front(&first_peer_device(device)->connection->sender_work,
+ &udw->w);
} else {
drbd_warn(device, "Could not kmalloc an udw\n");
}
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 5cf496d..eb2bc90 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -280,10 +280,11 @@ static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
struct drbd_work {
struct list_head list;
int (*cb)(struct drbd_work *, int cancel);
- union {
- struct drbd_device *device;
- struct drbd_connection *connection;
- };
+};
+
+struct drbd_device_work {
+ struct drbd_work w;
+ struct drbd_device *device;
};
#include "drbd_interval.h"
@@ -292,6 +293,7 @@ extern int drbd_wait_misc(struct drbd_device *, struct drbd_interval *);
struct drbd_request {
struct drbd_work w;
+ struct drbd_device *device;
/* if local IO is not allowed, will be NULL.
* if local IO _is_ allowed, holds the locally submitted bio clone,
@@ -355,7 +357,7 @@ struct digest_info {
};
struct drbd_peer_request {
- struct drbd_work w;
+ struct drbd_device_work dw;
struct drbd_epoch *epoch; /* for writes */
struct page *pages;
atomic_t pending_bios;
@@ -681,11 +683,11 @@ struct drbd_device {
struct gendisk *vdisk;
unsigned long last_reattach_jif;
- struct drbd_work resync_work,
- unplug_work,
- go_diskless,
- md_sync_work,
- start_resync_work;
+ struct drbd_work resync_work;
+ struct drbd_work unplug_work;
+ struct drbd_work go_diskless;
+ struct drbd_work md_sync_work;
+ struct drbd_work start_resync_work;
struct timer_list resync_timer;
struct timer_list md_sync_timer;
struct timer_list start_resync_timer;
@@ -1860,7 +1862,8 @@ 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(&first_peer_device(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);
}
@@ -2087,7 +2090,9 @@ 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(&first_peer_device(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!
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 7f178dc..0500b56 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -312,7 +312,7 @@ void tl_abort_disk_io(struct drbd_device *device)
list_for_each_entry_safe(req, r, &connection->transfer_log, tl_requests) {
if (!(req->rq_state & RQ_LOCAL_PENDING))
continue;
- if (req->w.device != device)
+ if (req->device != device)
continue;
_req_mod(req, ABORT_DISK_IO);
}
@@ -1917,13 +1917,6 @@ void drbd_init_set_defaults(struct drbd_device *device)
device->bm_io_work.w.cb = w_bitmap_io;
device->start_resync_work.cb = w_start_resync;
- device->resync_work.device = device;
- device->unplug_work.device = device;
- device->go_diskless.device = device;
- device->md_sync_work.device = device;
- device->bm_io_work.w.device = device;
- device->start_resync_work.device = device;
-
init_timer(&device->resync_timer);
init_timer(&device->md_sync_timer);
init_timer(&device->start_resync_timer);
@@ -2222,12 +2215,12 @@ static void do_retry(struct work_struct *ws)
spin_unlock_irq(&retry->lock);
list_for_each_entry_safe(req, tmp, &writes, tl_requests) {
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct bio *bio = req->master_bio;
unsigned long start_time = req->start_time;
bool expected;
- expected =
+ expected =
expect(atomic_read(&req->completion_ref) == 0) &&
expect(req->rq_state & RQ_POSTPONED) &&
expect((req->rq_state & RQ_LOCAL_PENDING) == 0 ||
@@ -2273,7 +2266,7 @@ void drbd_restart_request(struct drbd_request *req)
/* Drop the extra reference that would otherwise
* have been dropped by complete_master_bio.
* do_retry() needs to grab a new one. */
- dec_ap_bio(req->w.device);
+ dec_ap_bio(req->device);
queue_work(retry.wq, &retry.worker);
}
@@ -3468,8 +3461,9 @@ int drbd_bmio_clear_n_write(struct drbd_device *device)
static int w_bitmap_io(struct drbd_work *w, int unused)
{
- struct bm_io_work *work = container_of(w, struct bm_io_work, w);
- struct drbd_device *device = w->device;
+ struct drbd_device *device =
+ container_of(w, struct drbd_device, bm_io_work.w);
+ struct bm_io_work *work = &device->bm_io_work;
int rv = -EIO;
D_ASSERT(device, atomic_read(&device->ap_bio_cnt) == 0);
@@ -3509,7 +3503,8 @@ void drbd_ldev_destroy(struct drbd_device *device)
static int w_go_diskless(struct drbd_work *w, int unused)
{
- struct drbd_device *device = w->device;
+ struct drbd_device *device =
+ container_of(w, struct drbd_device, go_diskless);
D_ASSERT(device, device->state.disk == D_FAILED);
/* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
@@ -3583,7 +3578,8 @@ void drbd_queue_bitmap_io(struct drbd_device *device,
set_bit(BITMAP_IO, &device->flags);
if (atomic_read(&device->ap_bio_cnt) == 0) {
if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
- drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work,
+ &device->bm_io_work.w);
}
spin_unlock_irq(&device->resource->req_lock);
}
@@ -3643,12 +3639,14 @@ static void md_sync_timer_fn(unsigned long data)
/* must not double-queue! */
if (list_empty(&device->md_sync_work.list))
- drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &device->md_sync_work);
+ drbd_queue_work_front(&first_peer_device(device)->connection->sender_work,
+ &device->md_sync_work);
}
static int w_md_sync(struct drbd_work *w, int unused)
{
- struct drbd_device *device = w->device;
+ struct drbd_device *device =
+ container_of(w, struct drbd_device, md_sync_work);
drbd_warn(device, "md_sync_timer expired! Worker calls drbd_md_sync().\n");
#ifdef DEBUG
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 250c8d4..3c88efa 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -209,7 +209,7 @@ static void reclaim_finished_net_peer_reqs(struct drbd_device *device,
stop to examine the list... */
list_for_each_safe(le, tle, &device->net_ee) {
- peer_req = list_entry(le, struct drbd_peer_request, w.list);
+ peer_req = list_entry(le, struct drbd_peer_request, dw.w.list);
if (drbd_peer_req_has_active_page(peer_req))
break;
list_move(le, to_be_freed);
@@ -225,7 +225,7 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
reclaim_finished_net_peer_reqs(device, &reclaimed);
spin_unlock_irq(&device->resource->req_lock);
- list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
+ list_for_each_entry_safe(peer_req, t, &reclaimed, dw.w.list)
drbd_free_net_peer_req(device, peer_req);
}
@@ -363,7 +363,7 @@ drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t secto
peer_req->i.waiting = false;
peer_req->epoch = NULL;
- peer_req->w.device = device;
+ peer_req->dw.device = device;
peer_req->pages = page;
atomic_set(&peer_req->pending_bios, 0);
peer_req->flags = 0;
@@ -402,7 +402,7 @@ int drbd_free_peer_reqs(struct drbd_device *device, struct list_head *list)
list_splice_init(list, &work_list);
spin_unlock_irq(&device->resource->req_lock);
- list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
+ list_for_each_entry_safe(peer_req, t, &work_list, dw.w.list) {
__drbd_free_peer_req(device, peer_req, is_net);
count++;
}
@@ -424,18 +424,18 @@ static int drbd_finish_peer_reqs(struct drbd_device *device)
list_splice_init(&device->done_ee, &work_list);
spin_unlock_irq(&device->resource->req_lock);
- list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
+ list_for_each_entry_safe(peer_req, t, &reclaimed, dw.w.list)
drbd_free_net_peer_req(device, peer_req);
/* possible callbacks here:
* e_end_block, and e_end_resync_block, e_send_superseded.
* all ignore the last argument.
*/
- list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
+ list_for_each_entry_safe(peer_req, t, &work_list, dw.w.list) {
int err2;
/* list_del not necessary, next/prev members not touched */
- err2 = peer_req->w.cb(&peer_req->w, !!err);
+ err2 = peer_req->dw.w.cb(&peer_req->dw.w, !!err);
if (!err)
err = err2;
drbd_free_peer_req(device, peer_req);
@@ -1664,9 +1664,10 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req
*/
static int e_end_resync_block(struct drbd_work *w, int unused)
{
+ struct drbd_device_work *dw = device_work(w);
struct drbd_peer_request *peer_req =
- container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
sector_t sector = peer_req->i.sector;
int err;
@@ -1702,10 +1703,10 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
/* corresponding dec_unacked() in e_end_resync_block()
* respective _drbd_clear_done_ee */
- peer_req->w.cb = e_end_resync_block;
+ peer_req->dw.w.cb = e_end_resync_block;
spin_lock_irq(&device->resource->req_lock);
- list_add(&peer_req->w.list, &device->sync_ee);
+ list_add(&peer_req->dw.w.list, &device->sync_ee);
spin_unlock_irq(&device->resource->req_lock);
atomic_add(data_size >> 9, &device->rs_sect_ev);
@@ -1715,7 +1716,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->w.list);
+ list_del(&peer_req->dw.w.list);
spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req);
@@ -1835,9 +1836,10 @@ static void restart_conflicting_writes(struct drbd_device *device,
*/
static int e_end_block(struct drbd_work *w, int cancel)
{
+ struct drbd_device_work *dw = device_work(w);
struct drbd_peer_request *peer_req =
- container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
sector_t sector = peer_req->i.sector;
int err = 0, pcmd;
@@ -1874,11 +1876,11 @@ static int e_end_block(struct drbd_work *w, int cancel)
return err;
}
-static int e_send_ack(struct drbd_work *w, enum drbd_packet ack)
+static int e_send_ack(struct drbd_device_work *dw, enum drbd_packet ack)
{
- struct drbd_device *device = w->device;
+ struct drbd_device *device = dw->device;
struct drbd_peer_request *peer_req =
- container_of(w, struct drbd_peer_request, w);
+ container_of(dw, struct drbd_peer_request, dw);
int err;
err = drbd_send_ack(first_peer_device(device), ack, peer_req);
@@ -1889,14 +1891,15 @@ static int e_send_ack(struct drbd_work *w, enum drbd_packet ack)
static int e_send_superseded(struct drbd_work *w, int unused)
{
- return e_send_ack(w, P_SUPERSEDED);
+ return e_send_ack(device_work(w), P_SUPERSEDED);
}
static int e_send_retry_write(struct drbd_work *w, int unused)
{
- struct drbd_connection *connection = first_peer_device(w->device)->connection;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_connection *connection = first_peer_device(dw->device)->connection;
- return e_send_ack(w, connection->agreed_pro_version >= 100 ?
+ return e_send_ack(dw, connection->agreed_pro_version >= 100 ?
P_RETRY_WRITE : P_SUPERSEDED);
}
@@ -1943,7 +1946,7 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee
bool rv = 0;
spin_lock_irq(&device->resource->req_lock);
- list_for_each_entry(rs_req, &device->sync_ee, w.list) {
+ list_for_each_entry(rs_req, &device->sync_ee, dw.w.list) {
if (overlaps(peer_req->i.sector, peer_req->i.size,
rs_req->i.sector, rs_req->i.size)) {
rv = 1;
@@ -2114,9 +2117,9 @@ static int handle_write_conflicts(struct drbd_device *device,
superseded ? "local" : "remote");
inc_unacked(device);
- peer_req->w.cb = superseded ? e_send_superseded :
+ peer_req->dw.w.cb = superseded ? e_send_superseded :
e_send_retry_write;
- list_add_tail(&peer_req->w.list, &device->done_ee);
+ list_add_tail(&peer_req->dw.w.list, &device->done_ee);
wake_asender(first_peer_device(device)->connection);
err = -ENOENT;
@@ -2212,7 +2215,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
return -EIO;
}
- peer_req->w.cb = e_end_block;
+ peer_req->dw.w.cb = e_end_block;
dp_flags = be32_to_cpu(p->dp_flags);
rw |= wire_flags_to_bio(device, dp_flags);
@@ -2252,7 +2255,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
update_peer_seq(peer_device, peer_seq);
spin_lock_irq(&device->resource->req_lock);
}
- list_add(&peer_req->w.list, &device->active_ee);
+ list_add(&peer_req->dw.w.list, &device->active_ee);
spin_unlock_irq(&device->resource->req_lock);
if (device->state.conn == C_SYNC_TARGET)
@@ -2299,7 +2302,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->w.list);
+ list_del(&peer_req->dw.w.list);
drbd_remove_epoch_entry_interval(device, peer_req);
spin_unlock_irq(&device->resource->req_lock);
if (peer_req->flags & EE_CALL_AL_COMPLETE_IO)
@@ -2454,13 +2457,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
switch (pi->cmd) {
case P_DATA_REQUEST:
- peer_req->w.cb = w_e_end_data_req;
+ peer_req->dw.w.cb = w_e_end_data_req;
fault_type = DRBD_FAULT_DT_RD;
/* application IO, don't drbd_rs_begin_io */
goto submit;
case P_RS_DATA_REQUEST:
- peer_req->w.cb = w_e_end_rsdata_req;
+ peer_req->dw.w.cb = w_e_end_rsdata_req;
fault_type = DRBD_FAULT_RS_RD;
/* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector);
@@ -2484,13 +2487,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
if (pi->cmd == P_CSUM_RS_REQUEST) {
D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
- peer_req->w.cb = w_e_end_csum_rs_req;
+ peer_req->dw.w.cb = w_e_end_csum_rs_req;
/* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector);
} else if (pi->cmd == P_OV_REPLY) {
/* track progress, we may need to throttle */
atomic_add(size >> 9, &device->rs_sect_in);
- peer_req->w.cb = w_e_end_ov_reply;
+ peer_req->dw.w.cb = w_e_end_ov_reply;
dec_rs_pending(device);
/* drbd_rs_begin_io done when we sent this request,
* but accounting still needs to be done. */
@@ -2514,7 +2517,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
drbd_info(device, "Online Verify start sector: %llu\n",
(unsigned long long)sector);
}
- peer_req->w.cb = w_e_end_ov_req;
+ peer_req->dw.w.cb = w_e_end_ov_req;
fault_type = DRBD_FAULT_RS_RD;
break;
@@ -2555,7 +2558,7 @@ submit_for_resync:
submit:
inc_unacked(device);
spin_lock_irq(&device->resource->req_lock);
- list_add_tail(&peer_req->w.list, &device->read_ee);
+ list_add_tail(&peer_req->dw.w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock);
if (drbd_submit_peer_request(device, peer_req, READ, fault_type) == 0)
@@ -2564,7 +2567,7 @@ submit:
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->w.list);
+ list_del(&peer_req->dw.w.list);
spin_unlock_irq(&device->resource->req_lock);
/* no drbd_rs_complete_io(), we are dropping the connection anyways */
@@ -4494,7 +4497,6 @@ void conn_flush_workqueue(struct drbd_connection *connection)
struct drbd_wq_barrier barr;
barr.w.cb = w_complete;
- barr.w.connection = connection;
init_completion(&barr.done);
drbd_queue_work(&connection->sender_work, &barr.w);
wait_for_completion(&barr.done);
@@ -5217,7 +5219,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info *
struct drbd_peer_device *peer_device;
struct drbd_device *device;
struct p_block_ack *p = pi->data;
- struct drbd_work *w;
+ struct drbd_device_work *dw;
sector_t sector;
int size;
@@ -5249,13 +5251,13 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info *
drbd_advance_rs_marks(device, device->ov_left);
if (device->ov_left == 0) {
- w = kmalloc(sizeof(*w), GFP_NOIO);
- if (w) {
- w->cb = w_ov_finished;
- w->device = device;
- drbd_queue_work(&peer_device->connection->sender_work, w);
+ dw = kmalloc(sizeof(*dw), GFP_NOIO);
+ if (dw) {
+ dw->w.cb = w_ov_finished;
+ dw->device = device;
+ drbd_queue_work(&peer_device->connection->sender_work, &dw->w);
} else {
- drbd_err(device, "kmalloc(w) failed.");
+ drbd_err(device, "kmalloc(dw) failed.");
ov_out_of_sync_print(device);
drbd_resync_finished(device);
}
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index daf7861..0fb0977 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -72,7 +72,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device,
drbd_req_make_private_bio(req, bio_src);
req->rq_state = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0;
- req->w.device = device;
+ req->device = device;
req->master_bio = bio_src;
req->epoch = 0;
@@ -95,7 +95,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device,
void drbd_req_destroy(struct kref *kref)
{
struct drbd_request *req = container_of(kref, struct drbd_request, kref);
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
const unsigned s = req->rq_state;
if ((req->master_bio && !(s & RQ_POSTPONED)) ||
@@ -191,7 +191,7 @@ void complete_master_bio(struct drbd_device *device,
static void drbd_remove_request_interval(struct rb_root *root,
struct drbd_request *req)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct drbd_interval *i = &req->i;
drbd_remove_interval(root, i);
@@ -211,7 +211,7 @@ static
void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
{
const unsigned s = req->rq_state;
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
int rw;
int error, ok;
@@ -306,7 +306,7 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_error *m, int put)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
D_ASSERT(device, m || (req->rq_state & RQ_POSTPONED));
if (!atomic_sub_and_test(put, &req->completion_ref))
@@ -329,7 +329,7 @@ static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_
static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m,
int clear, int set)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
unsigned s = req->rq_state;
int c_put = 0;
int k_put = 0;
@@ -454,7 +454,7 @@ static void drbd_report_io_error(struct drbd_device *device, struct drbd_request
int __req_mod(struct drbd_request *req, enum drbd_req_event what,
struct bio_and_error *m)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct net_conf *nc;
int p, rv = 0;
@@ -542,7 +542,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
D_ASSERT(device, (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(&first_peer_device(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,7 +578,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
D_ASSERT(device, 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(&first_peer_device(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();
@@ -592,7 +594,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
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(&first_peer_device(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 +707,8 @@ 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(&first_peer_device(device)->connection->sender_work, &req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work,
+ &req->w);
break;
case RESEND:
@@ -720,12 +724,13 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
Throwing them out of the TL here by pretending we got a BARRIER_ACK.
During connection handshake, we ensure that the peer was not rebooted. */
if (!(req->rq_state & RQ_NET_OK)) {
- /* FIXME could this possibly be a req->w.cb == w_send_out_of_sync?
+ /* FIXME could this possibly be a req->dw.cb == w_send_out_of_sync?
* in that case we must not set RQ_NET_PENDING. */
mod_rq_state(req, m, RQ_COMPLETION_SUSP, RQ_NET_QUEUED|RQ_NET_PENDING);
if (req->w.cb) {
- drbd_queue_work(&first_peer_device(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;
@@ -835,7 +840,7 @@ static bool remote_due_to_read_balancing(struct drbd_device *device, sector_t se
static void complete_conflicting_writes(struct drbd_request *req)
{
DEFINE_WAIT(wait);
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct drbd_interval *i;
sector_t sector = req->i.sector;
int size = req->i.size;
@@ -915,7 +920,7 @@ static void maybe_pull_ahead(struct drbd_device *device)
*/
static bool do_remote_read(struct drbd_request *req)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
enum drbd_read_balancing rbm;
if (req->private_bio) {
@@ -960,7 +965,7 @@ static bool do_remote_read(struct drbd_request *req)
* which does NOT include those that we are L_AHEAD for. */
static int drbd_process_write_request(struct drbd_request *req)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
int remote, send_oos;
remote = drbd_should_do_remote(device->state);
@@ -997,7 +1002,7 @@ static int drbd_process_write_request(struct drbd_request *req)
static void
drbd_submit_req_private_bio(struct drbd_request *req)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct bio *bio = req->private_bio;
const int rw = bio_rw(bio);
@@ -1390,7 +1395,7 @@ void request_timer_fn(unsigned long data)
drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n");
_drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL);
}
- if (dt && req->rq_state & RQ_LOCAL_PENDING && req->w.device == device &&
+ if (dt && req->rq_state & RQ_LOCAL_PENDING && req->device == device &&
time_after(now, req->start_time + dt) &&
!time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) {
drbd_warn(device, "Local backing device failed to meet the disk-timeout\n");
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 5ce6dc5..c684c96 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -294,7 +294,7 @@ extern void drbd_restart_request(struct drbd_request *req);
* outside the spinlock, e.g. when walking some list on cleanup. */
static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
{
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct bio_and_error m;
int rv;
@@ -314,7 +314,7 @@ static inline int req_mod(struct drbd_request *req,
enum drbd_req_event what)
{
unsigned long flags;
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct bio_and_error m;
int rv;
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 3f5c5a5..c9a0dba 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -35,6 +35,7 @@ extern void tl_abort_disk_io(struct drbd_device *device);
struct after_state_chg_work {
struct drbd_work w;
+ struct drbd_device *device;
union drbd_state os;
union drbd_state ns;
enum chg_state_flags flags;
@@ -1148,9 +1149,10 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
ascw->ns = ns;
ascw->flags = flags;
ascw->w.cb = w_after_state_ch;
- ascw->w.device = device;
+ ascw->device = device;
ascw->done = done;
- drbd_queue_work(&first_peer_device(device)->connection->sender_work, &ascw->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work,
+ &ascw->w);
} else {
drbd_err(device, "Could not kmalloc an ascw\n");
}
@@ -1162,7 +1164,7 @@ static int w_after_state_ch(struct drbd_work *w, int unused)
{
struct after_state_chg_work *ascw =
container_of(w, struct after_state_chg_work, w);
- struct drbd_device *device = w->device;
+ struct drbd_device *device = ascw->device;
after_state_ch(device, ascw->os, ascw->ns, ascw->flags);
if (ascw->flags & CS_WAIT_COMPLETE)
@@ -1531,18 +1533,19 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
}
struct after_conn_state_chg_work {
- struct drbd_work w;
+ struct drbd_device_work dw;
enum drbd_conns oc;
union drbd_state ns_min;
union drbd_state ns_max; /* new, max state, over all devices */
enum chg_state_flags flags;
+ struct drbd_connection *connection;
};
static int w_after_conn_state_ch(struct drbd_work *w, int unused)
{
struct after_conn_state_chg_work *acscw =
- container_of(w, struct after_conn_state_chg_work, w);
- struct drbd_connection *connection = w->connection;
+ container_of(w, struct after_conn_state_chg_work, dw.w);
+ struct drbd_connection *connection = acscw->connection;
enum drbd_conns oc = acscw->oc;
union drbd_state ns_max = acscw->ns_max;
struct drbd_peer_device *peer_device;
@@ -1843,10 +1846,10 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
acscw->ns_min = ns_min;
acscw->ns_max = ns_max;
acscw->flags = flags;
- acscw->w.cb = w_after_conn_state_ch;
+ acscw->dw.w.cb = w_after_conn_state_ch;
kref_get(&connection->kref);
- acscw->w.connection = connection;
- drbd_queue_work(&connection->sender_work, &acscw->w);
+ acscw->connection = connection;
+ drbd_queue_work(&connection->sender_work, &acscw->dw.w);
} else {
drbd_err(connection, "Could not kmalloc an acscw\n");
}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 7d68227..514d189 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -21,7 +21,7 @@
along with drbd; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+*/
#include <linux/module.h>
#include <linux/drbd.h>
@@ -39,7 +39,7 @@
#include "drbd_protocol.h"
#include "drbd_req.h"
-static int w_make_ov_request(struct drbd_work *w, int cancel);
+static int w_make_ov_request(struct drbd_work *, int);
/* endio handlers:
@@ -100,18 +100,19 @@ void drbd_md_io_complete(struct bio *bio, int error)
void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{
unsigned long flags = 0;
- struct drbd_device *device = peer_req->w.device;
+ struct drbd_device *device = peer_req->dw.device;
spin_lock_irqsave(&device->resource->req_lock, flags);
device->read_cnt += peer_req->i.size >> 9;
- list_del(&peer_req->w.list);
+ list_del(&peer_req->dw.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->resource->req_lock, flags);
- drbd_queue_work(&first_peer_device(device)->connection->sender_work, &peer_req->w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work,
+ &peer_req->dw.w);
put_ldev(device);
}
@@ -120,7 +121,7 @@ void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(lo
static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{
unsigned long flags = 0;
- struct drbd_device *device = peer_req->w.device;
+ struct drbd_device *device = peer_req->dw.device;
struct drbd_interval i;
int do_wake;
u64 block_id;
@@ -136,13 +137,13 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
spin_lock_irqsave(&device->resource->req_lock, flags);
device->writ_cnt += peer_req->i.size >> 9;
- list_move_tail(&peer_req->w.list, &device->done_ee);
+ list_move_tail(&peer_req->dw.w.list, &device->done_ee);
/*
* Do not remove from the write_requests tree here: we did not send the
* Ack yet and did not wake possibly waiting conflicting requests.
* Removed from the tree from "drbd_process_done_ee" within the
- * appropriate w.cb (e_end_block/e_end_resync_block) or from
+ * appropriate dw.cb (e_end_block/e_end_resync_block) or from
* _drbd_clear_done_ee.
*/
@@ -171,7 +172,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
void drbd_peer_request_endio(struct bio *bio, int error)
{
struct drbd_peer_request *peer_req = bio->bi_private;
- struct drbd_device *device = peer_req->w.device;
+ struct drbd_device *device = peer_req->dw.device;
int uptodate = bio_flagged(bio, BIO_UPTODATE);
int is_write = bio_data_dir(bio) == WRITE;
@@ -208,7 +209,7 @@ void drbd_request_endio(struct bio *bio, int error)
{
unsigned long flags;
struct drbd_request *req = bio->bi_private;
- struct drbd_device *device = req->w.device;
+ struct drbd_device *device = req->device;
struct bio_and_error m;
enum drbd_req_event what;
int uptodate = bio_flagged(bio, BIO_UPTODATE);
@@ -332,8 +333,9 @@ void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest)
/* MAYBE merge common code with w_e_end_ov_req */
static int w_e_send_csum(struct drbd_work *w, int cancel)
{
- struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
int digest_size;
void *digest;
int err = 0;
@@ -396,9 +398,9 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
if (!peer_req)
goto defer;
- peer_req->w.cb = w_e_send_csum;
+ peer_req->dw.w.cb = w_e_send_csum;
spin_lock_irq(&device->resource->req_lock);
- list_add(&peer_req->w.list, &device->read_ee);
+ list_add(&peer_req->dw.w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock);
atomic_add(size >> 9, &device->rs_sect_ev);
@@ -410,7 +412,7 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
* retry may or may not help.
* If it does not, you may need to force disconnect. */
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->w.list);
+ list_del(&peer_req->dw.w.list);
spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req);
@@ -421,7 +423,9 @@ defer:
int w_resync_timer(struct drbd_work *w, int cancel)
{
- struct drbd_device *device = w->device;
+ struct drbd_device *device =
+ container_of(w, struct drbd_device, resync_work);
+
switch (device->state.conn) {
case C_VERIFY_S:
w_make_ov_request(w, cancel);
@@ -439,7 +443,8 @@ 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(&first_peer_device(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)
@@ -563,7 +568,8 @@ static int drbd_rs_number_requests(struct drbd_device *device)
int w_make_resync_request(struct drbd_work *w, int cancel)
{
- struct drbd_device *device = w->device;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_device *device = dw->device;
unsigned long bit;
sector_t sector;
const sector_t capacity = drbd_get_capacity(device->this_bdev);
@@ -727,7 +733,7 @@ next_sector:
static int w_make_ov_request(struct drbd_work *w, int cancel)
{
- struct drbd_device *device = w->device;
+ struct drbd_device *device = device_work(w)->device;
int number, i, size;
sector_t sector;
const sector_t capacity = drbd_get_capacity(device->this_bdev);
@@ -781,8 +787,10 @@ static int w_make_ov_request(struct drbd_work *w, int cancel)
int w_ov_finished(struct drbd_work *w, int cancel)
{
- struct drbd_device *device = w->device;
- kfree(w);
+ struct drbd_device_work *dw =
+ container_of(w, struct drbd_device_work, w);
+ struct drbd_device *device = dw->device;
+ kfree(dw);
ov_out_of_sync_print(device);
drbd_resync_finished(device);
@@ -791,8 +799,10 @@ int w_ov_finished(struct drbd_work *w, int cancel)
static int w_resync_finished(struct drbd_work *w, int cancel)
{
- struct drbd_device *device = w->device;
- kfree(w);
+ struct drbd_device_work *dw =
+ container_of(w, struct drbd_device_work, w);
+ struct drbd_device *device = dw->device;
+ kfree(dw);
drbd_resync_finished(device);
@@ -814,7 +824,7 @@ int drbd_resync_finished(struct drbd_device *device)
unsigned long db, dt, dbdt;
unsigned long n_oos;
union drbd_state os, ns;
- struct drbd_work *w;
+ struct drbd_device_work *dw;
char *khelper_cmd = NULL;
int verify_done = 0;
@@ -828,20 +838,21 @@ int drbd_resync_finished(struct drbd_device *device)
* is not finished by now). Retry in 100ms. */
schedule_timeout_interruptible(HZ / 10);
- w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC);
- if (w) {
- w->cb = w_resync_finished;
- w->device = device;
- drbd_queue_work(&first_peer_device(device)->connection->sender_work, w);
+ dw = kmalloc(sizeof(struct drbd_device_work), GFP_ATOMIC);
+ if (dw) {
+ dw->w.cb = w_resync_finished;
+ dw->device = device;
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work,
+ &dw->w);
return 1;
}
- drbd_err(device, "Warn failed to drbd_rs_del_all() and to kmalloc(w).\n");
+ drbd_err(device, "Warn failed to drbd_rs_del_all() and to kmalloc(dw).\n");
}
dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
if (dt <= 0)
dt = 1;
-
+
db = device->rs_total;
/* adjust for verify start and stop sectors, respective reached position */
if (device->state.conn == C_VERIFY_S || device->state.conn == C_VERIFY_T)
@@ -972,7 +983,7 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_
atomic_add(i, &device->pp_in_use_by_net);
atomic_sub(i, &device->pp_in_use);
spin_lock_irq(&device->resource->req_lock);
- list_add_tail(&peer_req->w.list, &device->net_ee);
+ list_add_tail(&peer_req->dw.w.list, &device->net_ee);
spin_unlock_irq(&device->resource->req_lock);
wake_up(&drbd_pp_wait);
} else
@@ -987,8 +998,9 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_
*/
int w_e_end_data_req(struct drbd_work *w, int cancel)
{
- struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
int err;
if (unlikely(cancel)) {
@@ -1018,14 +1030,14 @@ int w_e_end_data_req(struct drbd_work *w, int cancel)
/**
* w_e_end_rsdata_req() - Worker callback to send a P_RS_DATA_REPLY packet in response to a P_RS_DATA_REQUEST
- * @device: DRBD device.
* @w: work object.
* @cancel: The connection will be closed anyways
*/
int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
{
- struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
int err;
if (unlikely(cancel)) {
@@ -1073,8 +1085,9 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
{
- struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
struct digest_info *di;
int digest_size;
void *digest = NULL;
@@ -1136,8 +1149,9 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
int w_e_end_ov_req(struct drbd_work *w, int cancel)
{
- struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
sector_t sector = peer_req->i.sector;
unsigned int size = peer_req->i.size;
int digest_size;
@@ -1192,8 +1206,9 @@ void drbd_ov_out_of_sync_found(struct drbd_device *device, sector_t sector, int
int w_e_end_ov_reply(struct drbd_work *w, int cancel)
{
- struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = w->device;
+ struct drbd_device_work *dw = device_work(w);
+ struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
+ struct drbd_device *device = dw->device;
struct digest_info *di;
void *digest;
sector_t sector = peer_req->i.sector;
@@ -1285,7 +1300,8 @@ int drbd_send_barrier(struct drbd_connection *connection)
int w_send_write_hint(struct drbd_work *w, int cancel)
{
- struct drbd_device *device = w->device;
+ struct drbd_device *device =
+ container_of(w, struct drbd_device, unplug_work);
struct drbd_socket *sock;
if (cancel)
@@ -1320,7 +1336,7 @@ static void maybe_send_barrier(struct drbd_connection *connection, unsigned int
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_device *device = req->device;
struct drbd_connection *connection = first_peer_device(device)->connection;
int err;
@@ -1343,14 +1359,13 @@ int w_send_out_of_sync(struct drbd_work *w, int cancel)
/**
* w_send_dblock() - Worker callback to send a P_DATA packet in order to mirror a write request
- * @device: DRBD device.
* @w: work object.
* @cancel: The connection will be closed anyways
*/
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_device *device = req->device;
struct drbd_connection *connection = first_peer_device(device)->connection;
int err;
@@ -1371,14 +1386,13 @@ int w_send_dblock(struct drbd_work *w, int cancel)
/**
* w_send_read_req() - Worker callback to send a read request (P_DATA_REQUEST) packet
- * @device: DRBD device.
* @w: work object.
* @cancel: The connection will be closed anyways
*/
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_device *device = req->device;
struct drbd_connection *connection = first_peer_device(device)->connection;
int err;
@@ -1402,7 +1416,7 @@ int w_send_read_req(struct drbd_work *w, int cancel)
int w_restart_disk_io(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_device *device = req->device;
if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
drbd_al_begin_io(device, &req->i, false);
@@ -1574,12 +1588,14 @@ void start_resync_timer_fn(unsigned long data)
{
struct drbd_device *device = (struct drbd_device *) data;
- drbd_queue_work(&first_peer_device(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)
{
- struct drbd_device *device = w->device;
+ struct drbd_device *device =
+ container_of(w, struct drbd_device, start_resync_work);
if (atomic_read(&device->unacked_cnt) || atomic_read(&device->rs_pending_cnt)) {
drbd_warn(device, "w_start_resync later...\n");
@@ -1881,7 +1897,7 @@ void wait_for_work(struct drbd_connection *connection, struct list_head *work_li
int drbd_worker(struct drbd_thread *thi)
{
struct drbd_connection *connection = thi->connection;
- struct drbd_work *w = NULL;
+ struct drbd_device_work *dw = NULL;
struct drbd_peer_device *peer_device;
LIST_HEAD(work_list);
int vnr;
@@ -1907,9 +1923,9 @@ int drbd_worker(struct drbd_thread *thi)
break;
while (!list_empty(&work_list)) {
- w = list_first_entry(&work_list, struct drbd_work, list);
- list_del_init(&w->list);
- if (w->cb(w, connection->cstate < C_WF_REPORT_PARAMS) == 0)
+ dw = list_first_entry(&work_list, struct drbd_device_work, w.list);
+ list_del_init(&dw->w.list);
+ if (dw->w.cb(&dw->w, connection->cstate < C_WF_REPORT_PARAMS) == 0)
continue;
if (connection->cstate >= C_WF_REPORT_PARAMS)
conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
@@ -1918,9 +1934,9 @@ int drbd_worker(struct drbd_thread *thi)
do {
while (!list_empty(&work_list)) {
- w = list_first_entry(&work_list, struct drbd_work, list);
- list_del_init(&w->list);
- w->cb(w, 1);
+ dw = list_first_entry(&work_list, struct drbd_device_work, w.list);
+ list_del_init(&dw->w.list);
+ dw->w.cb(&dw->w, 1);
}
dequeue_work_batch(&connection->sender_work, &work_list);
} while (!list_empty(&work_list));
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 18/27] drbd: Turn conn_flush_workqueue() into drbd_flush_workqueue()
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (16 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 17/27] drbd: Create a dedicated struct drbd_device_work Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 19/27] drbd: struct after_conn_state_chg_work: Use drbd_work instead of drbd_device_work Philipp Reisner
` (8 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
The new function can flush any work queue, not just the work queue of the data
socket of a connection.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 12 ++----------
drivers/block/drbd/drbd_main.c | 24 ++++++++++++++++++++++++
drivers/block/drbd/drbd_nl.c | 10 +++++-----
drivers/block/drbd/drbd_receiver.c | 22 ++--------------------
4 files changed, 33 insertions(+), 35 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index eb2bc90..7185c98 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -346,11 +346,6 @@ enum epoch_event {
EV_CLEANUP = 32, /* used as flag */
};
-struct drbd_wq_barrier {
- struct drbd_work w;
- struct completion done;
-};
-
struct digest_info {
int digest_size;
void *digest;
@@ -1349,12 +1344,7 @@ extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request
extern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool);
extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);
extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed);
-extern void conn_flush_workqueue(struct drbd_connection *connection);
extern int drbd_connected(struct drbd_peer_device *);
-static inline void drbd_flush_workqueue(struct drbd_device *device)
-{
- conn_flush_workqueue(first_peer_device(device)->connection);
-}
/* Yes, there is kernel_setsockopt, but only since 2.6.18.
* So we have our own copy of it here. */
@@ -1709,6 +1699,8 @@ drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
wake_up(&q->q_wait);
}
+extern void drbd_flush_workqueue(struct drbd_work_queue *work_queue);
+
static inline void wake_asender(struct drbd_connection *connection)
{
if (test_bit(SIGNAL_ASENDER, &connection->flags))
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0500b56..e11f606 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2397,6 +2397,30 @@ static void drbd_init_workqueue(struct drbd_work_queue* wq)
init_waitqueue_head(&wq->q_wait);
}
+struct completion_work {
+ struct drbd_work w;
+ struct completion done;
+};
+
+static int w_complete(struct drbd_work *w, int cancel)
+{
+ struct completion_work *completion_work =
+ container_of(w, struct completion_work, w);
+
+ complete(&completion_work->done);
+ return 0;
+}
+
+void drbd_flush_workqueue(struct drbd_work_queue *work_queue)
+{
+ struct completion_work completion_work;
+
+ completion_work.w.cb = w_complete;
+ init_completion(&completion_work.done);
+ drbd_queue_work(work_queue, &completion_work.w);
+ wait_for_completion(&completion_work.done);
+}
+
struct drbd_resource *drbd_find_resource(const char *name)
{
struct drbd_resource *resource;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index f613ba9..b202cdb 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1181,7 +1181,7 @@ void drbd_reconsider_max_bio_size(struct drbd_device *device)
static void conn_reconfig_start(struct drbd_connection *connection)
{
drbd_thread_start(&connection->worker);
- conn_flush_workqueue(connection);
+ drbd_flush_workqueue(&connection->sender_work);
}
/* if still unconfigured, stops worker again. */
@@ -1600,7 +1600,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
*/
wait_event(device->misc_wait, !atomic_read(&device->ap_pending_cnt) || drbd_suspended(device));
/* and for any other previously queued work */
- drbd_flush_workqueue(device);
+ drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work);
rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE);
retcode = rv; /* FIXME: Type mismatch. */
@@ -2249,7 +2249,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
((char *)new_net_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
- conn_flush_workqueue(connection);
+ drbd_flush_workqueue(&connection->sender_work);
mutex_lock(&adm_ctx.resource->conf_update);
old_net_conf = connection->net_conf;
@@ -2589,7 +2589,7 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
* Also wait for it's after_state_ch(). */
drbd_suspend_io(device);
wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags));
- drbd_flush_workqueue(device);
+ drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work);
/* If we happen to be C_STANDALONE R_SECONDARY, just change to
* D_INCONSISTENT, and set all bits in the bitmap. Otherwise,
@@ -2655,7 +2655,7 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
* Also wait for it's after_state_ch(). */
drbd_suspend_io(device);
wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags));
- drbd_flush_workqueue(device);
+ drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work);
/* If we happen to be C_STANDALONE R_PRIMARY, just set all bits
* in the bitmap. Otherwise, try to start a resync handshake
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 3c88efa..c99f252 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4484,24 +4484,6 @@ static void drbdd(struct drbd_connection *connection)
conn_request_state(connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
}
-static int w_complete(struct drbd_work *w, int cancel)
-{
- struct drbd_wq_barrier *b = container_of(w, struct drbd_wq_barrier, w);
-
- complete(&b->done);
- return 0;
-}
-
-void conn_flush_workqueue(struct drbd_connection *connection)
-{
- struct drbd_wq_barrier barr;
-
- barr.w.cb = w_complete;
- init_completion(&barr.done);
- drbd_queue_work(&connection->sender_work, &barr.w);
- wait_for_completion(&barr.done);
-}
-
static void conn_disconnect(struct drbd_connection *connection)
{
struct drbd_peer_device *peer_device;
@@ -4589,14 +4571,14 @@ static int drbd_disconnected(struct drbd_peer_device *peer_device)
/* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier,
* w_make_resync_request etc. which may still be on the worker queue
* to be "canceled" */
- drbd_flush_workqueue(device);
+ drbd_flush_workqueue(&peer_device->connection->sender_work);
drbd_finish_peer_reqs(device);
/* This second workqueue flush is necessary, since drbd_finish_peer_reqs()
might have issued a work again. The one before drbd_finish_peer_reqs() is
necessary to reclain net_ee in drbd_finish_peer_reqs(). */
- drbd_flush_workqueue(device);
+ drbd_flush_workqueue(&peer_device->connection->sender_work);
/* need to do it again, drbd_finish_peer_reqs() may have populated it
* again via drbd_try_clear_on_disk_bm(). */
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 19/27] drbd: struct after_conn_state_chg_work: Use drbd_work instead of drbd_device_work
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (17 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 18/27] drbd: Turn conn_flush_workqueue() into drbd_flush_workqueue() Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 20/27] drbd: struct drbd_peer_request: " Philipp Reisner
` (7 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_state.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index c9a0dba..720b803 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1533,7 +1533,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
}
struct after_conn_state_chg_work {
- struct drbd_device_work dw;
+ struct drbd_work w;
enum drbd_conns oc;
union drbd_state ns_min;
union drbd_state ns_max; /* new, max state, over all devices */
@@ -1544,7 +1544,7 @@ struct after_conn_state_chg_work {
static int w_after_conn_state_ch(struct drbd_work *w, int unused)
{
struct after_conn_state_chg_work *acscw =
- container_of(w, struct after_conn_state_chg_work, dw.w);
+ container_of(w, struct after_conn_state_chg_work, w);
struct drbd_connection *connection = acscw->connection;
enum drbd_conns oc = acscw->oc;
union drbd_state ns_max = acscw->ns_max;
@@ -1846,10 +1846,10 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
acscw->ns_min = ns_min;
acscw->ns_max = ns_max;
acscw->flags = flags;
- acscw->dw.w.cb = w_after_conn_state_ch;
+ acscw->w.cb = w_after_conn_state_ch;
kref_get(&connection->kref);
acscw->connection = connection;
- drbd_queue_work(&connection->sender_work, &acscw->dw.w);
+ drbd_queue_work(&connection->sender_work, &acscw->w);
} else {
drbd_err(connection, "Could not kmalloc an acscw\n");
}
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 20/27] drbd: struct drbd_peer_request: Use drbd_work instead of drbd_device_work
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (18 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 19/27] drbd: struct after_conn_state_chg_work: Use drbd_work instead of drbd_device_work Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 21/27] drbd: Make w_make_resync_request() static Philipp Reisner
` (6 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 3 +-
drivers/block/drbd/drbd_receiver.c | 91 ++++++++++++++++++------------------
drivers/block/drbd/drbd_worker.c | 50 +++++++++-----------
3 files changed, 69 insertions(+), 75 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 7185c98..12dc970 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -352,7 +352,8 @@ struct digest_info {
};
struct drbd_peer_request {
- struct drbd_device_work dw;
+ struct drbd_work w;
+ struct drbd_peer_device *peer_device;
struct drbd_epoch *epoch; /* for writes */
struct page *pages;
atomic_t pending_bios;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index c99f252..e2e01b4 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -200,19 +200,17 @@ static struct page *__drbd_alloc_pages(struct drbd_device *device,
static void reclaim_finished_net_peer_reqs(struct drbd_device *device,
struct list_head *to_be_freed)
{
- struct drbd_peer_request *peer_req;
- struct list_head *le, *tle;
+ struct drbd_peer_request *peer_req, *tmp;
/* The EEs are always appended to the end of the list. Since
they are sent in order over the wire, they have to finish
in order. As soon as we see the first not finished we can
stop to examine the list... */
- list_for_each_safe(le, tle, &device->net_ee) {
- peer_req = list_entry(le, struct drbd_peer_request, dw.w.list);
+ list_for_each_entry_safe(peer_req, tmp, &device->net_ee, w.list) {
if (drbd_peer_req_has_active_page(peer_req))
break;
- list_move(le, to_be_freed);
+ list_move(&peer_req->w.list, to_be_freed);
}
}
@@ -225,7 +223,7 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
reclaim_finished_net_peer_reqs(device, &reclaimed);
spin_unlock_irq(&device->resource->req_lock);
- list_for_each_entry_safe(peer_req, t, &reclaimed, dw.w.list)
+ list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
drbd_free_net_peer_req(device, peer_req);
}
@@ -363,7 +361,7 @@ drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t secto
peer_req->i.waiting = false;
peer_req->epoch = NULL;
- peer_req->dw.device = device;
+ peer_req->peer_device = peer_device;
peer_req->pages = page;
atomic_set(&peer_req->pending_bios, 0);
peer_req->flags = 0;
@@ -402,7 +400,7 @@ int drbd_free_peer_reqs(struct drbd_device *device, struct list_head *list)
list_splice_init(list, &work_list);
spin_unlock_irq(&device->resource->req_lock);
- list_for_each_entry_safe(peer_req, t, &work_list, dw.w.list) {
+ list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
__drbd_free_peer_req(device, peer_req, is_net);
count++;
}
@@ -424,18 +422,18 @@ static int drbd_finish_peer_reqs(struct drbd_device *device)
list_splice_init(&device->done_ee, &work_list);
spin_unlock_irq(&device->resource->req_lock);
- list_for_each_entry_safe(peer_req, t, &reclaimed, dw.w.list)
+ list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
drbd_free_net_peer_req(device, peer_req);
/* possible callbacks here:
* e_end_block, and e_end_resync_block, e_send_superseded.
* all ignore the last argument.
*/
- list_for_each_entry_safe(peer_req, t, &work_list, dw.w.list) {
+ list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
int err2;
/* list_del not necessary, next/prev members not touched */
- err2 = peer_req->dw.w.cb(&peer_req->dw.w, !!err);
+ err2 = peer_req->w.cb(&peer_req->w, !!err);
if (!err)
err = err2;
drbd_free_peer_req(device, peer_req);
@@ -1664,10 +1662,10 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req
*/
static int e_end_resync_block(struct drbd_work *w, int unused)
{
- struct drbd_device_work *dw = device_work(w);
struct drbd_peer_request *peer_req =
- container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ container_of(w, struct drbd_peer_request, w);
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
sector_t sector = peer_req->i.sector;
int err;
@@ -1675,12 +1673,12 @@ static int e_end_resync_block(struct drbd_work *w, int unused)
if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
drbd_set_in_sync(device, sector, peer_req->i.size);
- err = drbd_send_ack(first_peer_device(device), P_RS_WRITE_ACK, peer_req);
+ err = drbd_send_ack(peer_device, P_RS_WRITE_ACK, peer_req);
} else {
/* Record failure to sync */
drbd_rs_failed_io(device, sector, peer_req->i.size);
- err = drbd_send_ack(first_peer_device(device), P_NEG_ACK, peer_req);
+ err = drbd_send_ack(peer_device, P_NEG_ACK, peer_req);
}
dec_unacked(device);
@@ -1703,10 +1701,10 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
/* corresponding dec_unacked() in e_end_resync_block()
* respective _drbd_clear_done_ee */
- peer_req->dw.w.cb = e_end_resync_block;
+ peer_req->w.cb = e_end_resync_block;
spin_lock_irq(&device->resource->req_lock);
- list_add(&peer_req->dw.w.list, &device->sync_ee);
+ list_add(&peer_req->w.list, &device->sync_ee);
spin_unlock_irq(&device->resource->req_lock);
atomic_add(data_size >> 9, &device->rs_sect_ev);
@@ -1716,7 +1714,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->dw.w.list);
+ list_del(&peer_req->w.list);
spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req);
@@ -1836,10 +1834,10 @@ static void restart_conflicting_writes(struct drbd_device *device,
*/
static int e_end_block(struct drbd_work *w, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
struct drbd_peer_request *peer_req =
- container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ container_of(w, struct drbd_peer_request, w);
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
sector_t sector = peer_req->i.sector;
int err = 0, pcmd;
@@ -1849,11 +1847,11 @@ static int e_end_block(struct drbd_work *w, int cancel)
device->state.conn <= C_PAUSED_SYNC_T &&
peer_req->flags & EE_MAY_SET_IN_SYNC) ?
P_RS_WRITE_ACK : P_WRITE_ACK;
- err = drbd_send_ack(first_peer_device(device), pcmd, peer_req);
+ err = drbd_send_ack(peer_device, pcmd, peer_req);
if (pcmd == P_RS_WRITE_ACK)
drbd_set_in_sync(device, sector, peer_req->i.size);
} else {
- err = drbd_send_ack(first_peer_device(device), P_NEG_ACK, peer_req);
+ err = drbd_send_ack(peer_device, P_NEG_ACK, peer_req);
/* we expect it to be marked out of sync anyways...
* maybe assert this? */
}
@@ -1876,30 +1874,31 @@ static int e_end_block(struct drbd_work *w, int cancel)
return err;
}
-static int e_send_ack(struct drbd_device_work *dw, enum drbd_packet ack)
+static int e_send_ack(struct drbd_work *w, enum drbd_packet ack)
{
- struct drbd_device *device = dw->device;
struct drbd_peer_request *peer_req =
- container_of(dw, struct drbd_peer_request, dw);
+ container_of(w, struct drbd_peer_request, w);
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
int err;
- err = drbd_send_ack(first_peer_device(device), ack, peer_req);
- dec_unacked(device);
+ err = drbd_send_ack(peer_device, ack, peer_req);
+ dec_unacked(peer_device->device);
return err;
}
static int e_send_superseded(struct drbd_work *w, int unused)
{
- return e_send_ack(device_work(w), P_SUPERSEDED);
+ return e_send_ack(w, P_SUPERSEDED);
}
static int e_send_retry_write(struct drbd_work *w, int unused)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_connection *connection = first_peer_device(dw->device)->connection;
+ struct drbd_peer_request *peer_req =
+ container_of(w, struct drbd_peer_request, w);
+ struct drbd_connection *connection = peer_req->peer_device->connection;
- return e_send_ack(dw, connection->agreed_pro_version >= 100 ?
+ return e_send_ack(w, connection->agreed_pro_version >= 100 ?
P_RETRY_WRITE : P_SUPERSEDED);
}
@@ -1946,7 +1945,7 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee
bool rv = 0;
spin_lock_irq(&device->resource->req_lock);
- list_for_each_entry(rs_req, &device->sync_ee, dw.w.list) {
+ list_for_each_entry(rs_req, &device->sync_ee, w.list) {
if (overlaps(peer_req->i.sector, peer_req->i.size,
rs_req->i.sector, rs_req->i.size)) {
rv = 1;
@@ -2117,9 +2116,9 @@ static int handle_write_conflicts(struct drbd_device *device,
superseded ? "local" : "remote");
inc_unacked(device);
- peer_req->dw.w.cb = superseded ? e_send_superseded :
+ peer_req->w.cb = superseded ? e_send_superseded :
e_send_retry_write;
- list_add_tail(&peer_req->dw.w.list, &device->done_ee);
+ list_add_tail(&peer_req->w.list, &device->done_ee);
wake_asender(first_peer_device(device)->connection);
err = -ENOENT;
@@ -2215,7 +2214,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
return -EIO;
}
- peer_req->dw.w.cb = e_end_block;
+ peer_req->w.cb = e_end_block;
dp_flags = be32_to_cpu(p->dp_flags);
rw |= wire_flags_to_bio(device, dp_flags);
@@ -2255,7 +2254,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
update_peer_seq(peer_device, peer_seq);
spin_lock_irq(&device->resource->req_lock);
}
- list_add(&peer_req->dw.w.list, &device->active_ee);
+ list_add(&peer_req->w.list, &device->active_ee);
spin_unlock_irq(&device->resource->req_lock);
if (device->state.conn == C_SYNC_TARGET)
@@ -2302,7 +2301,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->dw.w.list);
+ list_del(&peer_req->w.list);
drbd_remove_epoch_entry_interval(device, peer_req);
spin_unlock_irq(&device->resource->req_lock);
if (peer_req->flags & EE_CALL_AL_COMPLETE_IO)
@@ -2457,13 +2456,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
switch (pi->cmd) {
case P_DATA_REQUEST:
- peer_req->dw.w.cb = w_e_end_data_req;
+ peer_req->w.cb = w_e_end_data_req;
fault_type = DRBD_FAULT_DT_RD;
/* application IO, don't drbd_rs_begin_io */
goto submit;
case P_RS_DATA_REQUEST:
- peer_req->dw.w.cb = w_e_end_rsdata_req;
+ peer_req->w.cb = w_e_end_rsdata_req;
fault_type = DRBD_FAULT_RS_RD;
/* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector);
@@ -2487,13 +2486,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
if (pi->cmd == P_CSUM_RS_REQUEST) {
D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
- peer_req->dw.w.cb = w_e_end_csum_rs_req;
+ peer_req->w.cb = w_e_end_csum_rs_req;
/* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector);
} else if (pi->cmd == P_OV_REPLY) {
/* track progress, we may need to throttle */
atomic_add(size >> 9, &device->rs_sect_in);
- peer_req->dw.w.cb = w_e_end_ov_reply;
+ peer_req->w.cb = w_e_end_ov_reply;
dec_rs_pending(device);
/* drbd_rs_begin_io done when we sent this request,
* but accounting still needs to be done. */
@@ -2517,7 +2516,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
drbd_info(device, "Online Verify start sector: %llu\n",
(unsigned long long)sector);
}
- peer_req->dw.w.cb = w_e_end_ov_req;
+ peer_req->w.cb = w_e_end_ov_req;
fault_type = DRBD_FAULT_RS_RD;
break;
@@ -2558,7 +2557,7 @@ submit_for_resync:
submit:
inc_unacked(device);
spin_lock_irq(&device->resource->req_lock);
- list_add_tail(&peer_req->dw.w.list, &device->read_ee);
+ list_add_tail(&peer_req->w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock);
if (drbd_submit_peer_request(device, peer_req, READ, fault_type) == 0)
@@ -2567,7 +2566,7 @@ submit:
/* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->dw.w.list);
+ list_del(&peer_req->w.list);
spin_unlock_irq(&device->resource->req_lock);
/* no drbd_rs_complete_io(), we are dropping the connection anyways */
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 514d189..abcfdab 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -100,11 +100,11 @@ void drbd_md_io_complete(struct bio *bio, int error)
void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{
unsigned long flags = 0;
- struct drbd_device *device = peer_req->dw.device;
+ struct drbd_device *device = peer_req->peer_device->device;
spin_lock_irqsave(&device->resource->req_lock, flags);
device->read_cnt += peer_req->i.size >> 9;
- list_del(&peer_req->dw.w.list);
+ 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))
@@ -112,7 +112,7 @@ void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(lo
spin_unlock_irqrestore(&device->resource->req_lock, flags);
drbd_queue_work(&first_peer_device(device)->connection->sender_work,
- &peer_req->dw.w);
+ &peer_req->w);
put_ldev(device);
}
@@ -121,7 +121,7 @@ void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(lo
static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{
unsigned long flags = 0;
- struct drbd_device *device = peer_req->dw.device;
+ struct drbd_device *device = peer_req->peer_device->device;
struct drbd_interval i;
int do_wake;
u64 block_id;
@@ -137,7 +137,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
spin_lock_irqsave(&device->resource->req_lock, flags);
device->writ_cnt += peer_req->i.size >> 9;
- list_move_tail(&peer_req->dw.w.list, &device->done_ee);
+ list_move_tail(&peer_req->w.list, &device->done_ee);
/*
* Do not remove from the write_requests tree here: we did not send the
@@ -172,7 +172,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
void drbd_peer_request_endio(struct bio *bio, int error)
{
struct drbd_peer_request *peer_req = bio->bi_private;
- struct drbd_device *device = peer_req->dw.device;
+ struct drbd_device *device = peer_req->peer_device->device;
int uptodate = bio_flagged(bio, BIO_UPTODATE);
int is_write = bio_data_dir(bio) == WRITE;
@@ -333,9 +333,8 @@ void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest)
/* MAYBE merge common code with w_e_end_ov_req */
static int w_e_send_csum(struct drbd_work *w, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+ struct drbd_device *device = peer_req->peer_device->device;
int digest_size;
void *digest;
int err = 0;
@@ -398,9 +397,9 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
if (!peer_req)
goto defer;
- peer_req->dw.w.cb = w_e_send_csum;
+ peer_req->w.cb = w_e_send_csum;
spin_lock_irq(&device->resource->req_lock);
- list_add(&peer_req->dw.w.list, &device->read_ee);
+ list_add(&peer_req->w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock);
atomic_add(size >> 9, &device->rs_sect_ev);
@@ -412,7 +411,7 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
* retry may or may not help.
* If it does not, you may need to force disconnect. */
spin_lock_irq(&device->resource->req_lock);
- list_del(&peer_req->dw.w.list);
+ list_del(&peer_req->w.list);
spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req);
@@ -983,7 +982,7 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_
atomic_add(i, &device->pp_in_use_by_net);
atomic_sub(i, &device->pp_in_use);
spin_lock_irq(&device->resource->req_lock);
- list_add_tail(&peer_req->dw.w.list, &device->net_ee);
+ list_add_tail(&peer_req->w.list, &device->net_ee);
spin_unlock_irq(&device->resource->req_lock);
wake_up(&drbd_pp_wait);
} else
@@ -998,9 +997,8 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_
*/
int w_e_end_data_req(struct drbd_work *w, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+ struct drbd_device *device = peer_req->peer_device->device;
int err;
if (unlikely(cancel)) {
@@ -1035,9 +1033,8 @@ int w_e_end_data_req(struct drbd_work *w, int cancel)
*/
int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+ struct drbd_device *device = peer_req->peer_device->device;
int err;
if (unlikely(cancel)) {
@@ -1085,9 +1082,8 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+ struct drbd_device *device = peer_req->peer_device->device;
struct digest_info *di;
int digest_size;
void *digest = NULL;
@@ -1149,9 +1145,8 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
int w_e_end_ov_req(struct drbd_work *w, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+ struct drbd_device *device = peer_req->peer_device->device;
sector_t sector = peer_req->i.sector;
unsigned int size = peer_req->i.size;
int digest_size;
@@ -1206,9 +1201,8 @@ void drbd_ov_out_of_sync_found(struct drbd_device *device, sector_t sector, int
int w_e_end_ov_reply(struct drbd_work *w, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
- struct drbd_device *device = dw->device;
+ struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+ struct drbd_device *device = peer_req->peer_device->device;
struct digest_info *di;
void *digest;
sector_t sector = peer_req->i.sector;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 21/27] drbd: Make w_make_resync_request() static
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (19 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 20/27] drbd: struct drbd_peer_request: " Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 22/27] drbd: Turn w_make_ov_request and make_resync_request into "normal" functions Philipp Reisner
` (5 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 1 -
drivers/block/drbd/drbd_worker.c | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 12dc970..2e262fd 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1316,7 +1316,6 @@ extern int w_e_end_ov_req(struct drbd_work *, int);
extern int w_ov_finished(struct drbd_work *, int);
extern int w_resync_timer(struct drbd_work *, int);
extern int w_send_write_hint(struct drbd_work *, int);
-extern int w_make_resync_request(struct drbd_work *, int);
extern int w_send_dblock(struct drbd_work *, int);
extern int w_send_read_req(struct drbd_work *, int);
extern int w_e_reissue(struct drbd_work *, int);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index abcfdab..b0f6ae0 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -40,7 +40,7 @@
#include "drbd_req.h"
static int w_make_ov_request(struct drbd_work *, int);
-
+static int w_make_resync_request(struct drbd_work *, int);
/* endio handlers:
* drbd_md_io_complete (defined here)
@@ -565,7 +565,7 @@ static int drbd_rs_number_requests(struct drbd_device *device)
return number;
}
-int w_make_resync_request(struct drbd_work *w, int cancel)
+static int w_make_resync_request(struct drbd_work *w, int cancel)
{
struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = dw->device;
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 22/27] drbd: Turn w_make_ov_request and make_resync_request into "normal" functions
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (20 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 21/27] drbd: Make w_make_resync_request() static Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 23/27] drbd: In the worker thread, process drbd_work instead of drbd_device_work items Philipp Reisner
` (4 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
These functions are not used as drbd_work callbacks.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_worker.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index b0f6ae0..7961af9 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -39,8 +39,8 @@
#include "drbd_protocol.h"
#include "drbd_req.h"
-static int w_make_ov_request(struct drbd_work *, int);
-static int w_make_resync_request(struct drbd_work *, int);
+static int make_ov_request(struct drbd_device *, int);
+static int make_resync_request(struct drbd_device *, int);
/* endio handlers:
* drbd_md_io_complete (defined here)
@@ -427,10 +427,10 @@ int w_resync_timer(struct drbd_work *w, int cancel)
switch (device->state.conn) {
case C_VERIFY_S:
- w_make_ov_request(w, cancel);
+ make_ov_request(device, cancel);
break;
case C_SYNC_TARGET:
- w_make_resync_request(w, cancel);
+ make_resync_request(device, cancel);
break;
}
@@ -565,10 +565,8 @@ static int drbd_rs_number_requests(struct drbd_device *device)
return number;
}
-static int w_make_resync_request(struct drbd_work *w, int cancel)
+static int make_resync_request(struct drbd_device *device, int cancel)
{
- struct drbd_device_work *dw = device_work(w);
- struct drbd_device *device = dw->device;
unsigned long bit;
sector_t sector;
const sector_t capacity = drbd_get_capacity(device->this_bdev);
@@ -730,9 +728,8 @@ next_sector:
return 0;
}
-static int w_make_ov_request(struct drbd_work *w, int cancel)
+static int make_ov_request(struct drbd_device *device, int cancel)
{
- struct drbd_device *device = device_work(w)->device;
int number, i, size;
sector_t sector;
const sector_t capacity = drbd_get_capacity(device->this_bdev);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 23/27] drbd: In the worker thread, process drbd_work instead of drbd_device_work items
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (21 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 22/27] drbd: Turn w_make_ov_request and make_resync_request into "normal" functions Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 24/27] drbd: Get rid of first_peer_device() in handle_write_conflicts() Philipp Reisner
` (3 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_worker.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 7961af9..b826648 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1888,7 +1888,7 @@ void wait_for_work(struct drbd_connection *connection, struct list_head *work_li
int drbd_worker(struct drbd_thread *thi)
{
struct drbd_connection *connection = thi->connection;
- struct drbd_device_work *dw = NULL;
+ struct drbd_work *w = NULL;
struct drbd_peer_device *peer_device;
LIST_HEAD(work_list);
int vnr;
@@ -1914,9 +1914,9 @@ int drbd_worker(struct drbd_thread *thi)
break;
while (!list_empty(&work_list)) {
- dw = list_first_entry(&work_list, struct drbd_device_work, w.list);
- list_del_init(&dw->w.list);
- if (dw->w.cb(&dw->w, connection->cstate < C_WF_REPORT_PARAMS) == 0)
+ w = list_first_entry(&work_list, struct drbd_work, list);
+ list_del_init(&w->list);
+ if (w->cb(w, connection->cstate < C_WF_REPORT_PARAMS) == 0)
continue;
if (connection->cstate >= C_WF_REPORT_PARAMS)
conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
@@ -1925,9 +1925,9 @@ int drbd_worker(struct drbd_thread *thi)
do {
while (!list_empty(&work_list)) {
- dw = list_first_entry(&work_list, struct drbd_device_work, w.list);
- list_del_init(&dw->w.list);
- dw->w.cb(&dw->w, 1);
+ w = list_first_entry(&work_list, struct drbd_work, list);
+ list_del_init(&w->list);
+ w->cb(w, 1);
}
dequeue_work_batch(&connection->sender_work, &work_list);
} while (!list_empty(&work_list));
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 24/27] drbd: Get rid of first_peer_device() in handle_write_conflicts()
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (22 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 23/27] drbd: In the worker thread, process drbd_work instead of drbd_device_work items Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 25/27] drbd: Remove unused parameter of wire_flags_to_bio() Philipp Reisner
` (2 subsequent siblings)
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index e2e01b4..5c0239e 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2065,7 +2065,7 @@ static void fail_postponed_requests(struct drbd_device *device, sector_t sector,
static int handle_write_conflicts(struct drbd_device *device,
struct drbd_peer_request *peer_req)
{
- struct drbd_connection *connection = first_peer_device(device)->connection;
+ struct drbd_connection *connection = peer_req->peer_device->connection;
bool resolve_conflicts = test_bit(RESOLVE_CONFLICTS, &connection->flags);
sector_t sector = peer_req->i.sector;
const unsigned int size = peer_req->i.size;
@@ -2119,7 +2119,7 @@ static int handle_write_conflicts(struct drbd_device *device,
peer_req->w.cb = superseded ? e_send_superseded :
e_send_retry_write;
list_add_tail(&peer_req->w.list, &device->done_ee);
- wake_asender(first_peer_device(device)->connection);
+ wake_asender(connection);
err = -ENOENT;
goto out;
@@ -2148,9 +2148,7 @@ static int handle_write_conflicts(struct drbd_device *device,
*/
err = drbd_wait_misc(device, &req->i);
if (err) {
- _conn_request_state(first_peer_device(device)->connection,
- NS(conn, C_TIMEOUT),
- CS_HARD);
+ _conn_request_state(connection, NS(conn, C_TIMEOUT), CS_HARD);
fail_postponed_requests(device, sector, size);
goto out;
}
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 25/27] drbd: Remove unused parameter of wire_flags_to_bio()
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (23 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 24/27] drbd: Get rid of first_peer_device() in handle_write_conflicts() Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 26/27] drbd: Use the right peer device Philipp Reisner
2013-12-23 21:50 ` [PATCH 27/27] drbd: Add drbd_thread->resource and make drbd_thread->connection optional Philipp Reisner
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 5c0239e..b7b05c9 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2029,7 +2029,7 @@ static int wait_for_and_update_peer_seq(struct drbd_peer_device *peer_device, co
/* see also bio_flags_to_wire()
* DRBD_REQ_*, because we need to semantically map the flags to data packet
* flags and back. We may replicate to other kernel versions. */
-static unsigned long wire_flags_to_bio(struct drbd_device *device, u32 dpf)
+static unsigned long wire_flags_to_bio(u32 dpf)
{
return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
(dpf & DP_FUA ? REQ_FUA : 0) |
@@ -2215,7 +2215,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
peer_req->w.cb = e_end_block;
dp_flags = be32_to_cpu(p->dp_flags);
- rw |= wire_flags_to_bio(device, dp_flags);
+ rw |= wire_flags_to_bio(dp_flags);
if (peer_req->pages == NULL) {
D_ASSERT(device, peer_req->i.size == 0);
D_ASSERT(device, dp_flags & DP_FLUSH);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 26/27] drbd: Use the right peer device
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (24 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 25/27] drbd: Remove unused parameter of wire_flags_to_bio() Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
2013-12-23 21:50 ` [PATCH 27/27] drbd: Add drbd_thread->resource and make drbd_thread->connection optional Philipp Reisner
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@kernel.org>
in w_e_ (peer request) callbacks and in peer request I/O completion handlers
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_worker.c | 69 +++++++++++++++++++++-----------------
1 file changed, 38 insertions(+), 31 deletions(-)
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index b826648..bf55f13 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -100,7 +100,8 @@ void drbd_md_io_complete(struct bio *bio, int error)
void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{
unsigned long flags = 0;
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
spin_lock_irqsave(&device->resource->req_lock, flags);
device->read_cnt += peer_req->i.size >> 9;
@@ -111,8 +112,7 @@ void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(lo
__drbd_chk_io_error(device, DRBD_READ_ERROR);
spin_unlock_irqrestore(&device->resource->req_lock, flags);
- drbd_queue_work(&first_peer_device(device)->connection->sender_work,
- &peer_req->w);
+ drbd_queue_work(&peer_device->connection->sender_work, &peer_req->w);
put_ldev(device);
}
@@ -121,7 +121,8 @@ void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(lo
static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{
unsigned long flags = 0;
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
struct drbd_interval i;
int do_wake;
u64 block_id;
@@ -162,7 +163,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(first_peer_device(device)->connection);
+ wake_asender(peer_device->connection);
put_ldev(device);
}
@@ -334,7 +335,8 @@ void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest)
static int w_e_send_csum(struct drbd_work *w, int cancel)
{
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
int digest_size;
void *digest;
int err = 0;
@@ -345,12 +347,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(first_peer_device(device)->connection->csums_tfm);
+ digest_size = crypto_hash_digestsize(peer_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(first_peer_device(device)->connection->csums_tfm, peer_req, digest);
+ drbd_csum_ee(peer_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
@@ -359,7 +361,7 @@ static int w_e_send_csum(struct drbd_work *w, int cancel)
drbd_free_peer_req(device, peer_req);
peer_req = NULL;
inc_rs_pending(device);
- err = drbd_send_drequest_csum(first_peer_device(device), sector, size,
+ err = drbd_send_drequest_csum(peer_device, sector, size,
digest, digest_size,
P_CSUM_RS_REQUEST);
kfree(digest);
@@ -995,7 +997,8 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_
int w_e_end_data_req(struct drbd_work *w, int cancel)
{
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
int err;
if (unlikely(cancel)) {
@@ -1005,13 +1008,13 @@ int w_e_end_data_req(struct drbd_work *w, int cancel)
}
if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
- err = drbd_send_block(first_peer_device(device), P_DATA_REPLY, peer_req);
+ err = drbd_send_block(peer_device, P_DATA_REPLY, peer_req);
} else {
if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Sending NegDReply. sector=%llus.\n",
(unsigned long long)peer_req->i.sector);
- err = drbd_send_ack(first_peer_device(device), P_NEG_DREPLY, peer_req);
+ err = drbd_send_ack(peer_device, P_NEG_DREPLY, peer_req);
}
dec_unacked(device);
@@ -1031,7 +1034,8 @@ int w_e_end_data_req(struct drbd_work *w, int cancel)
int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
{
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
int err;
if (unlikely(cancel)) {
@@ -1046,11 +1050,11 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
}
if (device->state.conn == C_AHEAD) {
- err = drbd_send_ack(first_peer_device(device), P_RS_CANCEL, peer_req);
+ err = drbd_send_ack(peer_device, P_RS_CANCEL, peer_req);
} else if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
if (likely(device->state.pdsk >= D_INCONSISTENT)) {
inc_rs_pending(device);
- err = drbd_send_block(first_peer_device(device), P_RS_DATA_REPLY, peer_req);
+ err = drbd_send_block(peer_device, P_RS_DATA_REPLY, peer_req);
} else {
if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Not sending RSDataReply, "
@@ -1062,7 +1066,7 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
drbd_err(device, "Sending NegRSDReply. sector %llus.\n",
(unsigned long long)peer_req->i.sector);
- err = drbd_send_ack(first_peer_device(device), P_NEG_RS_DREPLY, peer_req);
+ err = drbd_send_ack(peer_device, P_NEG_RS_DREPLY, peer_req);
/* update resync data with failure */
drbd_rs_failed_io(device, peer_req->i.sector, peer_req->i.size);
@@ -1080,7 +1084,8 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
{
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
struct digest_info *di;
int digest_size;
void *digest = NULL;
@@ -1103,13 +1108,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 (first_peer_device(device)->connection->csums_tfm) {
- digest_size = crypto_hash_digestsize(first_peer_device(device)->connection->csums_tfm);
+ if (peer_device->connection->csums_tfm) {
+ digest_size = crypto_hash_digestsize(peer_device->connection->csums_tfm);
D_ASSERT(device, digest_size == di->digest_size);
digest = kmalloc(digest_size, GFP_NOIO);
}
if (digest) {
- drbd_csum_ee(first_peer_device(device)->connection->csums_tfm, peer_req, digest);
+ drbd_csum_ee(peer_device->connection->csums_tfm, peer_req, digest);
eq = !memcmp(digest, di->digest, digest_size);
kfree(digest);
}
@@ -1118,16 +1123,16 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
drbd_set_in_sync(device, peer_req->i.sector, peer_req->i.size);
/* rs_same_csums unit is BM_BLOCK_SIZE */
device->rs_same_csum += peer_req->i.size >> BM_BLOCK_SHIFT;
- err = drbd_send_ack(first_peer_device(device), P_RS_IS_IN_SYNC, peer_req);
+ err = drbd_send_ack(peer_device, P_RS_IS_IN_SYNC, peer_req);
} else {
inc_rs_pending(device);
peer_req->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */
peer_req->flags &= ~EE_HAS_DIGEST; /* This peer request no longer has a digest pointer */
kfree(di);
- err = drbd_send_block(first_peer_device(device), P_RS_DATA_REPLY, peer_req);
+ err = drbd_send_block(peer_device, P_RS_DATA_REPLY, peer_req);
}
} else {
- err = drbd_send_ack(first_peer_device(device), P_NEG_RS_DREPLY, peer_req);
+ err = drbd_send_ack(peer_device, P_NEG_RS_DREPLY, peer_req);
if (__ratelimit(&drbd_ratelimit_state))
drbd_err(device, "Sending NegDReply. I guess it gets messy.\n");
}
@@ -1143,7 +1148,8 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
int w_e_end_ov_req(struct drbd_work *w, int cancel)
{
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
sector_t sector = peer_req->i.sector;
unsigned int size = peer_req->i.size;
int digest_size;
@@ -1153,7 +1159,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel)
if (unlikely(cancel))
goto out;
- digest_size = crypto_hash_digestsize(first_peer_device(device)->connection->verify_tfm);
+ digest_size = crypto_hash_digestsize(peer_device->connection->verify_tfm);
digest = kmalloc(digest_size, GFP_NOIO);
if (!digest) {
err = 1; /* terminate the connection in case the allocation failed */
@@ -1161,7 +1167,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel)
}
if (likely(!(peer_req->flags & EE_WAS_ERROR)))
- drbd_csum_ee(first_peer_device(device)->connection->verify_tfm, peer_req, digest);
+ drbd_csum_ee(peer_device->connection->verify_tfm, peer_req, digest);
else
memset(digest, 0, digest_size);
@@ -1173,7 +1179,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel)
drbd_free_peer_req(device, peer_req);
peer_req = NULL;
inc_rs_pending(device);
- err = drbd_send_drequest_csum(first_peer_device(device), sector, size, digest, digest_size, P_OV_REPLY);
+ err = drbd_send_drequest_csum(peer_device, sector, size, digest, digest_size, P_OV_REPLY);
if (err)
dec_rs_pending(device);
kfree(digest);
@@ -1199,7 +1205,8 @@ void drbd_ov_out_of_sync_found(struct drbd_device *device, sector_t sector, int
int w_e_end_ov_reply(struct drbd_work *w, int cancel)
{
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
- struct drbd_device *device = peer_req->peer_device->device;
+ struct drbd_peer_device *peer_device = peer_req->peer_device;
+ struct drbd_device *device = peer_device->device;
struct digest_info *di;
void *digest;
sector_t sector = peer_req->i.sector;
@@ -1224,10 +1231,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(first_peer_device(device)->connection->verify_tfm);
+ digest_size = crypto_hash_digestsize(peer_device->connection->verify_tfm);
digest = kmalloc(digest_size, GFP_NOIO);
if (digest) {
- drbd_csum_ee(first_peer_device(device)->connection->verify_tfm, peer_req, digest);
+ drbd_csum_ee(peer_device->connection->verify_tfm, peer_req, digest);
D_ASSERT(device, digest_size == di->digest_size);
eq = !memcmp(digest, di->digest, digest_size);
@@ -1246,7 +1253,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel)
else
ov_out_of_sync_print(device);
- err = drbd_send_ack_ex(first_peer_device(device), P_OV_RESULT, sector, size,
+ err = drbd_send_ack_ex(peer_device, P_OV_RESULT, sector, size,
eq ? ID_IN_SYNC : ID_OUT_OF_SYNC);
dec_unacked(device);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH 27/27] drbd: Add drbd_thread->resource and make drbd_thread->connection optional
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
` (25 preceding siblings ...)
2013-12-23 21:50 ` [PATCH 26/27] drbd: Use the right peer device Philipp Reisner
@ 2013-12-23 21:50 ` Philipp Reisner
26 siblings, 0 replies; 28+ messages in thread
From: Philipp Reisner @ 2013-12-23 21:50 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
In the drbd_thread "infrastructure" functions, only use the resource instead of
the connection. Make the connection field of drbd_thread optional. This will
allow to introduce threads which are not associated with a connection.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
drivers/block/drbd/drbd_int.h | 1 +
drivers/block/drbd/drbd_main.c | 49 ++++++++++++++++++++++++----------------
2 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 2e262fd..bc83b17 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -262,6 +262,7 @@ struct drbd_thread {
struct completion stop;
enum drbd_thread_state t_state;
int (*function) (struct drbd_thread *);
+ struct drbd_resource *resource;
struct drbd_connection *connection;
int reset_cpu_mask;
const char *name;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e11f606..3b66cbe3 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -322,13 +322,13 @@ void tl_abort_disk_io(struct drbd_device *device)
static int drbd_thread_setup(void *arg)
{
struct drbd_thread *thi = (struct drbd_thread *) arg;
- struct drbd_connection *connection = thi->connection;
+ struct drbd_resource *resource = thi->resource;
unsigned long flags;
int retval;
snprintf(current->comm, sizeof(current->comm), "drbd_%c_%s",
thi->name[0],
- thi->connection->resource->name);
+ resource->name);
restart:
retval = thi->function(thi);
@@ -346,7 +346,7 @@ restart:
*/
if (thi->t_state == RESTARTING) {
- drbd_info(connection, "Restarting %s thread\n", thi->name);
+ drbd_info(resource, "Restarting %s thread\n", thi->name);
thi->t_state = RUNNING;
spin_unlock_irqrestore(&thi->t_lock, flags);
goto restart;
@@ -358,29 +358,32 @@ restart:
complete_all(&thi->stop);
spin_unlock_irqrestore(&thi->t_lock, flags);
- drbd_info(connection, "Terminating %s\n", current->comm);
+ drbd_info(resource, "Terminating %s\n", current->comm);
/* Release mod reference taken when thread was started */
- kref_put(&connection->kref, drbd_destroy_connection);
+ if (thi->connection)
+ kref_put(&thi->connection->kref, drbd_destroy_connection);
+ kref_put(&resource->kref, drbd_destroy_resource);
module_put(THIS_MODULE);
return retval;
}
-static void drbd_thread_init(struct drbd_connection *connection, struct drbd_thread *thi,
+static void drbd_thread_init(struct drbd_resource *resource, struct drbd_thread *thi,
int (*func) (struct drbd_thread *), const char *name)
{
spin_lock_init(&thi->t_lock);
thi->task = NULL;
thi->t_state = NONE;
thi->function = func;
- thi->connection = connection;
+ thi->resource = resource;
+ thi->connection = NULL;
thi->name = name;
}
int drbd_thread_start(struct drbd_thread *thi)
{
- struct drbd_connection *connection = thi->connection;
+ struct drbd_resource *resource = thi->resource;
struct task_struct *nt;
unsigned long flags;
@@ -390,17 +393,19 @@ int drbd_thread_start(struct drbd_thread *thi)
switch (thi->t_state) {
case NONE:
- drbd_info(connection, "Starting %s thread (from %s [%d])\n",
+ drbd_info(resource, "Starting %s thread (from %s [%d])\n",
thi->name, current->comm, current->pid);
/* Get ref on module for thread - this is released when thread exits */
if (!try_module_get(THIS_MODULE)) {
- drbd_err(connection, "Failed to get module reference in drbd_thread_start\n");
+ drbd_err(resource, "Failed to get module reference in drbd_thread_start\n");
spin_unlock_irqrestore(&thi->t_lock, flags);
return false;
}
- kref_get(&thi->connection->kref);
+ kref_get(&resource->kref);
+ if (thi->connection)
+ kref_get(&thi->connection->kref);
init_completion(&thi->stop);
thi->reset_cpu_mask = 1;
@@ -409,12 +414,14 @@ int drbd_thread_start(struct drbd_thread *thi)
flush_signals(current); /* otherw. may get -ERESTARTNOINTR */
nt = kthread_create(drbd_thread_setup, (void *) thi,
- "drbd_%c_%s", thi->name[0], thi->connection->resource->name);
+ "drbd_%c_%s", thi->name[0], thi->resource->name);
if (IS_ERR(nt)) {
- drbd_err(connection, "Couldn't start thread\n");
+ drbd_err(resource, "Couldn't start thread\n");
- kref_put(&connection->kref, drbd_destroy_connection);
+ if (thi->connection)
+ kref_put(&thi->connection->kref, drbd_destroy_connection);
+ kref_put(&resource->kref, drbd_destroy_resource);
module_put(THIS_MODULE);
return false;
}
@@ -426,7 +433,7 @@ int drbd_thread_start(struct drbd_thread *thi)
break;
case EXITING:
thi->t_state = RESTARTING;
- drbd_info(connection, "Restarting %s thread (from %s [%d])\n",
+ drbd_info(resource, "Restarting %s thread (from %s [%d])\n",
thi->name, current->comm, current->pid);
/* fall through */
case RUNNING:
@@ -536,12 +543,13 @@ static void drbd_calc_cpu_mask(cpumask_var_t *cpu_mask)
*/
void drbd_thread_current_set_cpu(struct drbd_thread *thi)
{
+ struct drbd_resource *resource = thi->resource;
struct task_struct *p = current;
if (!thi->reset_cpu_mask)
return;
thi->reset_cpu_mask = 0;
- set_cpus_allowed_ptr(p, thi->connection->resource->cpu_mask);
+ set_cpus_allowed_ptr(p, resource->cpu_mask);
}
#else
#define drbd_calc_cpu_mask(A) ({})
@@ -2616,9 +2624,12 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
mutex_init(&connection->data.mutex);
mutex_init(&connection->meta.mutex);
- drbd_thread_init(connection, &connection->receiver, drbd_receiver, "receiver");
- drbd_thread_init(connection, &connection->worker, drbd_worker, "worker");
- drbd_thread_init(connection, &connection->asender, drbd_asender, "asender");
+ drbd_thread_init(resource, &connection->receiver, drbd_receiver, "receiver");
+ connection->receiver.connection = connection;
+ drbd_thread_init(resource, &connection->worker, drbd_worker, "worker");
+ connection->worker.connection = connection;
+ drbd_thread_init(resource, &connection->asender, drbd_asender, "asender");
+ connection->asender.connection = connection;
kref_init(&connection->kref);
--
1.7.9.5
^ permalink raw reply [flat|nested] 28+ messages in thread