• Filipe Manana's avatar
    btrfs: zoned: fix silent data loss after failure splitting ordered extent · adbd914d
    Filipe Manana authored
    On a zoned filesystem, sometimes we need to split an ordered extent into 3
    different ordered extents. The original ordered extent is shortened, at
    the front and at the rear, and we create two other new ordered extents to
    represent the trimmed parts of the original ordered extent.
    
    After adjusting the original ordered extent, we create an ordered extent
    to represent the pre-range, and that may fail with ENOMEM for example.
    After that we always try to create the ordered extent for the post-range,
    and if that happens to succeed we end up returning success to the caller
    as we overwrite the 'ret' variable which contained the previous error.
    
    This means we end up with a file range for which there is no ordered
    extent, which results in the range never getting a new file extent item
    pointing to the new data location. And since the split operation did
    not return an error, writeback does not fail and the inode's mapping is
    not flagged with an error, resulting in a subsequent fsync not reporting
    an error either.
    
    It's possibly very unlikely to have the creation of the post-range ordered
    extent succeed after the creation of the pre-range ordered extent failed,
    but it's not impossible.
    
    So fix this by making sure we only create the post-range ordered extent
    if there was no error creating the ordered extent for the pre-range.
    
    Fixes: d22002fd ("btrfs: zoned: split ordered extent when bio is sent")
    CC: stable@vger.kernel.org # 5.12+
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    adbd914d
ordered-data.c 28.1 KB