1 2#include <linux/wait.h> 3#include <linux/backing-dev.h> 4#include <linux/fs.h> 5#include <linux/sched.h> 6#include <linux/module.h> 7 8int bdi_init(struct backing_dev_info *bdi) 9{ 10 int i; 11 int err; 12 13 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) { 14 err = percpu_counter_init_irq(&bdi->bdi_stat[i], 0); 15 if (err) 16 goto err; 17 } 18 19 bdi->dirty_exceeded = 0; 20 err = prop_local_init_percpu(&bdi->completions); 21 22 if (err) { 23err: 24 while (i--) 25 percpu_counter_destroy(&bdi->bdi_stat[i]); 26 } 27 28 return err; 29} 30EXPORT_SYMBOL(bdi_init); 31 32void bdi_destroy(struct backing_dev_info *bdi) 33{ 34 int i; 35 36 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) 37 percpu_counter_destroy(&bdi->bdi_stat[i]); 38 39 prop_local_destroy_percpu(&bdi->completions); 40} 41EXPORT_SYMBOL(bdi_destroy); 42 43static wait_queue_head_t congestion_wqh[2] = { 44 __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]), 45 __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1]) 46 }; 47 48 49void clear_bdi_congested(struct backing_dev_info *bdi, int rw) 50{ 51 enum bdi_state bit; 52 wait_queue_head_t *wqh = &congestion_wqh[rw]; 53 54 bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; 55 clear_bit(bit, &bdi->state); 56 smp_mb__after_clear_bit(); 57 if (waitqueue_active(wqh)) 58 wake_up(wqh); 59} 60EXPORT_SYMBOL(clear_bdi_congested); 61 62void set_bdi_congested(struct backing_dev_info *bdi, int rw) 63{ 64 enum bdi_state bit; 65 66 bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; 67 set_bit(bit, &bdi->state); 68} 69EXPORT_SYMBOL(set_bdi_congested); 70 71/** 72 * congestion_wait - wait for a backing_dev to become uncongested 73 * @rw: READ or WRITE 74 * @timeout: timeout in jiffies 75 * 76 * Waits for up to @timeout jiffies for a backing_dev (any backing_dev) to exit 77 * write congestion. If no backing_devs are congested then just wait for the 78 * next write to be completed. 79 */ 80long congestion_wait(int rw, long timeout) 81{ 82 long ret; 83 DEFINE_WAIT(wait); 84 wait_queue_head_t *wqh = &congestion_wqh[rw]; 85 86 prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); 87 ret = io_schedule_timeout(timeout); 88 finish_wait(wqh, &wait); 89 return ret; 90} 91EXPORT_SYMBOL(congestion_wait); 92