Due to folios, the kernel will call scoutfs_writepages() and this
becomes unused. It could be ported but the helper function to call isn't
exported anymore.
Signed-off-by: Auke Kok <auke.kok@versity.com>
This works together with the dropped block_write_full_page(), allowing
us to drop the _writepage() method as long as we implement
_writepages(). Since v5.19-rc3-395-g67235182a41c. This used to be the
.migratepage() method.
Signed-off-by: Auke Kok <auke.kok@versity.com>
This caller of scoutfs_get_block is now actively used in el10 and
the WARN_ON_ONCE(!lock) in data.c:567 triggers. Add the
scoutfs_per_task_add_excl/del calls in scoutfs_readpage,
scoutfs_readpages, and scoutfs_readahead to register the cluster
lock for scoutfs_get_block_read.
Add unconditionally rather than guarded by the add_excl return,
since these methods can be reached reentrantly from a top-level
read that already added the entry. Skipping the I/O in that case
left BUG_ON(!list_empty(pages)) in scoutfs_readpages and the page
locked in scoutfs_readpage.
Move scoutfs_per_task_del before scoutfs_unlock to match the
ordering used by file.c read/write paths.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Since v5.1-rc3-29-gaa30f47cf666, and in el9, there are changes to reduce
the amount of boilerplate code needed to hook up lots of attribute files
using a .default_groups member. In el10, this is the required method as
.default_attrs has been removed. This touches every sysfs part that we
have.
Signed-off-by: Auke Kok <auke.kok@versity.com>
In v6.9-rc4-8-gead083aeeed9, this now takes a struct file argument,
adding to the ifdef salad we've got going on here.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Since ~v6.5-rc1-95-g0d72b92883c6, generic_fillattr() asks us to pass
through the request_mask from the caller. This allows it to only
request a subset.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Yet another major shrinker API evolution in v6.6-rc4-53-gc42d50aefd17.
The struct shrinker now has to be dynamically allocated. This is
purposely a backwards incompatible break.
Collapse the previous KC_ALLOC_SHRINKER, KC_INIT_SHRINKER_FUNCS,
and KC_REGISTER_SHRINKER macros into a single KC_SETUP_SHRINKER
macro. The three operations have to happen in different orders on
different kernel APIs (the name is needed at alloc time on el10
and at register time on KC_SHRINKER_NAME kernels), so coupling
them keeps the ordering correct per kernel.
Add KC_SHRINKER_IS_NULL so callers can detect shrinker_alloc()
failure on el10 and return -ENOMEM. The macro compiles to a
constant 0 on older kernels where the shrinker is an embedded
struct that cannot fail allocation.
Signed-off-by: Auke Kok <auke.kok@versity.com>
The return type always has been int, so, we just need to add return
value checking and do something with it. We could return -ENOMEM here as
well, either way it'll fall all the way through no matter what.
This is since v6.4-rc2-100-g83f2caaaf9cb.
Signed-off-by: Auke Kok <auke.kok@versity.com>
In v6.8-9146-gc759e609030c, the second argument for __assign_str() was
removed, as the second parameter is already derived from the __string()
definition and no longer needed. We have to do a little digging in
headers here to find the definition.
Note the missing `;` at a few places... it has to be added now.
Signed-off-by: Auke Kok <auke.kok@versity.com>
v6.9-rc4-29-g203c1ce0bb06 removes bd_inode. The canonical replacement is
bd_mapping->host, where applicable. We have one use where we directly
need the mapping instead of the inode, as well.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Instead of defining a struct that ends with a flex array member with
`val[0]`, the compiler now balks at this since technically, the spec
considers this unsanitary. As a result however, we can't memcpy to
`struct->val` since that's a pointer and now we're writing something of
a different length (u8's in our case) into something that's of pointer
size. So there we have to do the opposite, and memcpy to
&struct->val[0].
Signed-off-by: Auke Kok <auke.kok@versity.com>
In v6.12-rc1-3-g5f60d5f6bbc1, asm/unaligned.h only included
asm-generic/unaligned.h and that was cleaned up from architecture
specific things. Everyone should now include linux/unaligned.h and the
former include was removed.
A quick peek at server.c shows that while included, it no longer uses
any function from this header at all, so it can just be dropped.
Signed-off-by: Auke Kok <auke.kok@versity.com>
In v6.6-rc5-1-g077c212f0344, one can no longer directly access the
inode m_time and a_time etc. We have to go through these static inline
functions to get to them. The compat is matched closely to mimic the
new functions.
Further back, ctime accessors were added in v6.5-rc1-7-g9b6304c1d537,
and need to be applied as well.
Signed-off-by: Auke Kok <auke.kok@versity.com>
In v6.1-rc5-2-ge9a688bcb193, get_random_u32_below() becomes available and
can start replacing prandom_bytes_max(). Switch to it where we can.
get_random_bytes() has been available since el7, so also replace
prandom_bytes() where we're using it.
Signed-off-by: Auke Kok <auke.kok@versity.com>
In RHEL10, the grep version is bumped from 3.6 to 3.11, and grep
no longer recognizes the \Z character anymore.
We have 2 solutions: We can either choose to use `grep -P` to
continue using it, or, alternatively, we can choose a different
`null` match to have an effectively empty exclude list.
The latter seems easy enough: By default, we can just exclude
empty lines ("^$") obtaining the exact same behavior as before.
Signed-off-by: Auke Kok <auke.kok@versity.com>
This is somewhat cumbersome, we want to see the error message, but the
format changes enough to make this messy. We opt to change the golden to
the new format, which only shows one of the arguments in its error
output: the thing that cannot be overwritten. We then add a filter that
rewrites the old output format with sed patterns to be exactly like the
new format, so this will work everywhere again, without changing or
adding filters to obscure error messages.
Signed-off-by: Auke Kok <auke.kok@versity.com>
The new format in el10 has non-hex output, separated by a comma. Add the
additional filter string so this works as expected.
Signed-off-by: Auke Kok <auke.kok@versity.com>
El9.8 backported the upstream v6.15.* rename of from_timer to
timer_container_of. Switch the two callers in fence.c and recov.c
to the new style and add a simple kcompat define for older kernels.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Ramps up data preallocation based on the number of online
blocks. This results in a simple 2<<n block allocation pattern
until n=11 (2048) - the default value of data_prealloc_blocks.
Signed-off-by: Auke Kok <auke.kok@versity.com>
When scoutfs_setattr truncates a file with offline extents, it unlocks
the inode lock before calling scoutfs_data_wait to wait for the data
to be staged. If data_wait returns any error, the code jumps to 'goto
out' which calls scoutfs_unlock again, thus double-unlocking the lock.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Skews a totl twice, restore it, and intersperse setfattr/unlink to
exercise both injected and naturally-produced deltas.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Run concurrent quota add/del on one mount against rapid file
creation and deletion on both mounts to exercise the race fixed
in the previous commit.
Signed-off-by: Auke Kok <auke.kok@versity.com>
A quota check holds the quota cluster lock for READ and marks the
cached ruleset EBUSY while loading rules. A quota mod on the same
mount holds the lock for WRITE (compatible with the local READ)
and calls scoutfs_quota_invalidate(), tripping
BUG_ON(rs == ERR_PTR(-EBUSY)).
Make invalidate skip EBUSY so the reader's claim is preserved, and
have scoutfs_quota_mod_rule wait for the reader to finish before
calling invalidate. Without the wait, the in-flight reader would
publish its stale ruleset after invalidate runs, leaving the cache
stale until the next invalidation.
Signed-off-by: Auke Kok <auke.kok@versity.com>
When searching for the next least merge range we need to sweep all the
stored items because they're interleaved with respect to key sorting
because we've clobbered the zone.
To search all of them we need to start from 0, not from the caller's
start key after setting the zone. If the caller happens to provide a
start key with a small zone but large other fields (totl keys with
sufficiently large identifiers) we can miss ranges.
Signed-off-by: Zach Brown <zab@zabbo.net>
I'm seeing consistent CPU soft lockups in block_free_work on
my bare metal system that aren't reached by VM instances. The
reason is that the bare metal machine has a ton more memory
available causing the block free work queue to grow much
larger in size, and then it has so much work that it can take 30+
seconds before it goes through it all.
This is all with a debug kernel. A non debug kernel will likely
zoom through the outstanding work here at a much faster rate.
Signed-off-by: Auke Kok <auke.kok@versity.com>
block_submit_bio will return -ENOLINK if called during a forced
shutdown, the bio is never submitted, and thus no completion callback
will fire to set BLOCK_BIT_ERROR. Any other task waiting for this
specific bp will end up waiting forever.
To fix, fall through to the existing block_end_io call on the
error path instead of returning directly. That means moving
the forcing_unmount check past the setup calls so block_end_io's
bookkeeping stays balanced. block_end_io then sets BLOCK_BIT_ERROR
and wakes up waiters just as it would on a failed async completion.
Signed-off-by: Auke Kok <auke.kok@versity.com>
scoutfs_quota_mod_rule calls scoutfs_item_create/delete which use
the transaction allocator but it never held it. Without the hold,
a concurrent transaction commit can call scoutfs_alloc_init to
reinitialize the allocator while dirty_alloc_blocks is in the middle
of setting up the freed list block. This overwrites alloc->freed with
the server's fresh (empty) state, causing a blkno mismatch BUG_ON
in list_block_add.
Reproduced by stressing concurrent quota add/del operations across
mounts. Crashdump analysis confirms dirty_list_block COW'd a freed
block (fr_old=9842, new blkno=9852) but by the time list_block_add
ran, freed.ref.blkno was 0 with first_nr=0 and total_nr=0: the freed
list head had been zeroed by a concurrent alloc_init.
Fix by adding scoutfs_hold_trans/scoutfs_release_trans around the
item modification in scoutfs_quota_mod_rule, preventing transaction
commit from racing with the allocator use.
Rename the 'unlock' label to 'release' since 'out' now directly
does the unlock. The unlock safely handles a NULL lock.
Signed-off-by: Auke Kok <auke.kok@versity.com>
A malformed message encountered here increases the counter, but doesn't
tear down the connection because of the nested for loops. The comments
indicate that that is the expected behavior - a misbehaving client
should not be tolerated.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Clang's scan-build found this leak when we get an invalidation
for a lock we no longer have. Free ireq to fix.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Clang flow analysis flags resp_data in process_response as possibly
uninitialized when find_request returns NULL.
kmod/src/net.c:533:6: error: variable 'resp_data' is used uninitialized
whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
In practice the read is harmless because resp_func stays NULL in that
path and call_resp_func only dereferences resp_data when resp_func is
non-NULL. Initialize at declaration.
Signed-off-by: Auke Kok <auke.kok@versity.com>
Without overly broad filtering empty lines from dmesg, filter
them so dmesg.new doesn't trigger a test failure. I don't want
to overly process dmesg, so do this as late as possible.
The xfs lockdep patterns can forget a leading/trailing empty line,
causing a failure despite the explicit removal of the lockdep
false positive.
Signed-off-by: Auke Kok <auke.kok@versity.com>
This already caught xfs_nondir_ilock_class, but recent CI runs
have been hitting xfs_dir_ilock_class, too.
Signed-off-by: Auke Kok <auke.kok@versity.com>