(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: Joel Colledge <[email protected]>
Signed-off-by: Christoph Böhmwalder <[email protected]>
---
Changes in v2:
- Make opf the correct type
- Fix compiler warnings
---
drivers/block/drbd/drbd_int.h | 8 ++-
drivers/block/drbd/drbd_receiver.c | 81 +++++++++++++++++-------------
drivers/block/drbd/drbd_worker.c | 4 +-
3 files changed, 53 insertions(+), 40 deletions(-)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4d661282ff41..6ab96fb2983f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -395,6 +395,7 @@ struct drbd_peer_request {
struct drbd_peer_device *peer_device;
struct drbd_epoch *epoch; /* for writes */
struct page *pages;
+ blk_opf_t opf;
atomic_t pending_bios;
struct drbd_interval i;
/* see comments on ee flag bits below */
@@ -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.
* While corresponding bios are in flight, the only modification will be
* set_bit WAS_ERROR, which has to be atomic.
@@ -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_should_slow_down(struct drbd_device *device, sector_t sector,
bool throttle_if_app_is_waiting);
-extern int drbd_submit_peer_request(struct drbd_device *,
- struct drbd_peer_request *, blk_opf_t, int);
+extern int drbd_submit_peer_request(struct drbd_peer_request *);
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,
sector_t, unsigned int,
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index c897c4572036..af52a3ae37c1 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -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);
}
+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()
- * @device: DRBD device.
* @peer_req: peer request
*
* 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
* on certain Xen deployments.
*/
/* TODO allocate from our own bio_set. */
-int drbd_submit_peer_request(struct drbd_device *device,
- struct drbd_peer_request *peer_req,
- const blk_opf_t opf, const int fault_type)
+int drbd_submit_peer_request(struct drbd_peer_request *peer_req)
{
+ struct drbd_device *device = peer_req->peer_device->device;
struct bio *bios = NULL;
struct bio *bio;
struct page *page = peer_req->pages;
@@ -1667,7 +1676,18 @@ int drbd_submit_peer_request(struct drbd_device *device,
* generated bio, but a bio allocated on behalf of the peer.
*/
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 */
bio->bi_iter.bi_sector = sector;
bio->bi_private = peer_req;
@@ -1697,7 +1717,7 @@ int drbd_submit_peer_request(struct drbd_device *device,
bios = bios->bi_next;
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);
return 0;
}
@@ -2051,6 +2071,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
* respective _drbd_clear_done_ee */
peer_req->w.cb = e_end_resync_block;
+ peer_req->opf = REQ_OP_WRITE;
peer_req->submit_jif = jiffies;
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
spin_unlock_irq(&device->resource->req_lock);
atomic_add(pi->size >> 9, &device->rs_sect_ev);
- if (drbd_submit_peer_request(device, peer_req, REQ_OP_WRITE,
- DRBD_FAULT_RS_WR) == 0)
+ if (drbd_submit_peer_request(peer_req) == 0)
return 0;
/* 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
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)
{
if (dpf & DP_ZEROES)
@@ -2395,6 +2405,15 @@ static enum req_op wire_flags_to_bio_op(u32 dpf)
return REQ_OP_WRITE;
}
+/* see also bio_flags_to_wire() */
+static unsigned long 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,
unsigned int size)
{
@@ -2538,8 +2557,6 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
struct drbd_peer_request *peer_req;
struct p_data *p = pi->data;
u32 peer_seq = be32_to_cpu(p->seq_num);
- enum req_op op;
- blk_opf_t op_flags;
u32 dp_flags;
int err, tp;
@@ -2578,11 +2595,10 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
peer_req->flags |= EE_APPLICATION;
dp_flags = be32_to_cpu(p->dp_flags);
- op = wire_flags_to_bio_op(dp_flags);
- op_flags = wire_flags_to_bio_flags(dp_flags);
+ peer_req->opf = wire_flags_to_bio(connection, dp_flags);
if (pi->cmd == P_TRIM) {
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);
/* need to play safe: an older DRBD sender
* may mean zero-out while sending P_TRIM. */
@@ -2590,7 +2606,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
peer_req->flags |= EE_ZEROOUT;
} else if (pi->cmd == P_ZEROES) {
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);
/* Do (not) pass down BLKDEV_ZERO_NOUNMAP? */
if (dp_flags & DP_DISCARD)
@@ -2677,8 +2693,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
peer_req->flags |= EE_CALL_AL_COMPLETE_IO;
}
- err = drbd_submit_peer_request(device, peer_req, op | op_flags,
- DRBD_FAULT_DT_WR);
+ err = drbd_submit_peer_request(peer_req);
if (!err)
return 0;
@@ -2789,7 +2804,6 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
struct drbd_peer_request *peer_req;
struct digest_info *di = NULL;
int size, verb;
- unsigned int fault_type;
struct p_block_req *p = pi->data;
peer_device = conn_peer_device(connection, pi->vnr);
@@ -2849,11 +2863,11 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
put_ldev(device);
return -ENOMEM;
}
+ peer_req->opf = REQ_OP_READ;
switch (pi->cmd) {
case P_DATA_REQUEST:
peer_req->w.cb = w_e_end_data_req;
- fault_type = DRBD_FAULT_DT_RD;
/* application IO, don't drbd_rs_begin_io */
peer_req->flags |= EE_APPLICATION;
goto submit;
@@ -2867,14 +2881,12 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
fallthrough;
case P_RS_DATA_REQUEST:
peer_req->w.cb = w_e_end_rsdata_req;
- fault_type = DRBD_FAULT_RS_RD;
/* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector);
break;
case P_OV_REPLY:
case P_CSUM_RS_REQUEST:
- fault_type = DRBD_FAULT_RS_RD;
di = kmalloc(sizeof(*di) + pi->size, GFP_NOIO);
if (!di)
goto out_free_e;
@@ -2923,7 +2935,6 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
(unsigned long long)sector);
}
peer_req->w.cb = w_e_end_ov_req;
- fault_type = DRBD_FAULT_RS_RD;
break;
default:
@@ -2975,8 +2986,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
submit:
update_receiver_timing_details(connection, drbd_submit_peer_request);
inc_unacked(device);
- if (drbd_submit_peer_request(device, peer_req, REQ_OP_READ,
- fault_type) == 0)
+ if (drbd_submit_peer_request(peer_req) == 0)
return 0;
/* don't care for the reason here */
@@ -4947,7 +4957,6 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac
if (get_ldev(device)) {
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,
size, 0, GFP_NOIO);
@@ -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->opf = REQ_OP_DISCARD;
peer_req->submit_jif = jiffies;
peer_req->flags |= EE_TRIM;
@@ -4965,8 +4975,7 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac
spin_unlock_irq(&device->resource->req_lock);
atomic_add(pi->size >> 9, &device->rs_sect_ev);
- err = drbd_submit_peer_request(device, peer_req, op,
- DRBD_FAULT_RS_WR);
+ err = drbd_submit_peer_request(peer_req);
if (err) {
spin_lock_irq(&device->resource->req_lock);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 0bb1a900c2d5..c69beefc9d5c 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -400,13 +400,13 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
goto defer;
peer_req->w.cb = w_e_send_csum;
+ peer_req->opf = REQ_OP_READ;
spin_lock_irq(&device->resource->req_lock);
list_add_tail(&peer_req->w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock);
atomic_add(size >> 9, &device->rs_sect_ev);
- if (drbd_submit_peer_request(device, peer_req, REQ_OP_READ,
- DRBD_FAULT_RS_RD) == 0)
+ if (drbd_submit_peer_request(peer_req) == 0)
return 0;
/* If it failed because of ENOMEM, retry should help. If it failed
--
2.37.3
Hi Christoph,
I love your patch! Perhaps something to improve:
[auto build test WARNING on axboe-block/for-next]
[also build test WARNING on linus/master v6.1-rc1 next-20221020]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Christoph-B-hmwalder/drbd-Store-op-in-drbd_peer_request/20221020-170145
base: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
patch link: https://lore.kernel.org/r/20221020085946.132253-1-christoph.boehmwalder%40linbit.com
patch subject: [PATCH v2] drbd: Store op in drbd_peer_request
config: parisc-randconfig-s051-20221019
compiler: hppa-linux-gcc (GCC) 12.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/60b5915aa524152936deba45d2b2ca55e5f2ac5e
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Christoph-B-hmwalder/drbd-Store-op-in-drbd_peer_request/20221020-170145
git checkout 60b5915aa524152936deba45d2b2ca55e5f2ac5e
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=parisc SHELL=/bin/bash drivers/block/drbd/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
sparse warnings: (new ones prefixed by >>)
drivers/block/drbd/drbd_receiver.c:5308:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5309:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5318:54: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5375:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:5375:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:5375:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:273:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:273:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:273:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:529:29: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:529:29: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:529:29: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:601:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:601:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:601:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:705:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:705:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:705:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:774:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:774:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:774:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:1167:27: sparse: sparse: cast to restricted __be16
drivers/block/drbd/drbd_receiver.c:1168:27: sparse: sparse: cast to restricted __be16
drivers/block/drbd/drbd_receiver.c:1169:28: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:1173:27: sparse: sparse: cast to restricted __be16
drivers/block/drbd/drbd_receiver.c:1174:28: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:1179:27: sparse: sparse: cast to restricted __be16
drivers/block/drbd/drbd_receiver.c:1180:28: sparse: sparse: cast to restricted __be16
drivers/block/drbd/drbd_receiver.c:822:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:822:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:822:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:877:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:877:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:877:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:1042:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:1042:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:1042:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:1432:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:1432:14: sparse: struct disk_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:1432:14: sparse: struct disk_conf *
drivers/block/drbd/drbd_receiver.c:1585:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:1585:14: sparse: struct disk_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:1585:14: sparse: struct disk_conf *
drivers/block/drbd/drbd_receiver.c:1878:22: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:1882:22: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:2128:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:2159:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:2373:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:2373:22: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:2373:22: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:2383:27: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:2383:27: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:2383:27: sparse: struct net_conf *
>> drivers/block/drbd/drbd_receiver.c:2413:46: sparse: sparse: incorrect type in return expression (different base types) @@ expected unsigned long @@ got restricted blk_opf_t @@
drivers/block/drbd/drbd_receiver.c:2413:46: sparse: expected unsigned long
drivers/block/drbd/drbd_receiver.c:2413:46: sparse: got restricted blk_opf_t
drivers/block/drbd/drbd_receiver.c:2559:24: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:2586:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:2597:20: sparse: sparse: cast to restricted __be32
>> drivers/block/drbd/drbd_receiver.c:2598:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted blk_opf_t [usertype] opf @@ got unsigned long @@
drivers/block/drbd/drbd_receiver.c:2598:23: sparse: expected restricted blk_opf_t [usertype] opf
drivers/block/drbd/drbd_receiver.c:2598:23: sparse: got unsigned long
drivers/block/drbd/drbd_receiver.c:2629:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:2629:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:2629:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:2760:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:2760:22: sparse: struct disk_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:2760:22: sparse: struct disk_conf *
drivers/block/drbd/drbd_receiver.c:2815:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:2816:18: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3023:23: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:3023:23: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:3023:23: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:3099:23: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:3099:23: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:3099:23: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:3156:23: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:3156:23: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:3156:23: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:3502:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:3502:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:3502:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:3634:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3635:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3636:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3637:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3638:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3639:27: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3660:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:3660:22: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:3660:22: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:3744:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:3744:9: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:3744:9: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:3901:46: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3959:55: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3960:57: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3961:56: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3962:53: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:3996:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:3996:25: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:3996:25: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:4001:17: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:4001:17: sparse: struct disk_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:4001:17: sparse: struct disk_conf *
drivers/block/drbd/drbd_receiver.c:4007:17: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:4007:17: sparse: struct fifo_buffer [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:4007:17: sparse: struct fifo_buffer *
drivers/block/drbd/drbd_receiver.c:4074:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:4075:19: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:4076:19: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:4084:28: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:4084:28: sparse: struct disk_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:4084:28: sparse: struct disk_conf *
drivers/block/drbd/drbd_receiver.c:4125:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:4125:25: sparse: struct disk_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:4125:25: sparse: struct disk_conf *
drivers/block/drbd/drbd_receiver.c:4245:29: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:4345:18: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:4346:17: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:4371:18: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:4372:17: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:4404:24: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:4608:52: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:4935:9: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:4935:9: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:4953:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:4954:16: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5262:25: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] protocol_min @@ got restricted __be32 [usertype] @@
drivers/block/drbd/drbd_receiver.c:5263:25: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] protocol_max @@ got restricted __be32 [usertype] @@
drivers/block/drbd/drbd_receiver.c:5264:26: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] feature_flags @@ got restricted __be32 [usertype] @@
drivers/block/drbd/drbd_receiver.c:5570:23: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5589:23: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5634:27: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:5635:23: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5644:38: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5686:27: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:5687:23: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5695:38: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5732:27: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:5733:20: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5741:38: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5768:27: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:5775:38: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5777:9: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5777:9: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5777:9: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5777:9: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5798:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:5799:16: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5801:38: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5828:44: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5860:18: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:5861:16: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5863:38: sparse: sparse: cast to restricted __be32
drivers/block/drbd/drbd_receiver.c:5865:13: sparse: sparse: cast to restricted __be64
drivers/block/drbd/drbd_receiver.c:5914:14: sparse: sparse: incompatible types in comparison expression (different address spaces):
drivers/block/drbd/drbd_receiver.c:5914:14: sparse: struct net_conf [noderef] __rcu *
drivers/block/drbd/drbd_receiver.c:5914:14: sparse: struct net_conf *
drivers/block/drbd/drbd_receiver.c:6004:37: sparse: sparse: incompatible types in comparison expression (different address spaces):
vim +2413 drivers/block/drbd/drbd_receiver.c
2407
2408 /* see also bio_flags_to_wire() */
2409 static unsigned long wire_flags_to_bio(struct drbd_connection *connection, u32 dpf)
2410 {
2411 return wire_flags_to_bio_op(dpf) |
2412 (dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
> 2413 (dpf & DP_FUA ? REQ_FUA : 0) |
2414 (dpf & DP_FLUSH ? REQ_PREFLUSH : 0);
2415 }
2416
2417 static void fail_postponed_requests(struct drbd_device *device, sector_t sector,
2418 unsigned int size)
2419 {
2420 struct drbd_interval *i;
2421
2422 repeat:
2423 drbd_for_each_overlap(i, &device->write_requests, sector, size) {
2424 struct drbd_request *req;
2425 struct bio_and_error m;
2426
2427 if (!i->local)
2428 continue;
2429 req = container_of(i, struct drbd_request, i);
2430 if (!(req->rq_state & RQ_POSTPONED))
2431 continue;
2432 req->rq_state &= ~RQ_POSTPONED;
2433 __req_mod(req, NEG_ACKED, &m);
2434 spin_unlock_irq(&device->resource->req_lock);
2435 if (m.bio)
2436 complete_master_bio(device, &m);
2437 spin_lock_irq(&device->resource->req_lock);
2438 goto repeat;
2439 }
2440 }
2441
2442 static int handle_write_conflicts(struct drbd_device *device,
2443 struct drbd_peer_request *peer_req)
2444 {
2445 struct drbd_connection *connection = peer_req->peer_device->connection;
2446 bool resolve_conflicts = test_bit(RESOLVE_CONFLICTS, &connection->flags);
2447 sector_t sector = peer_req->i.sector;
2448 const unsigned int size = peer_req->i.size;
2449 struct drbd_interval *i;
2450 bool equal;
2451 int err;
2452
2453 /*
2454 * Inserting the peer request into the write_requests tree will prevent
2455 * new conflicting local requests from being added.
2456 */
2457 drbd_insert_interval(&device->write_requests, &peer_req->i);
2458
2459 repeat:
2460 drbd_for_each_overlap(i, &device->write_requests, sector, size) {
2461 if (i == &peer_req->i)
2462 continue;
2463 if (i->completed)
2464 continue;
2465
2466 if (!i->local) {
2467 /*
2468 * Our peer has sent a conflicting remote request; this
2469 * should not happen in a two-node setup. Wait for the
2470 * earlier peer request to complete.
2471 */
2472 err = drbd_wait_misc(device, i);
2473 if (err)
2474 goto out;
2475 goto repeat;
2476 }
2477
2478 equal = i->sector == sector && i->size == size;
2479 if (resolve_conflicts) {
2480 /*
2481 * If the peer request is fully contained within the
2482 * overlapping request, it can be considered overwritten
2483 * and thus superseded; otherwise, it will be retried
2484 * once all overlapping requests have completed.
2485 */
2486 bool superseded = i->sector <= sector && i->sector +
2487 (i->size >> 9) >= sector + (size >> 9);
2488
2489 if (!equal)
2490 drbd_alert(device, "Concurrent writes detected: "
2491 "local=%llus +%u, remote=%llus +%u, "
2492 "assuming %s came first\n",
2493 (unsigned long long)i->sector, i->size,
2494 (unsigned long long)sector, size,
2495 superseded ? "local" : "remote");
2496
2497 peer_req->w.cb = superseded ? e_send_superseded :
2498 e_send_retry_write;
2499 list_add_tail(&peer_req->w.list, &device->done_ee);
2500 queue_work(connection->ack_sender, &peer_req->peer_device->send_acks_work);
2501
2502 err = -ENOENT;
2503 goto out;
2504 } else {
2505 struct drbd_request *req =
2506 container_of(i, struct drbd_request, i);
2507
2508 if (!equal)
2509 drbd_alert(device, "Concurrent writes detected: "
2510 "local=%llus +%u, remote=%llus +%u\n",
2511 (unsigned long long)i->sector, i->size,
2512 (unsigned long long)sector, size);
2513
2514 if (req->rq_state & RQ_LOCAL_PENDING ||
2515 !(req->rq_state & RQ_POSTPONED)) {
2516 /*
2517 * Wait for the node with the discard flag to
2518 * decide if this request has been superseded
2519 * or needs to be retried.
2520 * Requests that have been superseded will
2521 * disappear from the write_requests tree.
2522 *
2523 * In addition, wait for the conflicting
2524 * request to finish locally before submitting
2525 * the conflicting peer request.
2526 */
2527 err = drbd_wait_misc(device, &req->i);
2528 if (err) {
2529 _conn_request_state(connection, NS(conn, C_TIMEOUT), CS_HARD);
2530 fail_postponed_requests(device, sector, size);
2531 goto out;
2532 }
2533 goto repeat;
2534 }
2535 /*
2536 * Remember to restart the conflicting requests after
2537 * the new peer request has completed.
2538 */
2539 peer_req->flags |= EE_RESTART_REQUESTS;
2540 }
2541 }
2542 err = 0;
2543
2544 out:
2545 if (err)
2546 drbd_remove_epoch_entry_interval(device, peer_req);
2547 return err;
2548 }
2549
2550 /* mirrored write */
2551 static int receive_Data(struct drbd_connection *connection, struct packet_info *pi)
2552 {
2553 struct drbd_peer_device *peer_device;
2554 struct drbd_device *device;
2555 struct net_conf *nc;
2556 sector_t sector;
2557 struct drbd_peer_request *peer_req;
2558 struct p_data *p = pi->data;
2559 u32 peer_seq = be32_to_cpu(p->seq_num);
2560 u32 dp_flags;
2561 int err, tp;
2562
2563 peer_device = conn_peer_device(connection, pi->vnr);
2564 if (!peer_device)
2565 return -EIO;
2566 device = peer_device->device;
2567
2568 if (!get_ldev(device)) {
2569 int err2;
2570
2571 err = wait_for_and_update_peer_seq(peer_device, peer_seq);
2572 drbd_send_ack_dp(peer_device, P_NEG_ACK, p, pi->size);
2573 atomic_inc(&connection->current_epoch->epoch_size);
2574 err2 = drbd_drain_block(peer_device, pi->size);
2575 if (!err)
2576 err = err2;
2577 return err;
2578 }
2579
2580 /*
2581 * Corresponding put_ldev done either below (on various errors), or in
2582 * drbd_peer_request_endio, if we successfully submit the data at the
2583 * end of this function.
2584 */
2585
2586 sector = be64_to_cpu(p->sector);
2587 peer_req = read_in_block(peer_device, p->block_id, sector, pi);
2588 if (!peer_req) {
2589 put_ldev(device);
2590 return -EIO;
2591 }
2592
2593 peer_req->w.cb = e_end_block;
2594 peer_req->submit_jif = jiffies;
2595 peer_req->flags |= EE_APPLICATION;
2596
2597 dp_flags = be32_to_cpu(p->dp_flags);
> 2598 peer_req->opf = wire_flags_to_bio(connection, dp_flags);
2599 if (pi->cmd == P_TRIM) {
2600 D_ASSERT(peer_device, peer_req->i.size > 0);
2601 D_ASSERT(peer_device, peer_req_op(peer_req) == REQ_OP_DISCARD);
2602 D_ASSERT(peer_device, peer_req->pages == NULL);
2603 /* need to play safe: an older DRBD sender
2604 * may mean zero-out while sending P_TRIM. */
2605 if (0 == (connection->agreed_features & DRBD_FF_WZEROES))
2606 peer_req->flags |= EE_ZEROOUT;
2607 } else if (pi->cmd == P_ZEROES) {
2608 D_ASSERT(peer_device, peer_req->i.size > 0);
2609 D_ASSERT(peer_device, peer_req_op(peer_req) == REQ_OP_WRITE_ZEROES);
2610 D_ASSERT(peer_device, peer_req->pages == NULL);
2611 /* Do (not) pass down BLKDEV_ZERO_NOUNMAP? */
2612 if (dp_flags & DP_DISCARD)
2613 peer_req->flags |= EE_TRIM;
2614 } else if (peer_req->pages == NULL) {
2615 D_ASSERT(device, peer_req->i.size == 0);
2616 D_ASSERT(device, dp_flags & DP_FLUSH);
2617 }
2618
2619 if (dp_flags & DP_MAY_SET_IN_SYNC)
2620 peer_req->flags |= EE_MAY_SET_IN_SYNC;
2621
2622 spin_lock(&connection->epoch_lock);
2623 peer_req->epoch = connection->current_epoch;
2624 atomic_inc(&peer_req->epoch->epoch_size);
2625 atomic_inc(&peer_req->epoch->active);
2626 spin_unlock(&connection->epoch_lock);
2627
2628 rcu_read_lock();
2629 nc = rcu_dereference(peer_device->connection->net_conf);
2630 tp = nc->two_primaries;
2631 if (peer_device->connection->agreed_pro_version < 100) {
2632 switch (nc->wire_protocol) {
2633 case DRBD_PROT_C:
2634 dp_flags |= DP_SEND_WRITE_ACK;
2635 break;
2636 case DRBD_PROT_B:
2637 dp_flags |= DP_SEND_RECEIVE_ACK;
2638 break;
2639 }
2640 }
2641 rcu_read_unlock();
2642
2643 if (dp_flags & DP_SEND_WRITE_ACK) {
2644 peer_req->flags |= EE_SEND_WRITE_ACK;
2645 inc_unacked(device);
2646 /* corresponding dec_unacked() in e_end_block()
2647 * respective _drbd_clear_done_ee */
2648 }
2649
2650 if (dp_flags & DP_SEND_RECEIVE_ACK) {
2651 /* I really don't like it that the receiver thread
2652 * sends on the msock, but anyways */
2653 drbd_send_ack(peer_device, P_RECV_ACK, peer_req);
2654 }
2655
2656 if (tp) {
2657 /* two primaries implies protocol C */
2658 D_ASSERT(device, dp_flags & DP_SEND_WRITE_ACK);
2659 peer_req->flags |= EE_IN_INTERVAL_TREE;
2660 err = wait_for_and_update_peer_seq(peer_device, peer_seq);
2661 if (err)
2662 goto out_interrupted;
2663 spin_lock_irq(&device->resource->req_lock);
2664 err = handle_write_conflicts(device, peer_req);
2665 if (err) {
2666 spin_unlock_irq(&device->resource->req_lock);
2667 if (err == -ENOENT) {
2668 put_ldev(device);
2669 return 0;
2670 }
2671 goto out_interrupted;
2672 }
2673 } else {
2674 update_peer_seq(peer_device, peer_seq);
2675 spin_lock_irq(&device->resource->req_lock);
2676 }
2677 /* TRIM and is processed synchronously,
2678 * we wait for all pending requests, respectively wait for
2679 * active_ee to become empty in drbd_submit_peer_request();
2680 * better not add ourselves here. */
2681 if ((peer_req->flags & (EE_TRIM | EE_ZEROOUT)) == 0)
2682 list_add_tail(&peer_req->w.list, &device->active_ee);
2683 spin_unlock_irq(&device->resource->req_lock);
2684
2685 if (device->state.conn == C_SYNC_TARGET)
2686 wait_event(device->ee_wait, !overlapping_resync_write(device, peer_req));
2687
2688 if (device->state.pdsk < D_INCONSISTENT) {
2689 /* In case we have the only disk of the cluster, */
2690 drbd_set_out_of_sync(device, peer_req->i.sector, peer_req->i.size);
2691 peer_req->flags &= ~EE_MAY_SET_IN_SYNC;
2692 drbd_al_begin_io(device, &peer_req->i);
2693 peer_req->flags |= EE_CALL_AL_COMPLETE_IO;
2694 }
2695
2696 err = drbd_submit_peer_request(peer_req);
2697 if (!err)
2698 return 0;
2699
2700 /* don't care for the reason here */
2701 drbd_err(device, "submit failed, triggering re-connect\n");
2702 spin_lock_irq(&device->resource->req_lock);
2703 list_del(&peer_req->w.list);
2704 drbd_remove_epoch_entry_interval(device, peer_req);
2705 spin_unlock_irq(&device->resource->req_lock);
2706 if (peer_req->flags & EE_CALL_AL_COMPLETE_IO) {
2707 peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO;
2708 drbd_al_complete_io(device, &peer_req->i);
2709 }
2710
2711 out_interrupted:
2712 drbd_may_finish_epoch(connection, peer_req->epoch, EV_PUT | EV_CLEANUP);
2713 put_ldev(device);
2714 drbd_free_peer_req(device, peer_req);
2715 return err;
2716 }
2717
--
0-DAY CI Kernel Test Service
https://01.org/lkp