Commit ce668b6d authored by Christoph Böhmwalder's avatar Christoph Böhmwalder Committed by Jens Axboe

drbd: Store op in drbd_peer_request

(Sort of) cherry-picked from the out-of-tree drbd9 branch. Original
commit message by Joel Colledge:

    This simplifies drbd_submit_peer_request by removing most of the
    arguments. It also makes the treatment of the op better aligned with
    that in struct bio.

    Determine fault_type dynamically using information which is already
    available instead of passing it in as a parameter.

Note: The opf in receive_rs_deallocated was changed from
REQ_OP_WRITE_ZEROES to REQ_OP_DISCARD. This was required in the
out-of-tree module, and does not matter in-tree. The opf is ignored
anyway in drbd_submit_peer_request, since the discard/zero-out is
decided by the EE_TRIM flag.
Signed-off-by: default avatarJoel Colledge <joel.colledge@linbit.com>
Signed-off-by: default avatarChristoph Böhmwalder <christoph.boehmwalder@linbit.com>
Link: https://lore.kernel.org/r/20221109133453.51652-4-christoph.boehmwalder@linbit.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 21b87a7d
...@@ -395,6 +395,7 @@ struct drbd_peer_request { ...@@ -395,6 +395,7 @@ struct drbd_peer_request {
struct drbd_peer_device *peer_device; struct drbd_peer_device *peer_device;
struct drbd_epoch *epoch; /* for writes */ struct drbd_epoch *epoch; /* for writes */
struct page *pages; struct page *pages;
blk_opf_t opf;
atomic_t pending_bios; atomic_t pending_bios;
struct drbd_interval i; struct drbd_interval i;
/* see comments on ee flag bits below */ /* see comments on ee flag bits below */
...@@ -406,6 +407,10 @@ struct drbd_peer_request { ...@@ -406,6 +407,10 @@ struct drbd_peer_request {
}; };
}; };
/* Equivalent to bio_op and req_op. */
#define peer_req_op(peer_req) \
((peer_req)->opf & REQ_OP_MASK)
/* ee flag bits. /* ee flag bits.
* While corresponding bios are in flight, the only modification will be * While corresponding bios are in flight, the only modification will be
* set_bit WAS_ERROR, which has to be atomic. * set_bit WAS_ERROR, which has to be atomic.
...@@ -1545,8 +1550,7 @@ extern void drbd_send_acks_wf(struct work_struct *ws); ...@@ -1545,8 +1550,7 @@ extern void drbd_send_acks_wf(struct work_struct *ws);
extern bool drbd_rs_c_min_rate_throttle(struct drbd_device *device); extern bool drbd_rs_c_min_rate_throttle(struct drbd_device *device);
extern bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector, extern bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector,
bool throttle_if_app_is_waiting); bool throttle_if_app_is_waiting);
extern int drbd_submit_peer_request(struct drbd_device *, extern int drbd_submit_peer_request(struct drbd_peer_request *peer_req);
struct drbd_peer_request *, blk_opf_t, int);
extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *); extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *);
extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64, extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64,
sector_t, unsigned int, sector_t, unsigned int,
......
...@@ -1603,9 +1603,19 @@ static void drbd_issue_peer_discard_or_zero_out(struct drbd_device *device, stru ...@@ -1603,9 +1603,19 @@ static void drbd_issue_peer_discard_or_zero_out(struct drbd_device *device, stru
drbd_endio_write_sec_final(peer_req); drbd_endio_write_sec_final(peer_req);
} }
static int peer_request_fault_type(struct drbd_peer_request *peer_req)
{
if (peer_req_op(peer_req) == REQ_OP_READ) {
return peer_req->flags & EE_APPLICATION ?
DRBD_FAULT_DT_RD : DRBD_FAULT_RS_RD;
} else {
return peer_req->flags & EE_APPLICATION ?
DRBD_FAULT_DT_WR : DRBD_FAULT_RS_WR;
}
}
/** /**
* drbd_submit_peer_request() * drbd_submit_peer_request()
* @device: DRBD device.
* @peer_req: peer request * @peer_req: peer request
* *
* May spread the pages to multiple bios, * May spread the pages to multiple bios,
...@@ -1619,10 +1629,9 @@ static void drbd_issue_peer_discard_or_zero_out(struct drbd_device *device, stru ...@@ -1619,10 +1629,9 @@ static void drbd_issue_peer_discard_or_zero_out(struct drbd_device *device, stru
* on certain Xen deployments. * on certain Xen deployments.
*/ */
/* TODO allocate from our own bio_set. */ /* TODO allocate from our own bio_set. */
int drbd_submit_peer_request(struct drbd_device *device, int drbd_submit_peer_request(struct drbd_peer_request *peer_req)
struct drbd_peer_request *peer_req,
const blk_opf_t opf, const int fault_type)
{ {
struct drbd_device *device = peer_req->peer_device->device;
struct bio *bios = NULL; struct bio *bios = NULL;
struct bio *bio; struct bio *bio;
struct page *page = peer_req->pages; struct page *page = peer_req->pages;
...@@ -1667,7 +1676,18 @@ int drbd_submit_peer_request(struct drbd_device *device, ...@@ -1667,7 +1676,18 @@ int drbd_submit_peer_request(struct drbd_device *device,
* generated bio, but a bio allocated on behalf of the peer. * generated bio, but a bio allocated on behalf of the peer.
*/ */
next_bio: next_bio:
bio = bio_alloc(device->ldev->backing_bdev, nr_pages, opf, GFP_NOIO); /* _DISCARD, _WRITE_ZEROES handled above.
* REQ_OP_FLUSH (empty flush) not expected,
* should have been mapped to a "drbd protocol barrier".
* REQ_OP_SECURE_ERASE: I don't see how we could ever support that.
*/
if (!(peer_req_op(peer_req) == REQ_OP_WRITE ||
peer_req_op(peer_req) == REQ_OP_READ)) {
drbd_err(device, "Invalid bio op received: 0x%x\n", peer_req->opf);
return -EINVAL;
}
bio = bio_alloc(device->ldev->backing_bdev, nr_pages, peer_req->opf, GFP_NOIO);
/* > peer_req->i.sector, unless this is the first bio */ /* > peer_req->i.sector, unless this is the first bio */
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_private = peer_req; bio->bi_private = peer_req;
...@@ -1697,7 +1717,7 @@ int drbd_submit_peer_request(struct drbd_device *device, ...@@ -1697,7 +1717,7 @@ int drbd_submit_peer_request(struct drbd_device *device,
bios = bios->bi_next; bios = bios->bi_next;
bio->bi_next = NULL; bio->bi_next = NULL;
drbd_submit_bio_noacct(device, fault_type, bio); drbd_submit_bio_noacct(device, peer_request_fault_type(peer_req), bio);
} while (bios); } while (bios);
return 0; return 0;
} }
...@@ -2051,6 +2071,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto ...@@ -2051,6 +2071,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
* respective _drbd_clear_done_ee */ * respective _drbd_clear_done_ee */
peer_req->w.cb = e_end_resync_block; peer_req->w.cb = e_end_resync_block;
peer_req->opf = REQ_OP_WRITE;
peer_req->submit_jif = jiffies; peer_req->submit_jif = jiffies;
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
...@@ -2058,8 +2079,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto ...@@ -2058,8 +2079,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
atomic_add(pi->size >> 9, &device->rs_sect_ev); atomic_add(pi->size >> 9, &device->rs_sect_ev);
if (drbd_submit_peer_request(device, peer_req, REQ_OP_WRITE, if (drbd_submit_peer_request(peer_req) == 0)
DRBD_FAULT_RS_WR) == 0)
return 0; return 0;
/* don't care for the reason here */ /* don't care for the reason here */
...@@ -2375,16 +2395,6 @@ static int wait_for_and_update_peer_seq(struct drbd_peer_device *peer_device, co ...@@ -2375,16 +2395,6 @@ static int wait_for_and_update_peer_seq(struct drbd_peer_device *peer_device, co
return ret; return ret;
} }
/* see also bio_flags_to_wire()
* DRBD_REQ_*, because we need to semantically map the flags to data packet
* flags and back. We may replicate to other kernel versions. */
static blk_opf_t wire_flags_to_bio_flags(u32 dpf)
{
return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
(dpf & DP_FUA ? REQ_FUA : 0) |
(dpf & DP_FLUSH ? REQ_PREFLUSH : 0);
}
static enum req_op wire_flags_to_bio_op(u32 dpf) static enum req_op wire_flags_to_bio_op(u32 dpf)
{ {
if (dpf & DP_ZEROES) if (dpf & DP_ZEROES)
...@@ -2395,6 +2405,15 @@ static enum req_op wire_flags_to_bio_op(u32 dpf) ...@@ -2395,6 +2405,15 @@ static enum req_op wire_flags_to_bio_op(u32 dpf)
return REQ_OP_WRITE; return REQ_OP_WRITE;
} }
/* see also bio_flags_to_wire() */
static blk_opf_t wire_flags_to_bio(struct drbd_connection *connection, u32 dpf)
{
return wire_flags_to_bio_op(dpf) |
(dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
(dpf & DP_FUA ? REQ_FUA : 0) |
(dpf & DP_FLUSH ? REQ_PREFLUSH : 0);
}
static void fail_postponed_requests(struct drbd_device *device, sector_t sector, static void fail_postponed_requests(struct drbd_device *device, sector_t sector,
unsigned int size) unsigned int size)
{ {
...@@ -2538,8 +2557,6 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2538,8 +2557,6 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
struct drbd_peer_request *peer_req; struct drbd_peer_request *peer_req;
struct p_data *p = pi->data; struct p_data *p = pi->data;
u32 peer_seq = be32_to_cpu(p->seq_num); u32 peer_seq = be32_to_cpu(p->seq_num);
enum req_op op;
blk_opf_t op_flags;
u32 dp_flags; u32 dp_flags;
int err, tp; int err, tp;
...@@ -2578,11 +2595,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2578,11 +2595,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
peer_req->flags |= EE_APPLICATION; peer_req->flags |= EE_APPLICATION;
dp_flags = be32_to_cpu(p->dp_flags); dp_flags = be32_to_cpu(p->dp_flags);
op = wire_flags_to_bio_op(dp_flags); peer_req->opf = wire_flags_to_bio(connection, dp_flags);
op_flags = wire_flags_to_bio_flags(dp_flags);
if (pi->cmd == P_TRIM) { if (pi->cmd == P_TRIM) {
D_ASSERT(peer_device, peer_req->i.size > 0); D_ASSERT(peer_device, peer_req->i.size > 0);
D_ASSERT(peer_device, op == REQ_OP_DISCARD); D_ASSERT(peer_device, peer_req_op(peer_req) == REQ_OP_DISCARD);
D_ASSERT(peer_device, peer_req->pages == NULL); D_ASSERT(peer_device, peer_req->pages == NULL);
/* need to play safe: an older DRBD sender /* need to play safe: an older DRBD sender
* may mean zero-out while sending P_TRIM. */ * may mean zero-out while sending P_TRIM. */
...@@ -2590,7 +2606,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2590,7 +2606,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
peer_req->flags |= EE_ZEROOUT; peer_req->flags |= EE_ZEROOUT;
} else if (pi->cmd == P_ZEROES) { } else if (pi->cmd == P_ZEROES) {
D_ASSERT(peer_device, peer_req->i.size > 0); D_ASSERT(peer_device, peer_req->i.size > 0);
D_ASSERT(peer_device, op == REQ_OP_WRITE_ZEROES); D_ASSERT(peer_device, peer_req_op(peer_req) == REQ_OP_WRITE_ZEROES);
D_ASSERT(peer_device, peer_req->pages == NULL); D_ASSERT(peer_device, peer_req->pages == NULL);
/* Do (not) pass down BLKDEV_ZERO_NOUNMAP? */ /* Do (not) pass down BLKDEV_ZERO_NOUNMAP? */
if (dp_flags & DP_DISCARD) if (dp_flags & DP_DISCARD)
...@@ -2677,8 +2693,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2677,8 +2693,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
peer_req->flags |= EE_CALL_AL_COMPLETE_IO; peer_req->flags |= EE_CALL_AL_COMPLETE_IO;
} }
err = drbd_submit_peer_request(device, peer_req, op | op_flags, err = drbd_submit_peer_request(peer_req);
DRBD_FAULT_DT_WR);
if (!err) if (!err)
return 0; return 0;
...@@ -2789,7 +2804,6 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2789,7 +2804,6 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
struct drbd_peer_request *peer_req; struct drbd_peer_request *peer_req;
struct digest_info *di = NULL; struct digest_info *di = NULL;
int size, verb; int size, verb;
unsigned int fault_type;
struct p_block_req *p = pi->data; struct p_block_req *p = pi->data;
peer_device = conn_peer_device(connection, pi->vnr); peer_device = conn_peer_device(connection, pi->vnr);
...@@ -2849,11 +2863,11 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2849,11 +2863,11 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
put_ldev(device); put_ldev(device);
return -ENOMEM; return -ENOMEM;
} }
peer_req->opf = REQ_OP_READ;
switch (pi->cmd) { switch (pi->cmd) {
case P_DATA_REQUEST: case P_DATA_REQUEST:
peer_req->w.cb = w_e_end_data_req; peer_req->w.cb = w_e_end_data_req;
fault_type = DRBD_FAULT_DT_RD;
/* application IO, don't drbd_rs_begin_io */ /* application IO, don't drbd_rs_begin_io */
peer_req->flags |= EE_APPLICATION; peer_req->flags |= EE_APPLICATION;
goto submit; goto submit;
...@@ -2867,14 +2881,12 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2867,14 +2881,12 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
fallthrough; fallthrough;
case P_RS_DATA_REQUEST: case P_RS_DATA_REQUEST:
peer_req->w.cb = w_e_end_rsdata_req; peer_req->w.cb = w_e_end_rsdata_req;
fault_type = DRBD_FAULT_RS_RD;
/* used in the sector offset progress display */ /* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector); device->bm_resync_fo = BM_SECT_TO_BIT(sector);
break; break;
case P_OV_REPLY: case P_OV_REPLY:
case P_CSUM_RS_REQUEST: case P_CSUM_RS_REQUEST:
fault_type = DRBD_FAULT_RS_RD;
di = kmalloc(sizeof(*di) + pi->size, GFP_NOIO); di = kmalloc(sizeof(*di) + pi->size, GFP_NOIO);
if (!di) if (!di)
goto out_free_e; goto out_free_e;
...@@ -2923,7 +2935,6 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2923,7 +2935,6 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
(unsigned long long)sector); (unsigned long long)sector);
} }
peer_req->w.cb = w_e_end_ov_req; peer_req->w.cb = w_e_end_ov_req;
fault_type = DRBD_FAULT_RS_RD;
break; break;
default: default:
...@@ -2975,8 +2986,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2975,8 +2986,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
submit: submit:
update_receiver_timing_details(connection, drbd_submit_peer_request); update_receiver_timing_details(connection, drbd_submit_peer_request);
inc_unacked(device); inc_unacked(device);
if (drbd_submit_peer_request(device, peer_req, REQ_OP_READ, if (drbd_submit_peer_request(peer_req) == 0)
fault_type) == 0)
return 0; return 0;
/* don't care for the reason here */ /* don't care for the reason here */
...@@ -4947,7 +4957,6 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac ...@@ -4947,7 +4957,6 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac
if (get_ldev(device)) { if (get_ldev(device)) {
struct drbd_peer_request *peer_req; struct drbd_peer_request *peer_req;
const enum req_op op = REQ_OP_WRITE_ZEROES;
peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER, sector, peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER, sector,
size, 0, GFP_NOIO); size, 0, GFP_NOIO);
...@@ -4957,6 +4966,7 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac ...@@ -4957,6 +4966,7 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac
} }
peer_req->w.cb = e_end_resync_block; peer_req->w.cb = e_end_resync_block;
peer_req->opf = REQ_OP_DISCARD;
peer_req->submit_jif = jiffies; peer_req->submit_jif = jiffies;
peer_req->flags |= EE_TRIM; peer_req->flags |= EE_TRIM;
...@@ -4965,8 +4975,7 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac ...@@ -4965,8 +4975,7 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
atomic_add(pi->size >> 9, &device->rs_sect_ev); atomic_add(pi->size >> 9, &device->rs_sect_ev);
err = drbd_submit_peer_request(device, peer_req, op, err = drbd_submit_peer_request(peer_req);
DRBD_FAULT_RS_WR);
if (err) { if (err) {
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
......
...@@ -400,13 +400,13 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, ...@@ -400,13 +400,13 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
goto defer; goto defer;
peer_req->w.cb = w_e_send_csum; peer_req->w.cb = w_e_send_csum;
peer_req->opf = REQ_OP_READ;
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_add_tail(&peer_req->w.list, &device->read_ee); list_add_tail(&peer_req->w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
atomic_add(size >> 9, &device->rs_sect_ev); atomic_add(size >> 9, &device->rs_sect_ev);
if (drbd_submit_peer_request(device, peer_req, REQ_OP_READ, if (drbd_submit_peer_request(peer_req) == 0)
DRBD_FAULT_RS_RD) == 0)
return 0; return 0;
/* If it failed because of ENOMEM, retry should help. If it failed /* If it failed because of ENOMEM, retry should help. If it failed
......
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