diff options
author | Keith Busch <keith.busch@intel.com> | 2015-01-12 15:04:06 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-01-28 09:44:15 -0700 |
commit | 77a086890173c0958515f7322880e4680cf12f8e (patch) | |
tree | 389cf1ad41d73a634b239df6a0d90209acc8357c /block | |
parent | 7fb4898e0cd6e7eba7419790921391e53848a35d (diff) | |
download | lwn-77a086890173c0958515f7322880e4680cf12f8e.tar.gz lwn-77a086890173c0958515f7322880e4680cf12f8e.zip |
block: keep established cmd_flags when cloning into a blk-mq request
blk_mq_alloc_request() may establish REQ_MQ_INFLIGHT in addition to
incrementing the hctx->nr_active count. Any cmd_flags that are
established in the newly allocated clone request must be preserved in
addition to the cmd_flags that are later copied over from the original
request as part of blk_rq_prep_clone().
Otherwise, if REQ_MQ_INFLIGHT isn't set in the clone request the
hctx->nr_active count won't get decremented via blk_mq_free_request().
The only consumer of blk_rq_prep_clone() is request-based DM, which uses
blk_rq_init() prior to calling blk_rq_prep_clone() for the non-blk-mq
case. Given the cloned request's cmd_flags will be 0 it is safe to OR
them with the original request's cmd_flags for both the non-blk-mq and
blk-mq cases.
Reported-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index c81f02cd17d4..b5e0cc381458 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2914,7 +2914,7 @@ EXPORT_SYMBOL_GPL(blk_rq_unprep_clone); static void __blk_rq_prep_clone(struct request *dst, struct request *src) { dst->cpu = src->cpu; - dst->cmd_flags = (src->cmd_flags & REQ_CLONE_MASK) | REQ_NOMERGE; + dst->cmd_flags |= (src->cmd_flags & REQ_CLONE_MASK) | REQ_NOMERGE; dst->cmd_type = src->cmd_type; dst->__sector = blk_rq_pos(src); dst->__data_len = blk_rq_bytes(src); |