On Mon, Feb 01, 2021 at 02:07:22AM -0800, syzbot wrote: > Hello, > > syzbot found the following issue on: Thank you, syzbot. This is legit. But annoying. > BUG: Bad page state in process syz-executor.4 pfn:369c1 > page:0000000025f15602 refcount:0 mapcount:0 mapping:0000000000000000 index:0x3d pfn:0x369c1 > flags: 0xfff00000020005(locked|uptodate|mappedtodisk) > raw: 00fff00000020005 dead000000000100 dead000000000122 0000000000000000 > raw: 000000000000003d 0000000000000000 00000000ffffffff 0000000000000000 > page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set Having the uptodate and mappedtodisk flags set is fine. It's the 'locked' flag which is triggering the bug. Here's the code in question: truncated: error = AOP_TRUNCATED_PAGE; put_page(page); unlock: unlock_page(page); So we're going to unlock the page! But we actually have to unlock it first, before the refcount goes to zero. Does anyone see a better way than this? (Andrew, this is a fix to "mm/filemap: add filemap_range_uptodate") diff --git a/mm/filemap.c b/mm/filemap.c index bc4c9ac0ef4a..a945102b55c2 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2322,8 +2322,9 @@ static int filemap_update_page(struct kiocb *iocb, put_page(page); return error; truncated: - error = AOP_TRUNCATED_PAGE; + unlock_page(page); put_page(page); + return AOP_TRUNCATED_PAGE; unlock: unlock_page(page); return error;