Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 40100
b: refs/heads/master
c: 6da6180
h: refs/heads/master
v: v3
  • Loading branch information
Mark Fasheh authored and Jens Axboe committed Oct 19, 2006
1 parent 7b970d7 commit 252f5ad
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 62752ee198dca9209b7dee504763e51b11e9e0ca
refs/heads/master: 6da61809822c22634a3de2dcb3c60283b836a88a
80 changes: 66 additions & 14 deletions trunk/fs/splice.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,13 +707,12 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
* key here is the 'actor' worker passed in that actually moves the data
* to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
*/
ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
loff_t *ppos, size_t len, unsigned int flags,
splice_actor *actor)
static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
struct file *out, loff_t *ppos, size_t len,
unsigned int flags, splice_actor *actor)
{
int ret, do_wakeup, err;
struct splice_desc sd;
struct inode *inode = out->f_mapping->host;

ret = 0;
do_wakeup = 0;
Expand All @@ -723,14 +722,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
sd.file = out;
sd.pos = *ppos;

/*
* The actor worker might be calling ->prepare_write and
* ->commit_write. Most of the time, these expect i_mutex to
* be held. Since this may result in an ABBA deadlock with
* pipe->inode, we have to order lock acquiry here.
*/
inode_double_lock(inode, pipe->inode);

for (;;) {
if (pipe->nrbufs) {
struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
Expand Down Expand Up @@ -803,8 +794,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
pipe_wait(pipe);
}

inode_double_unlock(inode, pipe->inode);

if (do_wakeup) {
smp_mb();
if (waitqueue_active(&pipe->wait))
Expand All @@ -815,6 +804,69 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
return ret;
}

ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
loff_t *ppos, size_t len, unsigned int flags,
splice_actor *actor)
{
ssize_t ret;
struct inode *inode = out->f_mapping->host;

/*
* The actor worker might be calling ->prepare_write and
* ->commit_write. Most of the time, these expect i_mutex to
* be held. Since this may result in an ABBA deadlock with
* pipe->inode, we have to order lock acquiry here.
*/
inode_double_lock(inode, pipe->inode);
ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor);
inode_double_unlock(inode, pipe->inode);

return ret;
}

/**
* generic_file_splice_write_nolock - generic_file_splice_write without mutexes
* @pipe: pipe info
* @out: file to write to
* @len: number of bytes to splice
* @flags: splice modifier flags
*
* Will either move or copy pages (determined by @flags options) from
* the given pipe inode to the given file. The caller is responsible
* for acquiring i_mutex on both inodes.
*
*/
ssize_t
generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
loff_t *ppos, size_t len, unsigned int flags)
{
struct address_space *mapping = out->f_mapping;
struct inode *inode = mapping->host;
ssize_t ret;
int err;

ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
if (ret > 0) {
*ppos += ret;

/*
* If file or inode is SYNC and we actually wrote some data,
* sync it.
*/
if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
err = generic_osync_inode(inode, mapping,
OSYNC_METADATA|OSYNC_DATA);

if (err)
ret = err;
}
}

return ret;
}

EXPORT_SYMBOL(generic_file_splice_write_nolock);

/**
* generic_file_splice_write - splice data from a pipe to a file
* @pipe: pipe info
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,8 @@ extern ssize_t generic_file_splice_read(struct file *, loff_t *,
struct pipe_inode_info *, size_t, unsigned int);
extern ssize_t generic_file_splice_write(struct pipe_inode_info *,
struct file *, loff_t *, size_t, unsigned int);
extern ssize_t generic_file_splice_write_nolock(struct pipe_inode_info *,
struct file *, loff_t *, size_t, unsigned int);
extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
struct file *out, loff_t *, size_t len, unsigned int flags);
extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
Expand Down

0 comments on commit 252f5ad

Please sign in to comment.