Commit Graph
1784 Commits
Author SHA1 Message Date
Zach BrownandAndy Grover 9395360324 scoutfs: add srch entry inc/dec
We're going to need to increment and decrement srch entries in coming
fixes.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-03 09:58:35 -08:00
Zach BrownandAndy Grover 7c5823ad12 scoutfs: drop duplicate compacted srch entries
The k-way merge used by srch file compaction only dropped the second
entry in a pair of duplicate entries.  Duplicate entries are both
supposed to be removed so that entries for removed xattrs don't take up
space in the files.

This both drops the second entry and removes the first encoded entry.
As we encode entries we rememeber their starting offset and the previous
entry that they were encoded from.  When we hit a duplicate entry
we undo the encoding of the previous entry.

This only works wihin srch file blocks.  We can still have duplicate
entries that span blocks but that's unlikely and relatively harmless.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-03 09:58:35 -08:00
Zach BrownandAndy Grover 560c91a0e4 scoutfs: fix binary search for sorted srch block
The search_xattrs ioctl looks for srch entries in srch files that map
the caller's hashed xattr name to inodes.  As it searches it maintains a
range of entries that it is looking for.  When it searches sorted srch
files for entries it first performs a binary search for the start of the
range and then iterates over the blocks until it reaches the end of its
range.

The binary search for the start of the range was a bit wrong.  If the
start of the range was less than all the blocks then the binary search
could wrap the left index, try to get a file block at a negative index,
and return an error for the search.

This is relatively hard to hit in practice.  You have to search for the
xattr name with the smallest hashed value and have a sorted srch file
that's just the right size so that blk offset 0 is the last block
compared in the binary search, which sets the right index to -1.  If
there are lots of xattrs, or sorted files of the wrong length, it'll
work.

This fixes the binary search so that it specifically records the first
block offset that intersects with the range and tests that the left and
right offsets haven't been inverted.  Now that we're not breaking out of
the binary search loop we can more obviously put each block reference
that we get.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-03 09:58:35 -08:00
Zach BrownandAndy Grover 4647a6ccb2 scoutfs: fix srch btree iref puts
The srch code was putting btree item refs outside of success.  This is
fine, but they only need to be put when btree ops return success and
have set the reference.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-03 09:58:35 -08:00
Andy GroverandZach Brown 1bef610416 scoutfs: Don't destroy sroot unless srch_search_xattrs() was called
Until then, sroot is uninitialized so it's not safe to call
destroy_rb_root().

Signed-off-by: Andy Grover <agrover@versity.com>
2020-12-03 09:02:31 -08:00
Zach BrownandZach Brown 9375b9d3b7 scoutfs: commit while enough meta for dirty items
Dirty items in a client transaction are stored in OS pages.  When the
transaction is committed each item is stored in its position in a dirty
btree block in the client's existing log btree.  Allocators are refilled
between transaction commits so a given commit must have sufficient meta
allocator space (avail blocks and unused freed entries) for all the
btree blocks that are dirtied.

The number of btree blocks that are written, thus the number of cow
allocations and frees, depends on the number of blocks in the log btree
and the distribution of dirty items amongst those blocks.  In a typical
load items will be near each other and many dirty items in smaller
kernel pages will be stored in fewer larger btree blocks.

But with the right circumstances, the ratio of dirty pages to dirty
blocks can be much smaller.  With a very large directory and random
entry renames you can easily have 1 btree block dirtied for every page
of dirty items.

Our existing allocator meta allocator fill targets and the number of
dirty item cache pages we allowed did not properly take this in to
account.  It was possible (and, it turned out, relatively easy to test
for with a hgue directory and random renames) to run out of meta avail
blocks while storing dirty items in dirtied btree blocks.

This rebalances our targets and thresholds to make it more likely that
we'll have enough allocator resources to commit dirty items.  Instead of
having an arbitrary limit on the number of dirty item cache pages, we
require that a given number of dirty item cache pages have a given
number of allocator blocks available.

We require a decent number of avialable blocks for each dirty page, so
we increase the server's target number of blocks to give the client so
that it can still build large transactions.

This code is conservative and should not be a problem in practice, but
it's theoretically possible to build a log btree and set of dirty items
that would dirty more blocks that this code assumes.  We will probably
revisit this as we add proper support for ENOSPC.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-02 09:25:13 -08:00
Zach BrownandZach Brown ae286bf837 scoutfs: update srch _alloc_meta_low callers
The srch system checks that is has allocator space while deleting srch
files and while merging them and dirtying output blocks.  Update the
callers to check for the correct number of avail or freed blocks that it
needs between each check.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-02 09:25:13 -08:00
Zach BrownandZach Brown a5d9ac5514 scoutfs: rework scoutfs_alloc_meta_low, takes arg
Previously, scoutfs_alloc_meta_lo_thresh() returned true when a small
static number of metadata blocks were either available to allocate or
had space for freeing.  This didn't make a lot of sense as the correct
number depends on how many allocations each caller will make during
their atomic transaction.

Rework the call to take an argument for the number of avail or freed
blocks available to test.  This first pass just uses the existing
number, we'll get to the callers.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-02 09:25:13 -08:00
Zach BrownandAndy Grover 7b2310442b scoutfs-tests: add createmany-rename-large-dir
Add a test that randomly renames entries in a single large directory.
This has caught bugs in the reservation of allocator resources for
client transactions.

Signed-off-by: Zach Brown <zab@versity.com>
2020-12-02 09:23:15 -08:00
Andy GroverandZach Brown cf278f5fa0 scoutfs: Tidy some enum usage
Prefer named to anonymous enums. This helps readability a little.

Use enum as param type if possible (a couple spots).

Remove unused enum in lock_server.c.

Define enum spbm_flags using shift notation for consistency.

Rename get_file_block()'s "gfb" parameter to "flags" for consistency.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-11-30 13:35:44 -08:00
Andy GroverandZach Brown 73333af364 scoutfs: Use enum for lock mode
Signed-off-by: Andy Grover <agrover@versity.com>
2020-11-30 13:35:44 -08:00
Andy GroverandZach Brown 9a647a98f1 scoutfs-utils: Header changes to match kmod PR 41
Signed-off-by: Andy Grover <agrover@versity.com>
2020-11-30 13:35:39 -08:00
Zach BrownandAndy Grover 2f3d1c395e scoutfs: show metadev_path in sysfs/mount_options
We forgot to add metadev_path to the options that are found in the
mount_options sysfs directory.

Signed-off-by: Zach Brown <zab@versity.com>
2020-11-24 14:02:02 -08:00
Zach BrownandAndy Grover 222e5f1b9d scoutfs: convert endian in SCOUTFS_IS_META_BDEV
We missed that flags is le64.

Signed-off-by: Zach Brown <zab@versity.com>
2020-11-24 14:02:02 -08:00
Andy GroverandZach Brown 30668c1cdd scoutfs-utils: Fix df
Not initializing wid[] can cause incorrect output.

Also, we only need 6 columns if we reference the array from 0.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-11-19 13:03:31 -08:00
Zach BrownandZach Brown 84bb170e3a scoutfs-tests: add dmesg for missing metadev_path
The xfstests generic/067 test is a bit of a stinker in that it's trying
to make sure a mount failes when the device is invalid.  It does this
with raw mount calls without any filesystem-specific conventions.  Our
mount fails, so the test passes, but not for the reason the test
assumes.  It's not a great test.  But we expect it to not be great and
produce this message.

Signed-off-by: Zach Brown <zab@versity.com>
2020-11-19 11:42:04 -08:00
Zach BrownandZach Brown 320c411678 scoutfs-tests: add another expected ext4 dmesg
Add another expected message that comes from attempting to mount an ext4
filesystem from a device that returns read errors.

Signed-off-by: Zach Brown <zab@versity.com>
2020-11-19 11:42:04 -08:00
Zach BrownandZach Brown c08f818b64 scoutfs-tests: fix T_SKIP_CHECKOUTS
The tests were checking that the literal string was zero, which it never
was.  Once we check the value of the variable then we notice that the
sense of some tests went from -n || to -n &&, so switch those to -z.

Signed-off-by: Zach Brown <zab@versity.com>
2020-11-19 11:42:04 -08:00
Andy GroverandZach Brown 0e5fb021a2 scoutfs-tests: xfstests.sh: Changes for metadata device for scratch dev
Change MOUNT_OPTIONS and define SCOUTFS_SCRATCH_MOUNT_OPTIONS.

Signed-off-by: Andy Grover <agrover@versity.com>
[zab@versity.com: minor comment fixes]
2020-11-19 11:42:04 -08:00
Andy GroverandZach Brown b40f53633f scoutfs-tests: Support for specifying scratch meta device
For xfstests, we need to be able to specify both for scratch device as
well.

using -e and -f for now, but we should really be switching to long options.

Signed-off-by: Andy Grover <agrover@versity.com>
[zab@versity.com: minor arg message fixes]
2020-11-19 11:42:04 -08:00
Andy GroverandZach Brown aed9f66410 scoutfs-tests: xfstests: honor SKIP_CHECKOUT
Signed-off-by: Andy Grover <agrover@versity.com>
2020-11-19 11:42:04 -08:00
Andy GroverandZach Brown 09256fdf15 scoutfs-tests: Changes for use of separate block devices for meta and data
Add -z option to run-tests.sh to specify metadata device.

Do a bunch of things twice.

Fix up setup-error-teardown test.

Signed-off-by: Andy Grover <agrover@versity.com>
[zab@versity.com: minor arg message fixes, golden output]
2020-11-19 11:42:04 -08:00
Andy GroverandZach Brown 8f72d16609 scoutfs-utils: Use separate block devices for metadata and data
mkfs: Take two block devices as arguments. Write everything to metadata
dev, and the superblock to the data dev. UUIDs match. Differentiate by
checking a bit in a new "flags" field in the superblock.

Refactor device_size() a little. Convert spaces to tabs.

Move code to pretty-print sizes to dev.c so we can use it in error
messages there, as well as in mkfs.c.

print: Include flags in output.

Add -D and -M options for setting max dev sizes

Allow sizes to be specified using units like "K", "G" etc.

Note: -D option replaces -S option, and uses above units rather than
the number of 4k data blocks.

Update man pages for cmdline changes.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-11-19 11:41:54 -08:00
Zach BrownandZach Brown 08eb75c508 scoutfs: update README.md for metadev_path
Update the README.md introduction to scoutfs to mention the need for and
use of metadata and data block devices.

Signed-off-by: Zach Brown <zab@versity.com>
2020-11-19 11:41:20 -08:00
Andy GroverandZach Brown 9f151fde92 scoutfs: Use separate block devices for metadata and data
Require a second path to metadata bdev be given via mount option.

Verify meta sb matches sb also written to data sb. Change code as needed
in super.c to allow both to be read. Remove check for overlapping
meta and data blknos, since they are now on entirely separate bdevs.

Use meta_bdev for superblock, quorum, and block.c reads and writes.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-11-19 11:41:20 -08:00
Zach BrownandAndy Grover f46ab548a4 scoutfs-utils: format df in two rows
It was too tricky to pick out the difference between metadata and data
usage in the previous format.  This makes it much more clear which
values are for either metadata or data.

Signed-off-by: Zach Brown <zab@versity.com>
2020-11-10 15:23:14 -08:00
Zach BrownandZach Brown ff532eba75 scoutfs: recover max lock write_version
Write locks are given an increasing version number as they're granted
which makes its way into items in the log btrees and is used to find the
most recent version of an item.

The initialization of the lock server's next write_version for granted
locks dates back to the initial prototype of the forest of log btrees.
It is only initialized to zero as the module is loaded.  This means that
reloading the module, perhaps by rebooting, resets all the item versions
to 0 and can lead to newly written items being ignored in favour of
older existing items with greater versions from a previous mount.

To fix this we initialize the lock server's write_version to the
greatest of all the versions in items in log btrees.  We add a field to
the log_trees struct which records the greatest version which is
maintained as we write out items in transactions.  These are read by the
server as it starts.

Then lock recovery needs to include the write_version so that the
lock_server can be sure to set the next write_version past the greatest
version in the currently granted locks.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-30 11:14:10 -07:00
Zach BrownandZach Brown 736d9d7df8 scoutfs: remove struct scoutfs_log_trees_val
The log_trees structs store the data that is used by client commits.
The primary struct is communicated over the wire so it includes the rid
and nr that identify the log.  The _val struct was stored in btree item
values and was missing the rid and nr because those were stored in the
item's key.

It's madness to duplicate the entire struct just to shave off those two
fields.  We can remove the _val struct and store the main struct in item
values, including the rid and nr.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-30 11:14:10 -07:00
Zach BrownandZach Brown 45e2209123 scoutfs-tests: add persistent-item-vers test
Add a test which makes sure that we don't initialize the lock server's
write version to a version less than existing log tree items.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-30 11:13:00 -07:00
Zach BrownandZach Brown 9cf2a6ced0 scoutfs-tests: add remounting test helpers
Add functions to remount all the mounts, including after having removed
and reinserted the module.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-30 11:13:00 -07:00
Zach BrownandZach Brown 66c6331131 scoutfs-utils: add max item vers to log trees
Add a field to the log_trees struct which records the greatest item
version seen in items in the tree.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-30 11:12:52 -07:00
Zach BrownandZach Brown 42bf0980b6 scoutfs-utils: remove scoutfs_log_trees_val
We're just using the one log_trees struct for both network messages and
persistent btree item values.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-30 11:12:52 -07:00
Andy GroverandZach Brown e6228ead73 scoutfs: Ensure padding in structs remains zeroed
Audit code for structs allocated on stack without initialization, or
using kmalloc() instead of kzalloc().

- avl.c: zero padding in avl_node on insert.
- btree.c: Verify item padding is zero, or WARN_ONCE.
- inode.c: scoutfs_inode contains scoutfs_timespecs, which have padding.
- net.c: zero pad in net header.
- net.h: scoutfs_net_addr has padding, zero it in scoutfs_addr_from_sin().
- xattr.c: scoutfs_xattr has padding, zero it.
- forest.c: item_root in forest_next_hint() appears to either be
    assigned-to or unused, so no need to zero it.
- key.h: Ensure padding is zeroed in scoutfs_key_set_{zeros,ones}

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:33 -07:00
Andy GroverandZach Brown 13438c8f5d scoutfs: Remove struct scoutfs_betimespec
Unused.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:33 -07:00
Andy GroverandZach Brown d9d9b65f14 scoutfs: remove __packed from all struct definitions
Instead, explicitly add padding field, and adjust member ordering to
eliminate compiler-added padding between members, and at the end of the
struct (if possible: some structs end in a u8[0] array.)

This should prevent unaligned accesses. Not a big deal on x86_64, but
other archs like aarch64 really want this.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:33 -07:00
Andy GroverandZach Brown 5e1c8586cc scoutfs: ensure btree values end on 8-byte-alignment boundary
Round val_len up to BTREE_VALUE_ALIGN (8), to keep mid_free_len aligned.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:33 -07:00
Andy GroverandZach Brown 68d7a2e2cb scoutfs: align items in item cache to 8 bytes
This will ensure structs, which are internally 8 byte aligned, will remain
so when in the item cache.

16 bytes alignment doesn't seem like it's needed so just do 8.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:33 -07:00
Andy GroverandZach Brown 87cb971630 scoutfs: fix hash compiler warnings
Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:33 -07:00
Zach BrownandZach Brown dc47ec65e4 scoutfs: remove btree value owner footer offset
We were using a trailing owner offset to iterate over btree item values
from the back of the block towards the front.  We did this to reclaim
fragmented free space in a block to satisfy an allocation instead of
having to split the block, which is expensive mostly because it has to
allocate and free metadata blocks.

In the before times, we used to compact items by sorting items by their
offset, moving them, and then sorting them by their keys again.  The
sorting by keys was expensive so we added these owner offsets to be able
to compact without sorting.

But the complexity of maintaining the owner metadata is not worth it.
We can avoid the expensive sorting by keys by allocating a temporary
array of item offsets and sorting only it by the value offset.  That's
nice and quick, it was the key comparisons that were expensive.  Then we
can remove the owner offset entirely, as well as the block header final
free region that compaction needed.

And we also don't compact as often in the modern era because we do the
bulk of our work in the item cache instead of in the btree, and we've
changed the split/merge/compaction heuristics to avoid constantly
splitting/merging/comapcting and an item population happens to hover
right around a shared threshold.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-29 14:15:33 -07:00
Zach BrownandZach Brown dbea353b92 scoutfs: bring back sort_priv
Bring back sort_priv, we have need for sorting with a caller argument.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-29 14:15:33 -07:00
Andy GroverandZach Brown 5701182665 scoutfs-utils: Enable -Wpadded
The compiler will complain if it sees any padding.

Fix a spot in print.c for this.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:22 -07:00
Andy GroverandZach Brown 6fea9f90c4 scoutfs-utils: Sync latest headers with kernel code
__packed no longer used.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:22 -07:00
Andy GroverandZach Brown e78ba2b427 scoutfs-utils: specify types for some long constants
This avoids warnings on Centos 7 from gcc 4.8.5.
2020-10-29 14:15:22 -07:00
Andy GroverandZach Brown 8bd6646d9a scoutfs-utils: avoid redeclarations of __[be,le][16,32,64] in sparse.h
dev.c includes linux/fs.h which includes linux/types.h, which defines
these types, __be16 etc. These are also defined in sparse.h, but I don't
think these are needed.

Definitions in linux/types.h includes stuff to set attr(bitwise) if
__CHECKER__ is defined, so we can remove __sp_biwise.

Signed-off-by: Andy Grover <agrover@versity.com>
2020-10-29 14:15:22 -07:00
Zach BrownandZach Brown 6b1dd980f0 scoutfs-utils: remove btree item owner
We no longer have an owner offset trailing btree item values.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-29 14:15:22 -07:00
Zach BrownandZach Brown ea7c41d876 scoutfs-utils: remove free_*_blocks super fields
The kernel is no longer storing the total free space in all allocators
in super block fields.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-26 15:19:41 -07:00
Zach BrownandZach Brown 669e7f733b scoutfs-utils: add -S to limit device size
Add an option to mkfs to have it limit the size of the device that's
used by mkfs.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-26 15:19:41 -07:00
Zach BrownandZach Brown 4bd86d1a00 scoutfs-utils: return error for small device
The check for a small device didn't return an error code because it was
copied from error tests of ret for an error code.  It has to generate
one, do so.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-26 15:19:41 -07:00
Zach BrownandZach Brown b424208555 scoutfs-utils: remove unused packed extents
Signed-off-by: Zach Brown <zab@versity.com>
2020-10-26 15:19:41 -07:00
Zach BrownandZach Brown 4ca0b3ff74 scoutfs-utils: try compacting srch more frequently
Signed-off-by: Zach Brown <zab@versity.com>
2020-10-26 15:19:41 -07:00