summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <mchristi@redhat.com>2016-06-05 15:32:23 -0400
committerJens Axboe <axboe@fb.com>2016-06-07 15:41:38 -0400
commit3a5e02ced11e22ecd9da3d6710afe15bcfee1d10 (patch)
tree78f6d1a737b01b559b61310b9355f1f7ecfdd54c
parent4e1b2d52a80d79296a5d899d73249748dea71a53 (diff)
block, drivers: add REQ_OP_FLUSH operation
This adds a REQ_OP_FLUSH operation that is sent to request_fn based drivers by the block layer's flush code, instead of sending requests with the request->cmd_flags REQ_FLUSH bit set. Signed-off-by: Mike Christie <mchristi@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--Documentation/block/writeback_cache_control.txt6
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--block/blk-flush.c4
-rw-r--r--drivers/block/loop.c4
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/block/osdblk.c2
-rw-r--r--drivers/block/ps3disk.c4
-rw-r--r--drivers/block/skd_main.c2
-rw-r--r--drivers/block/virtio_blk.c2
-rw-r--r--drivers/block/xen-blkfront.c8
-rw-r--r--drivers/ide/ide-disk.c2
-rw-r--r--drivers/md/dm.c2
-rw-r--r--drivers/mmc/card/block.c6
-rw-r--r--drivers/mmc/card/queue.h3
-rw-r--r--drivers/mtd/mtd_blkdevs.c2
-rw-r--r--drivers/nvme/host/core.c2
-rw-r--r--drivers/scsi/sd.c7
-rw-r--r--include/linux/blk_types.h3
-rw-r--r--include/linux/blkdev.h3
-rw-r--r--kernel/trace/blktrace.c5
20 files changed, 40 insertions, 31 deletions
diff --git a/Documentation/block/writeback_cache_control.txt b/Documentation/block/writeback_cache_control.txt
index 59e0516cbf6b..da70bdacd503 100644
--- a/Documentation/block/writeback_cache_control.txt
+++ b/Documentation/block/writeback_cache_control.txt
@@ -73,9 +73,9 @@ doing:
73 73
74 blk_queue_write_cache(sdkp->disk->queue, true, false); 74 blk_queue_write_cache(sdkp->disk->queue, true, false);
75 75
76and handle empty REQ_FLUSH requests in its prep_fn/request_fn. Note that 76and handle empty REQ_OP_FLUSH requests in its prep_fn/request_fn. Note that
77REQ_FLUSH requests with a payload are automatically turned into a sequence 77REQ_FLUSH requests with a payload are automatically turned into a sequence
78of an empty REQ_FLUSH request followed by the actual write by the block 78of an empty REQ_OP_FLUSH request followed by the actual write by the block
79layer. For devices that also support the FUA bit the block layer needs 79layer. For devices that also support the FUA bit the block layer needs
80to be told to pass through the REQ_FUA bit using: 80to be told to pass through the REQ_FUA bit using:
81 81
@@ -83,4 +83,4 @@ to be told to pass through the REQ_FUA bit using:
83 83
84and the driver must handle write requests that have the REQ_FUA bit set 84and the driver must handle write requests that have the REQ_FUA bit set
85in prep_fn/request_fn. If the FUA bit is not natively supported the block 85in prep_fn/request_fn. If the FUA bit is not natively supported the block
86layer turns it into an empty REQ_FLUSH request after the actual write. 86layer turns it into an empty REQ_OP_FLUSH request after the actual write.
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 17e96dc29596..ef6b4d960bad 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1286,7 +1286,7 @@ static void do_ubd_request(struct request_queue *q)
1286 1286
1287 req = dev->request; 1287 req = dev->request;
1288 1288
1289 if (req->cmd_flags & REQ_FLUSH) { 1289 if (req_op(req) == REQ_OP_FLUSH) {
1290 io_req = kmalloc(sizeof(struct io_thread_req), 1290 io_req = kmalloc(sizeof(struct io_thread_req),
1291 GFP_ATOMIC); 1291 GFP_ATOMIC);
1292 if (io_req == NULL) { 1292 if (io_req == NULL) {
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 9fd1f63a6348..21f0d5b0d2ca 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -29,7 +29,7 @@
29 * The actual execution of flush is double buffered. Whenever a request 29 * The actual execution of flush is double buffered. Whenever a request
30 * needs to execute PRE or POSTFLUSH, it queues at 30 * needs to execute PRE or POSTFLUSH, it queues at
31 * fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a 31 * fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a
32 * flush is issued and the pending_idx is toggled. When the flush 32 * REQ_OP_FLUSH is issued and the pending_idx is toggled. When the flush
33 * completes, all the requests which were pending are proceeded to the next 33 * completes, all the requests which were pending are proceeded to the next
34 * step. This allows arbitrary merging of different types of FLUSH/FUA 34 * step. This allows arbitrary merging of different types of FLUSH/FUA
35 * requests. 35 * requests.
@@ -330,7 +330,7 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq)
330 } 330 }
331 331
332 flush_rq->cmd_type = REQ_TYPE_FS; 332 flush_rq->cmd_type = REQ_TYPE_FS;
333 flush_rq->cmd_flags = WRITE_FLUSH | REQ_FLUSH_SEQ; 333 req_set_op_attrs(flush_rq, REQ_OP_FLUSH, WRITE_FLUSH | REQ_FLUSH_SEQ);
334 flush_rq->rq_disk = first_rq->rq_disk; 334 flush_rq->rq_disk = first_rq->rq_disk;
335 flush_rq->end_io = flush_end_io; 335 flush_rq->end_io = flush_end_io;
336 336
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b9b737cafd5f..364d491d4bdd 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -542,7 +542,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
542 pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset; 542 pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset;
543 543
544 if (op_is_write(req_op(rq))) { 544 if (op_is_write(req_op(rq))) {
545 if (rq->cmd_flags & REQ_FLUSH) 545 if (req_op(rq) == REQ_OP_FLUSH)
546 ret = lo_req_flush(lo, rq); 546 ret = lo_req_flush(lo, rq);
547 else if (req_op(rq) == REQ_OP_DISCARD) 547 else if (req_op(rq) == REQ_OP_DISCARD)
548 ret = lo_discard(lo, rq, pos); 548 ret = lo_discard(lo, rq, pos);
@@ -1659,7 +1659,7 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
1659 if (lo->lo_state != Lo_bound) 1659 if (lo->lo_state != Lo_bound)
1660 return -EIO; 1660 return -EIO;
1661 1661
1662 if (lo->use_dio && (!(cmd->rq->cmd_flags & REQ_FLUSH) || 1662 if (lo->use_dio && (req_op(cmd->rq) != REQ_OP_FLUSH ||
1663 req_op(cmd->rq) == REQ_OP_DISCARD)) 1663 req_op(cmd->rq) == REQ_OP_DISCARD))
1664 cmd->use_aio = true; 1664 cmd->use_aio = true;
1665 else 1665 else
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 6c2c28d124d0..d6f3c9336f29 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -284,7 +284,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
284 type = NBD_CMD_DISC; 284 type = NBD_CMD_DISC;
285 else if (req_op(req) == REQ_OP_DISCARD) 285 else if (req_op(req) == REQ_OP_DISCARD)
286 type = NBD_CMD_TRIM; 286 type = NBD_CMD_TRIM;
287 else if (req->cmd_flags & REQ_FLUSH) 287 else if (req_op(req) == REQ_OP_FLUSH)
288 type = NBD_CMD_FLUSH; 288 type = NBD_CMD_FLUSH;
289 else if (rq_data_dir(req) == WRITE) 289 else if (rq_data_dir(req) == WRITE)
290 type = NBD_CMD_WRITE; 290 type = NBD_CMD_WRITE;
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c
index c2854a2bfdb0..92900f5f0b47 100644
--- a/drivers/block/osdblk.c
+++ b/drivers/block/osdblk.c
@@ -321,7 +321,7 @@ static void osdblk_rq_fn(struct request_queue *q)
321 * driver-specific, etc. 321 * driver-specific, etc.
322 */ 322 */
323 323
324 do_flush = rq->cmd_flags & REQ_FLUSH; 324 do_flush = (req_op(rq) == REQ_OP_FLUSH);
325 do_write = (rq_data_dir(rq) == WRITE); 325 do_write = (rq_data_dir(rq) == WRITE);
326 326
327 if (!do_flush) { /* osd_flush does not use a bio */ 327 if (!do_flush) { /* osd_flush does not use a bio */
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 4b7e405830d7..acb44529c05e 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -196,7 +196,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
196 dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); 196 dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
197 197
198 while ((req = blk_fetch_request(q))) { 198 while ((req = blk_fetch_request(q))) {
199 if (req->cmd_flags & REQ_FLUSH) { 199 if (req_op(req) == REQ_OP_FLUSH) {
200 if (ps3disk_submit_flush_request(dev, req)) 200 if (ps3disk_submit_flush_request(dev, req))
201 break; 201 break;
202 } else if (req->cmd_type == REQ_TYPE_FS) { 202 } else if (req->cmd_type == REQ_TYPE_FS) {
@@ -256,7 +256,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
256 return IRQ_HANDLED; 256 return IRQ_HANDLED;
257 } 257 }
258 258
259 if (req->cmd_flags & REQ_FLUSH) { 259 if (req_op(req) == REQ_OP_FLUSH) {
260 read = 0; 260 read = 0;
261 op = "flush"; 261 op = "flush";
262 } else { 262 } else {
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c
index 910e065918af..5c07a23e2ada 100644
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -597,7 +597,7 @@ static void skd_request_fn(struct request_queue *q)
597 data_dir = rq_data_dir(req); 597 data_dir = rq_data_dir(req);
598 io_flags = req->cmd_flags; 598 io_flags = req->cmd_flags;
599 599
600 if (io_flags & REQ_FLUSH) 600 if (req_op(req) == REQ_OP_FLUSH)
601 flush++; 601 flush++;
602 602
603 if (io_flags & REQ_FUA) 603 if (io_flags & REQ_FUA)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 42758b52768c..18e4069dd24b 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -172,7 +172,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
172 BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); 172 BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
173 173
174 vbr->req = req; 174 vbr->req = req;
175 if (req->cmd_flags & REQ_FLUSH) { 175 if (req_op(req) == REQ_OP_FLUSH) {
176 vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_FLUSH); 176 vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_FLUSH);
177 vbr->out_hdr.sector = 0; 177 vbr->out_hdr.sector = 0;
178 vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req)); 178 vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 6fd160197b7a..3aeb25bd5057 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -743,7 +743,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
743 * The indirect operation can only be a BLKIF_OP_READ or 743 * The indirect operation can only be a BLKIF_OP_READ or
744 * BLKIF_OP_WRITE 744 * BLKIF_OP_WRITE
745 */ 745 */
746 BUG_ON(req->cmd_flags & (REQ_FLUSH | REQ_FUA)); 746 BUG_ON(req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA);
747 ring_req->operation = BLKIF_OP_INDIRECT; 747 ring_req->operation = BLKIF_OP_INDIRECT;
748 ring_req->u.indirect.indirect_op = rq_data_dir(req) ? 748 ring_req->u.indirect.indirect_op = rq_data_dir(req) ?
749 BLKIF_OP_WRITE : BLKIF_OP_READ; 749 BLKIF_OP_WRITE : BLKIF_OP_READ;
@@ -755,7 +755,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
755 ring_req->u.rw.handle = info->handle; 755 ring_req->u.rw.handle = info->handle;
756 ring_req->operation = rq_data_dir(req) ? 756 ring_req->operation = rq_data_dir(req) ?
757 BLKIF_OP_WRITE : BLKIF_OP_READ; 757 BLKIF_OP_WRITE : BLKIF_OP_READ;
758 if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) { 758 if (req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) {
759 /* 759 /*
760 * Ideally we can do an unordered flush-to-disk. 760 * Ideally we can do an unordered flush-to-disk.
761 * In case the backend onlysupports barriers, use that. 761 * In case the backend onlysupports barriers, use that.
@@ -865,7 +865,7 @@ static inline bool blkif_request_flush_invalid(struct request *req,
865 struct blkfront_info *info) 865 struct blkfront_info *info)
866{ 866{
867 return ((req->cmd_type != REQ_TYPE_FS) || 867 return ((req->cmd_type != REQ_TYPE_FS) ||
868 ((req->cmd_flags & REQ_FLUSH) && 868 ((req_op(req) == REQ_OP_FLUSH) &&
869 !(info->feature_flush & REQ_FLUSH)) || 869 !(info->feature_flush & REQ_FLUSH)) ||
870 ((req->cmd_flags & REQ_FUA) && 870 ((req->cmd_flags & REQ_FUA) &&
871 !(info->feature_flush & REQ_FUA))); 871 !(info->feature_flush & REQ_FUA)));
@@ -2055,7 +2055,7 @@ static int blkif_recover(struct blkfront_info *info)
2055 /* 2055 /*
2056 * Get the bios in the request so we can re-queue them. 2056 * Get the bios in the request so we can re-queue them.
2057 */ 2057 */
2058 if (copy[i].request->cmd_flags & REQ_FLUSH || 2058 if (req_op(copy[i].request) == REQ_OP_FLUSH ||
2059 req_op(copy[i].request) == REQ_OP_DISCARD || 2059 req_op(copy[i].request) == REQ_OP_DISCARD ||
2060 copy[i].request->cmd_flags & (REQ_FUA | REQ_SECURE)) { 2060 copy[i].request->cmd_flags & (REQ_FUA | REQ_SECURE)) {
2061 /* 2061 /*
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 05dbcce70b0e..e378ef70ed63 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -431,7 +431,7 @@ static int idedisk_prep_fn(struct request_queue *q, struct request *rq)
431 ide_drive_t *drive = q->queuedata; 431 ide_drive_t *drive = q->queuedata;
432 struct ide_cmd *cmd; 432 struct ide_cmd *cmd;
433 433
434 if (!(rq->cmd_flags & REQ_FLUSH)) 434 if (req_op(rq) != REQ_OP_FLUSH)
435 return BLKPREP_OK; 435 return BLKPREP_OK;
436 436
437 if (rq->special) { 437 if (rq->special) {
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index f6b104c77b6d..fcc68c8edba0 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2171,7 +2171,7 @@ static void dm_request_fn(struct request_queue *q)
2171 2171
2172 /* always use block 0 to find the target for flushes for now */ 2172 /* always use block 0 to find the target for flushes for now */
2173 pos = 0; 2173 pos = 0;
2174 if (!(rq->cmd_flags & REQ_FLUSH)) 2174 if (req_op(rq) != REQ_OP_FLUSH)
2175 pos = blk_rq_pos(rq); 2175 pos = blk_rq_pos(rq);
2176 2176
2177 if ((dm_request_peeked_before_merge_deadline(md) && 2177 if ((dm_request_peeked_before_merge_deadline(md) &&
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 201a8719f6c4..bca20f88a8b2 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1722,7 +1722,8 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
1722 !IS_ALIGNED(blk_rq_sectors(next), 8)) 1722 !IS_ALIGNED(blk_rq_sectors(next), 8))
1723 break; 1723 break;
1724 1724
1725 if (req_op(next) == REQ_OP_DISCARD || next->cmd_flags & REQ_FLUSH) 1725 if (req_op(next) == REQ_OP_DISCARD ||
1726 req_op(next) == REQ_OP_FLUSH)
1726 break; 1727 break;
1727 1728
1728 if (rq_data_dir(cur) != rq_data_dir(next)) 1729 if (rq_data_dir(cur) != rq_data_dir(next))
@@ -2147,7 +2148,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
2147 struct mmc_card *card = md->queue.card; 2148 struct mmc_card *card = md->queue.card;
2148 struct mmc_host *host = card->host; 2149 struct mmc_host *host = card->host;
2149 unsigned long flags; 2150 unsigned long flags;
2150 unsigned int cmd_flags = req ? req->cmd_flags : 0;
2151 2151
2152 if (req && !mq->mqrq_prev->req) 2152 if (req && !mq->mqrq_prev->req)
2153 /* claim host only for the first request */ 2153 /* claim host only for the first request */
@@ -2171,7 +2171,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
2171 ret = mmc_blk_issue_secdiscard_rq(mq, req); 2171 ret = mmc_blk_issue_secdiscard_rq(mq, req);
2172 else 2172 else
2173 ret = mmc_blk_issue_discard_rq(mq, req); 2173 ret = mmc_blk_issue_discard_rq(mq, req);
2174 } else if (cmd_flags & REQ_FLUSH) { 2174 } else if (req && req_op(req) == REQ_OP_FLUSH) {
2175 /* complete ongoing async transfer before issuing flush */ 2175 /* complete ongoing async transfer before issuing flush */
2176 if (card->host->areq) 2176 if (card->host->areq)
2177 mmc_blk_issue_rw_rq(mq, NULL); 2177 mmc_blk_issue_rw_rq(mq, NULL);
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 9fb26f20a44d..d62531124d54 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -3,7 +3,8 @@
3 3
4static inline bool mmc_req_is_special(struct request *req) 4static inline bool mmc_req_is_special(struct request *req)
5{ 5{
6 return req && (req->cmd_flags & REQ_FLUSH || req_op(req) == REQ_OP_DISCARD); 6 return req &&
7 (req_op(req) == REQ_OP_FLUSH || req_op(req) == REQ_OP_DISCARD);
7} 8}
8 9
9struct request; 10struct request;
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 4eb9a5fb151c..78b3eb45faf6 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -87,7 +87,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
87 if (req->cmd_type != REQ_TYPE_FS) 87 if (req->cmd_type != REQ_TYPE_FS)
88 return -EIO; 88 return -EIO;
89 89
90 if (req->cmd_flags & REQ_FLUSH) 90 if (req_op(req) == REQ_OP_FLUSH)
91 return tr->flush(dev); 91 return tr->flush(dev);
92 92
93 if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > 93 if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 089b8b8aad4f..abdfdcfb66f4 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -290,7 +290,7 @@ int nvme_setup_cmd(struct nvme_ns *ns, struct request *req,
290 290
291 if (req->cmd_type == REQ_TYPE_DRV_PRIV) 291 if (req->cmd_type == REQ_TYPE_DRV_PRIV)
292 memcpy(cmd, req->cmd, sizeof(*cmd)); 292 memcpy(cmd, req->cmd, sizeof(*cmd));
293 else if (req->cmd_flags & REQ_FLUSH) 293 else if (req_op(req) == REQ_OP_FLUSH)
294 nvme_setup_flush(ns, cmd); 294 nvme_setup_flush(ns, cmd);
295 else if (req_op(req) == REQ_OP_DISCARD) 295 else if (req_op(req) == REQ_OP_DISCARD)
296 ret = nvme_setup_discard(ns, req, cmd); 296 ret = nvme_setup_discard(ns, req, cmd);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index fad86ad89e64..5a9db0fe1ee0 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1143,12 +1143,11 @@ static int sd_init_command(struct scsi_cmnd *cmd)
1143 return sd_setup_discard_cmnd(cmd); 1143 return sd_setup_discard_cmnd(cmd);
1144 case REQ_OP_WRITE_SAME: 1144 case REQ_OP_WRITE_SAME:
1145 return sd_setup_write_same_cmnd(cmd); 1145 return sd_setup_write_same_cmnd(cmd);
1146 case REQ_OP_FLUSH:
1147 return sd_setup_flush_cmnd(cmd);
1146 case REQ_OP_READ: 1148 case REQ_OP_READ:
1147 case REQ_OP_WRITE: 1149 case REQ_OP_WRITE:
1148 if (rq->cmd_flags & REQ_FLUSH) 1150 return sd_setup_read_write_cmnd(cmd);
1149 return sd_setup_flush_cmnd(cmd);
1150 else
1151 return sd_setup_read_write_cmnd(cmd);
1152 default: 1151 default:
1153 BUG(); 1152 BUG();
1154 } 1153 }
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 23c1ab2a9475..32d87522f349 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -249,9 +249,10 @@ enum req_op {
249 REQ_OP_WRITE, 249 REQ_OP_WRITE,
250 REQ_OP_DISCARD, /* request to discard sectors */ 250 REQ_OP_DISCARD, /* request to discard sectors */
251 REQ_OP_WRITE_SAME, /* write same block many times */ 251 REQ_OP_WRITE_SAME, /* write same block many times */
252 REQ_OP_FLUSH, /* request for cache flush */
252}; 253};
253 254
254#define REQ_OP_BITS 2 255#define REQ_OP_BITS 3
255 256
256typedef unsigned int blk_qc_t; 257typedef unsigned int blk_qc_t;
257#define BLK_QC_T_NONE -1U 258#define BLK_QC_T_NONE -1U
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 78ae3dbf2de1..0c9f8793c87e 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -666,6 +666,9 @@ static inline bool rq_mergeable(struct request *rq)
666 if (rq->cmd_type != REQ_TYPE_FS) 666 if (rq->cmd_type != REQ_TYPE_FS)
667 return false; 667 return false;
668 668
669 if (req_op(rq) == REQ_OP_FLUSH)
670 return false;
671
669 if (rq->cmd_flags & REQ_NOMERGE_FLAGS) 672 if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
670 return false; 673 return false;
671 674
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 2d16fad519b2..0c70fbb6ea8d 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -223,6 +223,8 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
223 what |= MASK_TC_BIT(op_flags, FUA); 223 what |= MASK_TC_BIT(op_flags, FUA);
224 if (op == REQ_OP_DISCARD) 224 if (op == REQ_OP_DISCARD)
225 what |= BLK_TC_ACT(BLK_TC_DISCARD); 225 what |= BLK_TC_ACT(BLK_TC_DISCARD);
226 if (op == REQ_OP_FLUSH)
227 what |= BLK_TC_ACT(BLK_TC_FLUSH);
226 228
227 pid = tsk->pid; 229 pid = tsk->pid;
228 if (act_log_check(bt, what, sector, pid)) 230 if (act_log_check(bt, what, sector, pid))
@@ -1788,6 +1790,9 @@ void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes)
1788 case REQ_OP_DISCARD: 1790 case REQ_OP_DISCARD:
1789 rwbs[i++] = 'D'; 1791 rwbs[i++] = 'D';
1790 break; 1792 break;
1793 case REQ_OP_FLUSH:
1794 rwbs[i++] = 'F';
1795 break;
1791 case REQ_OP_READ: 1796 case REQ_OP_READ:
1792 rwbs[i++] = 'R'; 1797 rwbs[i++] = 'R';
1793 break; 1798 break;