diff options
| -rw-r--r-- | drivers/block/loop.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index f00257782fcc..cd504353b278 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -356,14 +356,14 @@ lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd) | |||
| 356 | return __splice_from_pipe(pipe, sd, lo_splice_actor); | 356 | return __splice_from_pipe(pipe, sd, lo_splice_actor); |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | static int | 359 | static ssize_t |
| 360 | do_lo_receive(struct loop_device *lo, | 360 | do_lo_receive(struct loop_device *lo, |
| 361 | struct bio_vec *bvec, int bsize, loff_t pos) | 361 | struct bio_vec *bvec, int bsize, loff_t pos) |
| 362 | { | 362 | { |
| 363 | struct lo_read_data cookie; | 363 | struct lo_read_data cookie; |
| 364 | struct splice_desc sd; | 364 | struct splice_desc sd; |
| 365 | struct file *file; | 365 | struct file *file; |
| 366 | long retval; | 366 | ssize_t retval; |
| 367 | 367 | ||
| 368 | cookie.lo = lo; | 368 | cookie.lo = lo; |
| 369 | cookie.page = bvec->bv_page; | 369 | cookie.page = bvec->bv_page; |
| @@ -379,26 +379,28 @@ do_lo_receive(struct loop_device *lo, | |||
| 379 | file = lo->lo_backing_file; | 379 | file = lo->lo_backing_file; |
| 380 | retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); | 380 | retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); |
| 381 | 381 | ||
| 382 | if (retval < 0) | 382 | return retval; |
| 383 | return retval; | ||
| 384 | if (retval != bvec->bv_len) | ||
| 385 | return -EIO; | ||
| 386 | return 0; | ||
| 387 | } | 383 | } |
| 388 | 384 | ||
| 389 | static int | 385 | static int |
| 390 | lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) | 386 | lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) |
| 391 | { | 387 | { |
| 392 | struct bio_vec *bvec; | 388 | struct bio_vec *bvec; |
| 393 | int i, ret = 0; | 389 | ssize_t s; |
| 390 | int i; | ||
| 394 | 391 | ||
| 395 | bio_for_each_segment(bvec, bio, i) { | 392 | bio_for_each_segment(bvec, bio, i) { |
| 396 | ret = do_lo_receive(lo, bvec, bsize, pos); | 393 | s = do_lo_receive(lo, bvec, bsize, pos); |
| 397 | if (ret < 0) | 394 | if (s < 0) |
| 395 | return s; | ||
| 396 | |||
| 397 | if (s != bvec->bv_len) { | ||
| 398 | zero_fill_bio(bio); | ||
| 398 | break; | 399 | break; |
| 400 | } | ||
| 399 | pos += bvec->bv_len; | 401 | pos += bvec->bv_len; |
| 400 | } | 402 | } |
| 401 | return ret; | 403 | return 0; |
| 402 | } | 404 | } |
| 403 | 405 | ||
| 404 | static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | 406 | static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) |
