• Paul Taysom's avatar
    mmc: reordered shutdown sequence in mmc_bld_remove_req · fdfa20c1
    Paul Taysom authored
    We had a multi-partition SD-Card with two ext2 file systems. The partition
    table was getting overwritten by a race between the card removal and
    the unmount of the 2nd ext2 partition.
    
    What was observed:
    1. Suspend/resume would call to remove the device. The clearing
       of the device information is done asynchronously.
    2. A request is made to unmount the file system (this is called
       after the removal has started).
    3. The remapping table was cleared by the asynchronous part of
       the device removal.
    4. A write request to the super block (block 0 of the partition)
       was sent down and instead of being remapped to the partition
       offset, it was remapped to block 0 of the device which is where
       the partition table is located.
    5. Write was queued and written resulting in the overwriting
       of the partition table with the ext2 super block.
    6. The mmc_queue is cleaned up.
    
    The mmc card device driver used to access SD cards, was calling del_gendisk
    before calling mmc_cleanup-queue. The comment in the mmc_blk_remove_req
    code indicated that it expected del_gendisk to block all further requests
    from being queued but it doesn't. The mmc driver uses the presences of the
    mmc_queue to determine if the request should be queued.
    
    The fix was to clean up the mmc_queue before the rest of the
    the delete partition code is called.
    
    This prevents the overwriting of the partition table.
    
    However, the umount gets an error trying to write the super block.
    The umount should be issued before the device is removed but that
    is not always possible. The umount is still needed to cleanup other
    data structures.
    
    Addresses the problem described in http://crbug.com/240815Signed-off-by: default avatarPaul Taysom <taysom@chromium.org>
    Signed-off-by: default avatarChris Ball <cjb@laptop.org>
    fdfa20c1
block.c 61.7 KB