blob: ef11dffa237e278fd3f46c516f802ea8f81a960e [file] [log] [blame] [edit]
/* SPDX-License-Identifier: GPL-2.0 */
/**
* struct pipe_inode_info - a linux kernel pipe
* @mutex: mutex protecting the whole thing
* @queue: The pipe buffer.
* @rd_wait: reader wait point in case of empty pipe
* @wr_wait: writer wait point in case of full pipe
* @note_loss: The next read() should insert a data-lost message
* @footprint: The amount of space pinned by the pipe (in pages).
* @max_footprint: The maximum amount of space that can be pinned (in pages).
* @content: The amount of content (in bytes).
* @spare_folio: Cached released folio
* @spare_buffer: Cached released buffer
* @readers: number of current readers of this pipe
* @writers: number of current writers of this pipe
* @files: number of struct file referring this pipe (protected by ->i_lock)
* @r_counter: reader counter
* @w_counter: writer counter
* @poll_usage: is this pipe used for epoll, which has crazy wakeups?
* @fasync_readers: reader side fasync
* @fasync_writers: writer side fasync
* @user: the user who created this pipe
* @watch_queue: If this pipe is a watch_queue, this is the stuff for that
**/
struct pipe_inode_info {
struct mutex mutex;
struct list_head queue;
wait_queue_head_t rd_wait, wr_wait;
#ifdef CONFIG_WATCH_QUEUE
bool note_loss;
#endif
size_t footprint;
size_t max_footprint;
size_t content;
unsigned int readers;
unsigned int writers;
unsigned int files;
unsigned int r_counter;
unsigned int w_counter;
bool poll_usage;
struct folio *spare_folio;
struct pipe_buffer *spare_buffer;
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
struct user_struct *user;
#ifdef CONFIG_WATCH_QUEUE
struct watch_queue *watch_queue;
#endif
};
/**
* pipe_empty - Return true if the pipe is empty
* @pipe: The pipe to query
*/
static inline bool pipe_empty(const struct pipe_inode_info *pipe)
{
return list_empty(&pipe->queue);
}
/**
* pipe_full - Return true if the pipe is full
* @pipe: The pipe to query
*/
static inline bool pipe_full(const struct pipe_inode_info *pipe)
{
return pipe->footprint >= pipe->max_footprint;
}
/**
* pipe_occupancy - Return number of pages remaining in a pipe
* @pipe: The pipe to query
*/
static inline size_t pipe_occupancy(const struct pipe_inode_info *pipe)
{
return min_t(ssize_t, pipe->max_footprint - pipe->footprint, 0);
}
/**
* pipe_head_buf - Return the head pipe buffer or NULL
* @pipe: The pipe to access
*/
static inline struct pipe_buffer *pipe_head_buf(struct pipe_inode_info *pipe)
{
return list_first_entry_or_null(&pipe->queue,
struct pipe_buffer, queue_link);
}
/* Wait for a pipe to be readable/writable while dropping the pipe lock */
void pipe_wait_readable(struct pipe_inode_info *);
void pipe_wait_writable(struct pipe_inode_info *);
struct pipe_inode_info *alloc_pipe_info(void);
bool pipe_consume(struct pipe_inode_info *pipe, struct pipe_buffer *buf, size_t consumed);