aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/pipe.c61
-rw-r--r--fs/splice.c4
2 files changed, 64 insertions, 1 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 3694af10dd2..d007830d9c8 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -164,6 +164,20 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
page_cache_release(page);
}
+/**
+ * generic_pipe_buf_map - virtually map a pipe buffer
+ * @pipe: the pipe that the buffer belongs to
+ * @buf: the buffer that should be mapped
+ * @atomic: whether to use an atomic map
+ *
+ * Description:
+ * This function returns a kernel virtual address mapping for the
+ * passed in @pipe_buffer. If @atomic is set, an atomic map is provided
+ * and the caller has to be careful not to fault before calling
+ * the unmap function.
+ *
+ * Note that this function occupies KM_USER0 if @atomic != 0.
+ */
void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
struct pipe_buffer *buf, int atomic)
{
@@ -175,6 +189,15 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
return kmap(buf->page);
}
+/**
+ * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer
+ * @pipe: the pipe that the buffer belongs to
+ * @buf: the buffer that should be unmapped
+ * @map_data: the data that the mapping function returned
+ *
+ * Description:
+ * This function undoes the mapping that ->map() provided.
+ */
void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
struct pipe_buffer *buf, void *map_data)
{
@@ -185,11 +208,28 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
kunmap(buf->page);
}
+/**
+ * generic_pipe_buf_steal - attempt to take ownership of a @pipe_buffer
+ * @pipe: the pipe that the buffer belongs to
+ * @buf: the buffer to attempt to steal
+ *
+ * Description:
+ * This function attempts to steal the @struct page attached to
+ * @buf. If successful, this function returns 0 and returns with
+ * the page locked. The caller may then reuse the page for whatever
+ * he wishes, the typical use is insertion into a different file
+ * page cache.
+ */
int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
struct page *page = buf->page;
+ /*
+ * A reference of one is golden, that means that the owner of this
+ * page is the only one holding a reference to it. lock the page
+ * and return OK.
+ */
if (page_count(page) == 1) {
lock_page(page);
return 0;
@@ -198,11 +238,30 @@ int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
return 1;
}
-void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf)
+/**
+ * generic_pipe_buf_get - get a reference to a @struct pipe_buffer
+ * @pipe: the pipe that the buffer belongs to
+ * @buf: the buffer to get a reference to
+ *
+ * Description:
+ * This function grabs an extra reference to @buf. It's used in
+ * in the tee() system call, when we duplicate the buffers in one
+ * pipe into another.
+ */
+void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
{
page_cache_get(buf->page);
}
+/**
+ * generic_pipe_buf_confirm - verify contents of the pipe buffer
+ * @pipe: the pipe that the buffer belongs to
+ * @buf: the buffer to confirm
+ *
+ * Description:
+ * This function does nothing, because the generic pipe code uses
+ * pages that are always good when inserted into the pipe.
+ */
int generic_pipe_buf_confirm(struct pipe_inode_info *info,
struct pipe_buffer *buf)
{
diff --git a/fs/splice.c b/fs/splice.c
index c804121601b..ed2ce995475 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -85,6 +85,10 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
buf->flags &= ~PIPE_BUF_FLAG_LRU;
}
+/*
+ * Check whether the contents of buf is OK to access. Since the content
+ * is a page cache page, IO may be in flight.
+ */
static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{