提交 341b446b 编写于 作者: I Ingo Molnar 提交者: Jens Axboe

[PATCH] another round of fs/pipe.c cleanups

make pipe.c a bit more readable and hackable.
Signed-off-by: NIngo Molnar <mingo@elte.hu>
Signed-off-by: NJens Axboe <axboe@suse.de>
上级 73d62d83
...@@ -44,7 +44,8 @@ void pipe_wait(struct pipe_inode_info *pipe) ...@@ -44,7 +44,8 @@ void pipe_wait(struct pipe_inode_info *pipe)
* Pipes are system-local resources, so sleeping on them * Pipes are system-local resources, so sleeping on them
* is considered a noninteractive wait: * is considered a noninteractive wait:
*/ */
prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); prepare_to_wait(&pipe->wait, &wait,
TASK_INTERRUPTIBLE | TASK_NONINTERACTIVE);
if (pipe->inode) if (pipe->inode)
mutex_unlock(&pipe->inode->i_mutex); mutex_unlock(&pipe->inode->i_mutex);
schedule(); schedule();
...@@ -93,7 +94,8 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len) ...@@ -93,7 +94,8 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len)
return 0; return 0;
} }
static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{ {
struct page *page = buf->page; struct page *page = buf->page;
...@@ -102,25 +104,22 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buff ...@@ -102,25 +104,22 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buff
/* /*
* If nobody else uses this page, and we don't already have a * If nobody else uses this page, and we don't already have a
* temporary page, let's keep track of it as a one-deep * temporary page, let's keep track of it as a one-deep
* allocation cache * allocation cache. (Otherwise just release our reference to it)
*/ */
if (page_count(page) == 1 && !pipe->tmp_page) { if (page_count(page) == 1 && !pipe->tmp_page)
pipe->tmp_page = page; pipe->tmp_page = page;
return; else
} page_cache_release(page);
/*
* Otherwise just release our reference to it
*/
page_cache_release(page);
} }
static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, struct pipe_buffer *buf) static void * anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{ {
return kmap(buf->page); return kmap(buf->page);
} }
static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *buf) static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{ {
kunmap(buf->page); kunmap(buf->page);
} }
...@@ -182,7 +181,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov, ...@@ -182,7 +181,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
ops->unmap(pipe, buf); ops->unmap(pipe, buf);
if (unlikely(error)) { if (unlikely(error)) {
if (!ret) ret = -EFAULT; if (!ret)
ret = -EFAULT;
break; break;
} }
ret += chars; ret += chars;
...@@ -218,7 +218,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov, ...@@ -218,7 +218,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
} }
} }
if (signal_pending(current)) { if (signal_pending(current)) {
if (!ret) ret = -ERESTARTSYS; if (!ret)
ret = -ERESTARTSYS;
break; break;
} }
if (do_wakeup) { if (do_wakeup) {
...@@ -228,7 +229,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov, ...@@ -228,7 +229,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
pipe_wait(pipe); pipe_wait(pipe);
} }
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
/* Signal writers asynchronously that there is more room. */
/* Signal writers asynchronously that there is more room. */
if (do_wakeup) { if (do_wakeup) {
wake_up_interruptible(&pipe->wait); wake_up_interruptible(&pipe->wait);
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
...@@ -242,6 +244,7 @@ static ssize_t ...@@ -242,6 +244,7 @@ static ssize_t
pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{ {
struct iovec iov = { .iov_base = buf, .iov_len = count }; struct iovec iov = { .iov_base = buf, .iov_len = count };
return pipe_readv(filp, &iov, 1, ppos); return pipe_readv(filp, &iov, 1, ppos);
} }
...@@ -276,10 +279,12 @@ pipe_writev(struct file *filp, const struct iovec *_iov, ...@@ -276,10 +279,12 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
/* We try to merge small writes */ /* We try to merge small writes */
chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */ chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
if (pipe->nrbufs && chars != 0) { if (pipe->nrbufs && chars != 0) {
int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & (PIPE_BUFFERS-1); int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
(PIPE_BUFFERS-1);
struct pipe_buffer *buf = pipe->bufs + lastbuf; struct pipe_buffer *buf = pipe->bufs + lastbuf;
struct pipe_buf_operations *ops = buf->ops; struct pipe_buf_operations *ops = buf->ops;
int offset = buf->offset + buf->len; int offset = buf->offset + buf->len;
if (ops->can_merge && offset + chars <= PAGE_SIZE) { if (ops->can_merge && offset + chars <= PAGE_SIZE) {
void *addr; void *addr;
int error; int error;
...@@ -306,9 +311,11 @@ pipe_writev(struct file *filp, const struct iovec *_iov, ...@@ -306,9 +311,11 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
for (;;) { for (;;) {
int bufs; int bufs;
if (!pipe->readers) { if (!pipe->readers) {
send_sig(SIGPIPE, current, 0); send_sig(SIGPIPE, current, 0);
if (!ret) ret = -EPIPE; if (!ret)
ret = -EPIPE;
break; break;
} }
bufs = pipe->nrbufs; bufs = pipe->nrbufs;
...@@ -326,7 +333,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov, ...@@ -326,7 +333,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
} }
pipe->tmp_page = page; pipe->tmp_page = page;
} }
/* Always wakeup, even if the copy fails. Otherwise /* Always wake up, even if the copy fails. Otherwise
* we lock up (O_NONBLOCK-)readers that sleep due to * we lock up (O_NONBLOCK-)readers that sleep due to
* syscall merging. * syscall merging.
* FIXME! Is this really true? * FIXME! Is this really true?
...@@ -339,7 +346,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov, ...@@ -339,7 +346,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
error = pipe_iov_copy_from_user(kmap(page), iov, chars); error = pipe_iov_copy_from_user(kmap(page), iov, chars);
kunmap(page); kunmap(page);
if (unlikely(error)) { if (unlikely(error)) {
if (!ret) ret = -EFAULT; if (!ret)
ret = -EFAULT;
break; break;
} }
ret += chars; ret += chars;
...@@ -359,11 +367,13 @@ pipe_writev(struct file *filp, const struct iovec *_iov, ...@@ -359,11 +367,13 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
if (bufs < PIPE_BUFFERS) if (bufs < PIPE_BUFFERS)
continue; continue;
if (filp->f_flags & O_NONBLOCK) { if (filp->f_flags & O_NONBLOCK) {
if (!ret) ret = -EAGAIN; if (!ret)
ret = -EAGAIN;
break; break;
} }
if (signal_pending(current)) { if (signal_pending(current)) {
if (!ret) ret = -ERESTARTSYS; if (!ret)
ret = -ERESTARTSYS;
break; break;
} }
if (do_wakeup) { if (do_wakeup) {
...@@ -391,6 +401,7 @@ pipe_write(struct file *filp, const char __user *buf, ...@@ -391,6 +401,7 @@ pipe_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
return pipe_writev(filp, &iov, 1, ppos); return pipe_writev(filp, &iov, 1, ppos);
} }
...@@ -401,7 +412,8 @@ bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) ...@@ -401,7 +412,8 @@ bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
} }
static ssize_t static ssize_t
bad_pipe_w(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
loff_t *ppos)
{ {
return -EBADF; return -EBADF;
} }
...@@ -475,6 +487,7 @@ pipe_release(struct inode *inode, int decr, int decw) ...@@ -475,6 +487,7 @@ pipe_release(struct inode *inode, int decr, int decw)
pipe = inode->i_pipe; pipe = inode->i_pipe;
pipe->readers -= decr; pipe->readers -= decr;
pipe->writers -= decw; pipe->writers -= decw;
if (!pipe->readers && !pipe->writers) { if (!pipe->readers && !pipe->writers) {
free_pipe_info(inode); free_pipe_info(inode);
} else { } else {
...@@ -525,14 +538,15 @@ static int ...@@ -525,14 +538,15 @@ static int
pipe_rdwr_fasync(int fd, struct file *filp, int on) pipe_rdwr_fasync(int fd, struct file *filp, int on)
{ {
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
struct pipe_inode_info *pipe = inode->i_pipe;
int retval; int retval;
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
if (retval >= 0) if (retval >= 0)
retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
...@@ -720,6 +734,7 @@ static int pipefs_delete_dentry(struct dentry *dentry) ...@@ -720,6 +734,7 @@ static int pipefs_delete_dentry(struct dentry *dentry)
{ {
return 1; return 1;
} }
static struct dentry_operations pipefs_dentry_operations = { static struct dentry_operations pipefs_dentry_operations = {
.d_delete = pipefs_delete_dentry, .d_delete = pipefs_delete_dentry,
}; };
...@@ -757,6 +772,7 @@ static struct inode * get_pipe_inode(void) ...@@ -757,6 +772,7 @@ static struct inode * get_pipe_inode(void)
fail_iput: fail_iput:
iput(inode); iput(inode);
fail_inode: fail_inode:
return NULL; return NULL;
} }
...@@ -769,7 +785,7 @@ int do_pipe(int *fd) ...@@ -769,7 +785,7 @@ int do_pipe(int *fd)
struct inode * inode; struct inode * inode;
struct file *f1, *f2; struct file *f1, *f2;
int error; int error;
int i,j; int i, j;
error = -ENFILE; error = -ENFILE;
f1 = get_empty_filp(); f1 = get_empty_filp();
...@@ -802,6 +818,7 @@ int do_pipe(int *fd) ...@@ -802,6 +818,7 @@ int do_pipe(int *fd)
dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
if (!dentry) if (!dentry)
goto close_f12_inode_i_j; goto close_f12_inode_i_j;
dentry->d_op = &pipefs_dentry_operations; dentry->d_op = &pipefs_dentry_operations;
d_add(dentry, inode); d_add(dentry, inode);
f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt));
...@@ -825,6 +842,7 @@ int do_pipe(int *fd) ...@@ -825,6 +842,7 @@ int do_pipe(int *fd)
fd_install(j, f2); fd_install(j, f2);
fd[0] = i; fd[0] = i;
fd[1] = j; fd[1] = j;
return 0; return 0;
close_f12_inode_i_j: close_f12_inode_i_j:
...@@ -849,8 +867,9 @@ int do_pipe(int *fd) ...@@ -849,8 +867,9 @@ int do_pipe(int *fd)
* d_name - pipe: will go nicely and kill the special-casing in procfs. * d_name - pipe: will go nicely and kill the special-casing in procfs.
*/ */
static struct super_block *pipefs_get_sb(struct file_system_type *fs_type, static struct super_block *
int flags, const char *dev_name, void *data) pipefs_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{ {
return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
} }
...@@ -864,6 +883,7 @@ static struct file_system_type pipe_fs_type = { ...@@ -864,6 +883,7 @@ static struct file_system_type pipe_fs_type = {
static int __init init_pipe_fs(void) static int __init init_pipe_fs(void)
{ {
int err = register_filesystem(&pipe_fs_type); int err = register_filesystem(&pipe_fs_type);
if (!err) { if (!err) {
pipe_mnt = kern_mount(&pipe_fs_type); pipe_mnt = kern_mount(&pipe_fs_type);
if (IS_ERR(pipe_mnt)) { if (IS_ERR(pipe_mnt)) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册