Commit Graph
65 Commits
Author SHA1 Message Date
Zach BrownandZach Brown dee9fbcf66 scoutfs: use packed extents and bitmaps
The btree forest item storage doesn't have as much item granular state
as the item cache did.  The item cache could tell if a cached item was
populated from persistent storage or was created in memory.  It could
simply remove created items rather than leaving behind a deletion item.

The cached btree blocks in the btree forest item storage mechanism can't
do this.  It has to create deletion items when deleting newly created
items because it doesn't know if the item already exists in the
persistent record or not.

This created a problem with the extent storage we were using.  The
individual extent items were stored with a key set to the last logical
block of their extent.  As extents grew or shrank they often were
deleted and created at different key values during a transaction.  In
the btree forest log trees this left a huge stream of deletion items
beind, one for every previous version of the extent.  Then searches for
an extent covering a block would have to skip over all these deleted
items before hitting the current stored extent.

Streaming writes would operate on O(n) for every extent operation.  It
got to be out of hand.  This large change solves the problem by using
more coarse and stable item storage to track free blocks and blocks
mapped into file data.

For file data we now have large packed extent items which store packed
representations of all the logical mappings of a fixed region of a file.
The data code has loading and storage functions which transfer that
persistent version to and from the version that is modified in memory.

Free blocks are stored in bitmaps that are similarly efficiently packed
into fixed size items.  The client is no longer working with free extent
items managed by the forest, it's working with free block bitmap btrees
directly.  It needs access to the client's metadata block allocator and
block write contexts so we move those two out of the forest code and up
into the transaction.

Previously the client and server would exchange extents with network
messages.  Now the roots of the btrees that store the free block bitmap
items are communicated along with the roots of the other trees involved
in a transaction.  The client doesn't need to send free extents back to
the server so we can remove those tasks and rpcs.

The server no longer has to manage free extents.  It transfers block
bitmap items between trees around commits.   All of its extent
manipulation can be removed.

The item size portion of transaction item counts are removed because
we're not using that level of granularity now that metadata transactions
are dirty btree blocks instead of dirty items we pack into fixed sized
segments.

Signed-off-by: Zach Brown <zab@versity.com>
2020-01-17 11:21:36 -08:00
Zach BrownandZach Brown edd8fe075c scoutfs: remove lsm code
Remove all the now unused code that deals with lsm: segment IO, the item
cache, and the manifest.

Signed-off-by: Zach Brown <zab@versity.com>
2020-01-17 11:21:36 -08:00
Zach BrownandZach Brown 858dad1d51 scoutfs: add forest subsystem
The forest code presents a consistent item interface that's implemented
on top of a forest of persistent btrees.

Signed-off-by: Zach Brown <zab@versity.com>
2020-01-17 11:21:36 -08:00
Zach BrownandZach Brown bdafa6ede6 scoutfs: add block allocator
Add our block allocator core.  It'll be used shortly.

Signed-off-by: Zach Brown <zab@versity.com>
2020-01-17 11:21:36 -08:00
Zach BrownandZach Brown e444c2b8c2 scoutfs: remove sort_priv
The only user was item compaction in the btree and it has been removed.

Signed-off-by: Zach Brown <zab@versity.com>
2020-01-17 11:21:36 -08:00
Zach BrownandZach Brown 2a6d209854 scoutfs: add kernelcompat files
Add files that we'll use to detect and work around incompatibilities
between kernel versions.

Signed-off-by: Zach Brown <zab@versity.com>
2020-01-15 14:57:57 -08:00
Zach BrownandZach Brown 34b8950bca scoutfs: initial lock server core
Add the core lock server code for providing a lock service from our
server.  The lock messages are wired up but nothing calls them.

Signed-off-by: Zach Brown <zab@versity.com>
2019-04-12 10:54:07 -07:00
Zach BrownandZach Brown c34dd452a7 scoutfs: add quorum voting
Add a quorum election implementation.  The mounts that can participate
in the election are specified in a quorum config array in the super
block.  Each configured participant is assigned a preallocated block
that it can write to.

All mounts read the quorum blocks to find the member who was elected the
leader and should be running the server.  The voting mounts loop reading
voting blocks and writing their vote block until someone is elected with
a amjority.

Nothing calls this code yet, this adds the initial implementation and
format.

Signed-off-by: Zach Brown <zab@versity.com>
2019-04-12 10:54:07 -07:00
Zach BrownandZach Brown f75e1e1322 scoutfs: reformat Makefile to one object per line
Reformat the scoutfs-y object list so that there's one object per line.
Diffs now clearly demonstrate what is changing instead of having word
wrapping constantly obscuring changes in the built objects.

(Did everyone spot the scoutfs_trace sorting mistake?  Another reason
not to mash everything into wrapped lines :)).

Signed-off-by: Zach Brown <zab@versity.com>
2019-04-12 10:54:07 -07:00
Zach BrownandZach Brown 00adbd31be scoutfs: add sparse bitmap library
Add a quick library for maintaining a very large bitmap with sparse
allocation.

Signed-off-by: Zach Brown <zab@versity.com>
2018-08-28 15:34:30 -07:00
Zach BrownandZach Brown c4cb5c0651 scoutfs: add trivial seq file wrapper
Add a seq file wrapper which lets callers track objects easily.

Signed-off-by: Zach Brown <zab@versity.com>
2018-07-27 09:50:21 -07:00
Zach BrownandZach Brown d708421cfb scoutfs: remove unused client and server code
The previous commit added shared networking code and disabled the old
unused code.  This removes all that unused client and server code that
was refactored to become the shared networking code.

Signed-off-by: Zach Brown <zab@versity.com>
2018-07-27 09:50:21 -07:00
Zach BrownandZach Brown 17dec65a52 scoutfs: add bidirectional network messages
The client and server networking code was a bit too rudimentary.

The existing code only had support for the client synchronously and
actively sending requests that the server could only passively respond
to.  We're going to need the server to be able to send requests to
connected clients and it can't block waiting for responses from each
one.

This refactors sending and receiving in both the client and server code
into shared networking code.  It's built around a connection struct that
then holds the message state.  Both peers on the connection can send
requests and send responses.

The existing code only retransmitted requests down newly established
connections.  Requests could be processed twice.

This adds robust reliability guarantees.  Requests are resend until
their response is received.  Requests are only processed once by a given
peer, regardless of the connection's transport socket.  Responses are
reiably resent until acknowledged.

This only adds the new refactored code and disables the old unused code
to keep the diff foot print minmal.  A following commit will remove all
the unused code.

Signed-off-by: Zach Brown <zab@versity.com>
2018-07-27 09:50:21 -07:00
Zach BrownandZach Brown e19716a0f2 scoutfs: clean up super block use
The code that works with the super block had drifted a bit.  We still
had two from an old design and we weren't doing anything with its crc.

Move to only using one super block at a fixed blkno and store and verify
its crc field by sharing code with the btree block checksumming.

Signed-off-by: Zach Brown <zab@versity.com>
2018-06-29 15:56:42 -07:00
Zach BrownandZach Brown dfac36a9aa scoutfs: trace key struct
The userspace trace event printing code has trouble with arguments that
refer to fields in entries.  Add macros to make entries for all the
fields and use them as the formatted arguments.

We also remove the mapping of zone and type to strings.  It's smaller to
print the values directly and gets rid of some silly code.

Signed-off-by: Zach Brown <zab@versity.com>
2018-06-29 14:42:06 -07:00
Zach BrownandZach Brown 1b3645db8b scoutfs: remove dead server allocator code
Remove the bitmap segno allocator code that the server used to use to
manage allocations.

Signed-off-by: Zach Brown <zab@versity.com>
2018-06-29 14:42:06 -07:00
Zach BrownandZach Brown 869d11fd0f scoutfs: add core extent functions
Add a file of extent functions that callers will use to manipulate and
store extents in different persistent formats.

Signed-off-by: Zach Brown <zab@versity.com>
2018-06-29 14:42:06 -07:00
Zach BrownandMark Swan b0bd273acc scoutfs: remove support for multi-element kvecs
Originally the item interfaces were written with full support for
vectored keys and values.  Callers constructed keys and values made up
of header structs and data buffers.  Segments supported much larger
values which could span pages when stored in memory.

But over time we've pulled that support back.  Keys are described by a
key struct instead of a multi-element kvec.  Values are now much smaller
and don't span pages.  The item interfaces still use the kvec arrays but
everyone only uses a single element.

So let's make the world a whole lot less awful but having the item
interfaces only supporting a single value buffer specified by a kvec.  A
bunch of code disappears and the result is much easier to understand.

Signed-off-by: Zach Brown <zab@versity.com>
2018-04-04 09:15:27 -05:00
Zach BrownandZach Brown f52dc28322 scoutfs: simplify lock use of kernel dlm
We had an excessive number of layers between scoutfs and the dlm code in
the kernel.  We had dlmglue, the scoutfs locks, and task refs.  Each
layer had structs that track the lifetime of the layer below it.  We
were about to add another layer to hold on to locks just a bit longer so
that we can avoid down conversion and transaction commit storms under
contention.

This collapses all those layers into simple state machine in lock.c that
manages the mode of dlm locks on behalf of the file system.

The users of the lock interface are mainly unchanged.  We did change
from a heavier trylock to a lighter nonblock lock attempt and have to
change the single rare readpage use.  Lock fields change so a few
external users of those fields change.

This not only removes a lot of code it also contains functional
improvements.  For example, it can now convert directly to CW locks with
a single lock request instead of having to use two by first converting
to NL.

It introduces the concept of an unlock grace period.  Locks won't be
dropped on behalf of other nodes soon after being unlocked so that tasks
have a chance to batch up work before the other node gets a chance.
This can result in two orders of magnitude improvements in the time it
takes to, say, change a set of xattrs on the same file population from
two nodes concurrently.

There are significant changes to trace points, counters, and debug files
that follow the implementation changes.

Signed-off-by: Zach Brown <zab@versity.com>
2018-02-14 15:00:17 -08:00
Mark FashehandZach Brown ac09f03327 scoutfs: open by handle
This is implemented by filling in our export ops functions.
When we get those right, the VFS handles most of the details for us.

Internally, scoutfs handles are two u64's (ino and parent ino) and a
type which indicates whether the handle contains the parent ino or not.
Surpisingly enough, no existing type matches this pattern so we use our
own types to identify the handle.

Most of the export ops are self explanatory scoutfs_encode_fh() takes
an inode and an optional parent and encodes those into the smallest
handle that would fit. scoutfs_fh_to_[dentry|parent] turn an existing
file handle into a dentry.

scoutfs_get_parent() is a bit different and would be called on
directory inodes to connect a disconnected dentry path. For
scoutfs_get_parent(), we can export add_next_linkref() and use the backref
mechanism to quickly find a parent directory.

scoutfs_get_name() is almost identical to scoutfs_get_parent(). Here we're
linking an inode to a name which exists in the parent directory. We can also
use add_next_linkref, and simply copy the name from the backref.

As a result of this patch we can also now export scoutfs file systems
via NFS, however testing NFS thoroughly is outside the scope of this
work so export support should be considered experimental at best.

Signed-off-by: Mark Fasheh <mfasheh@versity.com>
[zab edited <= NAME_MAX]
2018-01-26 11:59:47 -08:00
Zach BrownandMark Fasheh e354fd18b1 scoutfs: add sysfs.c, fsid file
I wanted to add a sysfs file that exports the fsid for the mount of a
given device.  But our use of sysfs was confusing and spread through
super.c and counters.c.

This moves the core of our sysfs use to sysfs.c.  Instead of defining
the per-mount dir as a kset we define it as an object with attributes
which gives us a place to add an fsid attribute.

counters still have their own whack of sysfs implementation.  We'll let
it keep it for now but we could move it into sysfs.c.  It's just counter
interation around the insane sysfs obj/attr/type nonsense.  For now it
just needs to know to add its counters dir as a child of the per-mount
dir instead of adding it to the kset.

Signed-off-by: Zach Brown <zab@versity.com>
2017-12-20 12:21:13 -08:00
Zach BrownandMark Fasheh 9ed34f8892 scoutfs: add triggers
Signed-off-by: Zach Brown <zab@versity.com>
2017-12-20 12:21:13 -08:00
Zach BrownandMark Fasheh ce4daa817a scoutfs: add support for format_hash
Calculate the hash of format.h and ioctl.h and make sure the hash stored
in the super during mkfs matches our calculated hash on mount.

Signed-off-by: Zach Brown <zab@versity.com>
2017-10-12 13:57:31 -07:00
Zach BrownandMark Fasheh c3e690a1ac scoutfs: add per_task storage helper
Add some functions for storing and using per-task storage in a list.
Callers can use this to pass pointers to children in a given scope when
interfaces don't allow for passing individual arguments amongst
concurrent callers in the scope.

Signed-off-by: Zach Brown <zab@versity.com>
2017-10-09 15:31:29 -07:00
Mark FashehandZach Brown c0d3f99a6e scoutfs: Cluster coherent read/write
With trylock implemented we can add locking in readpage. After that it's
pretty easy to implement our own read/write functions which at this
point are more or less wrapping the kernel helpers in the correct
cluster locking.

Data invalidation is a bit interesting. If the lock we are invalidating
is an inode group lock, we use the lock boundaries to incrementally
search our inode cache. When an inode struct is found, we sync and
(optionally) truncate pages.

Signed-off-by: Mark Fasheh <mfasheh@versity.com>
[zab: adapted to newer lock call, fixed some error handling]
Signed-off-by: Zach Brown <zab@versity.com>
2017-08-30 10:38:00 -07:00
Mark Fasheh 72a8e9e171 scoutfs: pull in some of ocfs2 stackglue
Dlmglue is built on top of this. Bring in the portions we need which
includes the stackglue API as well as most of the fs/dlm implementation.
I left off the Ocfs2 specific version and connection handling. Also
left out is the old Ocfs2 dlm support which we'll never want.

Like dlmglue, we keep as much of the generic stackglue code in tact
here. This will make translating to/from upstream patches much easier.

Signed-off-by: Mark Fasheh <mfasheh@versity.com>
2017-08-23 21:40:20 -05:00
Mark Fasheh fc21a0253c scoutfs: Hook dlmglue into our build system
Signed-off-by: Mark Fasheh <mfasheh@versity.com>
2017-08-23 15:54:08 -05:00
Zach Brown c1b2ad9421 scoutfs: separate client and server net processing
The networking code was really suffering by trying to combine the client
and server processing paths into one file.  The code can be a lot
simpler by giving the client and server their own processing paths that
take their different socket lifecysles into account.

The client maintains a single connection.  Blocked senders work on the
socket under a sending mutex.  The recv path runs in work that can be
canceled after first shutting down the socket.

A long running server work function acquires the listener lock, manages
the listening socket, and accepts new sockets.  Each accepted socket has
a single recv work blocked waiting for requests.  That then spawns
concurrent processing work which sends replies under a sending mutex.
All of this is torn down by shutting down sockets and canceling work
which frees its context.

All this restructuring makes it a lot easier to track what is happening
in mount and unmount between the client and server.  This fixes bugs
where unmount was failing because the monolithic socket shutdown
function was queueing other work while running while draining.

Signed-off-by: Zach Brown <zab@versity.com>
2017-08-04 10:47:42 -07:00
Zach BrownandZach Brown 9f4095bffb scoutfs: break the build if we export raw types
Raw [su]{8,16,32,64} types keep leaking into our exported headers where
they break userspace builds.  Make sure that we only use the exported __
types and add a check to break our build if we get it wrong.

Signed-off-by: Zach Brown <zab@versity.com>
2017-08-04 10:37:49 -07:00
Zach BrownandZach Brown cefe06af61 scoutfs: add git describe to built module
It's handy to quickly find the git commit that built a given module.  We
add a MOD_INFO() tag for it so we can see it in modinfo on the built
module.  We add a ELF note that the kernel tracks in
/sys/modules/$m/notes/ when the module is loaded.

Signed-off-by: Zach Brown <zab@versity.com>
2017-08-03 15:07:23 -07:00
Zach Brown 412e7a7e3b scoutfs: remove unused ring log storage
Remove the old unused ring now all of its previous callers now use the
btree.

Signed-off-by: Zach Brown <zab@versity.com>
2017-07-08 10:59:40 -07:00
Zach Brown 3eaabe81de scoutfs: add btree stored in persistent ring
Add a cow btree whose blocks are stored in a persistently allocated
ring.   This will let us incrementally index very large data sets
efficiently.

This is an adaptation of the previous btree code which now uses the
ring, stores variable length keys, and augments the items with bits that
ored up through parents.

Signed-off-by: Zach Brown <zab@versity.com>
2017-07-08 10:59:40 -07:00
Mark Fasheh e711c15acf scoutfs: use dlm for locking
To actually use it, we first have to copy symbols over from the dlm build
into the scoutfs source directory. Make that happen automatically for us in
the Makefile.

The only users of locking at the moment are mount, unmount and xattr
read/write. Adding more locking calls should be a straight-forward endeavor.

The LVB based server ip communication didn't work out, and LVBS as they are
written don't make sense in a range locking world. So instead, we record the
server ip address in the superblock. This is protected by the listen lock,
which also arbitrates which node will be the manifest server.

We take and drop the dlm lock on each lock/unlock call. Lock caching will
come in a future patch.

Signed-off-by: Mark Fasheh <mfasheh@versity.com>
2017-06-23 15:08:02 -05:00
Zach Brown 5e0e9ac12e Move to much simpler manifest/alloc storage
Using the treap to be able to incrementally read and write the manifest
and allocation storage from all nodes wasn't quite ready for prime time.
The biggest problem is that invalidating cached nodes which are the
target of native pointers, either for consistency or memory pressure, is
problematic.  This was getting in the way of adding shared support as
readers and writers try to use as much of their treap caches as they
can.  There were other serious problems that we'd run into eventually:
memory pressure from duplicate caching in native nodes and the page
cache, small IOs from reading a page at a time, the risk of
pathologically imbalanced treaps, and the ring being corrupted if the
migration balancing doesn't work (the model assumed you could always
dirty an individual node in a transaction, you have to dirty all the
parents in each new transaction).

Let's back off to a much simpler mechanism while we build the rest of
the system around it.  We can revisit aggressively optimizing this when
it's our worst problem.

We'll store the indexes that the manifest server needs in simple
preallocated rings with log entries.   The server has to read the index
in its entirety into a native rbtree before it can work on it.  We won't
access the physical ring from mounts anymore, they'll send messages to
the server.

The ring callers are now working with a pinned tree in memory so the
interface can be a bit simpler.  By storing the indexes in their own
rings the code and write path become a lot simper: we have an IO
submission path for each index instead of "dirtying" calls per index and
then a writing call.

All this is much more robust and much less likely to get in our way as
we stand up the rest of the system around it.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:51:10 -07:00
Zach Brown 39ae89d85f Add network messaging between mounts
We're going to need communication between mounts to update and
distribute the manifest and allocators in the treap ring.

This adds a netwoking core where one mount becomes the server and other
mounts send requests to it.  The messaging semantics are pretty simple
in that clients reliably send requests and the server passively reply to
requests.  Complexity beyond that is up to the callers implementing the
requests.

It relies on locking to establish the server role and to broadcast the
address of the server socket.  We add a trivial lvb back to our local
test locking implementation to store the address.  We also add the
ability to shut down locking so that the locking networking work stops
blocking.

A little demonstration request is included which just gives visibility
into client and server clocks in the trace logs.  Next up we'll add the
requests that do real work.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:51:10 -07:00
Zach Brown b3b2693939 Add simple debugging range locking layer
We can work on shared mechanics without requiring a full locking server.
We can stand up a simple layer which uses shared data structures in a
kernel image to lock between mounts in the same kernel.

On mount we add supers to a list.  Held locks are tracked in a rbtree.
A lock attempt blocks until it doesn't conflict with anything in the
rbtree.

As locks are acquired we walk all the other supers and write/invaludate
any items they have which intersect with the acquired range.  This is
easier to implement and less efficient than caching locks after they're
unlocked and implementing downconvert/blocking/revoke.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:44:55 -07:00
Zach Brown 97cb75bd88 Remove dead btree, block, and buddy code
Remove all the unused dead code from the previous btree block design.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:44:55 -07:00
Zach Brown 9f5e42f7dd Add simple data items
Add basic file data support by managing file data items from the page
cache address space callbacks.

Data is read by copying from cached items into page contents in
readpage.

Writes create new ephemeral items which reference dirty pages.  The
items are deleted once they're written in a transaction or if
invalidatepage removes the dirty page they reference.

There's a lot more to do to remove data copies, avoid compaction bw
overhead, and add support for truncate, o_direct, and mmap.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:44:54 -07:00
Zach Brown 2bc1617280 Use contiguous key struct instead of kvecs
Using kvecs for keys seemed like a good idea because there were a few
uses that had keys in fragmented memory: dirent keys made up of an
on-stack struct and the file name in the dentry, and keys straddling the
pages that make up a cached segment.

But it hasn't worked out very well.  The code to perform ops on keys
by iterating over vectors is pretty fiddly.  And the raw kvecs only
describe the actively referenced key, they know nothing about the total
size of the buffer that the key resides in.  Some ops can't check that
they're not clobbering things, they're relying on callers not to mess
up.

And critically, the kvec iteration's become a bottleneck.  It turns out
that comparing keys is a very hot path in the item cache.  All the code
to initialize and iterate over two key vectors adds up when each high
level fs operation is a few tree descents and each tree descent is a
bunch of compares.

So let's back off and have a specific struct for tracking keys that are
stored in contiguous memory regions.  Users ensure that keys are
contiguous.  The code ends up being a lot clearer, code now can see how
big the full key buffer is, and the rbtree node comparison fast path is
now just a memcmp.

Almost all of the changes in the patch are mechanical semantic changes
involving types, function names, args, and occasionaly slightly
different return conventions.

A slightly more involved change is that now dirent key users have to
manage an allocated contiguous key with a copy of the path from the
dentry.

Item reading is now a little more clever about calculating the greatest
range it can cache by initially walking all the segments instead of
trying to do it as it runs out of items in each segment.

The largest meaningful change is that now keys can't straddle page
boundaries in memory which means they can't cross block boundaries in
the segment.  We align key offsets to the next block as we write keys to
segments that would have straddled a block.

We then also have to account for that padding when building segments.
We add a helper that calculates if a given number of items will fit in a
segment which is used by item dirtying, segment writing, and compaction.

I left the tracepoint formatting for another patch.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:44:54 -07:00
Zach Brown 2083793ae0 Add first pass at segment compaction
This is the first draft of compaction which has the core mechanics.

Add segment functions to free a segment's segno and to delete the entry
that refers to the given segment.

Add manifest functions that lock the manifest and dirty and delete
manifest entries.  These are used by the compaction thread to atomically
modify the manfiest with the result of a compaction.

Sort the level 0 entries in the manifest by their sequence.  This lets
compaction use the first oldest entry and reading can walk them
backwards to get them in order and not have to sort.  We also more
carefully use the sequence field in the manifest search key to
differentiate between finding high level entries that overlap and
finding specific entries identified by their seq.

Add some fields to the per-super compact_info struct which support
compaction.  We need to know the limit on the number of segments per
level and we record keys per level which tell us which segment to use
next time that level is compacted.

We kick a compaction thread when we add a manifest entry and that brings
the level count over the limit.

scoutfs_manifest_next_compact() is the first meaty function.  The
compaction thread uses this to get all the segments involved in a
compaction.  It does a quick manifest update if the next manifest
candidate doesn't overlap with any sgements in the next level.

The compaction operation itself is a pretty straight forward
read-modify-write operation.  It asks the manifest to give it references
to the segments it'll need, reads them in, iterates over them to count
and copies items in order to output segments, and atomically updates the
manifest.

Now that the manifest can be dirty without any dirty segments we need to
fix the transaction writing function's assumption that everything flows
from dirty segments.  It also has to now lock and unlock the manifest as
it adds the entry for its level 0 segment.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:44:53 -07:00
Zach Brown db9f2be728 Switch to indexed manifest using treap ring
The first pass manifest and allocator storage used a simple ring log
that was entirely replayed into memory to be used.  That risked the
manifest being too large to fit in memory, especially with large keys
and large volumes.

So we move to using an indexed persistent structure that can be read on
demand and cached.  We use a treap of byte referenced nodoes stored in a
circular ring.

The code interface is modeled a bit on the in-memory rbtree interface.
Except that we can get IO errors and manage allocation so we return data
pointers to the item payload istead of item structs and we can return
errors.

The manifest and allocator are converted over and the old ring code is
removed entirely.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:44:53 -07:00
Zach Brown c4954eb6f4 Add initial LSM write implementation
Add all the core strutural components to be able to modify metadata.  We
modify items in fs write operations, track dirty items in the cache,
allocate free segment block reagions, stream dirty items into segments,
write out the segments, update the manifest to reference the written
segments, and write out a new ring that has the new manifest.

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:42:30 -07:00
Zach Brown 43d0d44e48 Add initial LSM implementation
Add the initial core components of the LSM implementation to be able to
read the root inode:

 - bio.c: read big block regions
 - seg.c: cache logical segments
 - ring.c: read the manifest from storage
 - manifest.c: organize segments into an LSM
 - kvec.c: work with arbitrary memory vectors
 - item.c: cache fs metadata items read from segments

Signed-off-by: Zach Brown <zab@versity.com>
2017-04-18 13:38:50 -07:00
Zach Brown 1fde47170b scoutfs: simplify btree block format
Now that we are using fixed smaller blocks we can make the btree format
significantly simpler.  The fixed small block size limits the number of
items that will be stored in each block.  We can use a simple sorted
array of item offsets to maintain the item sort order instead of
the treap.

Getting rid of the treap not only removes a bunch of code, it makes
tasks like verifying or repairing a btree block a lot simpler.

The main impact on the code is that now an item doesn't record its
position in the sort order.  Users of sorted item position now need to
track an items sorted position instead of just the item.

Signed-off-by: Zach Brown <zab@versity.com>
2016-08-02 13:28:08 -07:00
Zach Brown 90a73506c1 scoutfs: remove homebrew tracing
Oh, thank goodness.  It turns out that there's a crash extension for
working with tracepoints in crash dumps.  Let's use standard tracepoints
and pretend this tracing hack never happened.

Signed-off-by: Zach Brown <zab@versity.com>
2016-07-20 12:08:12 -07:00
Zach Brown 59b1f62df8 scoutfs: add basic xattr support
Add basic support for extended attributes.  The next steps are
to add support for more prefixes, including ACLs, and to properly
delete them on unlink.

Signed-off-by: Zach Brown <zab@versity.com>
2016-07-04 10:59:43 -07:00
Zach Brown cedeacacb8 scoutfs: add file with simple name functions
Directory entries and extended attributes similarly hash and compare
strings so we'll give them some shared functions for doing so.

Signed-off-by: Zach Brown <zab@versity.com>
2016-07-04 10:49:41 -07:00
Zach Brown 5c7ba5ed39 scoutfs: remove wrlock and roster
These were interesting experiments in how to manage locks across the
cluster but we'll be going in a more flexible direction.

Signed-off-by: Zach Brown <zab@versity.com>
2016-07-01 21:03:40 -07:00
Zach Brown 7d6dd91a24 scoutfs: add tracing messages
This adds tracing functionality that's cheap and easy to
use.  By constantly gathering traces we'll always have rich
history to analyze when something goes wrong.

Signed-off-by: Zach Brown <zab@versity.com>
2016-05-28 11:11:15 -07:00
Zach Brown 0820a7b5bd scoutfs: introduce write locking
Introduce the concept of acquiring write locks around write operations.

The core idea is that reads are unlocked and that write lock contention
between nodes should be rare.  This first pass simply broadcasts write
lock requests to all the mounts in the volume.  It achieves a reasonable
degree of fairness and doesn't require centralizing state in a lock
server.

We have to flesh out a bit of initial infrastructure to support the
write locking protocol.  The roster manages cluster membership and
messaging and only understands mounts in the same kernel for now.
Creation needs to know which inodes to try and lock so we see the start
of per-mount free inode reservations.

The transformation of users is straight forward: they aquire the write
lock on the inodes they're working with instead of holding a
transaction.  The write lock machinery now manages transactions.

This passes single mount testing but that isn't saying much.  The next
step is to run multi-mount tests.

Signed-off-by: Zach Brown <zab@versity.com>
2016-05-23 17:25:06 -07:00