[PATCH]: Fill the size of FIFOs Instead of reporting 0 in size when stating() a pipe, we give the number of queued bytes. This might avoid using ioctl(FIONREAD) to get this information. References: http://lkml.org/lkml/2007/4/2/138 Cc: Eric Dumazet <dada1@xxxxxxxxxxxxx> Signed-off-by: Jan Engelhardt <jengelh@xxxxxx> --- fs/pipe.c | 20 +++----------------- fs/stat.c | 14 ++++++++++---- include/linux/pipe_fs_i.h | 2 ++ 3 files changed, 15 insertions(+), 21 deletions(-) Index: linux-2.6.23/fs/pipe.c =================================================================== --- linux-2.6.23.orig/fs/pipe.c +++ linux-2.6.23/fs/pipe.c @@ -577,14 +577,15 @@ bad_pipe_w(struct file *filp, const char return -EBADF; } -static unsigned int pipe_size(struct inode *inode) +unsigned int pipe_size(struct inode *inode) { struct pipe_inode_info *pipe; unsigned int count, buf; int nrbufs; + if ((pipe = inode->i_pipe) == NULL) + return 0; mutex_lock(&inode->i_mutex); - pipe = inode->i_pipe; count = 0; buf = pipe->curbuf; nrbufs = pipe->nrbufs; @@ -923,20 +924,6 @@ static struct dentry_operations pipefs_d .d_dname = pipefs_dname, }; -int pipe_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat) -{ - struct inode *inode = dentry->d_inode; - - generic_fillattr(inode, stat); - stat->size = pipe_size(inode); - return 0; -} - -const struct inode_operations pipe_inode_operations = { - .getattr = pipe_getattr, -}; - static struct inode * get_pipe_inode(void) { struct inode *inode = new_inode(pipe_mnt->mnt_sb); @@ -950,7 +937,6 @@ static struct inode * get_pipe_inode(voi goto fail_iput; inode->i_pipe = pipe; - inode->i_op = &pipe_inode_operations; pipe->readers = pipe->writers = 1; inode->i_fop = &rdwr_pipe_fops; Index: linux-2.6.23/fs/stat.c =================================================================== --- linux-2.6.23.orig/fs/stat.c +++ linux-2.6.23/fs/stat.c @@ -11,6 +11,7 @@ #include <linux/highuid.h> #include <linux/fs.h> #include <linux/namei.h> +#include <linux/pipe_fs_i.h> #include <linux/security.h> #include <linux/syscalls.h> #include <linux/pagemap.h> @@ -46,11 +47,16 @@ int vfs_getattr(struct vfsmount *mnt, st if (retval) return retval; - if (inode->i_op->getattr) - return inode->i_op->getattr(mnt, dentry, stat); + if (inode->i_op->getattr) { + retval = inode->i_op->getattr(mnt, dentry, stat); + } else { + generic_fillattr(inode, stat); + retval = 0; + } - generic_fillattr(inode, stat); - return 0; + if (retval == 0 && S_ISFIFO(inode->i_mode)) + stat->size = pipe_size(inode); + return retval; } EXPORT_SYMBOL(vfs_getattr); Index: linux-2.6.23/include/linux/pipe_fs_i.h =================================================================== --- linux-2.6.23.orig/include/linux/pipe_fs_i.h +++ linux-2.6.23/include/linux/pipe_fs_i.h @@ -134,6 +134,8 @@ struct pipe_buf_operations { memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ #define PIPE_SIZE PAGE_SIZE +extern unsigned int pipe_size(struct inode *); + /* Drop the inode semaphore and wait for a pipe event, atomically */ void pipe_wait(struct pipe_inode_info *pipe); - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html