diff options
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 |