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 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