diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-04-10 09:18:35 -0400 |
---|---|---|
committer | Jens Axboe <axboe@suse.de> | 2006-04-10 09:18:35 -0400 |
commit | 3a326a2ce88e71d00ac0d133e314a3342a7709f8 (patch) | |
tree | 3a3cf55be19311c04d195e37baec9f49c4015b18 | |
parent | 0b749ce3802428007a37870eb51ba3c0bdf90857 (diff) |
[PATCH] introduce a "kernel-internal pipe object" abstraction
separate out the 'internal pipe object' abstraction, and make it
usable to splice. This cleans up and fixes several aspects of the
internal splice APIs and the pipe code:
- pipes: the allocation and freeing of pipe_inode_info is now more symmetric
and more streamlined with existing kernel practices.
- splice: small micro-optimization: less pointer dereferencing in splice
methods
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Update XFS for the ->splice_read/->splice_write changes.
Signed-off-by: Jens Axboe <axboe@suse.de>
-rw-r--r-- | fs/fifo.c | 12 | ||||
-rw-r--r-- | fs/pipe.c | 51 | ||||
-rw-r--r-- | fs/splice.c | 122 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 8 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 4 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.h | 4 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vnode.h | 4 | ||||
-rw-r--r-- | include/linux/fs.h | 8 | ||||
-rw-r--r-- | include/linux/pipe_fs_i.h | 7 |
9 files changed, 114 insertions, 106 deletions
@@ -15,12 +15,13 @@ | |||
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/pipe_fs_i.h> | 16 | #include <linux/pipe_fs_i.h> |
17 | 17 | ||
18 | static void wait_for_partner(struct inode* inode, unsigned int* cnt) | 18 | static void wait_for_partner(struct inode* inode, unsigned int *cnt) |
19 | { | 19 | { |
20 | int cur = *cnt; | 20 | int cur = *cnt; |
21 | while(cur == *cnt) { | 21 | |
22 | pipe_wait(inode); | 22 | while (cur == *cnt) { |
23 | if(signal_pending(current)) | 23 | pipe_wait(inode->i_pipe); |
24 | if (signal_pending(current)) | ||
24 | break; | 25 | break; |
25 | } | 26 | } |
26 | } | 27 | } |
@@ -37,7 +38,8 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
37 | mutex_lock(PIPE_MUTEX(*inode)); | 38 | mutex_lock(PIPE_MUTEX(*inode)); |
38 | if (!inode->i_pipe) { | 39 | if (!inode->i_pipe) { |
39 | ret = -ENOMEM; | 40 | ret = -ENOMEM; |
40 | if(!pipe_new(inode)) | 41 | inode->i_pipe = alloc_pipe_info(inode); |
42 | if (!inode->i_pipe) | ||
41 | goto err_nocleanup; | 43 | goto err_nocleanup; |
42 | } | 44 | } |
43 | filp->f_version = 0; | 45 | filp->f_version = 0; |
@@ -36,7 +36,7 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | /* Drop the inode semaphore and wait for a pipe event, atomically */ | 38 | /* Drop the inode semaphore and wait for a pipe event, atomically */ |
39 | void pipe_wait(struct inode * inode) | 39 | void pipe_wait(struct pipe_inode_info *pipe) |
40 | { | 40 | { |
41 | DEFINE_WAIT(wait); | 41 | DEFINE_WAIT(wait); |
42 | 42 | ||
@@ -44,11 +44,13 @@ void pipe_wait(struct inode * inode) | |||
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(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); | 47 | prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); |
48 | mutex_unlock(PIPE_MUTEX(*inode)); | 48 | if (pipe->inode) |
49 | mutex_unlock(&pipe->inode->i_mutex); | ||
49 | schedule(); | 50 | schedule(); |
50 | finish_wait(PIPE_WAIT(*inode), &wait); | 51 | finish_wait(&pipe->wait, &wait); |
51 | mutex_lock(PIPE_MUTEX(*inode)); | 52 | if (pipe->inode) |
53 | mutex_lock(&pipe->inode->i_mutex); | ||
52 | } | 54 | } |
53 | 55 | ||
54 | static int | 56 | static int |
@@ -223,7 +225,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
223 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); | 225 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); |
224 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); | 226 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); |
225 | } | 227 | } |
226 | pipe_wait(inode); | 228 | pipe_wait(inode->i_pipe); |
227 | } | 229 | } |
228 | mutex_unlock(PIPE_MUTEX(*inode)); | 230 | mutex_unlock(PIPE_MUTEX(*inode)); |
229 | /* Signal writers asynchronously that there is more room. */ | 231 | /* Signal writers asynchronously that there is more room. */ |
@@ -370,7 +372,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
370 | do_wakeup = 0; | 372 | do_wakeup = 0; |
371 | } | 373 | } |
372 | PIPE_WAITING_WRITERS(*inode)++; | 374 | PIPE_WAITING_WRITERS(*inode)++; |
373 | pipe_wait(inode); | 375 | pipe_wait(inode->i_pipe); |
374 | PIPE_WAITING_WRITERS(*inode)--; | 376 | PIPE_WAITING_WRITERS(*inode)--; |
375 | } | 377 | } |
376 | out: | 378 | out: |
@@ -675,6 +677,20 @@ static struct file_operations rdwr_pipe_fops = { | |||
675 | .fasync = pipe_rdwr_fasync, | 677 | .fasync = pipe_rdwr_fasync, |
676 | }; | 678 | }; |
677 | 679 | ||
680 | struct pipe_inode_info * alloc_pipe_info(struct inode *inode) | ||
681 | { | ||
682 | struct pipe_inode_info *info; | ||
683 | |||
684 | info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); | ||
685 | if (info) { | ||
686 | init_waitqueue_head(&info->wait); | ||
687 | info->r_counter = info->w_counter = 1; | ||
688 | info->inode = inode; | ||
689 | } | ||
690 | |||
691 | return info; | ||
692 | } | ||
693 | |||
678 | void free_pipe_info(struct inode *inode) | 694 | void free_pipe_info(struct inode *inode) |
679 | { | 695 | { |
680 | int i; | 696 | int i; |
@@ -691,23 +707,6 @@ void free_pipe_info(struct inode *inode) | |||
691 | kfree(info); | 707 | kfree(info); |
692 | } | 708 | } |
693 | 709 | ||
694 | struct inode* pipe_new(struct inode* inode) | ||
695 | { | ||
696 | struct pipe_inode_info *info; | ||
697 | |||
698 | info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); | ||
699 | if (!info) | ||
700 | goto fail_page; | ||
701 | inode->i_pipe = info; | ||
702 | |||
703 | init_waitqueue_head(PIPE_WAIT(*inode)); | ||
704 | PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1; | ||
705 | |||
706 | return inode; | ||
707 | fail_page: | ||
708 | return NULL; | ||
709 | } | ||
710 | |||
711 | static struct vfsmount *pipe_mnt __read_mostly; | 710 | static struct vfsmount *pipe_mnt __read_mostly; |
712 | static int pipefs_delete_dentry(struct dentry *dentry) | 711 | static int pipefs_delete_dentry(struct dentry *dentry) |
713 | { | 712 | { |
@@ -724,8 +723,10 @@ static struct inode * get_pipe_inode(void) | |||
724 | if (!inode) | 723 | if (!inode) |
725 | goto fail_inode; | 724 | goto fail_inode; |
726 | 725 | ||
727 | if(!pipe_new(inode)) | 726 | inode->i_pipe = alloc_pipe_info(inode); |
727 | if (!inode->i_pipe) | ||
728 | goto fail_iput; | 728 | goto fail_iput; |
729 | |||
729 | PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; | 730 | PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; |
730 | inode->i_fop = &rdwr_pipe_fops; | 731 | inode->i_fop = &rdwr_pipe_fops; |
731 | 732 | ||
diff --git a/fs/splice.c b/fs/splice.c index 9bfd6af0cf45..ed91a62402e0 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -136,34 +136,33 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = { | |||
136 | * Pipe output worker. This sets up our pipe format with the page cache | 136 | * Pipe output worker. This sets up our pipe format with the page cache |
137 | * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). | 137 | * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). |
138 | */ | 138 | */ |
139 | static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | 139 | static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, |
140 | int nr_pages, unsigned long offset, | 140 | int nr_pages, unsigned long offset, |
141 | unsigned long len, unsigned int flags) | 141 | unsigned long len, unsigned int flags) |
142 | { | 142 | { |
143 | struct pipe_inode_info *info; | ||
144 | int ret, do_wakeup, i; | 143 | int ret, do_wakeup, i; |
145 | 144 | ||
146 | ret = 0; | 145 | ret = 0; |
147 | do_wakeup = 0; | 146 | do_wakeup = 0; |
148 | i = 0; | 147 | i = 0; |
149 | 148 | ||
150 | mutex_lock(PIPE_MUTEX(*inode)); | 149 | if (pipe->inode) |
150 | mutex_lock(&pipe->inode->i_mutex); | ||
151 | 151 | ||
152 | info = inode->i_pipe; | ||
153 | for (;;) { | 152 | for (;;) { |
154 | int bufs; | 153 | int bufs; |
155 | 154 | ||
156 | if (!PIPE_READERS(*inode)) { | 155 | if (!pipe->readers) { |
157 | send_sig(SIGPIPE, current, 0); | 156 | send_sig(SIGPIPE, current, 0); |
158 | if (!ret) | 157 | if (!ret) |
159 | ret = -EPIPE; | 158 | ret = -EPIPE; |
160 | break; | 159 | break; |
161 | } | 160 | } |
162 | 161 | ||
163 | bufs = info->nrbufs; | 162 | bufs = pipe->nrbufs; |
164 | if (bufs < PIPE_BUFFERS) { | 163 | if (bufs < PIPE_BUFFERS) { |
165 | int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS - 1); | 164 | int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS - 1); |
166 | struct pipe_buffer *buf = info->bufs + newbuf; | 165 | struct pipe_buffer *buf = pipe->bufs + newbuf; |
167 | struct page *page = pages[i++]; | 166 | struct page *page = pages[i++]; |
168 | unsigned long this_len; | 167 | unsigned long this_len; |
169 | 168 | ||
@@ -175,7 +174,7 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | |||
175 | buf->offset = offset; | 174 | buf->offset = offset; |
176 | buf->len = this_len; | 175 | buf->len = this_len; |
177 | buf->ops = &page_cache_pipe_buf_ops; | 176 | buf->ops = &page_cache_pipe_buf_ops; |
178 | info->nrbufs = ++bufs; | 177 | pipe->nrbufs = ++bufs; |
179 | do_wakeup = 1; | 178 | do_wakeup = 1; |
180 | 179 | ||
181 | ret += this_len; | 180 | ret += this_len; |
@@ -205,25 +204,25 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | |||
205 | 204 | ||
206 | if (do_wakeup) { | 205 | if (do_wakeup) { |
207 | smp_mb(); | 206 | smp_mb(); |
208 | if (waitqueue_active(PIPE_WAIT(*inode))) | 207 | if (waitqueue_active(&pipe->wait)) |
209 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); | 208 | wake_up_interruptible_sync(&pipe->wait); |
210 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, | 209 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
211 | POLL_IN); | ||
212 | do_wakeup = 0; | 210 | do_wakeup = 0; |
213 | } | 211 | } |
214 | 212 | ||
215 | PIPE_WAITING_WRITERS(*inode)++; | 213 | pipe->waiting_writers++; |
216 | pipe_wait(inode); | 214 | pipe_wait(pipe); |
217 | PIPE_WAITING_WRITERS(*inode)--; | 215 | pipe->waiting_writers--; |
218 | } | 216 | } |
219 | 217 | ||
220 | mutex_unlock(PIPE_MUTEX(*inode)); | 218 | if (pipe->inode) |
219 | mutex_unlock(&pipe->inode->i_mutex); | ||
221 | 220 | ||
222 | if (do_wakeup) { | 221 | if (do_wakeup) { |
223 | smp_mb(); | 222 | smp_mb(); |
224 | if (waitqueue_active(PIPE_WAIT(*inode))) | 223 | if (waitqueue_active(&pipe->wait)) |
225 | wake_up_interruptible(PIPE_WAIT(*inode)); | 224 | wake_up_interruptible(&pipe->wait); |
226 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); | 225 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
227 | } | 226 | } |
228 | 227 | ||
229 | while (i < nr_pages) | 228 | while (i < nr_pages) |
@@ -232,8 +231,9 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | |||
232 | return ret; | 231 | return ret; |
233 | } | 232 | } |
234 | 233 | ||
235 | static int __generic_file_splice_read(struct file *in, struct inode *pipe, | 234 | static int |
236 | size_t len, unsigned int flags) | 235 | __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, |
236 | size_t len, unsigned int flags) | ||
237 | { | 237 | { |
238 | struct address_space *mapping = in->f_mapping; | 238 | struct address_space *mapping = in->f_mapping; |
239 | unsigned int offset, nr_pages; | 239 | unsigned int offset, nr_pages; |
@@ -298,7 +298,7 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, | |||
298 | * Will read pages from given file and fill them into a pipe. | 298 | * Will read pages from given file and fill them into a pipe. |
299 | * | 299 | * |
300 | */ | 300 | */ |
301 | ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, | 301 | ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, |
302 | size_t len, unsigned int flags) | 302 | size_t len, unsigned int flags) |
303 | { | 303 | { |
304 | ssize_t spliced; | 304 | ssize_t spliced; |
@@ -306,6 +306,7 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, | |||
306 | 306 | ||
307 | ret = 0; | 307 | ret = 0; |
308 | spliced = 0; | 308 | spliced = 0; |
309 | |||
309 | while (len) { | 310 | while (len) { |
310 | ret = __generic_file_splice_read(in, pipe, len, flags); | 311 | ret = __generic_file_splice_read(in, pipe, len, flags); |
311 | 312 | ||
@@ -509,11 +510,10 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, | |||
509 | * key here is the 'actor' worker passed in that actually moves the data | 510 | * key here is the 'actor' worker passed in that actually moves the data |
510 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. | 511 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. |
511 | */ | 512 | */ |
512 | static ssize_t move_from_pipe(struct inode *inode, struct file *out, | 513 | static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, |
513 | size_t len, unsigned int flags, | 514 | size_t len, unsigned int flags, |
514 | splice_actor *actor) | 515 | splice_actor *actor) |
515 | { | 516 | { |
516 | struct pipe_inode_info *info; | ||
517 | int ret, do_wakeup, err; | 517 | int ret, do_wakeup, err; |
518 | struct splice_desc sd; | 518 | struct splice_desc sd; |
519 | 519 | ||
@@ -525,22 +525,22 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
525 | sd.file = out; | 525 | sd.file = out; |
526 | sd.pos = out->f_pos; | 526 | sd.pos = out->f_pos; |
527 | 527 | ||
528 | mutex_lock(PIPE_MUTEX(*inode)); | 528 | if (pipe->inode) |
529 | mutex_lock(&pipe->inode->i_mutex); | ||
529 | 530 | ||
530 | info = inode->i_pipe; | ||
531 | for (;;) { | 531 | for (;;) { |
532 | int bufs = info->nrbufs; | 532 | int bufs = pipe->nrbufs; |
533 | 533 | ||
534 | if (bufs) { | 534 | if (bufs) { |
535 | int curbuf = info->curbuf; | 535 | int curbuf = pipe->curbuf; |
536 | struct pipe_buffer *buf = info->bufs + curbuf; | 536 | struct pipe_buffer *buf = pipe->bufs + curbuf; |
537 | struct pipe_buf_operations *ops = buf->ops; | 537 | struct pipe_buf_operations *ops = buf->ops; |
538 | 538 | ||
539 | sd.len = buf->len; | 539 | sd.len = buf->len; |
540 | if (sd.len > sd.total_len) | 540 | if (sd.len > sd.total_len) |
541 | sd.len = sd.total_len; | 541 | sd.len = sd.total_len; |
542 | 542 | ||
543 | err = actor(info, buf, &sd); | 543 | err = actor(pipe, buf, &sd); |
544 | if (err) { | 544 | if (err) { |
545 | if (!ret && err != -ENODATA) | 545 | if (!ret && err != -ENODATA) |
546 | ret = err; | 546 | ret = err; |
@@ -553,10 +553,10 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
553 | buf->len -= sd.len; | 553 | buf->len -= sd.len; |
554 | if (!buf->len) { | 554 | if (!buf->len) { |
555 | buf->ops = NULL; | 555 | buf->ops = NULL; |
556 | ops->release(info, buf); | 556 | ops->release(pipe, buf); |
557 | curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1); | 557 | curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1); |
558 | info->curbuf = curbuf; | 558 | pipe->curbuf = curbuf; |
559 | info->nrbufs = --bufs; | 559 | pipe->nrbufs = --bufs; |
560 | do_wakeup = 1; | 560 | do_wakeup = 1; |
561 | } | 561 | } |
562 | 562 | ||
@@ -568,9 +568,9 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
568 | 568 | ||
569 | if (bufs) | 569 | if (bufs) |
570 | continue; | 570 | continue; |
571 | if (!PIPE_WRITERS(*inode)) | 571 | if (!pipe->writers) |
572 | break; | 572 | break; |
573 | if (!PIPE_WAITING_WRITERS(*inode)) { | 573 | if (!pipe->waiting_writers) { |
574 | if (ret) | 574 | if (ret) |
575 | break; | 575 | break; |
576 | } | 576 | } |
@@ -589,22 +589,23 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
589 | 589 | ||
590 | if (do_wakeup) { | 590 | if (do_wakeup) { |
591 | smp_mb(); | 591 | smp_mb(); |
592 | if (waitqueue_active(PIPE_WAIT(*inode))) | 592 | if (waitqueue_active(&pipe->wait)) |
593 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); | 593 | wake_up_interruptible_sync(&pipe->wait); |
594 | kill_fasync(PIPE_FASYNC_WRITERS(*inode),SIGIO,POLL_OUT); | 594 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
595 | do_wakeup = 0; | 595 | do_wakeup = 0; |
596 | } | 596 | } |
597 | 597 | ||
598 | pipe_wait(inode); | 598 | pipe_wait(pipe); |
599 | } | 599 | } |
600 | 600 | ||
601 | mutex_unlock(PIPE_MUTEX(*inode)); | 601 | if (pipe->inode) |
602 | mutex_unlock(&pipe->inode->i_mutex); | ||
602 | 603 | ||
603 | if (do_wakeup) { | 604 | if (do_wakeup) { |
604 | smp_mb(); | 605 | smp_mb(); |
605 | if (waitqueue_active(PIPE_WAIT(*inode))) | 606 | if (waitqueue_active(&pipe->wait)) |
606 | wake_up_interruptible(PIPE_WAIT(*inode)); | 607 | wake_up_interruptible(&pipe->wait); |
607 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); | 608 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
608 | } | 609 | } |
609 | 610 | ||
610 | mutex_lock(&out->f_mapping->host->i_mutex); | 611 | mutex_lock(&out->f_mapping->host->i_mutex); |
@@ -616,7 +617,7 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
616 | 617 | ||
617 | /** | 618 | /** |
618 | * generic_file_splice_write - splice data from a pipe to a file | 619 | * generic_file_splice_write - splice data from a pipe to a file |
619 | * @inode: pipe inode | 620 | * @pipe: pipe info |
620 | * @out: file to write to | 621 | * @out: file to write to |
621 | * @len: number of bytes to splice | 622 | * @len: number of bytes to splice |
622 | * @flags: splice modifier flags | 623 | * @flags: splice modifier flags |
@@ -625,11 +626,14 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
625 | * the given pipe inode to the given file. | 626 | * the given pipe inode to the given file. |
626 | * | 627 | * |
627 | */ | 628 | */ |
628 | ssize_t generic_file_splice_write(struct inode *inode, struct file *out, | 629 | ssize_t |
629 | size_t len, unsigned int flags) | 630 | generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, |
631 | size_t len, unsigned int flags) | ||
630 | { | 632 | { |
631 | struct address_space *mapping = out->f_mapping; | 633 | struct address_space *mapping = out->f_mapping; |
632 | ssize_t ret = move_from_pipe(inode, out, len, flags, pipe_to_file); | 634 | ssize_t ret; |
635 | |||
636 | ret = move_from_pipe(pipe, out, len, flags, pipe_to_file); | ||
633 | 637 | ||
634 | /* | 638 | /* |
635 | * if file or inode is SYNC and we actually wrote some data, sync it | 639 | * if file or inode is SYNC and we actually wrote some data, sync it |
@@ -664,10 +668,10 @@ EXPORT_SYMBOL(generic_file_splice_write); | |||
664 | * is involved. | 668 | * is involved. |
665 | * | 669 | * |
666 | */ | 670 | */ |
667 | ssize_t generic_splice_sendpage(struct inode *inode, struct file *out, | 671 | ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, |
668 | size_t len, unsigned int flags) | 672 | size_t len, unsigned int flags) |
669 | { | 673 | { |
670 | return move_from_pipe(inode, out, len, flags, pipe_to_sendpage); | 674 | return move_from_pipe(pipe, out, len, flags, pipe_to_sendpage); |
671 | } | 675 | } |
672 | 676 | ||
673 | EXPORT_SYMBOL(generic_splice_sendpage); | 677 | EXPORT_SYMBOL(generic_splice_sendpage); |
@@ -675,8 +679,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); | |||
675 | /* | 679 | /* |
676 | * Attempt to initiate a splice from pipe to file. | 680 | * Attempt to initiate a splice from pipe to file. |
677 | */ | 681 | */ |
678 | static long do_splice_from(struct inode *pipe, struct file *out, size_t len, | 682 | static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, |
679 | unsigned int flags) | 683 | size_t len, unsigned int flags) |
680 | { | 684 | { |
681 | loff_t pos; | 685 | loff_t pos; |
682 | int ret; | 686 | int ret; |
@@ -698,8 +702,8 @@ static long do_splice_from(struct inode *pipe, struct file *out, size_t len, | |||
698 | /* | 702 | /* |
699 | * Attempt to initiate a splice from a file to a pipe. | 703 | * Attempt to initiate a splice from a file to a pipe. |
700 | */ | 704 | */ |
701 | static long do_splice_to(struct file *in, struct inode *pipe, size_t len, | 705 | static long do_splice_to(struct file *in, struct pipe_inode_info *pipe, |
702 | unsigned int flags) | 706 | size_t len, unsigned int flags) |
703 | { | 707 | { |
704 | loff_t pos, isize, left; | 708 | loff_t pos, isize, left; |
705 | int ret; | 709 | int ret; |
@@ -732,14 +736,14 @@ static long do_splice_to(struct file *in, struct inode *pipe, size_t len, | |||
732 | static long do_splice(struct file *in, struct file *out, size_t len, | 736 | static long do_splice(struct file *in, struct file *out, size_t len, |
733 | unsigned int flags) | 737 | unsigned int flags) |
734 | { | 738 | { |
735 | struct inode *pipe; | 739 | struct pipe_inode_info *pipe; |
736 | 740 | ||
737 | pipe = in->f_dentry->d_inode; | 741 | pipe = in->f_dentry->d_inode->i_pipe; |
738 | if (pipe->i_pipe) | 742 | if (pipe) |
739 | return do_splice_from(pipe, out, len, flags); | 743 | return do_splice_from(pipe, out, len, flags); |
740 | 744 | ||
741 | pipe = out->f_dentry->d_inode; | 745 | pipe = out->f_dentry->d_inode->i_pipe; |
742 | if (pipe->i_pipe) | 746 | if (pipe) |
743 | return do_splice_to(in, pipe, len, flags); | 747 | return do_splice_to(in, pipe, len, flags); |
744 | 748 | ||
745 | return -EINVAL; | 749 | return -EINVAL; |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index ae4c4754ed31..269721af02f3 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -252,7 +252,7 @@ xfs_file_sendfile_invis( | |||
252 | STATIC ssize_t | 252 | STATIC ssize_t |
253 | xfs_file_splice_read( | 253 | xfs_file_splice_read( |
254 | struct file *infilp, | 254 | struct file *infilp, |
255 | struct inode *pipe, | 255 | struct pipe_inode_info *pipe, |
256 | size_t len, | 256 | size_t len, |
257 | unsigned int flags) | 257 | unsigned int flags) |
258 | { | 258 | { |
@@ -266,7 +266,7 @@ xfs_file_splice_read( | |||
266 | STATIC ssize_t | 266 | STATIC ssize_t |
267 | xfs_file_splice_read_invis( | 267 | xfs_file_splice_read_invis( |
268 | struct file *infilp, | 268 | struct file *infilp, |
269 | struct inode *pipe, | 269 | struct pipe_inode_info *pipe, |
270 | size_t len, | 270 | size_t len, |
271 | unsigned int flags) | 271 | unsigned int flags) |
272 | { | 272 | { |
@@ -279,7 +279,7 @@ xfs_file_splice_read_invis( | |||
279 | 279 | ||
280 | STATIC ssize_t | 280 | STATIC ssize_t |
281 | xfs_file_splice_write( | 281 | xfs_file_splice_write( |
282 | struct inode *pipe, | 282 | struct pipe_inode_info *pipe, |
283 | struct file *outfilp, | 283 | struct file *outfilp, |
284 | size_t len, | 284 | size_t len, |
285 | unsigned int flags) | 285 | unsigned int flags) |
@@ -293,7 +293,7 @@ xfs_file_splice_write( | |||
293 | 293 | ||
294 | STATIC ssize_t | 294 | STATIC ssize_t |
295 | xfs_file_splice_write_invis( | 295 | xfs_file_splice_write_invis( |
296 | struct inode *pipe, | 296 | struct pipe_inode_info *pipe, |
297 | struct file *outfilp, | 297 | struct file *outfilp, |
298 | size_t len, | 298 | size_t len, |
299 | unsigned int flags) | 299 | unsigned int flags) |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 90cd314acbaa..74a52937f208 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -338,7 +338,7 @@ ssize_t | |||
338 | xfs_splice_read( | 338 | xfs_splice_read( |
339 | bhv_desc_t *bdp, | 339 | bhv_desc_t *bdp, |
340 | struct file *infilp, | 340 | struct file *infilp, |
341 | struct inode *pipe, | 341 | struct pipe_inode_info *pipe, |
342 | size_t count, | 342 | size_t count, |
343 | int flags, | 343 | int flags, |
344 | int ioflags, | 344 | int ioflags, |
@@ -380,7 +380,7 @@ xfs_splice_read( | |||
380 | ssize_t | 380 | ssize_t |
381 | xfs_splice_write( | 381 | xfs_splice_write( |
382 | bhv_desc_t *bdp, | 382 | bhv_desc_t *bdp, |
383 | struct inode *pipe, | 383 | struct pipe_inode_info *pipe, |
384 | struct file *outfilp, | 384 | struct file *outfilp, |
385 | size_t count, | 385 | size_t count, |
386 | int flags, | 386 | int flags, |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index eaa5659713fb..55c689a86ad2 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h | |||
@@ -94,9 +94,9 @@ extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, | |||
94 | loff_t *, int, size_t, read_actor_t, | 94 | loff_t *, int, size_t, read_actor_t, |
95 | void *, struct cred *); | 95 | void *, struct cred *); |
96 | extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, | 96 | extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, |
97 | struct inode *, size_t, int, int, | 97 | struct pipe_inode_info *, size_t, int, int, |
98 | struct cred *); | 98 | struct cred *); |
99 | extern ssize_t xfs_splice_write(struct bhv_desc *, struct inode *, | 99 | extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *, |
100 | struct file *, size_t, int, int, | 100 | struct file *, size_t, int, int, |
101 | struct cred *); | 101 | struct cred *); |
102 | 102 | ||
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 6f1c79a28f8b..88b09f186289 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -174,9 +174,9 @@ typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, | |||
174 | loff_t *, int, size_t, read_actor_t, | 174 | loff_t *, int, size_t, read_actor_t, |
175 | void *, struct cred *); | 175 | void *, struct cred *); |
176 | typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, | 176 | typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, |
177 | struct inode *, size_t, int, int, | 177 | struct pipe_inode_info *, size_t, int, int, |
178 | struct cred *); | 178 | struct cred *); |
179 | typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct inode *, | 179 | typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *, |
180 | struct file *, size_t, int, int, | 180 | struct file *, size_t, int, int, |
181 | struct cred *); | 181 | struct cred *); |
182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, | 182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 1e9ebaba07b7..7e6454454fbd 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1039,8 +1039,8 @@ struct file_operations { | |||
1039 | int (*check_flags)(int); | 1039 | int (*check_flags)(int); |
1040 | int (*dir_notify)(struct file *filp, unsigned long arg); | 1040 | int (*dir_notify)(struct file *filp, unsigned long arg); |
1041 | int (*flock) (struct file *, int, struct file_lock *); | 1041 | int (*flock) (struct file *, int, struct file_lock *); |
1042 | ssize_t (*splice_write)(struct inode *, struct file *, size_t, unsigned int); | 1042 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); |
1043 | ssize_t (*splice_read)(struct file *, struct inode *, size_t, unsigned int); | 1043 | ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); |
1044 | }; | 1044 | }; |
1045 | 1045 | ||
1046 | struct inode_operations { | 1046 | struct inode_operations { |
@@ -1611,8 +1611,8 @@ extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor | |||
1611 | extern void do_generic_mapping_read(struct address_space *mapping, | 1611 | extern void do_generic_mapping_read(struct address_space *mapping, |
1612 | struct file_ra_state *, struct file *, | 1612 | struct file_ra_state *, struct file *, |
1613 | loff_t *, read_descriptor_t *, read_actor_t); | 1613 | loff_t *, read_descriptor_t *, read_actor_t); |
1614 | extern ssize_t generic_file_splice_read(struct file *, struct inode *, size_t, unsigned int); | 1614 | extern ssize_t generic_file_splice_read(struct file *, struct pipe_inode_info *, size_t, unsigned int); |
1615 | extern ssize_t generic_file_splice_write(struct inode *, struct file *, size_t, unsigned int); | 1615 | extern ssize_t generic_file_splice_write(struct pipe_inode_info *, struct file *, size_t, unsigned int); |
1616 | extern void | 1616 | extern void |
1617 | file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); | 1617 | file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); |
1618 | extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, | 1618 | extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index ec384958d509..9cf99cb34c15 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -36,6 +36,7 @@ struct pipe_inode_info { | |||
36 | unsigned int w_counter; | 36 | unsigned int w_counter; |
37 | struct fasync_struct *fasync_readers; | 37 | struct fasync_struct *fasync_readers; |
38 | struct fasync_struct *fasync_writers; | 38 | struct fasync_struct *fasync_writers; |
39 | struct inode *inode; | ||
39 | }; | 40 | }; |
40 | 41 | ||
41 | /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual | 42 | /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual |
@@ -53,10 +54,10 @@ struct pipe_inode_info { | |||
53 | #define PIPE_FASYNC_WRITERS(inode) (&((inode).i_pipe->fasync_writers)) | 54 | #define PIPE_FASYNC_WRITERS(inode) (&((inode).i_pipe->fasync_writers)) |
54 | 55 | ||
55 | /* Drop the inode semaphore and wait for a pipe event, atomically */ | 56 | /* Drop the inode semaphore and wait for a pipe event, atomically */ |
56 | void pipe_wait(struct inode * inode); | 57 | void pipe_wait(struct pipe_inode_info *pipe); |
57 | 58 | ||
58 | struct inode* pipe_new(struct inode* inode); | 59 | struct pipe_inode_info * alloc_pipe_info(struct inode * inode); |
59 | void free_pipe_info(struct inode* inode); | 60 | void free_pipe_info(struct inode * inode); |
60 | 61 | ||
61 | /* | 62 | /* |
62 | * splice is tied to pipes as a transport (at least for now), so we'll just | 63 | * splice is tied to pipes as a transport (at least for now), so we'll just |