fs: Call security_ops->inode_killpriv on truncate
[pandora-kernel.git] / fs / splice.c
index 7968da9..bfe62ae 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/gfp.h>
 #include <linux/socket.h>
 #include <linux/compat.h>
-#include <linux/aio.h>
 #include "internal.h"
 
 /*
@@ -524,6 +523,9 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
        loff_t isize, left;
        int ret;
 
+       if (IS_DAX(in->f_mapping->host))
+               return default_file_splice_read(in, ppos, pipe, len, flags);
+
        isize = i_size_read(in->f_mapping->host);
        if (unlikely(*ppos >= isize))
                return 0;
@@ -1159,7 +1161,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
        long ret, bytes;
        umode_t i_mode;
        size_t len;
-       int i, flags;
+       int i, flags, more;
 
        /*
         * We require the input being a regular file, as we don't want to
@@ -1202,6 +1204,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
         * Don't block on output, we have to drain the direct pipe.
         */
        sd->flags &= ~SPLICE_F_NONBLOCK;
+       more = sd->flags & SPLICE_F_MORE;
 
        while (len) {
                size_t read_len;
@@ -1214,6 +1217,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
                read_len = ret;
                sd->total_len = read_len;
 
+               /*
+                * If more data is pending, set SPLICE_F_MORE
+                * If this is the last data and SPLICE_F_MORE was not set
+                * initially, clears it.
+                */
+               if (read_len < len)
+                       sd->flags |= SPLICE_F_MORE;
+               else if (!more)
+                       sd->flags &= ~SPLICE_F_MORE;
                /*
                 * NOTE: nonblocking mode only applies to the input. We
                 * must not do the output in nonblocking mode as then we
@@ -1534,34 +1546,29 @@ 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;
 
        pipe = get_pipe_info(file);
        if (!pipe)
                return -EBADF;
 
-       ret = rw_copy_check_uvector(READ, uiov, nr_segs,
-                                   ARRAY_SIZE(iovstack), iovstack, &iov);
-       if (ret <= 0)
-               goto out;
-
-       count = ret;
-       iov_iter_init(&iter, READ, iov, nr_segs, count);
+       ret = import_iovec(READ, uiov, nr_segs,
+                          ARRAY_SIZE(iovstack), &iov, &iter);
+       if (ret < 0)
+               return ret;
 
+       sd.total_len = iov_iter_count(&iter);
        sd.len = 0;
-       sd.total_len = count;
        sd.flags = flags;
        sd.u.data = &iter;
        sd.pos = 0;
 
-       pipe_lock(pipe);
-       ret = __splice_from_pipe(pipe, &sd, pipe_to_user);
-       pipe_unlock(pipe);
-
-out:
-       if (iov != iovstack)
-               kfree(iov);
+       if (sd.total_len) {
+               pipe_lock(pipe);
+               ret = __splice_from_pipe(pipe, &sd, pipe_to_user);
+               pipe_unlock(pipe);
+       }
 
+       kfree(iov);
        return ret;
 }