Here's the general jist of our original locking design for libsvn_fs.
I'm using casual language to describe it, purposely not going into too
much detail, so that it can be easily compared to other designs. (We
*have* done some detailed API spec'ing, which we can describe later.)
Also, remember that this is not a UI discussion. For the moment,
we're deliberately avoiding chat about how a Subversion client would
The main idea is: a user "locks" a file in the filesystem. This means
than a new (potentially) long-lived transaction is created in the
filesystem which represents this one locked file. There's a 1-to-1
mapping between a locked file and a lock-txn. We keep this mapping in
a new 'locks' table that maps a path to a txn-id.
* When somebody tries to write to any path, the filesystem checks to
see if a lock-txn already exists for it. If so, and if the writer
owns the lock-txn, then the new data is put into the lock-txn,
overwriting whatever was previously there. (And obviously, if the
writer doesn't own the lock-txn, the write is rejected.)
* When somebody tries to read from a non-HEAD revision, everything
is normal. When somebody tries to read from the HEAD revision,
the system treats locked paths specially: instead of pulling the
file's data out of the HEAD revision, it gets pulled out of the
* The lock-owner ultimately ends up "unlocking" the file, which
causes the lock-txn to be committed. Either that, or the lock
owner destroys the lock, which aborts the lock-txn, and all
changes are lost.
The net affect of this (from a WebDAV client's point of view) is that
a user can LOCK a file indefinitely and do any number of PUTs to it.
People who do checkouts of HEAD, or just GETs of the file, will always
see the file's latest text (that is, whatever text was most recently
PUT by the lock-owner.) If somebody else tries to do a normal
Subversion commit which includes a change the locked file, the entire
commit will be rejected. Ultimately the owner UNLOCKs the file and a
new revision is created.
Really, we envision at least two APIs to end the lifecycle of a
1. A call to svn_fs_unlock() will attempt to commit a single
lock-txn and create a new revision.
2. A new svn_fs_commit_txn2() function will take a "main" txn as
usual, but also take a list of lock-txns. It would first merge
the lock-txns into the main txn, then merge the whole thing with
the HEAD revision.
Depending on how we design the new commit function, we might also want
to give users the option to "hold on" to their lock-txns after the
commit completes. (In other words, delete the temporary main txn, but
not the lock-txns.)
There's at least one annoyance with this design: operations like
'move' and 'delete' must verify that no locks exist for paths below
the deleted/moved thing. This requires scanning the table of locked
paths, or doing a 'reverse directory walk'. Actually, it may be slow
in general to scan a locks-table -- we're talking about doing it for
every read of a path@HEAD and every write of a path.
To unsubscribe, e-mail: email@example.com
For additional commands, e-mail: firstname.lastname@example.org
Received on Wed May 19 23:57:46 2004