]> git.hungrycats.org Git - bees/commitdiff
tempfile: make sure FS_COMPR_FL stays set
authorZygo Blaxell <bees@furryterror.org>
Tue, 25 Feb 2025 08:16:27 +0000 (03:16 -0500)
committerZygo Blaxell <bees@furryterror.org>
Mon, 30 Jun 2025 03:25:36 +0000 (23:25 -0400)
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 <bees@furryterror.org>
src/bees.cc

index e13b035db983d4d4df2a9af8d25d393650bdee69..d22fe19768c0ed6a36301e4ab38a906679990aa6 100644 (file)
@@ -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<BeesContext> 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);