Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346056
b: refs/heads/master
c: c141ebd
h: refs/heads/master
v: v3
  • Loading branch information
Philipp Reisner committed Nov 8, 2012
1 parent 9da0eed commit 253655d
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 76 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ec0bddbc5574ea5903cec8f30ed57777f14d86a8
refs/heads/master: c141ebda031a0550d75634f7c94f7c85c2d5c9f5
9 changes: 3 additions & 6 deletions trunk/drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,8 @@ drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) {
#define DRBD_MD_MAGIC (DRBD_MAGIC+4)

extern struct ratelimit_state drbd_ratelimit_state;
extern struct idr minors;
extern struct list_head drbd_tconns;
extern struct rw_semaphore drbd_cfg_rwsem;
/* drbd_cfg_rwsem protects: drbd_tconns list, minors idr, tconn->volumes idr
note: non sleeping iterations over the idrs are protoected by RCU */
extern struct idr minors; /* RCU, updates: genl_lock() */
extern struct list_head drbd_tconns; /* RCU, updates: genl_lock() */

/* on the wire */
enum drbd_packet {
Expand Down Expand Up @@ -1477,7 +1474,7 @@ extern struct page *drbd_alloc_pages(struct drbd_conf *, unsigned int, bool);
extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled);
extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed);
extern void conn_flush_workqueue(struct drbd_tconn *tconn);
extern int drbd_connected(int vnr, void *p, void *data);
extern int drbd_connected(struct drbd_conf *mdev);
static inline void drbd_flush_workqueue(struct drbd_conf *mdev)
{
conn_flush_workqueue(mdev->tconn);
Expand Down
20 changes: 7 additions & 13 deletions trunk/drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0
*/
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 */
Expand Down Expand Up @@ -2331,21 +2330,20 @@ static void drbd_cleanup(void)

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");
Expand Down Expand Up @@ -2408,7 +2406,7 @@ struct drbd_tconn *conn_get_by_name(const char *name)
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);
Expand All @@ -2417,7 +2415,7 @@ struct drbd_tconn *conn_get_by_name(const char *name)
}
tconn = NULL;
found:
up_read(&drbd_cfg_rwsem);
rcu_read_unlock();
return tconn;
}

Expand Down Expand Up @@ -2502,10 +2500,8 @@ struct drbd_tconn *conn_create(const char *name)

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;

Expand Down Expand Up @@ -2637,7 +2633,7 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor,
/* 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;

Expand Down Expand Up @@ -2913,12 +2909,10 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
}
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);
Expand Down
43 changes: 15 additions & 28 deletions trunk/drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,15 @@ static void conn_md_sync(struct drbd_tconn *tconn)
struct drbd_conf *mdev;
int vnr;

down_read(&drbd_cfg_rwsem);
idr_for_each_entry(&tconn->volumes, mdev, vnr)
rcu_read_lock();
idr_for_each_entry(&tconn->volumes, mdev, vnr) {
kref_get(&mdev->kref);
rcu_read_unlock();
drbd_md_sync(mdev);
up_read(&drbd_cfg_rwsem);
kref_put(&mdev->kref, &drbd_minor_destroy);
rcu_read_lock();
}
rcu_read_unlock();
}

int conn_khelper(struct drbd_tconn *tconn, char *cmd)
Expand Down Expand Up @@ -1193,12 +1198,12 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
rcu_assign_pointer(mdev->rs_plan_s, new_plan);
}

mutex_unlock(&mdev->tconn->conf_update);
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);
kfree(old_plan);
Expand Down Expand Up @@ -2013,7 +2018,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
new_my_addr = (struct sockaddr *)&new_conf->my_addr;
new_peer_addr = (struct sockaddr *)&new_conf->peer_addr;

/* No need to take drbd_cfg_rwsem here. All reconfiguration is
/* No need for _rcu here. All reconfiguration is
* strictly serialized on genl_lock(). We are protected against
* concurrent reconfiguration/addition/deletion */
list_for_each_entry(oconn, &drbd_tconns, all_tconn) {
Expand Down Expand Up @@ -2672,7 +2677,7 @@ int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
*/

/* synchronize with conn_create()/conn_destroy() */
down_read(&drbd_cfg_rwsem);
rcu_read_lock();
/* revalidate iterator position */
list_for_each_entry_rcu(tmp, &drbd_tconns, all_tconn) {
if (pos == NULL) {
Expand Down Expand Up @@ -2738,7 +2743,7 @@ int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
}

out:
up_read(&drbd_cfg_rwsem);
rcu_read_unlock();
/* where to start the next iteration */
cb->args[0] = (long)pos;
cb->args[1] = (pos == tconn) ? volume + 1 : 0;
Expand Down Expand Up @@ -3018,9 +3023,7 @@ int drbd_adm_add_minor(struct sk_buff *skb, struct genl_info *info)
goto out;
}

down_write(&drbd_cfg_rwsem);
retcode = conn_new_minor(adm_ctx.tconn, dh->minor, adm_ctx.volume);
up_write(&drbd_cfg_rwsem);
out:
drbd_adm_finish(info, retcode);
return 0;
Expand Down Expand Up @@ -3053,9 +3056,7 @@ int drbd_adm_delete_minor(struct sk_buff *skb, struct genl_info *info)
if (retcode != NO_ERROR)
goto out;

down_write(&drbd_cfg_rwsem);
retcode = adm_delete_minor(adm_ctx.mdev);
up_write(&drbd_cfg_rwsem);
out:
drbd_adm_finish(info, retcode);
return 0;
Expand All @@ -3078,52 +3079,43 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
goto out;
}

down_read(&drbd_cfg_rwsem);
/* demote */
idr_for_each_entry(&adm_ctx.tconn->volumes, mdev, i) {
retcode = drbd_set_role(mdev, R_SECONDARY, 0);
if (retcode < SS_SUCCESS) {
drbd_msg_put_info("failed to demote");
goto out_unlock;
goto out;
}
}
up_read(&drbd_cfg_rwsem);

/* disconnect; may stop the receiver;
* must not hold the drbd_cfg_rwsem */
retcode = conn_try_disconnect(adm_ctx.tconn, 0);
if (retcode < SS_SUCCESS) {
drbd_msg_put_info("failed to disconnect");
goto out;
}

down_read(&drbd_cfg_rwsem);
/* detach */
idr_for_each_entry(&adm_ctx.tconn->volumes, mdev, i) {
retcode = adm_detach(mdev);
if (retcode < SS_SUCCESS) {
drbd_msg_put_info("failed to detach");
goto out_unlock;
goto out;
}
}
up_read(&drbd_cfg_rwsem);

/* If we reach this, all volumes (of this tconn) are Secondary,
* Disconnected, Diskless, aka Unconfigured. Make sure all threads have
* actually stopped, state handling only does drbd_thread_stop_nowait().
* This needs to be done without holding drbd_cfg_rwsem. */
* actually stopped, state handling only does drbd_thread_stop_nowait(). */
drbd_thread_stop(&adm_ctx.tconn->worker);

/* Now, nothing can fail anymore */

/* delete volumes */
down_write(&drbd_cfg_rwsem);
idr_for_each_entry(&adm_ctx.tconn->volumes, mdev, i) {
retcode = adm_delete_minor(mdev);
if (retcode != NO_ERROR) {
/* "can not happen" */
drbd_msg_put_info("failed to delete volume");
up_write(&drbd_cfg_rwsem);
goto out;
}
}
Expand All @@ -3140,10 +3132,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
retcode = ERR_CONN_IN_USE;
drbd_msg_put_info("failed to delete connection");
}
up_write(&drbd_cfg_rwsem);
goto out;
out_unlock:
up_read(&drbd_cfg_rwsem);
out:
drbd_adm_finish(info, retcode);
return 0;
Expand All @@ -3159,7 +3148,6 @@ int drbd_adm_delete_connection(struct sk_buff *skb, struct genl_info *info)
if (retcode != NO_ERROR)
goto out;

down_write(&drbd_cfg_rwsem);
if (conn_lowest_minor(adm_ctx.tconn) < 0) {
list_del_rcu(&adm_ctx.tconn->all_tconn);
synchronize_rcu();
Expand All @@ -3169,7 +3157,6 @@ int drbd_adm_delete_connection(struct sk_buff *skb, struct genl_info *info)
} else {
retcode = ERR_CONN_IN_USE;
}
up_write(&drbd_cfg_rwsem);

if (retcode == NO_ERROR)
drbd_thread_stop(&adm_ctx.tconn->worker);
Expand Down
6 changes: 2 additions & 4 deletions trunk/drivers/block/drbd/drbd_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
oos .. known out-of-sync kB
*/

down_read(&drbd_cfg_rwsem);
rcu_read_lock();
idr_for_each_entry(&minors, mdev, i) {
if (prev_i != i - 1)
seq_printf(seq, "\n");
Expand All @@ -242,10 +242,8 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
mdev->state.role == R_SECONDARY) {
seq_printf(seq, "%2d: cs:Unconfigured\n", i);
} else {
rcu_read_lock();
nc = rcu_dereference(mdev->tconn->net_conf);
wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
rcu_read_unlock();
seq_printf(seq,
"%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
" ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
Expand Down Expand Up @@ -299,7 +297,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
}
}
}
up_read(&drbd_cfg_rwsem);
rcu_read_unlock();

return 0;
}
Expand Down
Loading

0 comments on commit 253655d

Please sign in to comment.