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 bio *master_bio; /* master bio pointer */
|
||||
unsigned long rq_state; /* see comments above _req_mod() */
|
||||
unsigned long start_time;
|
||||
|
||||
/* once it hits 0, we may complete the master_bio */
|
||||
atomic_t completion_ref;
|
||||
/* once it hits 0, we may destroy this drbd_request object */
|
||||
struct kref kref;
|
||||
|
||||
unsigned rq_state; /* see comments above _req_mod() */
|
||||
};
|
||||
|
||||
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,
|
||||
* count writes in its epoch. */
|
||||
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 (!(s & RQ_WRITE))
|
||||
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 */
|
||||
__RQ_POSTPONED,
|
||||
|
||||
/* would have been completed,
|
||||
* but was not, because of drbd_suspended() */
|
||||
__RQ_COMPLETION_SUSP,
|
||||
|
||||
/* We expect a receive ACK (wire proto B) */
|
||||
__RQ_EXP_RECEIVE_ACK,
|
||||
|
||||
/* We expect a write ACK (wite proto C) */
|
||||
__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)
|
||||
@@ -230,8 +237,10 @@ enum drbd_req_state_bits {
|
||||
#define RQ_WRITE (1UL << __RQ_WRITE)
|
||||
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
|
||||
#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_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
|
||||
should be counted in the epoch object*/
|
||||
|
||||
Reference in New Issue
Block a user