summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/blk-flush.c11
-rw-r--r--block/blk-lib.c9
2 files changed, 18 insertions, 2 deletions
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 6e1543c10493..53abb5c73d99 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -308,9 +308,16 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
flush_rq->mq_ctx = first_rq->mq_ctx;
flush_rq->mq_hctx = first_rq->mq_hctx;
- if (!q->elevator)
+ if (!q->elevator) {
flush_rq->tag = first_rq->tag;
- else
+
+ /*
+ * We borrow data request's driver tag, so have to mark
+ * this flush request as INFLIGHT for avoiding double
+ * account of this driver tag
+ */
+ flush_rq->rq_flags |= RQF_MQ_INFLIGHT;
+ } else
flush_rq->internal_tag = first_rq->internal_tag;
flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 019e09bb9c0e..0d1811e57ac7 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -47,6 +47,15 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
op = REQ_OP_DISCARD;
}
+ /* In case the discard granularity isn't set by buggy device driver */
+ if (WARN_ON_ONCE(!q->limits.discard_granularity)) {
+ char dev_name[BDEVNAME_SIZE];
+
+ bdevname(bdev, dev_name);
+ pr_err_ratelimited("%s: Error: discard_granularity is 0.\n", dev_name);
+ return -EOPNOTSUPP;
+ }
+
bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
if ((sector | nr_sects) & bs_mask)
return -EINVAL;