2005-04-17 02:20:36 +04:00
/*
* linux / fs / fifo . c
*
* written by Paul H . Hargrove
*
* Fixes :
* 10 - 06 - 1999 , AV : fixed OOM handling in fifo_open ( ) , moved
* initialization there , switched to external
* allocation of pipe_inode_info .
*/
# include <linux/mm.h>
# include <linux/slab.h>
# include <linux/fs.h>
Detach sched.h from mm.h
First thing mm.h does is including sched.h solely for can_do_mlock() inline
function which has "current" dereference inside. By dealing with can_do_mlock()
mm.h can be detached from sched.h which is good. See below, why.
This patch
a) removes unconditional inclusion of sched.h from mm.h
b) makes can_do_mlock() normal function in mm/mlock.c
c) exports can_do_mlock() to not break compilation
d) adds sched.h inclusions back to files that were getting it indirectly.
e) adds less bloated headers to some files (asm/signal.h, jiffies.h) that were
getting them indirectly
Net result is:
a) mm.h users would get less code to open, read, preprocess, parse, ... if
they don't need sched.h
b) sched.h stops being dependency for significant number of files:
on x86_64 allmodconfig touching sched.h results in recompile of 4083 files,
after patch it's only 3744 (-8.3%).
Cross-compile tested on
all arm defconfigs, all mips defconfigs, all powerpc defconfigs,
alpha alpha-up
arm
i386 i386-up i386-defconfig i386-allnoconfig
ia64 ia64-up
m68k
mips
parisc parisc-up
powerpc powerpc-up
s390 s390-up
sparc sparc-up
sparc64 sparc64-up
um-x86_64
x86_64 x86_64-up x86_64-defconfig x86_64-allnoconfig
as well as my two usual configs.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-21 01:22:52 +04:00
# include <linux/sched.h>
2005-04-17 02:20:36 +04:00
# include <linux/pipe_fs_i.h>
2006-04-10 17:18:35 +04:00
static void wait_for_partner ( struct inode * inode , unsigned int * cnt )
2005-04-17 02:20:36 +04:00
{
int cur = * cnt ;
2006-04-10 17:18:35 +04:00
while ( cur = = * cnt ) {
pipe_wait ( inode - > i_pipe ) ;
if ( signal_pending ( current ) )
2005-04-17 02:20:36 +04:00
break ;
}
}
static void wake_up_partner ( struct inode * inode )
{
2006-04-11 15:53:10 +04:00
wake_up_interruptible ( & inode - > i_pipe - > wait ) ;
2005-04-17 02:20:36 +04:00
}
static int fifo_open ( struct inode * inode , struct file * filp )
{
2006-04-11 15:53:33 +04:00
struct pipe_inode_info * pipe ;
2005-04-17 02:20:36 +04:00
int ret ;
2006-04-11 15:53:10 +04:00
mutex_lock ( & inode - > i_mutex ) ;
2006-04-11 15:53:33 +04:00
pipe = inode - > i_pipe ;
if ( ! pipe ) {
2005-04-17 02:20:36 +04:00
ret = - ENOMEM ;
2006-04-11 15:53:33 +04:00
pipe = alloc_pipe_info ( inode ) ;
if ( ! pipe )
2005-04-17 02:20:36 +04:00
goto err_nocleanup ;
2006-04-11 15:53:33 +04:00
inode - > i_pipe = pipe ;
2005-04-17 02:20:36 +04:00
}
filp - > f_version = 0 ;
/* We can only do regular read/write on fifos */
filp - > f_mode & = ( FMODE_READ | FMODE_WRITE ) ;
switch ( filp - > f_mode ) {
2008-09-02 23:28:45 +04:00
case FMODE_READ :
2005-04-17 02:20:36 +04:00
/*
* O_RDONLY
* POSIX .1 says that O_NONBLOCK means return with the FIFO
* opened , even when there is no process writing the FIFO .
*/
2008-07-01 16:16:09 +04:00
filp - > f_op = & read_pipefifo_fops ;
2006-04-11 15:53:33 +04:00
pipe - > r_counter + + ;
if ( pipe - > readers + + = = 0 )
2005-04-17 02:20:36 +04:00
wake_up_partner ( inode ) ;
2006-04-11 15:53:33 +04:00
if ( ! pipe - > writers ) {
2005-04-17 02:20:36 +04:00
if ( ( filp - > f_flags & O_NONBLOCK ) ) {
/* suppress POLLHUP until we have
* seen a writer */
2006-04-11 15:53:33 +04:00
filp - > f_version = pipe - > w_counter ;
2005-04-17 02:20:36 +04:00
} else
{
2006-04-11 15:53:33 +04:00
wait_for_partner ( inode , & pipe - > w_counter ) ;
2005-04-17 02:20:36 +04:00
if ( signal_pending ( current ) )
goto err_rd ;
}
}
break ;
2008-09-02 23:28:45 +04:00
case FMODE_WRITE :
2005-04-17 02:20:36 +04:00
/*
* O_WRONLY
* POSIX .1 says that O_NONBLOCK means return - 1 with
* errno = ENXIO when there is no process reading the FIFO .
*/
ret = - ENXIO ;
2006-04-11 15:53:33 +04:00
if ( ( filp - > f_flags & O_NONBLOCK ) & & ! pipe - > readers )
2005-04-17 02:20:36 +04:00
goto err ;
2008-07-01 16:16:09 +04:00
filp - > f_op = & write_pipefifo_fops ;
2006-04-11 15:53:33 +04:00
pipe - > w_counter + + ;
if ( ! pipe - > writers + + )
2005-04-17 02:20:36 +04:00
wake_up_partner ( inode ) ;
2006-04-11 15:53:33 +04:00
if ( ! pipe - > readers ) {
wait_for_partner ( inode , & pipe - > r_counter ) ;
2005-04-17 02:20:36 +04:00
if ( signal_pending ( current ) )
goto err_wr ;
}
break ;
2008-09-02 23:28:45 +04:00
case FMODE_READ | FMODE_WRITE :
2005-04-17 02:20:36 +04:00
/*
* 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 .
*/
2008-07-01 16:16:09 +04:00
filp - > f_op = & rdwr_pipefifo_fops ;
2005-04-17 02:20:36 +04:00
2006-04-11 15:53:33 +04:00
pipe - > readers + + ;
pipe - > writers + + ;
pipe - > r_counter + + ;
pipe - > w_counter + + ;
if ( pipe - > readers = = 1 | | pipe - > writers = = 1 )
2005-04-17 02:20:36 +04:00
wake_up_partner ( inode ) ;
break ;
default :
ret = - EINVAL ;
goto err ;
}
/* Ok! */
2006-04-11 15:53:10 +04:00
mutex_unlock ( & inode - > i_mutex ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
err_rd :
2006-04-11 15:53:33 +04:00
if ( ! - - pipe - > readers )
wake_up_interruptible ( & pipe - > wait ) ;
2005-04-17 02:20:36 +04:00
ret = - ERESTARTSYS ;
goto err ;
err_wr :
2006-04-11 15:53:33 +04:00
if ( ! - - pipe - > writers )
wake_up_interruptible ( & pipe - > wait ) ;
2005-04-17 02:20:36 +04:00
ret = - ERESTARTSYS ;
goto err ;
err :
2006-04-11 15:53:33 +04:00
if ( ! pipe - > readers & & ! pipe - > writers )
2005-04-17 02:20:36 +04:00
free_pipe_info ( inode ) ;
err_nocleanup :
2006-04-11 15:53:10 +04:00
mutex_unlock ( & inode - > i_mutex ) ;
2005-04-17 02:20:36 +04:00
return ret ;
}
/*
* Dummy default file - operations : the only thing this does
* is contain the open that then fills in the correct operations
* depending on the access mode of the file . . .
*/
2006-03-28 13:56:42 +04:00
const struct file_operations def_fifo_fops = {
2008-07-01 16:16:09 +04:00
. open = fifo_open , /* will set read_ or write_pipefifo_fops */
2005-04-17 02:20:36 +04:00
} ;