Eliminate lock c->dirtylk which is the cause of fossil hanging while
taking a snapshot, as mentioned in BUGS of fossilcons(8).
Dirtylk prevents any thread from dirtying new blocks while flushThread
is writing old dirty blocks to disk. Deadlock occurs when a thread T
tries to dirty a block B while holding a lock on an already-dirty block
A. T can't proceed until c->dirtylk is unlocked, which won't happen
until flushThread has written out block A; but block A can't be written
out until T unlocks it.
Dirtylk serves no useful purpose: whenever cacheFlush is called with
wait=1, a write lock is already held on the "epoch lock" fs->elk, which
prevents any new 9p requests from touching the file system. Any
dirtying of blocks is limited to internal fossil activities for requests
which were already in progress when cacheFlush was called, and thus
strictly bounded even without c->dirtylk.
|