diff options
Diffstat (limited to 'drivers/block/loop.c')
-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) |