diff options
author | Filipe Manana <fdmanana@suse.com> | 2024-02-02 12:09:22 +0000 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2024-02-13 18:38:05 +0100 |
commit | 1bd96c92c6a0a4d43815eb685c15aa4b78879dc9 (patch) | |
tree | 2e76ef3f5b5ba62834ce44eaac8a7a4b6b6ef492 /fs/btrfs/inode.c | |
parent | feefe1f49d26bad9d8997096e3a200280fa7b1c5 (diff) | |
download | linux-stable-1bd96c92c6a0a4d43815eb685c15aa4b78879dc9.tar.gz linux-stable-1bd96c92c6a0a4d43815eb685c15aa4b78879dc9.tar.bz2 linux-stable-1bd96c92c6a0a4d43815eb685c15aa4b78879dc9.zip |
btrfs: reject encoded write if inode has nodatasum flag set
Currently we allow an encoded write against inodes that have the NODATASUM
flag set, either because they are NOCOW files or they were created while
the filesystem was mounted with "-o nodatasum". This results in having
compressed extents without corresponding checksums, which is a filesystem
inconsistency reported by 'btrfs check'.
For example, running btrfs/281 with MOUNT_OPTIONS="-o nodatacow" triggers
this and 'btrfs check' errors out with:
[1/7] checking root items
[2/7] checking extents
[3/7] checking free space tree
[4/7] checking fs roots
root 256 inode 257 errors 1040, bad file extent, some csum missing
root 256 inode 258 errors 1040, bad file extent, some csum missing
ERROR: errors found in fs roots
(...)
So reject encoded writes if the target inode has NODATASUM set.
CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d232eca1bbee..5f39462dceb0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10288,6 +10288,13 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, if (encoded->encryption != BTRFS_ENCODED_IO_ENCRYPTION_NONE) return -EINVAL; + /* + * Compressed extents should always have checksums, so error out if we + * have a NOCOW file or inode was created while mounted with NODATASUM. + */ + if (inode->flags & BTRFS_INODE_NODATASUM) + return -EINVAL; + orig_count = iov_iter_count(from); /* The extent size must be sane. */ |