diff options
author | Matthew Wilcox <willy@infradead.org> | 2017-10-13 18:58:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-13 19:18:33 -0400 |
commit | f892760aa66a2d657deaf59538fb69433036767c (patch) | |
tree | 3a1cbccecb6c363e4fcc922127867ca89972e655 /include/linux/buffer_head.h | |
parent | e8c97af0c1f23d6ffedcaa3918861f2595e1db62 (diff) |
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().
[akpm@linux-foundation.org: s/PAGE_SIZE/~0U/ per Linus and Matthew]
Link: http://lkml.kernel.org/r/20171006211541.GA7409@bombadil.infradead.org
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
Reported-by: Toshi Kani <toshi.kani@hpe.com>
Reported-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Tested-by: Toshi Kani <toshi.kani@hpe.com>
Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/buffer_head.h')
-rw-r--r-- | include/linux/buffer_head.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index c8dae555eccf..446b24cac67d 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
@@ -232,6 +232,7 @@ int generic_write_end(struct file *, struct address_space *, | |||
232 | loff_t, unsigned, unsigned, | 232 | loff_t, unsigned, unsigned, |
233 | struct page *, void *); | 233 | struct page *, void *); |
234 | void page_zero_new_buffers(struct page *page, unsigned from, unsigned to); | 234 | void page_zero_new_buffers(struct page *page, unsigned from, unsigned to); |
235 | void clean_page_buffers(struct page *page); | ||
235 | int cont_write_begin(struct file *, struct address_space *, loff_t, | 236 | int cont_write_begin(struct file *, struct address_space *, loff_t, |
236 | unsigned, unsigned, struct page **, void **, | 237 | unsigned, unsigned, struct page **, void **, |
237 | get_block_t *, loff_t *); | 238 | get_block_t *, loff_t *); |