diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-03-21 02:21:19 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-04-09 14:12:59 -0400 |
commit | ba5bb147330a8737b6b5a812cc774c79c070704b (patch) | |
tree | 3043bd880634f47275a2083c53ed98ce2c1c70bc /include/linux/pipe_fs_i.h | |
parent | 18c03cfd403b88852f75f200206983ee6df28423 (diff) |
pipe: take allocation and freeing of pipe_inode_info out of ->i_mutex
* new field - pipe->files; number of struct file over that pipe (all
sharing the same inode, of course); protected by inode->i_lock.
* pipe_release() decrements pipe->files, clears inode->i_pipe when
if the counter has reached 0 (all under ->i_lock) and, in that case,
frees pipe after having done pipe_unlock()
* fifo_open() starts with grabbing ->i_lock, and either bumps pipe->files
if ->i_pipe was non-NULL or allocates a new pipe (dropping and regaining
->i_lock) and rechecks ->i_pipe; if it's still NULL, inserts new pipe
there, otherwise bumps ->i_pipe->files and frees the one we'd allocated.
At that point we know that ->i_pipe is non-NULL and won't go away, so
we can do pipe_lock() on it and proceed as we used to. If we end up
failing, decrement pipe->files and if it reaches 0 clear ->i_pipe and
free the sucker after pipe_unlock().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux/pipe_fs_i.h')
-rw-r--r-- | include/linux/pipe_fs_i.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index ad1a427b5267..59778e1c9c08 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -34,6 +34,7 @@ struct pipe_buffer { * @tmp_page: cached released page * @readers: number of current readers of this pipe * @writers: number of current writers of this pipe + * @files: number of struct file refering this pipe (protected by ->i_lock) * @waiting_writers: number of writers blocked waiting for room * @r_counter: reader counter * @w_counter: writer counter @@ -47,6 +48,7 @@ struct pipe_inode_info { unsigned int nrbufs, curbuf, buffers; unsigned int readers; unsigned int writers; + unsigned int files; unsigned int waiting_writers; unsigned int r_counter; unsigned int w_counter; |