You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/07/25 16:43:45 UTC
svn commit: r1506992 [1/3] - in
/subversion/branches/fsfs-format7/subversion: include/ libsvn_fs_fs/
Author: stefan2
Date: Thu Jul 25 14:43:44 2013
New Revision: 1506992
URL: http://svn.apache.org/r1506992
Log:
On the fsfs-format7 branch: Manually sync with fsfs-improvements
(i.e. this is not a merge). Things will probably not compile.
Modified:
subversion/branches/fsfs-format7/subversion/include/svn_error_codes.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/hotcopy.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/lock.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/rep-cache-db.sql
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/verify.c
Modified: subversion/branches/fsfs-format7/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/include/svn_error_codes.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/include/svn_error_codes.h (original)
+++ subversion/branches/fsfs-format7/subversion/include/svn_error_codes.h Thu Jul 25 14:43:44 2013
@@ -807,24 +807,24 @@ SVN_ERROR_START
"Could not initialize the revprop caching infrastructure.")
/** @since New in 1.9. */
- SVN_ERRDEF(SVN_ERR_FS_ITEM_INDEX_CORRUPTION,
+ SVN_ERRDEF(SVN_ERR_FS_MALFORMED_TXN_ID,
SVN_ERR_FS_CATEGORY_START + 53,
- "Corrupt index file.")
+ "Malformed transaction ID string.")
/** @since New in 1.9. */
- SVN_ERRDEF(SVN_ERR_FS_ITEM_INDEX_REVISION,
+ SVN_ERRDEF(SVN_ERR_FS_ITEM_INDEX_CORRUPTION,
SVN_ERR_FS_CATEGORY_START + 54,
- "Revision not covered by index.")
+ "Corrupt index file.")
/** @since New in 1.9. */
- SVN_ERRDEF(SVN_ERR_FS_ITEM_INDEX_OVERFLOW,
+ SVN_ERRDEF(SVN_ERR_FS_ITEM_INDEX_REVISION,
SVN_ERR_FS_CATEGORY_START + 55,
- "Item index too large for this revision.")
+ "Revision not covered by index.")
/** @since New in 1.9. */
- SVN_ERRDEF(SVN_ERR_FS_MALFORMED_TXN_ID,
+ SVN_ERRDEF(SVN_ERR_FS_ITEM_INDEX_OVERFLOW,
SVN_ERR_FS_CATEGORY_START + 56,
- "Malformed transaction ID string.")
+ "Item index too large for this revision.")
/** @since New in 1.9. */
SVN_ERRDEF(SVN_ERR_FS_CONTAINER_INDEX,
@@ -1552,7 +1552,10 @@ SVN_ERROR_START
SVN_ERR_RA_SERF_CATEGORY_START + 2,
"Initialization of the GSSAPI context failed")
- /** @since New in 1.7. */
+ /** @since New in 1.7.
+ * @note When @c svn_error_t.apr_err is set to this,
+ * @c svn_error_t.child->apr_err is a serf error code, not a Subversion
+ * one! */
SVN_ERRDEF(SVN_ERR_RA_SERF_WRAPPED_ERROR,
SVN_ERR_RA_SERF_CATEGORY_START + 3,
"While handling serf response:")
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c Thu Jul 25 14:43:44 2013
@@ -34,7 +34,6 @@
#include "pack.h"
#include "util.h"
#include "temp_serializer.h"
-#include "index.h"
#include "../libsvn_fs/fs-loader.h"
@@ -42,7 +41,7 @@
/* Defined this to enable access logging via dgb__log_access
#define SVN_FS_FS__LOG_ACCESS
-*/
+ */
/* Data / item types.
*/
@@ -59,26 +58,25 @@
* For pre-format7 repos, the display will be restricted.
*/
static svn_error_t *
-dgb__log_access(svn_fs_t *fs,
- svn_revnum_t revision,
- apr_uint64_t item_index,
- void *item,
- int item_type,
- apr_pool_t *scratch_pool)
+dbg_log_access(svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_off_t offset,
+ void *item,
+ int item_type,
+ apr_pool_t *scratch_pool)
{
/* no-op if this macro is not defined */
#ifdef SVN_FS_FS__LOG_ACCESS
fs_fs_data_t *ffd = fs->fsap_data;
- apr_off_t offset = -1;
- apr_uint32_t sub_item = 0;
static const char *types[] = {"<n/a>", "rep ", "node ", "chgs "};
const char *description = "";
const char *type = types[item_type];
const char *pack = "";
+ apr_off_t offset_in_rev = offset;
/* determine rev / pack file offset */
- SVN_ERR(svn_fs_fs__item_offset(&offset, &sub_item, fs, revision, NULL,
- item_index, scratch_pool));
+ SVN_ERR(svn_fs_fs__item_offset(&offset, fs, revision, offset,
+ scratch_pool));
/* constructing the pack file description */
if (revision < ffd->min_unpacked_rev)
@@ -120,7 +118,7 @@ dgb__log_access(svn_fs_t *fs,
description = apr_psprintf(scratch_pool,
" DELTA against %ld/%" APR_UINT64_T_FMT,
header->base_revision,
- header->base_item_index);
+ header->base_offset);
}
else if (item_type == SVN_FS_FS__ITEM_TYPE_CHANGES && item != NULL)
{
@@ -136,10 +134,9 @@ dgb__log_access(svn_fs_t *fs,
}
}
- /* reduced logging for format 6 and earlier */
printf("%5s%10" APR_UINT64_T_HEX_FMT " %s %7ld %7" APR_UINT64_T_FMT \
" %s\n",
- pack, (apr_uint64_t)(offset), type, revision, item_index,
+ pack, (apr_uint64_t)(offset), type, revision, offset_in_rev,
description);
#endif
@@ -147,17 +144,13 @@ dgb__log_access(svn_fs_t *fs,
return SVN_NO_ERROR;
}
-/* Convenience wrapper around svn_io_file_aligned_seek, taking filesystem
- FS instead of a block size. */
+/* Convenience wrapper around svn_io_file_aligned_seek. */
static svn_error_t *
aligned_seek(apr_file_t *file,
- apr_off_t *buffer_start,
apr_off_t offset,
apr_pool_t *pool)
{
- const apr_size_t default_block_size = 4096;
- return svn_error_trace(svn_io_file_aligned_seek(file, default_block_size,
- buffer_start, offset,
+ return svn_error_trace(svn_io_file_aligned_seek(file, 0, NULL, offset,
pool));
}
@@ -168,19 +161,16 @@ static svn_error_t *
open_and_seek_revision(apr_file_t **file,
svn_fs_t *fs,
svn_revnum_t rev,
- apr_uint64_t item,
+ apr_off_t offset,
apr_pool_t *pool)
{
apr_file_t *rev_file;
- apr_off_t offset = -1;
- apr_uint32_t sub_item = 0;
SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, rev, pool));
- SVN_ERR(svn_fs_fs__item_offset(&offset, &sub_item, fs, rev, NULL, item,
- pool));
- SVN_ERR(aligned_seek(rev_file, NULL, offset, pool));
+ SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev, offset, pool));
+ SVN_ERR(aligned_seek(rev_file, offset, pool));
*file = rev_file;
@@ -197,17 +187,13 @@ open_and_seek_transaction(apr_file_t **f
apr_pool_t *pool)
{
apr_file_t *rev_file;
- apr_off_t offset;
- apr_uint32_t sub_item = 0;
SVN_ERR(svn_io_file_open(&rev_file,
svn_fs_fs__path_txn_proto_rev(fs, &rep->txn_id,
pool),
APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));
- SVN_ERR(svn_fs_fs__item_offset(&offset, &sub_item, fs, SVN_INVALID_REVNUM,
- &rep->txn_id, rep->offset, pool));
- SVN_ERR(aligned_seek(rev_file, NULL, offset, pool));
+ SVN_ERR(aligned_seek(rev_file, rep->offset, pool));
*file = rev_file;
@@ -284,7 +270,7 @@ get_node_revision_body(node_revision_t *
else
{
/* noderevs in rev / pack files can be cached */
- const svn_fs_fs__id_part_t *rev_item = svn_fs_fs__id_rev_item(id);
+ const svn_fs_fs__id_part_t *rev_item = svn_fs_fs__id_rev_offset(id);
pair_cache_key_t key;
key.revision = rev_item->revision;
key.second = rev_item->number;
@@ -302,18 +288,17 @@ get_node_revision_body(node_revision_t *
return SVN_NO_ERROR;
}
- /* someone needs to read the data from this file: */
- err = open_and_seek_revision(&revision_file, fs,
- rev_item->revision,
- rev_item->number,
- pool);
-
- /* pre-format7 reading, parsing and caching */
+ /* read the data from disk */
+ SVN_ERR(open_and_seek_revision(&revision_file, fs,
+ rev_item->revision,
+ rev_item->number,
+ pool));
SVN_ERR(svn_fs_fs__read_noderev(noderev_p,
svn_stream_from_aprfile2(revision_file,
FALSE,
pool),
pool));
+
/* Workaround issue #4031: is-fresh-txn-root in revision files. */
(*noderev_p)->is_fresh_txn_root = FALSE;
@@ -334,7 +319,7 @@ svn_fs_fs__get_node_revision(node_revisi
const svn_fs_id_t *id,
apr_pool_t *pool)
{
- const svn_fs_fs__id_part_t *rev_item = svn_fs_fs__id_rev_item(id);
+ const svn_fs_fs__id_part_t *rev_offset = svn_fs_fs__id_rev_offset(id);
svn_error_t *err = get_node_revision_body(noderev_p, fs, id, pool);
if (err && err->apr_err == SVN_ERR_FS_CORRUPT)
@@ -345,18 +330,17 @@ svn_fs_fs__get_node_revision(node_revisi
id_string->data);
}
- SVN_ERR(dgb__log_access(fs,
- rev_item->revision,
- rev_item->number,
- *noderev_p,
- SVN_FS_FS__ITEM_TYPE_NODEREV,
- pool));
+ SVN_ERR(dbg_log_access(fs,
+ rev_offset->revision,
+ rev_offset->number,
+ *noderev_p,
+ SVN_FS_FS__ITEM_TYPE_NODEREV,
+ pool));
return svn_error_trace(err);
}
-
/* Given a revision file REV_FILE, opened to REV in FS, find the Node-ID
of the header located at OFFSET and store it in *ID_P. Allocate
temporary variables from POOL. */
@@ -370,7 +354,7 @@ get_fs_id_at_offset(svn_fs_id_t **id_p,
{
node_revision_t *noderev;
- SVN_ERR(aligned_seek(rev_file, NULL, offset, pool));
+ SVN_ERR(aligned_seek(rev_file, offset, pool));
SVN_ERR(svn_fs_fs__read_noderev(&noderev,
svn_stream_from_aprfile2(rev_file, TRUE,
pool),
@@ -387,6 +371,7 @@ get_fs_id_at_offset(svn_fs_id_t **id_p,
return SVN_NO_ERROR;
}
+
/* Given an open revision file REV_FILE in FS for REV, locate the trailer that
specifies the offset to the root node-id and to the changed path
information. Store the root node offset in *ROOT_OFFSET and the
@@ -395,10 +380,10 @@ get_fs_id_at_offset(svn_fs_id_t **id_p,
If PACKED is true, REV_FILE should be a packed shard file.
### There is currently no such parameter. This function assumes that
- is_packed_rev(FS, REV) will indicate whether REV_FILE is a packed
- file. Therefore FS->fsap_data->min_unpacked_rev must not have been
- refreshed since REV_FILE was opened if there is a possibility that
- revision REV may have become packed since then.
+ svn_fs_fs__is_packed_rev(FS, REV) will indicate whether REV_FILE is
+ a packed file. Therefore FS->fsap_data->min_unpacked_rev must not
+ have been refreshed since REV_FILE was opened if there is a
+ possibility that revision REV may have become packed since then.
TODO: Take an IS_PACKED parameter instead, in order to remove this
requirement.
@@ -449,8 +434,7 @@ get_root_changes_offset(apr_off_t *root_
SVN_ERR(svn_io_file_seek(rev_file, seek_relative, &offset, pool));
trailer->len = trailer->blocksize-1;
- offset -= trailer->len;
- SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &offset, pool));
+ SVN_ERR(aligned_seek(rev_file, offset - trailer->len, pool));
/* Read in this last block, from which we will identify the last line. */
SVN_ERR(svn_io_file_read(rev_file, trailer->data, &trailer->len, pool));
@@ -486,14 +470,14 @@ svn_fs_fs__rev_get_root(svn_fs_id_t **ro
SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
SVN_ERR(svn_cache__get((void **) root_id_p, &is_cached,
- ffd->rev_root_id_cache, &rev, pool));
+ ffd->rev_root_id_cache, &rev, pool));
if (is_cached)
return SVN_NO_ERROR;
SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&revision_file, fs, rev, pool));
+ SVN_ERR(get_root_changes_offset(&root_offset, NULL, revision_file, fs, rev,
+ pool));
- SVN_ERR(get_root_changes_offset(&root_offset, NULL, revision_file,
- fs, rev, pool));
SVN_ERR(get_fs_id_at_offset(&root_id, revision_file, fs, rev,
root_offset, pool));
@@ -519,7 +503,8 @@ typedef struct shared_file_t
/* file system to open the file in */
svn_fs_t *fs;
- /* revision contained in the file */
+ /* a revision contained in the FILE. Since this file may be shared,
+ that value may be different from REP_STATE_T->REVISION. */
svn_revnum_t revision;
/* pool to use when creating the FILE. This guarantees that the file
@@ -548,16 +533,70 @@ typedef struct rep_state_t
apr_size_t header_size;
apr_off_t start; /* The starting offset for the raw
svndiff/plaintext data minus header.
- -1 if the offset is yet unknwon. */
- /* sub-item index in case the rep is containered */
- apr_uint32_t sub_item;
- apr_off_t current;/* The current offset relative to start. */
- apr_off_t size; /* Final value of CURRENT. */
+ -1 if the offset is yet unknown. */
+ apr_off_t current;/* The current offset relative to START. */
+ apr_off_t size; /* The on-disk size of the representation. */
int ver; /* If a delta, what svndiff version?
-1 for unknown delta version. */
int chunk_index; /* number of the window to read */
} rep_state_t;
+/* Open FILE->FILE and FILE->STREAM if they haven't been opened, yet. */
+static svn_error_t*
+auto_open_shared_file(shared_file_t *file)
+{
+ if (file->file == NULL)
+ {
+ SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&file->file, file->fs,
+ file->revision, file->pool));
+ file->stream = svn_stream_from_aprfile2(file->file, TRUE, file->pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Set RS->START to the begin of the representation raw in RS->FILE->FILE,
+ if that hasn't been done yet. Use POOL for temporary allocations. */
+static svn_error_t*
+auto_set_start_offset(rep_state_t *rs, apr_pool_t *pool)
+{
+ if (rs->start == -1)
+ {
+ SVN_ERR(svn_fs_fs__item_offset(&rs->start, rs->file->fs, rs->revision,
+ rs->offset, pool));
+ rs->start += rs->header_size;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Set RS->VER depending on what is found in the already open RS->FILE->FILE
+ if the diff version is still unknown. Use POOL for temporary allocations.
+ */
+static svn_error_t*
+auto_read_diff_version(rep_state_t *rs, apr_pool_t *pool)
+{
+ if (rs->ver == -1)
+ {
+ char buf[4];
+ SVN_ERR(aligned_seek(rs->file->file, rs->start, pool));
+ SVN_ERR(svn_io_file_read_full2(rs->file->file, buf, sizeof(buf),
+ NULL, NULL, pool));
+
+ /* ### Layering violation */
+ if (! ((buf[0] == 'S') && (buf[1] == 'V') && (buf[2] == 'N')))
+ return svn_error_create
+ (SVN_ERR_FS_CORRUPT, NULL,
+ _("Malformed svndiff data in representation"));
+ rs->ver = buf[3];
+
+ rs->chunk_index = 0;
+ rs->current = 4;
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* See create_rep_state, which wraps this and adds another error. */
static svn_error_t *
create_rep_state_body(rep_state_t **rep_state,
@@ -602,77 +641,70 @@ create_rep_state_body(rep_state_t **rep_
rs->ver = -1;
rs->start = -1;
+ /* cache lookup, i.e. skip reading the rep header if possible */
if (ffd->rep_header_cache && !svn_fs_fs__id_txn_used(&rep->txn_id))
SVN_ERR(svn_cache__get((void **) &rh, &is_cached,
ffd->rep_header_cache, &key, pool));
- if (is_cached)
+ /* initialize the (shared) FILE member in RS */
+ if (reuse_shared_file)
{
- if (reuse_shared_file)
- {
- rs->file = *shared_file;
- }
- else
- {
- shared_file_t *file = apr_pcalloc(pool, sizeof(*file));
- file->revision = rep->revision;
- file->pool = pool;
- file->fs = fs;
- rs->file = file;
-
- /* remember the current file, if suggested by the caller */
- if (shared_file)
- *shared_file = file;
- }
+ rs->file = *shared_file;
}
else
{
- /* we will need the on-disk location for non-txn reps */
- apr_off_t offset;
- apr_uint32_t sub_item;
- if (! svn_fs_fs__id_txn_used(&rep->txn_id))
- SVN_ERR(svn_fs_fs__item_offset(&offset, &sub_item,
- fs, rep->revision, NULL,
- rep->offset, pool));
+ shared_file_t *file = apr_pcalloc(pool, sizeof(*file));
+ file->revision = rep->revision;
+ file->pool = pool;
+ file->fs = fs;
+ rs->file = file;
+
+ /* remember the current file, if suggested by the caller */
+ if (shared_file)
+ *shared_file = file;
+ }
+ /* read rep header, if necessary */
+ if (!is_cached)
+ {
+ /* ensure file is open and navigate to the start of rep header */
if (reuse_shared_file)
{
- /* ... we can re-use the same, already open file object
- */
- SVN_ERR_ASSERT(sub_item == 0);
- SVN_ERR(aligned_seek((*shared_file)->file, NULL, offset, pool));
+ apr_off_t offset;
+ /* ... we can re-use the same, already open file object.
+ * This implies that we don't read from a txn.
+ */
rs->file = *shared_file;
+ SVN_ERR(auto_open_shared_file(rs->file));
+ SVN_ERR(svn_fs_fs__get_packed_offset(&offset, fs, rep->revision,
+ pool));
+ SVN_ERR(aligned_seek((*shared_file)->file, offset + rep->offset,
+ pool));
}
else
{
- shared_file_t *file = apr_pcalloc(pool, sizeof(*file));
- file->revision = rep->revision;
- file->pool = pool;
- file->fs = fs;
-
- /* otherwise, create a new file object
+ /* otherwise, create a new file object. May or may not be
+ * an in-txn file.
*/
- SVN_ERR(open_and_seek_representation(&file->file, fs, rep, pool));
- file->stream = svn_stream_from_aprfile2(file->file, TRUE,
- file->pool);
- rs->file = file;
-
- /* remember the current file, if suggested by the caller */
- if (shared_file)
- *shared_file = file;
+ SVN_ERR(open_and_seek_representation(&rs->file->file, fs, rep,
+ pool));
+ rs->file->stream = svn_stream_from_aprfile2(rs->file->file, TRUE,
+ rs->file->pool);
}
SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->file->stream, pool));
SVN_ERR(svn_fs_fs__get_file_offset(&rs->start, rs->file->file, pool));
+ /* cache the rep header if appropriate */
if (! svn_fs_fs__id_txn_used(&rep->txn_id))
if (ffd->rep_header_cache)
SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh, pool));
}
- SVN_ERR(dgb__log_access(fs, rep->revision, rep->offset, rh,
- SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
+ /* finalize */
+ SVN_ERR(dbg_log_access(fs, rep->revision, rep->offset, rh,
+ SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
rs->header_size = rh->header_size;
*rep_state = rs;
@@ -682,8 +714,7 @@ create_rep_state_body(rep_state_t **rep_
/* This is a plaintext, so just return the current rep_state. */
return SVN_NO_ERROR;
- /* We are dealing with a delta, find out what version. */
- rs->chunk_index = 0;
+ /* skip "SVNx" diff marker */
rs->current = 4;
return SVN_NO_ERROR;
@@ -691,7 +722,7 @@ create_rep_state_body(rep_state_t **rep_
/* Read the rep args for REP in filesystem FS and create a rep_state
for reading the representation. Return the rep_state in *REP_STATE
- and the rep args in *REP_ARGS, both allocated in POOL.
+ and the rep header in *REP_HEADER, both allocated in POOL.
When reading multiple reps, i.e. a skip delta chain, you may provide
non-NULL SHARED_FILE. (If SHARED_FILE is not NULL, in the first
@@ -748,8 +779,6 @@ svn_fs_fs__check_rep(representation_t *r
return SVN_NO_ERROR;
}
-/* .
- Do any allocations in POOL. */
svn_error_t *
svn_fs_fs__rep_chain_length(int *chain_length,
representation_t *rep,
@@ -803,7 +832,6 @@ svn_fs_fs__rep_chain_length(int *chain_l
return SVN_NO_ERROR;
}
-
struct rep_read_baton
{
/* The FS from which we're reading. */
@@ -878,18 +906,6 @@ get_window_key(window_cache_key_t *key,
*
* If the information could be found, put RS to CHUNK_INDEX.
*/
-
-/* Return data type for get_cached_window_sizes_func.
- */
-typedef struct window_sizes_t
-{
- /* length of the txdelta window in its on-disk format */
- svn_filesize_t packed_len;
-
- /* expanded (and combined) window length */
- svn_filesize_t target_len;
-} window_sizes_t;
-
static svn_error_t *
get_cached_window(svn_txdelta_window_t **window_p,
rep_state_t *rs,
@@ -929,14 +945,12 @@ get_cached_window(svn_txdelta_window_t *
return SVN_NO_ERROR;
}
-/* Store the WINDOW read for the rep state RS with the given START_OFFSET
- * within the pack / rev file in the current FSFS session's cache. This
- * will be a no-op if no cache has been given.
+/* Store the WINDOW read for the rep state RS in the current FSFS
+ * session's cache. This will be a no-op if no cache has been given.
* Temporary allocations will be made from SCRATCH_POOL. */
static svn_error_t *
set_cached_window(svn_txdelta_window_t *window,
rep_state_t *rs,
- apr_off_t start_offset,
apr_pool_t *scratch_pool)
{
if (rs->window_cache)
@@ -946,7 +960,6 @@ set_cached_window(svn_txdelta_window_t *
window_cache_key_t key = {0};
cached_window.window = window;
- cached_window.start_offset = start_offset - rs->start;
cached_window.end_offset = rs->current;
/* but key it with the start offset because that is the known state
@@ -1040,7 +1053,7 @@ build_rep_list(apr_array_header_t **list
svn_boolean_t is_cached = FALSE;
shared_file_t *shared_file = NULL;
- *list = apr_array_make(pool, 1, sizeof(struct rep_state *));
+ *list = apr_array_make(pool, 1, sizeof(rep_state_t *));
rep = *first_rep;
/* The value as stored in the data struct.
@@ -1067,10 +1080,8 @@ build_rep_list(apr_array_header_t **list
SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file,
&rep, fs, pool));
- /* for txn reps and containered reps, there won't be a cached
- * combined window */
- if (!svn_fs_fs__id_txn_used(&rep.txn_id)
- && rep_header->type != svn_fs_fs__rep_container)
+ /* for txn reps, there won't be a cached combined window */
+ if (!svn_fs_fs__id_txn_used(&rep.txn_id))
SVN_ERR(get_cached_combined_window(window_p, rs, &is_cached, pool));
if (is_cached)
@@ -1084,11 +1095,9 @@ build_rep_list(apr_array_header_t **list
return SVN_NO_ERROR;
}
- if (rep_header->type == svn_fs_fs__rep_plain
- || rep_header->type == svn_fs_fs__rep_container)
+ if (rep_header->type == svn_fs_fs__rep_plain)
{
- /* This is a plaintext or container item, so just return the
- current rep_state. */
+ /* This is a plaintext, so just return the current rep_state. */
*src_state = rs;
return SVN_NO_ERROR;
}
@@ -1156,65 +1165,9 @@ rep_read_get_baton(struct rep_read_baton
return SVN_NO_ERROR;
}
-/* Open FILE->FILE and FILE->STREAM if they haven't been opened, yet. */
-static svn_error_t*
-auto_open_shared_file(shared_file_t *file)
-{
- if (file->file == NULL)
- {
- SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&file->file, file->fs,
- file->revision, file->pool));
- file->stream = svn_stream_from_aprfile2(file->file, TRUE, file->pool);
- }
-
- return SVN_NO_ERROR;
-}
-
-/* Set RS->START to the begin of the representation raw in RS->FILE->FILE,
- if that hasn't been done yet. Use POOL for temporary allocations. */
-static svn_error_t*
-auto_set_start_offset(rep_state_t *rs, apr_pool_t *pool)
-{
- if (rs->start == -1)
- {
- SVN_ERR(svn_fs_fs__item_offset(&rs->start, &rs->sub_item,
- rs->file->fs, rs->revision, NULL,
- rs->offset, pool));
- rs->start += rs->header_size;
- }
-
- return SVN_NO_ERROR;
-}
-
-/* Set RS->VER depending on what is found in the already open RS->FILE->FILE
- if the diff version is still unknown. Use POOL for temporary allocations.
- */
-static svn_error_t*
-auto_read_diff_version(rep_state_t *rs, apr_pool_t *pool)
-{
- if (rs->ver == -1)
- {
- char buf[4];
- SVN_ERR(aligned_seek(rs->file->file, NULL, rs->start, pool));
- SVN_ERR(svn_io_file_read_full2(rs->file->file, buf, sizeof(buf),
- NULL, NULL, pool));
-
- /* ### Layering violation */
- if (! ((buf[0] == 'S') && (buf[1] == 'V') && (buf[2] == 'N')))
- return svn_error_create
- (SVN_ERR_FS_CORRUPT, NULL,
- _("Malformed svndiff data in representation"));
- rs->ver = buf[3];
-
- rs->chunk_index = 0;
- rs->current = 4;
- }
-
- return SVN_NO_ERROR;
-}
-
/* Skip forwards to THIS_CHUNK in REP_STATE and then read the next delta
- window into *NWIN. */
+ window into *NWIN. Note that RS->CHUNK_INDEX will be THIS_CHUNK rather
+ than THIS_CHUNK + 1 when this function returns. */
static svn_error_t *
read_delta_window(svn_txdelta_window_t **nwin, int this_chunk,
rep_state_t *rs, apr_pool_t *pool)
@@ -1224,8 +1177,8 @@ read_delta_window(svn_txdelta_window_t *
apr_off_t end_offset;
SVN_ERR_ASSERT(rs->chunk_index <= this_chunk);
- SVN_ERR(dgb__log_access(rs->file->fs, rs->revision, rs->offset,
- NULL, SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
+ SVN_ERR(dbg_log_access(rs->file->fs, rs->revision, rs->offset,
+ NULL, SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
/* Read the next window. But first, try to find it in the cache. */
SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
@@ -1234,28 +1187,13 @@ read_delta_window(svn_txdelta_window_t *
/* someone has to actually read the data from file. Open it */
SVN_ERR(auto_open_shared_file(rs->file));
-
- /* invoke the 'block-read' feature for non-txn data.
- However, don't do that if we are in the middle of some representation,
- because the block is unlikely to contain other data. */
- if (rs->chunk_index == 0 && SVN_IS_VALID_REVNUM(rs->revision))
- {
- /* reading the whole block probably also provided us with the
- desired txdelta window */
- SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
- if (is_cached)
- return SVN_NO_ERROR;
- }
-
- /* data is still not cached -> we need to read it.
- Make sure we have all the necessary info. */
SVN_ERR(auto_set_start_offset(rs, pool));
SVN_ERR(auto_read_diff_version(rs, pool));
/* RS->FILE may be shared between RS instances -> make sure we point
* to the right data. */
start_offset = rs->start + rs->current;
- SVN_ERR(aligned_seek(rs->file->file, NULL, start_offset, pool));
+ SVN_ERR(aligned_seek(rs->file->file, start_offset, pool));
/* Skip windows to reach the current chunk if we aren't there yet. */
while (rs->chunk_index < this_chunk)
@@ -1286,7 +1224,7 @@ read_delta_window(svn_txdelta_window_t *
/* the window has not been cached before, thus cache it now
* (if caching is used for them at all) */
if (SVN_IS_VALID_REVNUM(rs->revision))
- SVN_ERR(set_cached_window(*nwin, rs, start_offset, pool));
+ SVN_ERR(set_cached_window(*nwin, rs, pool));
return SVN_NO_ERROR;
}
@@ -1304,7 +1242,7 @@ read_plain_window(svn_stringbuf_t **nwin
SVN_ERR(auto_set_start_offset(rs, pool));
offset = rs->start + rs->current;
- SVN_ERR(aligned_seek(rs->file->file, NULL, offset, pool));
+ SVN_ERR(aligned_seek(rs->file->file, offset, pool));
/* Read the plain data. */
*nwin = svn_stringbuf_create_ensure(size, pool);
@@ -1465,7 +1403,7 @@ get_contents(struct rep_read_baton *rb,
SVN_ERR(auto_set_start_offset(rs, rb->pool));
offset = rs->start + rs->current;
- SVN_ERR(aligned_seek(rs->file->file, NULL, offset,rb->pool));
+ SVN_ERR(aligned_seek(rs->file->file, offset, rb->pool));
SVN_ERR(svn_io_file_read_full2(rs->file->file, cur, copy_len,
NULL, NULL, rb->pool));
}
@@ -1691,10 +1629,11 @@ svn_fs_fs__try_process_file_contents(svn
return SVN_NO_ERROR;
}
+
/* Baton used when reading delta windows. */
struct delta_read_baton
{
- struct rep_state_t *rs;
+ rep_state_t *rs;
unsigned char md5_digest[APR_MD5_DIGESTSIZE];
};
@@ -1764,7 +1703,8 @@ svn_fs_fs__get_file_delta_stream(svn_txd
/* Read both fulltexts and construct a delta. */
if (source)
- SVN_ERR(svn_fs_fs__get_contents(&source_stream, fs, source->data_rep, pool));
+ SVN_ERR(svn_fs_fs__get_contents(&source_stream, fs, source->data_rep,
+ pool));
else
source_stream = svn_stream_empty(pool);
SVN_ERR(svn_fs_fs__get_contents(&target_stream, fs, target->data_rep, pool));
@@ -1777,7 +1717,6 @@ svn_fs_fs__get_file_delta_stream(svn_txd
return SVN_NO_ERROR;
}
-
/* Fetch the contents of a directory into ENTRIES. Values are stored
as filename to string mappings; further conversion is necessary to
convert them into svn_fs_dirent_t values. */
@@ -2107,7 +2046,7 @@ svn_fs_fs__get_changes(apr_array_header_
SVN_ERR(get_root_changes_offset(NULL, &changes_offset, revision_file, fs,
rev, pool));
- SVN_ERR(svn_io_file_seek(revision_file, APR_SET, &changes_offset, pool));
+ SVN_ERR(aligned_seek(revision_file, changes_offset, pool));
SVN_ERR(svn_fs_fs__read_changes(changes,
svn_stream_from_aprfile2(revision_file, TRUE, pool),
pool));
@@ -2119,8 +2058,8 @@ svn_fs_fs__get_changes(apr_array_header_
if (ffd->changes_cache)
SVN_ERR(svn_cache__set(ffd->changes_cache, &rev, *changes, pool));
- SVN_ERR(dgb__log_access(fs, rev, changes_offset, *changes,
- SVN_FS_FS__ITEM_TYPE_CHANGES, pool));
+ SVN_ERR(dbg_log_access(fs, rev, changes_offset, *changes,
+ SVN_FS_FS__ITEM_TYPE_CHANGES, pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.h Thu Jul 25 14:43:44 2013
@@ -27,7 +27,6 @@
#include "svn_fs.h"
#include "fs.h"
-#include "index.h"
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c Thu Jul 25 14:43:44 2013
@@ -25,7 +25,6 @@
#include "id.h"
#include "dag.h"
#include "tree.h"
-#include "index.h"
#include "temp_serializer.h"
#include "../libsvn_fs/fs-loader.h"
@@ -404,7 +403,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
* - Data that can be reconstructed from other elements has low prio
* (e.g. fulltexts, directories etc.)
* - Index data required to find any of the other data has high prio
- * (e.g. noderevs, L2P and P2L index pages)
+ * (e.g. noderevs)
* - everthing else should use default prio
*/
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c Thu Jul 25 14:43:44 2013
@@ -28,11 +28,11 @@
#include "svn_props.h"
#include "svn_pools.h"
+#include "cached_data.h"
#include "dag.h"
#include "fs.h"
#include "fs_fs.h"
#include "id.h"
-#include "cached_data.h"
#include "transaction.h"
#include "../libsvn_fs/fs-loader.h"
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c Thu Jul 25 14:43:44 2013
@@ -35,16 +35,16 @@
#include "svn_pools.h"
#include "fs.h"
#include "fs_fs.h"
-#include "pack.h"
-#include "recovery.h"
-#include "hotcopy.h"
-#include "verify.h"
#include "tree.h"
#include "lock.h"
+#include "hotcopy.h"
#include "id.h"
-#include "revprops.h"
+#include "pack.h"
+#include "recovery.h"
#include "rep-cache.h"
+#include "revprops.h"
#include "transaction.h"
+#include "verify.h"
#include "svn_private_config.h"
#include "private/svn_fs_util.h"
@@ -191,7 +191,7 @@ fs_info(const void **fsfs_info,
static fs_vtable_t fs_vtable = {
svn_fs_fs__youngest_rev,
svn_fs_fs__revision_prop,
- svn_fs_fs__revision_proplist,
+ svn_fs_fs__get_revision_proplist,
svn_fs_fs__change_rev_prop,
svn_fs_fs__set_uuid,
svn_fs_fs__revision_root,
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h Thu Jul 25 14:43:44 2013
@@ -71,10 +71,6 @@ extern "C" {
#define PATH_PACKED "pack" /* Packed revision data file */
#define PATH_EXT_PACKED_SHARD ".pack" /* Extension for packed
shards */
-#define PATH_EXT_L2P_INDEX ".l2p" /* extension of the log-
- to-phys index */
-#define PATH_EXT_P2L_INDEX ".p2l" /* extension of the phys-
- to-log index */
/* If you change this, look at tests/svn_test_fs.c(maybe_install_fsfs_conf) */
#define PATH_CONFIG "fsfs.conf" /* Configuration */
@@ -88,10 +84,6 @@ extern "C" {
#define PATH_EXT_PROPS ".props" /* Extension for node props */
#define PATH_EXT_REV ".rev" /* Extension of protorev file */
#define PATH_EXT_REV_LOCK ".rev-lock" /* Extension of protorev lock file */
-#define PATH_TXN_ITEM_INDEX "itemidx" /* File containing the current item
- index number */
-#define PATH_INDEX "index" /* name of index files w/o ext */
-
/* Names of files in legacy FS formats */
#define PATH_REV "rev" /* Proto rev file */
#define PATH_REV_LOCK "rev-lock" /* Proto rev (write) lock file */
@@ -237,7 +229,7 @@ typedef struct pair_cache_key_t
{
svn_revnum_t revision;
- apr_uint64_t second;
+ apr_int64_t second;
} pair_cache_key_t;
/* Key type that identifies a representation / rep header. */
@@ -260,7 +252,7 @@ typedef struct window_cache_key_t
apr_uint32_t revision;
/* Window number within that representation */
- int chunk_index;
+ apr_int32_t chunk_index;
/* Offset of the representation within REVISION */
apr_uint64_t offset;
@@ -337,8 +329,7 @@ typedef struct fs_fs_data_t
the key is window_cache_key_t */
svn_cache__t *combined_window_cache;
- /* Cache for svn_fs_fs__rep_header_t objects;
- * the key is (revision, item index) */
+ /* Cache for node_revision_t objects; the key is (revision, id offset) */
svn_cache__t *node_revision_cache;
/* Cache for change lists as APR arrays of change_t * objects; the key
@@ -346,7 +337,7 @@ typedef struct fs_fs_data_t
svn_cache__t *changes_cache;
/* Cache for svn_fs_fs__rep_header_t objects; the key is a
- (revision, item index) pair */
+ (revision, is_packed, offset) set */
svn_cache__t *rep_header_cache;
/* Cache for svn_mergeinfo_t objects; the key is a combination of
@@ -455,8 +446,8 @@ typedef struct representation_t
/* Revision where this representation is located. */
svn_revnum_t revision;
- /* Item offset within the revision. */
- apr_uint64_t offset;
+ /* Offset into the revision file where it is located. */
+ svn_filesize_t offset;
/* The size of the representation in bytes as seen in the revision
file. */
@@ -474,10 +465,10 @@ typedef struct representation_t
store the original txn of the node rev (not the rep!), along with some
intra-node uniqification content. */
struct
- {
- svn_fs_fs__id_part_t txn_id;
- apr_uint64_t number;
- } uniquifier;
+ {
+ svn_fs_fs__id_part_t txn_id;
+ apr_uint64_t number;
+ } uniquifier;
} representation_t;
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c Thu Jul 25 14:43:44 2013
@@ -37,7 +37,6 @@
#include "transaction.h"
#include "tree.h"
#include "util.h"
-#include "index.h"
#include "private/svn_fs_util.h"
#include "private/svn_string_private.h"
@@ -69,6 +68,168 @@
Values < 1 disable deltification. */
#define SVN_FS_FS_MAX_DELTIFICATION_WALK 1023
+/* Notes:
+
+To avoid opening and closing the rev-files all the time, it would
+probably be advantageous to keep each rev-file open for the
+lifetime of the transaction object. I'll leave that as a later
+optimization for now.
+
+I didn't keep track of pool lifetimes at all in this code. There
+are likely some errors because of that.
+
+*/
+
+/* Declarations. */
+
+static svn_error_t *
+get_youngest(svn_revnum_t *youngest_p, const char *fs_path, apr_pool_t *pool);
+
+/* Pathname helper functions */
+
+static const char *
+path_format(svn_fs_t *fs, apr_pool_t *pool)
+{
+ return svn_dirent_join(fs->path, PATH_FORMAT, pool);
+}
+
+static APR_INLINE const char *
+path_uuid(svn_fs_t *fs, apr_pool_t *pool)
+{
+ return svn_dirent_join(fs->path, PATH_UUID, pool);
+}
+
+const char *
+svn_fs_fs__path_current(svn_fs_t *fs, apr_pool_t *pool)
+{
+ return svn_dirent_join(fs->path, PATH_CURRENT, pool);
+}
+
+static APR_INLINE const char *
+path_lock(svn_fs_t *fs, apr_pool_t *pool)
+{
+ return svn_dirent_join(fs->path, PATH_LOCK_FILE, pool);
+}
+
+
+
+/* Get a lock on empty file LOCK_FILENAME, creating it in POOL. */
+static svn_error_t *
+get_lock_on_filesystem(const char *lock_filename,
+ apr_pool_t *pool)
+{
+ svn_error_t *err = svn_io_file_lock2(lock_filename, TRUE, FALSE, pool);
+
+ if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ /* No lock file? No big deal; these are just empty files
+ anyway. Create it and try again. */
+ svn_error_clear(err);
+ err = NULL;
+
+ SVN_ERR(svn_io_file_create_empty(lock_filename, pool));
+ SVN_ERR(svn_io_file_lock2(lock_filename, TRUE, FALSE, pool));
+ }
+
+ return svn_error_trace(err);
+}
+
+/* Reset the HAS_WRITE_LOCK member in the FFD given as BATON_VOID.
+ When registered with the pool holding the lock on the lock file,
+ this makes sure the flag gets reset just before we release the lock. */
+static apr_status_t
+reset_lock_flag(void *baton_void)
+{
+ fs_fs_data_t *ffd = baton_void;
+ ffd->has_write_lock = FALSE;
+ return APR_SUCCESS;
+}
+
+/* Obtain a write lock on the file LOCK_FILENAME (protecting with
+ LOCK_MUTEX if APR is threaded) in a subpool of POOL, call BODY with
+ BATON and that subpool, destroy the subpool (releasing the write
+ lock) and return what BODY returned. If IS_GLOBAL_LOCK is set,
+ set the HAS_WRITE_LOCK flag while we keep the write lock. */
+static svn_error_t *
+with_some_lock_file(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
+ apr_pool_t *pool),
+ void *baton,
+ const char *lock_filename,
+ svn_boolean_t is_global_lock,
+ apr_pool_t *pool)
+{
+ apr_pool_t *subpool = svn_pool_create(pool);
+ svn_error_t *err = get_lock_on_filesystem(lock_filename, subpool);
+
+ if (!err)
+ {
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ if (is_global_lock)
+ {
+ /* set the "got the lock" flag and register reset function */
+ apr_pool_cleanup_register(subpool,
+ ffd,
+ reset_lock_flag,
+ apr_pool_cleanup_null);
+ ffd->has_write_lock = TRUE;
+ }
+
+ /* nobody else will modify the repo state
+ => read HEAD & pack info once */
+ if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
+ SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool));
+ SVN_ERR(get_youngest(&ffd->youngest_rev_cache, fs->path,
+ pool));
+ err = body(baton, subpool);
+ }
+
+ svn_pool_destroy(subpool);
+
+ return svn_error_trace(err);
+}
+
+svn_error_t *
+svn_fs_fs__with_write_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
+ apr_pool_t *pool),
+ void *baton,
+ apr_pool_t *pool)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+ fs_fs_shared_data_t *ffsd = ffd->shared;
+
+ SVN_MUTEX__WITH_LOCK(ffsd->fs_write_lock,
+ with_some_lock_file(fs, body, baton,
+ path_lock(fs, pool),
+ TRUE,
+ pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Run BODY (with BATON and POOL) while the txn-current file
+ of FS is locked. */
+svn_error_t *
+svn_fs_fs__with_txn_current_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
+ apr_pool_t *pool),
+ void *baton,
+ apr_pool_t *pool)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+ fs_fs_shared_data_t *ffsd = ffd->shared;
+
+ SVN_MUTEX__WITH_LOCK(ffsd->txn_current_lock,
+ with_some_lock_file(fs, body, baton,
+ svn_fs_fs__path_txn_current_lock(fs, pool),
+ FALSE,
+ pool));
+
+ return SVN_NO_ERROR;
+}
+
@@ -84,6 +245,14 @@ check_format_file_buffer_numeric(const c
pool);
}
+/* Read the format number and maximum number of files per directory
+ from PATH and return them in *PFORMAT and *MAX_FILES_PER_DIR
+ respectively.
+
+ *MAX_FILES_PER_DIR is obtained from the 'layout' format option, and
+ will be set to zero if a linear scheme should be used.
+
+ Use POOL for temporary allocation. */
static svn_error_t *
read_format(int *pformat, int *max_files_per_dir,
const char *path, apr_pool_t *pool)
@@ -173,10 +342,11 @@ svn_fs_fs__write_format(svn_fs_t *fs,
apr_pool_t *pool)
{
svn_stringbuf_t *sb;
- const char *path = svn_fs_fs__path_format(fs, pool);
fs_fs_data_t *ffd = fs->fsap_data;
+ const char *path = path_format(fs, pool);
- SVN_ERR_ASSERT(1 <= ffd->format && ffd->format <= SVN_FS_FS__FORMAT_NUMBER);
+ SVN_ERR_ASSERT(1 <= ffd->format
+ && ffd->format <= SVN_FS_FS__FORMAT_NUMBER);
sb = svn_stringbuf_createf(pool, "%d\n", ffd->format);
@@ -239,25 +409,6 @@ svn_fs_fs__fs_supports_mergeinfo(svn_fs_
return ffd->format >= SVN_FS_FS__MIN_MERGEINFO_FORMAT;
}
-/* Find the youngest revision in a repository at path FS_PATH and
- return it in *YOUNGEST_P. Perform temporary allocations in
- POOL. */
-static svn_error_t *
-get_youngest(svn_revnum_t *youngest_p,
- const char *fs_path,
- apr_pool_t *pool)
-{
- svn_stringbuf_t *buf;
- SVN_ERR(svn_fs_fs__read_content(&buf,
- svn_dirent_join(fs_path, PATH_CURRENT, pool),
- pool));
-
- *youngest_p = SVN_STR_TO_REV(buf->data);
-
- return SVN_NO_ERROR;
-}
-
-
/* Read the configuration information of the file system at FS_PATH
* and set the respective values in FFD. Use POOL for allocations.
*/
@@ -284,11 +435,11 @@ read_config(fs_fs_data_t *ffd,
SVN_ERR(svn_config_get_bool(ffd->config, &ffd->deltify_directories,
CONFIG_SECTION_DELTIFICATION,
CONFIG_OPTION_ENABLE_DIR_DELTIFICATION,
- TRUE));
+ FALSE));
SVN_ERR(svn_config_get_bool(ffd->config, &ffd->deltify_properties,
CONFIG_SECTION_DELTIFICATION,
CONFIG_OPTION_ENABLE_PROPS_DELTIFICATION,
- TRUE));
+ FALSE));
SVN_ERR(svn_config_get_int64(ffd->config, &ffd->max_deltification_walk,
CONFIG_SECTION_DELTIFICATION,
CONFIG_OPTION_MAX_DELTIFICATION_WALK,
@@ -312,7 +463,7 @@ read_config(fs_fs_data_t *ffd,
SVN_ERR(svn_config_get_bool(ffd->config, &ffd->compress_packed_revprops,
CONFIG_SECTION_PACKED_REVPROPS,
CONFIG_OPTION_COMPRESS_PACKED_REVPROPS,
- TRUE));
+ FALSE));
SVN_ERR(svn_config_get_int64(ffd->config, &ffd->revprop_pack_size,
CONFIG_SECTION_PACKED_REVPROPS,
CONFIG_OPTION_REVPROP_PACK_SIZE,
@@ -396,16 +547,16 @@ write_config(svn_fs_t *fs,
"### Repositories containing large directories will benefit greatly." NL
"### In rarely read repositories, the I/O overhead may be significant as" NL
"### cache hit rates will most likely be low" NL
-"### directory deltification is enabled by default." NL
-"# " CONFIG_OPTION_ENABLE_DIR_DELTIFICATION " = true" NL
+"### directory deltification is disabled by default." NL
+"# " CONFIG_OPTION_ENABLE_DIR_DELTIFICATION " = false" NL
"###" NL
"### The following parameter enables deltification for properties on files" NL
"### and directories. Overall, this is a minor tuning option but can save" NL
"### some disk space if you merge frequently or frequently change node" NL
"### properties. You should not activate this if rep-sharing has been" NL
"### disabled because this may result in a net increase in repository size." NL
-"### property deltification is enabled by default." NL
-"# " CONFIG_OPTION_ENABLE_PROPS_DELTIFICATION " = true" NL
+"### property deltification is disabled by default." NL
+"# " CONFIG_OPTION_ENABLE_PROPS_DELTIFICATION " = false" NL
"###" NL
"### During commit, the server may need to walk the whole change history of" NL
"### of a given node to find a suitable deltification base. This linear" NL
@@ -460,8 +611,8 @@ write_config(svn_fs_t *fs,
"### even more so writing, become significantly more CPU intensive. With" NL
"### revprop caching enabled, the overhead can be offset by reduced I/O" NL
"### unless you often modify revprops after packing." NL
-"### Compressing packed revprops is enabled by default." NL
-"# " CONFIG_OPTION_COMPRESS_PACKED_REVPROPS " = true" NL
+"### Compressing packed revprops is disabled by default." NL
+"# " CONFIG_OPTION_COMPRESS_PACKED_REVPROPS " = false" NL
;
#undef NL
return svn_io_file_create(svn_dirent_join(fs->path, PATH_CONFIG, pool),
@@ -481,7 +632,7 @@ svn_fs_fs__open(svn_fs_t *fs, const char
/* Read the FS format number. */
SVN_ERR(read_format(&format, &max_files_per_dir,
- svn_fs_fs__path_format(fs, pool), pool));
+ path_format(fs, pool), pool));
SVN_ERR(check_format(format));
/* Now we've got a format number no matter what. */
@@ -489,7 +640,7 @@ svn_fs_fs__open(svn_fs_t *fs, const char
ffd->max_files_per_dir = max_files_per_dir;
/* Read in and cache the repository uuid. */
- SVN_ERR(svn_io_file_open(&uuid_file, svn_fs_fs__path_uuid(fs, pool),
+ SVN_ERR(svn_io_file_open(&uuid_file, path_uuid(fs, pool),
APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));
limit = sizeof(buf);
@@ -541,7 +692,7 @@ upgrade_body(void *baton, apr_pool_t *po
svn_fs_t *fs = upgrade_baton->fs;
fs_fs_data_t *ffd = fs->fsap_data;
int format, max_files_per_dir;
- const char *format_path = svn_fs_fs__path_format(fs, pool);
+ const char *format_path = path_format(fs, pool);
svn_node_kind_t kind;
svn_boolean_t needs_revprop_shard_cleanup = FALSE;
@@ -576,11 +727,11 @@ upgrade_body(void *baton, apr_pool_t *po
if (format < SVN_FS_FS__MIN_TXN_CURRENT_FORMAT)
{
SVN_ERR(create_file_ignore_eexist(
- svn_fs_fs__path_txn_current(fs, pool),
- "0\n", pool));
+ svn_fs_fs__path_txn_current(fs, pool), "0\n",
+ pool));
SVN_ERR(create_file_ignore_eexist(
- svn_fs_fs__path_txn_current_lock(fs, pool),
- "", pool));
+ svn_fs_fs__path_txn_current_lock(fs, pool), "",
+ pool));
}
/* If our filesystem predates the existance of the 'txn-protorevs'
@@ -607,16 +758,15 @@ upgrade_body(void *baton, apr_pool_t *po
&& max_files_per_dir > 0)
{
needs_revprop_shard_cleanup = TRUE;
- SVN_ERR(upgrade_pack_revprops(fs,
- upgrade_baton->notify_func,
- upgrade_baton->notify_baton,
- upgrade_baton->cancel_func,
- upgrade_baton->cancel_baton,
- pool));
+ SVN_ERR(svn_fs_fs__upgrade_pack_revprops(fs,
+ upgrade_baton->notify_func,
+ upgrade_baton->notify_baton,
+ upgrade_baton->cancel_func,
+ upgrade_baton->cancel_baton,
+ pool));
}
/* Bump the format file. */
-
ffd->format = SVN_FS_FS__FORMAT_NUMBER;
ffd->max_files_per_dir = max_files_per_dir;
SVN_ERR(svn_fs_fs__write_format(fs, TRUE, pool));
@@ -628,12 +778,12 @@ upgrade_body(void *baton, apr_pool_t *po
/* Now, it is safe to remove the redundant revprop files. */
if (needs_revprop_shard_cleanup)
- SVN_ERR(upgrade_cleanup_pack_revprops(fs,
- upgrade_baton->notify_func,
- upgrade_baton->notify_baton,
- upgrade_baton->cancel_func,
- upgrade_baton->cancel_baton,
- pool));
+ SVN_ERR(svn_fs_fs__upgrade_cleanup_pack_revprops(fs,
+ upgrade_baton->notify_func,
+ upgrade_baton->notify_baton,
+ upgrade_baton->cancel_func,
+ upgrade_baton->cancel_baton,
+ pool));
/* Done */
return SVN_NO_ERROR;
@@ -658,6 +808,25 @@ svn_fs_fs__upgrade(svn_fs_t *fs,
return svn_fs_fs__with_write_lock(fs, upgrade_body, (void *)&baton, pool);
}
+/* Find the youngest revision in a repository at path FS_PATH and
+ return it in *YOUNGEST_P. Perform temporary allocations in
+ POOL. */
+static svn_error_t *
+get_youngest(svn_revnum_t *youngest_p,
+ const char *fs_path,
+ apr_pool_t *pool)
+{
+ svn_stringbuf_t *buf;
+ SVN_ERR(svn_fs_fs__read_content(&buf,
+ svn_dirent_join(fs_path, PATH_CURRENT,
+ pool),
+ pool));
+
+ *youngest_p = SVN_STR_TO_REV(buf->data);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_fs_fs__youngest_rev(svn_revnum_t *youngest_p,
@@ -697,85 +866,8 @@ svn_fs_fs__ensure_revision_exists(svn_re
return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
_("No such revision %ld"), rev);
- return SVN_NO_ERROR;
-}
-
-/* Open the correct revision file for REV. If the filesystem FS has
- been packed, *FILE will be set to the packed file; otherwise, set *FILE
- to the revision file for REV. Return SVN_ERR_FS_NO_SUCH_REVISION if the
- file doesn't exist.
-
- TODO: Consider returning an indication of whether this is a packed rev
- file, so the caller need not rely on is_packed_rev() which in turn
- relies on the cached FFD->min_unpacked_rev value not having changed
- since the rev file was opened.
-
- Use POOL for allocations. */
-svn_error_t *
-svn_fs_fs__open_pack_or_rev_file(apr_file_t **file,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *pool)
-{
- fs_fs_data_t *ffd = fs->fsap_data;
- svn_error_t *err;
- svn_boolean_t retry = FALSE;
-
- do
- {
- const char *path = svn_fs_fs__path_rev_absolute(fs, rev, pool);
-
- /* open the revision file in buffered r/o mode */
- err = svn_io_file_open(file, path,
- APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
- if (err && APR_STATUS_IS_ENOENT(err->apr_err))
- {
- if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
- {
- /* Could not open the file. This may happen if the
- * file once existed but got packed later. */
- svn_error_clear(err);
-
- /* if that was our 2nd attempt, leave it at that. */
- if (retry)
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), rev);
-
- /* We failed for the first time. Refresh cache & retry. */
- SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool));
-
- retry = TRUE;
- }
- else
- {
- svn_error_clear(err);
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), rev);
- }
- }
- else
- {
- retry = FALSE;
- }
- }
- while (retry);
-
- return svn_error_trace(err);
}
-
-svn_error_t *
-svn_fs_fs__revision_proplist(apr_hash_t **proplist_p,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *pool)
-{
- SVN_ERR(get_revision_proplist(proplist_p, fs, rev, pool));
-
- return SVN_NO_ERROR;
-}
-
-
svn_error_t *
svn_fs_fs__file_length(svn_filesize_t *length,
node_revision_t *noderev,
@@ -848,16 +940,10 @@ representation_t *
svn_fs_fs__rep_copy(representation_t *rep,
apr_pool_t *pool)
{
- representation_t *rep_new;
-
if (rep == NULL)
return NULL;
- rep_new = apr_palloc(pool, sizeof(*rep_new));
-
- memcpy(rep_new, rep, sizeof(*rep_new));
-
- return rep_new;
+ return apr_pmemdup(pool, rep, sizeof(*rep));
}
@@ -871,15 +957,14 @@ write_revision_zero(svn_fs_t *fs)
/* Write out a rev file for revision 0. */
SVN_ERR(svn_io_file_create(path_revision_zero,
- "PLAIN\nEND\nENDREP\n"
- "id: 0.0.r0/17\n"
- "type: dir\n"
- "count: 0\n"
- "text: 0 0 4 4 "
- "2d2977d1c96f487abe4a1e202dd03b4e\n"
- "cpath: /\n"
- "\n\n17 107\n", fs->pool));
-
+ "PLAIN\nEND\nENDREP\n"
+ "id: 0.0.r0/17\n"
+ "type: dir\n"
+ "count: 0\n"
+ "text: 0 0 4 4 "
+ "2d2977d1c96f487abe4a1e202dd03b4e\n"
+ "cpath: /\n"
+ "\n\n17 107\n", fs->pool));
SVN_ERR(svn_io_set_file_read_only(path_revision_zero, FALSE, fs->pool));
/* Set a date on revision 0. */
@@ -887,7 +972,7 @@ write_revision_zero(svn_fs_t *fs)
date.len = strlen(date.data);
proplist = apr_hash_make(fs->pool);
svn_hash_sets(proplist, SVN_PROP_REVISION_DATE, &date);
- return set_revision_proplist(fs, 0, proplist, fs->pool);
+ return svn_fs_fs__set_revision_proplist(fs, 0, proplist, fs->pool);
}
svn_error_t *
@@ -902,15 +987,6 @@ svn_fs_fs__create(svn_fs_t *fs,
/* See if compatibility with older versions was explicitly requested. */
if (fs->config)
{
- const char *compatible;
- svn_version_t *compatible_version;
-
- compatible = svn_hash_gets(fs->config, SVN_FS_CONFIG_COMPATIBLE_VERSION);
- if (compatible)
- SVN_ERR(svn_version__parse_version_string(&compatible_version,
- compatible,
- pool));
-
if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_4_COMPATIBLE))
format = 1;
else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_5_COMPATIBLE))
@@ -919,9 +995,6 @@ svn_fs_fs__create(svn_fs_t *fs,
format = 3;
else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_8_COMPATIBLE))
format = 4;
- else if (compatible && compatible_version->major == SVN_VER_MAJOR
- && compatible_version->minor <= 8)
- format = 6;
}
ffd->format = format;
@@ -931,7 +1004,8 @@ svn_fs_fs__create(svn_fs_t *fs,
/* Create the revision data directories. */
if (ffd->max_files_per_dir)
- SVN_ERR(svn_io_make_dir_recursively(svn_fs_fs__path_rev_shard(fs, 0, pool),
+ SVN_ERR(svn_io_make_dir_recursively(svn_fs_fs__path_rev_shard(fs, 0,
+ pool),
pool));
else
SVN_ERR(svn_io_make_dir_recursively(svn_dirent_join(path, PATH_REVS_DIR,
@@ -940,9 +1014,9 @@ svn_fs_fs__create(svn_fs_t *fs,
/* Create the revprops directory. */
if (ffd->max_files_per_dir)
- SVN_ERR(svn_io_make_dir_recursively(
- svn_fs_fs__path_revprops_shard(fs, 0, pool),
- pool));
+ SVN_ERR(svn_io_make_dir_recursively(svn_fs_fs__path_revprops_shard(fs, 0,
+ pool),
+ pool));
else
SVN_ERR(svn_io_make_dir_recursively(svn_dirent_join(path,
PATH_REVPROPS_DIR,
@@ -962,10 +1036,10 @@ svn_fs_fs__create(svn_fs_t *fs,
/* Create the 'current' file. */
SVN_ERR(svn_io_file_create(svn_fs_fs__path_current(fs, pool),
- (format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT
- ? "0\n" : "0 1 1\n"),
+ (format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT
+ ? "0\n" : "0 1 1\n"),
pool));
- SVN_ERR(svn_io_file_create_empty(svn_fs_fs__path_lock(fs, pool), pool));
+ SVN_ERR(svn_io_file_create_empty(path_lock(fs, pool), pool));
SVN_ERR(svn_fs_fs__set_uuid(fs, NULL, pool));
SVN_ERR(write_revision_zero(fs));
@@ -1004,7 +1078,7 @@ svn_fs_fs__set_uuid(svn_fs_t *fs,
{
char *my_uuid;
apr_size_t my_uuid_len;
- const char *uuid_path = svn_fs_fs__path_uuid(fs, pool);
+ const char *uuid_path = path_uuid(fs, pool);
if (! uuid)
uuid = svn_uuid_generate(pool);
@@ -1187,6 +1261,7 @@ svn_fs_fs__set_node_origin(svn_fs_t *fs,
return svn_error_trace(err);
}
+
/*** Revisions ***/
@@ -1200,7 +1275,7 @@ svn_fs_fs__revision_prop(svn_string_t **
apr_hash_t *table;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
- SVN_ERR(svn_fs_fs__revision_proplist(&table, fs, rev, pool));
+ SVN_ERR(svn_fs_fs__get_revision_proplist(&table, fs, rev, pool));
*value_p = svn_hash_gets(table, propname);
@@ -1226,7 +1301,7 @@ change_rev_prop_body(void *baton, apr_po
struct change_rev_prop_baton *cb = baton;
apr_hash_t *table;
- SVN_ERR(svn_fs_fs__revision_proplist(&table, cb->fs, cb->rev, pool));
+ SVN_ERR(svn_fs_fs__get_revision_proplist(&table, cb->fs, cb->rev, pool));
if (cb->old_value_p)
{
@@ -1246,7 +1321,7 @@ change_rev_prop_body(void *baton, apr_po
}
svn_hash_sets(table, cb->name, cb->value);
- return set_revision_proplist(cb->fs, cb->rev, table, pool);
+ return svn_fs_fs__set_revision_proplist(cb->fs, cb->rev, table, pool);
}
svn_error_t *
@@ -1270,7 +1345,7 @@ svn_fs_fs__change_rev_prop(svn_fs_t *fs,
return svn_fs_fs__with_write_lock(fs, change_rev_prop_body, &cb, pool);
}
-
+
svn_error_t *
svn_fs_fs__info_format(int *fs_format,
svn_version_t **supports_version,
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h Thu Jul 25 14:43:44 2013
@@ -51,15 +51,6 @@ svn_error_t *svn_fs_fs__youngest_rev(svn
svn_fs_t *fs,
apr_pool_t *pool);
-/* For revision REV in fileysystem FS, open the revision (or packed rev)
- file and seek to the start of the revision. Return it in *FILE, and
- use POOL for allocations. */
-svn_error_t *
-svn_fs_fs__open_pack_or_rev_file(apr_file_t **file,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *pool);
-
/* Return SVN_ERR_FS_NO_SUCH_REVISION if the given revision REV is newer
than the current youngest revision in FS or is simply not a valid
revision number, else return success. */
@@ -68,20 +59,6 @@ svn_fs_fs__ensure_revision_exists(svn_re
svn_fs_t *fs,
apr_pool_t *pool);
-/* Return an error iff REV does not exist in FS. */
-svn_error_t *
-svn_fs_fs__revision_exists(svn_revnum_t rev,
- svn_fs_t *fs,
- apr_pool_t *pool);
-
-/* Set *PROPLIST to be an apr_hash_t containing the property list of
- revision REV as seen in filesystem FS. Use POOL for temporary
- allocations. */
-svn_error_t *svn_fs_fs__revision_proplist(apr_hash_t **proplist,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *pool);
-
/* Set *LENGTH to the be fulltext length of the node revision
specified by NODEREV. Use POOL for temporary allocations. */
svn_error_t *svn_fs_fs__file_length(svn_filesize_t *length,
@@ -126,30 +103,13 @@ svn_error_t *svn_fs_fs__set_uuid(svn_fs_
const char *uuid,
apr_pool_t *pool);
-/* Set *PATH to the path of REV in FS, whether in a pack file or not.
- Allocate *PATH in POOL.
-
- Note: If the caller does not have the write lock on FS, then the path is
- not guaranteed to be correct or to remain correct after the function
- returns, because the revision might become packed before or after this
- call. If a file exists at that path, then it is correct; if not, then
- the caller should call update_min_unpacked_rev() and re-try once. */
-const char *
-svn_fs_fs__path_rev_absolute(svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *pool);
-
/* Return the path to the 'current' file in FS.
Perform allocation in POOL. */
const char *
svn_fs_fs__path_current(svn_fs_t *fs, apr_pool_t *pool);
-/* Read the format number and maximum number of files per directory
- from PATH and return them in *PFORMAT and *MAX_FILES_PER_DIR
- respectively.
-
- *MAX_FILES_PER_DIR is obtained from the 'layout' format option, and
- will be set to zero if a linear scheme should be used.
+/* Write the format number and maximum number of files per directory
+ for FS, possibly expecting to overwrite a previously existing file.
Use POOL for temporary allocation. */
svn_error_t *
@@ -157,6 +117,25 @@ svn_fs_fs__write_format(svn_fs_t *fs,
svn_boolean_t overwrite,
apr_pool_t *pool);
+/* Obtain a write lock on the filesystem FS in a subpool of POOL, call
+ BODY with BATON and that subpool, destroy the subpool (releasing the write
+ lock) and return what BODY returned. */
+svn_error_t *
+svn_fs_fs__with_write_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
+ apr_pool_t *pool),
+ void *baton,
+ apr_pool_t *pool);
+
+/* Run BODY (with BATON and POOL) while the txn-current file
+ of FS is locked. */
+svn_error_t *
+svn_fs_fs__with_txn_current_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
+ apr_pool_t *pool),
+ void *baton,
+ apr_pool_t *pool);
+
/* Find the value of the property named PROPNAME in transaction TXN.
Return the contents in *VALUE_P. The contents will be allocated
from POOL. */
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/hotcopy.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/hotcopy.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/hotcopy.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/hotcopy.c Thu Jul 25 14:43:44 2013
@@ -26,10 +26,9 @@
#include "fs_fs.h"
#include "hotcopy.h"
#include "util.h"
+#include "recovery.h"
#include "revprops.h"
#include "rep-cache.h"
-#include "transaction.h"
-#include "recovery.h"
#include "../libsvn_fs/fs-loader.h"
@@ -341,8 +340,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
if (*dst_min_unpacked_rev < rev + max_files_per_dir)
{
*dst_min_unpacked_rev = rev + max_files_per_dir;
- SVN_ERR(svn_fs_fs__write_revnum_file(dst_fs,
- *dst_min_unpacked_rev,
+ SVN_ERR(svn_fs_fs__write_revnum_file(dst_fs, *dst_min_unpacked_rev,
scratch_pool));
}
@@ -829,9 +827,9 @@ hotcopy_body(void *baton, apr_pool_t *po
SVN_ERR(svn_io_check_path(svn_fs_fs__path_revprop_generation(src_fs, pool),
&kind, pool));
if (kind == svn_node_file)
- SVN_ERR(write_revprop_generation_file(dst_fs, 0, pool));
+ SVN_ERR(svn_fs_fs__write_revprop_generation_file(dst_fs, 0, pool));
- SVN_ERR(cleanup_revprop_namespace(dst_fs));
+ SVN_ERR(svn_fs_fs__cleanup_revprop_namespace(dst_fs));
/* Hotcopied FS is complete. Stamp it with a format file. */
dst_ffd->max_files_per_dir = max_files_per_dir;
@@ -875,19 +873,19 @@ hotcopy_create_empty_dest(svn_fs_t *src_
/* Create the revision data directories. */
if (dst_ffd->max_files_per_dir)
- SVN_ERR(svn_io_make_dir_recursively(
- svn_fs_fs__path_rev_shard(dst_fs, 0, pool),
- pool));
+ SVN_ERR(svn_io_make_dir_recursively(svn_fs_fs__path_rev_shard(dst_fs,
+ 0, pool),
+ pool));
else
- SVN_ERR(svn_io_make_dir_recursively(
- svn_dirent_join(dst_path, PATH_REVS_DIR, pool),
- pool));
+ SVN_ERR(svn_io_make_dir_recursively(svn_dirent_join(dst_path,
+ PATH_REVS_DIR, pool),
+ pool));
/* Create the revprops directory. */
if (src_ffd->max_files_per_dir)
SVN_ERR(svn_io_make_dir_recursively(
- svn_fs_fs__path_revprops_shard(dst_fs, 0, pool),
- pool));
+ svn_fs_fs__path_revprops_shard(dst_fs, 0, pool),
+ pool));
else
SVN_ERR(svn_io_make_dir_recursively(svn_dirent_join(dst_path,
PATH_REVPROPS_DIR,
@@ -908,10 +906,10 @@ hotcopy_create_empty_dest(svn_fs_t *src_
/* Create the 'current' file. */
SVN_ERR(svn_io_file_create(svn_fs_fs__path_current(dst_fs, pool),
- (dst_ffd->format >=
- SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT
- ? "0\n" : "0 1 1\n"),
- pool));
+ (dst_ffd->format >=
+ SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT
+ ? "0\n" : "0 1 1\n"),
+ pool));
/* Create lock file and UUID. */
SVN_ERR(svn_io_file_create_empty(svn_fs_fs__path_lock(dst_fs, pool), pool));
@@ -919,9 +917,8 @@ hotcopy_create_empty_dest(svn_fs_t *src_
/* Create the min unpacked rev file. */
if (dst_ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
- SVN_ERR(svn_io_file_create(
- svn_fs_fs__path_min_unpacked_rev(dst_fs, pool),
- "0\n", pool));
+ SVN_ERR(svn_io_file_create(svn_fs_fs__path_min_unpacked_rev(dst_fs, pool),
+ "0\n", pool));
/* Create the txn-current file if the repository supports
the transaction sequence file. */
if (dst_ffd->format >= SVN_FS_FS__MIN_TXN_CURRENT_FORMAT)
@@ -929,8 +926,8 @@ hotcopy_create_empty_dest(svn_fs_t *src_
SVN_ERR(svn_io_file_create(svn_fs_fs__path_txn_current(dst_fs, pool),
"0\n", pool));
SVN_ERR(svn_io_file_create_empty(
- svn_fs_fs__path_txn_current_lock(dst_fs, pool),
- pool));
+ svn_fs_fs__path_txn_current_lock(dst_fs, pool),
+ pool));
}
dst_ffd->youngest_rev_cache = 0;
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c Thu Jul 25 14:43:44 2013
@@ -24,7 +24,6 @@
#include <stdlib.h>
#include "id.h"
-#include "index.h"
#include "../libsvn_fs/fs-loader.h"
#include "private/svn_temp_serializer.h"
@@ -37,10 +36,13 @@ typedef struct fs_fs__id_t
svn_fs_id_t generic_id;
/* private members */
- svn_fs_fs__id_part_t node_id;
- svn_fs_fs__id_part_t copy_id;
- svn_fs_fs__id_part_t txn_id;
- svn_fs_fs__id_part_t rev_item;
+ struct
+ {
+ svn_fs_fs__id_part_t node_id;
+ svn_fs_fs__id_part_t copy_id;
+ svn_fs_fs__id_part_t txn_id;
+ svn_fs_fs__id_part_t rev_offset;
+ } private_id;
} fs_fs__id_t;
@@ -189,7 +191,7 @@ svn_fs_fs__id_node_id(const svn_fs_id_t
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return &id->node_id;
+ return &id->private_id.node_id;
}
@@ -198,7 +200,7 @@ svn_fs_fs__id_copy_id(const svn_fs_id_t
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return &id->copy_id;
+ return &id->private_id.copy_id;
}
@@ -207,16 +209,16 @@ svn_fs_fs__id_txn_id(const svn_fs_id_t *
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return &id->txn_id;
+ return &id->private_id.txn_id;
}
const svn_fs_fs__id_part_t *
-svn_fs_fs__id_rev_item(const svn_fs_id_t *fs_id)
+svn_fs_fs__id_rev_offset(const svn_fs_id_t *fs_id)
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return &id->rev_item;
+ return &id->private_id.rev_offset;
}
svn_revnum_t
@@ -224,16 +226,15 @@ svn_fs_fs__id_rev(const svn_fs_id_t *fs_
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return id->rev_item.revision;
+ return id->private_id.rev_offset.revision;
}
-
apr_uint64_t
-svn_fs_fs__id_item(const svn_fs_id_t *fs_id)
+svn_fs_fs__id_offset(const svn_fs_id_t *fs_id)
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return id->rev_item.number;
+ return id->private_id.rev_offset.number;
}
svn_boolean_t
@@ -241,7 +242,7 @@ svn_fs_fs__id_is_txn(const svn_fs_id_t *
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return svn_fs_fs__id_txn_used(&id->txn_id);
+ return svn_fs_fs__id_txn_used(&id->private_id.txn_id);
}
svn_string_t *
@@ -251,22 +252,22 @@ svn_fs_fs__id_unparse(const svn_fs_id_t
char string[6 * SVN_INT64_BUFFER_SIZE + 10];
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- char *p = unparse_id_part(string, &id->node_id);
- p = unparse_id_part(p, &id->copy_id);
+ char *p = unparse_id_part(string, &id->private_id.node_id);
+ p = unparse_id_part(p, &id->private_id.copy_id);
- if (svn_fs_fs__id_txn_used(&id->txn_id))
+ if (svn_fs_fs__id_txn_used(&id->private_id.txn_id))
{
*(p++) = 't';
- p += svn__i64toa(p, id->txn_id.revision);
+ p += svn__i64toa(p, id->private_id.txn_id.revision);
*(p++) = '-';
- p += svn__ui64tobase36(p, id->txn_id.number);
+ p += svn__ui64tobase36(p, id->private_id.txn_id.number);
}
else
{
*(p++) = 'r';
- p += svn__i64toa(p, id->rev_item.revision);
+ p += svn__i64toa(p, id->private_id.rev_offset.revision);
*(p++) = '/';
- p += svn__i64toa(p, id->rev_item.number);
+ p += svn__i64toa(p, id->private_id.rev_offset.number);
}
return svn_string_ncreate(string, p - string, pool);
@@ -285,8 +286,8 @@ svn_fs_fs__id_eq(const svn_fs_id_t *a,
if (a == b)
return TRUE;
- return memcmp(&id_a->node_id, &id_b->node_id,
- sizeof(*id_a) - sizeof(id_a->generic_id)) == 0;
+ return memcmp(&id_a->private_id, &id_b->private_id,
+ sizeof(id_a->private_id)) == 0;
}
@@ -302,14 +303,16 @@ svn_fs_fs__id_check_related(const svn_fs
/* If both node_ids start with _ and they have differing transaction
IDs, then it is impossible for them to be related. */
- if (id_a->node_id.revision == SVN_INVALID_REVNUM)
+ if (id_a->private_id.node_id.revision == SVN_INVALID_REVNUM)
{
- if ( !svn_fs_fs__id_part_eq(&id_a->txn_id, &id_b->txn_id)
- || !svn_fs_fs__id_txn_used(&id_a->txn_id))
+ if ( !svn_fs_fs__id_part_eq(&id_a->private_id.txn_id,
+ &id_b->private_id.txn_id)
+ || !svn_fs_fs__id_txn_used(&id_a->private_id.txn_id))
return FALSE;
}
- return svn_fs_fs__id_part_eq(&id_a->node_id, &id_b->node_id);
+ return svn_fs_fs__id_part_eq(&id_a->private_id.node_id,
+ &id_b->private_id.node_id);
}
@@ -351,8 +354,8 @@ svn_fs_fs__id_txn_create_root(const svn_
/* node ID and copy ID are "0" */
- id->txn_id = *txn_id;
- id->rev_item.revision = SVN_INVALID_REVNUM;
+ id->private_id.txn_id = *txn_id;
+ id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
id->generic_id.vtable = &id_vtable;
id->generic_id.fsap_data = &id;
@@ -368,10 +371,10 @@ svn_fs_fs__id_txn_create(const svn_fs_fs
{
fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
- id->node_id = *node_id;
- id->copy_id = *copy_id;
- id->txn_id = *txn_id;
- id->rev_item.revision = SVN_INVALID_REVNUM;
+ id->private_id.node_id = *node_id;
+ id->private_id.copy_id = *copy_id;
+ id->private_id.txn_id = *txn_id;
+ id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
id->generic_id.vtable = &id_vtable;
id->generic_id.fsap_data = &id;
@@ -383,15 +386,15 @@ svn_fs_fs__id_txn_create(const svn_fs_fs
svn_fs_id_t *
svn_fs_fs__id_rev_create(const svn_fs_fs__id_part_t *node_id,
const svn_fs_fs__id_part_t *copy_id,
- const svn_fs_fs__id_part_t *rev_item,
+ const svn_fs_fs__id_part_t *rev_offset,
apr_pool_t *pool)
{
fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
- id->node_id = *node_id;
- id->copy_id = *copy_id;
- id->txn_id.revision = SVN_INVALID_REVNUM;
- id->rev_item = *rev_item;
+ id->private_id.node_id = *node_id;
+ id->private_id.copy_id = *copy_id;
+ id->private_id.txn_id.revision = SVN_INVALID_REVNUM;
+ id->private_id.rev_offset = *rev_offset;
id->generic_id.vtable = &id_vtable;
id->generic_id.fsap_data = &id;
@@ -440,14 +443,14 @@ svn_fs_fs__id_parse(const char *data,
str = svn_cstring_tokenize(".", &data_copy);
if (str == NULL)
return NULL;
- if (! part_parse(&id->node_id, str))
+ if (! part_parse(&id->private_id.node_id, str))
return NULL;
/* Copy Id */
str = svn_cstring_tokenize(".", &data_copy);
if (str == NULL)
return NULL;
- if (! part_parse(&id->copy_id, str))
+ if (! part_parse(&id->private_id.copy_id, str))
return NULL;
/* Txn/Rev Id */
@@ -461,14 +464,14 @@ svn_fs_fs__id_parse(const char *data,
svn_error_t *err;
/* This is a revision type ID */
- id->txn_id.revision = SVN_INVALID_REVNUM;
- id->txn_id.number = 0;
+ id->private_id.txn_id.revision = SVN_INVALID_REVNUM;
+ id->private_id.txn_id.number = 0;
data_copy = str + 1;
str = svn_cstring_tokenize("/", &data_copy);
if (str == NULL)
return NULL;
- id->rev_item.revision = SVN_STR_TO_REV(str);
+ id->private_id.rev_offset.revision = SVN_STR_TO_REV(str);
err = svn_cstring_atoi64(&val, data_copy);
if (err)
@@ -476,15 +479,15 @@ svn_fs_fs__id_parse(const char *data,
svn_error_clear(err);
return NULL;
}
- id->rev_item.number = (apr_uint64_t)val;
+ id->private_id.rev_offset.number = (apr_uint64_t)val;
}
else if (str[0] == 't')
{
/* This is a transaction type ID */
- id->rev_item.revision = SVN_INVALID_REVNUM;
- id->rev_item.number = 0;
+ id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
+ id->private_id.rev_offset.number = 0;
- if (! txn_id_parse(&id->txn_id, str + 1))
+ if (! txn_id_parse(&id->private_id.txn_id, str + 1))
return NULL;
}
else
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h Thu Jul 25 14:43:44 2013
@@ -40,7 +40,9 @@ typedef struct svn_fs_fs__id_part_t
0 for others -> old-style ID or the root in rev 0. */
svn_revnum_t revision;
- /* some numerical value. */
+ /* sub-id value relative to REVISION. Its interpretation depends on
+ the part itself. In rev_offset, it is the offset value, in others
+ it represents a unique counter value. */
apr_uint64_t number;
} svn_fs_fs__id_part_t;
@@ -82,16 +84,16 @@ const svn_fs_fs__id_part_t *svn_fs_fs__i
/* Get the "txn id" portion of ID, or NULL if it is a permanent ID. */
const svn_fs_fs__id_part_t *svn_fs_fs__id_txn_id(const svn_fs_id_t *id);
-/* Get the "rev,item" portion of ID. */
-const svn_fs_fs__id_part_t *svn_fs_fs__id_rev_item(const svn_fs_id_t *id);
+/* Get the "rev,offset" portion of ID. */
+const svn_fs_fs__id_part_t *svn_fs_fs__id_rev_offset(const svn_fs_id_t *id);
/* Get the "rev" portion of ID, or SVN_INVALID_REVNUM if it is a
transaction ID. */
svn_revnum_t svn_fs_fs__id_rev(const svn_fs_id_t *id);
-/* Access the "item" portion of the ID, or 0 if it is a transaction
+/* Access the "offset" portion of the ID, or 0 if it is a transaction
ID. */
-apr_uint64_t svn_fs_fs__id_item(const svn_fs_id_t *id);
+apr_uint64_t svn_fs_fs__id_offset(const svn_fs_id_t *id);
/* Return TRUE, if this is a transaction ID. */
svn_boolean_t svn_fs_fs__id_is_txn(const svn_fs_id_t *id);
@@ -127,11 +129,11 @@ svn_fs_id_t *svn_fs_fs__id_txn_create(co
const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
-/* Create a permanent ID based on NODE_ID, COPY_ID and REV_ITEM,
+/* Create a permanent ID based on NODE_ID, COPY_ID and REV_OFFSET,
allocated in POOL. */
svn_fs_id_t *svn_fs_fs__id_rev_create(const svn_fs_fs__id_part_t *node_id,
const svn_fs_fs__id_part_t *copy_id,
- const svn_fs_fs__id_part_t *rev_item,
+ const svn_fs_fs__id_part_t *rev_offset,
apr_pool_t *pool);
/* Return a copy of ID, allocated from POOL. */
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/lock.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/lock.c Thu Jul 25 14:43:44 2013
@@ -37,7 +37,7 @@
#include "lock.h"
#include "tree.h"
#include "fs_fs.h"
-#include "transaction.h"
+#include "util.h"
#include "../libsvn_fs/fs-loader.h"
#include "private/svn_fs_util.h"
@@ -457,8 +457,7 @@ delete_lock(svn_fs_t *fs,
}
else
{
- const char *rev_0_path
- = svn_fs_fs__path_rev_absolute(fs, 0, pool);
+ const char *rev_0_path = svn_fs_fs__path_rev_absolute(fs, 0, pool);
SVN_ERR(write_digest_file(this_children, this_lock, fs->path,
digest_path, rev_0_path, subpool));
}