| |
| 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. |
| |
| |
| |
| |