RenameDirectory state machine was not handling target not found correctly.
This would have caused asserts (which result in crashes in production builds)
There was also a bug in the rollback logic which would have caused a lingering
lock on the source link. While breaking assumptions this was a benign bug as
any operation on that directory would try and succeed acquiring this lock again.
It would succeed as lock requests are idempotent.
* kmod: minor write path fixes
We didn't actually see these happen in production.
Fix 1:
From kernel code it looks like copy_page_from_iter can not return 0 in
normal cases but our code should still cover the case if this changes in
the future.
Fix 2:
-ENOMEM was other error where we could write things partially in which
case we would not return written and we would end up at wrong offset.
It's simpler to just return written if we managed to write anything
and surface the error on subsequent call in which we will fail early.
* kmod: add BUG_ON for unexpected span pages
_queuesWithWork can go negative.
Consider the following scenario
there are 2 queues first one has work and
consumer is active.
1. producer adds work to queue 1 and sees it needs
to update _queuesWithWork but is preempted
2. consumer consumes work from queue 0 and
decrements _queuesWithWork to 0
3. consumer continues consuming and consumes all
work from queue 1
4. consumer decrements _queuesWithWork to -1
5. only now producer updates _queuesWithWork to 0
It could be also solved by removeWork returning new value
and then consumer stopping consumption if it is 0.
The new code reads only what's needed in the happy path, and does not
fall back to reading the entire span when doing RS recovery (but it
might read slightly more than necessary in that case).
There's no lazy CRC check or page cache reading yet.