When a cloned request is retried on other queues it always needs to be checked against the queue limits of that queue. Otherwise the calculations for nr_phys_segments might be wrong, leading to a crash in scsi_init_sgtable(). To clarify this the patch renames blk_rq_check_limits() to blk_cloned_rq_check_limits() and removes the symbol export, as the new function should only be used for cloned requests and never exported.
Unified · Split
| @@ -2114,7 +2114,8 @@ blk_qc_t submit_bio(int rw, struct bio *bio) · 2113 unmodified lines | ||
| 2114 | 2114 | EXPORT_SYMBOL(submit_bio); |
| 2115 | 2115 | |
| 2116 | 2116 | /** |
| 2117 | − * blk_rq_check_limits - Helper function to check a request for the queue limit | |
| 2117 | + * blk_cloned_rq_check_limits - Helper function to check a cloned request | |
| 2118 | + * for new the queue limits | |
| 2118 | 2119 | * @q: the queue |
| 2119 | 2120 | * @rq: the request being checked |
| 2120 | 2121 | * |
| @@ -2125,20 +2126,13 @@ EXPORT_SYMBOL(submit_bio); · 4 unmodified lines | ||
| 2125 | 2126 | * after it is inserted to @q, it should be checked against @q before |
| 2126 | 2127 | * the insertion using this generic function. |
| 2127 | 2128 | * |
| 2128 | − * This function should also be useful for request stacking drivers | |
| 2129 | − * in some cases below, so export this function. | |
| 2130 | 2129 | * Request stacking drivers like request-based dm may change the queue |
| 2131 | − * limits while requests are in the queue (e.g. dm's table swapping). | |
| 2132 | − * Such request stacking drivers should check those requests against | |
| 2133 | − * the new queue limits again when they dispatch those requests, | |
| 2134 | − * although such checkings are also done against the old queue limits | |
| 2135 | − * when submitting requests. | |
| 2130 | + * limits when retrying requests on other queues. Those requests need | |
| 2131 | + * to be checked against the new queue limits again during dispatch. | |
| 2136 | 2132 | */ |
| 2137 | −int blk_rq_check_limits(struct request_queue *q, struct request *rq) | |
| 2133 | +static int blk_cloned_rq_check_limits(struct request_queue *q, | |
| 2134 | + struct request *rq) | |
| 2138 | 2135 | { |
| 2139 | − if (!rq_mergeable(rq)) | |
| 2140 | − return 0; | |
| 2141 | − | |
| 2142 | 2136 | if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, rq->cmd_flags)) { |
| 2143 | 2137 | printk(KERN_ERR "%s: over max size limit.\n", __func__); |
| 2144 | 2138 | return -EIO; |
| @@ -2158,7 +2152,6 @@ int blk_rq_check_limits(struct request_queue *q, struct request *rq) · 13 unmodified lines | ||
| 2158 | 2152 | |
| 2159 | 2153 | return 0; |
| 2160 | 2154 | } |
| 2161 | −EXPORT_SYMBOL_GPL(blk_rq_check_limits); | |
| 2162 | 2155 | |
| 2163 | 2156 | /** |
| 2164 | 2157 | * blk_insert_cloned_request - Helper for stacking drivers to submit a request |
| @@ -2170,7 +2163,7 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq) · 5 unmodified lines | ||
| 2170 | 2163 | unsigned long flags; |
| 2171 | 2164 | int where = ELEVATOR_INSERT_BACK; |
| 2172 | 2165 | |
| 2173 | − if (blk_rq_check_limits(q, rq)) | |
| 2166 | + if (blk_cloned_rq_check_limits(q, rq)) | |
| 2174 | 2167 | return -EIO; |
| 2175 | 2168 | |
| 2176 | 2169 | if (rq->rq_disk && |
| @@ -773,7 +773,6 @@ extern void blk_rq_set_block_pc(struct request *); · 772 unmodified lines | ||
| 773 | 773 | extern void blk_requeue_request(struct request_queue *, struct request *); |
| 774 | 774 | extern void blk_add_request_payload(struct request *rq, struct page *page, |
| 775 | 775 | unsigned int len); |
| 776 | −extern int blk_rq_check_limits(struct request_queue *q, struct request *rq); | |
| 777 | 776 | extern int blk_lld_busy(struct request_queue *q); |
| 778 | 777 | extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src, |
| 779 | 778 | struct bio_set *bs, gfp_t gfp_mask, |