Skip to content

Commit e98bf64

Browse files
adam900710kdave
authored andcommitted
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>
1 parent 4bdc558 commit e98bf64

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

fs/btrfs/inode.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7258,11 +7258,49 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
72587258
struct extent_map *em;
72597259
int ret;
72607260

7261+
/*
7262+
* Note the missing NOCOW type.
7263+
*
7264+
* For pure NOCOW writes, we should not create an io extent map, but
7265+
* just reusing the existing one.
7266+
* Only PREALLOC writes (NOCOW write into preallocated range) can
7267+
* create an io extent map.
7268+
*/
72617269
ASSERT(type == BTRFS_ORDERED_PREALLOC ||
72627270
type == BTRFS_ORDERED_COMPRESSED ||
7263-
type == BTRFS_ORDERED_NOCOW ||
72647271
type == BTRFS_ORDERED_REGULAR);
72657272

7273+
switch (type) {
7274+
case BTRFS_ORDERED_PREALLOC:
7275+
/* Uncompressed extents. */
7276+
ASSERT(block_len == len);
7277+
7278+
/* We're only referring part of a larger preallocated extent. */
7279+
ASSERT(block_len <= ram_bytes);
7280+
break;
7281+
case BTRFS_ORDERED_REGULAR:
7282+
/* Uncompressed extents. */
7283+
ASSERT(block_len == len);
7284+
7285+
/* COW results a new extent matching our file extent size. */
7286+
ASSERT(orig_block_len == len);
7287+
ASSERT(ram_bytes == len);
7288+
7289+
/* Since it's a new extent, we should not have any offset. */
7290+
ASSERT(orig_start == start);
7291+
break;
7292+
case BTRFS_ORDERED_COMPRESSED:
7293+
/* Must be compressed. */
7294+
ASSERT(compress_type != BTRFS_COMPRESS_NONE);
7295+
7296+
/*
7297+
* Encoded write can make us to refer to part of the
7298+
* uncompressed extent.
7299+
*/
7300+
ASSERT(len <= ram_bytes);
7301+
break;
7302+
}
7303+
72667304
em = alloc_extent_map();
72677305
if (!em)
72687306
return ERR_PTR(-ENOMEM);

0 commit comments

Comments
 (0)