diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 8405d07b49cd..de6b60c52292 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -156,6 +156,19 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( const bool is_nocow = (flags & ((1U << BTRFS_ORDERED_NOCOW) | (1U << BTRFS_ORDERED_PREALLOC))); + /* Only one type flag can be set. */ + ASSERT(has_single_bit_set(flags & BTRFS_ORDERED_EXCLUSIVE_FLAGS)); + + /* DIRECT cannot be set with COMPRESSED nor ENCODED. */ + if (test_bit(BTRFS_ORDERED_DIRECT, &flags)) { + ASSERT(!test_bit(BTRFS_ORDERED_COMPRESSED, &flags)); + ASSERT(!test_bit(BTRFS_ORDERED_ENCODED, &flags)); + } + + /* ENCODED must be set with COMPRESSED. */ + if (test_bit(BTRFS_ORDERED_ENCODED, &flags)) + ASSERT(test_bit(BTRFS_ORDERED_COMPRESSED, &flags)); + /* * For a NOCOW write we can free the qgroup reserve right now. For a COW * one we transfer the reserved space from the inode's iotree into the diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index cd74c5ecfd67..03e12380a2fd 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -47,8 +47,25 @@ struct btrfs_ordered_sum { * IO is done and any metadata is inserted into the tree. */ enum { + /* Extra status bits for ordered extents */ + + /* Set when all the pages are written. */ + BTRFS_ORDERED_IO_DONE, + /* Set when removed from the tree. */ + BTRFS_ORDERED_COMPLETE, + /* We had an io error when writing this out. */ + BTRFS_ORDERED_IOERR, + /* Set when we have to truncate an extent. */ + BTRFS_ORDERED_TRUNCATED, + /* Used during fsync to track already logged extents. */ + BTRFS_ORDERED_LOGGED, + /* We have already logged all the csums of the ordered extent. */ + BTRFS_ORDERED_LOGGED_CSUM, + /* We wait for this extent to complete in the current transaction. */ + BTRFS_ORDERED_PENDING, + /* - * Different types for ordered extents, one and only one of the 4 types + * Different types for ordered extents, one and only one of these types * need to be set when creating ordered extent. * * REGULAR: For regular non-compressed COW write @@ -61,37 +78,27 @@ enum { BTRFS_ORDERED_PREALLOC, BTRFS_ORDERED_COMPRESSED, + /* Extra bit for encoded write, must be set with COMPRESSED. */ + BTRFS_ORDERED_ENCODED, + /* * Extra bit for direct io, can only be set for - * REGULAR/NOCOW/PREALLOC. No direct io for compressed extent. + * REGULAR/NOCOW/PREALLOC. Must not be set for COMPRESSED nor ENCODED. */ BTRFS_ORDERED_DIRECT, - /* Extra status bits for ordered extents */ - - /* set when all the pages are written */ - BTRFS_ORDERED_IO_DONE, - /* set when removed from the tree */ - BTRFS_ORDERED_COMPLETE, - /* We had an io error when writing this out */ - BTRFS_ORDERED_IOERR, - /* Set when we have to truncate an extent */ - BTRFS_ORDERED_TRUNCATED, - /* Used during fsync to track already logged extents */ - BTRFS_ORDERED_LOGGED, - /* We have already logged all the csums of the ordered extent */ - BTRFS_ORDERED_LOGGED_CSUM, - /* We wait for this extent to complete in the current transaction */ - BTRFS_ORDERED_PENDING, - /* BTRFS_IOC_ENCODED_WRITE */ - BTRFS_ORDERED_ENCODED, + BTRFS_ORDERED_NR_FLAGS, }; +static_assert(BTRFS_ORDERED_NR_FLAGS <= BITS_PER_LONG); + +/* One and only one flag can be set. */ +#define BTRFS_ORDERED_EXCLUSIVE_FLAGS ((1UL << BTRFS_ORDERED_REGULAR) | \ + (1UL << BTRFS_ORDERED_NOCOW) | \ + (1UL << BTRFS_ORDERED_PREALLOC) | \ + (1UL << BTRFS_ORDERED_COMPRESSED)) /* BTRFS_ORDERED_* flags that specify the type of the extent. */ -#define BTRFS_ORDERED_TYPE_FLAGS ((1UL << BTRFS_ORDERED_REGULAR) | \ - (1UL << BTRFS_ORDERED_NOCOW) | \ - (1UL << BTRFS_ORDERED_PREALLOC) | \ - (1UL << BTRFS_ORDERED_COMPRESSED) | \ +#define BTRFS_ORDERED_TYPE_FLAGS (BTRFS_ORDERED_EXCLUSIVE_FLAGS | \ (1UL << BTRFS_ORDERED_DIRECT) | \ (1UL << BTRFS_ORDERED_ENCODED))