diff mbox series

[RESEND] btrfs: inode: Don't compress if NODATASUM or NODATACOW set

Message ID 20190627061517.2112-1-wqu@suse.com
State New, archived
Headers show
Series [RESEND] btrfs: inode: Don't compress if NODATASUM or NODATACOW set | expand

Commit Message

Qu Wenruo June 27, 2019, 6:15 a.m. UTC
As btrfs(5) specified:

	If nodatacow or nodatasum are enabled, compression is disabled.

If NODATASUM or NODATACOW set, we should not compress the extent.

Normally NODATACOW is detected properly in run_delalloc_range() so
compression won't happen for NODATACOW.

However for NODATASUM we don't have any check, and it can cause
compressed extent without csum pretty easily, just by:

  mkfs.btrfs -f $dev
  mount $dev $mnt -o nodatasum
  touch $mnt/foobar
  mount -o remount,datasum,compress $mnt
  xfs_io -f -c "pwrite 0 128K" $mnt/foobar

And in fact, we have bug report about corrupted compressed extent
without proper data checksum so even RAID1 can't recover the corruption.

Running compression without proper checksum could cause more damage when
corruption happens, so there is no need to allow compression for

Reported-by: James Harvey <jamespharvey20@gmail.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
 fs/btrfs/inode.c | 8 ++++++++
 1 file changed, 8 insertions(+)
diff mbox series


diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a2aabdb85226..4e0c7f18fa3a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -398,6 +398,14 @@  static inline int inode_need_compress(struct inode *inode, u64 start, u64 end)
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+	/*
+	 * Btrfs doesn't support compression without csum or CoW.
+	 * This should have the highest priority.
+	 */
+	if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW ||
+	    BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)
+		return 0;
 	/* force compress */
 	if (btrfs_test_opt(fs_info, FORCE_COMPRESS))
 		return 1;