]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/splice.c
Merge branch 'omap-clock-fixes' of git://git.pwsan.com/linux-2.6
[linux-2.6-omap-h63xx.git] / fs / splice.c
index a54b3e3f10a716cb63ab56311745716a70086d0f..c18aa7e03e2b8d33470d6632052a839c3a1845c8 100644 (file)
@@ -59,7 +59,8 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
                 */
                wait_on_page_writeback(page);
 
-               if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL))
+               if (page_has_private(page) &&
+                   !try_to_release_page(page, GFP_KERNEL))
                        goto out_unlock;
 
                /*
@@ -736,10 +737,19 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
         * ->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.
+        *
+        * Outer lock must be inode->i_mutex, as pipe_wait() will
+        * release and reacquire pipe->inode->i_mutex, AND inode must
+        * never be a pipe.
         */
-       inode_double_lock(inode, pipe->inode);
+       WARN_ON(S_ISFIFO(inode->i_mode));
+       mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+       if (pipe->inode)
+               mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
        ret = __splice_from_pipe(pipe, &sd, actor);
-       inode_double_unlock(inode, pipe->inode);
+       if (pipe->inode)
+               mutex_unlock(&pipe->inode->i_mutex);
+       mutex_unlock(&inode->i_mutex);
 
        return ret;
 }
@@ -830,11 +840,17 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
        };
        ssize_t ret;
 
-       inode_double_lock(inode, pipe->inode);
+       WARN_ON(S_ISFIFO(inode->i_mode));
+       mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
        ret = file_remove_suid(out);
-       if (likely(!ret))
+       if (likely(!ret)) {
+               if (pipe->inode)
+                       mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
                ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
-       inode_double_unlock(inode, pipe->inode);
+               if (pipe->inode)
+                       mutex_unlock(&pipe->inode->i_mutex);
+       }
+       mutex_unlock(&inode->i_mutex);
        if (ret > 0) {
                unsigned long nr_pages;
 
@@ -1435,8 +1451,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;
@@ -1461,9 +1477,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;
@@ -1685,7 +1701,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;