Merge branch 'locking-urgent-for-linus.patch' of git://git.kernel.org/pub/scm/linux...
[firefly-linux-kernel-4.4.55.git] / fs / splice.c
index f195a9b89fb22ea64ac5e8fda4af03d0ae3f16e3..f5cb9ba84510fe5632a62af0bbf3843a45eeba23 100644 (file)
@@ -718,63 +718,6 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
                                    sd->len, &pos, more);
 }
 
-/*
- * This is a little more tricky than the file -> pipe splicing. There are
- * basically three cases:
- *
- *     - Destination page already exists in the address space and there
- *       are users of it. For that case we have no other option that
- *       copying the data. Tough luck.
- *     - Destination page already exists in the address space, but there
- *       are no users of it. Make sure it's uptodate, then drop it. Fall
- *       through to last case.
- *     - Destination page does not exist, we can add the pipe page to
- *       the page cache and avoid the copy.
- *
- * If asked to move pages to the output file (SPLICE_F_MOVE is set in
- * sd->flags), we attempt to migrate pages from the pipe to the output
- * file address space page cache. This is possible if no one else has
- * the pipe page referenced outside of the pipe and page cache. If
- * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create
- * a new page in the output file page cache and fill/dirty that.
- */
-int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
-                struct splice_desc *sd)
-{
-       struct file *file = sd->u.file;
-       struct address_space *mapping = file->f_mapping;
-       unsigned int offset, this_len;
-       struct page *page;
-       void *fsdata;
-       int ret;
-
-       offset = sd->pos & ~PAGE_CACHE_MASK;
-
-       this_len = sd->len;
-       if (this_len + offset > PAGE_CACHE_SIZE)
-               this_len = PAGE_CACHE_SIZE - offset;
-
-       ret = pagecache_write_begin(file, mapping, sd->pos, this_len,
-                               AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
-       if (unlikely(ret))
-               goto out;
-
-       if (buf->page != page) {
-               char *src = kmap_atomic(buf->page);
-               char *dst = kmap_atomic(page);
-
-               memcpy(dst + offset, src + buf->offset, this_len);
-               flush_dcache_page(page);
-               kunmap_atomic(dst);
-               kunmap_atomic(src);
-       }
-       ret = pagecache_write_end(file, mapping, sd->pos, this_len, this_len,
-                               page, fsdata);
-out:
-       return ret;
-}
-EXPORT_SYMBOL(pipe_to_file);
-
 static void wakeup_pipe_writers(struct pipe_inode_info *pipe)
 {
        smp_mb();
@@ -803,7 +746,7 @@ static void wakeup_pipe_writers(struct pipe_inode_info *pipe)
  *    locking is required around copying the pipe buffers to the
  *    destination.
  */
-int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
+static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
                          splice_actor *actor)
 {
        int ret;
@@ -850,7 +793,6 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
 
        return 1;
 }
-EXPORT_SYMBOL(splice_from_pipe_feed);
 
 /**
  * splice_from_pipe_next - wait for some data to splice from
@@ -862,7 +804,7 @@ EXPORT_SYMBOL(splice_from_pipe_feed);
  *    value (one) if pipe buffers are available.  It will return zero
  *    or -errno if no more data needs to be spliced.
  */
-int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
+static int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
 {
        while (!pipe->nrbufs) {
                if (!pipe->writers)
@@ -887,7 +829,6 @@ int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
 
        return 1;
 }
-EXPORT_SYMBOL(splice_from_pipe_next);
 
 /**
  * splice_from_pipe_begin - start splicing from pipe
@@ -898,12 +839,11 @@ EXPORT_SYMBOL(splice_from_pipe_next);
  *    splice_from_pipe_next() and splice_from_pipe_feed() to
  *    initialize the necessary fields of @sd.
  */
-void splice_from_pipe_begin(struct splice_desc *sd)
+static void splice_from_pipe_begin(struct splice_desc *sd)
 {
        sd->num_spliced = 0;
        sd->need_wakeup = false;
 }
-EXPORT_SYMBOL(splice_from_pipe_begin);
 
 /**
  * splice_from_pipe_end - finish splicing from pipe
@@ -915,12 +855,11 @@ EXPORT_SYMBOL(splice_from_pipe_begin);
  *    be called after a loop containing splice_from_pipe_next() and
  *    splice_from_pipe_feed().
  */
-void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc *sd)
+static void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc *sd)
 {
        if (sd->need_wakeup)
                wakeup_pipe_writers(pipe);
 }
-EXPORT_SYMBOL(splice_from_pipe_end);
 
 /**
  * __splice_from_pipe - splice data from a pipe to given actor
@@ -985,74 +924,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
        return ret;
 }
 
-/**
- * generic_file_splice_write - splice data from a pipe to a file
- * @pipe:      pipe info
- * @out:       file to write to
- * @ppos:      position in @out
- * @len:       number of bytes to splice
- * @flags:     splice modifier flags
- *
- * Description:
- *    Will either move or copy pages (determined by @flags options) from
- *    the given pipe inode to the given file.
- *
- */
-ssize_t
-generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
-                         loff_t *ppos, size_t len, unsigned int flags)
-{
-       struct address_space *mapping = out->f_mapping;
-       struct inode *inode = mapping->host;
-       struct splice_desc sd = {
-               .total_len = len,
-               .flags = flags,
-               .pos = *ppos,
-               .u.file = out,
-       };
-       ssize_t ret;
-
-       pipe_lock(pipe);
-
-       splice_from_pipe_begin(&sd);
-       do {
-               ret = splice_from_pipe_next(pipe, &sd);
-               if (ret <= 0)
-                       break;
-
-               mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
-               ret = file_remove_suid(out);
-               if (!ret) {
-                       ret = file_update_time(out);
-                       if (!ret)
-                               ret = splice_from_pipe_feed(pipe, &sd,
-                                                           pipe_to_file);
-               }
-               mutex_unlock(&inode->i_mutex);
-       } while (ret > 0);
-       splice_from_pipe_end(pipe, &sd);
-
-       pipe_unlock(pipe);
-
-       if (sd.num_spliced)
-               ret = sd.num_spliced;
-
-       if (ret > 0) {
-               int err;
-
-               err = generic_write_sync(out, *ppos, ret);
-               if (err)
-                       ret = err;
-               else
-                       *ppos += ret;
-               balance_dirty_pages_ratelimited(mapping);
-       }
-
-       return ret;
-}
-
-EXPORT_SYMBOL(generic_file_splice_write);
-
 /**
  * iter_file_splice_write - splice data from a pipe to a file
  * @pipe:      pipe info
@@ -1677,7 +1548,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *uiov,
        struct iovec iovstack[UIO_FASTIOV];
        struct iovec *iov = iovstack;
        struct iov_iter iter;
-       ssize_t count = 0;
+       ssize_t count;
 
        pipe = get_pipe_info(file);
        if (!pipe)
@@ -1686,8 +1557,9 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *uiov,
        ret = rw_copy_check_uvector(READ, uiov, nr_segs,
                                    ARRAY_SIZE(iovstack), iovstack, &iov);
        if (ret <= 0)
-               return ret;
+               goto out;
 
+       count = ret;
        iov_iter_init(&iter, READ, iov, nr_segs, count);
 
        sd.len = 0;
@@ -1700,6 +1572,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *uiov,
        ret = __splice_from_pipe(pipe, &sd, pipe_to_user);
        pipe_unlock(pipe);
 
+out:
        if (iov != iovstack)
                kfree(iov);