diff options
Diffstat (limited to 'fs/buffer.c')
| -rw-r--r-- | fs/buffer.c | 23 | 
1 files changed, 15 insertions, 8 deletions
| diff --git a/fs/buffer.c b/fs/buffer.c index c8c2b7d8b8d6..109f55196866 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -39,12 +39,12 @@  #include <linux/buffer_head.h>  #include <linux/task_io_accounting_ops.h>  #include <linux/bio.h> -#include <linux/notifier.h>  #include <linux/cpu.h>  #include <linux/bitops.h>  #include <linux/mpage.h>  #include <linux/bit_spinlock.h>  #include <linux/pagevec.h> +#include <linux/sched/mm.h>  #include <trace/events/block.h>  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); @@ -813,12 +813,16 @@ struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size,  		bool retry)  {  	struct buffer_head *bh, *head; -	gfp_t gfp = GFP_NOFS; +	gfp_t gfp = GFP_NOFS | __GFP_ACCOUNT;  	long offset; +	struct mem_cgroup *memcg;  	if (retry)  		gfp |= __GFP_NOFAIL; +	memcg = get_mem_cgroup_from_page(page); +	memalloc_use_memcg(memcg); +  	head = NULL;  	offset = PAGE_SIZE;  	while ((offset -= size) >= 0) { @@ -835,6 +839,9 @@ struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size,  		/* Link the buffer to its page */  		set_bh_page(bh, page, offset);  	} +out: +	memalloc_unuse_memcg(); +	mem_cgroup_put(memcg);  	return head;  /*   * In case anything failed, we just free everything we got. @@ -848,7 +855,7 @@ no_grow:  		} while (head);  	} -	return NULL; +	goto out;  }  EXPORT_SYMBOL_GPL(alloc_page_buffers); @@ -3053,11 +3060,6 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,  	 */  	bio = bio_alloc(GFP_NOIO, 1); -	if (wbc) { -		wbc_init_bio(wbc, bio); -		wbc_account_io(wbc, bh->b_page, bh->b_size); -	} -  	bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);  	bio_set_dev(bio, bh->b_bdev);  	bio->bi_write_hint = write_hint; @@ -3077,6 +3079,11 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,  		op_flags |= REQ_PRIO;  	bio_set_op_attrs(bio, op, op_flags); +	if (wbc) { +		wbc_init_bio(wbc, bio); +		wbc_account_io(wbc, bh->b_page, bh->b_size); +	} +  	submit_bio(bio);  	return 0;  } |