BLOCK_CACHE_DEBUG_CHANGED is too strict
|Reported by:||romain||Owned by:||axeld|
Ticket #3690 often stops in a block cache check detecting an invalid block buffer change. It seems that this detected error is in fact not an error. Here is what seems to happen:
- The fat filesystem is using the block cache without transactions.
- Block n is acquire through block_cache_get. This initializes the compare pointer in the block cache object, is_dirty is set to false.
- Block n is released through block_cache_put. This adds the block cache object to the unused_block list.
- Block n is acquired through block_get_get_writable. This sets is_dirty to true.
- block_notifier_and_writter wakes up. It will flush the block because it is marked "dirty", not "is_writting", not "busy" and not using transaction. write_cached_block sets "is_dirty" to false.
- Block n is modified in memory.
- Block n is released through block_cache_put: this breaks in put_cached_block because the block is marked as not "dirty" but has a compare pointer that differs from current data.
First I am not sure if this analysis is correct. If it is right this may be solved by marking the block as "is_writing" via a dedicated API, but this field does not seem to be used. So I am not sure what is the purpose of this flag. A second option is to clear the compare data in write_cached_block. This what is done in the provided patch.
In the current situation there is also the problem that we can write the block on disk while it is being modified in memory. I do not know if this has to be handle by the code using the block_cache or in the block_cache itself.