* [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd
@ 2011-10-05 9:37 Philipp Reisner
2011-10-05 9:37 ` [PATCH 01/16] drbd: Consider all crypto options in connect and in net-options Philipp Reisner
` (15 more replies)
0 siblings, 16 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
This the first request for review of drbd-8.4. The complete set has
459 patches. This is the fourteenth installment containing 16 patches.
The whole set is available here:
git://git.drbd.org/linux-2.6-drbd.git for-jens
and is jens_for-3.2_drivers...for-jens
and this part is 6d5ade5^...68b38372
This patch series contains:
* Actually allow changing of the 'integrity-alg' setting while a
connection is established.
* Cleanups
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 01/16] drbd: Consider all crypto options in connect and in net-options
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 02/16] drbd: on reconfiguration requests, mind the SET_DEFAULTS flag Philipp Reisner
` (14 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
So for this was simply not considered after the options have been
re-arranged.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 230 ++++++++++++++++++++++--------------------
1 files changed, 121 insertions(+), 109 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index caa32e2..b9e8456 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1758,6 +1758,88 @@ check_net_options(struct drbd_tconn *tconn, struct net_conf *new_conf)
return rv;
}
+struct crypto {
+ struct crypto_hash *verify_tfm;
+ struct crypto_hash *csums_tfm;
+ struct crypto_hash *cram_hmac_tfm;
+ struct crypto_hash *integrity_w_tfm;
+ struct crypto_hash *integrity_r_tfm;
+ void *int_dig_in;
+ void *int_dig_vv;
+};
+
+static int
+alloc_tfm(struct crypto_hash **tfm, char *tfm_name, int err_alg, int err_nd)
+{
+ if (!tfm_name[0])
+ return NO_ERROR;
+
+ *tfm = crypto_alloc_hash(tfm_name, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(*tfm)) {
+ *tfm = NULL;
+ return err_alg;
+ }
+
+ if (!drbd_crypto_is_hash(crypto_hash_tfm(*tfm)))
+ return err_nd;
+
+ return NO_ERROR;
+}
+
+static enum drbd_ret_code
+alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
+{
+ char hmac_name[CRYPTO_MAX_ALG_NAME];
+ enum drbd_ret_code rv;
+ int hash_size;
+
+ rv = alloc_tfm(&crypto->csums_tfm, new_conf->csums_alg,
+ ERR_CSUMS_ALG, ERR_CSUMS_ALG_ND);
+ if (rv != NO_ERROR)
+ return rv;
+ rv = alloc_tfm(&crypto->verify_tfm, new_conf->verify_alg,
+ ERR_VERIFY_ALG, ERR_VERIFY_ALG_ND);
+ if (rv != NO_ERROR)
+ return rv;
+ rv = alloc_tfm(&crypto->integrity_w_tfm, new_conf->integrity_alg,
+ ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
+ if (rv != NO_ERROR)
+ return rv;
+ rv = alloc_tfm(&crypto->integrity_r_tfm, new_conf->integrity_alg,
+ ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
+ if (rv != NO_ERROR)
+ return rv;
+ if (new_conf->cram_hmac_alg[0] != 0) {
+ snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
+ new_conf->cram_hmac_alg);
+
+ rv = alloc_tfm(&crypto->cram_hmac_tfm, hmac_name,
+ ERR_AUTH_ALG, ERR_AUTH_ALG_ND);
+ }
+ if (crypto->integrity_w_tfm) {
+ hash_size = crypto_hash_digestsize(crypto->integrity_w_tfm);
+ crypto->int_dig_in = kmalloc(hash_size, GFP_KERNEL);
+ if (!crypto->int_dig_in)
+ return ERR_NOMEM;
+ crypto->int_dig_vv = kmalloc(hash_size, GFP_KERNEL);
+ if (!crypto->int_dig_vv)
+ return ERR_NOMEM;
+ }
+
+ return rv;
+}
+
+static void free_crypto(struct crypto *crypto)
+{
+ kfree(crypto->int_dig_in);
+ kfree(crypto->int_dig_vv);
+ crypto_free_hash(crypto->cram_hmac_tfm);
+ crypto_free_hash(crypto->integrity_w_tfm);
+ crypto_free_hash(crypto->integrity_r_tfm);
+ crypto_free_hash(crypto->csums_tfm);
+ crypto_free_hash(crypto->verify_tfm);
+}
+
int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
{
enum drbd_ret_code retcode;
@@ -1766,9 +1848,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
int err;
int ovr; /* online verify running */
int rsr; /* re-sync running */
- struct crypto_hash *verify_tfm = NULL;
- struct crypto_hash *csums_tfm = NULL;
-
+ struct crypto crypto = { };
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONN);
if (!adm_ctx.reply_skb)
@@ -1824,61 +1904,49 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
/* re-sync running */
rsr = conn_resync_running(tconn);
- if (rsr && old_conf && strcmp(new_conf->csums_alg, old_conf->csums_alg)) {
+ if (rsr && strcmp(new_conf->csums_alg, old_conf->csums_alg)) {
retcode = ERR_CSUMS_RESYNC_RUNNING;
goto fail;
}
- if (!rsr && new_conf->csums_alg[0]) {
- csums_tfm = crypto_alloc_hash(new_conf->csums_alg, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(csums_tfm)) {
- csums_tfm = NULL;
- retcode = ERR_CSUMS_ALG;
- goto fail;
- }
-
- if (!drbd_crypto_is_hash(crypto_hash_tfm(csums_tfm))) {
- retcode = ERR_CSUMS_ALG_ND;
- goto fail;
- }
- }
-
/* online verify running */
ovr = conn_ov_running(tconn);
- if (ovr) {
- if (strcmp(new_conf->verify_alg, old_conf->verify_alg)) {
- retcode = ERR_VERIFY_RUNNING;
- goto fail;
- }
+ if (ovr && strcmp(new_conf->verify_alg, old_conf->verify_alg)) {
+ retcode = ERR_VERIFY_RUNNING;
+ goto fail;
}
- if (!ovr && new_conf->verify_alg[0]) {
- verify_tfm = crypto_alloc_hash(new_conf->verify_alg, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(verify_tfm)) {
- verify_tfm = NULL;
- retcode = ERR_VERIFY_ALG;
- goto fail;
- }
-
- if (!drbd_crypto_is_hash(crypto_hash_tfm(verify_tfm))) {
- retcode = ERR_VERIFY_ALG_ND;
- goto fail;
- }
- }
+ retcode = alloc_crypto(&crypto, new_conf);
+ if (retcode != NO_ERROR)
+ goto fail;
rcu_assign_pointer(tconn->net_conf, new_conf);
if (!rsr) {
crypto_free_hash(tconn->csums_tfm);
- tconn->csums_tfm = csums_tfm;
- csums_tfm = NULL;
+ tconn->csums_tfm = crypto.csums_tfm;
+ crypto.csums_tfm = NULL;
}
if (!ovr) {
crypto_free_hash(tconn->verify_tfm);
- tconn->verify_tfm = verify_tfm;
- verify_tfm = NULL;
+ tconn->verify_tfm = crypto.verify_tfm;
+ crypto.verify_tfm = NULL;
}
+ /* FIXME can not assign these so bluntly while we have ongoing IO */
+ kfree(tconn->int_dig_in);
+ tconn->int_dig_in = crypto.int_dig_in;
+ kfree(tconn->int_dig_vv);
+ tconn->int_dig_vv = crypto.int_dig_vv;
+ crypto_free_hash(tconn->integrity_w_tfm);
+ tconn->integrity_w_tfm = crypto.integrity_w_tfm;
+ crypto_free_hash(tconn->integrity_r_tfm);
+ tconn->integrity_r_tfm = crypto.integrity_r_tfm;
+
+ /* FIXME Changing cram_hmac while the connection is established is useless */
+ crypto_free_hash(tconn->cram_hmac_tfm);
+ tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
+
mutex_unlock(&tconn->net_conf_update);
synchronize_rcu();
kfree(old_conf);
@@ -1890,8 +1958,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
fail:
mutex_unlock(&tconn->net_conf_update);
- crypto_free_hash(csums_tfm);
- crypto_free_hash(verify_tfm);
+ free_crypto(&crypto);
kfree(new_conf);
done:
conn_reconfig_done(tconn);
@@ -1902,14 +1969,9 @@ 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)
{
- char hmac_name[CRYPTO_MAX_ALG_NAME];
struct drbd_conf *mdev;
struct net_conf *old_conf, *new_conf = NULL;
- struct crypto_hash *tfm = NULL;
- struct crypto_hash *integrity_w_tfm = NULL;
- struct crypto_hash *integrity_r_tfm = NULL;
- void *int_dig_in = NULL;
- void *int_dig_vv = NULL;
+ struct crypto crypto = { };
struct drbd_tconn *oconn;
struct drbd_tconn *tconn;
struct sockaddr *new_my_addr, *new_peer_addr, *taken_addr;
@@ -2014,60 +2076,12 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- if (new_conf->cram_hmac_alg[0] != 0) {
- snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
- new_conf->cram_hmac_alg);
- tfm = crypto_alloc_hash(hmac_name, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm)) {
- tfm = NULL;
- retcode = ERR_AUTH_ALG;
- goto fail;
- }
-
- if (!drbd_crypto_is_hash(crypto_hash_tfm(tfm))) {
- retcode = ERR_AUTH_ALG_ND;
- goto fail;
- }
- }
-
- if (new_conf->integrity_alg[0]) {
- integrity_w_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(integrity_w_tfm)) {
- integrity_w_tfm = NULL;
- retcode=ERR_INTEGRITY_ALG;
- goto fail;
- }
-
- if (!drbd_crypto_is_hash(crypto_hash_tfm(integrity_w_tfm))) {
- retcode=ERR_INTEGRITY_ALG_ND;
- goto fail;
- }
-
- integrity_r_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(integrity_r_tfm)) {
- integrity_r_tfm = NULL;
- retcode=ERR_INTEGRITY_ALG;
- goto fail;
- }
- }
+ retcode = alloc_crypto(&crypto, new_conf);
+ if (retcode != NO_ERROR)
+ goto fail;
((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
- /* allocation not in the IO path, cqueue thread context */
- if (integrity_w_tfm) {
- i = crypto_hash_digestsize(integrity_w_tfm);
- int_dig_in = kmalloc(i, GFP_KERNEL);
- if (!int_dig_in) {
- retcode = ERR_NOMEM;
- goto fail;
- }
- int_dig_vv = kmalloc(i, GFP_KERNEL);
- if (!int_dig_vv) {
- retcode = ERR_NOMEM;
- goto fail;
- }
- }
-
conn_flush_workqueue(tconn);
mutex_lock(&tconn->net_conf_update);
@@ -2080,11 +2094,13 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
rcu_assign_pointer(tconn->net_conf, new_conf);
conn_free_crypto(tconn);
- tconn->cram_hmac_tfm = tfm;
- tconn->integrity_w_tfm = integrity_w_tfm;
- tconn->integrity_r_tfm = integrity_r_tfm;
- tconn->int_dig_in = int_dig_in;
- tconn->int_dig_vv = int_dig_vv;
+ tconn->int_dig_in = crypto.int_dig_in;
+ tconn->int_dig_vv = crypto.int_dig_vv;
+ tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
+ tconn->integrity_w_tfm = crypto.integrity_w_tfm;
+ tconn->integrity_r_tfm = crypto.integrity_r_tfm;
+ tconn->csums_tfm = crypto.csums_tfm;
+ tconn->verify_tfm = crypto.verify_tfm;
mutex_unlock(&tconn->net_conf_update);
@@ -2102,11 +2118,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
return 0;
fail:
- kfree(int_dig_in);
- kfree(int_dig_vv);
- crypto_free_hash(tfm);
- crypto_free_hash(integrity_w_tfm);
- crypto_free_hash(integrity_r_tfm);
+ free_crypto(&crypto);
kfree(new_conf);
conn_reconfig_done(tconn);
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 02/16] drbd: on reconfiguration requests, mind the SET_DEFAULTS flag
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
2011-10-05 9:37 ` [PATCH 01/16] drbd: Consider all crypto options in connect and in net-options Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 03/16] drbd: rename variable ndc to new_disk_conf Philipp Reisner
` (13 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
The DRBD_GENL_F_SET_DEFAULTS flag was ignored
for drbd_adm_disk_opts() and drbd_adm_net_opts().
Factor out drbd_set_*_defaults() helper functions,
and call them appropriately.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 1 +
drivers/block/drbd/drbd_main.c | 5 +-
drivers/block/drbd/drbd_nl.c | 150 ++++++++++++++++++++++++----------------
3 files changed, 91 insertions(+), 65 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 28e7ecc..e90bc9f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1389,6 +1389,7 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t);
/* drbd_nl.c */
+extern void drbd_set_res_opts_default(struct res_opts *r);
extern int drbd_msg_put_info(const char *info);
extern void drbd_suspend_io(struct drbd_conf *mdev);
extern void drbd_resume_io(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 114ae3a..c5134c8 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2460,10 +2460,7 @@ struct drbd_tconn *conn_create(const char *name)
drbd_thread_init(tconn, &tconn->worker, drbd_worker, "worker");
drbd_thread_init(tconn, &tconn->asender, drbd_asender, "asender");
- tconn->res_opts = (struct res_opts) {
- {}, 0, /* cpu_mask */
- DRBD_ON_NO_DATA_DEF, /* on_no_data */
- };
+ drbd_set_res_opts_default(&tconn->res_opts);
down_write(&drbd_cfg_rwsem);
kref_init(&tconn->kref);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index b9e8456..7bfcb96 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1099,6 +1099,84 @@ static void drbd_suspend_al(struct drbd_conf *mdev)
dev_info(DEV, "Suspended AL updates\n");
}
+
+static bool should_set_defaults(struct genl_info *info)
+{
+ unsigned flags = ((struct drbd_genlmsghdr*)info->userhdr)->flags;
+ return 0 != (flags & DRBD_GENL_F_SET_DEFAULTS);
+}
+
+/* Maybe we should we generate these functions
+ * from the drbd_genl.h magic as well?
+ * That way we would not "accidentally forget" to add defaults here. */
+
+#define RESET_ARRAY_FIELD(field) do { \
+ memset(field, 0, sizeof(field)); \
+ field ## _len = 0; \
+} while (0)
+void drbd_set_res_opts_default(struct res_opts *r)
+{
+ RESET_ARRAY_FIELD(r->cpu_mask);
+ r->on_no_data = DRBD_ON_NO_DATA_DEF;
+}
+
+static void drbd_set_net_conf_defaults(struct net_conf *nc)
+{
+ /* Do NOT (re)set those fields marked as GENLA_F_INVARIANT
+ * in drbd_genl.h, they can only be change with disconnect/reconnect */
+ RESET_ARRAY_FIELD(nc->shared_secret);
+
+ RESET_ARRAY_FIELD(nc->cram_hmac_alg);
+ RESET_ARRAY_FIELD(nc->integrity_alg);
+ RESET_ARRAY_FIELD(nc->verify_alg);
+ RESET_ARRAY_FIELD(nc->csums_alg);
+#undef RESET_ARRAY_FIELD
+
+ nc->wire_protocol = DRBD_PROTOCOL_DEF;
+ nc->try_connect_int = DRBD_CONNECT_INT_DEF;
+ nc->timeout = DRBD_TIMEOUT_DEF;
+ nc->ping_int = DRBD_PING_INT_DEF;
+ nc->ping_timeo = DRBD_PING_TIMEO_DEF;
+ nc->sndbuf_size = DRBD_SNDBUF_SIZE_DEF;
+ nc->rcvbuf_size = DRBD_RCVBUF_SIZE_DEF;
+ nc->ko_count = DRBD_KO_COUNT_DEF;
+ nc->max_buffers = DRBD_MAX_BUFFERS_DEF;
+ nc->max_epoch_size = DRBD_MAX_EPOCH_SIZE_DEF;
+ nc->unplug_watermark = DRBD_UNPLUG_WATERMARK_DEF;
+ nc->after_sb_0p = DRBD_AFTER_SB_0P_DEF;
+ nc->after_sb_1p = DRBD_AFTER_SB_1P_DEF;
+ nc->after_sb_2p = DRBD_AFTER_SB_2P_DEF;
+ nc->rr_conflict = DRBD_RR_CONFLICT_DEF;
+ nc->on_congestion = DRBD_ON_CONGESTION_DEF;
+ nc->cong_fill = DRBD_CONG_FILL_DEF;
+ nc->cong_extents = DRBD_CONG_EXTENTS_DEF;
+ nc->two_primaries = 0;
+ nc->no_cork = 0;
+ nc->always_asbp = 0;
+ nc->use_rle = 0;
+}
+
+static void drbd_set_disk_conf_defaults(struct disk_conf *dc)
+{
+ /* Do NOT (re)set those fields marked as GENLA_F_INVARIANT
+ * in drbd_genl.h, they can only be change with detach/reattach */
+ dc->on_io_error = DRBD_ON_IO_ERROR_DEF;
+ dc->fencing = DRBD_FENCING_DEF;
+ dc->resync_rate = DRBD_RATE_DEF;
+ dc->resync_after = DRBD_AFTER_DEF;
+ dc->al_extents = DRBD_AL_EXTENTS_DEF;
+ dc->c_plan_ahead = DRBD_C_PLAN_AHEAD_DEF;
+ dc->c_delay_target = DRBD_C_DELAY_TARGET_DEF;
+ dc->c_fill_target = DRBD_C_FILL_TARGET_DEF;
+ dc->c_max_rate = DRBD_C_MAX_RATE_DEF;
+ dc->c_min_rate = DRBD_C_MIN_RATE_DEF;
+ dc->no_disk_barrier = 0;
+ dc->no_disk_flush = 0;
+ dc->no_disk_drain = 0;
+ dc->no_md_flush = 0;
+}
+
+
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
{
enum drbd_ret_code retcode;
@@ -1149,6 +1227,9 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
}
memcpy(ndc, &mdev->ldev->dc, sizeof(*ndc));
+ if (should_set_defaults(info))
+ drbd_set_disk_conf_defaults(ndc);
+
err = disk_conf_from_attrs(ndc, info);
if (err) {
retcode = ERR_MANDATORY_TAG;
@@ -1264,27 +1345,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- nbc->dc = (struct disk_conf) {
- {}, 0, /* backing_dev */
- {}, 0, /* meta_dev */
- 0, /* meta_dev_idx */
- DRBD_DISK_SIZE_SECT_DEF, /* disk_size */
- DRBD_MAX_BIO_BVECS_DEF, /* max_bio_bvecs */
- DRBD_ON_IO_ERROR_DEF, /* on_io_error */
- DRBD_FENCING_DEF, /* fencing */
- DRBD_RATE_DEF, /* resync_rate */
- DRBD_AFTER_DEF, /* resync_after */
- DRBD_AL_EXTENTS_DEF, /* al_extents */
- DRBD_C_PLAN_AHEAD_DEF, /* c_plan_ahead */
- DRBD_C_DELAY_TARGET_DEF, /* c_delay_target */
- DRBD_C_FILL_TARGET_DEF, /* c_fill_target */
- DRBD_C_MAX_RATE_DEF, /* c_max_rate */
- DRBD_C_MIN_RATE_DEF, /* c_min_rate */
- 0, /* no_disk_barrier */
- 0, /* no_disk_flush */
- 0, /* no_disk_drain */
- 0, /* no_md_flush */
- };
+ drbd_set_disk_conf_defaults(&nbc->dc);
err = disk_conf_from_attrs(&nbc->dc, info);
if (err) {
@@ -1890,6 +1951,8 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
}
*new_conf = *old_conf;
+ if (should_set_defaults(info))
+ drbd_set_net_conf_defaults(new_conf);
err = net_conf_from_attrs(new_conf, info);
if (err) {
@@ -1994,45 +2057,13 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
}
/* allocation not in the IO path, cqueue thread context */
- new_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL);
+ new_conf = kzalloc(sizeof(*new_conf), GFP_KERNEL);
if (!new_conf) {
retcode = ERR_NOMEM;
goto fail;
}
- *new_conf = (struct net_conf) {
- {}, 0, /* my_addr */
- {}, 0, /* peer_addr */
- {}, 0, /* shared_secret */
- {}, 0, /* cram_hmac_alg */
- {}, 0, /* integrity_alg */
- {}, 0, /* verify_alg */
- {}, 0, /* csums_alg */
- DRBD_PROTOCOL_DEF, /* wire_protocol */
- DRBD_CONNECT_INT_DEF, /* try_connect_int */
- DRBD_TIMEOUT_DEF, /* timeout */
- DRBD_PING_INT_DEF, /* ping_int */
- DRBD_PING_TIMEO_DEF, /* ping_timeo */
- DRBD_SNDBUF_SIZE_DEF, /* sndbuf_size */
- DRBD_RCVBUF_SIZE_DEF, /* rcvbuf_size */
- DRBD_KO_COUNT_DEF, /* ko_count */
- DRBD_MAX_BUFFERS_DEF, /* max_buffers */
- DRBD_MAX_EPOCH_SIZE_DEF, /* max_epoch_size */
- DRBD_UNPLUG_WATERMARK_DEF, /* unplug_watermark */
- DRBD_AFTER_SB_0P_DEF, /* after_sb_0p */
- DRBD_AFTER_SB_1P_DEF, /* after_sb_1p */
- DRBD_AFTER_SB_2P_DEF, /* after_sb_2p */
- DRBD_RR_CONFLICT_DEF, /* rr_conflict */
- DRBD_ON_CONGESTION_DEF, /* on_congestion */
- DRBD_CONG_FILL_DEF, /* cong_fill */
- DRBD_CONG_EXTENTS_DEF, /* cong_extents */
- 0, /* two_primaries */
- 0, /* want_lose */
- 0, /* no_cork */
- 0, /* always_asbp */
- 0, /* dry_run */
- 0, /* use_rle */
- };
+ drbd_set_net_conf_defaults(new_conf);
err = net_conf_from_attrs(new_conf, info);
if (err) {
@@ -2320,12 +2351,9 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- if (((struct drbd_genlmsghdr*)info->userhdr)->flags
- & DRBD_GENL_F_SET_DEFAULTS) {
- memset(&sc, 0, sizeof(struct res_opts));
- sc.on_no_data = DRBD_ON_NO_DATA_DEF;
- } else
- sc = tconn->res_opts;
+ sc = tconn->res_opts;
+ if (should_set_defaults(info))
+ drbd_set_res_opts_default(&sc);
err = res_opts_from_attrs(&sc, info);
if (err) {
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 03/16] drbd: rename variable ndc to new_disk_conf
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
2011-10-05 9:37 ` [PATCH 01/16] drbd: Consider all crypto options in connect and in net-options Philipp Reisner
2011-10-05 9:37 ` [PATCH 02/16] drbd: on reconfiguration requests, mind the SET_DEFAULTS flag Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 04/16] drbd: rename variable sc to res_opts Philipp Reisner
` (12 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 34 +++++++++++++++++-----------------
1 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 7bfcb96..51dc869 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1181,7 +1181,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
{
enum drbd_ret_code retcode;
struct drbd_conf *mdev;
- struct disk_conf *ndc; /* new disk conf */
+ struct disk_conf *new_disk_conf;
int err, fifo_size;
int *rs_plan_s = NULL;
@@ -1220,39 +1220,39 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
* some half-updated struct when we
* assign it later. */
- ndc = kmalloc(sizeof(*ndc), GFP_KERNEL);
- if (!ndc) {
+ new_disk_conf = kmalloc(sizeof(*new_disk_conf), GFP_KERNEL);
+ if (!new_disk_conf) {
retcode = ERR_NOMEM;
goto fail;
}
- memcpy(ndc, &mdev->ldev->dc, sizeof(*ndc));
+ memcpy(new_disk_conf, &mdev->ldev->dc, sizeof(*new_disk_conf));
if (should_set_defaults(info))
- drbd_set_disk_conf_defaults(ndc);
+ drbd_set_disk_conf_defaults(new_disk_conf);
- err = disk_conf_from_attrs(ndc, info);
+ err = disk_conf_from_attrs(new_disk_conf, info);
if (err) {
retcode = ERR_MANDATORY_TAG;
drbd_msg_put_info(from_attrs_err_to_txt(err));
}
- if (!expect(ndc->resync_rate >= 1))
- ndc->resync_rate = 1;
+ if (!expect(new_disk_conf->resync_rate >= 1))
+ new_disk_conf->resync_rate = 1;
/* clip to allowed range */
- if (!expect(ndc->al_extents >= DRBD_AL_EXTENTS_MIN))
- ndc->al_extents = DRBD_AL_EXTENTS_MIN;
- if (!expect(ndc->al_extents <= DRBD_AL_EXTENTS_MAX))
- ndc->al_extents = DRBD_AL_EXTENTS_MAX;
+ if (!expect(new_disk_conf->al_extents >= DRBD_AL_EXTENTS_MIN))
+ new_disk_conf->al_extents = DRBD_AL_EXTENTS_MIN;
+ if (!expect(new_disk_conf->al_extents <= DRBD_AL_EXTENTS_MAX))
+ new_disk_conf->al_extents = DRBD_AL_EXTENTS_MAX;
/* most sanity checks done, try to assign the new sync-after
* dependency. need to hold the global lock in there,
* to avoid a race in the dependency loop check. */
- retcode = drbd_alter_sa(mdev, ndc->resync_after);
+ retcode = drbd_alter_sa(mdev, new_disk_conf->resync_after);
if (retcode != NO_ERROR)
goto fail;
- fifo_size = (ndc->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
+ fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
if (fifo_size != mdev->rs_plan_s.size && fifo_size > 0) {
rs_plan_s = kzalloc(sizeof(int) * fifo_size, GFP_KERNEL);
if (!rs_plan_s) {
@@ -1272,7 +1272,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
drbd_al_shrink(mdev);
- err = drbd_check_al_size(mdev, ndc);
+ err = drbd_check_al_size(mdev, new_disk_conf);
lc_unlock(mdev->act_log);
wake_up(&mdev->al_wait);
@@ -1285,7 +1285,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
* To avoid someone looking at a half-updated struct, we probably
* should have a rw-semaphor on net_conf and disk_conf.
*/
- mdev->ldev->dc = *ndc;
+ mdev->ldev->dc = *new_disk_conf;
drbd_md_sync(mdev);
@@ -1295,7 +1295,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
fail:
put_ldev(mdev);
- kfree(ndc);
+ kfree(new_disk_conf);
kfree(rs_plan_s);
out:
drbd_adm_finish(info, retcode);
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 04/16] drbd: rename variable sc to res_opts
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (2 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 03/16] drbd: rename variable ndc to new_disk_conf Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 05/16] drbd: fix copy/paste error in comment Philipp Reisner
` (11 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
sc was short for syncer conf, which does not exist anymore anyways.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 51dc869..addd175 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2335,7 +2335,7 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
cpumask_var_t new_cpu_mask;
struct drbd_tconn *tconn;
int *rs_plan_s = NULL;
- struct res_opts sc;
+ struct res_opts res_opts;
int err;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONN);
@@ -2351,11 +2351,11 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- sc = tconn->res_opts;
+ res_opts = tconn->res_opts;
if (should_set_defaults(info))
- drbd_set_res_opts_default(&sc);
+ drbd_set_res_opts_default(&res_opts);
- err = res_opts_from_attrs(&sc, info);
+ err = res_opts_from_attrs(&res_opts, info);
if (err) {
retcode = ERR_MANDATORY_TAG;
drbd_msg_put_info(from_attrs_err_to_txt(err));
@@ -2363,8 +2363,8 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
}
/* silently ignore cpu mask on UP kernel */
- if (nr_cpu_ids > 1 && sc.cpu_mask[0] != 0) {
- err = __bitmap_parse(sc.cpu_mask, 32, 0,
+ if (nr_cpu_ids > 1 && res_opts.cpu_mask[0] != 0) {
+ err = __bitmap_parse(res_opts.cpu_mask, 32, 0,
cpumask_bits(new_cpu_mask), nr_cpu_ids);
if (err) {
conn_warn(tconn, "__bitmap_parse() failed with %d\n", err);
@@ -2374,7 +2374,7 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
}
- tconn->res_opts = sc;
+ tconn->res_opts = res_opts;
if (!cpumask_equal(tconn->cpu_mask, new_cpu_mask)) {
cpumask_copy(tconn->cpu_mask, new_cpu_mask);
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 05/16] drbd: fix copy/paste error in comment
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (3 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 04/16] drbd: rename variable sc to res_opts Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 06/16] drbd: Wrong use of RCU in receive_protocol() Philipp Reisner
` (10 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_actlog.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 50b851e..933404e 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -307,7 +307,7 @@ static unsigned int rs_extent_to_bm_page(unsigned int rs_enr)
return rs_enr >>
/* bit to page */
((PAGE_SHIFT + 3) -
- /* al extent number to bit */
+ /* resync extent number to bit */
(BM_EXT_SHIFT - BM_BLOCK_SHIFT));
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 06/16] drbd: Wrong use of RCU in receive_protocol()
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (4 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 05/16] drbd: fix copy/paste error in comment Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 07/16] drbd: Rename integrity_w_tfm -> integrity_tfm Philipp Reisner
` (9 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
It is not enough to grab net_conf->integrity_alg under rcu_read_lock()
and access it outside of it; the entire net_conf object may be gone by
then.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 32 +++++++++++++++++++-------------
1 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 6da7aeb..98f03b1 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2998,7 +2998,6 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
int p_want_lose, p_two_primaries, cf;
char p_integrity_alg[SHARED_SECRET_MAX] = "";
- unsigned char *my_alg;
struct net_conf *nc;
p_proto = be32_to_cpu(p->protocol);
@@ -3009,6 +3008,18 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
cf = be32_to_cpu(p->conn_flags);
p_want_lose = cf & CF_WANT_LOSE;
+ if (tconn->agreed_pro_version >= 87) {
+ int err;
+
+ if (pi->size > sizeof(p_integrity_alg))
+ return -EIO;
+ err = drbd_recv_all(tconn, p_integrity_alg, pi->size);
+ if (err)
+ return err;
+
+ p_integrity_alg[SHARED_SECRET_MAX-1] = 0;
+ }
+
clear_bit(CONN_DRY_RUN, &tconn->flags);
if (cf & CF_DRY_RUN)
@@ -3047,23 +3058,18 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
goto disconnect_rcu_unlock;
}
- my_alg = nc->integrity_alg;
- rcu_read_unlock();
-
if (tconn->agreed_pro_version >= 87) {
- int err;
-
- err = drbd_recv_all(tconn, p_integrity_alg, pi->size);
- if (err)
- return err;
-
- p_integrity_alg[SHARED_SECRET_MAX-1] = 0;
- if (strcmp(p_integrity_alg, my_alg)) {
+ if (strcmp(p_integrity_alg, nc->integrity_alg)) {
conn_err(tconn, "incompatible setting of the data-integrity-alg\n");
goto disconnect;
}
+ }
+
+ rcu_read_unlock();
+
+ if (tconn->agreed_pro_version >= 87) {
conn_info(tconn, "data-integrity-alg: %s\n",
- my_alg[0] ? my_alg : (unsigned char *)"<not-used>");
+ nc->integrity_alg[0] ? nc->integrity_alg : (unsigned char *)"<not-used>");
}
return 0;
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 07/16] drbd: Rename integrity_w_tfm -> integrity_tfm
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (5 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 06/16] drbd: Wrong use of RCU in receive_protocol() Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 08/16] drbd: Rename integrity_r_tfm -> peer_integrity_tfm Philipp Reisner
` (8 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 2 +-
drivers/block/drbd/drbd_main.c | 18 +++++++++---------
drivers/block/drbd/drbd_nl.c | 16 ++++++++--------
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e90bc9f..4787c790 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -849,7 +849,7 @@ struct drbd_tconn { /* is a resource from the config file */
struct list_head out_of_sequence_requests;
struct crypto_hash *cram_hmac_tfm;
- struct crypto_hash *integrity_w_tfm; /* to be used by the worker thread */
+ struct crypto_hash *integrity_tfm; /* checksums we compute */
struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */
struct crypto_hash *csums_tfm;
struct crypto_hash *verify_tfm;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c5134c8..30dd8a9 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1689,8 +1689,8 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
int dgs;
int err;
- dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
- crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
+ dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_tfm) ?
+ crypto_hash_digestsize(mdev->tconn->integrity_tfm) : 0;
sock = &mdev->tconn->data;
p = drbd_prepare_command(mdev, sock);
@@ -1711,7 +1711,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
}
p->dp_flags = cpu_to_be32(dp_flags);
if (dgs)
- drbd_csum_bio(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, p + 1);
+ drbd_csum_bio(mdev, mdev->tconn->integrity_tfm, req->master_bio, p + 1);
err = __send_command(mdev->tconn, mdev->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
if (!err) {
/* For protocol A, we have to memcpy the payload into
@@ -1735,7 +1735,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, 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(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, digest);
+ drbd_csum_bio(mdev, mdev->tconn->integrity_tfm, req->master_bio, digest);
if (memcmp(p + 1, digest, dgs)) {
dev_warn(DEV,
"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
@@ -1762,8 +1762,8 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
int err;
int dgs;
- dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
- crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
+ dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_tfm) ?
+ crypto_hash_digestsize(mdev->tconn->integrity_tfm) : 0;
sock = &mdev->tconn->data;
p = drbd_prepare_command(mdev, sock);
@@ -1773,7 +1773,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
p->block_id = peer_req->block_id;
p->seq_num = 0; /* unused */
if (dgs)
- drbd_csum_ee(mdev, mdev->tconn->integrity_w_tfm, peer_req, p + 1);
+ drbd_csum_ee(mdev, mdev->tconn->integrity_tfm, peer_req, p + 1);
err = __send_command(mdev->tconn, mdev->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
if (!err)
err = _drbd_send_zc_ee(mdev, peer_req);
@@ -2406,7 +2406,7 @@ void conn_free_crypto(struct drbd_tconn *tconn)
crypto_free_hash(tconn->csums_tfm);
crypto_free_hash(tconn->verify_tfm);
crypto_free_hash(tconn->cram_hmac_tfm);
- crypto_free_hash(tconn->integrity_w_tfm);
+ crypto_free_hash(tconn->integrity_tfm);
crypto_free_hash(tconn->integrity_r_tfm);
kfree(tconn->int_dig_in);
kfree(tconn->int_dig_vv);
@@ -2414,7 +2414,7 @@ void conn_free_crypto(struct drbd_tconn *tconn)
tconn->csums_tfm = NULL;
tconn->verify_tfm = NULL;
tconn->cram_hmac_tfm = NULL;
- tconn->integrity_w_tfm = NULL;
+ tconn->integrity_tfm = NULL;
tconn->integrity_r_tfm = NULL;
tconn->int_dig_in = NULL;
tconn->int_dig_vv = NULL;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index addd175..d24d96d 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1823,7 +1823,7 @@ struct crypto {
struct crypto_hash *verify_tfm;
struct crypto_hash *csums_tfm;
struct crypto_hash *cram_hmac_tfm;
- struct crypto_hash *integrity_w_tfm;
+ struct crypto_hash *integrity_tfm;
struct crypto_hash *integrity_r_tfm;
void *int_dig_in;
void *int_dig_vv;
@@ -1862,7 +1862,7 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
ERR_VERIFY_ALG, ERR_VERIFY_ALG_ND);
if (rv != NO_ERROR)
return rv;
- rv = alloc_tfm(&crypto->integrity_w_tfm, new_conf->integrity_alg,
+ rv = alloc_tfm(&crypto->integrity_tfm, new_conf->integrity_alg,
ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
if (rv != NO_ERROR)
return rv;
@@ -1877,8 +1877,8 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
rv = alloc_tfm(&crypto->cram_hmac_tfm, hmac_name,
ERR_AUTH_ALG, ERR_AUTH_ALG_ND);
}
- if (crypto->integrity_w_tfm) {
- hash_size = crypto_hash_digestsize(crypto->integrity_w_tfm);
+ if (crypto->integrity_tfm) {
+ hash_size = crypto_hash_digestsize(crypto->integrity_tfm);
crypto->int_dig_in = kmalloc(hash_size, GFP_KERNEL);
if (!crypto->int_dig_in)
return ERR_NOMEM;
@@ -1895,7 +1895,7 @@ static void free_crypto(struct crypto *crypto)
kfree(crypto->int_dig_in);
kfree(crypto->int_dig_vv);
crypto_free_hash(crypto->cram_hmac_tfm);
- crypto_free_hash(crypto->integrity_w_tfm);
+ crypto_free_hash(crypto->integrity_tfm);
crypto_free_hash(crypto->integrity_r_tfm);
crypto_free_hash(crypto->csums_tfm);
crypto_free_hash(crypto->verify_tfm);
@@ -2001,8 +2001,8 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
tconn->int_dig_in = crypto.int_dig_in;
kfree(tconn->int_dig_vv);
tconn->int_dig_vv = crypto.int_dig_vv;
- crypto_free_hash(tconn->integrity_w_tfm);
- tconn->integrity_w_tfm = crypto.integrity_w_tfm;
+ crypto_free_hash(tconn->integrity_tfm);
+ tconn->integrity_tfm = crypto.integrity_tfm;
crypto_free_hash(tconn->integrity_r_tfm);
tconn->integrity_r_tfm = crypto.integrity_r_tfm;
@@ -2128,7 +2128,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
tconn->int_dig_in = crypto.int_dig_in;
tconn->int_dig_vv = crypto.int_dig_vv;
tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
- tconn->integrity_w_tfm = crypto.integrity_w_tfm;
+ tconn->integrity_tfm = crypto.integrity_tfm;
tconn->integrity_r_tfm = crypto.integrity_r_tfm;
tconn->csums_tfm = crypto.csums_tfm;
tconn->verify_tfm = crypto.verify_tfm;
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 08/16] drbd: Rename integrity_r_tfm -> peer_integrity_tfm
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (6 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 07/16] drbd: Rename integrity_w_tfm -> integrity_tfm Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 09/16] drbd: Remove obsolete drbd_crypto_is_hash() Philipp Reisner
` (7 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 2 +-
drivers/block/drbd/drbd_main.c | 8 ++++----
drivers/block/drbd/drbd_nl.c | 12 ++++++------
drivers/block/drbd/drbd_receiver.c | 12 ++++++------
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4787c790..e6e4f4e 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -850,7 +850,7 @@ struct drbd_tconn { /* is a resource from the config file */
struct crypto_hash *cram_hmac_tfm;
struct crypto_hash *integrity_tfm; /* checksums we compute */
- struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */
+ struct crypto_hash *peer_integrity_tfm; /* checksums we verify */
struct crypto_hash *csums_tfm;
struct crypto_hash *verify_tfm;
void *int_dig_in;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 30dd8a9..417c437 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1405,8 +1405,8 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
void drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packet cmd,
struct p_data *dp, int data_size)
{
- data_size -= (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_r_tfm) ?
- crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
+ data_size -= (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->peer_integrity_tfm) ?
+ crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm) : 0;
_drbd_send_ack(mdev, cmd, dp->sector, cpu_to_be32(data_size),
dp->block_id);
}
@@ -2407,7 +2407,7 @@ void conn_free_crypto(struct drbd_tconn *tconn)
crypto_free_hash(tconn->verify_tfm);
crypto_free_hash(tconn->cram_hmac_tfm);
crypto_free_hash(tconn->integrity_tfm);
- crypto_free_hash(tconn->integrity_r_tfm);
+ crypto_free_hash(tconn->peer_integrity_tfm);
kfree(tconn->int_dig_in);
kfree(tconn->int_dig_vv);
@@ -2415,7 +2415,7 @@ void conn_free_crypto(struct drbd_tconn *tconn)
tconn->verify_tfm = NULL;
tconn->cram_hmac_tfm = NULL;
tconn->integrity_tfm = NULL;
- tconn->integrity_r_tfm = NULL;
+ tconn->peer_integrity_tfm = NULL;
tconn->int_dig_in = NULL;
tconn->int_dig_vv = NULL;
}
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index d24d96d..efae733 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1824,7 +1824,7 @@ struct crypto {
struct crypto_hash *csums_tfm;
struct crypto_hash *cram_hmac_tfm;
struct crypto_hash *integrity_tfm;
- struct crypto_hash *integrity_r_tfm;
+ struct crypto_hash *peer_integrity_tfm;
void *int_dig_in;
void *int_dig_vv;
};
@@ -1866,7 +1866,7 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
if (rv != NO_ERROR)
return rv;
- rv = alloc_tfm(&crypto->integrity_r_tfm, new_conf->integrity_alg,
+ rv = alloc_tfm(&crypto->peer_integrity_tfm, new_conf->integrity_alg,
ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
if (rv != NO_ERROR)
return rv;
@@ -1896,7 +1896,7 @@ static void free_crypto(struct crypto *crypto)
kfree(crypto->int_dig_vv);
crypto_free_hash(crypto->cram_hmac_tfm);
crypto_free_hash(crypto->integrity_tfm);
- crypto_free_hash(crypto->integrity_r_tfm);
+ crypto_free_hash(crypto->peer_integrity_tfm);
crypto_free_hash(crypto->csums_tfm);
crypto_free_hash(crypto->verify_tfm);
}
@@ -2003,8 +2003,8 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
tconn->int_dig_vv = crypto.int_dig_vv;
crypto_free_hash(tconn->integrity_tfm);
tconn->integrity_tfm = crypto.integrity_tfm;
- crypto_free_hash(tconn->integrity_r_tfm);
- tconn->integrity_r_tfm = crypto.integrity_r_tfm;
+ crypto_free_hash(tconn->peer_integrity_tfm);
+ tconn->peer_integrity_tfm = crypto.peer_integrity_tfm;
/* FIXME Changing cram_hmac while the connection is established is useless */
crypto_free_hash(tconn->cram_hmac_tfm);
@@ -2129,7 +2129,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
tconn->int_dig_vv = crypto.int_dig_vv;
tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
tconn->integrity_tfm = crypto.integrity_tfm;
- tconn->integrity_r_tfm = crypto.integrity_r_tfm;
+ tconn->peer_integrity_tfm = crypto.peer_integrity_tfm;
tconn->csums_tfm = crypto.csums_tfm;
tconn->verify_tfm = crypto.verify_tfm;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 98f03b1..36b846b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1384,8 +1384,8 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
void *dig_vv = mdev->tconn->int_dig_vv;
unsigned long *data;
- dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_r_tfm) ?
- crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
+ dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->peer_integrity_tfm) ?
+ crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm) : 0;
if (dgs) {
/*
@@ -1442,7 +1442,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
}
if (dgs) {
- drbd_csum_ee(mdev, mdev->tconn->integrity_r_tfm, peer_req, dig_vv);
+ drbd_csum_ee(mdev, mdev->tconn->peer_integrity_tfm, peer_req, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
dev_err(DEV, "Digest integrity check FAILED: %llus +%u\n",
(unsigned long long)sector, data_size);
@@ -1491,8 +1491,8 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
void *dig_in = mdev->tconn->int_dig_in;
void *dig_vv = mdev->tconn->int_dig_vv;
- dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_r_tfm) ?
- crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
+ dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->peer_integrity_tfm) ?
+ crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm) : 0;
if (dgs) {
err = drbd_recv_all_warn(mdev->tconn, dig_in, dgs);
@@ -1520,7 +1520,7 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
}
if (dgs) {
- drbd_csum_bio(mdev, mdev->tconn->integrity_r_tfm, bio, dig_vv);
+ drbd_csum_bio(mdev, mdev->tconn->peer_integrity_tfm, bio, dig_vv);
if (memcmp(dig_in, dig_vv, dgs)) {
dev_err(DEV, "Digest integrity check FAILED. Broken NICs?\n");
return -EINVAL;
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 09/16] drbd: Remove obsolete drbd_crypto_is_hash()
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (7 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 08/16] drbd: Rename integrity_r_tfm -> peer_integrity_tfm Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 10/16] drbd: Introduce a "lockless" variant of drbd_send_protocoll() Philipp Reisner
` (6 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
We allocate hash transformations with crypto_alloc_hash() which will
only return hash algorithms. It is not necessary to reconfirm that we
actually got a hash algorithm.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 25 +++++++++++--------------
drivers/block/drbd/drbd_receiver.c | 5 -----
drivers/block/drbd/drbd_wrappers.h | 6 ------
3 files changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index efae733..fd97ffb 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1830,7 +1830,7 @@ struct crypto {
};
static int
-alloc_tfm(struct crypto_hash **tfm, char *tfm_name, int err_alg, int err_nd)
+alloc_hash(struct crypto_hash **tfm, char *tfm_name, int err_alg)
{
if (!tfm_name[0])
return NO_ERROR;
@@ -1841,9 +1841,6 @@ alloc_tfm(struct crypto_hash **tfm, char *tfm_name, int err_alg, int err_nd)
return err_alg;
}
- if (!drbd_crypto_is_hash(crypto_hash_tfm(*tfm)))
- return err_nd;
-
return NO_ERROR;
}
@@ -1854,28 +1851,28 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
enum drbd_ret_code rv;
int hash_size;
- rv = alloc_tfm(&crypto->csums_tfm, new_conf->csums_alg,
- ERR_CSUMS_ALG, ERR_CSUMS_ALG_ND);
+ rv = alloc_hash(&crypto->csums_tfm, new_conf->csums_alg,
+ ERR_CSUMS_ALG);
if (rv != NO_ERROR)
return rv;
- rv = alloc_tfm(&crypto->verify_tfm, new_conf->verify_alg,
- ERR_VERIFY_ALG, ERR_VERIFY_ALG_ND);
+ rv = alloc_hash(&crypto->verify_tfm, new_conf->verify_alg,
+ ERR_VERIFY_ALG);
if (rv != NO_ERROR)
return rv;
- rv = alloc_tfm(&crypto->integrity_tfm, new_conf->integrity_alg,
- ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
+ rv = alloc_hash(&crypto->integrity_tfm, new_conf->integrity_alg,
+ ERR_INTEGRITY_ALG);
if (rv != NO_ERROR)
return rv;
- rv = alloc_tfm(&crypto->peer_integrity_tfm, new_conf->integrity_alg,
- ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
+ rv = alloc_hash(&crypto->peer_integrity_tfm, new_conf->integrity_alg,
+ ERR_INTEGRITY_ALG);
if (rv != NO_ERROR)
return rv;
if (new_conf->cram_hmac_alg[0] != 0) {
snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
new_conf->cram_hmac_alg);
- rv = alloc_tfm(&crypto->cram_hmac_tfm, hmac_name,
- ERR_AUTH_ALG, ERR_AUTH_ALG_ND);
+ rv = alloc_hash(&crypto->cram_hmac_tfm, hmac_name,
+ ERR_AUTH_ALG);
}
if (crypto->integrity_tfm) {
hash_size = crypto_hash_digestsize(crypto->integrity_tfm);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 36b846b..30b6556 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3100,11 +3100,6 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
alg, name, PTR_ERR(tfm));
return tfm;
}
- if (!drbd_crypto_is_hash(crypto_hash_tfm(tfm))) {
- crypto_free_hash(tfm);
- dev_err(DEV, "\"%s\" is not a digest (%s)\n", alg, name);
- return ERR_PTR(-EINVAL);
- }
return tfm;
}
diff --git a/drivers/block/drbd/drbd_wrappers.h b/drivers/block/drbd/drbd_wrappers.h
index decf9b2..46a6d99 100644
--- a/drivers/block/drbd/drbd_wrappers.h
+++ b/drivers/block/drbd/drbd_wrappers.h
@@ -45,12 +45,6 @@ static inline void drbd_generic_make_request(struct drbd_conf *mdev,
generic_make_request(bio);
}
-static inline int drbd_crypto_is_hash(struct crypto_tfm *tfm)
-{
- return (crypto_tfm_alg_type(tfm) & CRYPTO_ALG_TYPE_HASH_MASK)
- == CRYPTO_ALG_TYPE_HASH;
-}
-
#ifndef __CHECKER__
# undef __cond_lock
# define __cond_lock(x,c) (c)
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 10/16] drbd: Introduce a "lockless" variant of drbd_send_protocoll()
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (8 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 09/16] drbd: Remove obsolete drbd_crypto_is_hash() Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:37 ` [PATCH 11/16] drbd: Allow to change data-integrity-alg on the fly Philipp Reisner
` (5 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 1 +
drivers/block/drbd/drbd_main.c | 44 ++++++++++++++++++++++++++++++++-------
2 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e6e4f4e..44f7726 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1051,6 +1051,7 @@ extern int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
extern int drbd_send_all(struct drbd_tconn *, struct socket *, void *, size_t,
unsigned);
+extern int __drbd_send_protocol(struct drbd_tconn *tconn);
extern int drbd_send_protocol(struct drbd_tconn *tconn);
extern int drbd_send_uuids(struct drbd_conf *mdev);
extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 417c437..bcdd66d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -757,14 +757,24 @@ static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr,
return prepare_header80(buffer, cmd, size);
}
+static void *__conn_prepare_command(struct drbd_tconn *tconn,
+ struct drbd_socket *sock)
+{
+ if (!sock->socket)
+ return NULL;
+ return sock->sbuf + drbd_header_size(tconn);
+}
+
void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
{
+ void *p;
+
mutex_lock(&sock->mutex);
- if (!sock->socket) {
+ p = __conn_prepare_command(tconn, sock);
+ if (!p)
mutex_unlock(&sock->mutex);
- return NULL;
- }
- return sock->sbuf + drbd_header_size(tconn);
+
+ return p;
}
void *drbd_prepare_command(struct drbd_conf *mdev, struct drbd_socket *sock)
@@ -798,13 +808,20 @@ static int __send_command(struct drbd_tconn *tconn, int vnr,
return err;
}
+static int __conn_send_command(struct drbd_tconn *tconn, struct drbd_socket *sock,
+ enum drbd_packet cmd, unsigned int header_size,
+ void *data, unsigned int size)
+{
+ return __send_command(tconn, 0, sock, cmd, header_size, data, size);
+}
+
int conn_send_command(struct drbd_tconn *tconn, struct drbd_socket *sock,
enum drbd_packet cmd, unsigned int header_size,
void *data, unsigned int size)
{
int err;
- err = __send_command(tconn, 0, sock, cmd, header_size, data, size);
+ err = __conn_send_command(tconn, sock, cmd, header_size, data, size);
mutex_unlock(&sock->mutex);
return err;
}
@@ -893,7 +910,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev)
return drbd_send_command(mdev, sock, cmd, size, NULL, 0);
}
-int drbd_send_protocol(struct drbd_tconn *tconn)
+int __drbd_send_protocol(struct drbd_tconn *tconn)
{
struct drbd_socket *sock;
struct p_protocol *p;
@@ -901,7 +918,7 @@ int drbd_send_protocol(struct drbd_tconn *tconn)
int size, cf;
sock = &tconn->data;
- p = conn_prepare_command(tconn, sock);
+ p = __conn_prepare_command(tconn, sock);
if (!p)
return -EIO;
@@ -935,7 +952,18 @@ int drbd_send_protocol(struct drbd_tconn *tconn)
strcpy(p->integrity_alg, nc->integrity_alg);
rcu_read_unlock();
- return conn_send_command(tconn, sock, P_PROTOCOL, size, NULL, 0);
+ return __conn_send_command(tconn, sock, P_PROTOCOL, size, NULL, 0);
+}
+
+int drbd_send_protocol(struct drbd_tconn *tconn)
+{
+ int err;
+
+ mutex_lock(&tconn->data.mutex);
+ err = __drbd_send_protocol(tconn);
+ mutex_unlock(&tconn->data.mutex);
+
+ return err;
}
int _drbd_send_uuids(struct drbd_conf *mdev, u64 uuid_flags)
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 11/16] drbd: Allow to change data-integrity-alg on the fly
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (9 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 10/16] drbd: Introduce a "lockless" variant of drbd_send_protocoll() Philipp Reisner
@ 2011-10-05 9:37 ` Philipp Reisner
2011-10-05 9:38 ` [PATCH 12/16] drbd: fix race when forcefully disconnecting Philipp Reisner
` (4 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
The main purpose of this is to allow to turn data integrity checking on
and off on demand without causing interruptions.
Implemented by allocating tconn->peer_integrity_tfm only when receiving
a P_PROTOCOL message. l accesses to tconn->peer_integrity_tf happen in
worker context, and no further synchronization is necessary.
On the sender side, tconn->integrity_tfm is modified under
tconn->data.mutex, and a P_PROTOCOL message is sent whenever. All
accesses to tconn->integrity_tfm already happen under this mutex.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_main.c | 4 +-
drivers/block/drbd/drbd_nl.c | 22 ++++++++------
drivers/block/drbd/drbd_receiver.c | 54 +++++++++++++++++------------------
3 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index bcdd66d..1ea12d4 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1433,8 +1433,8 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
void drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packet cmd,
struct p_data *dp, int data_size)
{
- data_size -= (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->peer_integrity_tfm) ?
- crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm) : 0;
+ if (mdev->tconn->peer_integrity_tfm)
+ data_size -= crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm);
_drbd_send_ack(mdev, cmd, dp->sector, cpu_to_be32(data_size),
dp->block_id);
}
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index fd97ffb..0bf74b1 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1824,7 +1824,6 @@ struct crypto {
struct crypto_hash *csums_tfm;
struct crypto_hash *cram_hmac_tfm;
struct crypto_hash *integrity_tfm;
- struct crypto_hash *peer_integrity_tfm;
void *int_dig_in;
void *int_dig_vv;
};
@@ -1863,10 +1862,6 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
ERR_INTEGRITY_ALG);
if (rv != NO_ERROR)
return rv;
- rv = alloc_hash(&crypto->peer_integrity_tfm, new_conf->integrity_alg,
- ERR_INTEGRITY_ALG);
- if (rv != NO_ERROR)
- return rv;
if (new_conf->cram_hmac_alg[0] != 0) {
snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
new_conf->cram_hmac_alg);
@@ -1893,7 +1888,6 @@ static void free_crypto(struct crypto *crypto)
kfree(crypto->int_dig_vv);
crypto_free_hash(crypto->cram_hmac_tfm);
crypto_free_hash(crypto->integrity_tfm);
- crypto_free_hash(crypto->peer_integrity_tfm);
crypto_free_hash(crypto->csums_tfm);
crypto_free_hash(crypto->verify_tfm);
}
@@ -1907,6 +1901,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
int ovr; /* online verify running */
int rsr; /* re-sync running */
struct crypto crypto = { };
+ bool change_integrity_alg;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONN);
if (!adm_ctx.reply_skb)
@@ -1938,6 +1933,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
conn_reconfig_start(tconn);
+ mutex_lock(&tconn->data.mutex);
mutex_lock(&tconn->net_conf_update);
old_conf = tconn->net_conf;
@@ -1976,6 +1972,9 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
+ change_integrity_alg = strcmp(old_conf->integrity_alg,
+ new_conf->integrity_alg);
+
retcode = alloc_crypto(&crypto, new_conf);
if (retcode != NO_ERROR)
goto fail;
@@ -1993,21 +1992,24 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
crypto.verify_tfm = NULL;
}
- /* FIXME can not assign these so bluntly while we have ongoing IO */
kfree(tconn->int_dig_in);
tconn->int_dig_in = crypto.int_dig_in;
kfree(tconn->int_dig_vv);
tconn->int_dig_vv = crypto.int_dig_vv;
crypto_free_hash(tconn->integrity_tfm);
tconn->integrity_tfm = crypto.integrity_tfm;
- crypto_free_hash(tconn->peer_integrity_tfm);
- tconn->peer_integrity_tfm = crypto.peer_integrity_tfm;
+ if (change_integrity_alg) {
+ /* Do this without trying to take tconn->data.mutex again. */
+ if (__drbd_send_protocol(tconn))
+ goto fail;
+ }
/* FIXME Changing cram_hmac while the connection is established is useless */
crypto_free_hash(tconn->cram_hmac_tfm);
tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
mutex_unlock(&tconn->net_conf_update);
+ mutex_unlock(&tconn->data.mutex);
synchronize_rcu();
kfree(old_conf);
@@ -2018,6 +2020,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
fail:
mutex_unlock(&tconn->net_conf_update);
+ mutex_unlock(&tconn->data.mutex);
free_crypto(&crypto);
kfree(new_conf);
done:
@@ -2126,7 +2129,6 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
tconn->int_dig_vv = crypto.int_dig_vv;
tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
tconn->integrity_tfm = crypto.integrity_tfm;
- tconn->peer_integrity_tfm = crypto.peer_integrity_tfm;
tconn->csums_tfm = crypto.csums_tfm;
tconn->verify_tfm = crypto.verify_tfm;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 30b6556..9c8bcce 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1384,10 +1384,9 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
void *dig_vv = mdev->tconn->int_dig_vv;
unsigned long *data;
- dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->peer_integrity_tfm) ?
- crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm) : 0;
-
- if (dgs) {
+ dgs = 0;
+ if (mdev->tconn->peer_integrity_tfm) {
+ dgs = crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm);
/*
* FIXME: Receive the incoming digest into the receive buffer
* here, together with its struct p_data?
@@ -1395,10 +1394,9 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
err = drbd_recv_all_warn(mdev->tconn, dig_in, dgs);
if (err)
return NULL;
+ data_size -= dgs;
}
- data_size -= dgs;
-
if (!expect(data_size != 0))
return NULL;
if (!expect(IS_ALIGNED(data_size, 512)))
@@ -1491,17 +1489,15 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
void *dig_in = mdev->tconn->int_dig_in;
void *dig_vv = mdev->tconn->int_dig_vv;
- dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->peer_integrity_tfm) ?
- crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm) : 0;
-
- if (dgs) {
+ dgs = 0;
+ if (mdev->tconn->peer_integrity_tfm) {
+ dgs = crypto_hash_digestsize(mdev->tconn->peer_integrity_tfm);
err = drbd_recv_all_warn(mdev->tconn, dig_in, dgs);
if (err)
return err;
+ data_size -= dgs;
}
- data_size -= dgs;
-
/* optimistically update recv_cnt. if receiving fails below,
* we disconnect anyways, and counters will be reset. */
mdev->recv_cnt += data_size>>9;
@@ -2997,7 +2993,6 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
struct p_protocol *p = pi->data;
int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
int p_want_lose, p_two_primaries, cf;
- char p_integrity_alg[SHARED_SECRET_MAX] = "";
struct net_conf *nc;
p_proto = be32_to_cpu(p->protocol);
@@ -3009,15 +3004,30 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
p_want_lose = cf & CF_WANT_LOSE;
if (tconn->agreed_pro_version >= 87) {
+ char integrity_alg[SHARED_SECRET_MAX];
+ struct crypto_hash *tfm = NULL;
int err;
- if (pi->size > sizeof(p_integrity_alg))
+ if (pi->size > sizeof(integrity_alg))
return -EIO;
- err = drbd_recv_all(tconn, p_integrity_alg, pi->size);
+ err = drbd_recv_all(tconn, integrity_alg, pi->size);
if (err)
return err;
+ integrity_alg[SHARED_SECRET_MAX-1] = 0;
- p_integrity_alg[SHARED_SECRET_MAX-1] = 0;
+ if (integrity_alg[0]) {
+ tfm = crypto_alloc_hash(integrity_alg, 0, CRYPTO_ALG_ASYNC);
+ if (!tfm) {
+ conn_err(tconn, "peer data-integrity-alg %s not supported\n",
+ integrity_alg);
+ goto disconnect;
+ }
+ conn_info(tconn, "peer data-integrity-alg: %s\n", integrity_alg);
+ }
+
+ if (tconn->peer_integrity_tfm)
+ crypto_free_hash(tconn->peer_integrity_tfm);
+ tconn->peer_integrity_tfm = tfm;
}
clear_bit(CONN_DRY_RUN, &tconn->flags);
@@ -3058,20 +3068,8 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
goto disconnect_rcu_unlock;
}
- if (tconn->agreed_pro_version >= 87) {
- if (strcmp(p_integrity_alg, nc->integrity_alg)) {
- conn_err(tconn, "incompatible setting of the data-integrity-alg\n");
- goto disconnect;
- }
- }
-
rcu_read_unlock();
- if (tconn->agreed_pro_version >= 87) {
- conn_info(tconn, "data-integrity-alg: %s\n",
- nc->integrity_alg[0] ? nc->integrity_alg : (unsigned char *)"<not-used>");
- }
-
return 0;
disconnect_rcu_unlock:
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 12/16] drbd: fix race when forcefully disconnecting
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (10 preceding siblings ...)
2011-10-05 9:37 ` [PATCH 11/16] drbd: Allow to change data-integrity-alg on the fly Philipp Reisner
@ 2011-10-05 9:38 ` Philipp Reisner
2011-10-05 9:38 ` [PATCH 13/16] drbd: fix thread stop deadlock Philipp Reisner
` (3 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:38 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
If a forced disconnect hits a restarting receiver right after it passed
its final "if (C_DISCONNECTING)" test in drbdd_init(), but before it was
actually restarted by drbd_thread_setup, we could be left with a
connection stuck in C_DISCONNECTING, never reaching C_STANDALONE,
which would be necessary to take it down or reconfigure it.
Move the last cleanup into w_after_conn_state_ch(), and do an additional
state change request in conn_try_disconnect(), just in case.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 85 ++++++++++++++++++++----------------
drivers/block/drbd/drbd_receiver.c | 14 +------
drivers/block/drbd/drbd_state.c | 13 ++++++
3 files changed, 62 insertions(+), 50 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 0bf74b1..455b9a9 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2160,37 +2160,54 @@ out:
static enum drbd_state_rv conn_try_disconnect(struct drbd_tconn *tconn, bool force)
{
enum drbd_state_rv rv;
- if (force) {
- spin_lock_irq(&tconn->req_lock);
- rv = _conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
- spin_unlock_irq(&tconn->req_lock);
- return rv;
- }
- rv = conn_request_state(tconn, NS(conn, C_DISCONNECTING), 0);
+ rv = conn_request_state(tconn, NS(conn, C_DISCONNECTING),
+ force ? CS_HARD : 0);
switch (rv) {
case SS_NOTHING_TO_DO:
+ break;
case SS_ALREADY_STANDALONE:
return SS_SUCCESS;
case SS_PRIMARY_NOP:
/* Our state checking code wants to see the peer outdated. */
rv = conn_request_state(tconn, NS2(conn, C_DISCONNECTING,
- pdsk, D_OUTDATED), CS_VERBOSE);
+ pdsk, D_OUTDATED), CS_VERBOSE);
break;
case SS_CW_FAILED_BY_PEER:
/* The peer probably wants to see us outdated. */
rv = conn_request_state(tconn, NS2(conn, C_DISCONNECTING,
disk, D_OUTDATED), 0);
if (rv == SS_IS_DISKLESS || rv == SS_LOWER_THAN_OUTDATED) {
- conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
- rv = SS_SUCCESS;
+ rv = conn_request_state(tconn, NS(conn, C_DISCONNECTING),
+ CS_HARD);
}
break;
default:;
/* no special handling necessary */
}
+ if (rv >= SS_SUCCESS) {
+ enum drbd_state_rv rv2;
+ /* No one else can reconfigure the network while I am here.
+ * The state handling only uses drbd_thread_stop_nowait(),
+ * we want to really wait here until the receiver is no more.
+ */
+ drbd_thread_stop(&adm_ctx.tconn->receiver);
+
+ /* 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
+ * C_STANDALONE already, now, and this becomes a no-op.
+ */
+ rv2 = conn_request_state(tconn, NS(conn, C_STANDALONE),
+ CS_VERBOSE | CS_HARD);
+ if (rv2 < SS_SUCCESS)
+ conn_err(tconn,
+ "unexpected rv2=%d in conn_try_disconnect()\n",
+ rv2);
+ }
return rv;
}
@@ -2221,19 +2238,9 @@ int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info)
rv = conn_try_disconnect(tconn, parms.force_disconnect);
if (rv < SS_SUCCESS)
- goto fail;
-
- /* No one else can reconfigure the network while I am here.
- * The state handling only uses drbd_thread_stop_nowait(),
- * we want to really wait here until the receiver is no more. */
- drbd_thread_stop(&tconn->receiver);
- if (wait_event_interruptible(tconn->ping_wait,
- tconn->cstate == C_STANDALONE)) {
- retcode = ERR_INTR;
- goto fail;
- }
-
- retcode = NO_ERROR;
+ retcode = rv; /* FIXME: Type mismatch. */
+ else
+ retcode = NO_ERROR;
fail:
drbd_adm_finish(info, retcode);
return 0;
@@ -3095,8 +3102,7 @@ out:
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
{
- enum drbd_ret_code retcode;
- enum drbd_state_rv rv;
+ int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */
struct drbd_conf *mdev;
unsigned i;
@@ -3120,30 +3126,35 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
goto out_unlock;
}
}
+ up_read(&drbd_cfg_rwsem);
- /* disconnect */
- rv = conn_try_disconnect(adm_ctx.tconn, 0);
- if (rv < SS_SUCCESS) {
- retcode = rv; /* enum type mismatch! */
+ /* disconnect; may stop the receiver;
+ * must not hold the drbd_cfg_rwsem */
+ retcode = conn_try_disconnect(adm_ctx.tconn, 0);
+ if (retcode < SS_SUCCESS) {
drbd_msg_put_info("failed to disconnect");
- goto out_unlock;
+ goto out;
}
- /* Make sure the network threads have actually stopped,
- * state handling only does drbd_thread_stop_nowait(). */
- drbd_thread_stop(&adm_ctx.tconn->receiver);
-
+ down_read(&drbd_cfg_rwsem);
/* detach */
idr_for_each_entry(&adm_ctx.tconn->volumes, mdev, i) {
- rv = adm_detach(mdev);
- if (rv < SS_SUCCESS) {
- retcode = rv; /* enum type mismatch! */
+ retcode = adm_detach(mdev);
+ if (retcode < SS_SUCCESS) {
drbd_msg_put_info("failed to detach");
goto out_unlock;
}
}
up_read(&drbd_cfg_rwsem);
+ /* If we reach this, all volumes (of this tconn) are Secondary,
+ * Disconnected, Diskless, aka Unconfigured. Make sure all threads have
+ * actually stopped, state handling only does drbd_thread_stop_nowait().
+ * This needs to be done without holding drbd_cfg_rwsem. */
+ drbd_thread_stop(&adm_ctx.tconn->worker);
+
+ /* Now, nothing can fail anymore */
+
/* delete volumes */
down_write(&drbd_cfg_rwsem);
idr_for_each_entry(&adm_ctx.tconn->volumes, mdev, i) {
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 9c8bcce..956cdda 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4213,20 +4213,8 @@ static void drbd_disconnect(struct drbd_tconn *tconn)
spin_unlock_irq(&tconn->req_lock);
- if (oc == C_DISCONNECTING) {
- struct net_conf *old_conf;
-
- mutex_lock(&tconn->net_conf_update);
- old_conf = tconn->net_conf;
- rcu_assign_pointer(tconn->net_conf, NULL);
- conn_free_crypto(tconn);
- mutex_unlock(&tconn->net_conf_update);
-
- synchronize_rcu();
- kfree(old_conf);
-
+ if (oc == C_DISCONNECTING)
conn_request_state(tconn, NS(conn, C_STANDALONE), CS_VERBOSE | CS_HARD);
- }
}
static int drbd_disconnected(int vnr, void *p, void *data)
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 978dcef..f2e1535 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1398,6 +1398,19 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
if (oc == C_STANDALONE && ns_max.conn == C_UNCONNECTED)
drbd_thread_start(&tconn->receiver);
+ if (oc == C_DISCONNECTING && ns_max.conn == C_STANDALONE) {
+ struct net_conf *old_conf;
+
+ mutex_lock(&tconn->net_conf_update);
+ old_conf = tconn->net_conf;
+ rcu_assign_pointer(tconn->net_conf, NULL);
+ conn_free_crypto(tconn);
+ mutex_unlock(&tconn->net_conf_update);
+
+ synchronize_rcu();
+ kfree(old_conf);
+ }
+
if (ns_max.susp_fen) {
/* case1: The outdate peer handler is successful: */
if (ns_max.pdsk <= D_OUTDATED) {
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 13/16] drbd: fix thread stop deadlock
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (11 preceding siblings ...)
2011-10-05 9:38 ` [PATCH 12/16] drbd: fix race when forcefully disconnecting Philipp Reisner
@ 2011-10-05 9:38 ` Philipp Reisner
2011-10-05 9:38 ` [PATCH 14/16] drbd: fix schedule in atomic Philipp Reisner
` (2 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:38 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
There are races where the receiver may be exiting,
but still need the worker to process some stuff.
Do not wait for the receiver to die from an exiting worker.
The receiver must already be dead in case the worker decides to exit.
If the receiver was still alive, it may still want to queue work, and do
drbd_flush_workqueue() from it's disconnect cleanup code,
which would no longer be processed by an exiting worker.
This also would deadlock,
if the worker was to synchornously wait for the receiver to die.
Do not implicitly stop the worker.
The worker will only be stopped from configuration context, from
conn_reconfig_done(), drbd_adm_down() or drbd_adm_delete_connection(),
after making sure the receiver is already stopped.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_main.c | 2 +-
drivers/block/drbd/drbd_nl.c | 14 ++++++++++----
drivers/block/drbd/drbd_state.c | 14 --------------
drivers/block/drbd/drbd_worker.c | 4 ----
4 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 1ea12d4..e0342d0 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -503,7 +503,7 @@ restart:
thi->task = NULL;
thi->t_state = NONE;
smp_mb();
- complete(&thi->stop);
+ complete_all(&thi->stop);
spin_unlock_irqrestore(&thi->t_lock, flags);
conn_info(tconn, "Terminating %s\n", current->comm);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 455b9a9..019f762 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1072,10 +1072,16 @@ static void conn_reconfig_start(struct drbd_tconn *tconn)
/* if still unconfigured, stops worker again. */
static void conn_reconfig_done(struct drbd_tconn *tconn)
{
+ bool stop_threads;
spin_lock_irq(&tconn->req_lock);
- if (conn_all_vols_unconf(tconn))
- drbd_thread_stop_nowait(&tconn->worker);
+ stop_threads = conn_all_vols_unconf(tconn);
spin_unlock_irq(&tconn->req_lock);
+ if (stop_threads) {
+ /* asender is implicitly stopped by receiver
+ * in drbd_disconnect() */
+ drbd_thread_stop(&tconn->receiver);
+ drbd_thread_stop(&tconn->worker);
+ }
}
/* Make sure IO is suspended before calling this function(). */
@@ -3169,7 +3175,6 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
/* delete connection */
if (conn_lowest_minor(adm_ctx.tconn) < 0) {
- drbd_thread_stop(&adm_ctx.tconn->worker);
list_del(&adm_ctx.tconn->all_tconn);
kref_put(&adm_ctx.tconn->kref, &conn_destroy);
@@ -3179,7 +3184,6 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
retcode = ERR_CONN_IN_USE;
drbd_msg_put_info("failed to delete connection");
}
-
up_write(&drbd_cfg_rwsem);
goto out;
out_unlock:
@@ -3210,6 +3214,8 @@ int drbd_adm_delete_connection(struct sk_buff *skb, struct genl_info *info)
}
up_write(&drbd_cfg_rwsem);
+ if (retcode == NO_ERROR)
+ drbd_thread_stop(&adm_ctx.tconn->worker);
out:
drbd_adm_finish(info, retcode);
return 0;
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index f2e1535..327a75e 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -41,7 +41,6 @@ extern void _tl_restart(struct drbd_tconn *, enum drbd_req_event what);
static int w_after_state_ch(struct drbd_work *w, int unused);
static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
union drbd_state ns, enum chg_state_flags flags);
-static void after_all_state_ch(struct drbd_tconn *tconn);
static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns);
@@ -1362,8 +1361,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
resume_next_sg(mdev);
}
- after_all_state_ch(mdev->tconn);
-
drbd_md_sync(mdev);
}
@@ -1375,12 +1372,6 @@ struct after_conn_state_chg_work {
enum chg_state_flags flags;
};
-static void after_all_state_ch(struct drbd_tconn *tconn)
-{
- if (conn_all_vols_unconf(tconn))
- drbd_thread_stop_nowait(&tconn->worker);
-}
-
static int w_after_conn_state_ch(struct drbd_work *w, int unused)
{
struct after_conn_state_chg_work *acscw =
@@ -1443,12 +1434,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
spin_unlock_irq(&tconn->req_lock);
}
}
-
-
- //conn_err(tconn, STATE_FMT, STATE_ARGS("nms", nms));
- after_all_state_ch(tconn);
kref_put(&tconn->kref, &conn_destroy);
-
return 0;
}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 0eed488..f22288b1 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1744,10 +1744,6 @@ int drbd_worker(struct drbd_thread *thi)
*/
spin_unlock_irq(&tconn->data.work.q_lock);
- /* _drbd_set_state only uses stop_nowait.
- * wait here for the exiting receiver. */
- drbd_thread_stop(&tconn->receiver);
-
down_read(&drbd_cfg_rwsem);
idr_for_each_entry(&tconn->volumes, mdev, vnr) {
D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 14/16] drbd: fix schedule in atomic
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (12 preceding siblings ...)
2011-10-05 9:38 ` [PATCH 13/16] drbd: fix thread stop deadlock Philipp Reisner
@ 2011-10-05 9:38 ` Philipp Reisner
2011-10-05 9:38 ` [PATCH 15/16] drbd: Remove left-over unused define Philipp Reisner
2011-10-05 9:38 ` [PATCH 16/16] drbd: Generate the drbd_set_*_defaults() functions from drbd_genl.h Philipp Reisner
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:38 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
An administrative detach used to request a state change directly to D_DISKLESS,
first suspending IO to avoid the last put_ldev() occuring from an endio handler,
potentially in irq context.
This is not enough on the receiving side (typically secondary), we may miss
some peer_req on the way to local disk, which then may do the last put_ldev()
from their drbd_peer_request_endio().
This patch makes the detach always go through the intermediate D_FAILED state.
We may consider to rename it D_DETACHING.
Alternative approach would be to create yet an other work item to be scheduled
on the worker, do the destructor work from there, and get the timing right.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 019f762..414503a 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1706,12 +1706,17 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
static int adm_detach(struct drbd_conf *mdev)
{
enum drbd_ret_code retcode;
+ int ret;
drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */
- retcode = drbd_request_state(mdev, NS(disk, D_DISKLESS));
- wait_event(mdev->misc_wait,
- mdev->state.disk != D_DISKLESS ||
- !atomic_read(&mdev->local_cnt));
+ retcode = drbd_request_state(mdev, NS(disk, D_FAILED));
+ /* D_FAILED will transition to DISKLESS. */
+ ret = wait_event_interruptible(mdev->misc_wait,
+ mdev->state.disk != D_FAILED);
drbd_resume_io(mdev);
+ if (retcode == SS_IS_DISKLESS)
+ retcode = SS_NOTHING_TO_DO;
+ if (ret)
+ retcode = ERR_INTR;
return retcode;
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 15/16] drbd: Remove left-over unused define
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (13 preceding siblings ...)
2011-10-05 9:38 ` [PATCH 14/16] drbd: fix schedule in atomic Philipp Reisner
@ 2011-10-05 9:38 ` Philipp Reisner
2011-10-05 9:38 ` [PATCH 16/16] drbd: Generate the drbd_set_*_defaults() functions from drbd_genl.h Philipp Reisner
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:38 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
include/linux/drbd_limits.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h
index 659a8eb..52530aa 100644
--- a/include/linux/drbd_limits.h
+++ b/include/linux/drbd_limits.h
@@ -168,5 +168,4 @@
#define DRBD_PROTOCOL_DEF DRBD_PROT_C
-#undef RANGE
#endif
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 16/16] drbd: Generate the drbd_set_*_defaults() functions from drbd_genl.h
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
` (14 preceding siblings ...)
2011-10-05 9:38 ` [PATCH 15/16] drbd: Remove left-over unused define Philipp Reisner
@ 2011-10-05 9:38 ` Philipp Reisner
15 siblings, 0 replies; 17+ messages in thread
From: Philipp Reisner @ 2011-10-05 9:38 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 2 +-
drivers/block/drbd/drbd_main.c | 2 +-
drivers/block/drbd/drbd_nl.c | 86 ++++--------------------------------
include/linux/drbd_genl.h | 87 ++++++++++++++++++-------------------
include/linux/genl_magic_func.h | 30 ++++++++++++-
include/linux/genl_magic_struct.h | 8 +++
6 files changed, 91 insertions(+), 124 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 44f7726..8655fcb 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1390,7 +1390,7 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t);
/* drbd_nl.c */
-extern void drbd_set_res_opts_default(struct res_opts *r);
+extern void drbd_set_res_opts_defaults(struct res_opts *r);
extern int drbd_msg_put_info(const char *info);
extern void drbd_suspend_io(struct drbd_conf *mdev);
extern void drbd_resume_io(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e0342d0..cd08136 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2488,7 +2488,7 @@ struct drbd_tconn *conn_create(const char *name)
drbd_thread_init(tconn, &tconn->worker, drbd_worker, "worker");
drbd_thread_init(tconn, &tconn->asender, drbd_asender, "asender");
- drbd_set_res_opts_default(&tconn->res_opts);
+ drbd_set_res_opts_defaults(&tconn->res_opts);
down_write(&drbd_cfg_rwsem);
kref_init(&tconn->kref);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 414503a..d596900 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1112,77 +1112,6 @@ static bool should_set_defaults(struct genl_info *info)
return 0 != (flags & DRBD_GENL_F_SET_DEFAULTS);
}
-/* Maybe we should we generate these functions
- * from the drbd_genl.h magic as well?
- * That way we would not "accidentally forget" to add defaults here. */
-
-#define RESET_ARRAY_FIELD(field) do { \
- memset(field, 0, sizeof(field)); \
- field ## _len = 0; \
-} while (0)
-void drbd_set_res_opts_default(struct res_opts *r)
-{
- RESET_ARRAY_FIELD(r->cpu_mask);
- r->on_no_data = DRBD_ON_NO_DATA_DEF;
-}
-
-static void drbd_set_net_conf_defaults(struct net_conf *nc)
-{
- /* Do NOT (re)set those fields marked as GENLA_F_INVARIANT
- * in drbd_genl.h, they can only be change with disconnect/reconnect */
- RESET_ARRAY_FIELD(nc->shared_secret);
-
- RESET_ARRAY_FIELD(nc->cram_hmac_alg);
- RESET_ARRAY_FIELD(nc->integrity_alg);
- RESET_ARRAY_FIELD(nc->verify_alg);
- RESET_ARRAY_FIELD(nc->csums_alg);
-#undef RESET_ARRAY_FIELD
-
- nc->wire_protocol = DRBD_PROTOCOL_DEF;
- nc->try_connect_int = DRBD_CONNECT_INT_DEF;
- nc->timeout = DRBD_TIMEOUT_DEF;
- nc->ping_int = DRBD_PING_INT_DEF;
- nc->ping_timeo = DRBD_PING_TIMEO_DEF;
- nc->sndbuf_size = DRBD_SNDBUF_SIZE_DEF;
- nc->rcvbuf_size = DRBD_RCVBUF_SIZE_DEF;
- nc->ko_count = DRBD_KO_COUNT_DEF;
- nc->max_buffers = DRBD_MAX_BUFFERS_DEF;
- nc->max_epoch_size = DRBD_MAX_EPOCH_SIZE_DEF;
- nc->unplug_watermark = DRBD_UNPLUG_WATERMARK_DEF;
- nc->after_sb_0p = DRBD_AFTER_SB_0P_DEF;
- nc->after_sb_1p = DRBD_AFTER_SB_1P_DEF;
- nc->after_sb_2p = DRBD_AFTER_SB_2P_DEF;
- nc->rr_conflict = DRBD_RR_CONFLICT_DEF;
- nc->on_congestion = DRBD_ON_CONGESTION_DEF;
- nc->cong_fill = DRBD_CONG_FILL_DEF;
- nc->cong_extents = DRBD_CONG_EXTENTS_DEF;
- nc->two_primaries = 0;
- nc->no_cork = 0;
- nc->always_asbp = 0;
- nc->use_rle = 0;
-}
-
-static void drbd_set_disk_conf_defaults(struct disk_conf *dc)
-{
- /* Do NOT (re)set those fields marked as GENLA_F_INVARIANT
- * in drbd_genl.h, they can only be change with detach/reattach */
- dc->on_io_error = DRBD_ON_IO_ERROR_DEF;
- dc->fencing = DRBD_FENCING_DEF;
- dc->resync_rate = DRBD_RATE_DEF;
- dc->resync_after = DRBD_AFTER_DEF;
- dc->al_extents = DRBD_AL_EXTENTS_DEF;
- dc->c_plan_ahead = DRBD_C_PLAN_AHEAD_DEF;
- dc->c_delay_target = DRBD_C_DELAY_TARGET_DEF;
- dc->c_fill_target = DRBD_C_FILL_TARGET_DEF;
- dc->c_max_rate = DRBD_C_MAX_RATE_DEF;
- dc->c_min_rate = DRBD_C_MIN_RATE_DEF;
- dc->no_disk_barrier = 0;
- dc->no_disk_flush = 0;
- dc->no_disk_drain = 0;
- dc->no_md_flush = 0;
-}
-
-
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
{
enum drbd_ret_code retcode;
@@ -1234,7 +1163,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
memcpy(new_disk_conf, &mdev->ldev->dc, sizeof(*new_disk_conf));
if (should_set_defaults(info))
- drbd_set_disk_conf_defaults(new_disk_conf);
+ set_disk_conf_defaults(new_disk_conf);
err = disk_conf_from_attrs(new_disk_conf, info);
if (err) {
@@ -1351,7 +1280,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- drbd_set_disk_conf_defaults(&nbc->dc);
+ set_disk_conf_defaults(&nbc->dc);
err = disk_conf_from_attrs(&nbc->dc, info);
if (err) {
@@ -1956,7 +1885,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
*new_conf = *old_conf;
if (should_set_defaults(info))
- drbd_set_net_conf_defaults(new_conf);
+ set_net_conf_defaults(new_conf);
err = net_conf_from_attrs(new_conf, info);
if (err) {
@@ -2074,7 +2003,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- drbd_set_net_conf_defaults(new_conf);
+ set_net_conf_defaults(new_conf);
err = net_conf_from_attrs(new_conf, info);
if (err) {
@@ -2346,6 +2275,11 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
return 0;
}
+void drbd_set_res_opts_defaults(struct res_opts *r)
+{
+ return set_res_opts_defaults(r);
+}
+
int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
{
enum drbd_ret_code retcode;
@@ -2370,7 +2304,7 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
res_opts = tconn->res_opts;
if (should_set_defaults(info))
- drbd_set_res_opts_default(&res_opts);
+ set_res_opts_defaults(&res_opts);
err = res_opts_from_attrs(&res_opts, info);
if (err) {
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 938e856..8cad681 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -112,63 +112,62 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
* but it won't propagate through the stack */
__u32_field(5, GENLA_F_MANDATORY | GENLA_F_INVARIANT, max_bio_bvecs)
- __u32_field(6, GENLA_F_MANDATORY, on_io_error)
- __u32_field(7, GENLA_F_MANDATORY, fencing)
-
- __u32_field(8, GENLA_F_MANDATORY, resync_rate)
- __u32_field(9, GENLA_F_MANDATORY, resync_after)
- __u32_field(10, GENLA_F_MANDATORY, al_extents)
- __u32_field(11, GENLA_F_MANDATORY, c_plan_ahead)
- __u32_field(12, GENLA_F_MANDATORY, c_delay_target)
- __u32_field(13, GENLA_F_MANDATORY, c_fill_target)
- __u32_field(14, GENLA_F_MANDATORY, c_max_rate)
- __u32_field(15, GENLA_F_MANDATORY, c_min_rate)
-
- __flg_field(16, GENLA_F_MANDATORY, no_disk_barrier)
- __flg_field(17, GENLA_F_MANDATORY, no_disk_flush)
- __flg_field(18, GENLA_F_MANDATORY, no_disk_drain)
- __flg_field(19, GENLA_F_MANDATORY, no_md_flush)
-
+ __u32_field_def(6, GENLA_F_MANDATORY, on_io_error, DRBD_ON_IO_ERROR_DEF)
+ __u32_field_def(7, GENLA_F_MANDATORY, fencing, DRBD_FENCING_DEF)
+
+ __u32_field_def(8, GENLA_F_MANDATORY, resync_rate, DRBD_RATE_DEF)
+ __u32_field_def(9, GENLA_F_MANDATORY, resync_after, DRBD_AFTER_DEF)
+ __u32_field_def(10, GENLA_F_MANDATORY, al_extents, DRBD_AL_EXTENTS_DEF)
+ __u32_field_def(11, GENLA_F_MANDATORY, c_plan_ahead, DRBD_C_PLAN_AHEAD_DEF)
+ __u32_field_def(12, GENLA_F_MANDATORY, c_delay_target, DRBD_C_DELAY_TARGET_DEF)
+ __u32_field_def(13, GENLA_F_MANDATORY, c_fill_target, DRBD_C_FILL_TARGET_DEF)
+ __u32_field_def(14, GENLA_F_MANDATORY, c_max_rate, DRBD_C_MAX_RATE_DEF)
+ __u32_field_def(15, GENLA_F_MANDATORY, c_min_rate, DRBD_C_MIN_RATE_DEF)
+
+ __flg_field_def(16, GENLA_F_MANDATORY, no_disk_barrier, 0)
+ __flg_field_def(17, GENLA_F_MANDATORY, no_disk_flush, 0)
+ __flg_field_def(18, GENLA_F_MANDATORY, no_disk_drain, 0)
+ __flg_field_def(19, GENLA_F_MANDATORY, no_md_flush, 0)
)
GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts,
- __str_field(1, GENLA_F_MANDATORY, cpu_mask, 32)
- __u32_field(2, GENLA_F_MANDATORY, on_no_data)
+ __str_field_def(1, GENLA_F_MANDATORY, cpu_mask, 32)
+ __u32_field_def(2, GENLA_F_MANDATORY, on_no_data, DRBD_ON_NO_DATA_DEF)
)
GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf,
__bin_field(1, GENLA_F_REQUIRED | GENLA_F_INVARIANT, my_addr, 128)
__bin_field(2, GENLA_F_REQUIRED | GENLA_F_INVARIANT, peer_addr, 128)
- __str_field(3, GENLA_F_MANDATORY | GENLA_F_SENSITIVE,
+ __str_field_def(3, GENLA_F_MANDATORY | GENLA_F_SENSITIVE,
shared_secret, SHARED_SECRET_MAX)
- __str_field(4, GENLA_F_MANDATORY, cram_hmac_alg, SHARED_SECRET_MAX)
- __str_field(5, GENLA_F_MANDATORY, integrity_alg, SHARED_SECRET_MAX)
- __str_field(6, GENLA_F_MANDATORY, verify_alg, SHARED_SECRET_MAX)
- __str_field(7, GENLA_F_MANDATORY, csums_alg, SHARED_SECRET_MAX)
- __u32_field(8, GENLA_F_MANDATORY, wire_protocol)
- __u32_field(9, GENLA_F_MANDATORY, try_connect_int)
- __u32_field(10, GENLA_F_MANDATORY, timeout)
- __u32_field(11, GENLA_F_MANDATORY, ping_int)
- __u32_field(12, GENLA_F_MANDATORY, ping_timeo)
- __u32_field(13, GENLA_F_MANDATORY, sndbuf_size)
- __u32_field(14, GENLA_F_MANDATORY, rcvbuf_size)
- __u32_field(15, GENLA_F_MANDATORY, ko_count)
- __u32_field(16, GENLA_F_MANDATORY, max_buffers)
- __u32_field(17, GENLA_F_MANDATORY, max_epoch_size)
- __u32_field(18, GENLA_F_MANDATORY, unplug_watermark)
- __u32_field(19, GENLA_F_MANDATORY, after_sb_0p)
- __u32_field(20, GENLA_F_MANDATORY, after_sb_1p)
- __u32_field(21, GENLA_F_MANDATORY, after_sb_2p)
- __u32_field(22, GENLA_F_MANDATORY, rr_conflict)
- __u32_field(23, GENLA_F_MANDATORY, on_congestion)
- __u32_field(24, GENLA_F_MANDATORY, cong_fill)
- __u32_field(25, GENLA_F_MANDATORY, cong_extents)
- __flg_field(26, GENLA_F_MANDATORY, two_primaries)
+ __str_field_def(4, GENLA_F_MANDATORY, cram_hmac_alg, SHARED_SECRET_MAX)
+ __str_field_def(5, GENLA_F_MANDATORY, integrity_alg, SHARED_SECRET_MAX)
+ __str_field_def(6, GENLA_F_MANDATORY, verify_alg, SHARED_SECRET_MAX)
+ __str_field_def(7, GENLA_F_MANDATORY, csums_alg, SHARED_SECRET_MAX)
+ __u32_field_def(8, GENLA_F_MANDATORY, wire_protocol, DRBD_PROTOCOL_DEF)
+ __u32_field_def(9, GENLA_F_MANDATORY, try_connect_int, DRBD_CONNECT_INT_DEF)
+ __u32_field_def(10, GENLA_F_MANDATORY, timeout, DRBD_TIMEOUT_DEF)
+ __u32_field_def(11, GENLA_F_MANDATORY, ping_int, DRBD_PING_INT_DEF)
+ __u32_field_def(12, GENLA_F_MANDATORY, ping_timeo, DRBD_PING_TIMEO_DEF)
+ __u32_field_def(13, GENLA_F_MANDATORY, sndbuf_size, DRBD_SNDBUF_SIZE_DEF)
+ __u32_field_def(14, GENLA_F_MANDATORY, rcvbuf_size, DRBD_RCVBUF_SIZE_DEF)
+ __u32_field_def(15, GENLA_F_MANDATORY, ko_count, DRBD_KO_COUNT_DEF)
+ __u32_field_def(16, GENLA_F_MANDATORY, max_buffers, DRBD_MAX_BUFFERS_DEF)
+ __u32_field_def(17, GENLA_F_MANDATORY, max_epoch_size, DRBD_MAX_EPOCH_SIZE_DEF)
+ __u32_field_def(18, GENLA_F_MANDATORY, unplug_watermark, DRBD_UNPLUG_WATERMARK_DEF)
+ __u32_field_def(19, GENLA_F_MANDATORY, after_sb_0p, DRBD_AFTER_SB_0P_DEF)
+ __u32_field_def(20, GENLA_F_MANDATORY, after_sb_1p, DRBD_AFTER_SB_1P_DEF)
+ __u32_field_def(21, GENLA_F_MANDATORY, after_sb_2p, DRBD_AFTER_SB_2P_DEF)
+ __u32_field_def(22, GENLA_F_MANDATORY, rr_conflict, DRBD_RR_CONFLICT_DEF)
+ __u32_field_def(23, GENLA_F_MANDATORY, on_congestion, DRBD_ON_CONGESTION_DEF)
+ __u32_field_def(24, GENLA_F_MANDATORY, cong_fill, DRBD_CONG_FILL_DEF)
+ __u32_field_def(25, GENLA_F_MANDATORY, cong_extents, DRBD_CONG_EXTENTS_DEF)
+ __flg_field_def(26, GENLA_F_MANDATORY, two_primaries, 0)
__flg_field(27, GENLA_F_MANDATORY | GENLA_F_INVARIANT, want_lose)
- __flg_field(28, GENLA_F_MANDATORY, no_cork)
- __flg_field(29, GENLA_F_MANDATORY, always_asbp)
+ __flg_field_def(28, GENLA_F_MANDATORY, no_cork, 0)
+ __flg_field_def(29, GENLA_F_MANDATORY, always_asbp, 0)
__flg_field(30, GENLA_F_MANDATORY | GENLA_F_INVARIANT, dry_run)
- __flg_field(31, GENLA_F_MANDATORY, use_rle)
+ __flg_field_def(31, GENLA_F_MANDATORY, use_rle, 0)
)
GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms,
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h
index c71cb12..ce02500 100644
--- a/include/linux/genl_magic_func.h
+++ b/include/linux/genl_magic_func.h
@@ -190,8 +190,8 @@ static struct nlattr *nested_attr_tb[128];
#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
-/* *_from_attrs functions are static, but potentially unused */ \
-int s_name ## _from_attrs(struct s_name *s, struct genl_info *info) \
+static int s_name ## _from_attrs(struct s_name *s, struct genl_info *info) __attribute__((unused)); \
+static int s_name ## _from_attrs(struct s_name *s, struct genl_info *info) \
{ \
const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1; \
struct nlattr *tla = info->attrs[tag_number]; \
@@ -421,6 +421,32 @@ static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb, \
#include GENL_MAGIC_INCLUDE_FILE
+
+/* Functions for initializing structs to default values. */
+
+#undef __field
+#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put)
+#undef __array
+#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, __get, __put)
+#undef __u32_field_def
+#define __u32_field_def(attr_nr, attr_flag, name, default) \
+ x->name = default;
+#undef __flg_field_def
+#define __flg_field_def(attr_nr, attr_flag, name, default) \
+ x->name = default;
+#undef __str_field_def
+#define __str_field_def(attr_nr, attr_flag, name, maxlen) \
+ memset(x->name, 0, sizeof(x->name)); \
+ x->name ## _len = 0;
+#undef GENL_struct
+#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
+static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \
+static void set_ ## s_name ## _defaults(struct s_name *x) { \
+s_fields \
+}
+
+#include GENL_MAGIC_INCLUDE_FILE
+
#endif /* __KERNEL__ */
/* }}}1 */
diff --git a/include/linux/genl_magic_struct.h b/include/linux/genl_magic_struct.h
index 9a605b9..f2c7cc7 100644
--- a/include/linux/genl_magic_struct.h
+++ b/include/linux/genl_magic_struct.h
@@ -107,6 +107,14 @@ enum {
__array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
nla_memcpy, NLA_PUT)
+/* fields with default values */
+#define __flg_field_def(attr_nr, attr_flag, name, default) \
+ __flg_field(attr_nr, attr_flag, name)
+#define __u32_field_def(attr_nr, attr_flag, name, default) \
+ __u32_field(attr_nr, attr_flag, name)
+#define __str_field_def(attr_nr, attr_flag, name, maxlen) \
+ __str_field(attr_nr, attr_flag, name, maxlen)
+
#define __nla_put_flag(skb, attrtype, value) \
do { \
if (value) \
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2011-10-05 9:41 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-05 9:37 [RFC 00/16] drbd: part 14 of adding multiple volume support to drbd Philipp Reisner
2011-10-05 9:37 ` [PATCH 01/16] drbd: Consider all crypto options in connect and in net-options Philipp Reisner
2011-10-05 9:37 ` [PATCH 02/16] drbd: on reconfiguration requests, mind the SET_DEFAULTS flag Philipp Reisner
2011-10-05 9:37 ` [PATCH 03/16] drbd: rename variable ndc to new_disk_conf Philipp Reisner
2011-10-05 9:37 ` [PATCH 04/16] drbd: rename variable sc to res_opts Philipp Reisner
2011-10-05 9:37 ` [PATCH 05/16] drbd: fix copy/paste error in comment Philipp Reisner
2011-10-05 9:37 ` [PATCH 06/16] drbd: Wrong use of RCU in receive_protocol() Philipp Reisner
2011-10-05 9:37 ` [PATCH 07/16] drbd: Rename integrity_w_tfm -> integrity_tfm Philipp Reisner
2011-10-05 9:37 ` [PATCH 08/16] drbd: Rename integrity_r_tfm -> peer_integrity_tfm Philipp Reisner
2011-10-05 9:37 ` [PATCH 09/16] drbd: Remove obsolete drbd_crypto_is_hash() Philipp Reisner
2011-10-05 9:37 ` [PATCH 10/16] drbd: Introduce a "lockless" variant of drbd_send_protocoll() Philipp Reisner
2011-10-05 9:37 ` [PATCH 11/16] drbd: Allow to change data-integrity-alg on the fly Philipp Reisner
2011-10-05 9:38 ` [PATCH 12/16] drbd: fix race when forcefully disconnecting Philipp Reisner
2011-10-05 9:38 ` [PATCH 13/16] drbd: fix thread stop deadlock Philipp Reisner
2011-10-05 9:38 ` [PATCH 14/16] drbd: fix schedule in atomic Philipp Reisner
2011-10-05 9:38 ` [PATCH 15/16] drbd: Remove left-over unused define Philipp Reisner
2011-10-05 9:38 ` [PATCH 16/16] drbd: Generate the drbd_set_*_defaults() functions from drbd_genl.h Philipp Reisner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®