aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-04-11 07:57:45 -0400
committerJens Axboe <axboe@suse.de>2006-04-11 07:57:45 -0400
commit341b446bc5aa36d1d5b8159c1e66716b5d89024d (patch)
tree6ccd0b90df84a94a4b7b4f8a6622d11786d74714
parent73d62d83ec3627782ba6f55defc76f3ffbef46ee (diff)
[PATCH] another round of fs/pipe.c cleanups
make pipe.c a bit more readable and hackable. Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Jens Axboe <axboe@suse.de>
-rw-r--r--fs/pipe.c76
1 files changed, 48 insertions, 28 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index b941e1951eac..e984beb93a0e 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -44,7 +44,8 @@ void pipe_wait(struct pipe_inode_info *pipe)
44 * Pipes are system-local resources, so sleeping on them 44 * Pipes are system-local resources, so sleeping on them
45 * is considered a noninteractive wait: 45 * is considered a noninteractive wait:
46 */ 46 */
47 prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); 47 prepare_to_wait(&pipe->wait, &wait,
48 TASK_INTERRUPTIBLE | TASK_NONINTERACTIVE);
48 if (pipe->inode) 49 if (pipe->inode)
49 mutex_unlock(&pipe->inode->i_mutex); 50 mutex_unlock(&pipe->inode->i_mutex);
50 schedule(); 51 schedule();
@@ -93,7 +94,8 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len)
93 return 0; 94 return 0;
94} 95}
95 96
96static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) 97static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
98 struct pipe_buffer *buf)
97{ 99{
98 struct page *page = buf->page; 100 struct page *page = buf->page;
99 101
@@ -102,25 +104,22 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buff
102 /* 104 /*
103 * If nobody else uses this page, and we don't already have a 105 * If nobody else uses this page, and we don't already have a
104 * temporary page, let's keep track of it as a one-deep 106 * temporary page, let's keep track of it as a one-deep
105 * allocation cache 107 * allocation cache. (Otherwise just release our reference to it)
106 */ 108 */
107 if (page_count(page) == 1 && !pipe->tmp_page) { 109 if (page_count(page) == 1 && !pipe->tmp_page)
108 pipe->tmp_page = page; 110 pipe->tmp_page = page;
109 return; 111 else
110 } 112 page_cache_release(page);
111
112 /*
113 * Otherwise just release our reference to it
114 */
115 page_cache_release(page);
116} 113}
117 114
118static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, struct pipe_buffer *buf) 115static void * anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe,
116 struct pipe_buffer *buf)
119{ 117{
120 return kmap(buf->page); 118 return kmap(buf->page);
121} 119}
122 120
123static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *buf) 121static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe,
122 struct pipe_buffer *buf)
124{ 123{
125 kunmap(buf->page); 124 kunmap(buf->page);
126} 125}
@@ -182,7 +181,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
182 error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); 181 error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
183 ops->unmap(pipe, buf); 182 ops->unmap(pipe, buf);
184 if (unlikely(error)) { 183 if (unlikely(error)) {
185 if (!ret) ret = -EFAULT; 184 if (!ret)
185 ret = -EFAULT;
186 break; 186 break;
187 } 187 }
188 ret += chars; 188 ret += chars;
@@ -218,7 +218,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
218 } 218 }
219 } 219 }
220 if (signal_pending(current)) { 220 if (signal_pending(current)) {
221 if (!ret) ret = -ERESTARTSYS; 221 if (!ret)
222 ret = -ERESTARTSYS;
222 break; 223 break;
223 } 224 }
224 if (do_wakeup) { 225 if (do_wakeup) {
@@ -228,7 +229,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
228 pipe_wait(pipe); 229 pipe_wait(pipe);
229 } 230 }
230 mutex_unlock(&inode->i_mutex); 231 mutex_unlock(&inode->i_mutex);
231 /* Signal writers asynchronously that there is more room. */ 232
233 /* Signal writers asynchronously that there is more room. */
232 if (do_wakeup) { 234 if (do_wakeup) {
233 wake_up_interruptible(&pipe->wait); 235 wake_up_interruptible(&pipe->wait);
234 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); 236 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
@@ -242,6 +244,7 @@ static ssize_t
242pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) 244pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
243{ 245{
244 struct iovec iov = { .iov_base = buf, .iov_len = count }; 246 struct iovec iov = { .iov_base = buf, .iov_len = count };
247
245 return pipe_readv(filp, &iov, 1, ppos); 248 return pipe_readv(filp, &iov, 1, ppos);
246} 249}
247 250
@@ -276,10 +279,12 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
276 /* We try to merge small writes */ 279 /* We try to merge small writes */
277 chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */ 280 chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
278 if (pipe->nrbufs && chars != 0) { 281 if (pipe->nrbufs && chars != 0) {
279 int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & (PIPE_BUFFERS-1); 282 int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
283 (PIPE_BUFFERS-1);
280 struct pipe_buffer *buf = pipe->bufs + lastbuf; 284 struct pipe_buffer *buf = pipe->bufs + lastbuf;
281 struct pipe_buf_operations *ops = buf->ops; 285 struct pipe_buf_operations *ops = buf->ops;
282 int offset = buf->offset + buf->len; 286 int offset = buf->offset + buf->len;
287
283 if (ops->can_merge && offset + chars <= PAGE_SIZE) { 288 if (ops->can_merge && offset + chars <= PAGE_SIZE) {
284 void *addr; 289 void *addr;
285 int error; 290 int error;
@@ -306,9 +311,11 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
306 311
307 for (;;) { 312 for (;;) {
308 int bufs; 313 int bufs;
314
309 if (!pipe->readers) { 315 if (!pipe->readers) {
310 send_sig(SIGPIPE, current, 0); 316 send_sig(SIGPIPE, current, 0);
311 if (!ret) ret = -EPIPE; 317 if (!ret)
318 ret = -EPIPE;
312 break; 319 break;
313 } 320 }
314 bufs = pipe->nrbufs; 321 bufs = pipe->nrbufs;
@@ -326,7 +333,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
326 } 333 }
327 pipe->tmp_page = page; 334 pipe->tmp_page = page;
328 } 335 }
329 /* Always wakeup, even if the copy fails. Otherwise 336 /* Always wake up, even if the copy fails. Otherwise
330 * we lock up (O_NONBLOCK-)readers that sleep due to 337 * we lock up (O_NONBLOCK-)readers that sleep due to
331 * syscall merging. 338 * syscall merging.
332 * FIXME! Is this really true? 339 * FIXME! Is this really true?
@@ -339,7 +346,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
339 error = pipe_iov_copy_from_user(kmap(page), iov, chars); 346 error = pipe_iov_copy_from_user(kmap(page), iov, chars);
340 kunmap(page); 347 kunmap(page);
341 if (unlikely(error)) { 348 if (unlikely(error)) {
342 if (!ret) ret = -EFAULT; 349 if (!ret)
350 ret = -EFAULT;
343 break; 351 break;
344 } 352 }
345 ret += chars; 353 ret += chars;
@@ -359,11 +367,13 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
359 if (bufs < PIPE_BUFFERS) 367 if (bufs < PIPE_BUFFERS)
360 continue; 368 continue;
361 if (filp->f_flags & O_NONBLOCK) { 369 if (filp->f_flags & O_NONBLOCK) {
362 if (!ret) ret = -EAGAIN; 370 if (!ret)
371 ret = -EAGAIN;
363 break; 372 break;
364 } 373 }
365 if (signal_pending(current)) { 374 if (signal_pending(current)) {
366 if (!ret) ret = -ERESTARTSYS; 375 if (!ret)
376 ret = -ERESTARTSYS;
367 break; 377 break;
368 } 378 }
369 if (do_wakeup) { 379 if (do_wakeup) {
@@ -391,6 +401,7 @@ pipe_write(struct file *filp, const char __user *buf,
391 size_t count, loff_t *ppos) 401 size_t count, loff_t *ppos)
392{ 402{
393 struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; 403 struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
404
394 return pipe_writev(filp, &iov, 1, ppos); 405 return pipe_writev(filp, &iov, 1, ppos);
395} 406}
396 407
@@ -401,7 +412,8 @@ bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
401} 412}
402 413
403static ssize_t 414static ssize_t
404bad_pipe_w(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) 415bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
416 loff_t *ppos)
405{ 417{
406 return -EBADF; 418 return -EBADF;
407} 419}
@@ -475,6 +487,7 @@ pipe_release(struct inode *inode, int decr, int decw)
475 pipe = inode->i_pipe; 487 pipe = inode->i_pipe;
476 pipe->readers -= decr; 488 pipe->readers -= decr;
477 pipe->writers -= decw; 489 pipe->writers -= decw;
490
478 if (!pipe->readers && !pipe->writers) { 491 if (!pipe->readers && !pipe->writers) {
479 free_pipe_info(inode); 492 free_pipe_info(inode);
480 } else { 493 } else {
@@ -525,14 +538,15 @@ static int
525pipe_rdwr_fasync(int fd, struct file *filp, int on) 538pipe_rdwr_fasync(int fd, struct file *filp, int on)
526{ 539{
527 struct inode *inode = filp->f_dentry->d_inode; 540 struct inode *inode = filp->f_dentry->d_inode;
541 struct pipe_inode_info *pipe = inode->i_pipe;
528 int retval; 542 int retval;
529 543
530 mutex_lock(&inode->i_mutex); 544 mutex_lock(&inode->i_mutex);
531 545
532 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); 546 retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
533 547
534 if (retval >= 0) 548 if (retval >= 0)
535 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); 549 retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
536 550
537 mutex_unlock(&inode->i_mutex); 551 mutex_unlock(&inode->i_mutex);
538 552
@@ -720,6 +734,7 @@ static int pipefs_delete_dentry(struct dentry *dentry)
720{ 734{
721 return 1; 735 return 1;
722} 736}
737
723static struct dentry_operations pipefs_dentry_operations = { 738static struct dentry_operations pipefs_dentry_operations = {
724 .d_delete = pipefs_delete_dentry, 739 .d_delete = pipefs_delete_dentry,
725}; 740};
@@ -757,6 +772,7 @@ static struct inode * get_pipe_inode(void)
757 772
758fail_iput: 773fail_iput:
759 iput(inode); 774 iput(inode);
775
760fail_inode: 776fail_inode:
761 return NULL; 777 return NULL;
762} 778}
@@ -769,7 +785,7 @@ int do_pipe(int *fd)
769 struct inode * inode; 785 struct inode * inode;
770 struct file *f1, *f2; 786 struct file *f1, *f2;
771 int error; 787 int error;
772 int i,j; 788 int i, j;
773 789
774 error = -ENFILE; 790 error = -ENFILE;
775 f1 = get_empty_filp(); 791 f1 = get_empty_filp();
@@ -802,6 +818,7 @@ int do_pipe(int *fd)
802 dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); 818 dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
803 if (!dentry) 819 if (!dentry)
804 goto close_f12_inode_i_j; 820 goto close_f12_inode_i_j;
821
805 dentry->d_op = &pipefs_dentry_operations; 822 dentry->d_op = &pipefs_dentry_operations;
806 d_add(dentry, inode); 823 d_add(dentry, inode);
807 f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); 824 f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt));
@@ -825,6 +842,7 @@ int do_pipe(int *fd)
825 fd_install(j, f2); 842 fd_install(j, f2);
826 fd[0] = i; 843 fd[0] = i;
827 fd[1] = j; 844 fd[1] = j;
845
828 return 0; 846 return 0;
829 847
830close_f12_inode_i_j: 848close_f12_inode_i_j:
@@ -849,8 +867,9 @@ no_files:
849 * d_name - pipe: will go nicely and kill the special-casing in procfs. 867 * d_name - pipe: will go nicely and kill the special-casing in procfs.
850 */ 868 */
851 869
852static struct super_block *pipefs_get_sb(struct file_system_type *fs_type, 870static struct super_block *
853 int flags, const char *dev_name, void *data) 871pipefs_get_sb(struct file_system_type *fs_type, int flags,
872 const char *dev_name, void *data)
854{ 873{
855 return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); 874 return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
856} 875}
@@ -864,6 +883,7 @@ static struct file_system_type pipe_fs_type = {
864static int __init init_pipe_fs(void) 883static int __init init_pipe_fs(void)
865{ 884{
866 int err = register_filesystem(&pipe_fs_type); 885 int err = register_filesystem(&pipe_fs_type);
886
867 if (!err) { 887 if (!err) {
868 pipe_mnt = kern_mount(&pipe_fs_type); 888 pipe_mnt = kern_mount(&pipe_fs_type);
869 if (IS_ERR(pipe_mnt)) { 889 if (IS_ERR(pipe_mnt)) {