diff options
author | Omar Sandoval <osandov@fb.com> | 2020-04-16 14:46:13 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-10-01 13:18:04 +0200 |
commit | 1aa9de56d7626342343fa2d93a6923a6142c737e (patch) | |
tree | f61bb829d24f80189452b4c6151d418e904c24bd /drivers/vfio | |
parent | b3b21823d68e7e4b43201953cc500b02ab027034 (diff) | |
download | linux-stable-1aa9de56d7626342343fa2d93a6923a6142c737e.tar.gz linux-stable-1aa9de56d7626342343fa2d93a6923a6142c737e.tar.bz2 linux-stable-1aa9de56d7626342343fa2d93a6923a6142c737e.zip |
btrfs: fix double __endio_write_update_ordered in direct I/O
[ Upstream commit c36cac28cb94e58f7e21ff43bdc6064346dab32c ]
In btrfs_submit_direct(), if we fail to allocate the btrfs_dio_private,
we complete the ordered extent range. However, we don't mark that the
range doesn't need to be cleaned up from btrfs_direct_IO() until later.
Therefore, if we fail to allocate the btrfs_dio_private, we complete the
ordered extent range twice. We could fix this by updating
unsubmitted_oe_range earlier, but it's cleaner to reorganize the code so
that creating the btrfs_dio_private and submitting the bios are
separate, and once the btrfs_dio_private is created, cleanup always
happens through the btrfs_dio_private.
The logic around unsubmitted_oe_range_end and unsubmitted_oe_range_start
is really subtle. We have the following:
1. btrfs_direct_IO sets those two to the same value.
2. When we call __blockdev_direct_IO unless
btrfs_get_blocks_direct->btrfs_get_blocks_direct_write is called to
modify unsubmitted_oe_range_start so that start < end. Cleanup
won't happen.
3. We come into btrfs_submit_direct - if it dip allocation fails we'd
return with oe_range_end now modified so cleanup will happen.
4. If we manage to allocate the dip we reset the unsubmitted range
members to be equal so that cleanup happens from
btrfs_endio_direct_write.
This 4-step logic is not really obvious, especially given it's scattered
across 3 functions.
Fixes: f28a49287817 ("Btrfs: fix leaking of ordered extents after direct IO write error")
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Omar Sandoval <osandov@fb.com>
[ add range start/end logic explanation from Nikolay ]
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/vfio')
0 files changed, 0 insertions, 0 deletions