diff options
| -rw-r--r-- | block/blk-core.c | 80 |
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 | **/ |
| 2253 | bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) | 2243 | bool 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 | ||
