fs: new inode i_state corruption fix
[safe/jmp/linux-2.6] / fs / splice.c
index b30311b..4ed0ba4 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/file.h>
 #include <linux/pagemap.h>
 #include <linux/splice.h>
+#include <linux/memcontrol.h>
 #include <linux/mm_inline.h>
 #include <linux/swap.h>
 #include <linux/writeback.h>
@@ -371,7 +372,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                         * for an in-flight io page
                         */
                        if (flags & SPLICE_F_NONBLOCK) {
-                               if (TestSetPageLocked(page)) {
+                               if (!trylock_page(page)) {
                                        error = -EAGAIN;
                                        break;
                                }
@@ -731,8 +732,8 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
        };
 
        /*
-        * The actor worker might be calling ->prepare_write and
-        * ->commit_write. Most of the time, these expect i_mutex to
+        * The actor worker might be calling ->write_begin and
+        * ->write_end. Most of the time, these expect i_mutex to
         * be held. Since this may result in an ABBA deadlock with
         * pipe->inode, we have to order lock acquiry here.
         */
@@ -898,6 +899,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
        if (unlikely(!(out->f_mode & FMODE_WRITE)))
                return -EBADF;
 
+       if (unlikely(out->f_flags & O_APPEND))
+               return -EINVAL;
+
        ret = rw_verify_area(WRITE, out, ppos, len);
        if (unlikely(ret < 0))
                return ret;
@@ -1431,8 +1435,8 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
  * Currently we punt and implement it as a normal copy, see pipe_to_user().
  *
  */
-asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
-                            unsigned long nr_segs, unsigned int flags)
+SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
+               unsigned long, nr_segs, unsigned int, flags)
 {
        struct file *file;
        long error;
@@ -1457,9 +1461,9 @@ asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
        return error;
 }
 
-asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
-                          int fd_out, loff_t __user *off_out,
-                          size_t len, unsigned int flags)
+SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
+               int, fd_out, loff_t __user *, off_out,
+               size_t, len, unsigned int, flags)
 {
        long error;
        struct file *in, *out;
@@ -1681,7 +1685,7 @@ static long do_tee(struct file *in, struct file *out, size_t len,
        return ret;
 }
 
-asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags)
+SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
 {
        struct file *in;
        int error, fput_in;