Yes, that is correct.  Let me explain the reasons why I believe this is currently needed and what protections are around it, and then please let me know what concerns you have/know of.

1. All reads that would attempt to update it are siloed into this single request, so there will only ever be a single thread trying to write a value to the container.
https://github.com/infinispan/infinispan/pull/1922/files#L0R254

2. L1 invalidation sees if there is a current read trying to update the L1 and tries to stop the update if it can, if not then it waits until the get updates the L1 before proceeding with the invalidation.
https://github.com/infinispan/infinispan/pull/1922/files#L0R333

3. Locking cannot be done for 2 reasons I have found so far - only 1 which could be fixed.
3a. L1 locking only does a try lock, which could fail under a concurrent write to the L1 from a read (could be fixed by increasing L1 timeout)
3b. Even with locking, L1 invalidation and a concurrent read ordering could be mixed up causing an inconsistency 
Node A owns k with v1
Node B does a remote get retrieve k, sees v1
Node A updates k to v2
Node B receives invalidation, locks k and removes nothing
Node B receives response from get locks k and puts v1 back in the L1

4. Happens-before memory semantics are guaranteed since the DefaultDataContainer always does a put of the value back into the map.

One thing I am not as sure about is rehashing and how that could affect it, since I don't know what locking guarantees that requires. @danberindei