From 3a17a4dcdd8550a6e54f4c6e16272c7ce0f9eb14 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Tue, 25 Feb 2025 03:16:27 -0500 Subject: [PATCH] tempfile: make sure FS_COMPR_FL stays set btrfs will set the FS_NOCOMP_FL flag when all of the following are true: 1. The filesystem is not mounted with the `compress-force` option 2. Heuristic analysis of the data suggests the data is compressible 3. Compression fails to produce a result that is smaller than the original If the compression ratio is 40%, and the original data is 128K long, then compressed data will be about 52K long (rounded up to 4K), so item 3 is usually false; however, if the original data is 8K long, then the compressed data will be 8K long too, and btrfs will set FS_NOCOMP_FL. To work around that, keep setting FS_COMPR_FL and clearing FS_NOCOMP_FL every time a TempFile is reset. Signed-off-by: Zygo Blaxell --- src/bees.cc | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/bees.cc b/src/bees.cc index e13b035..d22fe19 100644 --- a/src/bees.cc +++ b/src/bees.cc @@ -502,6 +502,19 @@ BeesTempFile::resize(off_t offset) // Count time spent here BEESCOUNTADD(tmp_resize_ms, resize_timer.age() * 1000); + // Modify flags - every time + // - btrfs will keep trying to set FS_NOCOMP_FL behind us when compression heuristics identify + // the data as compressible, but it fails to compress + // - clear FS_NOCOW_FL because we can only dedupe between files with the same FS_NOCOW_FL state, + // and we don't open FS_NOCOW_FL files for dedupe. + BEESTRACE("Getting FS_COMPR_FL and FS_NOCOMP_FL on m_fd " << name_fd(m_fd)); + int flags = ioctl_iflags_get(m_fd); + flags |= FS_COMPR_FL; + flags &= ~(FS_NOCOMP_FL | FS_NOCOW_FL); + BEESTRACE("Setting FS_COMPR_FL and clearing FS_NOCOMP_FL | FS_NOCOW_FL on m_fd " << name_fd(m_fd) << " flags " << to_hex(flags)); + ioctl_iflags_set(m_fd, flags); + + // That may have queued some delayed ref deletes, so throttle them bees_throttle(resize_timer.age(), "tmpfile_resize"); } @@ -543,17 +556,6 @@ BeesTempFile::BeesTempFile(shared_ptr ctx) : // Add this file to open_root_ino lookup table m_roots->insert_tmpfile(m_fd); - // Set compression attribute - BEESTRACE("Getting FS_COMPR_FL on m_fd " << name_fd(m_fd)); - int flags = ioctl_iflags_get(m_fd); - flags |= FS_COMPR_FL; - - // Clear NOCOW because it conflicts with COMPR, and NOCOW could be set on the root subvol - flags &= FS_NOCOW_FL; - - BEESTRACE("Setting FS_COMPR_FL on m_fd " << name_fd(m_fd) << " flags " << to_hex(flags)); - ioctl_iflags_set(m_fd, flags); - // Count time spent here BEESCOUNTADD(tmp_create_ms, create_timer.age() * 1000);