blk-merge.c (a3b072cd180c12e8fe0ece9487b9065808327640) blk-merge.c (5cb8850c9c4a7605f74f5c9c7ecadd0b02e87a25)
1/*
2 * Functions related to segment and merge handling
3 */
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/bio.h>
7#include <linux/blkdev.h>
8#include <linux/scatterlist.h>

--- 7 unchanged lines hidden (view full) ---

16 int cluster, high, highprv = 1;
17 unsigned int seg_size, nr_phys_segs;
18 struct bio *fbio, *bbio;
19 struct bvec_iter iter;
20
21 if (!bio)
22 return 0;
23
1/*
2 * Functions related to segment and merge handling
3 */
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/bio.h>
7#include <linux/blkdev.h>
8#include <linux/scatterlist.h>

--- 7 unchanged lines hidden (view full) ---

16 int cluster, high, highprv = 1;
17 unsigned int seg_size, nr_phys_segs;
18 struct bio *fbio, *bbio;
19 struct bvec_iter iter;
20
21 if (!bio)
22 return 0;
23
24 /*
25 * This should probably be returning 0, but blk_add_request_payload()
26 * (Christoph!!!!)
27 */
28 if (bio->bi_rw & REQ_DISCARD)
29 return 1;
30
31 if (bio->bi_rw & REQ_WRITE_SAME)
32 return 1;
33
24 fbio = bio;
25 cluster = blk_queue_cluster(q);
26 seg_size = 0;
27 nr_phys_segs = 0;
28 for_each_bio(bio) {
29 bio_for_each_segment(bv, bio, iter) {
30 /*
31 * the trick here is making sure that a high page is

--- 124 unchanged lines hidden (view full) ---

156 }
157
158 sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
159 (*nsegs)++;
160 }
161 *bvprv = *bvec;
162}
163
34 fbio = bio;
35 cluster = blk_queue_cluster(q);
36 seg_size = 0;
37 nr_phys_segs = 0;
38 for_each_bio(bio) {
39 bio_for_each_segment(bv, bio, iter) {
40 /*
41 * the trick here is making sure that a high page is

--- 124 unchanged lines hidden (view full) ---

166 }
167
168 sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
169 (*nsegs)++;
170 }
171 *bvprv = *bvec;
172}
173
164/*
165 * map a request to scatterlist, return number of sg entries setup. Caller
166 * must make sure sg can hold rq->nr_phys_segments entries
167 */
168int blk_rq_map_sg(struct request_queue *q, struct request *rq,
169 struct scatterlist *sglist)
174static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
175 struct scatterlist *sglist,
176 struct scatterlist **sg)
170{
171 struct bio_vec bvec, bvprv = { NULL };
177{
178 struct bio_vec bvec, bvprv = { NULL };
172 struct req_iterator iter;
173 struct scatterlist *sg;
179 struct bvec_iter iter;
174 int nsegs, cluster;
175
176 nsegs = 0;
177 cluster = blk_queue_cluster(q);
178
180 int nsegs, cluster;
181
182 nsegs = 0;
183 cluster = blk_queue_cluster(q);
184
179 /*
180 * for each bio in rq
181 */
182 sg = NULL;
183 rq_for_each_segment(bvec, rq, iter) {
184 __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
185 &nsegs, &cluster);
186 } /* segments in rq */
185 if (bio->bi_rw & REQ_DISCARD) {
186 /*
187 * This is a hack - drivers should be neither modifying the
188 * biovec, nor relying on bi_vcnt - but because of
189 * blk_add_request_payload(), a discard bio may or may not have
190 * a payload we need to set up here (thank you Christoph) and
191 * bi_vcnt is really the only way of telling if we need to.
192 */
187
193
194 if (bio->bi_vcnt)
195 goto single_segment;
188
196
197 return 0;
198 }
199
200 if (bio->bi_rw & REQ_WRITE_SAME) {
201single_segment:
202 *sg = sglist;
203 bvec = bio_iovec(bio);
204 sg_set_page(*sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
205 return 1;
206 }
207
208 for_each_bio(bio)
209 bio_for_each_segment(bvec, bio, iter)
210 __blk_segment_map_sg(q, &bvec, sglist, &bvprv, sg,
211 &nsegs, &cluster);
212
213 return nsegs;
214}
215
216/*
217 * map a request to scatterlist, return number of sg entries setup. Caller
218 * must make sure sg can hold rq->nr_phys_segments entries
219 */
220int blk_rq_map_sg(struct request_queue *q, struct request *rq,
221 struct scatterlist *sglist)
222{
223 struct scatterlist *sg = NULL;
224 int nsegs = 0;
225
226 if (rq->bio)
227 nsegs = __blk_bios_map_sg(q, rq->bio, sglist, &sg);
228
189 if (unlikely(rq->cmd_flags & REQ_COPY_USER) &&
190 (blk_rq_bytes(rq) & q->dma_pad_mask)) {
191 unsigned int pad_len =
192 (q->dma_pad_mask & ~blk_rq_bytes(rq)) + 1;
193
194 sg->length += pad_len;
195 rq->extra_len += pad_len;
196 }

--- 28 unchanged lines hidden (view full) ---

225 * Note:
226 * Caller must make sure sg can hold bio->bi_phys_segments entries
227 *
228 * Will return the number of sg entries setup
229 */
230int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
231 struct scatterlist *sglist)
232{
229 if (unlikely(rq->cmd_flags & REQ_COPY_USER) &&
230 (blk_rq_bytes(rq) & q->dma_pad_mask)) {
231 unsigned int pad_len =
232 (q->dma_pad_mask & ~blk_rq_bytes(rq)) + 1;
233
234 sg->length += pad_len;
235 rq->extra_len += pad_len;
236 }

--- 28 unchanged lines hidden (view full) ---

265 * Note:
266 * Caller must make sure sg can hold bio->bi_phys_segments entries
267 *
268 * Will return the number of sg entries setup
269 */
270int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
271 struct scatterlist *sglist)
272{
233 struct bio_vec bvec, bvprv = { NULL };
234 struct scatterlist *sg;
235 int nsegs, cluster;
236 struct bvec_iter iter;
273 struct scatterlist *sg = NULL;
274 int nsegs;
275 struct bio *next = bio->bi_next;
276 bio->bi_next = NULL;
237
277
238 nsegs = 0;
239 cluster = blk_queue_cluster(q);
240
241 sg = NULL;
242 bio_for_each_segment(bvec, bio, iter) {
243 __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
244 &nsegs, &cluster);
245 } /* segments in bio */
246
278 nsegs = __blk_bios_map_sg(q, bio, sglist, &sg);
279 bio->bi_next = next;
247 if (sg)
248 sg_mark_end(sg);
249
250 BUG_ON(bio->bi_phys_segments && nsegs > bio->bi_phys_segments);
251 return nsegs;
252}
253EXPORT_SYMBOL(blk_bio_map_sg);
254

--- 303 unchanged lines hidden ---
280 if (sg)
281 sg_mark_end(sg);
282
283 BUG_ON(bio->bi_phys_segments && nsegs > bio->bi_phys_segments);
284 return nsegs;
285}
286EXPORT_SYMBOL(blk_bio_map_sg);
287

--- 303 unchanged lines hidden ---