revert android-tegra-2.6.36-honeycomb-mr1-9001adc to v2.6.36
[firefly-linux-kernel-4.4.55.git] / fs / splice.c
index ce2f02579e3539ff504f564564077b0641691e6d..8f1dfaecc8f06125429d3bc66b052d779f61f446 100644 (file)
@@ -1311,6 +1311,18 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
 static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
                               struct pipe_inode_info *opipe,
                               size_t len, unsigned int flags);
+/*
+ * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
+ * location, so checking ->i_pipe is not enough to verify that this is a
+ * pipe.
+ */
+static inline struct pipe_inode_info *pipe_info(struct inode *inode)
+{
+       if (S_ISFIFO(inode->i_mode))
+               return inode->i_pipe;
+
+       return NULL;
+}
 
 /*
  * Determine where to splice to/from.
@@ -1324,8 +1336,8 @@ static long do_splice(struct file *in, loff_t __user *off_in,
        loff_t offset, *off;
        long ret;
 
-       ipipe = get_pipe_info(in);
-       opipe = get_pipe_info(out);
+       ipipe = pipe_info(in->f_path.dentry->d_inode);
+       opipe = pipe_info(out->f_path.dentry->d_inode);
 
        if (ipipe && opipe) {
                if (off_in || off_out)
@@ -1543,7 +1555,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
        int error;
        long ret;
 
-       pipe = get_pipe_info(file);
+       pipe = pipe_info(file->f_path.dentry->d_inode);
        if (!pipe)
                return -EBADF;
 
@@ -1630,7 +1642,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
        };
        long ret;
 
-       pipe = get_pipe_info(file);
+       pipe = pipe_info(file->f_path.dentry->d_inode);
        if (!pipe)
                return -EBADF;
 
@@ -2010,8 +2022,8 @@ static int link_pipe(struct pipe_inode_info *ipipe,
 static long do_tee(struct file *in, struct file *out, size_t len,
                   unsigned int flags)
 {
-       struct pipe_inode_info *ipipe = get_pipe_info(in);
-       struct pipe_inode_info *opipe = get_pipe_info(out);
+       struct pipe_inode_info *ipipe = pipe_info(in->f_path.dentry->d_inode);
+       struct pipe_inode_info *opipe = pipe_info(out->f_path.dentry->d_inode);
        int ret = -EINVAL;
 
        /*