[PATCH] splice: fix problem introduced with inode diet

After the inode slimming patch that unionised i_pipe/i_bdev/i_cdev, it's
no longer enough to check for existance of ->i_pipe to verify that this
is a pipe.

Original patch from Eric Dumazet <dada1@cosmosbay.com>
Final solution suggested by Linus.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Jens Axboe and committed by Linus Torvalds ddac0d39 aaa9b971

+20 -6
+20 -6
fs/splice.c
··· 1109 1109 EXPORT_SYMBOL(do_splice_direct); 1110 1110 1111 1111 /* 1112 + * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same 1113 + * location, so checking ->i_pipe is not enough to verify that this is a 1114 + * pipe. 1115 + */ 1116 + static inline struct pipe_inode_info *pipe_info(struct inode *inode) 1117 + { 1118 + if (S_ISFIFO(inode->i_mode)) 1119 + return inode->i_pipe; 1120 + 1121 + return NULL; 1122 + } 1123 + 1124 + /* 1112 1125 * Determine where to splice to/from. 1113 1126 */ 1114 1127 static long do_splice(struct file *in, loff_t __user *off_in, ··· 1132 1119 loff_t offset, *off; 1133 1120 long ret; 1134 1121 1135 - pipe = in->f_dentry->d_inode->i_pipe; 1122 + pipe = pipe_info(in->f_dentry->d_inode); 1136 1123 if (pipe) { 1137 1124 if (off_in) 1138 1125 return -ESPIPE; ··· 1153 1140 return ret; 1154 1141 } 1155 1142 1156 - pipe = out->f_dentry->d_inode->i_pipe; 1143 + pipe = pipe_info(out->f_dentry->d_inode); 1157 1144 if (pipe) { 1158 1145 if (off_out) 1159 1146 return -ESPIPE; ··· 1311 1298 static long do_vmsplice(struct file *file, const struct iovec __user *iov, 1312 1299 unsigned long nr_segs, unsigned int flags) 1313 1300 { 1314 - struct pipe_inode_info *pipe = file->f_dentry->d_inode->i_pipe; 1301 + struct pipe_inode_info *pipe; 1315 1302 struct page *pages[PIPE_BUFFERS]; 1316 1303 struct partial_page partial[PIPE_BUFFERS]; 1317 1304 struct splice_pipe_desc spd = { ··· 1321 1308 .ops = &user_page_pipe_buf_ops, 1322 1309 }; 1323 1310 1324 - if (unlikely(!pipe)) 1311 + pipe = pipe_info(file->f_dentry->d_inode); 1312 + if (!pipe) 1325 1313 return -EBADF; 1326 1314 if (unlikely(nr_segs > UIO_MAXIOV)) 1327 1315 return -EINVAL; ··· 1549 1535 static long do_tee(struct file *in, struct file *out, size_t len, 1550 1536 unsigned int flags) 1551 1537 { 1552 - struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe; 1553 - struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe; 1538 + struct pipe_inode_info *ipipe = pipe_info(in->f_dentry->d_inode); 1539 + struct pipe_inode_info *opipe = pipe_info(out->f_dentry->d_inode); 1554 1540 int ret = -EINVAL; 1555 1541 1556 1542 /*