aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-06-12 15:20:37 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-07-10 02:04:14 -0400
commitfd5821404e6823997666d668f62c76eae228abc9 (patch)
tree6d818f0d0201d0b0553aa0e50376802318e627af /drivers/block
parent130610d6f681c5d970340897f5db000d04a7ef78 (diff)
loop: convert to using splice_direct_to_actor() instead of sendfile()
This gets rid of the dependency on ->sendfile() for receiving data and converts loop to ->splice_read() instead. Also includes an IV offset fix from Hugh Dickins. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/loop.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0ed5470d2533..87d84e7d5432 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -74,6 +74,7 @@
74#include <linux/highmem.h> 74#include <linux/highmem.h>
75#include <linux/gfp.h> 75#include <linux/gfp.h>
76#include <linux/kthread.h> 76#include <linux/kthread.h>
77#include <linux/pipe_fs_i.h>
77 78
78#include <asm/uaccess.h> 79#include <asm/uaccess.h>
79 80
@@ -401,50 +402,73 @@ struct lo_read_data {
401}; 402};
402 403
403static int 404static int
404lo_read_actor(read_descriptor_t *desc, struct page *page, 405lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
405 unsigned long offset, unsigned long size) 406 struct splice_desc *sd)
406{ 407{
407 unsigned long count = desc->count; 408 struct lo_read_data *p = sd->u.data;
408 struct lo_read_data *p = desc->arg.data;
409 struct loop_device *lo = p->lo; 409 struct loop_device *lo = p->lo;
410 struct page *page = buf->page;
410 sector_t IV; 411 sector_t IV;
412 size_t size;
413 int ret;
411 414
412 IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); 415 ret = buf->ops->pin(pipe, buf);
416 if (unlikely(ret))
417 return ret;
413 418
414 if (size > count) 419 IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
415 size = count; 420 (buf->offset >> 9);
421 size = sd->len;
422 if (size > p->bsize)
423 size = p->bsize;
416 424
417 if (lo_do_transfer(lo, READ, page, offset, p->page, p->offset, size, IV)) { 425 if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) {
418 size = 0;
419 printk(KERN_ERR "loop: transfer error block %ld\n", 426 printk(KERN_ERR "loop: transfer error block %ld\n",
420 page->index); 427 page->index);
421 desc->error = -EINVAL; 428 size = -EINVAL;
422 } 429 }
423 430
424 flush_dcache_page(p->page); 431 flush_dcache_page(p->page);
425 432
426 desc->count = count - size; 433 if (size > 0)
427 desc->written += size; 434 p->offset += size;
428 p->offset += size; 435
429 return size; 436 return size;
430} 437}
431 438
432static int 439static int
440lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
441{
442 return __splice_from_pipe(pipe, sd, lo_splice_actor);
443}
444
445static int
433do_lo_receive(struct loop_device *lo, 446do_lo_receive(struct loop_device *lo,
434 struct bio_vec *bvec, int bsize, loff_t pos) 447 struct bio_vec *bvec, int bsize, loff_t pos)
435{ 448{
436 struct lo_read_data cookie; 449 struct lo_read_data cookie;
450 struct splice_desc sd;
437 struct file *file; 451 struct file *file;
438 int retval; 452 long retval;
439 453
440 cookie.lo = lo; 454 cookie.lo = lo;
441 cookie.page = bvec->bv_page; 455 cookie.page = bvec->bv_page;
442 cookie.offset = bvec->bv_offset; 456 cookie.offset = bvec->bv_offset;
443 cookie.bsize = bsize; 457 cookie.bsize = bsize;
458
459 sd.len = 0;
460 sd.total_len = bvec->bv_len;
461 sd.flags = 0;
462 sd.pos = pos;
463 sd.u.data = &cookie;
464
444 file = lo->lo_backing_file; 465 file = lo->lo_backing_file;
445 retval = file->f_op->sendfile(file, &pos, bvec->bv_len, 466 retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
446 lo_read_actor, &cookie); 467
447 return (retval < 0)? retval: 0; 468 if (retval < 0)
469 return retval;
470
471 return 0;
448} 472}
449 473
450static int 474static int
@@ -679,8 +703,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
679 if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) 703 if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
680 goto out_putf; 704 goto out_putf;
681 705
682 /* new backing store needs to support loop (eg sendfile) */ 706 /* new backing store needs to support loop (eg splice_read) */
683 if (!inode->i_fop->sendfile) 707 if (!inode->i_fop->splice_read)
684 goto out_putf; 708 goto out_putf;
685 709
686 /* size of the new backing store needs to be the same */ 710 /* size of the new backing store needs to be the same */
@@ -760,7 +784,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
760 * If we can't read - sorry. If we only can't write - well, 784 * If we can't read - sorry. If we only can't write - well,
761 * it's going to be read-only. 785 * it's going to be read-only.
762 */ 786 */
763 if (!file->f_op->sendfile) 787 if (!file->f_op->splice_read)
764 goto out_putf; 788 goto out_putf;
765 if (aops->prepare_write && aops->commit_write) 789 if (aops->prepare_write && aops->commit_write)
766 lo_flags |= LO_FLAGS_USE_AOPS; 790 lo_flags |= LO_FLAGS_USE_AOPS;