FAILED: patch "[PATCH] fs/mpage.c: fix mpage_writepage() for pages with buffers" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
f892760aa66a2d657deaf59538fb69433036767cMon Sep 17 00:00:00 2001
From: Matthew Wilcox <[email protected]>
Date: Fri, 13 Oct 2017 15:58:15 -0700
Subject: [PATCH] fs/mpage.c: fix mpage_writepage() for pages with buffers
When using FAT on a block device which supports rw_page, we can hit BUG_ON(!PageLocked(page)) in try_to_free_buffers(). This is because we call clean_buffers() after unlocking the page we've written. Introduce a new clean_page_buffers() which cleans all buffers associated with a page and call it from within bdev_write_page().
fs/block_dev.c +4 -2
@@ -716,10 +716,12 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,set_page_writeback (page); result = ops->rw_page (bdev, sector +get_start_sect (bdev), page, true); -if (result) +if (result) {end_page_writeback (page); -else + }else { +clean_page_buffers (page);unlock_page (page); + }blk_queue_exit (bdev->bd_queue);return result; }
fs/mpage.c +11 -3
@@ -468,6 +468,16 @@ static void clean_buffers(struct page *page, unsigned first_unmapped)try_to_free_buffers (page); } +/* +* For situations where we want to clean all buffers attached to a page. +* We don't need to calculate how many buffers are attached to the page, +* we just need to specify a number larger than the maximum number of buffers. +*/ +void clean_page_buffers (struct page *page) +{ +clean_buffers (page, ~0U ); +} +static int __mpage_writepage (struct page *page,struct writeback_control *wbc,void *data) {
@@ -605,10 +615,8 @@ static int __mpage_writepage(struct page *page, struct writeback_control *wbc,if (bio ==NULL ) {if (first_unmapped == blocks_per_page) {if (!bdev_write_page (bdev, blocks[0 ] << (blkbits -9 ), - page, wbc)) { -clean_buffers (page, first_unmapped); + page, wbc)) goto out; - } } bio =mpage_alloc (bdev, blocks[0 ] << (blkbits -9 ),BIO_MAX_PAGES ,GFP_NOFS |__GFP_HIGH);
include/linux/buffer_head.h +1 -0
@@ -232,6 +232,7 @@ int generic_write_end(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page *, void *);void page_zero_new_buffers (struct page *page,unsigned from,unsigned to); +void clean_page_buffers (struct page *page);int cont_write_begin (struct file *,struct address_space *,loff_t ,unsigned ,unsigned ,struct page **,void **,get_block_t *,loff_t *);