📄 lock.c
字号:
const char *token; svn_boolean_t break_lock;};static svn_error_t *txn_body_unlock(void *baton, trail_t *trail){ struct unlock_args *args = baton; const char *lock_token; svn_lock_t *lock; /* This could return SVN_ERR_FS_BAD_LOCK_TOKEN or SVN_ERR_FS_LOCK_EXPIRED. */ SVN_ERR(svn_fs_bdb__lock_token_get(&lock_token, trail->fs, args->path, trail, trail->pool)); /* If not breaking the lock, we need to do some more checking. */ if (!args->break_lock) { /* Sanity check: The lock token must exist, and must match. */ if (args->token == NULL) return svn_fs_base__err_no_lock_token(trail->fs, args->path); else if (strcmp(lock_token, args->token) != 0) return svn_fs_base__err_no_such_lock(trail->fs, args->path); SVN_ERR(svn_fs_bdb__lock_get(&lock, trail->fs, lock_token, trail, trail->pool)); /* There better be a username attached to the fs. */ if (!trail->fs->access_ctx || !trail->fs->access_ctx->username) return svn_fs_base__err_no_user(trail->fs); /* And that username better be the same as the lock's owner. */ if (strcmp(trail->fs->access_ctx->username, lock->owner) != 0) return svn_fs_base__err_lock_owner_mismatch (trail->fs, trail->fs->access_ctx->username, lock->owner); } /* Remove a row from each of the locking tables. */ SVN_ERR(delete_lock_and_token(lock_token, args->path, trail)); return SVN_NO_ERROR;}svn_error_t *svn_fs_base__unlock(svn_fs_t *fs, const char *path, const char *token, svn_boolean_t break_lock, apr_pool_t *pool){ struct unlock_args args; SVN_ERR(svn_fs_base__check_fs(fs)); args.path = svn_fs_base__canonicalize_abspath(path, pool); args.token = token; args.break_lock = break_lock; return svn_fs_base__retry_txn(fs, txn_body_unlock, &args, pool);}svn_error_t *svn_fs_base__get_lock_helper(svn_lock_t **lock_p, const char *path, trail_t *trail, apr_pool_t *pool){ const char *lock_token; svn_error_t *err; err = svn_fs_bdb__lock_token_get(&lock_token, trail->fs, path, trail, pool); /* We've deliberately decided that this function doesn't tell the caller *why* the lock is unavailable. */ if (err && ((err->apr_err == SVN_ERR_FS_NO_SUCH_LOCK) || (err->apr_err == SVN_ERR_FS_LOCK_EXPIRED) || (err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN))) { svn_error_clear(err); *lock_p = NULL; return SVN_NO_ERROR; } else SVN_ERR(err); /* Same situation here. */ err = svn_fs_bdb__lock_get(lock_p, trail->fs, lock_token, trail, pool); if (err && ((err->apr_err == SVN_ERR_FS_LOCK_EXPIRED) || (err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN))) { svn_error_clear(err); *lock_p = NULL; return SVN_NO_ERROR; } else SVN_ERR(err); return err;}struct lock_token_get_args{ svn_lock_t **lock_p; const char *path;};static svn_error_t *txn_body_get_lock(void *baton, trail_t *trail){ struct lock_token_get_args *args = baton; return svn_fs_base__get_lock_helper(args->lock_p, args->path, trail, trail->pool);}svn_error_t *svn_fs_base__get_lock(svn_lock_t **lock, svn_fs_t *fs, const char *path, apr_pool_t *pool){ struct lock_token_get_args args; SVN_ERR(svn_fs_base__check_fs(fs)); args.path = svn_fs_base__canonicalize_abspath(path, pool); args.lock_p = lock; return svn_fs_base__retry_txn(fs, txn_body_get_lock, &args, pool);}struct locks_get_args{ const char *path; svn_fs_get_locks_callback_t get_locks_func; void *get_locks_baton;};static svn_error_t *txn_body_get_locks(void *baton, trail_t *trail){ struct locks_get_args *args = baton; return svn_fs_bdb__locks_get(trail->fs, args->path, args->get_locks_func, args->get_locks_baton, trail, trail->pool);}svn_error_t *svn_fs_base__get_locks(svn_fs_t *fs, const char *path, svn_fs_get_locks_callback_t get_locks_func, void *get_locks_baton, apr_pool_t *pool){ struct locks_get_args args; SVN_ERR(svn_fs_base__check_fs(fs)); args.path = svn_fs_base__canonicalize_abspath(path, pool); args.get_locks_func = get_locks_func; args.get_locks_baton = get_locks_baton; return svn_fs_base__retry_txn(fs, txn_body_get_locks, &args, pool);}/* Utility function: verify that a lock can be used. If no username is attached to the FS, return SVN_ERR_FS_NO_USER. If the FS username doesn't match LOCK's owner, return SVN_ERR_FS_LOCK_OWNER_MISMATCH. If FS hasn't been supplied with a matching lock-token for LOCK, return SVN_ERR_FS_BAD_LOCK_TOKEN. Otherwise return SVN_NO_ERROR. */static svn_error_t *verify_lock(svn_fs_t *fs, svn_lock_t *lock, apr_pool_t *pool){ if ((! fs->access_ctx) || (! fs->access_ctx->username)) return svn_error_createf (SVN_ERR_FS_NO_USER, NULL, _("Cannot verify lock on path '%s'; no username available"), lock->path); else if (strcmp(fs->access_ctx->username, lock->owner) != 0) return svn_error_createf (SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL, _("User %s does not own lock on path '%s' (currently locked by %s)"), fs->access_ctx->username, lock->path, lock->owner); else if (apr_hash_get(fs->access_ctx->lock_tokens, lock->token, APR_HASH_KEY_STRING) == NULL) return svn_error_createf (SVN_ERR_FS_BAD_LOCK_TOKEN, NULL, _("Cannot verify lock on path '%s'; no matching lock-token available"), lock->path); return SVN_NO_ERROR;}/* This implements the svn_fs_get_locks_callback_t interface, where BATON is just an svn_fs_t object. */static svn_error_t *get_locks_callback(void *baton, svn_lock_t *lock, apr_pool_t *pool){ return verify_lock(baton, lock, pool);}/* The main routine for lock enforcement, used throughout libsvn_fs_base. */svn_error_t *svn_fs_base__allow_locked_operation(const char *path, svn_boolean_t recurse, trail_t *trail, apr_pool_t *pool){ if (recurse) { /* Discover all locks at or below the path. */ SVN_ERR(svn_fs_bdb__locks_get(trail->fs, path, get_locks_callback, trail->fs, trail, pool)); } else { svn_lock_t *lock; /* Discover any lock attached to the path. */ SVN_ERR(svn_fs_base__get_lock_helper(&lock, path, trail, pool)); if (lock) SVN_ERR(verify_lock(trail->fs, lock, pool)); } return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -