diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-15 12:03:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-15 12:03:47 -0400 |
commit | 23da64b4714812b66ecf010e7dfb3ed1bf2eda69 (patch) | |
tree | e2736bebc916cb540b0da83296d62b342612ecbd /fs/pipe.c | |
parent | a23c218bd36e11120daf18e00a91d5dc20e288e6 (diff) | |
parent | a36e71f996e25d6213f57951f7ae1874086ec57e (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: (28 commits)
cfq-iosched: add close cooperator code
cfq-iosched: log responsible 'cfqq' in idle timer arm
cfq-iosched: tweak kick logic a bit more
cfq-iosched: no need to save interrupts in cfq_kick_queue()
brd: fix cacheflushing
brd: support barriers
swap: Remove code handling bio_alloc failure with __GFP_WAIT
gfs2: Remove code handling bio_alloc failure with __GFP_WAIT
ext4: Remove code handling bio_alloc failure with __GFP_WAIT
dio: Remove code handling bio_alloc failure with __GFP_WAIT
block: Remove code handling bio_alloc failure with __GFP_WAIT
bio: add documentation to bio_alloc()
splice: add helpers for locking pipe inode
splice: remove generic_file_splice_write_nolock()
ocfs2: fix i_mutex locking in ocfs2_splice_to_file()
splice: fix i_mutex locking in generic_splice_write()
splice: remove i_mutex locking in splice_from_pipe()
splice: split up __splice_from_pipe()
block: fix SG_IO to return a proper error value
cfq-iosched: don't delay queue kick for a merged request
...
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 42 |
1 files changed, 38 insertions, 4 deletions
@@ -37,6 +37,42 @@ | |||
37 | * -- Manfred Spraul <manfred@colorfullife.com> 2002-05-09 | 37 | * -- Manfred Spraul <manfred@colorfullife.com> 2002-05-09 |
38 | */ | 38 | */ |
39 | 39 | ||
40 | static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass) | ||
41 | { | ||
42 | if (pipe->inode) | ||
43 | mutex_lock_nested(&pipe->inode->i_mutex, subclass); | ||
44 | } | ||
45 | |||
46 | void pipe_lock(struct pipe_inode_info *pipe) | ||
47 | { | ||
48 | /* | ||
49 | * pipe_lock() nests non-pipe inode locks (for writing to a file) | ||
50 | */ | ||
51 | pipe_lock_nested(pipe, I_MUTEX_PARENT); | ||
52 | } | ||
53 | EXPORT_SYMBOL(pipe_lock); | ||
54 | |||
55 | void pipe_unlock(struct pipe_inode_info *pipe) | ||
56 | { | ||
57 | if (pipe->inode) | ||
58 | mutex_unlock(&pipe->inode->i_mutex); | ||
59 | } | ||
60 | EXPORT_SYMBOL(pipe_unlock); | ||
61 | |||
62 | void pipe_double_lock(struct pipe_inode_info *pipe1, | ||
63 | struct pipe_inode_info *pipe2) | ||
64 | { | ||
65 | BUG_ON(pipe1 == pipe2); | ||
66 | |||
67 | if (pipe1 < pipe2) { | ||
68 | pipe_lock_nested(pipe1, I_MUTEX_PARENT); | ||
69 | pipe_lock_nested(pipe2, I_MUTEX_CHILD); | ||
70 | } else { | ||
71 | pipe_lock_nested(pipe2, I_MUTEX_CHILD); | ||
72 | pipe_lock_nested(pipe1, I_MUTEX_PARENT); | ||
73 | } | ||
74 | } | ||
75 | |||
40 | /* Drop the inode semaphore and wait for a pipe event, atomically */ | 76 | /* Drop the inode semaphore and wait for a pipe event, atomically */ |
41 | void pipe_wait(struct pipe_inode_info *pipe) | 77 | void pipe_wait(struct pipe_inode_info *pipe) |
42 | { | 78 | { |
@@ -47,12 +83,10 @@ void pipe_wait(struct pipe_inode_info *pipe) | |||
47 | * is considered a noninteractive wait: | 83 | * is considered a noninteractive wait: |
48 | */ | 84 | */ |
49 | prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE); | 85 | prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE); |
50 | if (pipe->inode) | 86 | pipe_unlock(pipe); |
51 | mutex_unlock(&pipe->inode->i_mutex); | ||
52 | schedule(); | 87 | schedule(); |
53 | finish_wait(&pipe->wait, &wait); | 88 | finish_wait(&pipe->wait, &wait); |
54 | if (pipe->inode) | 89 | pipe_lock(pipe); |
55 | mutex_lock(&pipe->inode->i_mutex); | ||
56 | } | 90 | } |
57 | 91 | ||
58 | static int | 92 | static int |