Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drbd: implement REQ_OP_WRITE_ZEROES

It seems like DRBD assumes its on the wire TRIM request always zeroes data.
Use that fact to implement REQ_OP_WRITE_ZEROES.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Christoph Hellwig and committed by
Jens Axboe
45c21793 0dbed96a

+15 -7
+2 -1
drivers/block/drbd/drbd_main.c
··· 1668 1668 (bio->bi_opf & REQ_FUA ? DP_FUA : 0) | 1669 1669 (bio->bi_opf & REQ_PREFLUSH ? DP_FLUSH : 0) | 1670 1670 (bio_op(bio) == REQ_OP_WRITE_SAME ? DP_WSAME : 0) | 1671 - (bio_op(bio) == REQ_OP_DISCARD ? DP_DISCARD : 0); 1671 + (bio_op(bio) == REQ_OP_DISCARD ? DP_DISCARD : 0) | 1672 + (bio_op(bio) == REQ_OP_WRITE_ZEROES ? DP_DISCARD : 0); 1672 1673 else 1673 1674 return bio->bi_opf & REQ_SYNC ? DP_RW_SYNC : 0; 1674 1675 }
+2
drivers/block/drbd/drbd_nl.c
··· 1217 1217 blk_queue_discard_granularity(q, 512); 1218 1218 q->limits.max_discard_sectors = drbd_max_discard_sectors(connection); 1219 1219 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); 1220 + q->limits.max_write_zeroes_sectors = drbd_max_discard_sectors(connection); 1220 1221 } else { 1221 1222 queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); 1222 1223 blk_queue_discard_granularity(q, 0); 1223 1224 q->limits.max_discard_sectors = 0; 1225 + q->limits.max_write_zeroes_sectors = 0; 1224 1226 } 1225 1227 } 1226 1228
+3 -3
drivers/block/drbd/drbd_receiver.c
··· 2285 2285 static unsigned long wire_flags_to_bio_op(u32 dpf) 2286 2286 { 2287 2287 if (dpf & DP_DISCARD) 2288 - return REQ_OP_DISCARD; 2288 + return REQ_OP_WRITE_ZEROES; 2289 2289 else 2290 2290 return REQ_OP_WRITE; 2291 2291 } ··· 2476 2476 op_flags = wire_flags_to_bio_flags(dp_flags); 2477 2477 if (pi->cmd == P_TRIM) { 2478 2478 D_ASSERT(peer_device, peer_req->i.size > 0); 2479 - D_ASSERT(peer_device, op == REQ_OP_DISCARD); 2479 + D_ASSERT(peer_device, op == REQ_OP_WRITE_ZEROES); 2480 2480 D_ASSERT(peer_device, peer_req->pages == NULL); 2481 2481 } else if (peer_req->pages == NULL) { 2482 2482 D_ASSERT(device, peer_req->i.size == 0); ··· 4789 4789 4790 4790 if (get_ldev(device)) { 4791 4791 struct drbd_peer_request *peer_req; 4792 - const int op = REQ_OP_DISCARD; 4792 + const int op = REQ_OP_WRITE_ZEROES; 4793 4793 4794 4794 peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER, sector, 4795 4795 size, 0, GFP_NOIO);
+5 -2
drivers/block/drbd/drbd_req.c
··· 59 59 drbd_req_make_private_bio(req, bio_src); 60 60 req->rq_state = (bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0) 61 61 | (bio_op(bio_src) == REQ_OP_WRITE_SAME ? RQ_WSAME : 0) 62 + | (bio_op(bio_src) == REQ_OP_WRITE_ZEROES ? RQ_UNMAP : 0) 62 63 | (bio_op(bio_src) == REQ_OP_DISCARD ? RQ_UNMAP : 0); 63 64 req->device = device; 64 65 req->master_bio = bio_src; ··· 1181 1180 if (get_ldev(device)) { 1182 1181 if (drbd_insert_fault(device, type)) 1183 1182 bio_io_error(bio); 1184 - else if (bio_op(bio) == REQ_OP_DISCARD) 1183 + else if (bio_op(bio) == REQ_OP_WRITE_ZEROES || 1184 + bio_op(bio) == REQ_OP_DISCARD) 1185 1185 drbd_process_discard_req(req); 1186 1186 else 1187 1187 generic_make_request(bio); ··· 1236 1234 _drbd_start_io_acct(device, req); 1237 1235 1238 1236 /* process discards always from our submitter thread */ 1239 - if (bio_op(bio) & REQ_OP_DISCARD) 1237 + if ((bio_op(bio) & REQ_OP_WRITE_ZEROES) || 1238 + (bio_op(bio) & REQ_OP_DISCARD)) 1240 1239 goto queue_for_submitter_thread; 1241 1240 1242 1241 if (rw == WRITE && req->private_bio && req->i.size
+3 -1
drivers/block/drbd/drbd_worker.c
··· 174 174 struct drbd_peer_request *peer_req = bio->bi_private; 175 175 struct drbd_device *device = peer_req->peer_device->device; 176 176 bool is_write = bio_data_dir(bio) == WRITE; 177 - bool is_discard = !!(bio_op(bio) == REQ_OP_DISCARD); 177 + bool is_discard = bio_op(bio) == REQ_OP_WRITE_ZEROES || 178 + bio_op(bio) == REQ_OP_DISCARD; 178 179 179 180 if (bio->bi_error && __ratelimit(&drbd_ratelimit_state)) 180 181 drbd_warn(device, "%s: error=%d s=%llus\n", ··· 250 249 /* to avoid recursion in __req_mod */ 251 250 if (unlikely(bio->bi_error)) { 252 251 switch (bio_op(bio)) { 252 + case REQ_OP_WRITE_ZEROES: 253 253 case REQ_OP_DISCARD: 254 254 if (bio->bi_error == -EOPNOTSUPP) 255 255 what = DISCARD_COMPLETED_NOTSUPP;