2006-10-20 10:28:16 +04:00
# include <linux/wait.h>
# include <linux/backing-dev.h>
# include <linux/fs.h>
# include <linux/sched.h>
# include <linux/module.h>
static wait_queue_head_t congestion_wqh [ 2 ] = {
__WAIT_QUEUE_HEAD_INITIALIZER ( congestion_wqh [ 0 ] ) ,
__WAIT_QUEUE_HEAD_INITIALIZER ( congestion_wqh [ 1 ] )
} ;
void clear_bdi_congested ( struct backing_dev_info * bdi , int rw )
{
enum bdi_state bit ;
wait_queue_head_t * wqh = & congestion_wqh [ rw ] ;
bit = ( rw = = WRITE ) ? BDI_write_congested : BDI_read_congested ;
clear_bit ( bit , & bdi - > state ) ;
smp_mb__after_clear_bit ( ) ;
if ( waitqueue_active ( wqh ) )
wake_up ( wqh ) ;
}
EXPORT_SYMBOL ( clear_bdi_congested ) ;
void set_bdi_congested ( struct backing_dev_info * bdi , int rw )
{
enum bdi_state bit ;
bit = ( rw = = WRITE ) ? BDI_write_congested : BDI_read_congested ;
set_bit ( bit , & bdi - > state ) ;
}
EXPORT_SYMBOL ( set_bdi_congested ) ;
/**
* congestion_wait - wait for a backing_dev to become uncongested
* @ rw : READ or WRITE
* @ timeout : timeout in jiffies
*
* Waits for up to @ timeout jiffies for a backing_dev ( any backing_dev ) to exit
* write congestion . If no backing_devs are congested then just wait for the
* next write to be completed .
*/
long congestion_wait ( int rw , long timeout )
{
long ret ;
DEFINE_WAIT ( wait ) ;
wait_queue_head_t * wqh = & congestion_wqh [ rw ] ;
prepare_to_wait ( wqh , & wait , TASK_UNINTERRUPTIBLE ) ;
ret = io_schedule_timeout ( timeout ) ;
finish_wait ( wqh , & wait ) ;
return ret ;
}
EXPORT_SYMBOL ( congestion_wait ) ;
2007-03-17 00:38:26 +03:00
long congestion_wait_interruptible ( int rw , long timeout )
{
long ret ;
DEFINE_WAIT ( wait ) ;
wait_queue_head_t * wqh = & congestion_wqh [ rw ] ;
prepare_to_wait ( wqh , & wait , TASK_INTERRUPTIBLE ) ;
if ( signal_pending ( current ) )
ret = - ERESTARTSYS ;
else
ret = io_schedule_timeout ( timeout ) ;
finish_wait ( wqh , & wait ) ;
return ret ;
}
EXPORT_SYMBOL ( congestion_wait_interruptible ) ;
2006-10-20 10:28:16 +04:00
/**
* congestion_end - wake up sleepers on a congested backing_dev_info
* @ rw : READ or WRITE
*/
void congestion_end ( int rw )
{
wait_queue_head_t * wqh = & congestion_wqh [ rw ] ;
if ( waitqueue_active ( wqh ) )
wake_up ( wqh ) ;
}
EXPORT_SYMBOL ( congestion_end ) ;