]> git.hungrycats.org Git - bees/commitdiff
thread: add workaround-clone-logical-ino config option
authorZygo Blaxell <bees@furryterror.org>
Wed, 24 Jun 2026 15:16:56 +0000 (11:16 -0400)
committerZygo Blaxell <bees@furryterror.org>
Sat, 5 Sep 2026 04:04:12 +0000 (00:04 -0400)
The dedupe (clone) ioctl and LOGICAL_INO must not run concurrently on
some kernels, so bees serializes them through MultiLocker.  This was
hardcoded on via MultiLocker::enable_locking(true) in bees_main.

Expose the behaviour as a boolean [thread] option,
workaround-clone-logical-ino, defaulting to yes (the prior hardcoded
behaviour).  When set to no, locking is disabled and any thread may run
either operation at any time, which is faster but unsafe on affected
kernels.  bees_main now passes the configured value straight to
enable_locking().

The option is consumed once at startup and handed to a static method, so
it needs no member in BeesContext or BeesRoots.  Document it in the
built-in config and docs/config-file.md.

Assisted-by: Claude-Code:claude-opus-4-8
docs/config-file.md
src/bees-config-v2.cc
src/bees.cc

index f3c65ccb5be47fc688b5d66922ddb94b49a7c3bc..6c492de00016c5641085ce934b2d77c40589ee51 100644 (file)
@@ -933,6 +933,16 @@ The `[thread]` section sets how many worker threads bees runs and how aggressive
 
   Default: `9999`.
 
+* **`workaround-clone-logical-ino`**
+  Whether to serialize the dedupe (clone) ioctl against the `LOGICAL_INO` ioctl to avoid a btrfs kernel bug that can be triggered when both run concurrently.
+
+  * `yes` (the default) prevents any thread from running dedupe while another thread is running `LOGICAL_INO`, and vice versa.  The two ioctls never overlap.
+  * `no` removes the restriction: any thread may run either operation at any time.  This is faster under high concurrency but unsafe on kernels affected by the bug.
+
+  Leave this enabled unless you have confirmed your kernel is not affected.
+
+  Default: `yes`.
+
 ## [throttle] section
 
 The [throttle] section helps manage btrfs commit latency by injecting intentional delays between system calls that queue delayed references (refs).  Instead of submitting as many commands as possible and waiting for the queue to drain, this option queues commands at the **average rate** at which they are processed.  This can improve system responsiveness and stabilize IO latency, particularly for write operations.
index 24dd4d60733f5e1a642445a09fb12065cd2dd76b..d08e6bbbec7e75b399db3896073a961ddcf7c1f5 100644 (file)
@@ -30,6 +30,15 @@ static const char bees_config_v2[] = R"--v2-config--(
         # Config version (number) or alias (STABLE, CURRENT, v0.11).
         version = 2
 
+[thread]
+
+        # Serialize the dedupe ioctl against LOGICAL_INO to avoid a kernel
+        # bug triggered when both run concurrently.  yes: no thread runs
+        # dedupe while another runs LOGICAL_INO (and vice versa).  no: any
+        # thread may run either operation at any time (faster, but unsafe
+        # on affected kernels).
+        workaround-clone-logical-ino = yes
+
 # scan_next's planner and matching pipeline emit a high volume of
 # DEBUG/INFO progress detail that is interesting only when actively
 # debugging dedup decisions.  Quiet to warnings-and-errors by default;
index e4f58fbd68b08857b467ab08246cc9109427ed3e..25f03ec7173bf21f830fe760864c96bc9e0046bb 100644 (file)
@@ -720,8 +720,11 @@ bees_main(int argc, char *argv[])
                        bc->get_config().get("state.point.defer", bees_parse_bool));
        }
 
-       // Workaround for the logical-ino-vs-clone kernel bug
-       MultiLocker::enable_locking(true);
+       // Workaround for the logical-ino-vs-clone kernel bug: serialize the
+       // dedupe ioctl against LOGICAL_INO unless the operator opts out.
+       const bool workaround_clone_logical_ino = bc->get_config().get("thread.workaround-clone-logical-ino", bees_parse_bool);
+       BEESLOGINFO("thread.workaround-clone-logical-ino = " << (workaround_clone_logical_ino ? "yes" : "no") << " [thread.workaround-clone-logical-ino]");
+       MultiLocker::enable_locking(workaround_clone_logical_ino);
 
        // Start crawlers
        bc->start();