drbd: Removing drbd_cfg_rwsem
* Updates to all configuration items is done under genl_lock().
Including removal of mdevs or tconns.
* All read non sleeping read sides are protected by rcu
* All sleeping read sides keep reference counts to keep the
objects alive
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 771b53e..22c2b4c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -120,7 +120,6 @@
*/
struct idr minors;
struct list_head drbd_tconns; /* list of struct drbd_tconn */
-DECLARE_RWSEM(drbd_cfg_rwsem);
struct kmem_cache *drbd_request_cache;
struct kmem_cache *drbd_ee_cache; /* peer requests */
@@ -2331,21 +2330,20 @@
drbd_genl_unregister();
- down_write(&drbd_cfg_rwsem);
idr_for_each_entry(&minors, mdev, i) {
idr_remove(&minors, mdev_to_minor(mdev));
idr_remove(&mdev->tconn->volumes, mdev->vnr);
del_gendisk(mdev->vdisk);
- synchronize_rcu();
+ /* synchronize_rcu(); No other threads running at this point */
kref_put(&mdev->kref, &drbd_minor_destroy);
}
+ /* not _rcu since, no other updater anymore. Genl already unregistered */
list_for_each_entry_safe(tconn, tmp, &drbd_tconns, all_tconn) {
- list_del_rcu(&tconn->all_tconn);
- synchronize_rcu();
+ list_del(&tconn->all_tconn); /* not _rcu no proc, not other threads */
+ /* synchronize_rcu(); */
kref_put(&tconn->kref, &conn_destroy);
}
- up_write(&drbd_cfg_rwsem);
drbd_destroy_mempools();
unregister_blkdev(DRBD_MAJOR, "drbd");
@@ -2408,7 +2406,7 @@
if (!name || !name[0])
return NULL;
- down_read(&drbd_cfg_rwsem);
+ rcu_read_lock();
list_for_each_entry_rcu(tconn, &drbd_tconns, all_tconn) {
if (!strcmp(tconn->name, name)) {
kref_get(&tconn->kref);
@@ -2417,7 +2415,7 @@
}
tconn = NULL;
found:
- up_read(&drbd_cfg_rwsem);
+ rcu_read_unlock();
return tconn;
}
@@ -2502,10 +2500,8 @@
drbd_set_res_opts_defaults(&tconn->res_opts);
- down_write(&drbd_cfg_rwsem);
kref_init(&tconn->kref);
list_add_tail_rcu(&tconn->all_tconn, &drbd_tconns);
- up_write(&drbd_cfg_rwsem);
return tconn;
@@ -2637,7 +2633,7 @@
/* inherit the connection state */
mdev->state.conn = tconn->cstate;
if (mdev->state.conn == C_WF_REPORT_PARAMS)
- drbd_connected(vnr, mdev, tconn);
+ drbd_connected(mdev);
return NO_ERROR;
@@ -2913,12 +2909,10 @@
}
spin_unlock_irq(&mdev->tconn->req_lock);
- 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);