• Zhihao Cheng's avatar
    ubifs: ubifs_writepage: Mark page dirty after writing inode failed · fb8bc4c7
    Zhihao Cheng authored
    There are two states for ubifs writing pages:
    1. Dirty, Private
    2. Not Dirty, Not Private
    
    There is a third possibility which maybe related to [1] that page is
    private but not dirty caused by following process:
    
              PA
    lock(page)
    ubifs_write_end
      attach_page_private		// set Private
        __set_page_dirty_nobuffers	// set Dirty
    unlock(page)
    
    write_cache_pages
      lock(page)
      clear_page_dirty_for_io(page)	// clear Dirty
      ubifs_writepage
        write_inode
        // fail, goto out, following codes are not executed
        // do_writepage
        //   set_page_writeback 	// set Writeback
        //   detach_page_private	// clear Private
        //   end_page_writeback 	// clear Writeback
        out:
        unlock(page)		// Private, Not Dirty
    
                                           PB
    				ksys_fadvise64_64
    				  generic_fadvise
    				     invalidate_inode_page
    				     // page is neither Dirty nor Writeback
    				       invalidate_complete_page
    				       // page_has_private is true
    					 try_to_release_page
    					   ubifs_releasepage
    					     ubifs_assert(c, 0) !!!
    
    Then we may get following assertion failed:
      UBIFS error (ubi0:0 pid 1492): ubifs_assert_failed [ubifs]:
      UBIFS assert failed: 0, in fs/ubifs/file.c:1499
      UBIFS warning (ubi0:0 pid 1492): ubifs_ro_mode [ubifs]:
      switched to read-only mode, error -22
      CPU: 2 PID: 1492 Comm: aa Not tainted 5.16.0-rc2-00012-g7bb767dee0ba-dirty
      Call Trace:
        dump_stack+0x13/0x1b
        ubifs_ro_mode+0x54/0x60 [ubifs]
        ubifs_assert_failed+0x4b/0x80 [ubifs]
        ubifs_releasepage+0x7e/0x1e0 [ubifs]
        try_to_release_page+0x57/0xe0
        invalidate_inode_page+0xfb/0x130
        invalidate_mapping_pagevec+0x12/0x20
        generic_fadvise+0x303/0x3c0
        vfs_fadvise+0x35/0x40
        ksys_fadvise64_64+0x4c/0xb0
    
    Jump [2] to find a reproducer.
    
    [1] https://linux-mtd.infradead.narkive.com/NQoBeT1u/patch-rfc-ubifs-fix-assert-failed-in-ubifs-set-page-dirty
    [2] https://bugzilla.kernel.org/show_bug.cgi?id=215357
    
    Fixes: 1e51764a ("UBIFS: add new flash file system")
    Signed-off-by: default avatarZhihao Cheng <chengzhihao1@huawei.com>
    Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
    fb8bc4c7
file.c 46.6 KB