fs/exfat: unlock pages under readonly status
authorShiyong Li <a22381@motorola.com>
Sat, 9 Dec 2017 01:30:22 +0000 (17:30 -0800)
committerxiest1 <xiest1@lenovo.com>
Tue, 5 Nov 2019 09:30:25 +0000 (17:30 +0800)
The ->writepage should unlock its page before returning the results.
Otherwise, evict_inode can be hanged while truncating pages.

- Backtrace -

(__schedule+0x3dc/0x908) from [<c0b67854>] (io_schedule+0x6c/0x94)
(io_schedule+0x6c/0x94) from [<c01ce2dc>] (sleep_on_page+0x8/0x10)
(sleep_on_page+0x8/0x10) from [<c0b64e70>] (__wait_on_bit_lock+0x6c/0xb8)
(__wait_on_bit_lock+0x6c/0xb8) from [<c01ce418>] (__lock_page+0x90/0x98)
(__lock_page+0x90/0x98) from [<c01dcae8>] (truncate_inode_pages_range+0x360/0x37c)
(truncate_inode_pages_range+0x360/0x37c) from [<c01dcb1c>] (truncate_inode_pages+0x18/0x20)
(truncate_inode_pages+0x18/0x20) from [<c0304618>] (exfat_evict_inode+0x18/0xb0)
(exfat_evict_inode+0x18/0xb0) from [<c0228590>] (evict+0x94/0x178)
(evict+0x94/0x178) from [<c02286a4>] (dispose_list+0x30/0x40)
(dispose_list+0x30/0x40) from [<c022924c>] (evict_inodes+0xc8/0xd0)
(evict_inodes+0xc8/0xd0) from [<c0212964>] (generic_shutdown_super+0x44/0xc4)
(generic_shutdown_super+0x44/0xc4) from [<c0212bd4>] (kill_block_super+0x18/0x68)
(kill_block_super+0x18/0x68) from [<c0212f3c>] (deactivate_locked_super+0x48/0x64)
(deactivate_locked_super+0x48/0x64) from [<c022d660>] (SyS_umount+0x90/0x390)

Change-Id: I0a9caebeceda503c72e365957b1bf97d74f3de89
Signed-off-by: Jaegeuk Kim <jaegeuk@motorola.com>
Signed-off-by: Shiyong Li <a22381@motorola.com>
Reviewed-on: https://gerrit.mot.com/1102178
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Igor Kovalenko <igork@motorola.com>
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1276879
Reviewed-by: Hua Tan <tanhua1@motorola.com>
fs/exfat/exfat_super.c

index c2f636baffb8f8521cab26d430e37d4e0590f6e7..da464a11474b7c72667354b61ffc87838cf8819f 100644 (file)
@@ -1617,8 +1617,11 @@ static int exfat_readpages(struct file *file, struct address_space *mapping,
 
 static int exfat_writepage(struct page *page, struct writeback_control *wbc)
 {
-       if (exfat_readonly(page->mapping->host->i_sb))
-               return -EROFS;
+       if (exfat_readonly(page->mapping->host->i_sb)) {
+               unlock_page(page);
+               SetPageError(page);
+               return 0;
+       }
        return block_write_full_page(page, exfat_get_block, wbc);
 }