2005-04-17 00:20:36 +02:00
|
|
|
/*
|
|
|
|
* linux/fs/pipe.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 1991, 1992, 1999 Linus Torvalds
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/mm.h>
|
|
|
|
#include <linux/file.h>
|
|
|
|
#include <linux/poll.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/fs.h>
|
2010-05-20 10:43:18 +02:00
|
|
|
#include <linux/log2.h>
|
2005-04-17 00:20:36 +02:00
|
|
|
#include <linux/mount.h>
|
2012-03-23 23:01:50 +01:00
|
|
|
#include <linux/magic.h>
|
2005-04-17 00:20:36 +02:00
|
|
|
#include <linux/pipe_fs_i.h>
|
|
|
|
#include <linux/uio.h>
|
|
|
|
#include <linux/highmem.h>
|
2006-03-30 15:15:30 +02:00
|
|
|
#include <linux/pagemap.h>
|
2007-02-07 07:48:00 +01:00
|
|
|
#include <linux/audit.h>
|
2008-05-07 05:42:38 +02:00
|
|
|
#include <linux/syscalls.h>
|
2010-05-19 21:03:16 +02:00
|
|
|
#include <linux/fcntl.h>
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
#include <linux/memcontrol.h>
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
|
|
#include <asm/ioctls.h>
|
|
|
|
|
2013-03-12 14:58:10 +01:00
|
|
|
#include "internal.h"
|
|
|
|
|
2010-05-19 21:03:16 +02:00
|
|
|
/*
|
|
|
|
* The max size that a non-root user is allowed to grow the pipe. Can
|
2010-06-03 14:54:39 +02:00
|
|
|
* be set by root in /proc/sys/fs/pipe-max-size
|
2010-05-19 21:03:16 +02:00
|
|
|
*/
|
2010-06-03 14:54:39 +02:00
|
|
|
unsigned int pipe_max_size = 1048576;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Minimum pipe size, as required by POSIX
|
|
|
|
*/
|
|
|
|
unsigned int pipe_min_size = PAGE_SIZE;
|
2010-05-19 21:03:16 +02:00
|
|
|
|
2016-01-18 16:36:09 +01:00
|
|
|
/* Maximum allocatable pages per user. Hard limit is unset by default, soft
|
|
|
|
* matches default values.
|
|
|
|
*/
|
|
|
|
unsigned long pipe_user_pages_hard;
|
|
|
|
unsigned long pipe_user_pages_soft = PIPE_DEF_BUFFERS * INR_OPEN_CUR;
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
/*
|
|
|
|
* We use a start+len construction, which provides full use of the
|
|
|
|
* allocated memory.
|
|
|
|
* -- Florian Coosmann (FGC)
|
|
|
|
*
|
|
|
|
* Reads with count = 0 should always return 0.
|
|
|
|
* -- Julian Bradfield 1999-06-07.
|
|
|
|
*
|
|
|
|
* FIFOs and Pipes now generate SIGIO for both readers and writers.
|
|
|
|
* -- Jeremy Elson <jelson@circlemud.org> 2001-08-16
|
|
|
|
*
|
|
|
|
* pipe_read & write cleanup
|
|
|
|
* -- Manfred Spraul <manfred@colorfullife.com> 2002-05-09
|
|
|
|
*/
|
|
|
|
|
2009-04-14 19:48:41 +02:00
|
|
|
static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass)
|
|
|
|
{
|
2013-03-21 16:01:38 +01:00
|
|
|
if (pipe->files)
|
2013-03-21 07:32:24 +01:00
|
|
|
mutex_lock_nested(&pipe->mutex, subclass);
|
2009-04-14 19:48:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void pipe_lock(struct pipe_inode_info *pipe)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* pipe_lock() nests non-pipe inode locks (for writing to a file)
|
|
|
|
*/
|
|
|
|
pipe_lock_nested(pipe, I_MUTEX_PARENT);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(pipe_lock);
|
|
|
|
|
|
|
|
void pipe_unlock(struct pipe_inode_info *pipe)
|
|
|
|
{
|
2013-03-21 16:01:38 +01:00
|
|
|
if (pipe->files)
|
2013-03-21 07:32:24 +01:00
|
|
|
mutex_unlock(&pipe->mutex);
|
2009-04-14 19:48:41 +02:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(pipe_unlock);
|
|
|
|
|
2013-03-21 17:24:01 +01:00
|
|
|
static inline void __pipe_lock(struct pipe_inode_info *pipe)
|
|
|
|
{
|
|
|
|
mutex_lock_nested(&pipe->mutex, I_MUTEX_PARENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void __pipe_unlock(struct pipe_inode_info *pipe)
|
|
|
|
{
|
|
|
|
mutex_unlock(&pipe->mutex);
|
|
|
|
}
|
|
|
|
|
2009-04-14 19:48:41 +02:00
|
|
|
void pipe_double_lock(struct pipe_inode_info *pipe1,
|
|
|
|
struct pipe_inode_info *pipe2)
|
|
|
|
{
|
|
|
|
BUG_ON(pipe1 == pipe2);
|
|
|
|
|
|
|
|
if (pipe1 < pipe2) {
|
|
|
|
pipe_lock_nested(pipe1, I_MUTEX_PARENT);
|
|
|
|
pipe_lock_nested(pipe2, I_MUTEX_CHILD);
|
|
|
|
} else {
|
2009-07-21 10:09:23 +02:00
|
|
|
pipe_lock_nested(pipe2, I_MUTEX_PARENT);
|
|
|
|
pipe_lock_nested(pipe1, I_MUTEX_CHILD);
|
2009-04-14 19:48:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
/* Drop the inode semaphore and wait for a pipe event, atomically */
|
2006-04-10 15:18:35 +02:00
|
|
|
void pipe_wait(struct pipe_inode_info *pipe)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
|
|
|
DEFINE_WAIT(wait);
|
|
|
|
|
2005-09-10 09:26:12 +02:00
|
|
|
/*
|
|
|
|
* Pipes are system-local resources, so sleeping on them
|
|
|
|
* is considered a noninteractive wait:
|
|
|
|
*/
|
2007-10-15 17:00:13 +02:00
|
|
|
prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
|
2009-04-14 19:48:41 +02:00
|
|
|
pipe_unlock(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
schedule();
|
2006-04-10 15:18:35 +02:00
|
|
|
finish_wait(&pipe->wait, &wait);
|
2009-04-14 19:48:41 +02:00
|
|
|
pipe_lock(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
|
2006-04-11 13:57:45 +02:00
|
|
|
static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
|
|
|
|
struct pipe_buffer *buf)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
|
|
|
struct page *page = buf->page;
|
|
|
|
|
2006-03-30 15:15:30 +02:00
|
|
|
/*
|
|
|
|
* If nobody else uses this page, and we don't already have a
|
|
|
|
* temporary page, let's keep track of it as a one-deep
|
2006-04-11 13:57:45 +02:00
|
|
|
* allocation cache. (Otherwise just release our reference to it)
|
2006-03-30 15:15:30 +02:00
|
|
|
*/
|
2006-04-11 13:57:45 +02:00
|
|
|
if (page_count(page) == 1 && !pipe->tmp_page)
|
2006-04-11 13:53:33 +02:00
|
|
|
pipe->tmp_page = page;
|
2006-04-11 13:57:45 +02:00
|
|
|
else
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 14:29:47 +02:00
|
|
|
put_page(page);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
static int anon_pipe_buf_steal(struct pipe_inode_info *pipe,
|
|
|
|
struct pipe_buffer *buf)
|
|
|
|
{
|
|
|
|
struct page *page = buf->page;
|
|
|
|
|
|
|
|
if (page_count(page) == 1) {
|
|
|
|
if (memcg_kmem_enabled()) {
|
|
|
|
memcg_kmem_uncharge(page, 0);
|
|
|
|
__ClearPageKmemcg(page);
|
|
|
|
}
|
|
|
|
__SetPageLocked(page);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-06-12 20:51:32 +02:00
|
|
|
/**
|
2008-02-14 00:03:22 +01:00
|
|
|
* generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer
|
2007-06-12 20:51:32 +02:00
|
|
|
* @pipe: the pipe that the buffer belongs to
|
|
|
|
* @buf: the buffer to attempt to steal
|
|
|
|
*
|
|
|
|
* Description:
|
2008-02-14 00:03:22 +01:00
|
|
|
* This function attempts to steal the &struct page attached to
|
2007-06-12 20:51:32 +02:00
|
|
|
* @buf. If successful, this function returns 0 and returns with
|
|
|
|
* the page locked. The caller may then reuse the page for whatever
|
2008-02-14 00:03:22 +01:00
|
|
|
* he wishes; the typical use is insertion into a different file
|
2007-06-12 20:51:32 +02:00
|
|
|
* page cache.
|
|
|
|
*/
|
2006-05-02 15:29:57 +02:00
|
|
|
int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
|
|
|
|
struct pipe_buffer *buf)
|
2006-03-30 15:16:46 +02:00
|
|
|
{
|
2006-04-30 16:36:32 +02:00
|
|
|
struct page *page = buf->page;
|
|
|
|
|
2007-06-12 20:51:32 +02:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2006-04-30 16:36:32 +02:00
|
|
|
if (page_count(page) == 1) {
|
|
|
|
lock_page(page);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2006-03-30 15:16:46 +02:00
|
|
|
}
|
2010-05-26 08:44:22 +02:00
|
|
|
EXPORT_SYMBOL(generic_pipe_buf_steal);
|
2006-03-30 15:16:46 +02:00
|
|
|
|
2007-06-12 20:51:32 +02:00
|
|
|
/**
|
2008-02-14 00:03:22 +01:00
|
|
|
* generic_pipe_buf_get - get a reference to a &struct pipe_buffer
|
2007-06-12 20:51:32 +02:00
|
|
|
* @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)
|
2006-04-11 15:51:17 +02:00
|
|
|
{
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 14:29:47 +02:00
|
|
|
get_page(buf->page);
|
2006-04-11 15:51:17 +02:00
|
|
|
}
|
2010-05-26 08:44:22 +02:00
|
|
|
EXPORT_SYMBOL(generic_pipe_buf_get);
|
2006-04-11 15:51:17 +02:00
|
|
|
|
2007-06-12 20:51:32 +02:00
|
|
|
/**
|
|
|
|
* generic_pipe_buf_confirm - verify contents of the pipe buffer
|
2007-07-27 08:08:51 +02:00
|
|
|
* @info: the pipe that the buffer belongs to
|
2007-06-12 20:51:32 +02:00
|
|
|
* @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.
|
|
|
|
*/
|
2007-06-14 13:10:48 +02:00
|
|
|
int generic_pipe_buf_confirm(struct pipe_inode_info *info,
|
|
|
|
struct pipe_buffer *buf)
|
2006-05-01 19:59:03 +02:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2010-05-26 08:44:22 +02:00
|
|
|
EXPORT_SYMBOL(generic_pipe_buf_confirm);
|
2006-05-01 19:59:03 +02:00
|
|
|
|
2009-05-07 15:37:36 +02:00
|
|
|
/**
|
|
|
|
* generic_pipe_buf_release - put a reference to a &struct pipe_buffer
|
|
|
|
* @pipe: the pipe that the buffer belongs to
|
|
|
|
* @buf: the buffer to put a reference to
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* This function releases a reference to @buf.
|
|
|
|
*/
|
|
|
|
void generic_pipe_buf_release(struct pipe_inode_info *pipe,
|
|
|
|
struct pipe_buffer *buf)
|
|
|
|
{
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 14:29:47 +02:00
|
|
|
put_page(buf->page);
|
2009-05-07 15:37:36 +02:00
|
|
|
}
|
2010-05-26 08:44:22 +02:00
|
|
|
EXPORT_SYMBOL(generic_pipe_buf_release);
|
2009-05-07 15:37:36 +02:00
|
|
|
|
2006-12-13 09:34:04 +01:00
|
|
|
static const struct pipe_buf_operations anon_pipe_buf_ops = {
|
2005-04-17 00:20:36 +02:00
|
|
|
.can_merge = 1,
|
2007-06-14 13:10:48 +02:00
|
|
|
.confirm = generic_pipe_buf_confirm,
|
2005-04-17 00:20:36 +02:00
|
|
|
.release = anon_pipe_buf_release,
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
.steal = anon_pipe_buf_steal,
|
2006-05-01 19:59:03 +02:00
|
|
|
.get = generic_pipe_buf_get,
|
2005-04-17 00:20:36 +02:00
|
|
|
};
|
|
|
|
|
pipes: add a "packetized pipe" mode for writing
The actual internal pipe implementation is already really about
individual packets (called "pipe buffers"), and this simply exposes that
as a special packetized mode.
When we are in the packetized mode (marked by O_DIRECT as suggested by
Alan Cox), a write() on a pipe will not merge the new data with previous
writes, so each write will get a pipe buffer of its own. The pipe
buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
will tell the reader side to break the read at that boundary (and throw
away any partial packet contents that do not fit in the read buffer).
End result: as long as you do writes less than PIPE_BUF in size (so that
the pipe doesn't have to split them up), you can now treat the pipe as a
packet interface, where each read() system call will read one packet at
a time. You can just use a sufficiently big read buffer (PIPE_BUF is
sufficient, since bigger than that doesn't guarantee atomicity anyway),
and the return value of the read() will naturally give you the size of
the packet.
NOTE! We do not support zero-sized packets, and zero-sized reads and
writes to a pipe continue to be no-ops. Also note that big packets will
currently be split at write time, but that the size at which that
happens is not really specified (except that it's bigger than PIPE_BUF).
Currently that limit is the system page size, but we might want to
explicitly support bigger packets some day.
The main user for this is going to be the autofs packet interface,
allowing us to stop having to care so deeply about exact packet sizes
(which have had bugs with 32/64-bit compatibility modes). But user
space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
fail with an EINVAL on kernels that do not support this interface.
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Miller <davem@davemloft.net>
Cc: Ian Kent <raven@themaw.net>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: stable@kernel.org # needed for systemd/autofs interaction fix
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-04-29 22:12:42 +02:00
|
|
|
static const struct pipe_buf_operations packet_pipe_buf_ops = {
|
|
|
|
.can_merge = 0,
|
|
|
|
.confirm = generic_pipe_buf_confirm,
|
|
|
|
.release = anon_pipe_buf_release,
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
.steal = anon_pipe_buf_steal,
|
pipes: add a "packetized pipe" mode for writing
The actual internal pipe implementation is already really about
individual packets (called "pipe buffers"), and this simply exposes that
as a special packetized mode.
When we are in the packetized mode (marked by O_DIRECT as suggested by
Alan Cox), a write() on a pipe will not merge the new data with previous
writes, so each write will get a pipe buffer of its own. The pipe
buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
will tell the reader side to break the read at that boundary (and throw
away any partial packet contents that do not fit in the read buffer).
End result: as long as you do writes less than PIPE_BUF in size (so that
the pipe doesn't have to split them up), you can now treat the pipe as a
packet interface, where each read() system call will read one packet at
a time. You can just use a sufficiently big read buffer (PIPE_BUF is
sufficient, since bigger than that doesn't guarantee atomicity anyway),
and the return value of the read() will naturally give you the size of
the packet.
NOTE! We do not support zero-sized packets, and zero-sized reads and
writes to a pipe continue to be no-ops. Also note that big packets will
currently be split at write time, but that the size at which that
happens is not really specified (except that it's bigger than PIPE_BUF).
Currently that limit is the system page size, but we might want to
explicitly support bigger packets some day.
The main user for this is going to be the autofs packet interface,
allowing us to stop having to care so deeply about exact packet sizes
(which have had bugs with 32/64-bit compatibility modes). But user
space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
fail with an EINVAL on kernels that do not support this interface.
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Miller <davem@davemloft.net>
Cc: Ian Kent <raven@themaw.net>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: stable@kernel.org # needed for systemd/autofs interaction fix
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-04-29 22:12:42 +02:00
|
|
|
.get = generic_pipe_buf_get,
|
|
|
|
};
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
static ssize_t
|
2014-04-03 01:56:54 +02:00
|
|
|
pipe_read(struct kiocb *iocb, struct iov_iter *to)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
2014-04-03 01:56:54 +02:00
|
|
|
size_t total_len = iov_iter_count(to);
|
2006-10-01 08:28:47 +02:00
|
|
|
struct file *filp = iocb->ki_filp;
|
2013-03-21 16:16:56 +01:00
|
|
|
struct pipe_inode_info *pipe = filp->private_data;
|
2005-04-17 00:20:36 +02:00
|
|
|
int do_wakeup;
|
|
|
|
ssize_t ret;
|
|
|
|
|
|
|
|
/* Null read succeeds. */
|
|
|
|
if (unlikely(total_len == 0))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
do_wakeup = 0;
|
|
|
|
ret = 0;
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_lock(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
for (;;) {
|
2006-04-11 13:53:33 +02:00
|
|
|
int bufs = pipe->nrbufs;
|
2005-04-17 00:20:36 +02:00
|
|
|
if (bufs) {
|
2006-04-11 13:53:33 +02:00
|
|
|
int curbuf = pipe->curbuf;
|
|
|
|
struct pipe_buffer *buf = pipe->bufs + curbuf;
|
2006-12-13 09:34:04 +01:00
|
|
|
const struct pipe_buf_operations *ops = buf->ops;
|
2005-04-17 00:20:36 +02:00
|
|
|
size_t chars = buf->len;
|
2014-02-04 01:11:42 +01:00
|
|
|
size_t written;
|
|
|
|
int error;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
if (chars > total_len)
|
|
|
|
chars = total_len;
|
|
|
|
|
2007-06-14 13:10:48 +02:00
|
|
|
error = ops->confirm(pipe, buf);
|
2006-05-01 19:59:03 +02:00
|
|
|
if (error) {
|
2006-03-30 15:15:30 +02:00
|
|
|
if (!ret)
|
2010-10-21 14:56:00 +02:00
|
|
|
ret = error;
|
2006-03-30 15:15:30 +02:00
|
|
|
break;
|
|
|
|
}
|
2006-05-01 19:59:03 +02:00
|
|
|
|
2014-04-03 01:56:54 +02:00
|
|
|
written = copy_page_to_iter(buf->page, buf->offset, chars, to);
|
2014-02-04 01:11:42 +01:00
|
|
|
if (unlikely(written < chars)) {
|
2006-04-11 13:57:45 +02:00
|
|
|
if (!ret)
|
2014-02-04 01:11:42 +01:00
|
|
|
ret = -EFAULT;
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
ret += chars;
|
|
|
|
buf->offset += chars;
|
|
|
|
buf->len -= chars;
|
pipes: add a "packetized pipe" mode for writing
The actual internal pipe implementation is already really about
individual packets (called "pipe buffers"), and this simply exposes that
as a special packetized mode.
When we are in the packetized mode (marked by O_DIRECT as suggested by
Alan Cox), a write() on a pipe will not merge the new data with previous
writes, so each write will get a pipe buffer of its own. The pipe
buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
will tell the reader side to break the read at that boundary (and throw
away any partial packet contents that do not fit in the read buffer).
End result: as long as you do writes less than PIPE_BUF in size (so that
the pipe doesn't have to split them up), you can now treat the pipe as a
packet interface, where each read() system call will read one packet at
a time. You can just use a sufficiently big read buffer (PIPE_BUF is
sufficient, since bigger than that doesn't guarantee atomicity anyway),
and the return value of the read() will naturally give you the size of
the packet.
NOTE! We do not support zero-sized packets, and zero-sized reads and
writes to a pipe continue to be no-ops. Also note that big packets will
currently be split at write time, but that the size at which that
happens is not really specified (except that it's bigger than PIPE_BUF).
Currently that limit is the system page size, but we might want to
explicitly support bigger packets some day.
The main user for this is going to be the autofs packet interface,
allowing us to stop having to care so deeply about exact packet sizes
(which have had bugs with 32/64-bit compatibility modes). But user
space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
fail with an EINVAL on kernels that do not support this interface.
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Miller <davem@davemloft.net>
Cc: Ian Kent <raven@themaw.net>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: stable@kernel.org # needed for systemd/autofs interaction fix
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-04-29 22:12:42 +02:00
|
|
|
|
|
|
|
/* Was it a packet buffer? Clean up and exit */
|
|
|
|
if (buf->flags & PIPE_BUF_FLAG_PACKET) {
|
|
|
|
total_len = chars;
|
|
|
|
buf->len = 0;
|
|
|
|
}
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
if (!buf->len) {
|
|
|
|
buf->ops = NULL;
|
2006-04-11 13:53:33 +02:00
|
|
|
ops->release(pipe, buf);
|
2010-05-20 10:43:18 +02:00
|
|
|
curbuf = (curbuf + 1) & (pipe->buffers - 1);
|
2006-04-11 13:53:33 +02:00
|
|
|
pipe->curbuf = curbuf;
|
|
|
|
pipe->nrbufs = --bufs;
|
2005-04-17 00:20:36 +02:00
|
|
|
do_wakeup = 1;
|
|
|
|
}
|
|
|
|
total_len -= chars;
|
|
|
|
if (!total_len)
|
|
|
|
break; /* common path: read succeeded */
|
|
|
|
}
|
|
|
|
if (bufs) /* More to do? */
|
|
|
|
continue;
|
2006-04-11 13:53:33 +02:00
|
|
|
if (!pipe->writers)
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
2006-04-11 13:53:33 +02:00
|
|
|
if (!pipe->waiting_writers) {
|
2005-04-17 00:20:36 +02:00
|
|
|
/* syscall merging: Usually we must not sleep
|
|
|
|
* if O_NONBLOCK is set, or if we got some data.
|
|
|
|
* But if a writer sleeps in kernel space, then
|
|
|
|
* we can wait for that data without violating POSIX.
|
|
|
|
*/
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
if (filp->f_flags & O_NONBLOCK) {
|
|
|
|
ret = -EAGAIN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (signal_pending(current)) {
|
2006-04-11 13:57:45 +02:00
|
|
|
if (!ret)
|
|
|
|
ret = -ERESTARTSYS;
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (do_wakeup) {
|
2011-01-21 01:21:59 +01:00
|
|
|
wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
|
2006-04-11 13:53:33 +02:00
|
|
|
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
2006-04-11 13:53:33 +02:00
|
|
|
pipe_wait(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
2006-04-11 13:57:45 +02:00
|
|
|
|
|
|
|
/* Signal writers asynchronously that there is more room. */
|
2005-04-17 00:20:36 +02:00
|
|
|
if (do_wakeup) {
|
2011-01-21 01:21:59 +01:00
|
|
|
wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
|
2006-04-11 13:53:33 +02:00
|
|
|
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
if (ret > 0)
|
|
|
|
file_accessed(filp);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
pipes: add a "packetized pipe" mode for writing
The actual internal pipe implementation is already really about
individual packets (called "pipe buffers"), and this simply exposes that
as a special packetized mode.
When we are in the packetized mode (marked by O_DIRECT as suggested by
Alan Cox), a write() on a pipe will not merge the new data with previous
writes, so each write will get a pipe buffer of its own. The pipe
buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
will tell the reader side to break the read at that boundary (and throw
away any partial packet contents that do not fit in the read buffer).
End result: as long as you do writes less than PIPE_BUF in size (so that
the pipe doesn't have to split them up), you can now treat the pipe as a
packet interface, where each read() system call will read one packet at
a time. You can just use a sufficiently big read buffer (PIPE_BUF is
sufficient, since bigger than that doesn't guarantee atomicity anyway),
and the return value of the read() will naturally give you the size of
the packet.
NOTE! We do not support zero-sized packets, and zero-sized reads and
writes to a pipe continue to be no-ops. Also note that big packets will
currently be split at write time, but that the size at which that
happens is not really specified (except that it's bigger than PIPE_BUF).
Currently that limit is the system page size, but we might want to
explicitly support bigger packets some day.
The main user for this is going to be the autofs packet interface,
allowing us to stop having to care so deeply about exact packet sizes
(which have had bugs with 32/64-bit compatibility modes). But user
space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
fail with an EINVAL on kernels that do not support this interface.
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Miller <davem@davemloft.net>
Cc: Ian Kent <raven@themaw.net>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: stable@kernel.org # needed for systemd/autofs interaction fix
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-04-29 22:12:42 +02:00
|
|
|
static inline int is_packetized(struct file *file)
|
|
|
|
{
|
|
|
|
return (file->f_flags & O_DIRECT) != 0;
|
|
|
|
}
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
static ssize_t
|
2014-04-03 21:05:18 +02:00
|
|
|
pipe_write(struct kiocb *iocb, struct iov_iter *from)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
2006-10-01 08:28:47 +02:00
|
|
|
struct file *filp = iocb->ki_filp;
|
2013-03-21 16:16:56 +01:00
|
|
|
struct pipe_inode_info *pipe = filp->private_data;
|
2014-04-03 21:05:18 +02:00
|
|
|
ssize_t ret = 0;
|
|
|
|
int do_wakeup = 0;
|
|
|
|
size_t total_len = iov_iter_count(from);
|
2005-04-17 00:20:36 +02:00
|
|
|
ssize_t chars;
|
|
|
|
|
|
|
|
/* Null write succeeds. */
|
|
|
|
if (unlikely(total_len == 0))
|
|
|
|
return 0;
|
|
|
|
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_lock(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
|
2006-04-11 13:53:33 +02:00
|
|
|
if (!pipe->readers) {
|
2005-04-17 00:20:36 +02:00
|
|
|
send_sig(SIGPIPE, current, 0);
|
|
|
|
ret = -EPIPE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We try to merge small writes */
|
|
|
|
chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
|
2006-04-11 13:53:33 +02:00
|
|
|
if (pipe->nrbufs && chars != 0) {
|
2006-04-11 13:57:45 +02:00
|
|
|
int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
|
2010-05-20 10:43:18 +02:00
|
|
|
(pipe->buffers - 1);
|
2006-04-11 13:53:33 +02:00
|
|
|
struct pipe_buffer *buf = pipe->bufs + lastbuf;
|
2006-12-13 09:34:04 +01:00
|
|
|
const struct pipe_buf_operations *ops = buf->ops;
|
2005-04-17 00:20:36 +02:00
|
|
|
int offset = buf->offset + buf->len;
|
2006-04-11 13:57:45 +02:00
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
if (ops->can_merge && offset + chars <= PAGE_SIZE) {
|
2015-10-17 23:26:09 +02:00
|
|
|
ret = ops->confirm(pipe, buf);
|
|
|
|
if (ret)
|
2006-03-30 15:15:30 +02:00
|
|
|
goto out;
|
2006-05-01 19:59:03 +02:00
|
|
|
|
2014-04-03 21:05:18 +02:00
|
|
|
ret = copy_page_from_iter(buf->page, offset, chars, from);
|
|
|
|
if (unlikely(ret < chars)) {
|
2015-10-17 23:26:09 +02:00
|
|
|
ret = -EFAULT;
|
2005-04-17 00:20:36 +02:00
|
|
|
goto out;
|
2006-05-01 20:02:05 +02:00
|
|
|
}
|
2014-04-03 21:05:18 +02:00
|
|
|
do_wakeup = 1;
|
2015-10-17 23:26:09 +02:00
|
|
|
buf->len += ret;
|
2014-04-03 21:05:18 +02:00
|
|
|
if (!iov_iter_count(from))
|
2005-04-17 00:20:36 +02:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
int bufs;
|
2006-04-11 13:57:45 +02:00
|
|
|
|
2006-04-11 13:53:33 +02:00
|
|
|
if (!pipe->readers) {
|
2005-04-17 00:20:36 +02:00
|
|
|
send_sig(SIGPIPE, current, 0);
|
2006-04-11 13:57:45 +02:00
|
|
|
if (!ret)
|
|
|
|
ret = -EPIPE;
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
|
|
|
}
|
2006-04-11 13:53:33 +02:00
|
|
|
bufs = pipe->nrbufs;
|
2010-05-20 10:43:18 +02:00
|
|
|
if (bufs < pipe->buffers) {
|
|
|
|
int newbuf = (pipe->curbuf + bufs) & (pipe->buffers-1);
|
2006-04-11 13:53:33 +02:00
|
|
|
struct pipe_buffer *buf = pipe->bufs + newbuf;
|
|
|
|
struct page *page = pipe->tmp_page;
|
2014-04-03 21:05:18 +02:00
|
|
|
int copied;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
if (!page) {
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
page = alloc_page(GFP_HIGHUSER | __GFP_ACCOUNT);
|
2005-04-17 00:20:36 +02:00
|
|
|
if (unlikely(!page)) {
|
|
|
|
ret = ret ? : -ENOMEM;
|
|
|
|
break;
|
|
|
|
}
|
2006-04-11 13:53:33 +02:00
|
|
|
pipe->tmp_page = page;
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
2006-04-11 13:57:45 +02:00
|
|
|
/* Always wake up, even if the copy fails. Otherwise
|
2005-04-17 00:20:36 +02:00
|
|
|
* we lock up (O_NONBLOCK-)readers that sleep due to
|
|
|
|
* syscall merging.
|
|
|
|
* FIXME! Is this really true?
|
|
|
|
*/
|
|
|
|
do_wakeup = 1;
|
2014-04-03 21:05:18 +02:00
|
|
|
copied = copy_page_from_iter(page, 0, PAGE_SIZE, from);
|
|
|
|
if (unlikely(copied < PAGE_SIZE && iov_iter_count(from))) {
|
2006-04-11 13:57:45 +02:00
|
|
|
if (!ret)
|
2014-04-03 21:05:18 +02:00
|
|
|
ret = -EFAULT;
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-04-03 21:05:18 +02:00
|
|
|
ret += copied;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/* Insert it into the buffer array */
|
|
|
|
buf->page = page;
|
|
|
|
buf->ops = &anon_pipe_buf_ops;
|
|
|
|
buf->offset = 0;
|
2014-04-03 21:05:18 +02:00
|
|
|
buf->len = copied;
|
pipes: add a "packetized pipe" mode for writing
The actual internal pipe implementation is already really about
individual packets (called "pipe buffers"), and this simply exposes that
as a special packetized mode.
When we are in the packetized mode (marked by O_DIRECT as suggested by
Alan Cox), a write() on a pipe will not merge the new data with previous
writes, so each write will get a pipe buffer of its own. The pipe
buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
will tell the reader side to break the read at that boundary (and throw
away any partial packet contents that do not fit in the read buffer).
End result: as long as you do writes less than PIPE_BUF in size (so that
the pipe doesn't have to split them up), you can now treat the pipe as a
packet interface, where each read() system call will read one packet at
a time. You can just use a sufficiently big read buffer (PIPE_BUF is
sufficient, since bigger than that doesn't guarantee atomicity anyway),
and the return value of the read() will naturally give you the size of
the packet.
NOTE! We do not support zero-sized packets, and zero-sized reads and
writes to a pipe continue to be no-ops. Also note that big packets will
currently be split at write time, but that the size at which that
happens is not really specified (except that it's bigger than PIPE_BUF).
Currently that limit is the system page size, but we might want to
explicitly support bigger packets some day.
The main user for this is going to be the autofs packet interface,
allowing us to stop having to care so deeply about exact packet sizes
(which have had bugs with 32/64-bit compatibility modes). But user
space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
fail with an EINVAL on kernels that do not support this interface.
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Miller <davem@davemloft.net>
Cc: Ian Kent <raven@themaw.net>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: stable@kernel.org # needed for systemd/autofs interaction fix
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-04-29 22:12:42 +02:00
|
|
|
buf->flags = 0;
|
|
|
|
if (is_packetized(filp)) {
|
|
|
|
buf->ops = &packet_pipe_buf_ops;
|
|
|
|
buf->flags = PIPE_BUF_FLAG_PACKET;
|
|
|
|
}
|
2006-04-11 13:53:33 +02:00
|
|
|
pipe->nrbufs = ++bufs;
|
|
|
|
pipe->tmp_page = NULL;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
2014-04-03 21:05:18 +02:00
|
|
|
if (!iov_iter_count(from))
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
|
|
|
}
|
2010-05-20 10:43:18 +02:00
|
|
|
if (bufs < pipe->buffers)
|
2005-04-17 00:20:36 +02:00
|
|
|
continue;
|
|
|
|
if (filp->f_flags & O_NONBLOCK) {
|
2006-04-11 13:57:45 +02:00
|
|
|
if (!ret)
|
|
|
|
ret = -EAGAIN;
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (signal_pending(current)) {
|
2006-04-11 13:57:45 +02:00
|
|
|
if (!ret)
|
|
|
|
ret = -ERESTARTSYS;
|
2005-04-17 00:20:36 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (do_wakeup) {
|
2011-01-21 01:21:59 +01:00
|
|
|
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
|
2006-04-11 13:53:33 +02:00
|
|
|
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
|
2005-04-17 00:20:36 +02:00
|
|
|
do_wakeup = 0;
|
|
|
|
}
|
2006-04-11 13:53:33 +02:00
|
|
|
pipe->waiting_writers++;
|
|
|
|
pipe_wait(pipe);
|
|
|
|
pipe->waiting_writers--;
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
out:
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
if (do_wakeup) {
|
2011-01-21 01:21:59 +01:00
|
|
|
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
|
2006-04-11 13:53:33 +02:00
|
|
|
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
2014-01-24 00:55:21 +01:00
|
|
|
if (ret > 0 && sb_start_write_trylock(file_inode(filp)->i_sb)) {
|
2012-03-26 15:59:21 +02:00
|
|
|
int err = file_update_time(filp);
|
|
|
|
if (err)
|
|
|
|
ret = err;
|
2014-01-24 00:55:21 +01:00
|
|
|
sb_end_write(file_inode(filp)->i_sb);
|
2012-03-26 15:59:21 +02:00
|
|
|
}
|
2005-04-17 00:20:36 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-02-08 13:21:23 +01:00
|
|
|
static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
2013-03-21 16:16:56 +01:00
|
|
|
struct pipe_inode_info *pipe = filp->private_data;
|
2005-04-17 00:20:36 +02:00
|
|
|
int count, buf, nrbufs;
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case FIONREAD:
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_lock(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
count = 0;
|
2006-04-11 13:53:33 +02:00
|
|
|
buf = pipe->curbuf;
|
|
|
|
nrbufs = pipe->nrbufs;
|
2005-04-17 00:20:36 +02:00
|
|
|
while (--nrbufs >= 0) {
|
2006-04-11 13:53:33 +02:00
|
|
|
count += pipe->bufs[buf].len;
|
2010-05-20 10:43:18 +02:00
|
|
|
buf = (buf+1) & (pipe->buffers - 1);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
2006-04-11 13:53:33 +02:00
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
return put_user(count, (int __user *)arg);
|
|
|
|
default:
|
2012-05-25 12:39:13 +02:00
|
|
|
return -ENOIOCTLCMD;
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No kernel lock held - fine */
|
|
|
|
static unsigned int
|
|
|
|
pipe_poll(struct file *filp, poll_table *wait)
|
|
|
|
{
|
|
|
|
unsigned int mask;
|
2013-03-21 16:16:56 +01:00
|
|
|
struct pipe_inode_info *pipe = filp->private_data;
|
2005-04-17 00:20:36 +02:00
|
|
|
int nrbufs;
|
|
|
|
|
2006-04-11 13:53:33 +02:00
|
|
|
poll_wait(filp, &pipe->wait, wait);
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/* Reading only -- no need for acquiring the semaphore. */
|
2006-04-11 13:53:33 +02:00
|
|
|
nrbufs = pipe->nrbufs;
|
2005-04-17 00:20:36 +02:00
|
|
|
mask = 0;
|
|
|
|
if (filp->f_mode & FMODE_READ) {
|
|
|
|
mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
|
2006-04-11 13:53:33 +02:00
|
|
|
if (!pipe->writers && filp->f_version != pipe->w_counter)
|
2005-04-17 00:20:36 +02:00
|
|
|
mask |= POLLHUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filp->f_mode & FMODE_WRITE) {
|
2010-05-20 10:43:18 +02:00
|
|
|
mask |= (nrbufs < pipe->buffers) ? POLLOUT | POLLWRNORM : 0;
|
2005-09-07 00:17:48 +02:00
|
|
|
/*
|
|
|
|
* Most Unices do not set POLLERR for FIFOs but on Linux they
|
|
|
|
* behave exactly like pipes for poll().
|
|
|
|
*/
|
2006-04-11 13:53:33 +02:00
|
|
|
if (!pipe->readers)
|
2005-04-17 00:20:36 +02:00
|
|
|
mask |= POLLERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
vfs: fix subtle use-after-free of pipe_inode_info
The pipe code was trying (and failing) to be very careful about freeing
the pipe info only after the last access, with a pattern like:
spin_lock(&inode->i_lock);
if (!--pipe->files) {
inode->i_pipe = NULL;
kill = 1;
}
spin_unlock(&inode->i_lock);
__pipe_unlock(pipe);
if (kill)
free_pipe_info(pipe);
where the final freeing is done last.
HOWEVER. The above is actually broken, because while the freeing is
done at the end, if we have two racing processes releasing the pipe
inode info, the one that *doesn't* free it will decrement the ->files
count, and unlock the inode i_lock, but then still use the
"pipe_inode_info" afterwards when it does the "__pipe_unlock(pipe)".
This is *very* hard to trigger in practice, since the race window is
very small, and adding debug options seems to just hide it by slowing
things down.
Simon originally reported this way back in July as an Oops in
kmem_cache_allocate due to a single bit corruption (due to the final
"spin_unlock(pipe->mutex.wait_lock)" incrementing a field in a different
allocation that had re-used the free'd pipe-info), it's taken this long
to figure out.
Since the 'pipe->files' accesses aren't even protected by the pipe lock
(we very much use the inode lock for that), the simple solution is to
just drop the pipe lock early. And since there were two users of this
pattern, create a helper function for it.
Introduced commit ba5bb147330a ("pipe: take allocation and freeing of
pipe_inode_info out of ->i_mutex").
Reported-by: Simon Kirby <sim@hostway.ca>
Reported-by: Ian Applegate <ia@cloudflare.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: stable@kernel.org # v3.10+
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-12-02 18:44:51 +01:00
|
|
|
static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe)
|
|
|
|
{
|
|
|
|
int kill = 0;
|
|
|
|
|
|
|
|
spin_lock(&inode->i_lock);
|
|
|
|
if (!--pipe->files) {
|
|
|
|
inode->i_pipe = NULL;
|
|
|
|
kill = 1;
|
|
|
|
}
|
|
|
|
spin_unlock(&inode->i_lock);
|
|
|
|
|
|
|
|
if (kill)
|
|
|
|
free_pipe_info(pipe);
|
|
|
|
}
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
static int
|
2013-03-12 14:58:10 +01:00
|
|
|
pipe_release(struct inode *inode, struct file *file)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
vfs: fix subtle use-after-free of pipe_inode_info
The pipe code was trying (and failing) to be very careful about freeing
the pipe info only after the last access, with a pattern like:
spin_lock(&inode->i_lock);
if (!--pipe->files) {
inode->i_pipe = NULL;
kill = 1;
}
spin_unlock(&inode->i_lock);
__pipe_unlock(pipe);
if (kill)
free_pipe_info(pipe);
where the final freeing is done last.
HOWEVER. The above is actually broken, because while the freeing is
done at the end, if we have two racing processes releasing the pipe
inode info, the one that *doesn't* free it will decrement the ->files
count, and unlock the inode i_lock, but then still use the
"pipe_inode_info" afterwards when it does the "__pipe_unlock(pipe)".
This is *very* hard to trigger in practice, since the race window is
very small, and adding debug options seems to just hide it by slowing
things down.
Simon originally reported this way back in July as an Oops in
kmem_cache_allocate due to a single bit corruption (due to the final
"spin_unlock(pipe->mutex.wait_lock)" incrementing a field in a different
allocation that had re-used the free'd pipe-info), it's taken this long
to figure out.
Since the 'pipe->files' accesses aren't even protected by the pipe lock
(we very much use the inode lock for that), the simple solution is to
just drop the pipe lock early. And since there were two users of this
pattern, create a helper function for it.
Introduced commit ba5bb147330a ("pipe: take allocation and freeing of
pipe_inode_info out of ->i_mutex").
Reported-by: Simon Kirby <sim@hostway.ca>
Reported-by: Ian Applegate <ia@cloudflare.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: stable@kernel.org # v3.10+
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-12-02 18:44:51 +01:00
|
|
|
struct pipe_inode_info *pipe = file->private_data;
|
2006-04-11 13:53:33 +02:00
|
|
|
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_lock(pipe);
|
2013-03-12 14:58:10 +01:00
|
|
|
if (file->f_mode & FMODE_READ)
|
|
|
|
pipe->readers--;
|
|
|
|
if (file->f_mode & FMODE_WRITE)
|
|
|
|
pipe->writers--;
|
2006-04-11 13:57:45 +02:00
|
|
|
|
2013-03-21 07:21:19 +01:00
|
|
|
if (pipe->readers || pipe->writers) {
|
2011-01-21 01:21:59 +01:00
|
|
|
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP);
|
2006-04-11 13:53:33 +02:00
|
|
|
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
|
|
|
|
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
2013-03-21 07:21:19 +01:00
|
|
|
|
vfs: fix subtle use-after-free of pipe_inode_info
The pipe code was trying (and failing) to be very careful about freeing
the pipe info only after the last access, with a pattern like:
spin_lock(&inode->i_lock);
if (!--pipe->files) {
inode->i_pipe = NULL;
kill = 1;
}
spin_unlock(&inode->i_lock);
__pipe_unlock(pipe);
if (kill)
free_pipe_info(pipe);
where the final freeing is done last.
HOWEVER. The above is actually broken, because while the freeing is
done at the end, if we have two racing processes releasing the pipe
inode info, the one that *doesn't* free it will decrement the ->files
count, and unlock the inode i_lock, but then still use the
"pipe_inode_info" afterwards when it does the "__pipe_unlock(pipe)".
This is *very* hard to trigger in practice, since the race window is
very small, and adding debug options seems to just hide it by slowing
things down.
Simon originally reported this way back in July as an Oops in
kmem_cache_allocate due to a single bit corruption (due to the final
"spin_unlock(pipe->mutex.wait_lock)" incrementing a field in a different
allocation that had re-used the free'd pipe-info), it's taken this long
to figure out.
Since the 'pipe->files' accesses aren't even protected by the pipe lock
(we very much use the inode lock for that), the simple solution is to
just drop the pipe lock early. And since there were two users of this
pattern, create a helper function for it.
Introduced commit ba5bb147330a ("pipe: take allocation and freeing of
pipe_inode_info out of ->i_mutex").
Reported-by: Simon Kirby <sim@hostway.ca>
Reported-by: Ian Applegate <ia@cloudflare.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: stable@kernel.org # v3.10+
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-12-02 18:44:51 +01:00
|
|
|
put_pipe_info(inode, pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2013-03-12 14:58:10 +01:00
|
|
|
pipe_fasync(int fd, struct file *filp, int on)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
2013-03-21 16:16:56 +01:00
|
|
|
struct pipe_inode_info *pipe = filp->private_data;
|
2013-03-12 14:58:10 +01:00
|
|
|
int retval = 0;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_lock(pipe);
|
2013-03-12 14:58:10 +01:00
|
|
|
if (filp->f_mode & FMODE_READ)
|
|
|
|
retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
|
|
|
|
if ((filp->f_mode & FMODE_WRITE) && retval >= 0) {
|
2006-04-11 13:57:45 +02:00
|
|
|
retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
|
2013-03-12 14:58:10 +01:00
|
|
|
if (retval < 0 && (filp->f_mode & FMODE_READ))
|
|
|
|
/* this can happen only if on == T */
|
2009-03-12 22:31:28 +01:00
|
|
|
fasync_helper(-1, filp, 0, &pipe->fasync_readers);
|
|
|
|
}
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
2009-02-01 22:52:56 +01:00
|
|
|
return retval;
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
|
2016-01-18 16:36:09 +01:00
|
|
|
static void account_pipe_buffers(struct pipe_inode_info *pipe,
|
|
|
|
unsigned long old, unsigned long new)
|
|
|
|
{
|
|
|
|
atomic_long_add(new - old, &pipe->user->pipe_bufs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool too_many_pipe_buffers_soft(struct user_struct *user)
|
|
|
|
{
|
|
|
|
return pipe_user_pages_soft &&
|
|
|
|
atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_soft;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool too_many_pipe_buffers_hard(struct user_struct *user)
|
|
|
|
{
|
|
|
|
return pipe_user_pages_hard &&
|
|
|
|
atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_hard;
|
|
|
|
}
|
|
|
|
|
2013-03-21 16:04:15 +01:00
|
|
|
struct pipe_inode_info *alloc_pipe_info(void)
|
2006-04-10 15:18:35 +02:00
|
|
|
{
|
2006-04-11 13:53:33 +02:00
|
|
|
struct pipe_inode_info *pipe;
|
2006-04-10 15:18:35 +02:00
|
|
|
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
|
2006-04-11 13:53:33 +02:00
|
|
|
if (pipe) {
|
2016-01-18 16:36:09 +01:00
|
|
|
unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
|
|
|
|
struct user_struct *user = get_current_user();
|
|
|
|
|
|
|
|
if (!too_many_pipe_buffers_hard(user)) {
|
|
|
|
if (too_many_pipe_buffers_soft(user))
|
|
|
|
pipe_bufs = 1;
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
pipe->bufs = kcalloc(pipe_bufs,
|
|
|
|
sizeof(struct pipe_buffer),
|
|
|
|
GFP_KERNEL_ACCOUNT);
|
2016-01-18 16:36:09 +01:00
|
|
|
}
|
|
|
|
|
2010-05-20 10:43:18 +02:00
|
|
|
if (pipe->bufs) {
|
|
|
|
init_waitqueue_head(&pipe->wait);
|
|
|
|
pipe->r_counter = pipe->w_counter = 1;
|
2016-01-18 16:36:09 +01:00
|
|
|
pipe->buffers = pipe_bufs;
|
|
|
|
pipe->user = user;
|
|
|
|
account_pipe_buffers(pipe, 0, pipe_bufs);
|
2013-03-21 07:32:24 +01:00
|
|
|
mutex_init(&pipe->mutex);
|
2010-05-20 10:43:18 +02:00
|
|
|
return pipe;
|
|
|
|
}
|
2016-01-18 16:36:09 +01:00
|
|
|
free_uid(user);
|
2010-05-20 10:43:18 +02:00
|
|
|
kfree(pipe);
|
2006-04-10 15:18:35 +02:00
|
|
|
}
|
|
|
|
|
2010-05-20 10:43:18 +02:00
|
|
|
return NULL;
|
2006-04-10 15:18:35 +02:00
|
|
|
}
|
|
|
|
|
2013-03-21 16:06:46 +01:00
|
|
|
void free_pipe_info(struct pipe_inode_info *pipe)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2016-01-18 16:36:09 +01:00
|
|
|
account_pipe_buffers(pipe, pipe->buffers, 0);
|
|
|
|
free_uid(pipe->user);
|
2010-05-20 10:43:18 +02:00
|
|
|
for (i = 0; i < pipe->buffers; i++) {
|
2006-04-11 13:53:33 +02:00
|
|
|
struct pipe_buffer *buf = pipe->bufs + i;
|
2005-04-17 00:20:36 +02:00
|
|
|
if (buf->ops)
|
2006-04-11 13:53:33 +02:00
|
|
|
buf->ops->release(pipe, buf);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
2006-04-11 13:53:33 +02:00
|
|
|
if (pipe->tmp_page)
|
|
|
|
__free_page(pipe->tmp_page);
|
2010-05-20 10:43:18 +02:00
|
|
|
kfree(pipe->bufs);
|
2006-04-11 13:53:33 +02:00
|
|
|
kfree(pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
|
2006-03-26 11:37:24 +02:00
|
|
|
static struct vfsmount *pipe_mnt __read_mostly;
|
2006-04-11 13:57:45 +02:00
|
|
|
|
2007-05-08 09:26:18 +02:00
|
|
|
/*
|
|
|
|
* pipefs_dname() is called from d_path().
|
|
|
|
*/
|
|
|
|
static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen)
|
|
|
|
{
|
|
|
|
return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
|
2015-03-17 23:26:12 +01:00
|
|
|
d_inode(dentry)->i_ino);
|
2007-05-08 09:26:18 +02:00
|
|
|
}
|
|
|
|
|
2009-02-20 07:02:22 +01:00
|
|
|
static const struct dentry_operations pipefs_dentry_operations = {
|
2007-05-08 09:26:18 +02:00
|
|
|
.d_dname = pipefs_dname,
|
2005-04-17 00:20:36 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct inode * get_pipe_inode(void)
|
|
|
|
{
|
2011-07-26 11:36:34 +02:00
|
|
|
struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
|
2006-04-11 13:53:33 +02:00
|
|
|
struct pipe_inode_info *pipe;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
if (!inode)
|
|
|
|
goto fail_inode;
|
|
|
|
|
2010-10-23 17:19:54 +02:00
|
|
|
inode->i_ino = get_next_ino();
|
|
|
|
|
2013-03-21 16:04:15 +01:00
|
|
|
pipe = alloc_pipe_info();
|
2006-04-11 13:53:33 +02:00
|
|
|
if (!pipe)
|
2005-04-17 00:20:36 +02:00
|
|
|
goto fail_iput;
|
2006-04-10 15:18:35 +02:00
|
|
|
|
2013-03-21 07:21:19 +01:00
|
|
|
inode->i_pipe = pipe;
|
|
|
|
pipe->files = 2;
|
2006-04-11 13:53:33 +02:00
|
|
|
pipe->readers = pipe->writers = 1;
|
2013-03-12 14:58:10 +01:00
|
|
|
inode->i_fop = &pipefifo_fops;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Mark the inode dirty from the very beginning,
|
|
|
|
* that way it will never be moved to the dirty
|
|
|
|
* list because "mark_inode_dirty()" will think
|
|
|
|
* that it already _is_ on the dirty list.
|
|
|
|
*/
|
|
|
|
inode->i_state = I_DIRTY;
|
|
|
|
inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
|
2008-11-14 00:39:05 +01:00
|
|
|
inode->i_uid = current_fsuid();
|
|
|
|
inode->i_gid = current_fsgid();
|
2005-04-17 00:20:36 +02:00
|
|
|
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
2006-04-11 13:53:33 +02:00
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
return inode;
|
|
|
|
|
|
|
|
fail_iput:
|
|
|
|
iput(inode);
|
2006-04-11 13:57:45 +02:00
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
fail_inode:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-07-21 13:33:25 +02:00
|
|
|
int create_pipe_files(struct file **res, int flags)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
2006-10-01 08:29:26 +02:00
|
|
|
int err;
|
2012-07-21 13:33:25 +02:00
|
|
|
struct inode *inode = get_pipe_inode();
|
2006-10-01 08:29:26 +02:00
|
|
|
struct file *f;
|
2009-08-08 22:52:35 +02:00
|
|
|
struct path path;
|
2012-07-21 13:33:25 +02:00
|
|
|
static struct qstr name = { .name = "" };
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
if (!inode)
|
2012-07-21 13:33:25 +02:00
|
|
|
return -ENFILE;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
2006-10-01 08:29:26 +02:00
|
|
|
err = -ENOMEM;
|
2011-01-07 07:50:07 +01:00
|
|
|
path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name);
|
2009-08-08 22:52:35 +02:00
|
|
|
if (!path.dentry)
|
2006-10-01 08:29:26 +02:00
|
|
|
goto err_inode;
|
2009-08-08 22:52:35 +02:00
|
|
|
path.mnt = mntget(pipe_mnt);
|
2006-04-11 13:57:45 +02:00
|
|
|
|
2009-08-08 22:52:35 +02:00
|
|
|
d_instantiate(path.dentry, inode);
|
2008-02-15 23:37:26 +01:00
|
|
|
|
2013-03-12 14:58:10 +01:00
|
|
|
f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops);
|
fs/pipe.c: preserve alloc_file() error code
If sys_pipe() was unable to allocate a 'struct file', it always failed
with ENFILE, which means "The number of simultaneously open files in the
system would exceed a system-imposed limit." However, alloc_file()
actually returns an ERR_PTR value and might fail with other error codes.
Currently, in addition to ENFILE, it can fail with ENOMEM, potentially
when there are few open files in the system. Update sys_pipe() to
preserve this error code.
In a prior submission of a similar patch (1) some concern was raised
about introducing a new error code for sys_pipe(). However, for most
system calls, programs cannot assume that new error codes will never be
introduced. In addition, ENOMEM was, in fact, already a possible error
code for sys_pipe(), in the case where the file descriptor table could
not be expanded due to insufficient memory.
(1) http://comments.gmane.org/gmane.linux.kernel/1357942
Signed-off-by: Eric Biggers <ebiggers3@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-10-17 23:26:08 +02:00
|
|
|
if (IS_ERR(f)) {
|
|
|
|
err = PTR_ERR(f);
|
2008-02-15 23:37:26 +01:00
|
|
|
goto err_dentry;
|
fs/pipe.c: preserve alloc_file() error code
If sys_pipe() was unable to allocate a 'struct file', it always failed
with ENFILE, which means "The number of simultaneously open files in the
system would exceed a system-imposed limit." However, alloc_file()
actually returns an ERR_PTR value and might fail with other error codes.
Currently, in addition to ENFILE, it can fail with ENOMEM, potentially
when there are few open files in the system. Update sys_pipe() to
preserve this error code.
In a prior submission of a similar patch (1) some concern was raised
about introducing a new error code for sys_pipe(). However, for most
system calls, programs cannot assume that new error codes will never be
introduced. In addition, ENOMEM was, in fact, already a possible error
code for sys_pipe(), in the case where the file descriptor table could
not be expanded due to insufficient memory.
(1) http://comments.gmane.org/gmane.linux.kernel/1357942
Signed-off-by: Eric Biggers <ebiggers3@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-10-17 23:26:08 +02:00
|
|
|
}
|
2006-04-11 13:57:45 +02:00
|
|
|
|
pipes: add a "packetized pipe" mode for writing
The actual internal pipe implementation is already really about
individual packets (called "pipe buffers"), and this simply exposes that
as a special packetized mode.
When we are in the packetized mode (marked by O_DIRECT as suggested by
Alan Cox), a write() on a pipe will not merge the new data with previous
writes, so each write will get a pipe buffer of its own. The pipe
buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
will tell the reader side to break the read at that boundary (and throw
away any partial packet contents that do not fit in the read buffer).
End result: as long as you do writes less than PIPE_BUF in size (so that
the pipe doesn't have to split them up), you can now treat the pipe as a
packet interface, where each read() system call will read one packet at
a time. You can just use a sufficiently big read buffer (PIPE_BUF is
sufficient, since bigger than that doesn't guarantee atomicity anyway),
and the return value of the read() will naturally give you the size of
the packet.
NOTE! We do not support zero-sized packets, and zero-sized reads and
writes to a pipe continue to be no-ops. Also note that big packets will
currently be split at write time, but that the size at which that
happens is not really specified (except that it's bigger than PIPE_BUF).
Currently that limit is the system page size, but we might want to
explicitly support bigger packets some day.
The main user for this is going to be the autofs packet interface,
allowing us to stop having to care so deeply about exact packet sizes
(which have had bugs with 32/64-bit compatibility modes). But user
space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
fail with an EINVAL on kernels that do not support this interface.
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Miller <davem@davemloft.net>
Cc: Ian Kent <raven@themaw.net>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: stable@kernel.org # needed for systemd/autofs interaction fix
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-04-29 22:12:42 +02:00
|
|
|
f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
|
2013-03-21 16:16:56 +01:00
|
|
|
f->private_data = inode->i_pipe;
|
2006-10-01 08:29:26 +02:00
|
|
|
|
2013-03-12 14:58:10 +01:00
|
|
|
res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops);
|
fs/pipe.c: preserve alloc_file() error code
If sys_pipe() was unable to allocate a 'struct file', it always failed
with ENFILE, which means "The number of simultaneously open files in the
system would exceed a system-imposed limit." However, alloc_file()
actually returns an ERR_PTR value and might fail with other error codes.
Currently, in addition to ENFILE, it can fail with ENOMEM, potentially
when there are few open files in the system. Update sys_pipe() to
preserve this error code.
In a prior submission of a similar patch (1) some concern was raised
about introducing a new error code for sys_pipe(). However, for most
system calls, programs cannot assume that new error codes will never be
introduced. In addition, ENOMEM was, in fact, already a possible error
code for sys_pipe(), in the case where the file descriptor table could
not be expanded due to insufficient memory.
(1) http://comments.gmane.org/gmane.linux.kernel/1357942
Signed-off-by: Eric Biggers <ebiggers3@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-10-17 23:26:08 +02:00
|
|
|
if (IS_ERR(res[0])) {
|
|
|
|
err = PTR_ERR(res[0]);
|
2012-07-21 13:33:25 +02:00
|
|
|
goto err_file;
|
fs/pipe.c: preserve alloc_file() error code
If sys_pipe() was unable to allocate a 'struct file', it always failed
with ENFILE, which means "The number of simultaneously open files in the
system would exceed a system-imposed limit." However, alloc_file()
actually returns an ERR_PTR value and might fail with other error codes.
Currently, in addition to ENFILE, it can fail with ENOMEM, potentially
when there are few open files in the system. Update sys_pipe() to
preserve this error code.
In a prior submission of a similar patch (1) some concern was raised
about introducing a new error code for sys_pipe(). However, for most
system calls, programs cannot assume that new error codes will never be
introduced. In addition, ENOMEM was, in fact, already a possible error
code for sys_pipe(), in the case where the file descriptor table could
not be expanded due to insufficient memory.
(1) http://comments.gmane.org/gmane.linux.kernel/1357942
Signed-off-by: Eric Biggers <ebiggers3@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-10-17 23:26:08 +02:00
|
|
|
}
|
2012-07-21 13:33:25 +02:00
|
|
|
|
|
|
|
path_get(&path);
|
2013-03-21 16:16:56 +01:00
|
|
|
res[0]->private_data = inode->i_pipe;
|
2012-07-21 13:33:25 +02:00
|
|
|
res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK);
|
|
|
|
res[1] = f;
|
|
|
|
return 0;
|
2005-04-17 00:20:36 +02:00
|
|
|
|
2012-07-21 13:33:25 +02:00
|
|
|
err_file:
|
|
|
|
put_filp(f);
|
|
|
|
err_dentry:
|
2013-03-21 16:06:46 +01:00
|
|
|
free_pipe_info(inode->i_pipe);
|
2009-08-08 22:52:35 +02:00
|
|
|
path_put(&path);
|
2012-07-21 13:33:25 +02:00
|
|
|
return err;
|
2008-04-23 01:51:27 +02:00
|
|
|
|
2012-07-21 13:33:25 +02:00
|
|
|
err_inode:
|
2013-03-21 16:06:46 +01:00
|
|
|
free_pipe_info(inode->i_pipe);
|
2005-04-17 00:20:36 +02:00
|
|
|
iput(inode);
|
2012-07-21 13:33:25 +02:00
|
|
|
return err;
|
2006-10-01 08:29:26 +02:00
|
|
|
}
|
|
|
|
|
2012-08-19 18:17:29 +02:00
|
|
|
static int __do_pipe_flags(int *fd, struct file **files, int flags)
|
2006-10-01 08:29:26 +02:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
int fdw, fdr;
|
|
|
|
|
pipes: add a "packetized pipe" mode for writing
The actual internal pipe implementation is already really about
individual packets (called "pipe buffers"), and this simply exposes that
as a special packetized mode.
When we are in the packetized mode (marked by O_DIRECT as suggested by
Alan Cox), a write() on a pipe will not merge the new data with previous
writes, so each write will get a pipe buffer of its own. The pipe
buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
will tell the reader side to break the read at that boundary (and throw
away any partial packet contents that do not fit in the read buffer).
End result: as long as you do writes less than PIPE_BUF in size (so that
the pipe doesn't have to split them up), you can now treat the pipe as a
packet interface, where each read() system call will read one packet at
a time. You can just use a sufficiently big read buffer (PIPE_BUF is
sufficient, since bigger than that doesn't guarantee atomicity anyway),
and the return value of the read() will naturally give you the size of
the packet.
NOTE! We do not support zero-sized packets, and zero-sized reads and
writes to a pipe continue to be no-ops. Also note that big packets will
currently be split at write time, but that the size at which that
happens is not really specified (except that it's bigger than PIPE_BUF).
Currently that limit is the system page size, but we might want to
explicitly support bigger packets some day.
The main user for this is going to be the autofs packet interface,
allowing us to stop having to care so deeply about exact packet sizes
(which have had bugs with 32/64-bit compatibility modes). But user
space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
fail with an EINVAL on kernels that do not support this interface.
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Miller <davem@davemloft.net>
Cc: Ian Kent <raven@themaw.net>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: stable@kernel.org # needed for systemd/autofs interaction fix
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-04-29 22:12:42 +02:00
|
|
|
if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
|
2008-07-24 06:29:30 +02:00
|
|
|
return -EINVAL;
|
|
|
|
|
2012-07-21 13:33:25 +02:00
|
|
|
error = create_pipe_files(files, flags);
|
|
|
|
if (error)
|
|
|
|
return error;
|
2006-10-01 08:29:26 +02:00
|
|
|
|
2008-07-24 06:29:30 +02:00
|
|
|
error = get_unused_fd_flags(flags);
|
2006-10-01 08:29:26 +02:00
|
|
|
if (error < 0)
|
|
|
|
goto err_read_pipe;
|
|
|
|
fdr = error;
|
|
|
|
|
2008-07-24 06:29:30 +02:00
|
|
|
error = get_unused_fd_flags(flags);
|
2006-10-01 08:29:26 +02:00
|
|
|
if (error < 0)
|
|
|
|
goto err_fdr;
|
|
|
|
fdw = error;
|
|
|
|
|
2008-12-14 10:57:47 +01:00
|
|
|
audit_fd_pair(fdr, fdw);
|
2006-10-01 08:29:26 +02:00
|
|
|
fd[0] = fdr;
|
|
|
|
fd[1] = fdw;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_fdr:
|
|
|
|
put_unused_fd(fdr);
|
|
|
|
err_read_pipe:
|
2012-07-21 13:33:25 +02:00
|
|
|
fput(files[0]);
|
|
|
|
fput(files[1]);
|
2006-10-01 08:29:26 +02:00
|
|
|
return error;
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
|
2012-08-19 18:17:29 +02:00
|
|
|
int do_pipe_flags(int *fd, int flags)
|
|
|
|
{
|
|
|
|
struct file *files[2];
|
|
|
|
int error = __do_pipe_flags(fd, files, flags);
|
|
|
|
if (!error) {
|
|
|
|
fd_install(fd[0], files[0]);
|
|
|
|
fd_install(fd[1], files[1]);
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2008-05-03 21:10:37 +02:00
|
|
|
/*
|
|
|
|
* sys_pipe() is the normal C calling standard for creating
|
|
|
|
* a pipe. It's not the way Unix traditionally does this, though.
|
|
|
|
*/
|
2009-01-14 14:14:34 +01:00
|
|
|
SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
|
2008-05-03 21:10:37 +02:00
|
|
|
{
|
2012-08-19 18:17:29 +02:00
|
|
|
struct file *files[2];
|
2008-05-03 21:10:37 +02:00
|
|
|
int fd[2];
|
|
|
|
int error;
|
|
|
|
|
2012-08-19 18:17:29 +02:00
|
|
|
error = __do_pipe_flags(fd, files, flags);
|
2008-05-03 21:10:37 +02:00
|
|
|
if (!error) {
|
2012-08-19 18:17:29 +02:00
|
|
|
if (unlikely(copy_to_user(fildes, fd, sizeof(fd)))) {
|
|
|
|
fput(files[0]);
|
|
|
|
fput(files[1]);
|
|
|
|
put_unused_fd(fd[0]);
|
|
|
|
put_unused_fd(fd[1]);
|
2008-05-03 21:10:37 +02:00
|
|
|
error = -EFAULT;
|
2012-08-19 18:17:29 +02:00
|
|
|
} else {
|
|
|
|
fd_install(fd[0], files[0]);
|
|
|
|
fd_install(fd[1], files[1]);
|
2008-05-07 05:42:38 +02:00
|
|
|
}
|
2008-05-03 21:10:37 +02:00
|
|
|
}
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2009-01-14 14:14:35 +01:00
|
|
|
SYSCALL_DEFINE1(pipe, int __user *, fildes)
|
2008-07-24 06:29:30 +02:00
|
|
|
{
|
|
|
|
return sys_pipe2(fildes, 0);
|
|
|
|
}
|
|
|
|
|
2013-03-21 07:07:59 +01:00
|
|
|
static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt)
|
2013-03-12 14:46:27 +01:00
|
|
|
{
|
|
|
|
int cur = *cnt;
|
|
|
|
|
|
|
|
while (cur == *cnt) {
|
2013-03-21 07:07:59 +01:00
|
|
|
pipe_wait(pipe);
|
2013-03-12 14:46:27 +01:00
|
|
|
if (signal_pending(current))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return cur == *cnt ? -ERESTARTSYS : 0;
|
|
|
|
}
|
|
|
|
|
2013-03-21 07:07:59 +01:00
|
|
|
static void wake_up_partner(struct pipe_inode_info *pipe)
|
2013-03-12 14:46:27 +01:00
|
|
|
{
|
2013-03-21 07:07:59 +01:00
|
|
|
wake_up_interruptible(&pipe->wait);
|
2013-03-12 14:46:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int fifo_open(struct inode *inode, struct file *filp)
|
|
|
|
{
|
|
|
|
struct pipe_inode_info *pipe;
|
2013-03-12 14:58:10 +01:00
|
|
|
bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
|
2013-03-12 14:46:27 +01:00
|
|
|
int ret;
|
|
|
|
|
2013-03-21 07:21:19 +01:00
|
|
|
filp->f_version = 0;
|
|
|
|
|
|
|
|
spin_lock(&inode->i_lock);
|
|
|
|
if (inode->i_pipe) {
|
|
|
|
pipe = inode->i_pipe;
|
|
|
|
pipe->files++;
|
|
|
|
spin_unlock(&inode->i_lock);
|
|
|
|
} else {
|
|
|
|
spin_unlock(&inode->i_lock);
|
2013-03-21 16:04:15 +01:00
|
|
|
pipe = alloc_pipe_info();
|
2013-03-12 14:46:27 +01:00
|
|
|
if (!pipe)
|
2013-03-21 07:21:19 +01:00
|
|
|
return -ENOMEM;
|
|
|
|
pipe->files = 1;
|
|
|
|
spin_lock(&inode->i_lock);
|
|
|
|
if (unlikely(inode->i_pipe)) {
|
|
|
|
inode->i_pipe->files++;
|
|
|
|
spin_unlock(&inode->i_lock);
|
2013-03-21 16:06:46 +01:00
|
|
|
free_pipe_info(pipe);
|
2013-03-21 07:21:19 +01:00
|
|
|
pipe = inode->i_pipe;
|
|
|
|
} else {
|
|
|
|
inode->i_pipe = pipe;
|
|
|
|
spin_unlock(&inode->i_lock);
|
|
|
|
}
|
2013-03-12 14:46:27 +01:00
|
|
|
}
|
2013-03-21 16:16:56 +01:00
|
|
|
filp->private_data = pipe;
|
2013-03-21 07:21:19 +01:00
|
|
|
/* OK, we have a pipe and it's pinned down */
|
|
|
|
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_lock(pipe);
|
2013-03-12 14:46:27 +01:00
|
|
|
|
|
|
|
/* We can only do regular read/write on fifos */
|
|
|
|
filp->f_mode &= (FMODE_READ | FMODE_WRITE);
|
|
|
|
|
|
|
|
switch (filp->f_mode) {
|
|
|
|
case FMODE_READ:
|
|
|
|
/*
|
|
|
|
* O_RDONLY
|
|
|
|
* POSIX.1 says that O_NONBLOCK means return with the FIFO
|
|
|
|
* opened, even when there is no process writing the FIFO.
|
|
|
|
*/
|
|
|
|
pipe->r_counter++;
|
|
|
|
if (pipe->readers++ == 0)
|
2013-03-21 07:07:59 +01:00
|
|
|
wake_up_partner(pipe);
|
2013-03-12 14:46:27 +01:00
|
|
|
|
2013-03-12 14:58:10 +01:00
|
|
|
if (!is_pipe && !pipe->writers) {
|
2013-03-12 14:46:27 +01:00
|
|
|
if ((filp->f_flags & O_NONBLOCK)) {
|
|
|
|
/* suppress POLLHUP until we have
|
|
|
|
* seen a writer */
|
|
|
|
filp->f_version = pipe->w_counter;
|
|
|
|
} else {
|
2013-03-21 07:07:59 +01:00
|
|
|
if (wait_for_partner(pipe, &pipe->w_counter))
|
2013-03-12 14:46:27 +01:00
|
|
|
goto err_rd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FMODE_WRITE:
|
|
|
|
/*
|
|
|
|
* O_WRONLY
|
|
|
|
* POSIX.1 says that O_NONBLOCK means return -1 with
|
|
|
|
* errno=ENXIO when there is no process reading the FIFO.
|
|
|
|
*/
|
|
|
|
ret = -ENXIO;
|
2013-03-12 14:58:10 +01:00
|
|
|
if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers)
|
2013-03-12 14:46:27 +01:00
|
|
|
goto err;
|
|
|
|
|
|
|
|
pipe->w_counter++;
|
|
|
|
if (!pipe->writers++)
|
2013-03-21 07:07:59 +01:00
|
|
|
wake_up_partner(pipe);
|
2013-03-12 14:46:27 +01:00
|
|
|
|
2013-03-12 14:58:10 +01:00
|
|
|
if (!is_pipe && !pipe->readers) {
|
2013-03-21 07:07:59 +01:00
|
|
|
if (wait_for_partner(pipe, &pipe->r_counter))
|
2013-03-12 14:46:27 +01:00
|
|
|
goto err_wr;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FMODE_READ | FMODE_WRITE:
|
|
|
|
/*
|
|
|
|
* O_RDWR
|
|
|
|
* POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
|
|
|
|
* This implementation will NEVER block on a O_RDWR open, since
|
|
|
|
* the process can at least talk to itself.
|
|
|
|
*/
|
|
|
|
|
|
|
|
pipe->readers++;
|
|
|
|
pipe->writers++;
|
|
|
|
pipe->r_counter++;
|
|
|
|
pipe->w_counter++;
|
|
|
|
if (pipe->readers == 1 || pipe->writers == 1)
|
2013-03-21 07:07:59 +01:00
|
|
|
wake_up_partner(pipe);
|
2013-03-12 14:46:27 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ok! */
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
2013-03-12 14:46:27 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_rd:
|
|
|
|
if (!--pipe->readers)
|
|
|
|
wake_up_interruptible(&pipe->wait);
|
|
|
|
ret = -ERESTARTSYS;
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
err_wr:
|
|
|
|
if (!--pipe->writers)
|
|
|
|
wake_up_interruptible(&pipe->wait);
|
|
|
|
ret = -ERESTARTSYS;
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
err:
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
vfs: fix subtle use-after-free of pipe_inode_info
The pipe code was trying (and failing) to be very careful about freeing
the pipe info only after the last access, with a pattern like:
spin_lock(&inode->i_lock);
if (!--pipe->files) {
inode->i_pipe = NULL;
kill = 1;
}
spin_unlock(&inode->i_lock);
__pipe_unlock(pipe);
if (kill)
free_pipe_info(pipe);
where the final freeing is done last.
HOWEVER. The above is actually broken, because while the freeing is
done at the end, if we have two racing processes releasing the pipe
inode info, the one that *doesn't* free it will decrement the ->files
count, and unlock the inode i_lock, but then still use the
"pipe_inode_info" afterwards when it does the "__pipe_unlock(pipe)".
This is *very* hard to trigger in practice, since the race window is
very small, and adding debug options seems to just hide it by slowing
things down.
Simon originally reported this way back in July as an Oops in
kmem_cache_allocate due to a single bit corruption (due to the final
"spin_unlock(pipe->mutex.wait_lock)" incrementing a field in a different
allocation that had re-used the free'd pipe-info), it's taken this long
to figure out.
Since the 'pipe->files' accesses aren't even protected by the pipe lock
(we very much use the inode lock for that), the simple solution is to
just drop the pipe lock early. And since there were two users of this
pattern, create a helper function for it.
Introduced commit ba5bb147330a ("pipe: take allocation and freeing of
pipe_inode_info out of ->i_mutex").
Reported-by: Simon Kirby <sim@hostway.ca>
Reported-by: Ian Applegate <ia@cloudflare.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: stable@kernel.org # v3.10+
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-12-02 18:44:51 +01:00
|
|
|
|
|
|
|
put_pipe_info(inode, pipe);
|
2013-03-12 14:46:27 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-03-12 14:58:10 +01:00
|
|
|
const struct file_operations pipefifo_fops = {
|
|
|
|
.open = fifo_open,
|
|
|
|
.llseek = no_llseek,
|
2014-04-03 01:56:54 +02:00
|
|
|
.read_iter = pipe_read,
|
2014-04-03 21:05:18 +02:00
|
|
|
.write_iter = pipe_write,
|
2013-03-12 14:58:10 +01:00
|
|
|
.poll = pipe_poll,
|
|
|
|
.unlocked_ioctl = pipe_ioctl,
|
|
|
|
.release = pipe_release,
|
|
|
|
.fasync = pipe_fasync,
|
2013-03-12 14:46:27 +01:00
|
|
|
};
|
|
|
|
|
2010-05-20 10:43:18 +02:00
|
|
|
/*
|
|
|
|
* Allocate a new array of pipe buffers and copy the info over. Returns the
|
|
|
|
* pipe size if successful, or return -ERROR on error.
|
|
|
|
*/
|
2010-05-24 19:34:43 +02:00
|
|
|
static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
|
2010-05-20 10:43:18 +02:00
|
|
|
{
|
|
|
|
struct pipe_buffer *bufs;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't
|
|
|
|
* expect a lot of shrink+grow operations, just free and allocate
|
|
|
|
* again like we would do for growing. If the pipe currently
|
|
|
|
* contains more buffers than arg, then return busy.
|
|
|
|
*/
|
2010-05-24 19:34:43 +02:00
|
|
|
if (nr_pages < pipe->nrbufs)
|
2010-05-20 10:43:18 +02:00
|
|
|
return -EBUSY;
|
|
|
|
|
pipe: account to kmemcg
Pipes can consume a significant amount of system memory, hence they
should be accounted to kmemcg.
This patch marks pipe_inode_info and anonymous pipe buffer page
allocations as __GFP_ACCOUNT so that they would be charged to kmemcg.
Note, since a pipe buffer page can be "stolen" and get reused for other
purposes, including mapping to userspace, we clear PageKmemcg thus
resetting page->_mapcount and uncharge it in anon_pipe_buf_steal, which
is introduced by this patch.
A note regarding anon_pipe_buf_steal implementation. We allow to steal
the page if its ref count equals 1. It looks racy, but it is correct
for anonymous pipe buffer pages, because:
- We lock out all other pipe users, because ->steal is called with
pipe_lock held, so the page can't be spliced to another pipe from
under us.
- The page is not on LRU and it never was.
- Thus a parallel thread can access it only by PFN. Although this is
quite possible (e.g. see page_idle_get_page and balloon_page_isolate)
this is not dangerous, because all such functions do is increase page
ref count, check if the page is the one they are looking for, and
decrease ref count if it isn't. Since our page is clean except for
PageKmemcg mark, which doesn't conflict with other _mapcount users,
the worst that can happen is we see page_count > 2 due to a transient
ref, in which case we false-positively abort ->steal, which is still
fine, because ->steal is not guaranteed to succeed.
Link: http://lkml.kernel.org/r/20160527150313.GD26059@esperanza
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 00:24:33 +02:00
|
|
|
bufs = kcalloc(nr_pages, sizeof(*bufs),
|
|
|
|
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
|
2010-05-20 10:43:18 +02:00
|
|
|
if (unlikely(!bufs))
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The pipe array wraps around, so just start the new one at zero
|
|
|
|
* and adjust the indexes.
|
|
|
|
*/
|
|
|
|
if (pipe->nrbufs) {
|
2010-06-08 16:28:45 +02:00
|
|
|
unsigned int tail;
|
|
|
|
unsigned int head;
|
2010-05-20 10:43:18 +02:00
|
|
|
|
2010-06-08 16:28:45 +02:00
|
|
|
tail = pipe->curbuf + pipe->nrbufs;
|
|
|
|
if (tail < pipe->buffers)
|
|
|
|
tail = 0;
|
|
|
|
else
|
|
|
|
tail &= (pipe->buffers - 1);
|
|
|
|
|
|
|
|
head = pipe->nrbufs - tail;
|
2010-05-20 10:43:18 +02:00
|
|
|
if (head)
|
|
|
|
memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer));
|
|
|
|
if (tail)
|
2010-06-08 16:28:45 +02:00
|
|
|
memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
|
2010-05-20 10:43:18 +02:00
|
|
|
}
|
|
|
|
|
2016-01-18 16:36:09 +01:00
|
|
|
account_pipe_buffers(pipe, pipe->buffers, nr_pages);
|
2010-05-20 10:43:18 +02:00
|
|
|
pipe->curbuf = 0;
|
|
|
|
kfree(pipe->bufs);
|
|
|
|
pipe->bufs = bufs;
|
2010-05-24 19:34:43 +02:00
|
|
|
pipe->buffers = nr_pages;
|
|
|
|
return nr_pages * PAGE_SIZE;
|
2010-05-20 10:43:18 +02:00
|
|
|
}
|
|
|
|
|
2010-06-03 14:54:39 +02:00
|
|
|
/*
|
|
|
|
* Currently we rely on the pipe array holding a power-of-2 number
|
|
|
|
* of pages.
|
|
|
|
*/
|
|
|
|
static inline unsigned int round_pipe_size(unsigned int size)
|
|
|
|
{
|
|
|
|
unsigned long nr_pages;
|
|
|
|
|
|
|
|
nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
|
|
return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This should work even if CONFIG_PROC_FS isn't set, as proc_dointvec_minmax
|
|
|
|
* will return an error.
|
|
|
|
*/
|
|
|
|
int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
|
|
|
|
size_t *lenp, loff_t *ppos)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
|
|
|
|
if (ret < 0 || !write)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
pipe_max_size = round_pipe_size(pipe_max_size);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-11-29 01:27:19 +01:00
|
|
|
/*
|
|
|
|
* After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
|
|
|
|
* location, so checking ->i_pipe is not enough to verify that this is a
|
|
|
|
* pipe.
|
|
|
|
*/
|
|
|
|
struct pipe_inode_info *get_pipe_info(struct file *file)
|
|
|
|
{
|
2013-03-21 16:16:56 +01:00
|
|
|
return file->f_op == &pipefifo_fops ? file->private_data : NULL;
|
2010-11-29 01:27:19 +01:00
|
|
|
}
|
|
|
|
|
2010-05-20 10:43:18 +02:00
|
|
|
long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
|
|
{
|
|
|
|
struct pipe_inode_info *pipe;
|
|
|
|
long ret;
|
|
|
|
|
2010-11-28 23:09:57 +01:00
|
|
|
pipe = get_pipe_info(file);
|
2010-05-20 10:43:18 +02:00
|
|
|
if (!pipe)
|
|
|
|
return -EBADF;
|
|
|
|
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_lock(pipe);
|
2010-05-20 10:43:18 +02:00
|
|
|
|
|
|
|
switch (cmd) {
|
2010-05-24 19:34:43 +02:00
|
|
|
case F_SETPIPE_SZ: {
|
2010-06-03 14:54:39 +02:00
|
|
|
unsigned int size, nr_pages;
|
2010-05-24 19:34:43 +02:00
|
|
|
|
2010-06-03 14:54:39 +02:00
|
|
|
size = round_pipe_size(arg);
|
|
|
|
nr_pages = size >> PAGE_SHIFT;
|
2010-05-24 19:34:43 +02:00
|
|
|
|
2010-06-09 09:27:57 +02:00
|
|
|
ret = -EINVAL;
|
|
|
|
if (!nr_pages)
|
|
|
|
goto out;
|
|
|
|
|
2010-06-03 14:54:39 +02:00
|
|
|
if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) {
|
2010-06-01 12:42:12 +02:00
|
|
|
ret = -EPERM;
|
2010-05-26 17:54:39 +02:00
|
|
|
goto out;
|
2016-01-18 16:36:09 +01:00
|
|
|
} else if ((too_many_pipe_buffers_hard(pipe->user) ||
|
|
|
|
too_many_pipe_buffers_soft(pipe->user)) &&
|
|
|
|
!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
|
|
|
|
ret = -EPERM;
|
|
|
|
goto out;
|
2010-05-26 17:54:39 +02:00
|
|
|
}
|
2010-06-03 14:54:39 +02:00
|
|
|
ret = pipe_set_size(pipe, nr_pages);
|
2010-05-20 10:43:18 +02:00
|
|
|
break;
|
2010-05-24 19:34:43 +02:00
|
|
|
}
|
2010-05-20 10:43:18 +02:00
|
|
|
case F_GETPIPE_SZ:
|
2010-05-24 19:34:43 +02:00
|
|
|
ret = pipe->buffers * PAGE_SIZE;
|
2010-05-20 10:43:18 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-05-26 17:54:39 +02:00
|
|
|
out:
|
2013-03-21 17:24:01 +01:00
|
|
|
__pipe_unlock(pipe);
|
2010-05-20 10:43:18 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-01-07 07:49:50 +01:00
|
|
|
static const struct super_operations pipefs_ops = {
|
|
|
|
.destroy_inode = free_inode_nonrcu,
|
2011-11-01 01:10:04 +01:00
|
|
|
.statfs = simple_statfs,
|
2011-01-07 07:49:50 +01:00
|
|
|
};
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
/*
|
|
|
|
* pipefs should _never_ be mounted by userland - too much of security hassle,
|
|
|
|
* no real gain from having the whole whorehouse mounted. So we don't need
|
|
|
|
* any operations on the root directory. However, we need a non-trivial
|
|
|
|
* d_name - pipe: will go nicely and kill the special-casing in procfs.
|
|
|
|
*/
|
2010-07-25 21:47:46 +02:00
|
|
|
static struct dentry *pipefs_mount(struct file_system_type *fs_type,
|
|
|
|
int flags, const char *dev_name, void *data)
|
2005-04-17 00:20:36 +02:00
|
|
|
{
|
2011-01-12 22:59:34 +01:00
|
|
|
return mount_pseudo(fs_type, "pipe:", &pipefs_ops,
|
|
|
|
&pipefs_dentry_operations, PIPEFS_MAGIC);
|
2005-04-17 00:20:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct file_system_type pipe_fs_type = {
|
|
|
|
.name = "pipefs",
|
2010-07-25 21:47:46 +02:00
|
|
|
.mount = pipefs_mount,
|
2005-04-17 00:20:36 +02:00
|
|
|
.kill_sb = kill_anon_super,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int __init init_pipe_fs(void)
|
|
|
|
{
|
|
|
|
int err = register_filesystem(&pipe_fs_type);
|
2006-04-11 13:57:45 +02:00
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
if (!err) {
|
|
|
|
pipe_mnt = kern_mount(&pipe_fs_type);
|
|
|
|
if (IS_ERR(pipe_mnt)) {
|
|
|
|
err = PTR_ERR(pipe_mnt);
|
|
|
|
unregister_filesystem(&pipe_fs_type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
fs_initcall(init_pipe_fs);
|