mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd
@ 2011-09-09 11:17 Philipp Reisner
  2011-09-09 11:17 ` [PATCH 01/11] drbd: Introduced drbd_read_state() Philipp Reisner
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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 
478 patches. This is the eighth installment containing 11 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 35b5cb2^...5129245

This patch series contains:
 * Ensure that state transitions that affect all volumes in a connections
   are only logged as state transition of the connections, not for the volumes

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 01/11] drbd: Introduced drbd_read_state()
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 02/11] drbd: Renamed id_susp(union drbd_state s) to drbd_suspended(struct drbd_conf *) Philipp Reisner
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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      |    9 +++++++++
 drivers/block/drbd/drbd_nl.c       |    5 ++---
 drivers/block/drbd/drbd_receiver.c |    6 +++---
 drivers/block/drbd/drbd_state.c    |   15 +++++++--------
 drivers/block/drbd/drbd_state.h    |    6 +++---
 drivers/block/drbd/drbd_worker.c   |    6 +++---
 6 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 54eb96a..ca07afd 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1682,6 +1682,15 @@ _drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 	return rv;
 }
 
+static inline union drbd_state drbd_read_state(struct drbd_conf *mdev)
+{
+	union drbd_state rv;
+
+	rv = mdev->state;
+
+	return rv;
+}
+
 #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)
 {
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 76b98b8..e43b47a 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1543,8 +1543,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 		drbd_suspend_al(mdev); /* IO is still suspended here... */
 
 	spin_lock_irq(&mdev->tconn->req_lock);
-	os = mdev->state;
-	ns.i = os.i;
+	os = drbd_read_state(mdev);
+	ns = os;
 	/* If MDF_CONSISTENT is not set go into inconsistent state,
 	   otherwise investigate MDF_WasUpToDate...
 	   If MDF_WAS_UP_TO_DATE is not set go into D_OUTDATED disk state,
@@ -1586,7 +1586,6 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
-	ns = mdev->state;
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (rv < SS_SUCCESS)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0b51f29..cd0fe24 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3476,7 +3476,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
 
 	spin_lock_irq(&mdev->tconn->req_lock);
  retry:
-	os = ns = mdev->state;
+	os = ns = drbd_read_state(mdev);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	/* peer says his disk is uptodate, while we think it is inconsistent,
@@ -3562,7 +3562,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
 	}
 
 	spin_lock_irq(&mdev->tconn->req_lock);
-	if (mdev->state.i != os.i)
+	if (os.i != drbd_read_state(mdev).i)
 		goto retry;
 	clear_bit(CONSIDER_RESYNC, &mdev->flags);
 	ns.peer = peer_state.role;
@@ -3584,7 +3584,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
 		return -EIO;
 	}
 	rv = _drbd_set_state(mdev, ns, cs_flags, NULL);
-	ns = mdev->state;
+	ns = drbd_read_state(mdev);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (rv < SS_SUCCESS) {
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index e2aab0d..2b7ba59 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -145,9 +145,8 @@ drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f,
 	enum drbd_state_rv rv;
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	ns = apply_mask_val(mdev->state, mask, val);
+	ns = apply_mask_val(drbd_read_state(mdev), mask, val);
 	rv = _drbd_set_state(mdev, ns, f, NULL);
-	ns = mdev->state;
 	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	return rv;
@@ -180,7 +179,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 		return SS_CW_FAILED_BY_PEER;
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	os = mdev->state;
+	os = drbd_read_state(mdev);
 	ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv == SS_SUCCESS)
@@ -226,7 +225,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 		mutex_lock(mdev->state_mutex);
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	os = mdev->state;
+	os = drbd_read_state(mdev);
 	ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv < SS_SUCCESS) {
@@ -262,7 +261,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 			goto abort;
 		}
 		spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-		ns = apply_mask_val(mdev->state, mask, val);
+		ns = apply_mask_val(drbd_read_state(mdev), mask, val);
 		rv = _drbd_set_state(mdev, ns, f, &done);
 	} else {
 		rv = _drbd_set_state(mdev, ns, f, &done);
@@ -794,7 +793,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 	const char *warn_sync_abort = NULL;
 	struct after_state_chg_work *ascw;
 
-	os = mdev->state;
+	os = drbd_read_state(mdev);
 
 	ns = sanitize_state(mdev, ns, &warn_sync_abort);
 	if (ns.i == os.i)
@@ -1412,7 +1411,7 @@ conn_is_valid_transition(struct drbd_tconn *tconn, union drbd_state mask, union
 	int vnr;
 
 	idr_for_each_entry(&tconn->volumes, mdev, vnr) {
-		os = mdev->state;
+		os = drbd_read_state(mdev);
 		ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL);
 
 		if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED)
@@ -1456,7 +1455,7 @@ conn_set_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state
 		tconn->cstate = val.conn;
 
 	idr_for_each_entry(&tconn->volumes, mdev, vnr) {
-		os = mdev->state;
+		os = drbd_read_state(mdev);
 		ns = apply_mask_val(os, mask, val);
 		ns = sanitize_state(mdev, ns, NULL);
 
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index c0331f1..fdcfab9 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -48,12 +48,12 @@ struct drbd_tconn;
 	  val.T2 = (S2); val.T3 = (S3); val; })
 
 #define _NS(D, T, S) \
-	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T = (S); __ns; })
+	D, ({ union drbd_state __ns; __ns = drbd_read_state(D); __ns.T = (S); __ns; })
 #define _NS2(D, T1, S1, T2, S2) \
-	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
+	D, ({ union drbd_state __ns; __ns = drbd_read_state(D); __ns.T1 = (S1); \
 	__ns.T2 = (S2); __ns; })
 #define _NS3(D, T1, S1, T2, S2, T3, S3) \
-	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
+	D, ({ union drbd_state __ns; __ns = drbd_read_state(D); __ns.T1 = (S1); \
 	__ns.T2 = (S2); __ns.T3 = (S3); __ns; })
 
 enum chg_state_flags {
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 640d04a..8059ea3 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -781,7 +781,7 @@ int drbd_resync_finished(struct drbd_conf *mdev)
 	ping_peer(mdev);
 
 	spin_lock_irq(&mdev->tconn->req_lock);
-	os = mdev->state;
+	os = drbd_read_state(mdev);
 
 	verify_done = (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T);
 
@@ -1548,7 +1548,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 	}
 
 	write_lock_irq(&global_state_lock);
-	ns = mdev->state;
+	ns = drbd_read_state(mdev);
 
 	ns.aftr_isp = !_drbd_may_sync_now(mdev);
 
@@ -1560,7 +1560,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 		ns.pdsk = D_INCONSISTENT;
 
 	r = __drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
-	ns = mdev->state;
+	ns = drbd_read_state(mdev);
 
 	if (ns.conn < C_CONNECTED)
 		r = SS_UNKNOWN_ERROR;
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 02/11] drbd: Renamed id_susp(union drbd_state s) to drbd_suspended(struct drbd_conf *)
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
  2011-09-09 11:17 ` [PATCH 01/11] drbd: Introduced drbd_read_state() Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 03/11] drbd: Moved susp, susp_nod and susp_fen to the connection object Philipp Reisner
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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      |    6 +++---
 drivers/block/drbd/drbd_nl.c       |    4 ++--
 drivers/block/drbd/drbd_proc.c     |    2 +-
 drivers/block/drbd/drbd_receiver.c |    4 ++--
 drivers/block/drbd/drbd_req.c      |    6 +++---
 drivers/block/drbd/drbd_state.c    |    7 ++++++-
 6 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ca07afd..4d17f9b 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -2217,16 +2217,16 @@ static inline int drbd_state_is_stable(struct drbd_conf *mdev)
 	return 1;
 }
 
-static inline int is_susp(union drbd_state s)
+static inline int drbd_suspended(struct drbd_conf *mdev)
 {
-	return s.susp || s.susp_nod || s.susp_fen;
+	return mdev->state.susp || mdev->state.susp_nod || mdev->state.susp_fen;
 }
 
 static inline bool may_inc_ap_bio(struct drbd_conf *mdev)
 {
 	int mxb = drbd_get_max_buffers(mdev);
 
-	if (is_susp(mdev->state))
+	if (drbd_suspended(mdev))
 		return false;
 	if (test_bit(SUSPEND_IO, &mdev->flags))
 		return false;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index e43b47a..57f320e 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -757,7 +757,7 @@ char *ppsize(char *buf, unsigned long long size)
 void drbd_suspend_io(struct drbd_conf *mdev)
 {
 	set_bit(SUSPEND_IO, &mdev->flags);
-	if (is_susp(mdev->state))
+	if (drbd_suspended(mdev))
 		return;
 	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
 }
@@ -1395,7 +1395,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 
 	drbd_suspend_io(mdev);
 	/* also wait for the last barrier ack. */
-	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt) || is_susp(mdev->state));
+	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt) || drbd_suspended(mdev));
 	/* and for any other previously queued work */
 	drbd_flush_workqueue(mdev);
 
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c
index 36c9a6c..a4dbdbc 100644
--- a/drivers/block/drbd/drbd_proc.c
+++ b/drivers/block/drbd/drbd_proc.c
@@ -250,7 +250,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
 			   drbd_disk_str(mdev->state.pdsk),
 			   (mdev->tconn->net_conf == NULL ? ' ' :
 			    (mdev->tconn->net_conf->wire_protocol - DRBD_PROT_A+'A')),
-			   is_susp(mdev->state) ? 's' : 'r',
+			   drbd_suspended(mdev) ? 's' : 'r',
 			   mdev->state.aftr_isp ? 'a' : '-',
 			   mdev->state.peer_isp ? 'p' : '-',
 			   mdev->state.user_isp ? 'u' : '-',
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index cd0fe24..d6afb3a 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3571,7 +3571,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
 	if ((ns.conn == C_CONNECTED || ns.conn == C_WF_BITMAP_S) && ns.disk == D_NEGOTIATING)
 		ns.disk = mdev->new_state_tmp.disk;
 	cs_flags = CS_VERBOSE + (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED ? 0 : CS_HARD);
-	if (ns.pdsk == D_CONSISTENT && is_susp(ns) && ns.conn == C_CONNECTED && os.conn < C_CONNECTED &&
+	if (ns.pdsk == D_CONSISTENT && drbd_suspended(mdev) && ns.conn == C_CONNECTED && os.conn < C_CONNECTED &&
 	    test_bit(NEW_CUR_UUID, &mdev->flags)) {
 		/* Do not allow tl_restart(RESEND) for a rebooted peer. We can only allow this
 		   for temporal network outages! */
@@ -4126,7 +4126,7 @@ static int drbd_disconnected(int vnr, void *p, void *data)
 	kfree(mdev->p_uuid);
 	mdev->p_uuid = NULL;
 
-	if (!is_susp(mdev->state))
+	if (!drbd_suspended(mdev))
 		tl_clear(mdev->tconn);
 
 	drbd_md_sync(mdev);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 6e0e3bb..e296d7e 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -303,7 +303,7 @@ static void _req_may_be_done_not_susp(struct drbd_request *req, struct bio_and_e
 {
 	struct drbd_conf *mdev = req->w.mdev;
 
-	if (!is_susp(mdev->state))
+	if (!drbd_suspended(mdev))
 		_req_may_be_done(req, m);
 }
 
@@ -789,7 +789,7 @@ int __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long s
 	send_oos = rw == WRITE && drbd_should_send_out_of_sync(mdev->state);
 	D_ASSERT(!(remote && send_oos));
 
-	if (!(local || remote) && !is_susp(mdev->state)) {
+	if (!(local || remote) && !drbd_suspended(mdev)) {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
 		err = -EIO;
@@ -830,7 +830,7 @@ allocate_barrier:
 		}
 	}
 
-	if (is_susp(mdev->state)) {
+	if (drbd_suspended(mdev)) {
 		/* If we got suspended, use the retry mechanism of
 		   generic_make_request() to restart processing of this
 		   bio. In the next call to drbd_make_request
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 2b7ba59..c9d9640 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -48,6 +48,11 @@ static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_st
 static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns,
 				       const char **warn_sync_abort);
 
+static inline bool is_susp(union drbd_state s)
+{
+        return s.susp || s.susp_nod || s.susp_fen;
+}
+
 bool conn_all_vols_unconf(struct drbd_tconn *tconn)
 {
 	struct drbd_conf *mdev;
@@ -1143,7 +1148,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 		if (get_ldev(mdev)) {
 			if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) &&
 			    mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
-				if (is_susp(mdev->state)) {
+				if (drbd_suspended(mdev)) {
 					set_bit(NEW_CUR_UUID, &mdev->flags);
 				} else {
 					drbd_uuid_new_current(mdev);
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 03/11] drbd: Moved susp, susp_nod and susp_fen to the connection object
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
  2011-09-09 11:17 ` [PATCH 01/11] drbd: Introduced drbd_read_state() Philipp Reisner
  2011-09-09 11:17 ` [PATCH 02/11] drbd: Renamed id_susp(union drbd_state s) to drbd_suspended(struct drbd_conf *) Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 04/11] drbd: Introduced a new type union drbd_dev_state Philipp Reisner
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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   |   10 +++++++++-
 drivers/block/drbd/drbd_state.c |    3 +++
 2 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4d17f9b..e33a770 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -862,6 +862,9 @@ struct drbd_tconn {			/* is a resource from the config file */
 	struct list_head all_tconn;	/* linked on global drbd_tconns */
 	struct idr volumes;		/* <tconn, vnr> to mdev mapping */
 	enum drbd_conns cstate;		/* Only C_STANDALONE to C_WF_REPORT_PARAMS */
+	unsigned susp:1;		/* IO suspended by user */
+	unsigned susp_nod:1;		/* IO suspended because no data */
+	unsigned susp_fen:1;		/* IO suspended because fence peer handler runs */
 	struct mutex cstate_mutex;	/* Protects graceful disconnects */
 
 	unsigned long flags;
@@ -1687,6 +1690,9 @@ static inline union drbd_state drbd_read_state(struct drbd_conf *mdev)
 	union drbd_state rv;
 
 	rv = mdev->state;
+	rv.susp = mdev->tconn->susp;
+	rv.susp_nod = mdev->tconn->susp_nod;
+	rv.susp_fen = mdev->tconn->susp_fen;
 
 	return rv;
 }
@@ -2219,7 +2225,9 @@ static inline int drbd_state_is_stable(struct drbd_conf *mdev)
 
 static inline int drbd_suspended(struct drbd_conf *mdev)
 {
-	return mdev->state.susp || mdev->state.susp_nod || mdev->state.susp_fen;
+	struct drbd_tconn *tconn = mdev->tconn;
+
+	return tconn->susp || tconn->susp_fen || tconn->susp_nod;
 }
 
 static inline bool may_inc_ap_bio(struct drbd_conf *mdev)
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index c9d9640..9354006 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -843,6 +843,9 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 		atomic_inc(&mdev->local_cnt);
 
 	mdev->state = ns;
+	mdev->tconn->susp = ns.susp;
+	mdev->tconn->susp_nod = ns.susp_nod;
+	mdev->tconn->susp_fen = ns.susp_fen;
 
 	/* solve the race between becoming unconfigured,
 	 * worker doing the cleanup, and
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 04/11] drbd: Introduced a new type union drbd_dev_state
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (2 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 03/11] drbd: Moved susp, susp_nod and susp_fen to the connection object Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 05/11] drbd: Renamed nms to ns_max Philipp Reisner
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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   |    6 +++---
 drivers/block/drbd/drbd_main.c  |    5 +----
 drivers/block/drbd/drbd_nl.c    |    4 ++--
 drivers/block/drbd/drbd_req.h   |    4 ++--
 drivers/block/drbd/drbd_state.c |    6 +++---
 drivers/block/drbd/drbd_state.h |   34 ++++++++++++++++++++++++++++++++++
 6 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e33a770..912ee5e 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -935,7 +935,7 @@ struct drbd_conf {
 	/* Used after attach while negotiating new disk state. */
 	union drbd_state new_state_tmp;
 
-	union drbd_state state;
+	union drbd_dev_state state;
 	wait_queue_head_t misc_wait;
 	wait_queue_head_t state_wait;  /* upon each state change. */
 	unsigned int send_cnt;
@@ -1689,7 +1689,7 @@ static inline union drbd_state drbd_read_state(struct drbd_conf *mdev)
 {
 	union drbd_state rv;
 
-	rv = mdev->state;
+	rv.i = mdev->state.i;
 	rv.susp = mdev->tconn->susp;
 	rv.susp_nod = mdev->tconn->susp_nod;
 	rv.susp_fen = mdev->tconn->susp_fen;
@@ -2155,7 +2155,7 @@ static inline int drbd_get_max_buffers(struct drbd_conf *mdev)
 
 static inline int drbd_state_is_stable(struct drbd_conf *mdev)
 {
-	union drbd_state s = mdev->state;
+	union drbd_dev_state s = mdev->state;
 
 	/* DO NOT add a default clause, we want the compiler to warn us
 	 * for any newly introduced state we may have forgotten to add here */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a773d73..a6459f7 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1823,15 +1823,12 @@ static void drbd_set_defaults(struct drbd_conf *mdev)
 {
 	/* Beware! The actual layout differs
 	 * between big endian and little endian */
-	mdev->state = (union drbd_state) {
+	mdev->state = (union drbd_dev_state) {
 		{ .role = R_SECONDARY,
 		  .peer = R_UNKNOWN,
 		  .conn = C_STANDALONE,
 		  .disk = D_DISKLESS,
 		  .pdsk = D_UNKNOWN,
-		  .susp = 0,
-		  .susp_nod = 0,
-		  .susp_fen = 0
 		} };
 }
 
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 57f320e..02d4224 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1475,7 +1475,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 		clear_bit(CRASHED_PRIMARY, &mdev->flags);
 
 	if (drbd_md_test_flag(mdev->ldev, MDF_PRIMARY_IND) &&
-	    !(mdev->state.role == R_PRIMARY && mdev->state.susp_nod)) {
+	    !(mdev->state.role == R_PRIMARY && mdev->tconn->susp_nod)) {
 		set_bit(CRASHED_PRIMARY, &mdev->flags);
 		cp_discovered = 1;
 	}
@@ -2402,7 +2402,7 @@ out:
 
 int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info)
 {
-	union drbd_state s;
+	union drbd_dev_state s;
 	enum drbd_ret_code retcode;
 
 	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 4e1f129..b9f474a 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -294,7 +294,7 @@ static inline int req_mod(struct drbd_request *req,
 	return rv;
 }
 
-static inline bool drbd_should_do_remote(union drbd_state s)
+static inline bool drbd_should_do_remote(union drbd_dev_state s)
 {
 	return s.pdsk == D_UP_TO_DATE ||
 		(s.pdsk >= D_INCONSISTENT &&
@@ -304,7 +304,7 @@ static inline bool drbd_should_do_remote(union drbd_state s)
 	   That is equivalent since before 96 IO was frozen in the C_WF_BITMAP*
 	   states. */
 }
-static inline bool drbd_should_send_out_of_sync(union drbd_state s)
+static inline bool drbd_should_send_out_of_sync(union drbd_dev_state s)
 {
 	return s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S;
 	/* pdsk = D_INCONSISTENT as a consequence. Protocol 96 check not necessary
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 9354006..64284b8 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -842,7 +842,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 	    (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))
 		atomic_inc(&mdev->local_cnt);
 
-	mdev->state = ns;
+	mdev->state.i = ns.i;
 	mdev->tconn->susp = ns.susp;
 	mdev->tconn->susp_nod = ns.susp_nod;
 	mdev->tconn->susp_fen = ns.susp_fen;
@@ -1375,7 +1375,7 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
 void conn_old_common_state(struct drbd_tconn *tconn, union drbd_state *pcs, enum chg_state_flags *pf)
 {
 	enum chg_state_flags flags = ~0;
-	union drbd_state os, cs = {}; /* old_state, common_state */
+	union drbd_dev_state os, cs = {}; /* old_state, common_state */
 	struct drbd_conf *mdev;
 	int vnr, first_vol = 1;
 
@@ -1406,7 +1406,7 @@ void conn_old_common_state(struct drbd_tconn *tconn, union drbd_state *pcs, enum
 
 	*pf |= CS_DC_MASK;
 	*pf &= flags;
-	*pcs = cs;
+	(*pcs).i = cs.i;
 }
 
 static enum drbd_state_rv
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index fdcfab9..0f8441d 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -72,6 +72,40 @@ enum chg_state_flags {
 	CS_IGN_OUTD_FAIL = 1 << 10,
 };
 
+/* drbd_dev_state and drbd_state are different types. This is to stress the
+   small difference. There is no suspended flag (.susp), and no suspended
+   while fence handler runs flas (susp_fen). */
+union drbd_dev_state {
+	struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+		unsigned role:2 ;   /* 3/4	 primary/secondary/unknown */
+		unsigned peer:2 ;   /* 3/4	 primary/secondary/unknown */
+		unsigned conn:5 ;   /* 17/32	 cstates */
+		unsigned disk:4 ;   /* 8/16	 from D_DISKLESS to D_UP_TO_DATE */
+		unsigned pdsk:4 ;   /* 8/16	 from D_DISKLESS to D_UP_TO_DATE */
+		unsigned _unused:1 ;
+		unsigned aftr_isp:1 ; /* isp .. imposed sync pause */
+		unsigned peer_isp:1 ;
+		unsigned user_isp:1 ;
+		unsigned _pad:11;   /* 0	 unused */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+		unsigned _pad:11;
+		unsigned user_isp:1 ;
+		unsigned peer_isp:1 ;
+		unsigned aftr_isp:1 ; /* isp .. imposed sync pause */
+		unsigned _unused:1 ;
+		unsigned pdsk:4 ;   /* 8/16	 from D_DISKLESS to D_UP_TO_DATE */
+		unsigned disk:4 ;   /* 8/16	 from D_DISKLESS to D_UP_TO_DATE */
+		unsigned conn:5 ;   /* 17/32	 cstates */
+		unsigned peer:2 ;   /* 3/4	 primary/secondary/unknown */
+		unsigned role:2 ;   /* 3/4	 primary/secondary/unknown */
+#else
+# error "this endianess is not supported"
+#endif
+	};
+	unsigned int i;
+};
+
 extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev,
 					    enum chg_state_flags f,
 					    union drbd_state mask,
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 05/11] drbd: Renamed nms to ns_max
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (3 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 04/11] drbd: Introduced a new type union drbd_dev_state Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 06/11] drbd: Calculate and provide ns_min to the w_after_conn_state_ch() work Philipp Reisner
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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_state.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 64284b8..bd50644 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1340,7 +1340,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 struct after_conn_state_chg_work {
 	struct drbd_work w;
 	enum drbd_conns oc;
-	union drbd_state nms; /* new, max state, over all mdevs */
+	union drbd_state ns_max; /* new, max state, over all mdevs */
 	enum chg_state_flags flags;
 };
 
@@ -1358,12 +1358,12 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
 		container_of(w, struct after_conn_state_chg_work, w);
 	struct drbd_tconn *tconn = w->tconn;
 	enum drbd_conns oc = acscw->oc;
-	union drbd_state nms = acscw->nms;
+	union drbd_state ns_max = acscw->ns_max;
 
 	kfree(acscw);
 
 	/* Upon network configuration, we need to start the receiver */
-	if (oc == C_STANDALONE && nms.conn == C_UNCONNECTED)
+	if (oc == C_STANDALONE && ns_max.conn == C_UNCONNECTED)
 		drbd_thread_start(&tconn->receiver);
 
 	//conn_err(tconn, STATE_FMT, STATE_ARGS("nms", nms));
@@ -1541,7 +1541,7 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	enum drbd_state_rv rv = SS_SUCCESS;
 	struct after_conn_state_chg_work *acscw;
 	enum drbd_conns oc = tconn->cstate;
-	union drbd_state ms, os;
+	union drbd_state ns_max, os;
 
 	rv = is_valid_conn_transition(oc, val.conn);
 	if (rv < SS_SUCCESS)
@@ -1558,14 +1558,14 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	}
 
 	conn_old_common_state(tconn, &os, &flags);
-	ms = conn_set_state(tconn, mask, val, flags);
-	ms.conn = val.conn;
-	conn_pr_state_change(tconn, os, ms, flags);
+	ns_max = conn_set_state(tconn, mask, val, flags);
+	ns_max.conn = val.conn;
+	conn_pr_state_change(tconn, os, ns_max, flags);
 
 	acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC);
 	if (acscw) {
 		acscw->oc = os.conn;
-		acscw->nms = ms;
+		acscw->ns_max = ns_max;
 		acscw->flags = flags;
 		acscw->w.cb = w_after_conn_state_ch;
 		acscw->w.tconn = tconn;
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 06/11] drbd: Calculate and provide ns_min to the w_after_conn_state_ch() work
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (4 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 05/11] drbd: Renamed nms to ns_max Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 07/11] drbd: Implemented conn_lowest_conn() Philipp Reisner
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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_state.c |   42 ++++++++++++++++++++++++++++----------
 1 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index bd50644..cfd923e 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1340,6 +1340,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 struct after_conn_state_chg_work {
 	struct drbd_work w;
 	enum drbd_conns oc;
+	union drbd_state ns_min;
 	union drbd_state ns_max; /* new, max state, over all mdevs */
 	enum chg_state_flags flags;
 };
@@ -1450,11 +1451,17 @@ conn_is_valid_transition(struct drbd_tconn *tconn, union drbd_state mask, union
 	return rv;
 }
 
-static union drbd_state
+void
 conn_set_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
-	       enum chg_state_flags flags)
+	       union drbd_state *pns_min, union drbd_state *pns_max, enum chg_state_flags flags)
 {
-	union drbd_state ns, os, ms = { };
+	union drbd_state ns, os, ns_max = { };
+	union drbd_state ns_min = {
+		{ .role = R_MASK,
+		  .peer = R_MASK,
+		  .disk = D_MASK,
+		  .pdsk = D_MASK
+		} };
 	struct drbd_conf *mdev;
 	enum drbd_state_rv rv;
 	int vnr;
@@ -1474,13 +1481,26 @@ conn_set_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state
 		if (rv < SS_SUCCESS)
 			BUG();
 
-		ms.role = max_t(enum drbd_role, mdev->state.role, ms.role);
-		ms.peer = max_t(enum drbd_role, mdev->state.peer, ms.peer);
-		ms.disk = max_t(enum drbd_disk_state, mdev->state.disk, ms.disk);
-		ms.pdsk = max_t(enum drbd_disk_state, mdev->state.pdsk, ms.pdsk);
+		ns.i = mdev->state.i;
+		ns_max.role = max_t(enum drbd_role, ns.role, ns_max.role);
+		ns_max.peer = max_t(enum drbd_role, ns.peer, ns_max.peer);
+		ns_max.conn = max_t(enum drbd_role, ns.conn, ns_max.conn);
+		ns_max.disk = max_t(enum drbd_disk_state, ns.disk, ns_max.disk);
+		ns_max.pdsk = max_t(enum drbd_disk_state, ns.pdsk, ns_max.pdsk);
+
+		ns_min.role = min_t(enum drbd_role, ns.role, ns_min.role);
+		ns_min.peer = min_t(enum drbd_role, ns.peer, ns_min.peer);
+		ns_min.conn = min_t(enum drbd_role, ns.conn, ns_min.conn);
+		ns_min.disk = min_t(enum drbd_disk_state, ns.disk, ns_min.disk);
+		ns_min.pdsk = min_t(enum drbd_disk_state, ns.pdsk, ns_min.pdsk);
 	}
 
-	return ms;
+	ns_min.susp = ns_max.susp = tconn->susp;
+	ns_min.susp_nod = ns_max.susp_nod = tconn->susp_nod;
+	ns_min.susp_fen = ns_max.susp_fen = tconn->susp_fen;
+
+	*pns_min = ns_min;
+	*pns_max = ns_max;
 }
 
 static enum drbd_state_rv
@@ -1541,7 +1561,7 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	enum drbd_state_rv rv = SS_SUCCESS;
 	struct after_conn_state_chg_work *acscw;
 	enum drbd_conns oc = tconn->cstate;
-	union drbd_state ns_max, os;
+	union drbd_state ns_max, ns_min, os;
 
 	rv = is_valid_conn_transition(oc, val.conn);
 	if (rv < SS_SUCCESS)
@@ -1558,13 +1578,13 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	}
 
 	conn_old_common_state(tconn, &os, &flags);
-	ns_max = conn_set_state(tconn, mask, val, flags);
-	ns_max.conn = val.conn;
+	conn_set_state(tconn, mask, val, &ns_min, &ns_max, flags);
 	conn_pr_state_change(tconn, os, ns_max, flags);
 
 	acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC);
 	if (acscw) {
 		acscw->oc = os.conn;
+		acscw->ns_min = ns_min;
 		acscw->ns_max = ns_max;
 		acscw->flags = flags;
 		acscw->w.cb = w_after_conn_state_ch;
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 07/11] drbd: Implemented conn_lowest_conn()
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (5 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 06/11] drbd: Calculate and provide ns_min to the w_after_conn_state_ch() work Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 08/11] drbd: Implemented conn_lowest_disk() Philipp Reisner
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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_state.c |   12 ++++++++++++
 drivers/block/drbd/drbd_state.h |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index cfd923e..e441d1f 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -115,6 +115,18 @@ enum drbd_disk_state conn_highest_pdsk(struct drbd_tconn *tconn)
 	return ds;
 }
 
+enum drbd_disk_state conn_lowest_conn(struct drbd_tconn *tconn)
+{
+	enum drbd_conns conn = C_MASK;
+	struct drbd_conf *mdev;
+	int vnr;
+
+	idr_for_each_entry(&tconn->volumes, mdev, vnr)
+		conn = min_t(enum drbd_conns, conn, mdev->state.conn);
+
+	return conn;
+}
+
 /**
  * cl_wide_st_chg() - true if the state change is a cluster wide one
  * @mdev:	DRBD device.
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index 0f8441d..e554537 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -154,5 +154,6 @@ enum drbd_role conn_highest_role(struct drbd_tconn *tconn);
 enum drbd_role conn_highest_peer(struct drbd_tconn *tconn);
 enum drbd_disk_state conn_highest_disk(struct drbd_tconn *tconn);
 enum drbd_disk_state conn_highest_pdsk(struct drbd_tconn *tconn);
+enum drbd_disk_state conn_lowest_conn(struct drbd_tconn *tconn);
 
 #endif
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 08/11] drbd: Implemented conn_lowest_disk()
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (6 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 07/11] drbd: Implemented conn_lowest_conn() Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 09/11] drbd: Implemented IO thawing for multiple volumes Philipp Reisner
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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_state.c |   12 ++++++++++++
 drivers/block/drbd/drbd_state.h |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index e441d1f..5db514e 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -103,6 +103,18 @@ enum drbd_disk_state conn_highest_disk(struct drbd_tconn *tconn)
 	return ds;
 }
 
+enum drbd_disk_state conn_lowest_disk(struct drbd_tconn *tconn)
+{
+	enum drbd_disk_state ds = D_MASK;
+	struct drbd_conf *mdev;
+	int vnr;
+
+	idr_for_each_entry(&tconn->volumes, mdev, vnr)
+		ds = min_t(enum drbd_disk_state, ds, mdev->state.disk);
+
+	return ds;
+}
+
 enum drbd_disk_state conn_highest_pdsk(struct drbd_tconn *tconn)
 {
 	enum drbd_disk_state ds = D_DISKLESS;
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index e554537..72e2053 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -153,6 +153,7 @@ static inline int drbd_request_state(struct drbd_conf *mdev,
 enum drbd_role conn_highest_role(struct drbd_tconn *tconn);
 enum drbd_role conn_highest_peer(struct drbd_tconn *tconn);
 enum drbd_disk_state conn_highest_disk(struct drbd_tconn *tconn);
+enum drbd_disk_state conn_lowest_disk(struct drbd_tconn *tconn);
 enum drbd_disk_state conn_highest_pdsk(struct drbd_tconn *tconn);
 enum drbd_disk_state conn_lowest_conn(struct drbd_tconn *tconn);
 
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 09/11] drbd: Implemented IO thawing for multiple volumes
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (7 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 08/11] drbd: Implemented conn_lowest_disk() Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 10/11] drbd: Improved logging of state changes Philipp Reisner
  2011-09-09 11:17 ` [PATCH 11/11] drbd: Use tconn in request_timer_fn() Philipp Reisner
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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_state.c |   72 +++++++++++++++++++++-----------------
 1 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 5db514e..441d80f 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1070,8 +1070,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			   union drbd_state ns, enum chg_state_flags flags)
 {
 	enum drbd_fencing_p fp;
-	enum drbd_req_event what = NOTHING;
-	union drbd_state nsm;
 	struct sib_info sib;
 
 	sib.sib_reason = SIB_STATE_CHANGE;
@@ -1100,44 +1098,21 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 	/* Here we have the actions that are performed after a
 	   state change. This function might sleep */
 
-	nsm.i = -1;
 	if (ns.susp_nod) {
-		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
+		enum drbd_req_event what = NOTHING;
+
+		if (os.conn < C_CONNECTED && conn_lowest_conn(mdev->tconn) >= C_CONNECTED)
 			what = RESEND;
 
-		if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING)
+		if (os.disk == D_ATTACHING && conn_lowest_disk(mdev->tconn) > D_ATTACHING)
 			what = RESTART_FROZEN_DISK_IO;
 
-		if (what != NOTHING)
-			nsm.susp_nod = 0;
-	}
-
-	if (ns.susp_fen) {
-		/* case1: The outdate peer handler is successful: */
-		if (os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) {
-			tl_clear(mdev->tconn);
-			if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
-				drbd_uuid_new_current(mdev);
-				clear_bit(NEW_CUR_UUID, &mdev->flags);
-			}
+		if (what != NOTHING) {
 			spin_lock_irq(&mdev->tconn->req_lock);
-			_drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);
+			_tl_restart(mdev->tconn, what);
+			_drbd_set_state(_NS(mdev, susp_nod, 0), CS_VERBOSE, NULL);
 			spin_unlock_irq(&mdev->tconn->req_lock);
 		}
-		/* case2: The connection was established again: */
-		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
-			clear_bit(NEW_CUR_UUID, &mdev->flags);
-			what = RESEND;
-			nsm.susp_fen = 0;
-		}
-	}
-
-	if (what != NOTHING) {
-		spin_lock_irq(&mdev->tconn->req_lock);
-		_tl_restart(mdev->tconn, what);
-		nsm.i &= mdev->state.i;
-		_drbd_set_state(mdev, nsm, CS_VERBOSE, NULL);
-		spin_unlock_irq(&mdev->tconn->req_lock);
 	}
 
 	/* Became sync source.  With protocol >= 96, we still need to send out
@@ -1384,6 +1359,9 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
 	struct drbd_tconn *tconn = w->tconn;
 	enum drbd_conns oc = acscw->oc;
 	union drbd_state ns_max = acscw->ns_max;
+	union drbd_state ns_min = acscw->ns_min;
+	struct drbd_conf *mdev;
+	int vnr;
 
 	kfree(acscw);
 
@@ -1391,6 +1369,36 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
 	if (oc == C_STANDALONE && ns_max.conn == C_UNCONNECTED)
 		drbd_thread_start(&tconn->receiver);
 
+	if (ns_max.susp_fen) {
+		/* case1: The outdate peer handler is successful: */
+		if (ns_max.pdsk <= D_OUTDATED) {
+			tl_clear(tconn);
+			idr_for_each_entry(&tconn->volumes, mdev, vnr) {
+				if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
+					drbd_uuid_new_current(mdev);
+					clear_bit(NEW_CUR_UUID, &mdev->flags);
+				}
+			}
+			conn_request_state(tconn,
+					   (union drbd_state) { { .susp_fen = 1 } },
+					   (union drbd_state) { { .susp_fen = 0 } },
+					   CS_VERBOSE);
+		}
+		/* case2: The connection was established again: */
+		if (ns_min.conn >= C_CONNECTED) {
+			idr_for_each_entry(&tconn->volumes, mdev, vnr)
+				clear_bit(NEW_CUR_UUID, &mdev->flags);
+			spin_lock_irq(&tconn->req_lock);
+			_tl_restart(tconn, RESEND);
+			_conn_request_state(tconn,
+					    (union drbd_state) { { .susp_fen = 1 } },
+					    (union drbd_state) { { .susp_fen = 0 } },
+					    CS_VERBOSE);
+			spin_unlock_irq(&tconn->req_lock);
+		}
+	}
+
+
 	//conn_err(tconn, STATE_FMT, STATE_ARGS("nms", nms));
 	after_all_state_ch(tconn);
 
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 10/11] drbd: Improved logging of state changes
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (8 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 09/11] drbd: Implemented IO thawing for multiple volumes Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  2011-09-09 11:17 ` [PATCH 11/11] drbd: Use tconn in request_timer_fn() Philipp Reisner
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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_state.c |   44 ++++++++++++++++++++++++++------------
 drivers/block/drbd/drbd_state.h |    3 +-
 2 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 441d80f..694bd3f 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -366,6 +366,7 @@ static long print_state_change(char *pb, union drbd_state os, union drbd_state n
 	char *pbp;
 	pbp = pb;
 	*pbp = 0;
+
 	if (ns.role != os.role && flags & CS_DC_ROLE)
 		pbp += sprintf(pbp, "role( %s -> %s ) ",
 			       drbd_role_str(os.role),
@@ -386,10 +387,18 @@ static long print_state_change(char *pb, union drbd_state os, union drbd_state n
 		pbp += sprintf(pbp, "pdsk( %s -> %s ) ",
 			       drbd_disk_str(os.pdsk),
 			       drbd_disk_str(ns.pdsk));
-	if (is_susp(ns) != is_susp(os))
-		pbp += sprintf(pbp, "susp( %d -> %d ) ",
-			       is_susp(os),
-			       is_susp(ns));
+
+	return pbp - pb;
+}
+
+static void drbd_pr_state_change(struct drbd_conf *mdev, union drbd_state os, union drbd_state ns,
+				 enum chg_state_flags flags)
+{
+	char pb[300];
+	char *pbp = pb;
+
+	pbp += print_state_change(pbp, os, ns, flags ^ CS_DC_MASK);
+
 	if (ns.aftr_isp != os.aftr_isp)
 		pbp += sprintf(pbp, "aftr_isp( %d -> %d ) ",
 			       os.aftr_isp,
@@ -403,15 +412,7 @@ static long print_state_change(char *pb, union drbd_state os, union drbd_state n
 			       os.user_isp,
 			       ns.user_isp);
 
-	return pbp - pb;
-}
-
-static void drbd_pr_state_change(struct drbd_conf *mdev, union drbd_state os, union drbd_state ns,
-				 enum chg_state_flags flags)
-{
-	char pb[300];
-
-	if (print_state_change(pb, os, ns, flags ^ CS_DC_MASK))
+	if (pbp != pb)
 		dev_info(DEV, "%s\n", pb);
 }
 
@@ -419,8 +420,16 @@ static void conn_pr_state_change(struct drbd_tconn *tconn, union drbd_state os,
 				 enum chg_state_flags flags)
 {
 	char pb[300];
+	char *pbp = pb;
+
+	pbp += print_state_change(pbp, os, ns, flags);
 
-	if (print_state_change(pb, os, ns, flags))
+	if (is_susp(ns) != is_susp(os) && flags & CS_DC_SUSP)
+		pbp += sprintf(pbp, "susp( %d -> %d ) ",
+			       is_susp(os),
+			       is_susp(ns));
+
+	if (pbp != pb)
 		conn_info(tconn, "%s\n", pb);
 }
 
@@ -858,6 +867,12 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 
 	drbd_pr_state_change(mdev, os, ns, flags);
 
+	/* Display changes to the susp* flags that where caused by the call to
+	   sanitize_state(). Only display it here if we where not called from
+	   _conn_request_state() */
+	if (!(flags & CS_DC_SUSP))
+		conn_pr_state_change(mdev->tconn, os, ns, (flags & ~CS_DC_MASK) | CS_DC_SUSP);
+
 	/* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference
 	 * on the ldev here, to be sure the transition -> D_DISKLESS resp.
 	 * drbd_ldev_destroy() won't happen before our corresponding
@@ -1610,6 +1625,7 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	}
 
 	conn_old_common_state(tconn, &os, &flags);
+	flags |= CS_DC_SUSP;
 	conn_set_state(tconn, mask, val, &ns_min, &ns_max, flags);
 	conn_pr_state_change(tconn, os, ns_max, flags);
 
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index 72e2053..a49bece 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -68,8 +68,9 @@ enum chg_state_flags {
 	CS_DC_CONN       = 1 << 7,
 	CS_DC_DISK       = 1 << 8,
 	CS_DC_PDSK       = 1 << 9,
+	CS_DC_SUSP       = 1 << 10,
 	CS_DC_MASK       = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK,
-	CS_IGN_OUTD_FAIL = 1 << 10,
+	CS_IGN_OUTD_FAIL = 1 << 11,
 };
 
 /* drbd_dev_state and drbd_state are different types. This is to stress the
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 11/11] drbd: Use tconn in request_timer_fn()
  2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
                   ` (9 preceding siblings ...)
  2011-09-09 11:17 ` [PATCH 10/11] drbd: Improved logging of state changes Philipp Reisner
@ 2011-09-09 11:17 ` Philipp Reisner
  10 siblings, 0 replies; 12+ messages in thread
From: Philipp Reisner @ 2011-09-09 11:17 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_receiver.c |    1 +
 drivers/block/drbd/drbd_req.c      |   15 ++++++++-------
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index d6afb3a..6e6b829 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -794,6 +794,7 @@ int drbd_connected(int vnr, void *p, void *data)
 		err = drbd_send_state(mdev);
 	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
 	clear_bit(RESIZE_PENDING, &mdev->flags);
+	mod_timer(&mdev->request_timer, jiffies + HZ); /* just start it here. */
 	return err;
 }
 
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index e296d7e..fd0b452 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -1047,21 +1047,22 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct
 void request_timer_fn(unsigned long data)
 {
 	struct drbd_conf *mdev = (struct drbd_conf *) data;
+	struct drbd_tconn *tconn = mdev->tconn;
 	struct drbd_request *req; /* oldest request */
 	struct list_head *le;
 	unsigned long et = 0; /* effective timeout = ko_count * timeout */
 
-	if (get_net_conf(mdev->tconn)) {
-		et = mdev->tconn->net_conf->timeout*HZ/10 * mdev->tconn->net_conf->ko_count;
-		put_net_conf(mdev->tconn);
+	if (get_net_conf(tconn)) {
+		et = tconn->net_conf->timeout*HZ/10 * tconn->net_conf->ko_count;
+		put_net_conf(tconn);
 	}
 	if (!et || mdev->state.conn < C_WF_REPORT_PARAMS)
 		return; /* Recurring timer stopped */
 
-	spin_lock_irq(&mdev->tconn->req_lock);
-	le = &mdev->tconn->oldest_tle->requests;
+	spin_lock_irq(&tconn->req_lock);
+	le = &tconn->oldest_tle->requests;
 	if (list_empty(le)) {
-		spin_unlock_irq(&mdev->tconn->req_lock);
+		spin_unlock_irq(&tconn->req_lock);
 		mod_timer(&mdev->request_timer, jiffies + et);
 		return;
 	}
@@ -1080,5 +1081,5 @@ void request_timer_fn(unsigned long data)
 		mod_timer(&mdev->request_timer, req->start_time + et);
 	}
 
-	spin_unlock_irq(&mdev->tconn->req_lock);
+	spin_unlock_irq(&tconn->req_lock);
 }
-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-09-09 11:19 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-09 11:17 [RFC 00/11] drbd: part 9 of adding multiple volume support to drbd Philipp Reisner
2011-09-09 11:17 ` [PATCH 01/11] drbd: Introduced drbd_read_state() Philipp Reisner
2011-09-09 11:17 ` [PATCH 02/11] drbd: Renamed id_susp(union drbd_state s) to drbd_suspended(struct drbd_conf *) Philipp Reisner
2011-09-09 11:17 ` [PATCH 03/11] drbd: Moved susp, susp_nod and susp_fen to the connection object Philipp Reisner
2011-09-09 11:17 ` [PATCH 04/11] drbd: Introduced a new type union drbd_dev_state Philipp Reisner
2011-09-09 11:17 ` [PATCH 05/11] drbd: Renamed nms to ns_max Philipp Reisner
2011-09-09 11:17 ` [PATCH 06/11] drbd: Calculate and provide ns_min to the w_after_conn_state_ch() work Philipp Reisner
2011-09-09 11:17 ` [PATCH 07/11] drbd: Implemented conn_lowest_conn() Philipp Reisner
2011-09-09 11:17 ` [PATCH 08/11] drbd: Implemented conn_lowest_disk() Philipp Reisner
2011-09-09 11:17 ` [PATCH 09/11] drbd: Implemented IO thawing for multiple volumes Philipp Reisner
2011-09-09 11:17 ` [PATCH 10/11] drbd: Improved logging of state changes Philipp Reisner
2011-09-09 11:17 ` [PATCH 11/11] drbd: Use tconn in request_timer_fn() Philipp Reisner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®