btrfs: add extra sanity checks for create_io_em()
The function create_io_em() is called before we submit an IO, to update the in-memory extent map for the involved range. This patch changes the following aspects: - Does not allow BTRFS_ORDERED_NOCOW type For real NOCOW (excluding NOCOW writes into preallocated ranges) writes, we never call create_io_em(), as we does not need to update the extent map at all. So remove the sanity check allowing BTRFS_ORDERED_NOCOW type. - Add extra sanity checks * PREALLOC - @block_len == len For uncompressed writes. * REGULAR - @block_len == @orig_block_len == @ram_bytes == @len We're creating a new uncompressed extent, and referring all of it. - @orig_start == @start We haven no offset inside the extent. * COMPRESSED - valid @compress_type - @len <= @ram_bytes This is to co-operate with encoded writes, which can cause a new file extent referring only part of a uncompressed extent. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
4bdc558bf9
commit
e98bf64f7a
@ -7258,11 +7258,49 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
|
||||
struct extent_map *em;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Note the missing NOCOW type.
|
||||
*
|
||||
* For pure NOCOW writes, we should not create an io extent map, but
|
||||
* just reusing the existing one.
|
||||
* Only PREALLOC writes (NOCOW write into preallocated range) can
|
||||
* create an io extent map.
|
||||
*/
|
||||
ASSERT(type == BTRFS_ORDERED_PREALLOC ||
|
||||
type == BTRFS_ORDERED_COMPRESSED ||
|
||||
type == BTRFS_ORDERED_NOCOW ||
|
||||
type == BTRFS_ORDERED_REGULAR);
|
||||
|
||||
switch (type) {
|
||||
case BTRFS_ORDERED_PREALLOC:
|
||||
/* Uncompressed extents. */
|
||||
ASSERT(block_len == len);
|
||||
|
||||
/* We're only referring part of a larger preallocated extent. */
|
||||
ASSERT(block_len <= ram_bytes);
|
||||
break;
|
||||
case BTRFS_ORDERED_REGULAR:
|
||||
/* Uncompressed extents. */
|
||||
ASSERT(block_len == len);
|
||||
|
||||
/* COW results a new extent matching our file extent size. */
|
||||
ASSERT(orig_block_len == len);
|
||||
ASSERT(ram_bytes == len);
|
||||
|
||||
/* Since it's a new extent, we should not have any offset. */
|
||||
ASSERT(orig_start == start);
|
||||
break;
|
||||
case BTRFS_ORDERED_COMPRESSED:
|
||||
/* Must be compressed. */
|
||||
ASSERT(compress_type != BTRFS_COMPRESS_NONE);
|
||||
|
||||
/*
|
||||
* Encoded write can make us to refer to part of the
|
||||
* uncompressed extent.
|
||||
*/
|
||||
ASSERT(len <= ram_bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
em = alloc_extent_map();
|
||||
if (!em)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
Loading…
x
Reference in New Issue
Block a user