* [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd
@ 2011-10-06 13:37 Philipp Reisner
2011-10-06 13:37 ` [PATCH 01/15] drbd: Removed dead code Philipp Reisner
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13: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 fifteenth installment containing 15 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 ce51036^...c605e11
This patch series contains:
* RCU for disk_conf
* Boolean configure options got two values; eliminate the "no-" prefixes
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/15] drbd: Removed dead code
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 02/15] drbd: Renamed the net_conf_update mutex to conf_update Philipp Reisner
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index d596900..13230d9 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2285,7 +2285,6 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
enum drbd_ret_code retcode;
cpumask_var_t new_cpu_mask;
struct drbd_tconn *tconn;
- int *rs_plan_s = NULL;
struct res_opts res_opts;
int err;
@@ -2336,7 +2335,6 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
}
fail:
- kfree(rs_plan_s);
free_cpumask_var(new_cpu_mask);
drbd_adm_finish(info, retcode);
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 02/15] drbd: Renamed the net_conf_update mutex to conf_update
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
2011-10-06 13:37 ` [PATCH 01/15] drbd: Removed dead code Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 03/15] drbd: drbd_dew_dev_size() gets the user requests disk_size as argument Philipp Reisner
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Preparing to use the same mutex for disk_conf updates
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 | 16 ++++++++--------
drivers/block/drbd/drbd_receiver.c | 10 +++++-----
drivers/block/drbd/drbd_state.c | 4 ++--
5 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 8655fcb..0311dfd 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -832,7 +832,7 @@ struct drbd_tconn { /* is a resource from the config file */
unsigned long flags;
struct net_conf *net_conf; /* content protected by rcu */
- struct mutex net_conf_update; /* mutex for ready-copy-update of net_conf */
+ struct mutex conf_update; /* mutex for ready-copy-update of net_conf and disk_conf */
wait_queue_head_t ping_wait; /* Woken upon reception of a ping, and a state change */
struct res_opts res_opts;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index cd08136..352c36f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2474,7 +2474,7 @@ struct drbd_tconn *conn_create(const char *name)
tconn->cstate = C_STANDALONE;
mutex_init(&tconn->cstate_mutex);
spin_lock_init(&tconn->req_lock);
- mutex_init(&tconn->net_conf_update);
+ mutex_init(&tconn->conf_update);
init_waitqueue_head(&tconn->ping_wait);
idr_init(&tconn->volumes);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 13230d9..6317ae5 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -619,11 +619,11 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
put_ldev(mdev);
}
} else {
- mutex_lock(&mdev->tconn->net_conf_update);
+ mutex_lock(&mdev->tconn->conf_update);
nc = mdev->tconn->net_conf;
if (nc)
nc->want_lose = 0; /* without copy; single bit op is atomic */
- mutex_unlock(&mdev->tconn->net_conf_update);
+ mutex_unlock(&mdev->tconn->conf_update);
set_disk_ro(mdev->vdisk, false);
if (get_ldev(mdev)) {
@@ -1874,7 +1874,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);
+ mutex_lock(&tconn->conf_update);
old_conf = tconn->net_conf;
if (!old_conf) {
@@ -1948,7 +1948,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
crypto_free_hash(tconn->cram_hmac_tfm);
tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
- mutex_unlock(&tconn->net_conf_update);
+ mutex_unlock(&tconn->conf_update);
mutex_unlock(&tconn->data.mutex);
synchronize_rcu();
kfree(old_conf);
@@ -1959,7 +1959,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
goto done;
fail:
- mutex_unlock(&tconn->net_conf_update);
+ mutex_unlock(&tconn->conf_update);
mutex_unlock(&tconn->data.mutex);
free_crypto(&crypto);
kfree(new_conf);
@@ -2055,11 +2055,11 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
conn_flush_workqueue(tconn);
- mutex_lock(&tconn->net_conf_update);
+ mutex_lock(&tconn->conf_update);
old_conf = tconn->net_conf;
if (old_conf) {
retcode = ERR_NET_CONFIGURED;
- mutex_unlock(&tconn->net_conf_update);
+ mutex_unlock(&tconn->conf_update);
goto fail;
}
rcu_assign_pointer(tconn->net_conf, new_conf);
@@ -2072,7 +2072,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
tconn->csums_tfm = crypto.csums_tfm;
tconn->verify_tfm = crypto.verify_tfm;
- mutex_unlock(&tconn->net_conf_update);
+ mutex_unlock(&tconn->conf_update);
rcu_read_lock();
idr_for_each_entry(&tconn->volumes, mdev, i) {
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 956cdda..567d64b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3221,7 +3221,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
p->csums_alg[SHARED_SECRET_MAX-1] = 0;
}
- mutex_lock(&mdev->tconn->net_conf_update);
+ mutex_lock(&mdev->tconn->conf_update);
old_conf = mdev->tconn->net_conf;
if (strcmp(old_conf->verify_alg, p->verify_alg)) {
@@ -3296,7 +3296,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
}
rcu_assign_pointer(tconn->net_conf, new_conf);
}
- mutex_unlock(&mdev->tconn->net_conf_update);
+ mutex_unlock(&mdev->tconn->conf_update);
if (new_conf) {
synchronize_rcu();
kfree(old_conf);
@@ -3314,7 +3314,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
return 0;
disconnect:
- mutex_unlock(&mdev->tconn->net_conf_update);
+ mutex_unlock(&mdev->tconn->conf_update);
/* just for completeness: actually not needed,
* as this is not reached if csums_tfm was ok. */
crypto_free_hash(csums_tfm);
@@ -3744,9 +3744,9 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
}
}
- mutex_lock(&mdev->tconn->net_conf_update);
+ mutex_lock(&mdev->tconn->conf_update);
mdev->tconn->net_conf->want_lose = 0; /* without copy; single bit op is atomic */
- mutex_unlock(&mdev->tconn->net_conf_update);
+ mutex_unlock(&mdev->tconn->conf_update);
drbd_md_sync(mdev); /* update connected indicator, la_size, ... */
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 327a75e..befaf07 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1392,11 +1392,11 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
if (oc == C_DISCONNECTING && ns_max.conn == C_STANDALONE) {
struct net_conf *old_conf;
- mutex_lock(&tconn->net_conf_update);
+ mutex_lock(&tconn->conf_update);
old_conf = tconn->net_conf;
rcu_assign_pointer(tconn->net_conf, NULL);
conn_free_crypto(tconn);
- mutex_unlock(&tconn->net_conf_update);
+ mutex_unlock(&tconn->conf_update);
synchronize_rcu();
kfree(old_conf);
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 03/15] drbd: drbd_dew_dev_size() gets the user requests disk_size as argument
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
2011-10-06 13:37 ` [PATCH 01/15] drbd: Removed dead code Philipp Reisner
2011-10-06 13:37 ` [PATCH 02/15] drbd: Renamed the net_conf_update mutex to conf_update Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 04/15] drbd: Split drbd_alter_sa() into drbd_sync_after_valid() and drbd_sync_after_changed() Philipp Reisner
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Preparing RCU for disk_conf
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_nl.c | 11 ++++++-----
drivers/block/drbd/drbd_receiver.c | 2 +-
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0311dfd..8c7e340 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1395,7 +1395,7 @@ 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);
extern char *ppsize(char *buf, unsigned long long size);
-extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, int);
+extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, sector_t, int);
enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 };
extern enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local);
extern void resync_after_online_grow(struct drbd_conf *);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 6317ae5..dfe43f2 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -797,7 +797,7 @@ void drbd_resume_io(struct drbd_conf *mdev)
enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local)
{
sector_t prev_first_sect, prev_size; /* previous meta location */
- sector_t la_size;
+ sector_t la_size, u_size;
sector_t size;
char ppb[10];
@@ -825,7 +825,8 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds
/* TODO: should only be some assert here, not (re)init... */
drbd_md_set_sector_offsets(mdev, mdev->ldev);
- size = drbd_new_dev_size(mdev, mdev->ldev, flags & DDSF_FORCED);
+ u_size = mdev->ldev->dc.disk_size;
+ size = drbd_new_dev_size(mdev, mdev->ldev, u_size, flags & DDSF_FORCED);
if (drbd_get_capacity(mdev->this_bdev) != size ||
drbd_bm_capacity(mdev) != size) {
@@ -888,12 +889,12 @@ out:
}
sector_t
-drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, int assume_peer_has_space)
+drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
+ sector_t u_size, int assume_peer_has_space)
{
sector_t p_size = mdev->p_size; /* partner's disk size. */
sector_t la_size = bdev->md.la_size_sect; /* last agreed size. */
sector_t m_size; /* my size */
- sector_t u_size = bdev->dc.disk_size; /* size requested by user. */
sector_t size = 0;
m_size = drbd_get_max_capacity(bdev);
@@ -1442,7 +1443,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
/* Prevent shrinking of consistent devices ! */
if (drbd_md_test_flag(nbc, MDF_CONSISTENT) &&
- drbd_new_dev_size(mdev, nbc, 0) < nbc->md.la_size_sect) {
+ drbd_new_dev_size(mdev, nbc, nbc->dc.disk_size, 0) < nbc->md.la_size_sect) {
dev_warn(DEV, "refusing to truncate a consistent device\n");
retcode = ERR_DISK_TO_SMALL;
goto force_diskless_dec;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 567d64b..23614e4 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3379,7 +3379,7 @@ static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi)
/* Never shrink a device with usable data during connect.
But allow online shrinking if we are connected. */
- if (drbd_new_dev_size(mdev, mdev->ldev, 0) <
+ if (drbd_new_dev_size(mdev, mdev->ldev, p_usize, 0) <
drbd_get_capacity(mdev->this_bdev) &&
mdev->state.disk >= D_OUTDATED &&
mdev->state.conn < C_CONNECTED) {
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 04/15] drbd: Split drbd_alter_sa() into drbd_sync_after_valid() and drbd_sync_after_changed()
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (2 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 03/15] drbd: drbd_dew_dev_size() gets the user requests disk_size as argument Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 05/15] drbd: Renamed (old|new)_conf into (old|new)_net_conf in receive_SyncParam Philipp Reisner
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Preparing RCU for disk_conf
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 3 ++-
drivers/block/drbd/drbd_nl.c | 15 +++++++--------
drivers/block/drbd/drbd_worker.c | 22 ++++++++--------------
3 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 8c7e340..f8d0ac3 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1409,7 +1409,8 @@ extern int drbd_khelper(struct drbd_conf *mdev, char *cmd);
/* drbd_worker.c */
extern int drbd_worker(struct drbd_thread *thi);
-extern int drbd_alter_sa(struct drbd_conf *mdev, int na);
+enum drbd_ret_code drbd_sync_after_valid(struct drbd_conf *mdev, int o_minor);
+void drbd_sync_after_changed(struct drbd_conf *mdev);
extern void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side);
extern void resume_next_sg(struct drbd_conf *mdev);
extern void suspend_other_sg(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index dfe43f2..4efeffa 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1181,13 +1181,6 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
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, new_disk_conf->resync_after);
- if (retcode != NO_ERROR)
- goto fail;
-
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);
@@ -1221,7 +1214,13 @@ 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 = *new_disk_conf;
+ write_lock_irq(&global_state_lock);
+ retcode = drbd_sync_after_valid(mdev, new_disk_conf->resync_after);
+ if (retcode == NO_ERROR) {
+ mdev->ldev->dc = *new_disk_conf;
+ drbd_sync_after_changed(mdev);
+ }
+ write_unlock_irq(&global_state_lock);
drbd_md_sync(mdev);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index f22288b1..f8fdf75 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1401,7 +1401,8 @@ void suspend_other_sg(struct drbd_conf *mdev)
write_unlock_irq(&global_state_lock);
}
-static int sync_after_error(struct drbd_conf *mdev, int o_minor)
+/* caller must hold global_state_lock */
+enum drbd_ret_code drbd_sync_after_valid(struct drbd_conf *mdev, int o_minor)
{
struct drbd_conf *odev;
@@ -1425,22 +1426,15 @@ static int sync_after_error(struct drbd_conf *mdev, int o_minor)
}
}
-int drbd_alter_sa(struct drbd_conf *mdev, int na)
+/* caller must hold global_state_lock */
+void drbd_sync_after_changed(struct drbd_conf *mdev)
{
int changes;
- int retcode;
- write_lock_irq(&global_state_lock);
- retcode = sync_after_error(mdev, na);
- if (retcode == NO_ERROR) {
- mdev->ldev->dc.resync_after = na;
- do {
- changes = _drbd_pause_after(mdev);
- changes |= _drbd_resume_next(mdev);
- } while (changes);
- }
- write_unlock_irq(&global_state_lock);
- return retcode;
+ do {
+ changes = _drbd_pause_after(mdev);
+ changes |= _drbd_resume_next(mdev);
+ } while (changes);
}
void drbd_rs_controller_reset(struct drbd_conf *mdev)
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 05/15] drbd: Renamed (old|new)_conf into (old|new)_net_conf in receive_SyncParam
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (3 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 04/15] drbd: Split drbd_alter_sa() into drbd_sync_after_valid() and drbd_sync_after_changed() Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 06/15] drbd: Introduce __s32_field in the genetlink macro magic Philipp Reisner
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Preparing RCU for disk_conf
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, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 23614e4..bba0050 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3146,7 +3146,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
unsigned int header_size, data_size, exp_max_sz;
struct crypto_hash *verify_tfm = NULL;
struct crypto_hash *csums_tfm = NULL;
- struct net_conf *old_conf, *new_conf = NULL;
+ struct net_conf *old_net_conf, *new_net_conf = NULL;
const int apv = tconn->agreed_pro_version;
int *rs_plan_s = NULL;
int fifo_size = 0;
@@ -3222,12 +3222,12 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
}
mutex_lock(&mdev->tconn->conf_update);
- old_conf = mdev->tconn->net_conf;
+ old_net_conf = mdev->tconn->net_conf;
- if (strcmp(old_conf->verify_alg, p->verify_alg)) {
+ if (strcmp(old_net_conf->verify_alg, p->verify_alg)) {
if (mdev->state.conn == C_WF_REPORT_PARAMS) {
dev_err(DEV, "Different verify-alg settings. me=\"%s\" peer=\"%s\"\n",
- old_conf->verify_alg, p->verify_alg);
+ old_net_conf->verify_alg, p->verify_alg);
goto disconnect;
}
verify_tfm = drbd_crypto_alloc_digest_safe(mdev,
@@ -3238,10 +3238,10 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
}
}
- if (apv >= 89 && strcmp(old_conf->csums_alg, p->csums_alg)) {
+ if (apv >= 89 && strcmp(old_net_conf->csums_alg, p->csums_alg)) {
if (mdev->state.conn == C_WF_REPORT_PARAMS) {
dev_err(DEV, "Different csums-alg settings. me=\"%s\" peer=\"%s\"\n",
- old_conf->csums_alg, p->csums_alg);
+ old_net_conf->csums_alg, p->csums_alg);
goto disconnect;
}
csums_tfm = drbd_crypto_alloc_digest_safe(mdev,
@@ -3272,34 +3272,34 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
}
if (verify_tfm || csums_tfm) {
- new_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL);
- if (!new_conf) {
+ new_net_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL);
+ if (!new_net_conf) {
dev_err(DEV, "Allocation of new net_conf failed\n");
goto disconnect;
}
- *new_conf = *old_conf;
+ *new_net_conf = *old_net_conf;
if (verify_tfm) {
- strcpy(new_conf->verify_alg, p->verify_alg);
- new_conf->verify_alg_len = strlen(p->verify_alg) + 1;
+ strcpy(new_net_conf->verify_alg, p->verify_alg);
+ new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1;
crypto_free_hash(mdev->tconn->verify_tfm);
mdev->tconn->verify_tfm = verify_tfm;
dev_info(DEV, "using verify-alg: \"%s\"\n", p->verify_alg);
}
if (csums_tfm) {
- strcpy(new_conf->csums_alg, p->csums_alg);
- new_conf->csums_alg_len = strlen(p->csums_alg) + 1;
+ strcpy(new_net_conf->csums_alg, p->csums_alg);
+ new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1;
crypto_free_hash(mdev->tconn->csums_tfm);
mdev->tconn->csums_tfm = csums_tfm;
dev_info(DEV, "using csums-alg: \"%s\"\n", p->csums_alg);
}
- rcu_assign_pointer(tconn->net_conf, new_conf);
+ rcu_assign_pointer(tconn->net_conf, new_net_conf);
}
mutex_unlock(&mdev->tconn->conf_update);
- if (new_conf) {
+ if (new_net_conf) {
synchronize_rcu();
- kfree(old_conf);
+ kfree(old_net_conf);
}
spin_lock(&mdev->peer_seq_lock);
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 06/15] drbd: Introduce __s32_field in the genetlink macro magic
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (4 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 05/15] drbd: Renamed (old|new)_conf into (old|new)_net_conf in receive_SyncParam Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 07/15] drbd: RCU for disk_conf Philipp Reisner
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Lars Ellenberg <lars.ellenberg@linbit.com>
...and drop explicit typecasts (int)meta_dev_idx < 0.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 8 ++++----
include/linux/drbd_genl.h | 2 +-
include/linux/genl_magic_struct.h | 3 +++
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 4efeffa..84b055f 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1289,7 +1289,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- if ((int)nbc->dc.meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
+ if (nbc->dc.meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
retcode = ERR_MD_IDX_INVALID;
goto fail;
}
@@ -1325,7 +1325,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
*/
bdev = blkdev_get_by_path(nbc->dc.meta_dev,
FMODE_READ | FMODE_WRITE | FMODE_EXCL,
- ((int)nbc->dc.meta_dev_idx < 0) ?
+ (nbc->dc.meta_dev_idx < 0) ?
(void *)mdev : (void *)drbd_m_holder);
if (IS_ERR(bdev)) {
dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
@@ -1361,7 +1361,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- if ((int)nbc->dc.meta_dev_idx < 0) {
+ if (nbc->dc.meta_dev_idx < 0) {
max_possible_sectors = DRBD_MAX_SECTORS_FLEX;
/* at least one MB, otherwise it does not make sense */
min_md_device_sectors = (2<<10);
@@ -1392,7 +1392,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
dev_warn(DEV, "==> truncating very big lower level device "
"to currently maximum possible %llu sectors <==\n",
(unsigned long long) max_possible_sectors);
- if ((int)nbc->dc.meta_dev_idx >= 0)
+ if (nbc->dc.meta_dev_idx >= 0)
dev_warn(DEV, "==>> using internal or flexible "
"meta data may help <<==\n");
}
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 8cad681..529627b 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -104,7 +104,7 @@ GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context,
GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
__str_field(1, GENLA_F_REQUIRED | GENLA_F_INVARIANT, backing_dev, 128)
__str_field(2, GENLA_F_REQUIRED | GENLA_F_INVARIANT, meta_dev, 128)
- __u32_field(3, GENLA_F_REQUIRED | GENLA_F_INVARIANT, meta_dev_idx)
+ __s32_field(3, GENLA_F_REQUIRED | GENLA_F_INVARIANT, meta_dev_idx)
/* use the resize command to try and change the disk_size */
__u64_field(4, GENLA_F_MANDATORY | GENLA_F_INVARIANT, disk_size)
diff --git a/include/linux/genl_magic_struct.h b/include/linux/genl_magic_struct.h
index f2c7cc7..ddbdd0a 100644
--- a/include/linux/genl_magic_struct.h
+++ b/include/linux/genl_magic_struct.h
@@ -97,6 +97,9 @@ enum {
#define __u32_field(attr_nr, attr_flag, name) \
__field(attr_nr, attr_flag, name, NLA_U32, __u32, \
nla_get_u32, NLA_PUT_U32)
+#define __s32_field(attr_nr, attr_flag, name) \
+ __field(attr_nr, attr_flag, name, NLA_U32, __s32, \
+ nla_get_u32, NLA_PUT_U32)
#define __u64_field(attr_nr, attr_flag, name) \
__field(attr_nr, attr_flag, name, NLA_U64, __u64, \
nla_get_u64, NLA_PUT_U64)
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 07/15] drbd: RCU for disk_conf
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (5 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 06/15] drbd: Introduce __s32_field in the genetlink macro magic Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 08/15] drbd: Made the fifo object a self contained object (preparing for RCU) Philipp Reisner
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 54 +++++++++++---
drivers/block/drbd/drbd_main.c | 25 ++++--
drivers/block/drbd/drbd_nl.c | 144 ++++++++++++++++++++++++------------
drivers/block/drbd/drbd_receiver.c | 138 ++++++++++++++++++++++------------
drivers/block/drbd/drbd_state.c | 16 +++-
drivers/block/drbd/drbd_worker.c | 38 +++++++---
6 files changed, 282 insertions(+), 133 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index f8d0ac3..cd77dd4 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -777,7 +777,7 @@ struct drbd_backing_dev {
struct block_device *backing_bdev;
struct block_device *md_bdev;
struct drbd_md md;
- struct disk_conf dc; /* The user provided config... */
+ struct disk_conf *disk_conf; /* RCU, for updates: mdev->tconn->conf_update */
sector_t known_size; /* last known size of that backing device */
};
@@ -1644,8 +1644,13 @@ static inline union drbd_state drbd_read_state(struct drbd_conf *mdev)
#define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__)
static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, const char *where)
{
- switch (mdev->ldev->dc.on_io_error) {
- case EP_PASS_ON:
+ enum drbd_io_error_p ep;
+
+ rcu_read_lock();
+ ep = rcu_dereference(mdev->ldev->disk_conf)->on_io_error;
+ rcu_read_unlock();
+ switch (ep) {
+ case EP_PASS_ON: /* FIXME would this be better named "Ignore"? */
if (!forcedetach) {
if (__ratelimit(&drbd_ratelimit_state))
dev_err(DEV, "Local IO failed in %s.\n", where);
@@ -1694,9 +1699,9 @@ static inline void drbd_chk_io_error_(struct drbd_conf *mdev,
* BTW, for internal meta data, this happens to be the maximum capacity
* we could agree upon with our peer node.
*/
-static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev)
+static inline sector_t _drbd_md_first_sector(int meta_dev_idx, struct drbd_backing_dev *bdev)
{
- switch (bdev->dc.meta_dev_idx) {
+ switch (meta_dev_idx) {
case DRBD_MD_INDEX_INTERNAL:
case DRBD_MD_INDEX_FLEX_INT:
return bdev->md.md_offset + bdev->md.bm_offset;
@@ -1706,13 +1711,30 @@ static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev)
}
}
+static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev)
+{
+ int meta_dev_idx;
+
+ rcu_read_lock();
+ meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx;
+ rcu_read_unlock();
+
+ return _drbd_md_first_sector(meta_dev_idx, bdev);
+}
+
/**
* drbd_md_last_sector() - Return the last sector number of the meta data area
* @bdev: Meta data block device.
*/
static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev)
{
- switch (bdev->dc.meta_dev_idx) {
+ int meta_dev_idx;
+
+ rcu_read_lock();
+ meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx;
+ rcu_read_unlock();
+
+ switch (meta_dev_idx) {
case DRBD_MD_INDEX_INTERNAL:
case DRBD_MD_INDEX_FLEX_INT:
return bdev->md.md_offset + MD_AL_OFFSET - 1;
@@ -1740,12 +1762,18 @@ static inline sector_t drbd_get_capacity(struct block_device *bdev)
static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev)
{
sector_t s;
- switch (bdev->dc.meta_dev_idx) {
+ int meta_dev_idx;
+
+ rcu_read_lock();
+ meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx;
+ rcu_read_unlock();
+
+ switch (meta_dev_idx) {
case DRBD_MD_INDEX_INTERNAL:
case DRBD_MD_INDEX_FLEX_INT:
s = drbd_get_capacity(bdev->backing_bdev)
? min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
- drbd_md_first_sector(bdev))
+ _drbd_md_first_sector(meta_dev_idx, bdev))
: 0;
break;
case DRBD_MD_INDEX_FLEX_EXT:
@@ -1771,9 +1799,15 @@ static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev)
static inline sector_t drbd_md_ss__(struct drbd_conf *mdev,
struct drbd_backing_dev *bdev)
{
- switch (bdev->dc.meta_dev_idx) {
+ int meta_dev_idx;
+
+ rcu_read_lock();
+ meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx;
+ rcu_read_unlock();
+
+ switch (meta_dev_idx) {
default: /* external, some index */
- return MD_RESERVED_SECT * bdev->dc.meta_dev_idx;
+ return MD_RESERVED_SECT * meta_dev_idx;
case DRBD_MD_INDEX_INTERNAL:
/* with drbd08, internal meta data is always "flexible" */
case DRBD_MD_INDEX_FLEX_INT:
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 352c36f..32ebedb 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -866,6 +866,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev)
const int apv = mdev->tconn->agreed_pro_version;
enum drbd_packet cmd;
struct net_conf *nc;
+ struct disk_conf *dc;
sock = &mdev->tconn->data;
p = drbd_prepare_command(mdev, sock);
@@ -887,11 +888,12 @@ int drbd_send_sync_param(struct drbd_conf *mdev)
memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
if (get_ldev(mdev)) {
- p->rate = cpu_to_be32(mdev->ldev->dc.resync_rate);
- p->c_plan_ahead = cpu_to_be32(mdev->ldev->dc.c_plan_ahead);
- p->c_delay_target = cpu_to_be32(mdev->ldev->dc.c_delay_target);
- p->c_fill_target = cpu_to_be32(mdev->ldev->dc.c_fill_target);
- p->c_max_rate = cpu_to_be32(mdev->ldev->dc.c_max_rate);
+ dc = rcu_dereference(mdev->ldev->disk_conf);
+ p->rate = cpu_to_be32(dc->resync_rate);
+ p->c_plan_ahead = cpu_to_be32(dc->c_plan_ahead);
+ p->c_delay_target = cpu_to_be32(dc->c_delay_target);
+ p->c_fill_target = cpu_to_be32(dc->c_fill_target);
+ p->c_max_rate = cpu_to_be32(dc->c_max_rate);
put_ldev(mdev);
} else {
p->rate = cpu_to_be32(DRBD_RATE_DEF);
@@ -1056,7 +1058,9 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl
if (get_ldev_if_state(mdev, D_NEGOTIATING)) {
D_ASSERT(mdev->ldev->backing_bdev);
d_size = drbd_get_max_capacity(mdev->ldev);
- u_size = mdev->ldev->dc.disk_size;
+ rcu_read_lock();
+ u_size = rcu_dereference(mdev->ldev->disk_conf)->disk_size;
+ rcu_read_unlock();
q_order_type = drbd_queue_order_type(mdev);
max_bio_size = queue_max_hw_sectors(mdev->ldev->backing_bdev->bd_disk->queue) << 9;
max_bio_size = min_t(int, max_bio_size, DRBD_MAX_BIO_SIZE);
@@ -2889,7 +2893,6 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
for (i = UI_CURRENT; i < UI_SIZE; i++)
bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]);
bdev->md.flags = be32_to_cpu(buffer->flags);
- bdev->dc.al_extents = be32_to_cpu(buffer->al_nr_extents);
bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
spin_lock_irq(&mdev->tconn->req_lock);
@@ -2901,8 +2904,12 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
}
spin_unlock_irq(&mdev->tconn->req_lock);
- if (bdev->dc.al_extents < 7)
- bdev->dc.al_extents = 127;
+ mutex_lock(&mdev->tconn->conf_update);
+ /* This blocks wants to be get removed... */
+ bdev->disk_conf->al_extents = be32_to_cpu(buffer->al_nr_extents);
+ if (bdev->disk_conf->al_extents < DRBD_AL_EXTENTS_MIN)
+ bdev->disk_conf->al_extents = DRBD_AL_EXTENTS_DEF;
+ mutex_unlock(&mdev->tconn->conf_update);
err:
mutex_unlock(&mdev->md_io_mutex);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 84b055f..a7d4c0e 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -419,7 +419,8 @@ static enum drbd_fencing_p highest_fencing_policy(struct drbd_tconn *tconn)
rcu_read_lock();
idr_for_each_entry(&tconn->volumes, mdev, vnr) {
if (get_ldev_if_state(mdev, D_CONSISTENT)) {
- fp = max_t(enum drbd_fencing_p, fp, mdev->ldev->dc.fencing);
+ fp = max_t(enum drbd_fencing_p, fp,
+ rcu_dereference(mdev->ldev->disk_conf)->fencing);
put_ldev(mdev);
}
}
@@ -700,7 +701,12 @@ static void drbd_md_set_sector_offsets(struct drbd_conf *mdev,
struct drbd_backing_dev *bdev)
{
sector_t md_size_sect = 0;
- switch (bdev->dc.meta_dev_idx) {
+ int meta_dev_idx;
+
+ rcu_read_lock();
+ meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx;
+
+ switch (meta_dev_idx) {
default:
/* v07 style fixed size indexed meta data */
bdev->md.md_size_sect = MD_RESERVED_SECT;
@@ -735,6 +741,7 @@ static void drbd_md_set_sector_offsets(struct drbd_conf *mdev,
bdev->md.bm_offset = -md_size_sect + MD_AL_OFFSET;
break;
}
+ rcu_read_unlock();
}
/* input size is expected to be in KB */
@@ -825,7 +832,9 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds
/* TODO: should only be some assert here, not (re)init... */
drbd_md_set_sector_offsets(mdev, mdev->ldev);
- u_size = mdev->ldev->dc.disk_size;
+ rcu_read_lock();
+ u_size = rcu_dereference(mdev->ldev->disk_conf)->disk_size;
+ rcu_read_unlock();
size = drbd_new_dev_size(mdev, mdev->ldev, u_size, flags & DDSF_FORCED);
if (drbd_get_capacity(mdev->this_bdev) != size ||
@@ -1001,7 +1010,9 @@ static void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_
struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue;
max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9);
- max_segments = mdev->ldev->dc.max_bio_bvecs;
+ rcu_read_lock();
+ max_segments = rcu_dereference(mdev->ldev->disk_conf)->max_bio_bvecs;
+ rcu_read_unlock();
put_ldev(mdev);
}
@@ -1117,7 +1128,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 *new_disk_conf;
+ struct disk_conf *new_disk_conf, *old_disk_conf;
int err, fifo_size;
int *rs_plan_s = NULL;
@@ -1150,19 +1161,15 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
goto out;
}
-/* FIXME freeze IO, cluster wide.
- *
- * We should make sure no-one uses
- * some half-updated struct when we
- * assign it later. */
-
- new_disk_conf = kmalloc(sizeof(*new_disk_conf), GFP_KERNEL);
+ new_disk_conf = kmalloc(sizeof(struct disk_conf), GFP_KERNEL);
if (!new_disk_conf) {
retcode = ERR_NOMEM;
goto fail;
}
- memcpy(new_disk_conf, &mdev->ldev->dc, sizeof(*new_disk_conf));
+ mutex_lock(&mdev->tconn->conf_update);
+ old_disk_conf = mdev->ldev->disk_conf;
+ *new_disk_conf = *old_disk_conf;
if (should_set_defaults(info))
set_disk_conf_defaults(new_disk_conf);
@@ -1187,7 +1194,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
if (!rs_plan_s) {
dev_err(DEV, "kmalloc of fifo_buffer failed");
retcode = ERR_NOMEM;
- goto fail;
+ goto fail_unlock;
}
}
@@ -1207,31 +1214,37 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
if (err) {
retcode = ERR_NOMEM;
- goto fail;
+ goto fail_unlock;
}
- /* FIXME
- * To avoid someone looking at a half-updated struct, we probably
- * should have a rw-semaphor on net_conf and disk_conf.
- */
write_lock_irq(&global_state_lock);
retcode = drbd_sync_after_valid(mdev, new_disk_conf->resync_after);
if (retcode == NO_ERROR) {
- mdev->ldev->dc = *new_disk_conf;
+ rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf);
drbd_sync_after_changed(mdev);
}
write_unlock_irq(&global_state_lock);
- drbd_md_sync(mdev);
+ if (retcode != NO_ERROR)
+ goto fail_unlock;
+ drbd_md_sync(mdev);
if (mdev->state.conn >= C_CONNECTED)
drbd_send_sync_param(mdev);
+ mutex_unlock(&mdev->tconn->conf_update);
+ synchronize_rcu();
+ kfree(old_disk_conf);
+ goto success;
+
+fail_unlock:
+ mutex_unlock(&mdev->tconn->conf_update);
fail:
- put_ldev(mdev);
kfree(new_disk_conf);
kfree(rs_plan_s);
+success:
+ put_ldev(mdev);
out:
drbd_adm_finish(info, retcode);
return 0;
@@ -1246,6 +1259,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
sector_t max_possible_sectors;
sector_t min_md_device_sectors;
struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
+ struct disk_conf *new_disk_conf = NULL;
struct block_device *bdev;
struct lru_cache *resync_lru = NULL;
union drbd_state ns, os;
@@ -1279,17 +1293,22 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
retcode = ERR_NOMEM;
goto fail;
}
+ new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
+ if (!new_disk_conf) {
+ retcode = ERR_NOMEM;
+ goto fail;
+ }
+ nbc->disk_conf = new_disk_conf;
- set_disk_conf_defaults(&nbc->dc);
-
- err = disk_conf_from_attrs(&nbc->dc, info);
+ set_disk_conf_defaults(new_disk_conf);
+ 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));
goto fail;
}
- if (nbc->dc.meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
+ if (new_disk_conf->meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
retcode = ERR_MD_IDX_INVALID;
goto fail;
}
@@ -1297,7 +1316,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
rcu_read_lock();
nc = rcu_dereference(mdev->tconn->net_conf);
if (nc) {
- if (nbc->dc.fencing == FP_STONITH && nc->wire_protocol == DRBD_PROT_A) {
+ if (new_disk_conf->fencing == FP_STONITH && nc->wire_protocol == DRBD_PROT_A) {
rcu_read_unlock();
retcode = ERR_STONITH_AND_PROT_A;
goto fail;
@@ -1305,10 +1324,10 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
}
rcu_read_unlock();
- bdev = blkdev_get_by_path(nbc->dc.backing_dev,
+ bdev = blkdev_get_by_path(new_disk_conf->backing_dev,
FMODE_READ | FMODE_WRITE | FMODE_EXCL, mdev);
if (IS_ERR(bdev)) {
- dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
+ dev_err(DEV, "open(\"%s\") failed with %ld\n", new_disk_conf->backing_dev,
PTR_ERR(bdev));
retcode = ERR_OPEN_DISK;
goto fail;
@@ -1323,12 +1342,12 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
* should check it for you already; but if you don't, or
* someone fooled it, we need to double check here)
*/
- bdev = blkdev_get_by_path(nbc->dc.meta_dev,
+ bdev = blkdev_get_by_path(new_disk_conf->meta_dev,
FMODE_READ | FMODE_WRITE | FMODE_EXCL,
- (nbc->dc.meta_dev_idx < 0) ?
+ (new_disk_conf->meta_dev_idx < 0) ?
(void *)mdev : (void *)drbd_m_holder);
if (IS_ERR(bdev)) {
- dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
+ dev_err(DEV, "open(\"%s\") failed with %ld\n", new_disk_conf->meta_dev,
PTR_ERR(bdev));
retcode = ERR_OPEN_MD_DISK;
goto fail;
@@ -1336,8 +1355,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
nbc->md_bdev = bdev;
if ((nbc->backing_bdev == nbc->md_bdev) !=
- (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
- nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
+ (new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
+ new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
retcode = ERR_MD_IDX_INVALID;
goto fail;
}
@@ -1353,21 +1372,21 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
/* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */
drbd_md_set_sector_offsets(mdev, nbc);
- if (drbd_get_max_capacity(nbc) < nbc->dc.disk_size) {
+ if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) {
dev_err(DEV, "max capacity %llu smaller than disk size %llu\n",
(unsigned long long) drbd_get_max_capacity(nbc),
- (unsigned long long) nbc->dc.disk_size);
+ (unsigned long long) new_disk_conf->disk_size);
retcode = ERR_DISK_TO_SMALL;
goto fail;
}
- if (nbc->dc.meta_dev_idx < 0) {
+ if (new_disk_conf->meta_dev_idx < 0) {
max_possible_sectors = DRBD_MAX_SECTORS_FLEX;
/* at least one MB, otherwise it does not make sense */
min_md_device_sectors = (2<<10);
} else {
max_possible_sectors = DRBD_MAX_SECTORS;
- min_md_device_sectors = MD_RESERVED_SECT * (nbc->dc.meta_dev_idx + 1);
+ min_md_device_sectors = MD_RESERVED_SECT * (new_disk_conf->meta_dev_idx + 1);
}
if (drbd_get_capacity(nbc->md_bdev) < min_md_device_sectors) {
@@ -1392,7 +1411,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
dev_warn(DEV, "==> truncating very big lower level device "
"to currently maximum possible %llu sectors <==\n",
(unsigned long long) max_possible_sectors);
- if (nbc->dc.meta_dev_idx >= 0)
+ if (new_disk_conf->meta_dev_idx >= 0)
dev_warn(DEV, "==>> using internal or flexible "
"meta data may help <<==\n");
}
@@ -1435,14 +1454,14 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
}
/* Since we are diskless, fix the activity log first... */
- if (drbd_check_al_size(mdev, &nbc->dc)) {
+ if (drbd_check_al_size(mdev, new_disk_conf)) {
retcode = ERR_NOMEM;
goto force_diskless_dec;
}
/* Prevent shrinking of consistent devices ! */
if (drbd_md_test_flag(nbc, MDF_CONSISTENT) &&
- drbd_new_dev_size(mdev, nbc, nbc->dc.disk_size, 0) < nbc->md.la_size_sect) {
+ drbd_new_dev_size(mdev, nbc, nbc->disk_conf->disk_size, 0) < nbc->md.la_size_sect) {
dev_warn(DEV, "refusing to truncate a consistent device\n");
retcode = ERR_DISK_TO_SMALL;
goto force_diskless_dec;
@@ -1455,11 +1474,13 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
/* Reset the "barriers don't work" bits here, then force meta data to
* be written, to ensure we determine if barriers are supported. */
- if (nbc->dc.no_md_flush)
+ if (new_disk_conf->no_md_flush)
set_bit(MD_NO_FUA, &mdev->flags);
else
clear_bit(MD_NO_FUA, &mdev->flags);
+ /* FIXME Missing stuff: rs_plan_s, clip al range */
+
/* Point of no return reached.
* Devices and memory are no longer released by error cleanup below.
* now mdev takes over responsibility, and the state engine should
@@ -1469,6 +1490,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
mdev->resync = resync_lru;
nbc = NULL;
resync_lru = NULL;
+ new_disk_conf = NULL;
mdev->write_ordering = WO_bdev_flush;
drbd_bump_write_ordering(mdev, WO_bdev_flush);
@@ -1566,9 +1588,11 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
if (drbd_md_test_flag(mdev->ldev, MDF_PEER_OUT_DATED))
ns.pdsk = D_OUTDATED;
- if ( ns.disk == D_CONSISTENT &&
- (ns.pdsk == D_OUTDATED || mdev->ldev->dc.fencing == FP_DONT_CARE))
+ rcu_read_lock();
+ if (ns.disk == D_CONSISTENT &&
+ (ns.pdsk == D_OUTDATED || rcu_dereference(mdev->ldev->disk_conf)->fencing == FP_DONT_CARE))
ns.disk = D_UP_TO_DATE;
+ rcu_read_unlock();
/* All tests on MDF_PRIMARY_IND, MDF_CONNECTED_IND,
MDF_CONSISTENT and MDF_WAS_UP_TO_DATE must happen before
@@ -1625,6 +1649,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
FMODE_READ | FMODE_WRITE | FMODE_EXCL);
kfree(nbc);
}
+ kfree(new_disk_conf);
lc_destroy(resync_lru);
finish:
@@ -1727,7 +1752,7 @@ _check_net_options(struct drbd_tconn *tconn, struct net_conf *old_conf, struct n
idr_for_each_entry(&tconn->volumes, mdev, i) {
if (get_ldev(mdev)) {
- enum drbd_fencing_p fp = mdev->ldev->dc.fencing;
+ enum drbd_fencing_p fp = rcu_dereference(mdev->ldev->disk_conf)->fencing;
put_ldev(mdev);
if (new_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH)
return ERR_STONITH_AND_PROT_A;
@@ -2204,11 +2229,13 @@ void resync_after_online_grow(struct drbd_conf *mdev)
int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
{
+ struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
struct resize_parms rs;
struct drbd_conf *mdev;
enum drbd_ret_code retcode;
enum determine_dev_size dd;
enum dds_flags ddsf;
+ sector_t u_size;
int err;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
@@ -2249,10 +2276,31 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
+ rcu_read_lock();
+ u_size = rcu_dereference(mdev->ldev->disk_conf)->disk_size;
+ rcu_read_unlock();
+ if (u_size != (sector_t)rs.resize_size) {
+ new_disk_conf = kmalloc(sizeof(struct disk_conf), GFP_KERNEL);
+ if (!new_disk_conf) {
+ retcode = ERR_NOMEM;
+ goto fail;
+ }
+ }
+
if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev))
mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev);
- mdev->ldev->dc.disk_size = (sector_t)rs.resize_size;
+ if (new_disk_conf) {
+ mutex_lock(&mdev->tconn->conf_update);
+ old_disk_conf = mdev->ldev->disk_conf;
+ *new_disk_conf = *old_disk_conf;
+ new_disk_conf->disk_size = (sector_t)rs.resize_size;
+ rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf);
+ mutex_unlock(&mdev->tconn->conf_update);
+ synchronize_rcu();
+ kfree(old_disk_conf);
+ }
+
ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0);
dd = drbd_determine_dev_size(mdev, ddsf);
drbd_md_sync(mdev);
@@ -2546,11 +2594,11 @@ int nla_put_status_info(struct sk_buff *skb, struct drbd_conf *mdev,
if (res_opts_to_skb(skb, &mdev->tconn->res_opts, exclude_sensitive))
goto nla_put_failure;
+ rcu_read_lock();
if (got_ldev)
- if (disk_conf_to_skb(skb, &mdev->ldev->dc, exclude_sensitive))
+ if (disk_conf_to_skb(skb, rcu_dereference(mdev->ldev->disk_conf), exclude_sensitive))
goto nla_put_failure;
- rcu_read_lock();
nc = rcu_dereference(mdev->tconn->net_conf);
if (nc)
err = net_conf_to_skb(skb, nc, exclude_sensitive);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index bba0050..add4176 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1166,6 +1166,7 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
*/
void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) __must_hold(local)
{
+ struct disk_conf *dc;
enum write_ordering_e pwo;
static char *write_ordering_str[] = {
[WO_none] = "none",
@@ -1175,10 +1176,14 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
pwo = mdev->write_ordering;
wo = min(pwo, wo);
- if (wo == WO_bdev_flush && mdev->ldev->dc.no_disk_flush)
+ rcu_read_lock();
+ dc = rcu_dereference(mdev->ldev->disk_conf);
+
+ if (wo == WO_bdev_flush && dc->no_disk_flush)
wo = WO_drain_io;
- if (wo == WO_drain_io && mdev->ldev->dc.no_disk_drain)
+ if (wo == WO_drain_io && dc->no_disk_drain)
wo = WO_none;
+ rcu_read_unlock();
mdev->write_ordering = wo;
if (pwo != mdev->write_ordering || wo == WO_bdev_flush)
dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]);
@@ -2190,9 +2195,14 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector)
struct lc_element *tmp;
int curr_events;
int throttle = 0;
+ unsigned int c_min_rate;
+
+ rcu_read_lock();
+ c_min_rate = rcu_dereference(mdev->ldev->disk_conf)->c_min_rate;
+ rcu_read_unlock();
/* feature disabled? */
- if (mdev->ldev->dc.c_min_rate == 0)
+ if (c_min_rate == 0)
return 0;
spin_lock_irq(&mdev->al_lock);
@@ -2232,7 +2242,7 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector)
db = mdev->rs_mark_left[i] - rs_left;
dbdt = Bit2KB(db/dt);
- if (dbdt > mdev->ldev->dc.c_min_rate)
+ if (dbdt > c_min_rate)
throttle = 1;
}
return throttle;
@@ -3147,6 +3157,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
struct crypto_hash *verify_tfm = NULL;
struct crypto_hash *csums_tfm = NULL;
struct net_conf *old_net_conf, *new_net_conf = NULL;
+ struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
const int apv = tconn->agreed_pro_version;
int *rs_plan_s = NULL;
int fifo_size = 0;
@@ -3189,24 +3200,34 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
if (err)
return err;
- if (get_ldev(mdev)) {
- mdev->ldev->dc.resync_rate = be32_to_cpu(p->rate);
- put_ldev(mdev);
+ new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
+ if (!new_disk_conf) {
+ dev_err(DEV, "Allocation of new disk_conf failed\n");
+ return -ENOMEM;
}
+ mutex_lock(&mdev->tconn->conf_update);
+ old_net_conf = mdev->tconn->net_conf;
+ old_disk_conf = mdev->ldev->disk_conf;
+ *new_disk_conf = *old_disk_conf;
+
+ new_disk_conf->resync_rate = be32_to_cpu(p->rate);
+
if (apv >= 88) {
if (apv == 88) {
if (data_size > SHARED_SECRET_MAX) {
dev_err(DEV, "verify-alg too long, "
"peer wants %u, accepting only %u byte\n",
data_size, SHARED_SECRET_MAX);
+ mutex_unlock(&mdev->tconn->conf_update);
return -EIO;
}
err = drbd_recv_all(mdev->tconn, p->verify_alg, data_size);
- if (err)
+ if (err) {
+ mutex_unlock(&mdev->tconn->conf_update);
return err;
-
+ }
/* we expect NUL terminated string */
/* but just in case someone tries to be evil */
D_ASSERT(p->verify_alg[data_size-1] == 0);
@@ -3221,9 +3242,6 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
p->csums_alg[SHARED_SECRET_MAX-1] = 0;
}
- mutex_lock(&mdev->tconn->conf_update);
- old_net_conf = mdev->tconn->net_conf;
-
if (strcmp(old_net_conf->verify_alg, p->verify_alg)) {
if (mdev->state.conn == C_WF_REPORT_PARAMS) {
dev_err(DEV, "Different verify-alg settings. me=\"%s\" peer=\"%s\"\n",
@@ -3252,14 +3270,13 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
}
}
- if (apv > 94 && get_ldev(mdev)) {
- mdev->ldev->dc.resync_rate = be32_to_cpu(p->rate);
- mdev->ldev->dc.c_plan_ahead = be32_to_cpu(p->c_plan_ahead);
- mdev->ldev->dc.c_delay_target = be32_to_cpu(p->c_delay_target);
- mdev->ldev->dc.c_fill_target = be32_to_cpu(p->c_fill_target);
- mdev->ldev->dc.c_max_rate = be32_to_cpu(p->c_max_rate);
+ if (apv > 94) {
+ new_disk_conf->c_plan_ahead = be32_to_cpu(p->c_plan_ahead);
+ new_disk_conf->c_delay_target = be32_to_cpu(p->c_delay_target);
+ new_disk_conf->c_fill_target = be32_to_cpu(p->c_fill_target);
+ new_disk_conf->c_max_rate = be32_to_cpu(p->c_max_rate);
- fifo_size = (mdev->ldev->dc.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) {
@@ -3268,7 +3285,6 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
goto disconnect;
}
}
- put_ldev(mdev);
}
if (verify_tfm || csums_tfm) {
@@ -3296,21 +3312,24 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
}
rcu_assign_pointer(tconn->net_conf, new_net_conf);
}
- mutex_unlock(&mdev->tconn->conf_update);
- if (new_net_conf) {
- synchronize_rcu();
- kfree(old_net_conf);
- }
+ }
- spin_lock(&mdev->peer_seq_lock);
- if (fifo_size != mdev->rs_plan_s.size) {
- kfree(mdev->rs_plan_s.values);
- mdev->rs_plan_s.values = rs_plan_s;
- mdev->rs_plan_s.size = fifo_size;
- mdev->rs_planed = 0;
- }
- spin_unlock(&mdev->peer_seq_lock);
+ rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf);
+ spin_lock(&mdev->peer_seq_lock);
+ if (rs_plan_s) {
+ kfree(mdev->rs_plan_s.values);
+ mdev->rs_plan_s.values = rs_plan_s;
+ mdev->rs_plan_s.size = fifo_size;
+ mdev->rs_planed = 0;
}
+ spin_unlock(&mdev->peer_seq_lock);
+
+ mutex_unlock(&mdev->tconn->conf_update);
+ synchronize_rcu();
+ if (new_net_conf)
+ kfree(old_net_conf);
+ kfree(old_disk_conf);
+
return 0;
disconnect:
@@ -3358,37 +3377,56 @@ static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi)
mdev->p_size = p_size;
if (get_ldev(mdev)) {
+ rcu_read_lock();
+ my_usize = rcu_dereference(mdev->ldev->disk_conf)->disk_size;
+ rcu_read_unlock();
+
warn_if_differ_considerably(mdev, "lower level device sizes",
p_size, drbd_get_max_capacity(mdev->ldev));
warn_if_differ_considerably(mdev, "user requested size",
- p_usize, mdev->ldev->dc.disk_size);
+ p_usize, my_usize);
/* if this is the first connect, or an otherwise expected
* param exchange, choose the minimum */
if (mdev->state.conn == C_WF_REPORT_PARAMS)
- p_usize = min_not_zero((sector_t)mdev->ldev->dc.disk_size,
- p_usize);
-
- my_usize = mdev->ldev->dc.disk_size;
-
- if (mdev->ldev->dc.disk_size != p_usize) {
- mdev->ldev->dc.disk_size = p_usize;
- dev_info(DEV, "Peer sets u_size to %lu sectors\n",
- (unsigned long)mdev->ldev->dc.disk_size);
- }
+ p_usize = min_not_zero(my_usize, p_usize);
/* Never shrink a device with usable data during connect.
But allow online shrinking if we are connected. */
if (drbd_new_dev_size(mdev, mdev->ldev, p_usize, 0) <
- drbd_get_capacity(mdev->this_bdev) &&
- mdev->state.disk >= D_OUTDATED &&
- mdev->state.conn < C_CONNECTED) {
+ drbd_get_capacity(mdev->this_bdev) &&
+ mdev->state.disk >= D_OUTDATED &&
+ mdev->state.conn < C_CONNECTED) {
dev_err(DEV, "The peer's disk size is too small!\n");
conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD);
- mdev->ldev->dc.disk_size = my_usize;
put_ldev(mdev);
return -EIO;
}
+
+ if (my_usize != p_usize) {
+ struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
+
+ new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
+ if (!new_disk_conf) {
+ dev_err(DEV, "Allocation of new disk_conf failed\n");
+ put_ldev(mdev);
+ return -ENOMEM;
+ }
+
+ mutex_lock(&mdev->tconn->conf_update);
+ old_disk_conf = mdev->ldev->disk_conf;
+ *new_disk_conf = *old_disk_conf;
+ new_disk_conf->disk_size = p_usize;
+
+ rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf);
+ mutex_unlock(&mdev->tconn->conf_update);
+ synchronize_rcu();
+ kfree(old_disk_conf);
+
+ dev_info(DEV, "Peer sets u_size to %lu sectors\n",
+ (unsigned long)my_usize);
+ }
+
put_ldev(mdev);
}
@@ -4268,7 +4306,9 @@ static int drbd_disconnected(int vnr, void *p, void *data)
fp = FP_DONT_CARE;
if (get_ldev(mdev)) {
- fp = mdev->ldev->dc.fencing;
+ rcu_read_lock();
+ fp = rcu_dereference(mdev->ldev->disk_conf)->fencing;
+ rcu_read_unlock();
put_ldev(mdev);
}
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index befaf07..3f65365 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -465,13 +465,13 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
enum drbd_state_rv rv = SS_SUCCESS;
struct net_conf *nc;
+ rcu_read_lock();
fp = FP_DONT_CARE;
if (get_ldev(mdev)) {
- fp = mdev->ldev->dc.fencing;
+ fp = rcu_dereference(mdev->ldev->disk_conf)->fencing;
put_ldev(mdev);
}
- rcu_read_lock();
nc = rcu_dereference(mdev->tconn->net_conf);
if (nc) {
if (!nc->two_primaries && ns.role == R_PRIMARY) {
@@ -656,7 +656,9 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
fp = FP_DONT_CARE;
if (get_ldev(mdev)) {
- fp = mdev->ldev->dc.fencing;
+ rcu_read_lock();
+ fp = rcu_dereference(mdev->ldev->disk_conf)->fencing;
+ rcu_read_unlock();
put_ldev(mdev);
}
@@ -1114,7 +1116,9 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
fp = FP_DONT_CARE;
if (get_ldev(mdev)) {
- fp = mdev->ldev->dc.fencing;
+ rcu_read_lock();
+ fp = rcu_dereference(mdev->ldev->disk_conf)->fencing;
+ rcu_read_unlock();
put_ldev(mdev);
}
@@ -1269,7 +1273,9 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
/* corresponding get_ldev was in __drbd_set_state, to serialize
* our cleanup here with the transition to D_DISKLESS,
* so it is safe to dreference ldev here. */
- eh = mdev->ldev->dc.on_io_error;
+ rcu_read_lock();
+ eh = rcu_dereference(mdev->ldev->disk_conf)->on_io_error;
+ rcu_read_unlock();
was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags);
/* current state still has to be D_FAILED,
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index f8fdf75..840e787 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -436,6 +436,7 @@ static void fifo_add_val(struct fifo_buffer *fb, int value)
static int drbd_rs_controller(struct drbd_conf *mdev)
{
+ struct disk_conf *dc;
unsigned int sect_in; /* Number of sectors that came in since the last turn */
unsigned int want; /* The number of sectors we want in the proxy */
int req_sect; /* Number of sectors to request in this turn */
@@ -449,14 +450,16 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
mdev->rs_in_flight -= sect_in;
spin_lock(&mdev->peer_seq_lock); /* get an atomic view on mdev->rs_plan_s */
+ rcu_read_lock();
+ dc = rcu_dereference(mdev->ldev->disk_conf);
- steps = mdev->rs_plan_s.size; /* (mdev->ldev->dc.c_plan_ahead * 10 * SLEEP_TIME) / HZ; */
+ steps = mdev->rs_plan_s.size; /* (dc->c_plan_ahead * 10 * SLEEP_TIME) / HZ; */
if (mdev->rs_in_flight + sect_in == 0) { /* At start of resync */
- want = ((mdev->ldev->dc.resync_rate * 2 * SLEEP_TIME) / HZ) * steps;
+ want = ((dc->resync_rate * 2 * SLEEP_TIME) / HZ) * steps;
} else { /* normal path */
- want = mdev->ldev->dc.c_fill_target ? mdev->ldev->dc.c_fill_target :
- sect_in * mdev->ldev->dc.c_delay_target * HZ / (SLEEP_TIME * 10);
+ want = dc->c_fill_target ? dc->c_fill_target :
+ sect_in * dc->c_delay_target * HZ / (SLEEP_TIME * 10);
}
correction = want - mdev->rs_in_flight - mdev->rs_planed;
@@ -468,14 +471,13 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
/* What we do in this step */
curr_corr = fifo_push(&mdev->rs_plan_s, 0);
- spin_unlock(&mdev->peer_seq_lock);
mdev->rs_planed -= curr_corr;
req_sect = sect_in + curr_corr;
if (req_sect < 0)
req_sect = 0;
- max_sect = (mdev->ldev->dc.c_max_rate * 2 * SLEEP_TIME) / HZ;
+ max_sect = (dc->c_max_rate * 2 * SLEEP_TIME) / HZ;
if (req_sect > max_sect)
req_sect = max_sect;
@@ -484,6 +486,8 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
sect_in, mdev->rs_in_flight, want, correction,
steps, cps, mdev->rs_planed, curr_corr, req_sect);
*/
+ rcu_read_unlock();
+ spin_unlock(&mdev->peer_seq_lock);
return req_sect;
}
@@ -491,11 +495,13 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
static int drbd_rs_number_requests(struct drbd_conf *mdev)
{
int number;
- if (mdev->rs_plan_s.size) { /* mdev->ldev->dc.c_plan_ahead */
+ if (mdev->rs_plan_s.size) { /* rcu_dereference(mdev->ldev->disk_conf)->c_plan_ahead */
number = drbd_rs_controller(mdev) >> (BM_BLOCK_SHIFT - 9);
mdev->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME;
} else {
- mdev->c_sync_rate = mdev->ldev->dc.resync_rate;
+ rcu_read_lock();
+ mdev->c_sync_rate = rcu_dereference(mdev->ldev->disk_conf)->resync_rate;
+ rcu_read_unlock();
number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ);
}
@@ -1320,13 +1326,17 @@ int w_restart_disk_io(struct drbd_work *w, int cancel)
static int _drbd_may_sync_now(struct drbd_conf *mdev)
{
struct drbd_conf *odev = mdev;
+ int ra;
while (1) {
if (!odev->ldev)
return 1;
- if (odev->ldev->dc.resync_after == -1)
+ rcu_read_lock();
+ ra = rcu_dereference(odev->ldev->disk_conf)->resync_after;
+ rcu_read_unlock();
+ if (ra == -1)
return 1;
- odev = minor_to_mdev(odev->ldev->dc.resync_after);
+ odev = minor_to_mdev(ra);
if (!expect(odev))
return 1;
if ((odev->state.conn >= C_SYNC_SOURCE &&
@@ -1405,6 +1415,7 @@ void suspend_other_sg(struct drbd_conf *mdev)
enum drbd_ret_code drbd_sync_after_valid(struct drbd_conf *mdev, int o_minor)
{
struct drbd_conf *odev;
+ int ra;
if (o_minor == -1)
return NO_ERROR;
@@ -1417,12 +1428,15 @@ enum drbd_ret_code drbd_sync_after_valid(struct drbd_conf *mdev, int o_minor)
if (odev == mdev)
return ERR_SYNC_AFTER_CYCLE;
+ rcu_read_lock();
+ ra = rcu_dereference(odev->ldev->disk_conf)->resync_after;
+ rcu_read_unlock();
/* dependency chain ends here, no cycles. */
- if (odev->ldev->dc.resync_after == -1)
+ if (ra == -1)
return NO_ERROR;
/* follow the dependency chain */
- odev = minor_to_mdev(odev->ldev->dc.resync_after);
+ odev = minor_to_mdev(ra);
}
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 08/15] drbd: Made the fifo object a self contained object (preparing for RCU)
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (6 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 07/15] drbd: RCU for disk_conf Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 09/15] drbd: Enforce limits of disk_conf members; centralized these checks Philipp Reisner
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
* Moved rs_planed into it, named total
* When having a pointer to the object the values can
be embedded into the fifo object.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_int.h | 7 ++++---
drivers/block/drbd/drbd_main.c | 1 +
drivers/block/drbd/drbd_nl.c | 34 ++++++++++++++++++++++------------
drivers/block/drbd/drbd_receiver.c | 13 ++++++-------
drivers/block/drbd/drbd_worker.c | 33 ++++++++++++++++++++++++---------
5 files changed, 57 insertions(+), 31 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index cd77dd4..2ecee6c 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -802,10 +802,12 @@ enum write_ordering_e {
};
struct fifo_buffer {
- int *values;
unsigned int head_index;
unsigned int size;
+ int total; /* sum of all values */
+ int values[0];
};
+extern struct fifo_buffer *fifo_alloc(int fifo_size);
/* flag bits per tconn */
enum {
@@ -996,9 +998,8 @@ struct drbd_conf {
int rs_last_events; /* counter of read or write "events" (unit sectors)
* on the lower level device when we last looked. */
int c_sync_rate; /* current resync rate after syncer throttle magic */
- struct fifo_buffer rs_plan_s; /* correction values of resync planer */
+ struct fifo_buffer *rs_plan_s; /* correction values of resync planer */
int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
- int rs_planed; /* resync sectors already planned */
atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */
int peer_max_bio_size;
int local_max_bio_size;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 32ebedb..0cbdf4f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2310,6 +2310,7 @@ void drbd_delete_device(struct drbd_conf *mdev)
__free_page(mdev->md_io_page);
put_disk(mdev->vdisk);
blk_cleanup_queue(mdev->rq_queue);
+ kfree(mdev->rs_plan_s);
kfree(mdev);
kref_put(&tconn->kref, &conn_destroy);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index a7d4c0e..ad81227 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1129,8 +1129,8 @@ 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 *new_disk_conf, *old_disk_conf;
+ struct fifo_buffer *rs_plan_s = NULL;
int err, fifo_size;
- int *rs_plan_s = NULL;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
if (!adm_ctx.reply_skb)
@@ -1189,8 +1189,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
new_disk_conf->al_extents = DRBD_AL_EXTENTS_MAX;
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 (fifo_size != mdev->rs_plan_s->size) {
+ rs_plan_s = fifo_alloc(fifo_size);
if (!rs_plan_s) {
dev_err(DEV, "kmalloc of fifo_buffer failed");
retcode = ERR_NOMEM;
@@ -1198,14 +1198,6 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
}
}
- if (fifo_size != mdev->rs_plan_s.size) {
- kfree(mdev->rs_plan_s.values);
- mdev->rs_plan_s.values = rs_plan_s;
- mdev->rs_plan_s.size = fifo_size;
- mdev->rs_planed = 0;
- rs_plan_s = NULL;
- }
-
wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
drbd_al_shrink(mdev);
err = drbd_check_al_size(mdev, new_disk_conf);
@@ -1228,6 +1220,14 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
if (retcode != NO_ERROR)
goto fail_unlock;
+ spin_lock(&mdev->peer_seq_lock);
+ if (rs_plan_s) {
+ kfree(mdev->rs_plan_s);
+ mdev->rs_plan_s = rs_plan_s;
+ rs_plan_s = NULL;
+ }
+ spin_unlock(&mdev->peer_seq_lock);
+
drbd_md_sync(mdev);
if (mdev->state.conn >= C_CONNECTED)
@@ -1262,6 +1262,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
struct disk_conf *new_disk_conf = NULL;
struct block_device *bdev;
struct lru_cache *resync_lru = NULL;
+ struct fifo_buffer *new_plan = NULL;
union drbd_state ns, os;
enum drbd_state_rv rv;
struct net_conf *nc;
@@ -1308,6 +1309,12 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
+ new_plan = fifo_alloc((new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ);
+ if (!new_plan) {
+ retcode = ERR_NOMEM;
+ goto fail;
+ }
+
if (new_disk_conf->meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
retcode = ERR_MD_IDX_INVALID;
goto fail;
@@ -1479,7 +1486,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
else
clear_bit(MD_NO_FUA, &mdev->flags);
- /* FIXME Missing stuff: rs_plan_s, clip al range */
+ /* FIXME Missing stuff: clip al range */
/* Point of no return reached.
* Devices and memory are no longer released by error cleanup below.
@@ -1488,9 +1495,11 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
D_ASSERT(mdev->ldev == NULL);
mdev->ldev = nbc;
mdev->resync = resync_lru;
+ mdev->rs_plan_s = new_plan;
nbc = NULL;
resync_lru = NULL;
new_disk_conf = NULL;
+ new_plan = NULL;
mdev->write_ordering = WO_bdev_flush;
drbd_bump_write_ordering(mdev, WO_bdev_flush);
@@ -1651,6 +1660,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
}
kfree(new_disk_conf);
lc_destroy(resync_lru);
+ kfree(new_plan);
finish:
drbd_adm_finish(info, retcode);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index add4176..19b421f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3159,7 +3159,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
struct net_conf *old_net_conf, *new_net_conf = NULL;
struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
const int apv = tconn->agreed_pro_version;
- int *rs_plan_s = NULL;
+ struct fifo_buffer *rs_plan_s = NULL;
int fifo_size = 0;
int err;
@@ -3277,8 +3277,8 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
new_disk_conf->c_max_rate = be32_to_cpu(p->c_max_rate);
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 (fifo_size != mdev->rs_plan_s->size) {
+ rs_plan_s = fifo_alloc(fifo_size);
if (!rs_plan_s) {
dev_err(DEV, "kmalloc of fifo_buffer failed");
put_ldev(mdev);
@@ -3317,10 +3317,8 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf);
spin_lock(&mdev->peer_seq_lock);
if (rs_plan_s) {
- kfree(mdev->rs_plan_s.values);
- mdev->rs_plan_s.values = rs_plan_s;
- mdev->rs_plan_s.size = fifo_size;
- mdev->rs_planed = 0;
+ kfree(mdev->rs_plan_s);
+ mdev->rs_plan_s = rs_plan_s;
}
spin_unlock(&mdev->peer_seq_lock);
@@ -3333,6 +3331,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
return 0;
disconnect:
+ kfree(rs_plan_s);
mutex_unlock(&mdev->tconn->conf_update);
/* just for completeness: actually not needed,
* as this is not reached if csums_tfm was ok. */
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 840e787..866924f 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -434,6 +434,21 @@ static void fifo_add_val(struct fifo_buffer *fb, int value)
fb->values[i] += value;
}
+struct fifo_buffer *fifo_alloc(int fifo_size)
+{
+ struct fifo_buffer *fb;
+
+ fb = kzalloc(sizeof(struct fifo_buffer) + sizeof(int) * fifo_size, GFP_KERNEL);
+ if (!fb)
+ return NULL;
+
+ fb->head_index = 0;
+ fb->size = fifo_size;
+ fb->total = 0;
+
+ return fb;
+}
+
static int drbd_rs_controller(struct drbd_conf *mdev)
{
struct disk_conf *dc;
@@ -453,7 +468,7 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
rcu_read_lock();
dc = rcu_dereference(mdev->ldev->disk_conf);
- steps = mdev->rs_plan_s.size; /* (dc->c_plan_ahead * 10 * SLEEP_TIME) / HZ; */
+ steps = mdev->rs_plan_s->size; /* (dc->c_plan_ahead * 10 * SLEEP_TIME) / HZ; */
if (mdev->rs_in_flight + sect_in == 0) { /* At start of resync */
want = ((dc->resync_rate * 2 * SLEEP_TIME) / HZ) * steps;
@@ -462,16 +477,16 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
sect_in * dc->c_delay_target * HZ / (SLEEP_TIME * 10);
}
- correction = want - mdev->rs_in_flight - mdev->rs_planed;
+ correction = want - mdev->rs_in_flight - mdev->rs_plan_s->total;
/* Plan ahead */
cps = correction / steps;
- fifo_add_val(&mdev->rs_plan_s, cps);
- mdev->rs_planed += cps * steps;
+ fifo_add_val(mdev->rs_plan_s, cps);
+ mdev->rs_plan_s->total += cps * steps;
/* What we do in this step */
- curr_corr = fifo_push(&mdev->rs_plan_s, 0);
- mdev->rs_planed -= curr_corr;
+ curr_corr = fifo_push(mdev->rs_plan_s, 0);
+ mdev->rs_plan_s->total -= curr_corr;
req_sect = sect_in + curr_corr;
if (req_sect < 0)
@@ -495,7 +510,7 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
static int drbd_rs_number_requests(struct drbd_conf *mdev)
{
int number;
- if (mdev->rs_plan_s.size) { /* rcu_dereference(mdev->ldev->disk_conf)->c_plan_ahead */
+ if (mdev->rs_plan_s->size) { /* rcu_dereference(mdev->ldev->disk_conf)->c_plan_ahead */
number = drbd_rs_controller(mdev) >> (BM_BLOCK_SHIFT - 9);
mdev->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME;
} else {
@@ -1456,9 +1471,9 @@ void drbd_rs_controller_reset(struct drbd_conf *mdev)
atomic_set(&mdev->rs_sect_in, 0);
atomic_set(&mdev->rs_sect_ev, 0);
mdev->rs_in_flight = 0;
- mdev->rs_planed = 0;
+ mdev->rs_plan_s->total = 0;
spin_lock(&mdev->peer_seq_lock);
- fifo_set(&mdev->rs_plan_s, 0);
+ fifo_set(mdev->rs_plan_s, 0);
spin_unlock(&mdev->peer_seq_lock);
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 09/15] drbd: Enforce limits of disk_conf members; centralized these checks
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (7 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 08/15] drbd: Made the fifo object a self contained object (preparing for RCU) Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 10/15] drbd: RCU for rs_plan_s Philipp Reisner
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 24 ++++++++++++++----------
1 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index ad81227..6d05bf5 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -959,9 +959,6 @@ static int drbd_check_al_size(struct drbd_conf *mdev, struct disk_conf *dc)
unsigned int in_use;
int i;
- if (!expect(dc->al_extents >= DRBD_AL_EXTENTS_MIN))
- dc->al_extents = DRBD_AL_EXTENTS_MIN;
-
if (mdev->act_log &&
mdev->act_log->nr_elements == dc->al_extents)
return 0;
@@ -1124,6 +1121,17 @@ static bool should_set_defaults(struct genl_info *info)
return 0 != (flags & DRBD_GENL_F_SET_DEFAULTS);
}
+static void enforce_disk_conf_limits(struct disk_conf *dc)
+{
+ if (dc->al_extents < DRBD_AL_EXTENTS_MIN)
+ dc->al_extents = DRBD_AL_EXTENTS_MIN;
+ if (dc->al_extents > DRBD_AL_EXTENTS_MAX)
+ dc->al_extents = DRBD_AL_EXTENTS_MAX;
+
+ if (dc->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX)
+ dc->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX;
+}
+
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
{
enum drbd_ret_code retcode;
@@ -1182,11 +1190,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
if (!expect(new_disk_conf->resync_rate >= 1))
new_disk_conf->resync_rate = 1;
- /* clip to allowed range */
- 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;
+ enforce_disk_conf_limits(new_disk_conf);
fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
if (fifo_size != mdev->rs_plan_s->size) {
@@ -1309,6 +1313,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
+ enforce_disk_conf_limits(new_disk_conf);
+
new_plan = fifo_alloc((new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ);
if (!new_plan) {
retcode = ERR_NOMEM;
@@ -1486,8 +1492,6 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
else
clear_bit(MD_NO_FUA, &mdev->flags);
- /* FIXME Missing stuff: clip al range */
-
/* Point of no return reached.
* Devices and memory are no longer released by error cleanup below.
* now mdev takes over responsibility, and the state engine should
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 10/15] drbd: RCU for rs_plan_s
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (8 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 09/15] drbd: Enforce limits of disk_conf members; centralized these checks Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 11/15] drbd: Convert boolean flags on netlink from NLA_FLAG to NLA_U8 Philipp Reisner
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
This removes the issue with using peer_seq_lock out of different
contexts.
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_nl.c | 18 +++++++--------
drivers/block/drbd/drbd_receiver.c | 17 +++++++--------
drivers/block/drbd/drbd_worker.c | 41 +++++++++++++++++++++---------------
4 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 2ecee6c..3f377e2 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -998,7 +998,7 @@ struct drbd_conf {
int rs_last_events; /* counter of read or write "events" (unit sectors)
* on the lower level device when we last looked. */
int c_sync_rate; /* current resync rate after syncer throttle magic */
- struct fifo_buffer *rs_plan_s; /* correction values of resync planer */
+ struct fifo_buffer *rs_plan_s; /* correction values of resync planer (RCU, tconn->conn_update) */
int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */
int peer_max_bio_size;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 6d05bf5..ca39deb 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1137,7 +1137,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 *new_disk_conf, *old_disk_conf;
- struct fifo_buffer *rs_plan_s = NULL;
+ struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
int err, fifo_size;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
@@ -1194,8 +1194,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
if (fifo_size != mdev->rs_plan_s->size) {
- rs_plan_s = fifo_alloc(fifo_size);
- if (!rs_plan_s) {
+ new_plan = fifo_alloc(fifo_size);
+ if (!new_plan) {
dev_err(DEV, "kmalloc of fifo_buffer failed");
retcode = ERR_NOMEM;
goto fail_unlock;
@@ -1224,13 +1224,10 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
if (retcode != NO_ERROR)
goto fail_unlock;
- spin_lock(&mdev->peer_seq_lock);
- if (rs_plan_s) {
- kfree(mdev->rs_plan_s);
- mdev->rs_plan_s = rs_plan_s;
- rs_plan_s = NULL;
+ if (new_plan) {
+ old_plan = mdev->rs_plan_s;
+ rcu_assign_pointer(mdev->rs_plan_s, new_plan);
}
- spin_unlock(&mdev->peer_seq_lock);
drbd_md_sync(mdev);
@@ -1240,13 +1237,14 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
mutex_unlock(&mdev->tconn->conf_update);
synchronize_rcu();
kfree(old_disk_conf);
+ kfree(old_plan);
goto success;
fail_unlock:
mutex_unlock(&mdev->tconn->conf_update);
fail:
kfree(new_disk_conf);
- kfree(rs_plan_s);
+ kfree(new_plan);
success:
put_ldev(mdev);
out:
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 19b421f..73f605b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3159,7 +3159,7 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
struct net_conf *old_net_conf, *new_net_conf = NULL;
struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
const int apv = tconn->agreed_pro_version;
- struct fifo_buffer *rs_plan_s = NULL;
+ struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
int fifo_size = 0;
int err;
@@ -3278,8 +3278,8 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
if (fifo_size != mdev->rs_plan_s->size) {
- rs_plan_s = fifo_alloc(fifo_size);
- if (!rs_plan_s) {
+ new_plan = fifo_alloc(fifo_size);
+ if (!new_plan) {
dev_err(DEV, "kmalloc of fifo_buffer failed");
put_ldev(mdev);
goto disconnect;
@@ -3315,23 +3315,22 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
}
rcu_assign_pointer(mdev->ldev->disk_conf, new_disk_conf);
- spin_lock(&mdev->peer_seq_lock);
- if (rs_plan_s) {
- kfree(mdev->rs_plan_s);
- mdev->rs_plan_s = rs_plan_s;
+ if (new_plan) {
+ old_plan = mdev->rs_plan_s;
+ rcu_assign_pointer(mdev->rs_plan_s, new_plan);
}
- spin_unlock(&mdev->peer_seq_lock);
mutex_unlock(&mdev->tconn->conf_update);
synchronize_rcu();
if (new_net_conf)
kfree(old_net_conf);
kfree(old_disk_conf);
+ kfree(old_plan);
return 0;
disconnect:
- kfree(rs_plan_s);
+ kfree(new_plan);
mutex_unlock(&mdev->tconn->conf_update);
/* just for completeness: actually not needed,
* as this is not reached if csums_tfm was ok. */
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 866924f..484a08b 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -460,15 +460,15 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
int steps; /* Number of time steps to plan ahead */
int curr_corr;
int max_sect;
+ struct fifo_buffer *plan;
sect_in = atomic_xchg(&mdev->rs_sect_in, 0); /* Number of sectors that came in */
mdev->rs_in_flight -= sect_in;
- spin_lock(&mdev->peer_seq_lock); /* get an atomic view on mdev->rs_plan_s */
- rcu_read_lock();
dc = rcu_dereference(mdev->ldev->disk_conf);
+ plan = rcu_dereference(mdev->rs_plan_s);
- steps = mdev->rs_plan_s->size; /* (dc->c_plan_ahead * 10 * SLEEP_TIME) / HZ; */
+ steps = plan->size; /* (dc->c_plan_ahead * 10 * SLEEP_TIME) / HZ; */
if (mdev->rs_in_flight + sect_in == 0) { /* At start of resync */
want = ((dc->resync_rate * 2 * SLEEP_TIME) / HZ) * steps;
@@ -477,16 +477,16 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
sect_in * dc->c_delay_target * HZ / (SLEEP_TIME * 10);
}
- correction = want - mdev->rs_in_flight - mdev->rs_plan_s->total;
+ correction = want - mdev->rs_in_flight - plan->total;
/* Plan ahead */
cps = correction / steps;
- fifo_add_val(mdev->rs_plan_s, cps);
- mdev->rs_plan_s->total += cps * steps;
+ fifo_add_val(plan, cps);
+ plan->total += cps * steps;
/* What we do in this step */
- curr_corr = fifo_push(mdev->rs_plan_s, 0);
- mdev->rs_plan_s->total -= curr_corr;
+ curr_corr = fifo_push(plan, 0);
+ plan->total -= curr_corr;
req_sect = sect_in + curr_corr;
if (req_sect < 0)
@@ -501,8 +501,6 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
sect_in, mdev->rs_in_flight, want, correction,
steps, cps, mdev->rs_planed, curr_corr, req_sect);
*/
- rcu_read_unlock();
- spin_unlock(&mdev->peer_seq_lock);
return req_sect;
}
@@ -510,15 +508,16 @@ static int drbd_rs_controller(struct drbd_conf *mdev)
static int drbd_rs_number_requests(struct drbd_conf *mdev)
{
int number;
- if (mdev->rs_plan_s->size) { /* rcu_dereference(mdev->ldev->disk_conf)->c_plan_ahead */
+
+ rcu_read_lock();
+ if (rcu_dereference(mdev->rs_plan_s)->size) {
number = drbd_rs_controller(mdev) >> (BM_BLOCK_SHIFT - 9);
mdev->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME;
} else {
- rcu_read_lock();
mdev->c_sync_rate = rcu_dereference(mdev->ldev->disk_conf)->resync_rate;
- rcu_read_unlock();
number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ);
}
+ rcu_read_unlock();
/* ignore the amount of pending requests, the resync controller should
* throttle down to incoming reply rate soon enough anyways. */
@@ -1468,13 +1467,21 @@ void drbd_sync_after_changed(struct drbd_conf *mdev)
void drbd_rs_controller_reset(struct drbd_conf *mdev)
{
+ struct fifo_buffer *plan;
+
atomic_set(&mdev->rs_sect_in, 0);
atomic_set(&mdev->rs_sect_ev, 0);
mdev->rs_in_flight = 0;
- mdev->rs_plan_s->total = 0;
- spin_lock(&mdev->peer_seq_lock);
- fifo_set(mdev->rs_plan_s, 0);
- spin_unlock(&mdev->peer_seq_lock);
+
+ /* Updating the RCU protected object in place is necessary since
+ this function gets called from atomic context.
+ It is valid since all other updates also lead to an completely
+ empty fifo */
+ rcu_read_lock();
+ plan = rcu_dereference(mdev->rs_plan_s);
+ plan->total = 0;
+ fifo_set(plan, 0);
+ rcu_read_unlock();
}
void start_resync_timer_fn(unsigned long data)
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 11/15] drbd: Convert boolean flags on netlink from NLA_FLAG to NLA_U8
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (9 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 10/15] drbd: RCU for rs_plan_s Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 12/15] drbd: Turn no-disk-flushes into disk-flushes={yes|no} Philipp Reisner
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Flags of type NLA_FLAG are either present or absent, but do not have a
value by themselves. Use type NLA_U8 for our boolean flags instead, and
use the value to determine if the flag should be on or off.
On the drbdsetup command line, all those flags have an optional yes/no
argument which defaults to yes.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
include/linux/genl_magic_struct.h | 10 ++--------
1 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/include/linux/genl_magic_struct.h b/include/linux/genl_magic_struct.h
index ddbdd0a..b1ddbb5 100644
--- a/include/linux/genl_magic_struct.h
+++ b/include/linux/genl_magic_struct.h
@@ -86,8 +86,8 @@ enum {
/* possible field types */
#define __flg_field(attr_nr, attr_flag, name) \
- __field(attr_nr, attr_flag, name, NLA_FLAG, char, \
- nla_get_flag, __nla_put_flag)
+ __field(attr_nr, attr_flag, name, NLA_U8, char, \
+ nla_get_u8, NLA_PUT_U8)
#define __u8_field(attr_nr, attr_flag, name) \
__field(attr_nr, attr_flag, name, NLA_U8, unsigned char, \
nla_get_u8, NLA_PUT_U8)
@@ -118,12 +118,6 @@ enum {
#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) \
- NLA_PUT_FLAG(skb, attrtype); \
- } while (0)
-
#define GENL_op_init(args...) args
#define GENL_doit(handler) \
.doit = handler, \
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 12/15] drbd: Turn no-disk-flushes into disk-flushes={yes|no}
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (10 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 11/15] drbd: Convert boolean flags on netlink from NLA_FLAG to NLA_U8 Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 13/15] drbd: Turn no-disk-drain into disk-drain={yes|no} Philipp Reisner
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Change the --no-disk-flushes drbdsetup command line option as well as
the no_disk_flush netlink packet.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 2 +-
include/linux/drbd_genl.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 73f605b..1024f04 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1179,7 +1179,7 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
rcu_read_lock();
dc = rcu_dereference(mdev->ldev->disk_conf);
- if (wo == WO_bdev_flush && dc->no_disk_flush)
+ if (wo == WO_bdev_flush && !dc->disk_flushes)
wo = WO_drain_io;
if (wo == WO_drain_io && dc->no_disk_drain)
wo = WO_none;
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 529627b..c5e7a99 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -124,8 +124,8 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
__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(16, GENLA_F_MANDATORY, disk_barrier, 1)
+ __flg_field_def(17, GENLA_F_MANDATORY, disk_flushes, 1)
__flg_field_def(18, GENLA_F_MANDATORY, no_disk_drain, 0)
__flg_field_def(19, GENLA_F_MANDATORY, no_md_flush, 0)
)
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 13/15] drbd: Turn no-disk-drain into disk-drain={yes|no}
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (11 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 12/15] drbd: Turn no-disk-flushes into disk-flushes={yes|no} Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:37 ` [PATCH 14/15] drbd: Turn no-md-flushes into md-flushes={yes|no} Philipp Reisner
2011-10-06 13:38 ` [PATCH 15/15] drbd: Turn no-tcp-cork into tcp-cork={yes|no} Philipp Reisner
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Change the --no-disk-drain drbdsetup command line option as well as
the no_disk_drain netlink packet.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 2 +-
include/linux/drbd_genl.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1024f04..a80f064 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1181,7 +1181,7 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
if (wo == WO_bdev_flush && !dc->disk_flushes)
wo = WO_drain_io;
- if (wo == WO_drain_io && dc->no_disk_drain)
+ if (wo == WO_drain_io && !dc->disk_drain)
wo = WO_none;
rcu_read_unlock();
mdev->write_ordering = wo;
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index c5e7a99..96e5b18 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -126,7 +126,7 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
__flg_field_def(16, GENLA_F_MANDATORY, disk_barrier, 1)
__flg_field_def(17, GENLA_F_MANDATORY, disk_flushes, 1)
- __flg_field_def(18, GENLA_F_MANDATORY, no_disk_drain, 0)
+ __flg_field_def(18, GENLA_F_MANDATORY, disk_drain, 1)
__flg_field_def(19, GENLA_F_MANDATORY, no_md_flush, 0)
)
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 14/15] drbd: Turn no-md-flushes into md-flushes={yes|no}
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (12 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 13/15] drbd: Turn no-disk-drain into disk-drain={yes|no} Philipp Reisner
@ 2011-10-06 13:37 ` Philipp Reisner
2011-10-06 13:38 ` [PATCH 15/15] drbd: Turn no-tcp-cork into tcp-cork={yes|no} Philipp Reisner
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:37 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Change the --no-md-flushes drbdsetup command line option as well as
the no_md_flush netlink packet.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_nl.c | 6 +++---
include/linux/drbd_genl.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index ca39deb..d82e3c1 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1485,10 +1485,10 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
/* Reset the "barriers don't work" bits here, then force meta data to
* be written, to ensure we determine if barriers are supported. */
- if (new_disk_conf->no_md_flush)
- set_bit(MD_NO_FUA, &mdev->flags);
- else
+ if (new_disk_conf->md_flushes)
clear_bit(MD_NO_FUA, &mdev->flags);
+ else
+ set_bit(MD_NO_FUA, &mdev->flags);
/* Point of no return reached.
* Devices and memory are no longer released by error cleanup below.
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 96e5b18..0fd79ea 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -127,7 +127,7 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
__flg_field_def(16, GENLA_F_MANDATORY, disk_barrier, 1)
__flg_field_def(17, GENLA_F_MANDATORY, disk_flushes, 1)
__flg_field_def(18, GENLA_F_MANDATORY, disk_drain, 1)
- __flg_field_def(19, GENLA_F_MANDATORY, no_md_flush, 0)
+ __flg_field_def(19, GENLA_F_MANDATORY, md_flushes, 1)
)
GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts,
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 15/15] drbd: Turn no-tcp-cork into tcp-cork={yes|no}
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
` (13 preceding siblings ...)
2011-10-06 13:37 ` [PATCH 14/15] drbd: Turn no-md-flushes into md-flushes={yes|no} Philipp Reisner
@ 2011-10-06 13:38 ` Philipp Reisner
14 siblings, 0 replies; 16+ messages in thread
From: Philipp Reisner @ 2011-10-06 13:38 UTC (permalink / raw)
To: linux-kernel, Jens Axboe; +Cc: drbd-dev
From: Andreas Gruenbacher <agruen@linbit.com>
Change the --no-tcp-cork drbdsetup command line option as well as
the no_cork netlink packet.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 8 ++++----
drivers/block/drbd/drbd_worker.c | 2 +-
include/linux/drbd_genl.h | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index a80f064..b014415 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -5022,7 +5022,7 @@ int drbd_asender(struct drbd_thread *thi)
int expect = header_size;
bool ping_timeout_active = false;
struct net_conf *nc;
- int ping_timeo, no_cork, ping_int;
+ int ping_timeo, tcp_cork, ping_int;
current->policy = SCHED_RR; /* Make this a realtime task! */
current->rt_priority = 2; /* more important than all other tasks */
@@ -5033,7 +5033,7 @@ int drbd_asender(struct drbd_thread *thi)
rcu_read_lock();
nc = rcu_dereference(tconn->net_conf);
ping_timeo = nc->ping_timeo;
- no_cork = nc->no_cork;
+ tcp_cork = nc->tcp_cork;
ping_int = nc->ping_int;
rcu_read_unlock();
@@ -5048,14 +5048,14 @@ int drbd_asender(struct drbd_thread *thi)
/* TODO: conditionally cork; it may hurt latency if we cork without
much to send */
- if (!no_cork)
+ if (tcp_cork)
drbd_tcp_cork(tconn->meta.socket);
if (tconn_finish_peer_reqs(tconn)) {
conn_err(tconn, "tconn_finish_peer_reqs() failed\n");
goto reconnect;
}
/* but unconditionally uncork unless disabled */
- if (!no_cork)
+ if (tcp_cork)
drbd_tcp_uncork(tconn->meta.socket);
/* short circuit, recv_msg would return EINTR anyways. */
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 484a08b..feb12b0 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1694,7 +1694,7 @@ int drbd_worker(struct drbd_thread *thi)
rcu_read_lock();
nc = rcu_dereference(tconn->net_conf);
- cork = nc ? !nc->no_cork : 0;
+ cork = nc ? nc->tcp_cork : 0;
rcu_read_unlock();
if (tconn->data.socket && cork)
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 0fd79ea..601334b 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -164,7 +164,7 @@ GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf,
__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_def(28, GENLA_F_MANDATORY, no_cork, 0)
+ __flg_field_def(28, GENLA_F_MANDATORY, tcp_cork, 1)
__flg_field_def(29, GENLA_F_MANDATORY, always_asbp, 0)
__flg_field(30, GENLA_F_MANDATORY | GENLA_F_INVARIANT, dry_run)
__flg_field_def(31, GENLA_F_MANDATORY, use_rle, 0)
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2011-10-06 13:41 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-06 13:37 [RFC 00/15] drbd: part 15 of adding multiple volume support to drbd Philipp Reisner
2011-10-06 13:37 ` [PATCH 01/15] drbd: Removed dead code Philipp Reisner
2011-10-06 13:37 ` [PATCH 02/15] drbd: Renamed the net_conf_update mutex to conf_update Philipp Reisner
2011-10-06 13:37 ` [PATCH 03/15] drbd: drbd_dew_dev_size() gets the user requests disk_size as argument Philipp Reisner
2011-10-06 13:37 ` [PATCH 04/15] drbd: Split drbd_alter_sa() into drbd_sync_after_valid() and drbd_sync_after_changed() Philipp Reisner
2011-10-06 13:37 ` [PATCH 05/15] drbd: Renamed (old|new)_conf into (old|new)_net_conf in receive_SyncParam Philipp Reisner
2011-10-06 13:37 ` [PATCH 06/15] drbd: Introduce __s32_field in the genetlink macro magic Philipp Reisner
2011-10-06 13:37 ` [PATCH 07/15] drbd: RCU for disk_conf Philipp Reisner
2011-10-06 13:37 ` [PATCH 08/15] drbd: Made the fifo object a self contained object (preparing for RCU) Philipp Reisner
2011-10-06 13:37 ` [PATCH 09/15] drbd: Enforce limits of disk_conf members; centralized these checks Philipp Reisner
2011-10-06 13:37 ` [PATCH 10/15] drbd: RCU for rs_plan_s Philipp Reisner
2011-10-06 13:37 ` [PATCH 11/15] drbd: Convert boolean flags on netlink from NLA_FLAG to NLA_U8 Philipp Reisner
2011-10-06 13:37 ` [PATCH 12/15] drbd: Turn no-disk-flushes into disk-flushes={yes|no} Philipp Reisner
2011-10-06 13:37 ` [PATCH 13/15] drbd: Turn no-disk-drain into disk-drain={yes|no} Philipp Reisner
2011-10-06 13:37 ` [PATCH 14/15] drbd: Turn no-md-flushes into md-flushes={yes|no} Philipp Reisner
2011-10-06 13:38 ` [PATCH 15/15] drbd: Turn no-tcp-cork into tcp-cork={yes|no} Philipp Reisner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome