]> git.hungrycats.org Git - bees/log
bees
21 months agoreadahead: inject some sanity at the foundation of an insane architecture
Zygo Blaxell [Fri, 15 Nov 2024 19:35:01 +0000 (14:35 -0500)]
readahead: inject some sanity at the foundation of an insane architecture

This solves some of the worst problems with bees reads:

1.  The kernel readahead doesn't work.  More precisely, it's much better
adapted for a very different use case:  a single thread alternating
between reading a file sequentially and processing the data that was read.
bees has multiple threads which compete for access to IO and then issue
reads in random order immediately after the call to readahead.  The kernel
uses idle ioprio scheduling for the readaheads, so the readaheads get
preempted by the random reads, or cancels the readaheads because the
data access pattern isn't sequential after the readahead was issued.

2.  Seeking drives perform terribly with multiple competing readers,
especially with btrfs striped profiles where the iops are broken into
tiny stripe-sized pieces.  At one point I intended to read the btrfs
device map and figure out which devices can be read in parallel, but to
make that useful, the user needs to have an array with multiple drives
in single profile, or 4+ drives in raid1 profile.  In all other cases,
the elaborate calculations always return the same result:  there can be
only one reader at a time.

This commit fixes both problems:

1.  Don't use the kernel readahead.  Use normal reads into a dummy
buffer instead.

2.  Allow only one thread to readahead at any time.  Once the read is
completed, the data is in the page cache, and all the random-order small
reads that bees does will hit the page cache, not a spinning disk.
In some cases we need to read two things close together, so add a
`bees_readahead_pair` which holds one lock across both reads.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agohash: use kernel readahead instead of bees_readahead to prefetch hash table
Zygo Blaxell [Mon, 25 Nov 2024 03:11:42 +0000 (22:11 -0500)]
hash: use kernel readahead instead of bees_readahead to prefetch hash table

The hash table is read sequentially and from a single thread, so
the kernel's implementation of readahead is appropriate here.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agodocs: add allocator regression in 6.0+ kernels
Zygo Blaxell [Sat, 7 Oct 2023 05:35:07 +0000 (01:35 -0400)]
docs: add allocator regression in 6.0+ kernels

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agocontext: when a task fails to acquire an extent lock, don't go ahead and scan the...
Zygo Blaxell [Tue, 19 Nov 2024 20:17:41 +0000 (15:17 -0500)]
context: when a task fails to acquire an extent lock, don't go ahead and scan the extent anyway

Commit c3b664fea54cfd8ac25411cbdb9536e4f24b008e ("context: don't forget
to retry locked extents") removed the critical return that prevents a
Task from processing an extent that is locked.

Put the return back.

Fixes: c3b664fea54cfd8ac25411cbdb9536e4f24b008e ("context: don't forget to retry locked extents")
Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agofs: get rid of 16 MiB limit on dedupe requests
Zygo Blaxell [Tue, 12 Nov 2024 01:47:36 +0000 (20:47 -0500)]
fs: get rid of 16 MiB limit on dedupe requests

The kernel has not required a 16 MiB limit on dedupe requests since
v4.18-rc1 b67287682688 ("Btrfs: dedupe_file_range ioctl: remove 16MiB
restriction").

Kernels before v4.18 would truncate the request and return the size
actually deduped in `bytes_deduped`.  Kernel v4.18 and later will loop
in the kernel until the entire request is satisfied (although still
in 16 MiB chunks, so larger extents will be split).

Modify the loop in userspace to measure the size the kernel actually
deduped, instead of assuming the kernel will only accept 16 MiB.
On current kernels this will always loop exactly once.

Since we now rely on `bytes_deduped`, make sure it has a sane value.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agoRevert "context: add experimental code for avoiding tiny extents"
Zygo Blaxell [Mon, 25 Nov 2024 01:16:46 +0000 (20:16 -0500)]
Revert "context: add experimental code for avoiding tiny extents"
because this problem is better solved elsewhere.

This reverts commit 11fabd66a84b6631fb39bb6b2c066c689351fc26.

21 months agousage: the default scan mode is 3 (recent)
Zygo Blaxell [Sat, 2 Sep 2023 16:19:43 +0000 (12:19 -0400)]
usage: the default scan mode is 3 (recent)

The code and docs were changed some time ago, but not the usage message.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agodocs: add the 6.10..6.12 delayed refs bug
Zygo Blaxell [Sat, 30 Nov 2024 00:30:42 +0000 (19:30 -0500)]
docs: add the 6.10..6.12 delayed refs bug

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agocrawl: rename next_transid() to avoid confusion with BeesScanMode::next_transid()
Zygo Blaxell [Sat, 30 Nov 2024 17:49:22 +0000 (12:49 -0500)]
crawl: rename next_transid() to avoid confusion with BeesScanMode::next_transid()

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
21 months agotrace: add file and line numbers all the way up the stack
Zygo Blaxell [Sat, 30 Nov 2024 15:18:58 +0000 (10:18 -0500)]
trace: add file and line numbers all the way up the stack

These were added to crucible all the way back in 2018 (1beb61fb78ba
"crucible: error: record location of exception in what() message")
but it's even more useful in the stack tracer in bees.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
2 years agocontext: reduce the size of LOGICAL_INO buffers
Zygo Blaxell [Mon, 17 Jul 2023 21:49:21 +0000 (17:49 -0400)]
context: reduce the size of LOGICAL_INO buffers

Since we'll never process more than BEES_MAX_EXTENT_REF_COUNT extent
references by definition, it follows that we should not allocate buffer
space for them when we perform the LOGICAL_INO ioctl.

There is some evidence (particularly
https://github.com/Zygo/bees/issues/260#issuecomment-1627598058) that
the kernel is subjecting the page cache to a lot of disruption when
trying allocate large buffers for LOGICAL_INO.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
2 years agousage: the default scan mode is 1 (independent)
Zygo Blaxell [Sat, 2 Sep 2023 16:19:18 +0000 (12:19 -0400)]
usage: the default scan mode is 1 (independent)

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
2 years agolib: fix btrfs_data_container pointer casts for 32-bit userspace on 64-bit kernels
Zygo Blaxell [Thu, 18 Apr 2024 03:07:41 +0000 (23:07 -0400)]
lib: fix btrfs_data_container pointer casts for 32-bit userspace on 64-bit kernels

Apparently reinterpret_cast<uint64_t> sign-extends 32-bit pointers.
This is OK when running on a 32-bit kernel that will truncate the pointer
to 32 bits, but when running on a 64-bit kernel, the extra bits are
interpreted as part of the (now very invalid) address.

Use <uintptr_t> instead, which is unsigned, integer, and the same word
size as the arch's pointer type.  Ordinary numeric conversion can take
it from there, filling the rest of the word with zeros.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: add vmalloc bug to kernel bugs list
Zygo Blaxell [Thu, 6 Jul 2023 17:45:09 +0000 (13:45 -0400)]
docs: add vmalloc bug to kernel bugs list

The bug is:

v6.3-rc6: f349b15e183d mm: vmalloc: avoid warn_alloc noise caused by fatal signal

The fixes are:

v6.4: 95a301eefa82 mm/vmalloc: do not output a spurious warning when huge vmalloc() fails
v6.3.10: c189994b5dd3 mm/vmalloc: do not output a spurious warning when huge vmalloc() fails

The bug has been backported to LTS, but the fix has not:

v6.2.11: 61334bc29781 mm: vmalloc: avoid warn_alloc noise caused by fatal signal
v6.1.24: ef6bd8f64ce0 mm: vmalloc: avoid warn_alloc noise caused by fatal signal
v5.15.107: a184df0de132 mm: vmalloc: avoid warn_alloc noise caused by fatal signal

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: log when LOGICAL_INO returns 0 refs
Zygo Blaxell [Mon, 8 May 2023 12:09:08 +0000 (08:09 -0400)]
context: log when LOGICAL_INO returns 0 refs

There was a bug in kernel 6.3 where LOGICAL_INO with IGNORE_OFFSET
sometimes fails to ignore the offset.  That bug is now fixed, but
LOGICAL_INO still returns 0 refs much more often than seems appropriate.

This is most likely because bees frequently deletes extents while there
is still work waiting for them in Task queues.  In this case, LOGICAL_INO
correctly returns an empty list, because every reference to some extent
is deleted, but the new extent tree with that extent removed is not yet
committed in btrfs.

Add a DEBUG-level log message and an event counter to track these events.
In the absence of a kernel bug, the debug message may indicate CPU time
was wasted performing a search whose outcome could have been predicted.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: add IGNORE_OFFSET regression in 6.2..6.3 to kernel bugs list
Zygo Blaxell [Wed, 10 May 2023 02:24:00 +0000 (22:24 -0400)]
docs: add IGNORE_OFFSET regression in 6.2..6.3 to kernel bugs list

This doesn't impact the current bees master, but it does break bees-next.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: downgrade toxic extent workaround message
Zygo Blaxell [Thu, 6 Jul 2023 16:36:08 +0000 (12:36 -0400)]
context: downgrade toxic extent workaround message

Toxic extents are much less of a problem now than they were in kernels
before 5.7.  Downgrade the log message level to reflect their lesser
importance.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotest: GCC 13 fix for limits.cc
Zygo Blaxell [Mon, 8 May 2023 01:02:58 +0000 (21:02 -0400)]
test: GCC 13 fix for limits.cc

GCC complains that #include <cstdint> is missing, so add that.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobtrfs-tree: fix build on clang++16
Zygo Blaxell [Mon, 8 May 2023 01:16:40 +0000 (21:16 -0400)]
btrfs-tree: fix build on clang++16

The "loops" variable isn't read (only set) if not built with extra
debug code.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: working around `btrfs send` issues isn't really a feature
Zygo Blaxell [Tue, 7 Mar 2023 15:20:16 +0000 (10:20 -0500)]
docs: working around `btrfs send` issues isn't really a feature

The critical kernel bugs in send have been fixed for years.
The limitations that remain aren't bugs, and bees has no sustainable
workaround for them.

Also update copyright year range.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: fill in missing LTS backports for "1119a72e223f btrfs: tree-checker: do not...
Zygo Blaxell [Tue, 7 Mar 2023 15:15:53 +0000 (10:15 -0500)]
docs: fill in missing LTS backports for "1119a72e223f btrfs: tree-checker: do not error out if extent ref hash doesn't match"

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: make sure transid_max's computed value isn't max
Zygo Blaxell [Tue, 7 Feb 2023 03:46:46 +0000 (22:46 -0500)]
roots: make sure transid_max's computed value isn't max

We check the result of transid_max_nocache(), but not the result of
transid_max().  The latter is a computed result that is even more likely
to be wrong[citation needed].

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: add "missing" features that have been in development for some time already
Zygo Blaxell [Sat, 25 Feb 2023 08:13:23 +0000 (03:13 -0500)]
docs: add "missing" features that have been in development for some time already

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: update GCC versions list and clarify markdown statement
Zygo Blaxell [Sat, 25 Feb 2023 08:13:00 +0000 (03:13 -0500)]
docs: update GCC versions list and clarify markdown statement

I don't know if anyone else is testing GCC versions before 8.0 any more,
but I'm not.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: update front page
Zygo Blaxell [Sat, 25 Feb 2023 08:12:27 +0000 (03:12 -0500)]
docs: update front page

At least one user was significantly confused by "designed for large
filesystems".

The btrfs send workarounds aren't new any more.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: minor changes to how-it-works based on past user questions
Zygo Blaxell [Sat, 25 Feb 2023 08:12:15 +0000 (03:12 -0500)]
docs: minor changes to how-it-works based on past user questions

Clarify that "too large" and "too small" are some distance away from each other.
The Goldilocks zone is _wide_.

The interval between cache drops is now shorter.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: various gotcha updates
Zygo Blaxell [Sat, 25 Feb 2023 08:11:30 +0000 (03:11 -0500)]
docs: various gotcha updates

Fixing the obviously wrong and out of date stuff.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: simplify the exit-with-SIGTERM description
Zygo Blaxell [Sat, 25 Feb 2023 08:10:29 +0000 (03:10 -0500)]
docs: simplify the exit-with-SIGTERM description

The description now matches the code again.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: update the feature interactions page
Zygo Blaxell [Sat, 25 Feb 2023 08:09:25 +0000 (03:09 -0500)]
docs: update the feature interactions page

Fixing the obviously out-of-date and no-longer-tested things.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: update kernel bugs and workarounds list for 6.2.0
Zygo Blaxell [Sat, 25 Feb 2023 08:08:59 +0000 (03:08 -0500)]
docs: update kernel bugs and workarounds list for 6.2.0

Remove some of the repetition to make the document easier to edit.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: create a Pool of BtrfsIoctlLogicalInoArgs objects
Zygo Blaxell [Tue, 21 Feb 2023 05:04:31 +0000 (00:04 -0500)]
context: create a Pool of BtrfsIoctlLogicalInoArgs objects

Each object contains a 16 MiB buffer, which is very heavy for some
malloc implementations.

Keep the objects in a Pool so that their buffers are only allocated and
deallocated once in the process lifetime.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agofs: allow BtrfsIoctlLogicalInoArgs to be reused, remove virtual methods
Zygo Blaxell [Tue, 21 Feb 2023 04:44:20 +0000 (23:44 -0500)]
fs: allow BtrfsIoctlLogicalInoArgs to be reused, remove virtual methods

Some malloc implementations will try to mmap() and munmap() large buffers
every time they are used, causing a severe loss of performance.

Nothing ever overrode the virtual methods, and there was no virtual
destructor, so they cause compiler warnings at build time when used with
a template that tries to delete pointers to them.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoProgressTracker: reduce memory usage with long-running work items
Zygo Blaxell [Fri, 24 Feb 2023 03:33:35 +0000 (22:33 -0500)]
ProgressTracker: reduce memory usage with long-running work items

ProgressTracker was only freeing memory for work items when they reach
the head of the work tracking queue.  If the first work item takes
hours to complete, and thousands of items are processed every second,
this leads to millions of completed items tracked in memory at a time,
wasting gigabytes of system RAM.

Rewrite ProgressHolderState methods to keep only incomplete work items
in memory, regardless of the order in which they are added or removed.

Also fix the unit tests which were relying on the memory leak to work,
and add test cases for code coverage.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoseeker: fix the test for ILP32 platforms
Zygo Blaxell [Sun, 12 Feb 2023 18:00:00 +0000 (13:00 -0500)]
seeker: fix the test for ILP32 platforms

Not sure what I was thinking, but the argument here should clearly
be uint64_t.

Fixes: https://github.com/Zygo/bees/issues/248
Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: don't share a RootFetcher between threads
Zygo Blaxell [Mon, 20 Feb 2023 16:13:18 +0000 (11:13 -0500)]
roots: don't share a RootFetcher between threads

If the send workaround is enabled, it is possible for two threads (a
thread running the crawl_new task, and a thread attempting to apply the
send workaround) to access the same RootFetcher object at the same time.
That never ends well.

Give each function its own BtrfsRootFetcher object.

Fixes: https://github.com/Zygo/bees/issues/250
Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoMakefile: also drop fiemap and fiewalk from main Makefile
Kai Krakow [Sat, 28 Jan 2023 10:21:51 +0000 (11:21 +0100)]
Makefile: also drop fiemap and fiewalk from main Makefile

Fixes: https://github.com/Zygo/bees/commit/ccd8dcd43f0c903a94367817a0a9e94034a5cce4
Signed-off-by: Kai Krakow <kai@kaishome.de>
3 years agohash: flush the table more slowly
Zygo Blaxell [Mon, 23 Jan 2023 04:44:51 +0000 (23:44 -0500)]
hash: flush the table more slowly

With SIGTERM and fast exit, the trickle writeback is less important.
We don't want to flood people's IO subsystems with continuous writes.
This really should be configurable at runtime.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotest: simplify Makefile
Zygo Blaxell [Mon, 23 Jan 2023 02:52:51 +0000 (21:52 -0500)]
test: simplify Makefile

Make can build dependencies in parallel, so let Make do that.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agosrc: bees-version.cc cleanups
Zygo Blaxell [Mon, 23 Jan 2023 03:19:16 +0000 (22:19 -0500)]
src: bees-version.cc cleanups

Do rebuild bees-version.cc if libcrucible changes.
Don't rebuild bees-version.cc if it doesn't change.
Also use the standard suffix for new files.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agosrc: simplify Makefile
Zygo Blaxell [Mon, 23 Jan 2023 02:50:07 +0000 (21:50 -0500)]
src: simplify Makefile

Make can build dependencies in parallel, so let Make do that.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agolib: drop version.cc entirely
Zygo Blaxell [Sat, 19 Nov 2022 07:19:25 +0000 (02:19 -0500)]
lib: drop version.cc entirely

crucible::VERSION doesn't make much sense now that libcrucible no
longer exists as a shared library.  Nothing ever referenced it, so
it can go away.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agolib: simplify dependency generation
Zygo Blaxell [Mon, 23 Jan 2023 02:28:28 +0000 (21:28 -0500)]
lib: simplify dependency generation

We don't need to run all the dependencies first, Make can do those in parallel.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agofd: FS_IOC_SETFLAGS takes an int* argument not a long*
Zygo Blaxell [Tue, 14 Dec 2021 06:18:39 +0000 (01:18 -0500)]
fd: FS_IOC_SETFLAGS takes an int* argument not a long*

According to ioctl_iflags(2):

The type of the argument given to the FS_IOC_GETFLAGS and
FS_IOC_SETFLAGS  operations is int *, notwithstanding the
implication in the kernel source file include/uapi/linux/fs.h
that the argument is long *.

So this code doesn't work on be64 machines.

Also, Valgrind complains about it.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agofd: pwrite returns ssize_t not int
Zygo Blaxell [Thu, 7 Apr 2022 11:25:37 +0000 (07:25 -0400)]
fd: pwrite returns ssize_t not int

A subtle distinction, and not one that is particularly relevant to bees,
but it does make toolchains complain.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agofs: get rid of base class btrfs_ioctl_logical_ino_args
Zygo Blaxell [Sun, 23 Oct 2022 18:01:38 +0000 (14:01 -0400)]
fs: get rid of base class btrfs_ioctl_logical_ino_args

Another instance of the pattern where we derived a crucible class
from a btrfs struct.  Make it an automatic variable instead.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agofs: remove duplicate BTRFS_COMPRESS_ definitions
Zygo Blaxell [Sun, 25 Oct 2020 05:10:58 +0000 (01:10 -0400)]
fs: remove duplicate BTRFS_COMPRESS_ definitions

This was fixed in

7f660f50b lib: fs: stop using libbtrfs-dev helper functions to re-enable buffer length checks

but apparently some copies live on.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agofiemap, fiewalk: drop dead example/test code
Zygo Blaxell [Thu, 4 Nov 2021 05:48:53 +0000 (01:48 -0400)]
fiemap, fiewalk: drop dead example/test code

These tools are obsolete.  fiemap was a thin wrapper around FIEMAP,
but FIEMAP is not useful on btrfs.  fiewalk was a thin wrapper around
BtrfsExtentWalker, but development on BtrfsExtentWalker has been
abandoned.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: remove the one call to operator vector<> method in BtrfsIoctlLogicalInoArgs
Zygo Blaxell [Sun, 23 Oct 2022 21:51:18 +0000 (17:51 -0400)]
context: remove the one call to operator vector<> method in BtrfsIoctlLogicalInoArgs

There's only one user of this method.  Open-code it so we can kill the
method in libcrucible.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agohash: don't spin when writes fail
Zygo Blaxell [Thu, 19 Jan 2023 14:24:48 +0000 (09:24 -0500)]
hash: don't spin when writes fail

When a hash table write fails, we skip over the write throttling because
we didn't report that we successfully wrote an extent.  This can be bad
if the filesystem is full and the allocations for writes are burning a
lot of CPU time searching for free space.

We also don't retry the write later on since we assume the extent is
clean after a write attempt whether it was successful or not, so the
extent might not be written out later when writes are possible again.

Check whether a hash extent is dirty, and always throttle after
attempting the write.

If a write fails, leave the extent dirty so we attempt to write it out
the next time flush cycles through the hash table.  During shutdown
this will reattempt each failing write once, after that the updated hash
table data will be dropped.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: fix broken link in options.md
Zygo Blaxell [Mon, 16 Jan 2023 05:06:22 +0000 (00:06 -0500)]
docs: fix broken link in options.md

Links in docs/ are relative to docs/, not the top level.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agomain: catch exceptions and exit gracefully
Zygo Blaxell [Wed, 4 Jan 2023 01:37:52 +0000 (20:37 -0500)]
main: catch exceptions and exit gracefully

Calling 'bees -m4' should not call 'std::terminate()', but it does.

Use catch_all instead.  It will still pass the exit value to return
from main.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agofs: get rid of base class btrfs_ioctl_same_extent_info
Zygo Blaxell [Sun, 23 Oct 2022 18:01:38 +0000 (14:01 -0400)]
fs: get rid of base class btrfs_ioctl_same_extent_info

We only use BtrfsExtentInfo when it's exactly equivalent to the
base, so drop the derived class.

While we're here, fix BtrfsExtentSame::add so it uses a btrfs-compatible
uint64_t instead of an off_t.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobtrfs-tree: fix whitespace and const
Zygo Blaxell [Sat, 25 Dec 2021 18:34:25 +0000 (13:34 -0500)]
btrfs-tree: fix whitespace and const

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobtrfs-tree: translate item types for error messages
Zygo Blaxell [Sun, 4 Dec 2022 08:43:21 +0000 (03:43 -0500)]
btrfs-tree: translate item types for error messages

Look up the name when filling in the what() field for the exception.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobtrfs-tree: add chunk items: length and type
Zygo Blaxell [Sun, 1 Jan 2023 01:15:12 +0000 (20:15 -0500)]
btrfs-tree: add chunk items: length and type

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoreadahead: report the original size in BEESTOOLONG
Zygo Blaxell [Fri, 30 Dec 2022 19:36:55 +0000 (14:36 -0500)]
readahead: report the original size in BEESTOOLONG

BEESTOOLONG was always reporting a size of zero, and the offset of the
end of the readahead region.  Report the original size instead (and also
in BEESTRACE and BEESNOTE).

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: add crawl_again, drop crawl_restart
Zygo Blaxell [Thu, 29 Dec 2022 10:35:57 +0000 (05:35 -0500)]
docs: add crawl_again, drop crawl_restart

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: fix extent lock failure handling
Zygo Blaxell [Thu, 22 Dec 2022 05:12:10 +0000 (00:12 -0500)]
roots: fix extent lock failure handling

Drop the crawl_restart counter, it doesn't happen here (or anywhere else).

Add the crawl_again counter for extents that are restarted due to an
extent-level lock.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotrace: use pthread_setname wrapper
Zygo Blaxell [Thu, 29 Dec 2022 09:03:53 +0000 (04:03 -0500)]
trace: use pthread_setname wrapper

libcrucible can deal with the Linux kernel and/or libc's thread name
limitations.  No need to duplicate that work in bees.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotask: use pthread_setname_np correctly
Zygo Blaxell [Thu, 29 Dec 2022 09:02:41 +0000 (04:02 -0500)]
task: use pthread_setname_np correctly

It turns out I've been using pthread_setname_np wrong the whole time:

 * on Linux, the thread name length is 15 characters.
   TASK_COMM_LEN is 16 bytes, and the last one is always 0.
   This is now hardcoded in many places and cannot be changed.

 * pthread_setname_np doesn't return -errno, so DIE_IF_MINUS_ERRNO
   was the wrong macro.  On the other hand, we never want to do anything
   differently when pthread_setname_np fails, so we never needed to
   check the return value.

Also, libc silently ignores attempts to set the thread name when it is too
long.  That's almost certainly a libc bug, but libc probably suppresses
the error result for the same reasons I ignore the error result.

Wrap the pthread_setname function with a C++ std::string overload that
truncates the argument at 15 characters, so we at least get the first
part of the task name in the thread name field.  Later commits can deal
with making the bees thread names shorter.

Also wrap pthread_getname for symmetry.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: remove duplicate (and wrong) default scan mode
Zygo Blaxell [Thu, 5 Jan 2023 06:09:13 +0000 (01:09 -0500)]
docs: remove duplicate (and wrong) default scan mode

The default scan mode is found in config.md.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: fix reference direction
Adam Faiz [Sat, 24 Dec 2022 02:26:30 +0000 (10:26 +0800)]
docs: fix reference direction

The Dependencies list is above the Packaging section, not below.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoMerge github PR #148
Zygo Blaxell [Fri, 23 Dec 2022 05:23:14 +0000 (00:23 -0500)]
Merge github PR #148

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: don't count MultiLock waiting time in dedup_ms
Zygo Blaxell [Thu, 22 Dec 2022 05:27:08 +0000 (00:27 -0500)]
context: don't count MultiLock waiting time in dedup_ms

This was inflating the dedup_ms statistic because it was counting all
the resolve time too.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: don't forget to retry locked extents
Zygo Blaxell [Thu, 22 Dec 2022 05:07:49 +0000 (00:07 -0500)]
context: don't forget to retry locked extents

The caller of scan_forward has to stop advancing the BeesFileCrawl
position when an extent lock blocks a scan, so that it will resume
from the same position when the Task is scheduled again; otherwise,
bees simply skips over the extent and leave it incompletely deduped.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobeesd: Honor DESTDIR on installation.
Hilton Chain [Fri, 23 Dec 2022 03:04:46 +0000 (11:04 +0800)]
beesd: Honor DESTDIR on installation.

Co-authored-by: Adam Faiz <adam.faiz@disroot.org>
Signed-off-by: Hilton Chain <hako@ultrarare.space>
3 years agoroots: replace BEES_TRANSID_FACTOR with BEES_TRANSID_POLL_INTERVAL
Zygo Blaxell [Wed, 30 Nov 2022 03:44:42 +0000 (22:44 -0500)]
roots: replace BEES_TRANSID_FACTOR with BEES_TRANSID_POLL_INTERVAL

Restart crawl_more (and update crawl roots and flush FD caches) every
time the transid changes, and only when the transid changes, but
not more often than a reasonable minimum poll interval.

Clean up the log message:  use the proper thread name and remove
the wildly inaccurate estimate of when crawl will resume.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: keep the resolve cache smaller
Zygo Blaxell [Mon, 6 Dec 2021 00:24:22 +0000 (19:24 -0500)]
context: keep the resolve cache smaller

We don't need to cache 65536 extent maps, especially if each one
can have almost 700K references.

Valgrind's massif tool points to the extent map cache as a very
large memory allocator, but test runs with memcg disagree.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: run insert_new_crawl from within a Task
Zygo Blaxell [Fri, 3 Dec 2021 04:56:46 +0000 (23:56 -0500)]
roots: run insert_new_crawl from within a Task

If we have loadavg targeting enabled, there may be no worker threads
available to respond to new subvols, so we should not bother updating
the subvols list.

Put insert_new_crawl into a Task so it only executes when a worker
is available.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: remove the line discussing 'max_transid' in recent scan mode
Zygo Blaxell [Tue, 20 Dec 2022 15:19:47 +0000 (10:19 -0500)]
docs: remove the line discussing 'max_transid' in recent scan mode

This makes the doc match the code again.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: disable recent sorting by max_transid
Zygo Blaxell [Mon, 19 Dec 2022 05:19:18 +0000 (00:19 -0500)]
roots: disable recent sorting by max_transid

On large filesystems where the min_transid of all subvols gets stuck at 0,
bees may lose the ability to effectively track recent data.  A secondary sort
by max_transid will allow scanning newer subvols that were created after bees
started running on the filesystem, but before bees completed the first scan
of all subvols.

On the other hand, the secondary sort does a reverse version of the
sequential scan mode, and the sequential scan mode is simply awful.

Disable it for now.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agodocs: update documentation for new 'recent' scan mode
Zygo Blaxell [Tue, 16 Nov 2021 04:43:02 +0000 (23:43 -0500)]
docs: update documentation for new 'recent' scan mode

Also attempted to clarify the descriptions of the modes based on
feedback and questions from users over the years.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: reimplement scan modes using virtual base and methods
Zygo Blaxell [Mon, 14 Nov 2022 18:01:41 +0000 (13:01 -0500)]
roots: reimplement scan modes using virtual base and methods

Split each scan mode into two distinct phases:

    1.  A heavy discovery phase, where we search the entire filesystem
    for something (new items in subvol trees in this case).

    2.  A light consuming phase, where we fetch extents to dedupe
    from places that we found in the discovery phase.

Part 1 recomputes the subvol ordering every time there is a new transid.
For some scan modes this computation is quite expensive, far too costly
to pay for every extent, so we do it no more than once per transaction.

Part 2 is run every time a worker thread hits the crawl_more Task.
It simply pulls one extent from the first crawler off a sorted list,
removing the crawler from the list when the crawler runs out of data.

Part 1 creates a new structure and swaps it into place, while Part 2
continues to run using the previous strucuture.  Neither of these
need to block the other, so they don't.

The separate class and base pointer also make it easer to add new scan
modes that are not based on subvol trees or that don't use BeesCrawl.

While we're here, fix up some method visibility in BeesRoots.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: remove duplicate default scan mode setting
Zygo Blaxell [Mon, 29 Nov 2021 05:55:41 +0000 (00:55 -0500)]
roots: remove duplicate default scan mode setting

Set the constructor's default scan mode to an invalid mode, so if we
change the default, we don't have to update two places.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: add 'recent' crawl mode for a mix of new and old data
Zygo Blaxell [Mon, 29 Nov 2021 05:41:29 +0000 (00:41 -0500)]
roots: add 'recent' crawl mode for a mix of new and old data

Crawl mode 3 'recent' prioritizes data from new updates to previously
scanned subvols over subvols that have not been completely scanned yet.
If no such new data exists, falls back to a variation of 'lockstep'
scan mode.

This enables us to keep up with new data as it arrives, a key weakness
of all the other scan modes, and worth violating our unwritten "no new
scan modes until we have extent-tree dedupe working" policy for.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: emit "crawl finished" at the correct time
Zygo Blaxell [Mon, 29 Nov 2021 05:30:36 +0000 (00:30 -0500)]
roots: emit "crawl finished" at the correct time

The correct time is when we set the deferred bit after a tree
search returns empty.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: improve thread status tracking messages
Zygo Blaxell [Mon, 29 Nov 2021 05:29:16 +0000 (00:29 -0500)]
roots: improve thread status tracking messages

Don't dereference a shared_ptr inside a thread status function.

Do trace the crawl start events.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: process PREALLOC extents synchronously in extent's Task worker
Zygo Blaxell [Tue, 16 Nov 2021 06:00:30 +0000 (01:00 -0500)]
context: process PREALLOC extents synchronously in extent's Task worker

Inode-oriented scan workers must do all of their work sequentially,
so it's counterproductive to spawn a Task to do a background dedupe.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: don't let multiple worker Tasks get stuck on a single extent or inode
Zygo Blaxell [Sun, 20 Nov 2022 17:01:16 +0000 (12:01 -0500)]
context: don't let multiple worker Tasks get stuck on a single extent or inode

When two Tasks attempt to lock the same extent, append the later Task
to the earlier Task's post-exec work queue.  This will guarantee that
all Tasks which attempt to manipulate the same extent will execute
sequentially, and free up threads to process other extents.

Similarly, if two scanner threads operate on the same inode, any dedupe
they perform will lock out other scanner threads in btrfs.  Avoid this
by serializing Task objects that reference the same file.

This does theoretically use an unbounded amount of memory, but in practice
a Task that encounters a contended extent or inode quickly stops spawning
new Tasks that might increase the queue size, and all Tasks that might
contend for the same lock(s) end up on a single FIFO queue.

Note that the scope of inode locks is intentionally global, i.e. when
an inode is locked, it locks every inode with the same number in every
subvol.  This avoids significant lock contention and task queue growth
when the same inode with the same file extents appear in snapshots.

Fixes: https://github.com/Zygo/bees/issues/158
Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: organize scan workers by inode instead of extent
Zygo Blaxell [Wed, 1 Dec 2021 19:42:42 +0000 (14:42 -0500)]
roots: organize scan workers by inode instead of extent

Split crawlers into two separate Tasks:

 1. a Task which locates the next inode with a new data extent.

 2. a Task which scans every new extent in that inode.

This simplifies some lock contention and execution ordering issues.
Files are read sequentially.  Workers dynamically scale up or
down as needed, without creating thousands of deferred Task objects.
Workers obtain inode locks for different inodes in btrfs, so they
can work in parallel instead of waiting for each other.

This change in behavior comes with new names for the worker Tasks:

        "crawl_master" is now "crawl_more", the singular Task which
        creates inode-scanning Tasks.

        "crawl_<subvol>" is now "crawl_<subvol>_<inode>".

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: use scan mode 'independent' by default
Zygo Blaxell [Tue, 16 Nov 2021 05:52:34 +0000 (00:52 -0500)]
roots: use scan mode 'independent' by default

Independent subvol scanners fairly consistently outperform either
of the correlated scan modes.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: use symbolic names for SCAN_MODEs
Zygo Blaxell [Wed, 24 Oct 2018 05:43:22 +0000 (01:43 -0400)]
roots: use symbolic names for SCAN_MODEs

This was done on the development branch three years ago, and
has been creating annoying merge conflicts ever since.  Sync
up the branches so they have the same names for these.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoroots: rework btrfs send workaround using btrfs-tree
Zygo Blaxell [Wed, 1 Dec 2021 19:43:08 +0000 (14:43 -0500)]
roots: rework btrfs send workaround using btrfs-tree

Drop the cache since we no longer have to open a file every time we
check a subvol's status.

Also stop counting workaround events at the root level twice.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobtrfs-tree: introduce lightweight classes for btrfs tree search operations
Zygo Blaxell [Wed, 3 Nov 2021 02:59:51 +0000 (22:59 -0400)]
btrfs-tree: introduce lightweight classes for btrfs tree search operations

btrfs-tree provides classes for low-level access to btrfs tree objects.

An item class is provided to decode polymorphic btrfs item fields.

Several tree classes provide forward and backward iteration over raw
object items at different tree levels.

A csum tree class provides convenient access to csums by bytenr,
supporting all current btrfs csum types.

Wrapper classes for inode and subvol items provide direct access to
btrfs metadata fields without clumsy stat() wrappers or ioctls.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoseeker: backward searching template function
Zygo Blaxell [Sat, 9 Oct 2021 04:22:48 +0000 (00:22 -0400)]
seeker: backward searching template function

This template turns a forward search primitive (e.g. lower_bound, FIEMAP,
TREE_SEARCH_V2) into a backward search primitive.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agoBeesFileRange: coalesce is not used, subtract was never implemented
Zygo Blaxell [Mon, 21 Nov 2022 04:19:45 +0000 (23:19 -0500)]
BeesFileRange: coalesce is not used, subtract was never implemented

Less dead code to maintain.  Also more Doxygen comments.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobytevector: validate length in get<T>()
Zygo Blaxell [Sat, 25 Dec 2021 21:26:34 +0000 (16:26 -0500)]
bytevector: validate length in get<T>()

Don't allow a pointer to T to be taken from a ByteVector that is not at
least sizeof(T) bytes long.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobytevector: do not deadlock in self-assignment
Zygo Blaxell [Sat, 19 Nov 2022 23:23:33 +0000 (18:23 -0500)]
bytevector: do not deadlock in self-assignment

Not that this is a particularly useful use case, but it will lock up,
and it should not.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobytevector: don't need _all_ of those mutexes
Zygo Blaxell [Sat, 19 Nov 2022 07:38:49 +0000 (02:38 -0500)]
bytevector: don't need _all_ of those mutexes

Methods that don't even look at the pointer don't need a mutex.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobytevector: add some fugly mutexes
Zygo Blaxell [Tue, 14 Dec 2021 04:56:44 +0000 (23:56 -0500)]
bytevector: add some fugly mutexes

We are using ByteVectors from multiple threads in some cases.  Mostly
these are the status and progress threads which read the ByteVector
object references embedded in BEESNOTE macros.

Since it's not clear what the data race implications are, protect
the shared_ptr in ByteVector with a mutex for now.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobytevector: add ostream output with hexdump
Zygo Blaxell [Sun, 17 Oct 2021 06:08:22 +0000 (02:08 -0400)]
bytevector: add ostream output with hexdump

There is a hexdump template in fs.  Move hexdump to its own header,
then ByteVector can use it too.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agobees: drop the balance/logical workaround that has been disabled for two years
Zygo Blaxell [Sat, 19 Nov 2022 07:00:17 +0000 (02:00 -0500)]
bees: drop the balance/logical workaround that has been disabled for two years

Kernels that needed the balance workaround frankly are too buggy
to run bees at all.  The workaround also makes the locking stories
around logical_ino calls and process exit complicated, so get rid of
it completely.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: drop long-dead ExtentWalker code
Zygo Blaxell [Sat, 19 Nov 2022 22:17:36 +0000 (17:17 -0500)]
context: drop long-dead ExtentWalker code

At some point BtrfsExtentWalker will be fully deprecated and removed from
bees.  Might as well start with code that hasn't been built in 6 years.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: speed up orderly process termination
Zygo Blaxell [Sat, 19 Nov 2022 07:45:15 +0000 (02:45 -0500)]
context: speed up orderly process termination

Quite often bees exceeds its service timeout for termination because
it is waiting for a loop embedded in a Task to finish some long-running
btrfs operation.  This can cause bees to be aborted by SIGKILL before
it can completely flush the hash table or save crawl state.

There are only two important things SIGTERM does when bees terminates:
 1.  Save crawl progress
 2.  Flush out the hash table

Everything else is automatically handled by the kernel when the process
is terminated by SIGKILL, so we don't have to bother doing it ourselves.
This can save considerable time at shutdown since we don't have to wait
for every thread to reach a point where it becomes idle, or force loops
to terminate by throwing exceptions, or check a condition every time we
access a pointer.  Instead, we need do only the things in the list
above, and then call _exit() to clean up everything else.

Hash table and crawl state writeback can happen in their background
threads instead of the foreground one.  Separate the "stop" method for
these classes into "stop_request" and "stop_wait" so that these writebacks
can run at the same time.

Deprecate and remove all references to the BeesHalt exception, and remove
several unnecessary checks for BeesContext::stop_requested.

Pause the task queue instead of cancelling it, which preserves the
crawl progress state and stops new Tasks from competing for iops and
CPU during writeback.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agocontext: dump current load tracking stats
Zygo Blaxell [Mon, 5 Dec 2022 05:22:29 +0000 (00:22 -0500)]
context: dump current load tracking stats

Dump the instantaneous load (last 5 seconds, extracted from load average)
and the computed target worker count (before rounding and truncation)
on the same status line as the task and worker thread count.

This should give better visibility into Task's thread count calculation
algorithm.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotask: use exponential backoff algorithm to set thread count
Zygo Blaxell [Mon, 5 Dec 2022 04:56:35 +0000 (23:56 -0500)]
task: use exponential backoff algorithm to set thread count

Tasks are often running longer than 5 seconds (especially extents with
multiple references requiring copy operations), so the load tracking
algorithm needs to average several samples over a longer period of time
than 5 seconds.  If the sample period is 60 seconds, we end up recomputing
the original load average from current_load, so skip the rounding error
and use the original load average value.

Arguably the real fix is to break up the more complex extent operations
over several downstream Task objects, but that's a more significant
design change.

Tweak the attack and decay rates so that threads are started a little
more slowly, but still stopped rapidly when load spikes up.

Remove the hysteresis to provide support for load average targets
below 1, or with fractional components, with a PWM-like effect.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotask: export load tracking statistics
Zygo Blaxell [Mon, 5 Dec 2022 05:10:10 +0000 (00:10 -0500)]
task: export load tracking statistics

Provide an interface so that programs can monitor the Task load
average calculations.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotask: rescue post-exec queue on Task destruction
Zygo Blaxell [Sun, 18 Dec 2022 05:30:37 +0000 (00:30 -0500)]
task: rescue post-exec queue on Task destruction

task1.append(task2) is supposed to run task2 after task1 is executed;
however, if task1 was just executed, and its last reference was owned by
a TaskConsumer, then task2 will be appended to a Task that will never
run again.

A similar problem arises in Exclusion, which can cause blocked tasks
to occasionally be dropped without executing them.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotask: increase saved thread name length to 64
Zygo Blaxell [Sat, 19 Nov 2022 07:45:18 +0000 (02:45 -0500)]
task: increase saved thread name length to 64

24 bytes seems a little low.  64 is a rounder (and more square) number.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
3 years agotask: add more Doxygen comments for PairLock
Zygo Blaxell [Sat, 19 Nov 2022 23:03:29 +0000 (18:03 -0500)]
task: add more Doxygen comments for PairLock

I need to remind myself why it's there, and not just std::lock.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>