Commit a0d856df authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Philipp Reisner

drbd: base completion and destruction of requests on ref counts

cherry-picked and adapted from drbd 9 devel branch

The logic for when to get or put a reference is in mod_rq_state().

To not get confused in the freeze/thaw respectively resend/restart
paths, or when cleaning up requests waiting for P_BARRIER_ACK, this
also introduces additional state flags:
RQ_COMPLETION_SUSP, and RQ_EXP_BARR_ACK.
Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent b406777e
...@@ -575,13 +575,14 @@ struct drbd_request { ...@@ -575,13 +575,14 @@ struct drbd_request {
struct list_head tl_requests; /* ring list in the transfer log */ struct list_head tl_requests; /* ring list in the transfer log */
struct bio *master_bio; /* master bio pointer */ struct bio *master_bio; /* master bio pointer */
unsigned long rq_state; /* see comments above _req_mod() */
unsigned long start_time; unsigned long start_time;
/* once it hits 0, we may complete the master_bio */ /* once it hits 0, we may complete the master_bio */
atomic_t completion_ref; atomic_t completion_ref;
/* once it hits 0, we may destroy this drbd_request object */ /* once it hits 0, we may destroy this drbd_request object */
struct kref kref; struct kref kref;
unsigned rq_state; /* see comments above _req_mod() */
}; };
struct drbd_epoch { struct drbd_epoch {
......
...@@ -210,7 +210,7 @@ void tl_release(struct drbd_tconn *tconn, unsigned int barrier_nr, ...@@ -210,7 +210,7 @@ void tl_release(struct drbd_tconn *tconn, unsigned int barrier_nr,
/* find latest not yet barrier-acked write request, /* find latest not yet barrier-acked write request,
* count writes in its epoch. */ * count writes in its epoch. */
list_for_each_entry(r, &tconn->transfer_log, tl_requests) { list_for_each_entry(r, &tconn->transfer_log, tl_requests) {
const unsigned long s = r->rq_state; const unsigned s = r->rq_state;
if (!req) { if (!req) {
if (!(s & RQ_WRITE)) if (!(s & RQ_WRITE))
continue; continue;
......
This diff is collapsed.
...@@ -203,11 +203,18 @@ enum drbd_req_state_bits { ...@@ -203,11 +203,18 @@ enum drbd_req_state_bits {
/* The peer has sent a retry ACK */ /* The peer has sent a retry ACK */
__RQ_POSTPONED, __RQ_POSTPONED,
/* would have been completed,
* but was not, because of drbd_suspended() */
__RQ_COMPLETION_SUSP,
/* We expect a receive ACK (wire proto B) */ /* We expect a receive ACK (wire proto B) */
__RQ_EXP_RECEIVE_ACK, __RQ_EXP_RECEIVE_ACK,
/* We expect a write ACK (wite proto C) */ /* We expect a write ACK (wite proto C) */
__RQ_EXP_WRITE_ACK, __RQ_EXP_WRITE_ACK,
/* waiting for a barrier ack, did an extra kref_get */
__RQ_EXP_BARR_ACK,
}; };
#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING) #define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING)
...@@ -230,8 +237,10 @@ enum drbd_req_state_bits { ...@@ -230,8 +237,10 @@ enum drbd_req_state_bits {
#define RQ_WRITE (1UL << __RQ_WRITE) #define RQ_WRITE (1UL << __RQ_WRITE)
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG) #define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
#define RQ_POSTPONED (1UL << __RQ_POSTPONED) #define RQ_POSTPONED (1UL << __RQ_POSTPONED)
#define RQ_COMPLETION_SUSP (1UL << __RQ_COMPLETION_SUSP)
#define RQ_EXP_RECEIVE_ACK (1UL << __RQ_EXP_RECEIVE_ACK) #define RQ_EXP_RECEIVE_ACK (1UL << __RQ_EXP_RECEIVE_ACK)
#define RQ_EXP_WRITE_ACK (1UL << __RQ_EXP_WRITE_ACK) #define RQ_EXP_WRITE_ACK (1UL << __RQ_EXP_WRITE_ACK)
#define RQ_EXP_BARR_ACK (1UL << __RQ_EXP_BARR_ACK)
/* For waking up the frozen transfer log mod_req() has to return if the request /* For waking up the frozen transfer log mod_req() has to return if the request
should be counted in the epoch object*/ should be counted in the epoch object*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment