mirror of
https://github.com/torvalds/linux.git
synced 2025-11-01 17:18:25 +02:00
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
1 changed files with 39 additions and 1 deletions
|
|
@ -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…
Reference in a new issue