Skip to content

Fix refresh_gen reading wrong lock for mode - #326

Open
aversecat wants to merge 1 commit into
mainfrom
auke/refresh_gen_cached_inode
Open

Fix refresh_gen reading wrong lock for mode#326
aversecat wants to merge 1 commit into
mainfrom
auke/refresh_gen_cached_inode

Conversation

@aversecat

Copy link
Copy Markdown
Contributor

This function determines if the local inode is cached under a different mode in the client local state. On receiving an updated mode it should therefore inspect it's own lock mode and not the mode passed by the server, which can have a different view after recovery.

This was caught twice in CI by
BUG_ON(atomic64_read(&si->last_refreshed) > refresh_gen) in scoutfs_inode_refresh in scoutfs_inode_refresh() during the lock-recover-invalidate test - our most flakey CI test by a mile.

Pulling the core revealed the lock was mode=WRITE but refresh_gen=0 with invalidate_pending=1, which means it should have had refresh_gen assigned on the null to write transition. This happens because it's only assigned if the server-supplied lock changes, because it doesn't look at the client's view of the state:

!can_read(nl->old_mode) && can_read(nl->new_mode)

Exactly the thing that can go wrong after a server fence/recovery, as exposed by this CI test.

This function determines if the local inode is cached under
a different mode in the client local state. On receiving an
updated mode it should therefore inspect it's own lock mode
and not the mode passed by the server, which can have a different
view after recovery.

This was caught twice in CI by
`BUG_ON(atomic64_read(&si->last_refreshed) > refresh_gen) in
scoutfs_inode_refresh` in scoutfs_inode_refresh() during the
lock-recover-invalidate test - our most flakey CI test by a mile.

Pulling the core revealed the lock was mode=WRITE but refresh_gen=0 with
invalidate_pending=1, which means it should have had refresh_gen
assigned on the null to write transition. This happens because it's only
assigned if the server-supplied lock changes, because it doesn't look
at the client's view of the state:

  `!can_read(nl->old_mode) && can_read(nl->new_mode)`

Exactly the thing that can go wrong after a server fence/recovery, as
exposed by this CI test.

Signed-off-by: Auke Kok <auke.kok@versity.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant