aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-core.c80
1 files changed, 12 insertions, 68 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 074b758efc42..86a1afeef606 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -158,20 +158,10 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
158 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) 158 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
159 error = -EIO; 159 error = -EIO;
160 160
161 if (unlikely(nbytes > bio->bi_size)) {
162 printk(KERN_ERR "%s: want %u bytes done, %u left\n",
163 __func__, nbytes, bio->bi_size);
164 nbytes = bio->bi_size;
165 }
166
167 if (unlikely(rq->cmd_flags & REQ_QUIET)) 161 if (unlikely(rq->cmd_flags & REQ_QUIET))
168 set_bit(BIO_QUIET, &bio->bi_flags); 162 set_bit(BIO_QUIET, &bio->bi_flags);
169 163
170 bio->bi_size -= nbytes; 164 bio_advance(bio, nbytes);
171 bio->bi_sector += (nbytes >> 9);
172
173 if (bio_integrity(bio))
174 bio_integrity_advance(bio, nbytes);
175 165
176 /* don't actually finish bio if it's part of flush sequence */ 166 /* don't actually finish bio if it's part of flush sequence */
177 if (bio->bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ)) 167 if (bio->bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
@@ -2252,8 +2242,7 @@ EXPORT_SYMBOL(blk_fetch_request);
2252 **/ 2242 **/
2253bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) 2243bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
2254{ 2244{
2255 int total_bytes, bio_nbytes, next_idx = 0; 2245 int total_bytes;
2256 struct bio *bio;
2257 2246
2258 if (!req->bio) 2247 if (!req->bio)
2259 return false; 2248 return false;
@@ -2299,56 +2288,21 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
2299 2288
2300 blk_account_io_completion(req, nr_bytes); 2289 blk_account_io_completion(req, nr_bytes);
2301 2290
2302 total_bytes = bio_nbytes = 0; 2291 total_bytes = 0;
2303 while ((bio = req->bio) != NULL) { 2292 while (req->bio) {
2304 int nbytes; 2293 struct bio *bio = req->bio;
2294 unsigned bio_bytes = min(bio->bi_size, nr_bytes);
2305 2295
2306 if (nr_bytes >= bio->bi_size) { 2296 if (bio_bytes == bio->bi_size)
2307 req->bio = bio->bi_next; 2297 req->bio = bio->bi_next;
2308 nbytes = bio->bi_size;
2309 req_bio_endio(req, bio, nbytes, error);
2310 next_idx = 0;
2311 bio_nbytes = 0;
2312 } else {
2313 int idx = bio->bi_idx + next_idx;
2314
2315 if (unlikely(idx >= bio->bi_vcnt)) {
2316 blk_dump_rq_flags(req, "__end_that");
2317 printk(KERN_ERR "%s: bio idx %d >= vcnt %d\n",
2318 __func__, idx, bio->bi_vcnt);
2319 break;
2320 }
2321
2322 nbytes = bio_iovec_idx(bio, idx)->bv_len;
2323 BIO_BUG_ON(nbytes > bio->bi_size);
2324
2325 /*
2326 * not a complete bvec done
2327 */
2328 if (unlikely(nbytes > nr_bytes)) {
2329 bio_nbytes += nr_bytes;
2330 total_bytes += nr_bytes;
2331 break;
2332 }
2333 2298
2334 /* 2299 req_bio_endio(req, bio, bio_bytes, error);
2335 * advance to the next vector
2336 */
2337 next_idx++;
2338 bio_nbytes += nbytes;
2339 }
2340 2300
2341 total_bytes += nbytes; 2301 total_bytes += bio_bytes;
2342 nr_bytes -= nbytes; 2302 nr_bytes -= bio_bytes;
2343 2303
2344 bio = req->bio; 2304 if (!nr_bytes)
2345 if (bio) { 2305 break;
2346 /*
2347 * end more in this run, or just return 'not-done'
2348 */
2349 if (unlikely(nr_bytes <= 0))
2350 break;
2351 }
2352 } 2306 }
2353 2307
2354 /* 2308 /*
@@ -2364,16 +2318,6 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
2364 return false; 2318 return false;
2365 } 2319 }
2366 2320
2367 /*
2368 * if the request wasn't completed, update state
2369 */
2370 if (bio_nbytes) {
2371 req_bio_endio(req, bio, bio_nbytes, error);
2372 bio->bi_idx += next_idx;
2373 bio_iovec(bio)->bv_offset += nr_bytes;
2374 bio_iovec(bio)->bv_len -= nr_bytes;
2375 }
2376
2377 req->__data_len -= total_bytes; 2321 req->__data_len -= total_bytes;
2378 req->buffer = bio_data(req->bio); 2322 req->buffer = bio_data(req->bio);
2379 2323