Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 345814
b: refs/heads/master
c: df24aa4
h: refs/heads/master
v: v3
  • Loading branch information
Philipp Reisner committed Oct 14, 2011
1 parent 9cd66a9 commit 912cfa3
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 15 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: 047cd4a682b09a7bc5dd5610262405bb085f8b19
refs/heads/master: df24aa45f4df43e8881c0f80d6a4e2653df7af05
28 changes: 14 additions & 14 deletions trunk/drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1572,6 +1572,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
struct drbd_nl_cfg_reply *reply)
{
struct drbd_tconn *tconn = mdev->tconn;
int retcode;
struct disconnect dc;

Expand All @@ -1582,39 +1583,38 @@ static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
}

if (dc.force) {
spin_lock_irq(&mdev->tconn->req_lock);
if (mdev->state.conn >= C_WF_CONNECTION)
_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), CS_HARD, NULL);
spin_unlock_irq(&mdev->tconn->req_lock);
spin_lock_irq(&tconn->req_lock);
if (tconn->cstate >= C_WF_CONNECTION)
_conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
spin_unlock_irq(&tconn->req_lock);
goto done;
}

retcode = _drbd_request_state(mdev, NS(conn, C_DISCONNECTING), CS_ORDERED);
retcode = conn_request_state(tconn, NS(conn, C_DISCONNECTING), 0);

if (retcode == SS_NOTHING_TO_DO)
goto done;
else if (retcode == SS_ALREADY_STANDALONE)
goto done;
else if (retcode == SS_PRIMARY_NOP) {
/* Our statche checking code wants to see the peer outdated. */
retcode = drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
pdsk, D_OUTDATED));
/* Our state checking code wants to see the peer outdated. */
retcode = conn_request_state(tconn, NS2(conn, C_DISCONNECTING,
pdsk, D_OUTDATED), CS_VERBOSE);
} else if (retcode == SS_CW_FAILED_BY_PEER) {
/* The peer probably wants to see us outdated. */
retcode = _drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
disk, D_OUTDATED),
CS_ORDERED);
retcode = conn_request_state(tconn, NS2(conn, C_DISCONNECTING,
disk, D_OUTDATED), 0);
if (retcode == SS_IS_DISKLESS || retcode == SS_LOWER_THAN_OUTDATED) {
drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
retcode = SS_SUCCESS;
}
}

if (retcode < SS_SUCCESS)
goto fail;

if (wait_event_interruptible(mdev->state_wait,
mdev->state.conn != C_DISCONNECTING)) {
if (wait_event_interruptible(tconn->ping_wait,
tconn->cstate != C_DISCONNECTING)) {
/* Do not test for mdev->state.conn == C_STANDALONE, since
someone else might connect us in the mean time! */
retcode = ERR_INTR;
Expand Down
62 changes: 62 additions & 0 deletions trunk/drivers/block/drbd/drbd_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,61 @@ static int _set_state_itr_fn(int vnr, void *p, void *data)
return 0;
}

static enum drbd_state_rv
_conn_rq_cond(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val)
{
struct _is_valid_itr_params params;
enum drbd_state_rv rv;

if (test_and_clear_bit(CONN_WD_ST_CHG_OKAY, &tconn->flags))
return SS_CW_SUCCESS;

if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &tconn->flags))
return SS_CW_FAILED_BY_PEER;

params.flags = CS_NO_CSTATE_CHG; /* öö think */
params.mask = mask;
params.val = val;

spin_lock_irq(&tconn->req_lock);
rv = tconn->cstate != C_WF_REPORT_PARAMS ? SS_CW_NO_NEED : SS_UNKNOWN_ERROR;

if (rv == SS_UNKNOWN_ERROR)
rv = idr_for_each(&tconn->volumes, _is_valid_itr_fn, &params);

if (rv == 0) /* idr_for_each semantics */
rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */

spin_unlock_irq(&tconn->req_lock);

return rv;
}

static enum drbd_state_rv
conn_cl_wide(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
enum chg_state_flags f)
{
enum drbd_state_rv rv;

spin_unlock_irq(&tconn->req_lock);
mutex_lock(&tconn->cstate_mutex);

if (!conn_send_state_req(tconn, mask, val)) {
rv = SS_CW_FAILED_BY_PEER;
/* if (f & CS_VERBOSE)
print_st_err(mdev, os, ns, rv); */
goto abort;
}

wait_event(tconn->ping_wait, (rv = _conn_rq_cond(tconn, mask, val)));

abort:
mutex_unlock(&tconn->cstate_mutex);
spin_lock_irq(&tconn->req_lock);

return rv;
}

enum drbd_state_rv
_conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
enum chg_state_flags flags)
Expand Down Expand Up @@ -1393,6 +1448,13 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
if (rv < SS_SUCCESS)
goto abort;

if (oc == C_WF_REPORT_PARAMS && val.conn == C_DISCONNECTING &&
!(flags & (CS_LOCAL_ONLY | CS_HARD))) {
rv = conn_cl_wide(tconn, mask, val, flags);
if (rv < SS_SUCCESS)
goto abort;
}

if (params.oc_state == OC_CONSISTENT) {
oc = params.oc;
print_conn_state_change(tconn, oc, val.conn);
Expand Down

0 comments on commit 912cfa3

Please sign in to comment.