diff options
Diffstat (limited to 'drivers/md/dm-bufio.c')
| -rw-r--r-- | drivers/md/dm-bufio.c | 53 | 
1 files changed, 45 insertions, 8 deletions
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 173cbb20d10..d724459860d 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -104,6 +104,8 @@ struct dm_bufio_client {  	struct list_head reserved_buffers;  	unsigned need_reserved_buffers; +	unsigned minimum_buffers; +  	struct hlist_head *cache_hash;  	wait_queue_head_t free_buffer_wait; @@ -538,7 +540,7 @@ static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block,  	bio_init(&b->bio);  	b->bio.bi_io_vec = b->bio_vec;  	b->bio.bi_max_vecs = DM_BUFIO_INLINE_VECS; -	b->bio.bi_sector = block << b->c->sectors_per_block_bits; +	b->bio.bi_iter.bi_sector = block << b->c->sectors_per_block_bits;  	b->bio.bi_bdev = b->c->bdev;  	b->bio.bi_end_io = end_io; @@ -605,9 +607,9 @@ static void write_endio(struct bio *bio, int error)  	BUG_ON(!test_bit(B_WRITING, &b->state)); -	smp_mb__before_clear_bit(); +	smp_mb__before_atomic();  	clear_bit(B_WRITING, &b->state); -	smp_mb__after_clear_bit(); +	smp_mb__after_atomic();  	wake_up_bit(&b->state, B_WRITING);  } @@ -861,8 +863,8 @@ static void __get_memory_limit(struct dm_bufio_client *c,  	buffers = dm_bufio_cache_size_per_client >>  		  (c->sectors_per_block_bits + SECTOR_SHIFT); -	if (buffers < DM_BUFIO_MIN_BUFFERS) -		buffers = DM_BUFIO_MIN_BUFFERS; +	if (buffers < c->minimum_buffers) +		buffers = c->minimum_buffers;  	*limit_buffers = buffers;  	*threshold_buffers = buffers * DM_BUFIO_WRITEBACK_PERCENT / 100; @@ -995,9 +997,9 @@ static void read_endio(struct bio *bio, int error)  	BUG_ON(!test_bit(B_READING, &b->state)); -	smp_mb__before_clear_bit(); +	smp_mb__before_atomic();  	clear_bit(B_READING, &b->state); -	smp_mb__after_clear_bit(); +	smp_mb__after_atomic();  	wake_up_bit(&b->state, B_READING);  } @@ -1350,6 +1352,34 @@ retry:  }  EXPORT_SYMBOL_GPL(dm_bufio_release_move); +/* + * Free the given buffer. + * + * This is just a hint, if the buffer is in use or dirty, this function + * does nothing. + */ +void dm_bufio_forget(struct dm_bufio_client *c, sector_t block) +{ +	struct dm_buffer *b; + +	dm_bufio_lock(c); + +	b = __find(c, block); +	if (b && likely(!b->hold_count) && likely(!b->state)) { +		__unlink_buffer(b); +		__free_buffer_wake(b); +	} + +	dm_bufio_unlock(c); +} +EXPORT_SYMBOL(dm_bufio_forget); + +void dm_bufio_set_minimum_buffers(struct dm_bufio_client *c, unsigned n) +{ +	c->minimum_buffers = n; +} +EXPORT_SYMBOL(dm_bufio_set_minimum_buffers); +  unsigned dm_bufio_get_block_size(struct dm_bufio_client *c)  {  	return c->block_size; @@ -1511,7 +1541,7 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign  	BUG_ON(block_size < 1 << SECTOR_SHIFT ||  	       (block_size & (block_size - 1))); -	c = kmalloc(sizeof(*c), GFP_KERNEL); +	c = kzalloc(sizeof(*c), GFP_KERNEL);  	if (!c) {  		r = -ENOMEM;  		goto bad_client; @@ -1546,6 +1576,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign  	INIT_LIST_HEAD(&c->reserved_buffers);  	c->need_reserved_buffers = reserved_buffers; +	c->minimum_buffers = DM_BUFIO_MIN_BUFFERS; +  	init_waitqueue_head(&c->free_buffer_wait);  	c->async_write_error = 0; @@ -1717,6 +1749,11 @@ static int __init dm_bufio_init(void)  {  	__u64 mem; +	dm_bufio_allocated_kmem_cache = 0; +	dm_bufio_allocated_get_free_pages = 0; +	dm_bufio_allocated_vmalloc = 0; +	dm_bufio_current_allocated = 0; +  	memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches);  	memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names);  | 
