]> err.no Git - linux-2.6/blobdiff - fs/splice.c
[SCSI] dc395x: dynamically map scatter-gather for PIO
[linux-2.6] / fs / splice.c
index 36bc262dfbd58c9e64204483197bbc52046cb3b5..e50a460239dd28fe267dde5bde37c7566445a0ba 100644 (file)
@@ -9,11 +9,12 @@
  * that transfers data buffers to or from a pipe buffer.
  *
  * Named by Larry McVoy, original implementation from Linus, extended by
- * Jens to support splicing to files and fixing the initial implementation
- * bugs.
+ * Jens to support splicing to files, network, direct splicing, etc and
+ * fixing lots of bugs.
  *
- * Copyright (C) 2005 Jens Axboe <axboe@suse.de>
- * Copyright (C) 2005 Linus Torvalds <torvalds@osdl.org>
+ * Copyright (C) 2005-2006 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org>
+ * Copyright (C) 2006 Ingo Molnar <mingo@elte.hu>
  *
  */
 #include <linux/fs.h>
@@ -91,7 +92,7 @@ static void *page_cache_pipe_buf_map(struct file *file,
 
                /*
                 * Page got truncated/unhashed. This will cause a 0-byte
-                * splice, if this is the first page
+                * splice, if this is the first page.
                 */
                if (!page->mapping) {
                        err = -ENODATA;
@@ -99,7 +100,7 @@ static void *page_cache_pipe_buf_map(struct file *file,
                }
 
                /*
-                * uh oh, read-error from disk
+                * Uh oh, read-error from disk.
                 */
                if (!PageUptodate(page)) {
                        err = -EIO;
@@ -107,7 +108,7 @@ static void *page_cache_pipe_buf_map(struct file *file,
                }
 
                /*
-                * page is ok afterall, fall through to mapping
+                * Page is ok afterall, fall through to mapping.
                 */
                unlock_page(page);
        }
@@ -248,7 +249,7 @@ __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
                nr_pages = PIPE_BUFFERS;
 
        /*
-        * initiate read-ahead on this page range. however, don't call into
+        * Initiate read-ahead on this page range. however, don't call into
         * read-ahead if this is a non-zero offset (we are likely doing small
         * chunk splice and the page is already there) for a single page.
         */
@@ -256,7 +257,7 @@ __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
                do_page_cache_readahead(mapping, in, index, nr_pages);
 
        /*
-        * now fill in the holes
+        * Now fill in the holes:
         */
        error = 0;
        for (i = 0; i < nr_pages; i++, index++) {
@@ -346,7 +347,6 @@ fill_it:
  * @flags:     splice modifier flags
  *
  * Will read pages from given file and fill them into a pipe.
- *
  */
 ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
                                 size_t len, unsigned int flags)
@@ -396,10 +396,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *info,
        int more;
 
        /*
-        * sub-optimal, but we are limited by the pipe ->map. we don't
+        * Sub-optimal, but we are limited by the pipe ->map. We don't
         * need a kmap'ed buffer here, we just want to make sure we
         * have the page pinned if the pipe page originates from the
-        * page cache
+        * page cache.
         */
        ptr = buf->ops->map(file, info, buf);
        if (IS_ERR(ptr))
@@ -460,7 +460,7 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
        offset = sd->pos & ~PAGE_CACHE_MASK;
 
        /*
-        * reuse buf page, if SPLICE_F_MOVE is set
+        * Reuse buf page, if SPLICE_F_MOVE is set.
         */
        if (sd->flags & SPLICE_F_MOVE) {
                /*
@@ -501,7 +501,7 @@ find_page:
 
                                if (!PageUptodate(page)) {
                                        /*
-                                        * page got invalidated, repeat
+                                        * Page got invalidated, repeat.
                                         */
                                        if (!page->mapping) {
                                                unlock_page(page);
@@ -598,6 +598,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
                        ret += sd.len;
                        buf->offset += sd.len;
                        buf->len -= sd.len;
+
                        if (!buf->len) {
                                buf->ops = NULL;
                                ops->release(pipe, buf);
@@ -681,7 +682,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
        ret = move_from_pipe(pipe, out, len, flags, pipe_to_file);
 
        /*
-        * if file or inode is SYNC and we actually wrote some data, sync it
+        * If file or inode is SYNC and we actually wrote some data, sync it.
         */
        if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host))
            && ret > 0) {
@@ -690,7 +691,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 
                mutex_lock(&inode->i_mutex);
                err = generic_osync_inode(mapping->host, mapping,
-                                               OSYNC_METADATA|OSYNC_DATA);
+                                         OSYNC_METADATA|OSYNC_DATA);
                mutex_unlock(&inode->i_mutex);
 
                if (err)
@@ -730,10 +731,10 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
        loff_t pos;
        int ret;
 
-       if (!out->f_op || !out->f_op->splice_write)
+       if (unlikely(!out->f_op || !out->f_op->splice_write))
                return -EINVAL;
 
-       if (!(out->f_mode & FMODE_WRITE))
+       if (unlikely(!(out->f_mode & FMODE_WRITE)))
                return -EBADF;
 
        pos = out->f_pos;
@@ -754,10 +755,10 @@ static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
        loff_t pos, isize, left;
        int ret;
 
-       if (!in->f_op || !in->f_op->splice_read)
+       if (unlikely(!in->f_op || !in->f_op->splice_read))
                return -EINVAL;
 
-       if (!(in->f_mode & FMODE_READ))
+       if (unlikely(!(in->f_mode & FMODE_READ)))
                return -EBADF;
 
        pos = in->f_pos;
@@ -771,7 +772,7 @@ static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
                return 0;
        
        left = isize - in->f_pos;
-       if (left < len)
+       if (unlikely(left < len))
                len = left;
 
        return in->f_op->splice_read(in, pipe, len, flags);
@@ -799,7 +800,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len,
         * 'out' and transfer the wanted data from 'in' to 'out' through that
         */
        pipe = current->splice_pipe;
-       if (!pipe) {
+       if (unlikely(!pipe)) {
                pipe = alloc_pipe_info(NULL);
                if (!pipe)
                        return -ENOMEM;
@@ -815,7 +816,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len,
        }
 
        /*
-        * do the splice
+        * Do the splice.
         */
        ret = 0;
        bytes = 0;