LOCKING PROPOSAL, by sussman, striker, brane, rassilon, jerenkrantz, fitz [This document assumes that you understand the WebDAV locking model. Look in notes/webdav-general-summary to read about that.] Accomplishing two goals: 1. General WebDAV interoperabilty In particular, with basic versioning-unaware WebDAV (rfc 2518) clients that expect support for LOCK and UNLOCK methods, such as MS Office and OpenOffice. 2. Exclusive and advisory locking for regular svn clients. Many, many people want this feature. ------------------------ Filesystem changes ================== DAV Lock-Object: - owner - token (unique URI) - scope = {exclusive | shared} - type = write - depth = {0 | infinity} * locks are not secret! none of the fields, not even the 'token' field. * create a new 'lock' table in our db schema. fields: [path, owner, scope, type, depth, lock-id, txn-name] 'path' always implicitly refers to path in HEAD. locks always imply HEAD. * define new fs lock-object as an opaque baton. * svn_fs_lock(path, scope, owner, depth, type) ==> returns a lock-object. Creates a txn if necessary (i.e. in the case of an exclusive lock) [Possible lazy optimization: don't create txn till first write happens] * all svn_fs_* write routines now take ({txn-name | lock-object}, path) if lock-object: - lock-object is converted to a txn via table lookup. - make sure the path's lock object matches the one passed in. - do the infinity check ??? - do the write to the txn. else: - do the write to the txn, but make sure no exclusive locks already exist on the path, else throw error. * all svn_fs_* read routines still take (root, path), but in the special case where root represents the HEAD revision, each read routine must now look up 'path' in the lock table, because the latest version of the file might be in a txn. * svn_fs_unlock(lock-object) aborts the txn, removes lock object from the lock table. * svn_fs_commit_txn([list of lock-objects], regular-txn, cleanup-locks-p): - if called by normal concurrent caller (list == NULL): make sure every mutable node is not only out-of-date, but has no exclusive lock attached. else, throw a conflict. - if called by svn_fs_unlock() (list != NULL): no need to check for out-of-dateness or locks at all. new automerging logic: 1- Automerge the regular-txn, then the list of lock-txns. 2- Possibly loop back to step 1, not needing to remerge the list. 3- Begin db txn: commit and possibly remove all lock txns. * by the way, we want this behavior: an exclusive lock request should be denied if a shared lock already exists. don't know if DAV works this way or not. mod_dav_svn changes: =================== * LOCK method calls svn_fs_lock(). sends back lock URI to client. * client does GET: see svn_fs_* read routines above. * client does PUT with lock URI: see svn_write_* routines above. * UNLOCK method with lock URI: calls svn_fs_commit_txn(cleanup-locks-p = true) ------------------------------------------------------------------- Client changes: [this proposal is only a design for exclusive locks. the discussion about how to do shared "advisory" locks got very complex and heated, so we punted for now.] * call an exclusive lock a "lock" * 'svn st -u' should show not just out-of-date objects, but locks too. * 'svn lock foo.c' creates a lock object on the server. returns a lock-token to client, which is stored in the file's entry. the lock-token is the "auth" for the application, so that only the same application can commit or release the lock. * 'svn unlock foo.c' does the reverse of above. requires that the working copy have the lock-token. --force means you don't need the token (or rather, the client simply "discovers" it by querying the server for the token.) * 'svn commit' changes behavior: when driving the commit editor, the client supplies any lock tokens attached to committables. the commit_editor's close_edit() then passes the tokens as a list to svn_fs_commit_txn(). * 'svn locklist' (?name) asks the server to list all locks within a directory, or if a lock is attached to a file. * 'svn lockrecover' re-fetches the lock-id back into the working copy, in case you've checked out (or are using) a new working copy. * breaking of locks: 1. implement 'svnadmin rmlock' 2. server-side config decides whether users can break locks. if allowed, then 'svn unlock --break' would do so.