You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
committed by
Philipp Reisner
parent
b406777e64
commit
a0d856dfae
@@ -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,
|
|||||||
/* 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;
|
||||||
|
|||||||
+272
-260
File diff suppressed because it is too large
Load Diff
@@ -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 {
|
|||||||
#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*/
|
||||||
|
|||||||
Reference in New Issue
Block a user