diff options
| author | Peter Wemm <peter@FreeBSD.org> | 2018-05-08 03:44:38 +0000 | 
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 2018-05-08 03:44:38 +0000 | 
| commit | 3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (patch) | |
| tree | 7e47911263e75034b767fe34b2f8d3d17e91f66d /subversion/libsvn_fs_base | |
| parent | a55fb3c0d5eca7d887798125d5b95942b1f01d4b (diff) | |
Diffstat (limited to 'subversion/libsvn_fs_base')
| -rw-r--r-- | subversion/libsvn_fs_base/bdb/rev-table.c | 3 | ||||
| -rw-r--r-- | subversion/libsvn_fs_base/fs.c | 44 | ||||
| -rw-r--r-- | subversion/libsvn_fs_base/fs_init.h | 33 | ||||
| -rw-r--r-- | subversion/libsvn_fs_base/lock.c | 2 | ||||
| -rw-r--r-- | subversion/libsvn_fs_base/revs-txns.c | 24 | ||||
| -rw-r--r-- | subversion/libsvn_fs_base/revs-txns.h | 8 | ||||
| -rw-r--r-- | subversion/libsvn_fs_base/tree.c | 80 | 
7 files changed, 137 insertions, 57 deletions
| diff --git a/subversion/libsvn_fs_base/bdb/rev-table.c b/subversion/libsvn_fs_base/bdb/rev-table.c index b752249bfa78..c39d2c962761 100644 --- a/subversion/libsvn_fs_base/bdb/rev-table.c +++ b/subversion/libsvn_fs_base/bdb/rev-table.c @@ -79,6 +79,9 @@ svn_fs_bdb__get_rev(revision_t **revision_p,       numbers begin with one.  */    db_recno_t recno = (db_recno_t) rev + 1; +  if (!SVN_IS_VALID_REVNUM(rev)) +    return svn_fs_base__err_dangling_rev(fs, rev); +    svn_fs_base__trail_debug(trail, "revisions", "get");    db_err = bfd->revisions->get(bfd->revisions, trail->db_txn,                                 svn_fs_base__set_dbt(&key, &recno, diff --git a/subversion/libsvn_fs_base/fs.c b/subversion/libsvn_fs_base/fs.c index 06dfbaf2f419..903225725f06 100644 --- a/subversion/libsvn_fs_base/fs.c +++ b/subversion/libsvn_fs_base/fs.c @@ -471,6 +471,13 @@ bdb_write_config(svn_fs_t *fs)  }  static svn_error_t * +base_bdb_refresh_revision(svn_fs_t *fs, +                          apr_pool_t *scratch_pool) +{ +  return SVN_NO_ERROR; +} + +static svn_error_t *  base_bdb_info_format(int *fs_format,                       svn_version_t **supports_version,                       svn_fs_t *fs, @@ -545,6 +552,7 @@ base_bdb_freeze(svn_fs_t *fs,  static fs_vtable_t fs_vtable = {    svn_fs_base__youngest_rev, +  base_bdb_refresh_revision,    svn_fs_base__revision_prop,    svn_fs_base__revision_proplist,    svn_fs_base__change_rev_prop, @@ -572,13 +580,12 @@ static fs_vtable_t fs_vtable = {  #define FORMAT_FILE   "format"  /* Depending on CREATE, create or open the environment and databases -   for filesystem FS in PATH. Use POOL for temporary allocations. */ +   for filesystem FS in PATH. */  static svn_error_t *  open_databases(svn_fs_t *fs,                 svn_boolean_t create,                 int format, -               const char *path, -               apr_pool_t *pool) +               const char *path)  {    base_fs_data_t *bfd; @@ -732,7 +739,7 @@ static svn_error_t *  base_create(svn_fs_t *fs,              const char *path,              svn_mutex__t *common_pool_lock, -            apr_pool_t *pool, +            apr_pool_t *scratch_pool,              apr_pool_t *common_pool)  {    int format = SVN_FS_BASE__FORMAT_NUMBER; @@ -743,7 +750,7 @@ base_create(svn_fs_t *fs,      {        svn_version_t *compatible_version;        SVN_ERR(svn_fs__compatible_version(&compatible_version, fs->config, -                                         pool)); +                                         scratch_pool));        /* select format number */        switch(compatible_version->minor) @@ -765,7 +772,7 @@ base_create(svn_fs_t *fs,      }    /* Create the environment and databases. */ -  svn_err = open_databases(fs, TRUE, format, path, pool); +  svn_err = open_databases(fs, TRUE, format, path);    if (svn_err) goto error;    /* Initialize the DAG subsystem. */ @@ -773,14 +780,15 @@ base_create(svn_fs_t *fs,    if (svn_err) goto error;    /* This filesystem is ready.  Stamp it with a format number. */ -  svn_err = svn_io_write_version_file( -   svn_dirent_join(fs->path, FORMAT_FILE, pool), format, pool); +  svn_err = svn_io_write_version_file(svn_dirent_join(fs->path, FORMAT_FILE, +                                                      scratch_pool), +                                      format, scratch_pool);    if (svn_err) goto error;    ((base_fs_data_t *) fs->fsap_data)->format = format; -  SVN_ERR(populate_opened_fs(fs, pool)); -  return SVN_NO_ERROR;; +  SVN_ERR(populate_opened_fs(fs, scratch_pool)); +  return SVN_NO_ERROR;  error:    return svn_error_compose_create(svn_err, @@ -826,7 +834,7 @@ static svn_error_t *  base_open(svn_fs_t *fs,            const char *path,            svn_mutex__t *common_pool_lock, -          apr_pool_t *pool, +          apr_pool_t *scratch_pool,            apr_pool_t *common_pool)  {    int format; @@ -835,8 +843,9 @@ base_open(svn_fs_t *fs,    /* Read the FS format number. */    svn_err = svn_io_read_version_file(&format, -                                     svn_dirent_join(path, FORMAT_FILE, pool), -                                     pool); +                                     svn_dirent_join(path, FORMAT_FILE, +                                                     scratch_pool), +                                     scratch_pool);    if (svn_err && APR_STATUS_IS_ENOENT(svn_err->apr_err))      {        /* Pre-1.2 filesystems did not have a format file (you could say @@ -852,7 +861,7 @@ base_open(svn_fs_t *fs,      goto error;    /* Create the environment and databases. */ -  svn_err = open_databases(fs, FALSE, format, path, pool); +  svn_err = open_databases(fs, FALSE, format, path);    if (svn_err) goto error;    ((base_fs_data_t *) fs->fsap_data)->format = format; @@ -862,12 +871,12 @@ base_open(svn_fs_t *fs,    if (write_format_file)      {        svn_err = svn_io_write_version_file(svn_dirent_join(path, FORMAT_FILE, -                                                        pool), -                                          format, pool); +                                                        scratch_pool), +                                          format, scratch_pool);        if (svn_err) goto error;      } -  SVN_ERR(populate_opened_fs(fs, pool)); +  SVN_ERR(populate_opened_fs(fs, scratch_pool));    return SVN_NO_ERROR;   error: @@ -948,6 +957,7 @@ base_upgrade(svn_fs_t *fs,        err = SVN_NO_ERROR;      }    SVN_ERR(err); +  SVN_ERR(check_format(old_format_number));    /* Bump the format file's stored version number. */    SVN_ERR(svn_io_write_version_file(version_file_path, diff --git a/subversion/libsvn_fs_base/fs_init.h b/subversion/libsvn_fs_base/fs_init.h new file mode 100644 index 000000000000..012a40593e09 --- /dev/null +++ b/subversion/libsvn_fs_base/fs_init.h @@ -0,0 +1,33 @@ +/* + * libsvn_fs_base/fs_init.h:  Exported function of libsvn_fs_base + * + * + * ==================================================================== + *    Licensed to the Apache Software Foundation (ASF) under one + *    or more contributor license agreements.  See the NOTICE file + *    distributed with this work for additional information + *    regarding copyright ownership.  The ASF licenses this file + *    to you under the Apache License, Version 2.0 (the + *    "License"); you may not use this file except in compliance + *    with the License.  You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + *    Unless required by applicable law or agreed to in writing, + *    software distributed under the License is distributed on an + *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + *    KIND, either express or implied.  See the License for the + *    specific language governing permissions and limitations + *    under the License. + * ==================================================================== + */ + +#ifndef LIBSVN_FS_LOADER_H +#error Please include libsvn_fs/fs_loader.h instead of this file +#else + +svn_error_t *svn_fs_base__init(const svn_version_t *loader_version, +                               fs_library_vtable_t **vtable, +                               apr_pool_t* common_pool); + +#endif diff --git a/subversion/libsvn_fs_base/lock.c b/subversion/libsvn_fs_base/lock.c index 1145207ea38c..7593e9321f37 100644 --- a/subversion/libsvn_fs_base/lock.c +++ b/subversion/libsvn_fs_base/lock.c @@ -108,7 +108,7 @@ txn_body_lock(void *baton, trail_t *trail)    SVN_ERR(svn_fs_base__get_path_kind(&kind, args->path, trail, trail->pool));    /* Until we implement directory locks someday, we only allow locks -     on files or non-existent paths. */ +     on files. */    if (kind == svn_node_dir)      return SVN_FS__ERR_NOT_FILE(trail->fs, args->path); diff --git a/subversion/libsvn_fs_base/revs-txns.c b/subversion/libsvn_fs_base/revs-txns.c index f1029f4e0d0f..2ee65455d7d5 100644 --- a/subversion/libsvn_fs_base/revs-txns.c +++ b/subversion/libsvn_fs_base/revs-txns.c @@ -194,7 +194,9 @@ svn_error_t *  svn_fs_base__revision_proplist(apr_hash_t **table_p,                                 svn_fs_t *fs,                                 svn_revnum_t rev, -                               apr_pool_t *pool) +                               svn_boolean_t refresh, +                               apr_pool_t *result_pool, +                               apr_pool_t *scratch_pool)  {    struct revision_proplist_args args;    apr_hash_t *table; @@ -204,9 +206,9 @@ svn_fs_base__revision_proplist(apr_hash_t **table_p,    args.table_p = &table;    args.rev = rev;    SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_revision_proplist, &args, -                                 FALSE, pool)); +                                 FALSE, result_pool)); -  *table_p = table ? table : apr_hash_make(pool); +  *table_p = table ? table : apr_hash_make(result_pool);    return SVN_NO_ERROR;  } @@ -216,7 +218,9 @@ svn_fs_base__revision_prop(svn_string_t **value_p,                             svn_fs_t *fs,                             svn_revnum_t rev,                             const char *propname, -                           apr_pool_t *pool) +                           svn_boolean_t refresh, +                           apr_pool_t *result_pool, +                           apr_pool_t *scratch_pool)  {    struct revision_proplist_args args;    apr_hash_t *table; @@ -227,7 +231,7 @@ svn_fs_base__revision_prop(svn_string_t **value_p,    args.table_p = &table;    args.rev = rev;    SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_revision_proplist, &args, -                                 FALSE, pool)); +                                 FALSE, result_pool));    /* And then the prop from that list (if there was a list). */    *value_p = svn_hash_gets(table, propname); @@ -247,8 +251,10 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,  {    transaction_t *txn;    const char *txn_id; +  const svn_string_t *present_value;    SVN_ERR(get_rev_txn(&txn, &txn_id, fs, rev, trail, pool)); +  present_value = svn_hash_gets(txn->proplist, name);    /* If there's no proplist, but we're just deleting a property, exit now. */    if ((! txn->proplist) && (! value)) @@ -262,7 +268,6 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,    if (old_value_p)      {        const svn_string_t *wanted_value = *old_value_p; -      const svn_string_t *present_value = svn_hash_gets(txn->proplist, name);        if ((!wanted_value != !present_value)            || (wanted_value && present_value                && !svn_string_compare(wanted_value, present_value))) @@ -275,6 +280,13 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,          }        /* Fall through. */      } + +  /* If the prop-set is a no-op, skip the actual write. */ +  if ((!present_value && !value) +      || (present_value && value +          && svn_string_compare(present_value, value))) +    return SVN_NO_ERROR; +    svn_hash_sets(txn->proplist, name, value);    /* Overwrite the revision. */ diff --git a/subversion/libsvn_fs_base/revs-txns.h b/subversion/libsvn_fs_base/revs-txns.h index 558a90c89266..4a2082773f6f 100644 --- a/subversion/libsvn_fs_base/revs-txns.h +++ b/subversion/libsvn_fs_base/revs-txns.h @@ -172,12 +172,16 @@ svn_error_t *svn_fs_base__youngest_rev(svn_revnum_t *youngest_p, svn_fs_t *fs,  svn_error_t *svn_fs_base__revision_prop(svn_string_t **value_p, svn_fs_t *fs,                                          svn_revnum_t rev,                                          const char *propname, -                                        apr_pool_t *pool); +                                        svn_boolean_t refresh, +                                        apr_pool_t *result_pool, +                                        apr_pool_t *scratch_pool);  svn_error_t *svn_fs_base__revision_proplist(apr_hash_t **table_p,                                              svn_fs_t *fs,                                              svn_revnum_t rev, -                                            apr_pool_t *pool); +                                            svn_boolean_t refresh, +                                            apr_pool_t *result_pool, +                                            apr_pool_t *scratch_pool);  svn_error_t *svn_fs_base__change_rev_prop(svn_fs_t *fs, svn_revnum_t rev,                                            const char *name, diff --git a/subversion/libsvn_fs_base/tree.c b/subversion/libsvn_fs_base/tree.c index 924e7c94a2a0..ba5debbd970b 100644 --- a/subversion/libsvn_fs_base/tree.c +++ b/subversion/libsvn_fs_base/tree.c @@ -68,6 +68,7 @@  #include "private/svn_fspath.h"  #include "private/svn_fs_util.h"  #include "private/svn_mergeinfo_private.h" +#include "private/svn_sorts_private.h"  /* ### I believe this constant will become internal to reps-strings.c. @@ -2580,8 +2581,7 @@ verify_locks(const char *txn_name,        apr_hash_this(hi, &key, NULL, NULL);        APR_ARRAY_PUSH(changed_paths, const char *) = key;      } -  qsort(changed_paths->elts, changed_paths->nelts, -        changed_paths->elt_size, svn_sort_compare_paths); +  svn_sort__array(changed_paths, svn_sort_compare_paths);    /* Now, traverse the array of changed paths, verify locks.  Note       that if we need to do a recursive verification a path, we'll skip @@ -2661,7 +2661,7 @@ txn_body_commit(void *baton, trail_t *trail)    svn_revnum_t youngest_rev;    const svn_fs_id_t *y_rev_root_id; -  dag_node_t *txn_base_root_node; +  dag_node_t *txn_base_root_node, *txn_root_node;    /* Getting the youngest revision locks the revisions table until       this trail is done. */ @@ -2694,6 +2694,19 @@ txn_body_commit(void *baton, trail_t *trail)       discovered locks. */    SVN_ERR(verify_locks(txn_name, trail, trail->pool)); +  /* Ensure every txn has a mutable root as then the new revision will +     have a distinct root node-revision-id.  This is necessary as +     future transactions use the root node-revision-id as a proxy for +     the transaction base revision. */ +  SVN_ERR(svn_fs_base__dag_txn_root(&txn_root_node, fs, txn_name, +                                    trail, trail->pool)); +  if (!svn_fs_base__dag_check_mutable(txn_root_node, txn->id)) +    { +      dag_node_t *clone; +      SVN_ERR(svn_fs_base__dag_clone_root(&clone, fs, txn->id, +                                          trail, trail->pool)); +    } +    /* Else, commit the txn. */    return svn_fs_base__dag_commit_txn(&(args->new_rev), txn, trail,                                       trail->pool); @@ -5061,8 +5074,8 @@ base_node_origin_rev(svn_revnum_t *revision,  /* Examine directory NODE's immediately children for mergeinfo. -   For those which have explicit mergeinfo, add their mergeinfo to -   RESULT_CATALOG (allocated in RESULT_CATALOG's pool). +   For those which have explicit mergeinfo, invoke RECEIVER with +   RECEIVER_BATON.     For those which don't, but sit atop trees which contain mergeinfo     somewhere deeper, add them to *CHILDREN_ATOP_MERGEINFO_TREES, a @@ -5076,10 +5089,11 @@ base_node_origin_rev(svn_revnum_t *revision,  struct get_mergeinfo_data_and_entries_baton  { -  svn_mergeinfo_catalog_t result_catalog;    apr_hash_t *children_atop_mergeinfo_trees;    dag_node_t *node;    const char *node_path; +  svn_fs_mergeinfo_receiver_t receiver; +  void *receiver_baton;  };  static svn_error_t * @@ -5090,7 +5104,6 @@ txn_body_get_mergeinfo_data_and_entries(void *baton, trail_t *trail)    apr_hash_t *entries;    apr_hash_index_t *hi;    apr_pool_t *iterpool = svn_pool_create(trail->pool); -  apr_pool_t *result_pool = apr_hash_pool_get(args->result_catalog);    apr_pool_t *children_pool =      apr_hash_pool_get(args->children_atop_mergeinfo_trees); @@ -5144,7 +5157,7 @@ txn_body_get_mergeinfo_data_and_entries(void *baton, trail_t *trail)               CHILD_NODE then treat it as if no mergeinfo is present rather               than raising a parse error. */            err = svn_mergeinfo_parse(&child_mergeinfo, pval->data, -                                    result_pool); +                                    iterpool);            if (err)              {                if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR) @@ -5154,10 +5167,12 @@ txn_body_get_mergeinfo_data_and_entries(void *baton, trail_t *trail)              }            else              { -              svn_hash_sets(args->result_catalog, -                            svn_fspath__join(args->node_path, dirent->name, -                                             result_pool), -                            child_mergeinfo); +              SVN_ERR(args->receiver(svn_fspath__join(args->node_path, +                                                      dirent->name, +                                                      iterpool), +                                     child_mergeinfo, +                                     args->receiver_baton, +                                     iterpool));              }          } @@ -5191,7 +5206,8 @@ static svn_error_t *  crawl_directory_for_mergeinfo(svn_fs_t *fs,                                dag_node_t *node,                                const char *node_path, -                              svn_mergeinfo_catalog_t result_catalog, +                              svn_fs_mergeinfo_receiver_t receiver, +                              void *baton,                                apr_pool_t *pool)  {    struct get_mergeinfo_data_and_entries_baton gmdae_args; @@ -5201,10 +5217,11 @@ crawl_directory_for_mergeinfo(svn_fs_t *fs,    /* Add mergeinfo for immediate children that have it, and fetch       immediate children that *don't* have it but sit atop trees that do. */ -  gmdae_args.result_catalog = result_catalog;    gmdae_args.children_atop_mergeinfo_trees = children_atop_mergeinfo_trees;    gmdae_args.node = node;    gmdae_args.node_path = node_path; +  gmdae_args.receiver = receiver; +  gmdae_args.receiver_baton = baton;    SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_get_mergeinfo_data_and_entries,                                   &gmdae_args, FALSE, pool)); @@ -5226,7 +5243,7 @@ crawl_directory_for_mergeinfo(svn_fs_t *fs,        SVN_ERR(crawl_directory_for_mergeinfo(fs, val,                                              svn_fspath__join(node_path, key,                                                               iterpool), -                                            result_catalog, iterpool)); +                                            receiver, baton, iterpool));      }    svn_pool_destroy(iterpool);    return SVN_NO_ERROR; @@ -5384,20 +5401,21 @@ txn_body_get_node_mergeinfo_stats(void *baton, trail_t *trail)  } -/* Get the mergeinfo for a set of paths, returned in -   *MERGEINFO_CATALOG.  Returned values are allocated in POOL, while -   temporary values are allocated in a sub-pool. */ +/* Find all the mergeinfo for a set of PATHS under ROOT and report it +   through RECEIVER with BATON.  INHERITED, INCLUDE_DESCENDANTS and +   ADJUST_INHERITED_MERGEINFO are the same as in the FS API. + +   Allocate temporary values are allocated in SCRATCH_POOL. */  static svn_error_t *  get_mergeinfos_for_paths(svn_fs_root_t *root, -                         svn_mergeinfo_catalog_t *mergeinfo_catalog,                           const apr_array_header_t *paths,                           svn_mergeinfo_inheritance_t inherit,                           svn_boolean_t include_descendants,                           svn_boolean_t adjust_inherited_mergeinfo, -                         apr_pool_t *result_pool, +                         svn_fs_mergeinfo_receiver_t receiver, +                         void *baton,                           apr_pool_t *scratch_pool)  { -  svn_mergeinfo_catalog_t result_catalog = apr_hash_make(result_pool);    apr_pool_t *iterpool = svn_pool_create(scratch_pool);    int i; @@ -5416,14 +5434,13 @@ get_mergeinfos_for_paths(svn_fs_root_t *root,        gmfp_args.root = root;        gmfp_args.path = path;        gmfp_args.inherit = inherit; -      gmfp_args.pool = result_pool; +      gmfp_args.pool = iterpool;        gmfp_args.adjust_inherited_mergeinfo = adjust_inherited_mergeinfo;        SVN_ERR(svn_fs_base__retry_txn(root->fs,                                       txn_body_get_mergeinfo_for_path,                                       &gmfp_args, FALSE, iterpool));        if (path_mergeinfo) -        svn_hash_sets(result_catalog, apr_pstrdup(result_pool, path), -                      path_mergeinfo); +        SVN_ERR(receiver(path, path_mergeinfo, baton, iterpool));        /* If we're including descendants, do so. */        if (include_descendants) @@ -5449,26 +5466,25 @@ get_mergeinfos_for_paths(svn_fs_root_t *root,            /* If it's worth crawling, crawl. */            if (do_crawl)              SVN_ERR(crawl_directory_for_mergeinfo(root->fs, gnms_args.node, -                                                  path, result_catalog, +                                                  path, receiver, baton,                                                    iterpool));          }      }    svn_pool_destroy(iterpool); -  *mergeinfo_catalog = result_catalog;    return SVN_NO_ERROR;  }  /* Implements svn_fs_get_mergeinfo. */  static svn_error_t * -base_get_mergeinfo(svn_mergeinfo_catalog_t *catalog, -                   svn_fs_root_t *root, +base_get_mergeinfo(svn_fs_root_t *root,                     const apr_array_header_t *paths,                     svn_mergeinfo_inheritance_t inherit,                     svn_boolean_t include_descendants,                     svn_boolean_t adjust_inherited_mergeinfo, -                   apr_pool_t *result_pool, +                   svn_fs_mergeinfo_receiver_t receiver, +                   void *baton,                     apr_pool_t *scratch_pool)  {    /* Verify that our filesystem version supports mergeinfo stuff. */ @@ -5480,10 +5496,11 @@ base_get_mergeinfo(svn_mergeinfo_catalog_t *catalog,      return svn_error_create(SVN_ERR_FS_NOT_REVISION_ROOT, NULL, NULL);    /* Retrieve a path -> mergeinfo mapping. */ -  return get_mergeinfos_for_paths(root, catalog, paths, +  return get_mergeinfos_for_paths(root, paths,                                    inherit, include_descendants,                                    adjust_inherited_mergeinfo, -                                  result_pool, scratch_pool); +                                  receiver, baton, +                                  scratch_pool);  } @@ -5493,6 +5510,7 @@ base_get_mergeinfo(svn_mergeinfo_catalog_t *catalog,  static root_vtable_t root_vtable = {    base_paths_changed, +  NULL,    base_check_path,    base_node_history,    base_node_id, | 
