• Thomas Betker's avatar
    jffs2: Fix lock acquisition order bug in jffs2_write_begin · e3bb00e3
    Thomas Betker authored
    commit 5ffd3412 upstream.
    
    jffs2_write_begin() first acquires the page lock, then f->sem. This
    causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first
    acquires f->sem, then the page lock:
    
    jffs2_garbage_collect_live
        mutex_lock(&f->sem)                         (A)
        jffs2_garbage_collect_dnode
            jffs2_gc_fetch_page
                read_cache_page_async
                    do_read_cache_page
                        lock_page(page)             (B)
    
    jffs2_write_begin
        grab_cache_page_write_begin
            find_lock_page
                lock_page(page)                     (B)
        mutex_lock(&f->sem)                         (A)
    
    We fix this by restructuring jffs2_write_begin() to take f->sem before
    the page lock. However, we make sure that f->sem is not held when
    calling jffs2_reserve_space(), as this is not permitted by the locking
    rules.
    
    The deadlock above was observed multiple times on an SoC with a dual
    ARMv7 (Cortex-A9), running the long-term 3.4.11 kernel; it occurred
    when using scp to copy files from a host system to the ARM target
    system. The fix was heavily tested on the same target system.
    Signed-off-by: default avatarThomas Betker <thomas.betker@rohde-schwarz.com>
    Acked-by: default avatarJoakim Tjernlund <Joakim.Tjernlund@transmode.se>
    Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
    [bwh: Backported to 3.2:
     - Adjust context
     - Use D1(printk(KERN_DEBUG ...)) instead of jffs2_dbg(1, ...)]
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    e3bb00e3
file.c 9.37 KB