Skip to content

Commit 3a326a2

Browse files
Ingo MolnarJens Axboe
authored andcommitted
[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 <[email protected]> Update XFS for the ->splice_read/->splice_write changes. Signed-off-by: Jens Axboe <[email protected]>
1 parent 0b749ce commit 3a326a2

File tree

9 files changed

+114
-106
lines changed

9 files changed

+114
-106
lines changed

fs/fifo.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
#include <linux/fs.h>
1616
#include <linux/pipe_fs_i.h>
1717

18-
static void wait_for_partner(struct inode* inode, unsigned int* cnt)
18+
static void wait_for_partner(struct inode* inode, unsigned int *cnt)
1919
{
2020
int cur = *cnt;
21-
while(cur == *cnt) {
22-
pipe_wait(inode);
23-
if(signal_pending(current))
21+
22+
while (cur == *cnt) {
23+
pipe_wait(inode->i_pipe);
24+
if (signal_pending(current))
2425
break;
2526
}
2627
}
@@ -37,7 +38,8 @@ static int fifo_open(struct inode *inode, struct file *filp)
3738
mutex_lock(PIPE_MUTEX(*inode));
3839
if (!inode->i_pipe) {
3940
ret = -ENOMEM;
40-
if(!pipe_new(inode))
41+
inode->i_pipe = alloc_pipe_info(inode);
42+
if (!inode->i_pipe)
4143
goto err_nocleanup;
4244
}
4345
filp->f_version = 0;

fs/pipe.c

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,21 @@
3636
*/
3737

3838
/* 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)
4040
{
4141
DEFINE_WAIT(wait);
4242

4343
/*
4444
* Pipes are system-local resources, so sleeping on them
4545
* is considered a noninteractive wait:
4646
*/
47-
prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
48-
mutex_unlock(PIPE_MUTEX(*inode));
47+
prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
48+
if (pipe->inode)
49+
mutex_unlock(&pipe->inode->i_mutex);
4950
schedule();
50-
finish_wait(PIPE_WAIT(*inode), &wait);
51-
mutex_lock(PIPE_MUTEX(*inode));
51+
finish_wait(&pipe->wait, &wait);
52+
if (pipe->inode)
53+
mutex_lock(&pipe->inode->i_mutex);
5254
}
5355

5456
static int
@@ -223,7 +225,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
223225
wake_up_interruptible_sync(PIPE_WAIT(*inode));
224226
kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
225227
}
226-
pipe_wait(inode);
228+
pipe_wait(inode->i_pipe);
227229
}
228230
mutex_unlock(PIPE_MUTEX(*inode));
229231
/* Signal writers asynchronously that there is more room. */
@@ -370,7 +372,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
370372
do_wakeup = 0;
371373
}
372374
PIPE_WAITING_WRITERS(*inode)++;
373-
pipe_wait(inode);
375+
pipe_wait(inode->i_pipe);
374376
PIPE_WAITING_WRITERS(*inode)--;
375377
}
376378
out:
@@ -675,6 +677,20 @@ static struct file_operations rdwr_pipe_fops = {
675677
.fasync = pipe_rdwr_fasync,
676678
};
677679

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+
678694
void free_pipe_info(struct inode *inode)
679695
{
680696
int i;
@@ -691,23 +707,6 @@ void free_pipe_info(struct inode *inode)
691707
kfree(info);
692708
}
693709

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-
711710
static struct vfsmount *pipe_mnt __read_mostly;
712711
static int pipefs_delete_dentry(struct dentry *dentry)
713712
{
@@ -724,8 +723,10 @@ static struct inode * get_pipe_inode(void)
724723
if (!inode)
725724
goto fail_inode;
726725

727-
if(!pipe_new(inode))
726+
inode->i_pipe = alloc_pipe_info(inode);
727+
if (!inode->i_pipe)
728728
goto fail_iput;
729+
729730
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
730731
inode->i_fop = &rdwr_pipe_fops;
731732

0 commit comments

Comments
 (0)