Ejemplo n.º 1
0
/* Get the current 'next-key' value and bump the record. */
static svn_error_t *
get_key_and_bump(svn_fs_t *fs,
                 const char **key,
                 trail_t *trail,
                 apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    DBC *cursor;
    char next_key[MAX_KEY_SIZE];
    apr_size_t key_len;
    int db_err;
    DBT query;
    DBT result;

    /* ### todo: see issue #409 for why bumping the key as part of this
       trail is problematic. */

    /* Open a cursor and move it to the 'next-key' value. We can then fetch
       the contents and use the cursor to overwrite those contents. Since
       this database allows duplicates, we can't do an arbitrary 'put' to
       write the new value -- that would append, not overwrite.  */

    svn_fs_base__trail_debug(trail, "strings", "cursor");
    SVN_ERR(BDB_WRAP(fs, N_("creating cursor for reading a string"),
                     bfd->strings->cursor(bfd->strings, trail->db_txn,
                                          &cursor, 0)));

    /* Advance the cursor to 'next-key' and read it. */

    db_err = svn_bdb_dbc_get(cursor,
                             svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
                             svn_fs_base__result_dbt(&result),
                             DB_SET);
    if (db_err)
    {
        svn_bdb_dbc_close(cursor);
        return BDB_WRAP(fs, N_("getting next-key value"), db_err);
    }

    svn_fs_base__track_dbt(&result, pool);
    *key = apr_pstrmemdup(pool, result.data, result.size);

    /* Bump to future key. */
    key_len = result.size;
    svn_fs_base__next_key(result.data, &key_len, next_key);

    /* Shove the new key back into the database, at the cursor position. */
    db_err = svn_bdb_dbc_put(cursor, &query,
                             svn_fs_base__str_to_dbt(&result, next_key),
                             DB_CURRENT);
    if (db_err)
    {
        svn_bdb_dbc_close(cursor); /* ignore the error, the original is
                                    more important. */
        return BDB_WRAP(fs, N_("bumping next string key"), db_err);
    }

    return BDB_WRAP(fs, N_("closing string-reading cursor"),
                    svn_bdb_dbc_close(cursor));
}
Ejemplo n.º 2
0
svn_error_t *
svn_fs_bdb__miscellaneous_set(svn_fs_t *fs,
                              const char *key_str,
                              const char *val,
                              trail_t *trail,
                              apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;

  svn_fs_base__str_to_dbt(&key, key_str);
  if (val == NULL)
    {
      svn_fs_base__trail_debug(trail, "miscellaneous", "del");
      return BDB_WRAP(fs, N_("deleting record from 'miscellaneous' table"),
                      bfd->miscellaneous->del(bfd->miscellaneous,
                                              trail->db_txn, &key, 0));
    }
  else
    {
      svn_fs_base__str_to_dbt(&value, val);
      svn_fs_base__trail_debug(trail, "miscellaneous", "add");
      return BDB_WRAP(fs, N_("storing miscellaneous record"),
                      bfd->miscellaneous->put(bfd->miscellaneous,
                                              trail->db_txn,
                                              &key, &value, 0));
    }
}
Ejemplo n.º 3
0
svn_error_t *
svn_fs_bdb__miscellaneous_get(const char **val,
                              svn_fs_t *fs,
                              const char *key_str,
                              trail_t *trail,
                              apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  *val = NULL;
  svn_fs_base__trail_debug(trail, "miscellaneous", "get");
  db_err = bfd->miscellaneous->get(bfd->miscellaneous, trail->db_txn,
                                   svn_fs_base__str_to_dbt(&key, key_str),
                                   svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);

  if (db_err != DB_NOTFOUND)
    {
      SVN_ERR(BDB_WRAP(fs, N_("fetching miscellaneous record"), db_err));
      *val = apr_pstrmemdup(pool, value.data, value.size);
    }
  return SVN_NO_ERROR;
}
Ejemplo n.º 4
0
svn_error_t *
svn_fs_bdb__string_append(svn_fs_t *fs,
                          const char **key,
                          apr_size_t len,
                          const char *buf,
                          trail_t *trail,
                          apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    DBT query, result;

    /* If the passed-in key is NULL, we graciously generate a new string
       using the value of the `next-key' record in the strings table. */
    if (*key == NULL)
    {
        SVN_ERR(get_key_and_bump(fs, key, trail, pool));
    }

    /* Store a new record into the database. */
    svn_fs_base__trail_debug(trail, "strings", "put");
    return BDB_WRAP(fs, N_("appending string"),
                    bfd->strings->put
                    (bfd->strings, trail->db_txn,
                     svn_fs_base__str_to_dbt(&query, *key),
                     svn_fs_base__set_dbt(&result, buf, len),
                     0));
}
Ejemplo n.º 5
0
svn_error_t *
svn_fs_bdb__delete_rep(svn_fs_t *fs,
                       const char *key,
                       trail_t *trail,
                       apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  int db_err;
  DBT query;

  svn_fs_base__trail_debug(trail, "representations", "del");
  db_err = bfd->representations->del
    (bfd->representations, trail->db_txn,
     svn_fs_base__str_to_dbt(&query, key), 0);

  /* If there's no such node, return an appropriately specific error.  */
  if (db_err == DB_NOTFOUND)
    return svn_error_createf
      (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0,
       _("No such representation '%s'"), key);

  /* Handle any other error conditions.  */
  SVN_ERR(BDB_WRAP(fs, _("deleting representation"), db_err));

  return SVN_NO_ERROR;
}
Ejemplo n.º 6
0
svn_error_t *
svn_fs_bdb__write_rep(svn_fs_t *fs,
                      const char *key,
                      const representation_t *rep,
                      trail_t *trail,
                      apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  skel_t *skel;

  /* Convert from native type to skel. */
  SVN_ERR(svn_fs_base__unparse_representation_skel(&skel, rep, pool));

  /* Now write the record. */
  svn_fs_base__trail_debug(trail, "representations", "put");
  SVN_ERR(BDB_WRAP(fs, _("storing representation"),
                   bfd->representations->put
                   (bfd->representations, trail->db_txn,
                    svn_fs_base__str_to_dbt(&query, key),
                    svn_fs_base__skel_to_dbt(&result, skel, pool),
                    0)));

  return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_bdb__read_rep(representation_t **rep_p,
                     svn_fs_t *fs,
                     const char *key,
                     trail_t *trail,
                     apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  svn_skel_t *skel;
  int db_err;
  DBT query, result;

  svn_fs_base__trail_debug(trail, "representations", "get");
  db_err = bfd->representations->get(bfd->representations,
                                     trail->db_txn,
                                     svn_fs_base__str_to_dbt(&query, key),
                                     svn_fs_base__result_dbt(&result), 0);
  svn_fs_base__track_dbt(&result, pool);

  /* If there's no such node, return an appropriately specific error.  */
  if (db_err == DB_NOTFOUND)
    return svn_error_createf
      (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0,
       _("No such representation '%s'"), key);

  /* Handle any other error conditions.  */
  SVN_ERR(BDB_WRAP(fs, _("reading representation"), db_err));

  /* Parse the REPRESENTATION skel.  */
  skel = svn_skel__parse(result.data, result.size, pool);

  /* Convert to a native type.  */
  return svn_fs_base__parse_representation_skel(rep_p, skel, pool);
}
Ejemplo n.º 8
0
svn_error_t *
svn_fs_bdb__write_new_rep(const char **key,
                          svn_fs_t *fs,
                          const representation_t *rep,
                          trail_t *trail,
                          apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  int db_err;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];

  /* ### todo: see issue #409 for why bumping the key as part of this
     trail is problematic. */

  /* Get the current value associated with `next-key'.  */
  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
  svn_fs_base__trail_debug(trail, "representations", "get");
  SVN_ERR(BDB_WRAP(fs, _("allocating new representation (getting next-key)"),
                   bfd->representations->get
                   (bfd->representations, trail->db_txn, &query,
                    svn_fs_base__result_dbt(&result), 0)));

  svn_fs_base__track_dbt(&result, pool);

  /* Store the new rep. */
  *key = apr_pstrmemdup(pool, result.data, result.size);
  SVN_ERR(svn_fs_bdb__write_rep(fs, *key, rep, trail, pool));

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__trail_debug(trail, "representations", "put");
  db_err = bfd->representations->put
    (bfd->representations, trail->db_txn,
     svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
     svn_fs_base__str_to_dbt(&result, next_key),
     0);

  SVN_ERR(BDB_WRAP(fs, _("bumping next representation key"), db_err));

  return SVN_NO_ERROR;
}
Ejemplo n.º 9
0
svn_error_t *
svn_fs_bdb__new_node_id(svn_fs_id_t **id_p,
                        svn_fs_t *fs,
                        const char *copy_id,
                        const char *txn_id,
                        trail_t *trail,
                        apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];
  int db_err;
  const char *next_node_id;

  SVN_ERR_ASSERT(txn_id);

  /* Get the current value associated with the `next-key' key in the table.  */
  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
  svn_fs_base__trail_debug(trail, "nodes", "get");
  SVN_ERR(BDB_WRAP(fs, N_("allocating new node ID (getting 'next-key')"),
                   bfd->nodes->get(bfd->nodes, trail->db_txn,
                                   &query,
                                   svn_fs_base__result_dbt(&result),
                                   0)));
  svn_fs_base__track_dbt(&result, pool);

  /* Squirrel away our next node id value. */
  next_node_id = apr_pstrmemdup(pool, result.data, result.size);

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__trail_debug(trail, "nodes", "put");
  db_err = bfd->nodes->put(bfd->nodes, trail->db_txn,
                           svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
                           svn_fs_base__str_to_dbt(&result, next_key),
                           0);
  SVN_ERR(BDB_WRAP(fs, N_("bumping next node ID key"), db_err));

  /* Create and return the new node id. */
  *id_p = svn_fs_base__id_create(next_node_id, copy_id, txn_id, pool);
  return SVN_NO_ERROR;
}
Ejemplo n.º 10
0
svn_error_t *svn_fs_bdb__reserve_rep_reuse_id(const char **id_p,
                                              svn_fs_t *fs,
                                              trail_t *trail,
                                              apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];
  int db_err;

  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);

  /* Get the current value associated with the `next-key' key in the
     `checksum-reps' table.  */
  svn_fs_base__trail_debug(trail, "checksum-reps", "get");
  SVN_ERR(BDB_WRAP(fs, _("allocating new representation reuse ID "
                         "(getting 'next-key')"),
                   bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
                                           &query,
                                           svn_fs_base__result_dbt(&result),
                                           0)));
  svn_fs_base__track_dbt(&result, pool);

  /* Set our return value. */
  *id_p = apr_pstrmemdup(pool, result.data, result.size);

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__trail_debug(trail, "checksum_reps", "put");
  db_err = bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
                                   svn_fs_base__str_to_dbt(&query,
                                                           NEXT_KEY_KEY),
                                   svn_fs_base__str_to_dbt(&result, next_key),
                                   0);

  return BDB_WRAP(fs, _("bumping next copy key"), db_err);
}
Ejemplo n.º 11
0
/* Allocate a Subversion transaction ID in FS, as part of TRAIL.  Set
   *ID_P to the new transaction ID, allocated in POOL.  */
static svn_error_t *
allocate_txn_id(const char **id_p,
                svn_fs_t *fs,
                trail_t *trail,
                apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];
  int db_err;

  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);

  /* Get the current value associated with the `next-key' key in the table.  */
  svn_fs_base__trail_debug(trail, "transactions", "get");
  SVN_ERR(BDB_WRAP(fs, "allocating new transaction ID (getting 'next-key')",
                   bfd->transactions->get(bfd->transactions, trail->db_txn,
                                          &query,
                                          svn_fs_base__result_dbt(&result),
                                          0)));
  svn_fs_base__track_dbt(&result, pool);

  /* Set our return value. */
  *id_p = apr_pstrmemdup(pool, result.data, result.size);

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
  svn_fs_base__str_to_dbt(&result, next_key);
  svn_fs_base__trail_debug(trail, "transactions", "put");
  db_err = bfd->transactions->put(bfd->transactions, trail->db_txn,
                                  &query, &result, 0);

  return BDB_WRAP(fs, "bumping next transaction key", db_err);
}
Ejemplo n.º 12
0
svn_error_t *svn_fs_bdb__delete_node_origin(svn_fs_t *fs,
                                            const char *node_id,
                                            trail_t *trail,
                                            apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;

  svn_fs_base__str_to_dbt(&key, node_id);
  svn_fs_base__trail_debug(trail, "node-origins", "del");
  SVN_ERR(BDB_WRAP(fs, "deleting entry from 'node-origins' table",
                   bfd->node_origins->del(bfd->node_origins,
                                          trail->db_txn, &key, 0)));
  return SVN_NO_ERROR;
}
Ejemplo n.º 13
0
svn_error_t *
svn_fs_bdb__string_clear(svn_fs_t *fs,
                         const char *key,
                         trail_t *trail,
                         apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    int db_err;
    DBT query, result;

    svn_fs_base__str_to_dbt(&query, key);

    /* Torch the prior contents */
    svn_fs_base__trail_debug(trail, "strings", "del");
    db_err = bfd->strings->del(bfd->strings, trail->db_txn, &query, 0);

    /* If there's no such node, return an appropriately specific error.  */
    if (db_err == DB_NOTFOUND)
        return svn_error_createf
               (SVN_ERR_FS_NO_SUCH_STRING, 0,
                "No such string '%s'", key);

    /* Handle any other error conditions.  */
    SVN_ERR(BDB_WRAP(fs, N_("clearing string"), db_err));

    /* Shove empty data back in for this key. */
    svn_fs_base__clear_dbt(&result);
    result.data = 0;
    result.size = 0;
    result.flags |= DB_DBT_USERMEM;

    svn_fs_base__trail_debug(trail, "strings", "put");
    return BDB_WRAP(fs, N_("storing empty contents"),
                    bfd->strings->put(bfd->strings, trail->db_txn,
                                      &query, &result, 0));
}
Ejemplo n.º 14
0
/* Removing node revisions.  */
svn_error_t *
svn_fs_bdb__delete_nodes_entry(svn_fs_t *fs,
                               const svn_fs_id_t *id,
                               trail_t *trail,
                               apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;

  svn_fs_base__trail_debug(trail, "nodes", "del");
  return BDB_WRAP(fs, N_("deleting entry from 'nodes' table"),
                  bfd->nodes->del(bfd->nodes,
                                  trail->db_txn,
                                  svn_fs_base__id_to_dbt(&key, id, pool),
                                  0));
}
Ejemplo n.º 15
0
svn_error_t *
svn_fs_bdb__delete_copy(svn_fs_t *fs,
                        const char *copy_id,
                        trail_t *trail,
                        apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    DBT key;
    int db_err;

    svn_fs_base__str_to_dbt(&key, copy_id);
    svn_fs_base__trail_debug(trail, "copies", "del");
    db_err = bfd->copies->del(bfd->copies, trail->db_txn, &key, 0);
    if (db_err == DB_NOTFOUND)
        return svn_fs_base__err_no_such_copy(fs, copy_id);
    return BDB_WRAP(fs, N_("deleting entry from 'copies' table"), db_err);
}
Ejemplo n.º 16
0
svn_error_t *svn_fs_bdb__set_node_origin(svn_fs_t *fs,
                                         const char *node_id,
                                         const svn_fs_id_t *origin_id,
                                         trail_t *trail,
                                         apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  /* Create a key from our NODE_ID. */
  svn_fs_base__str_to_dbt(&key, node_id);

  /* Check to see if we already have a mapping for NODE_ID.  If so,
     and the value is the same one we were about to write.  That's
     cool -- just do nothing.  If, however, the value is *different*,
     that's a red flag!  */
  svn_fs_base__trail_debug(trail, "node-origins", "get");
  db_err = bfd->node_origins->get(bfd->node_origins, trail->db_txn,
                                  &key, svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);
  if (db_err != DB_NOTFOUND)
    {
      const svn_string_t *origin_id_str = svn_fs_base__id_unparse(origin_id, pool);
      const svn_string_t *old_origin_id_str =
        svn_string_ncreate(value.data, value.size, pool);

      if (! svn_string_compare(origin_id_str, old_origin_id_str))
        return svn_error_createf
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Node origin for '%s' exists in filesystem '%s' with a different "
             "value (%s) than what we were about to store (%s)"),
           node_id, fs->path, old_origin_id_str->data, origin_id_str->data);
      else
        return SVN_NO_ERROR;
    }

  /* Create a value from our ORIGIN_ID, and add this record to the table. */
  svn_fs_base__id_to_dbt(&value, origin_id, pool);
  svn_fs_base__trail_debug(trail, "node-origins", "put");
  SVN_ERR(BDB_WRAP(fs, _("storing node-origins record"),
                   bfd->node_origins->put(bfd->node_origins, trail->db_txn,
                                          &key, &value, 0)));
  return SVN_NO_ERROR;
}
Ejemplo n.º 17
0
svn_error_t *
svn_fs_bdb__lock_delete(svn_fs_t *fs,
                        const char *lock_token,
                        trail_t *trail,
                        apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;
  int db_err;

  svn_fs_base__str_to_dbt(&key, lock_token);
  svn_fs_base__trail_debug(trail, "locks", "del");
  db_err = bfd->locks->del(bfd->locks, trail->db_txn, &key, 0);

  if (db_err == DB_NOTFOUND)
    return svn_fs_base__err_bad_lock_token(fs, lock_token);
  return BDB_WRAP(fs, "deleting lock from 'locks' table", db_err);
}
Ejemplo n.º 18
0
svn_error_t *svn_fs_bdb__set_checksum_rep(svn_fs_t *fs,
                                          svn_checksum_t *checksum,
                                          const char *rep_key,
                                          trail_t *trail,
                                          apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  /* We only allow SHA1 checksums in this table. */
  if (checksum->kind != svn_checksum_sha1)
    return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
                            _("Only SHA1 checksums can be used as keys in the "
                              "checksum-reps table.\n"));

  /* Create a key from our CHECKSUM. */
  svn_fs_base__checksum_to_dbt(&key, checksum);

  /* Check to see if we already have a mapping for CHECKSUM.  If so,
     and the value is the same one we were about to write, that's
     cool -- just do nothing.  If, however, the value is *different*,
     that's a red flag!  */
  svn_fs_base__trail_debug(trail, "checksum-reps", "get");
  db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
                                   &key, svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);
  if (db_err != DB_NOTFOUND)
    {
      const char *sum_str = svn_checksum_to_cstring_display(checksum, pool);
      return svn_error_createf
        (SVN_ERR_FS_ALREADY_EXISTS, NULL,
         _("Representation key for checksum '%s' exists in filesystem '%s'."),
         sum_str, fs->path);
    }

  /* Create a value from our REP_KEY, and add this record to the table. */
  svn_fs_base__str_to_dbt(&value, rep_key);
  svn_fs_base__trail_debug(trail, "checksum-reps", "put");
  SVN_ERR(BDB_WRAP(fs, _("storing checksum-reps record"),
                   bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
                                           &key, &value, 0)));
  return SVN_NO_ERROR;
}
Ejemplo n.º 19
0
svn_error_t *
svn_fs_bdb__lock_get(svn_lock_t **lock_p,
                     svn_fs_t *fs,
                     const char *lock_token,
                     trail_t *trail,
                     apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;
  svn_skel_t *skel;
  svn_lock_t *lock;

  svn_fs_base__trail_debug(trail, "lock", "get");
  db_err = bfd->locks->get(bfd->locks, trail->db_txn,
                           svn_fs_base__str_to_dbt(&key, lock_token),
                           svn_fs_base__result_dbt(&value),
                           0);
  svn_fs_base__track_dbt(&value, pool);

  if (db_err == DB_NOTFOUND)
    return svn_fs_base__err_bad_lock_token(fs, lock_token);
  SVN_ERR(BDB_WRAP(fs, "reading lock", db_err));

  /* Parse TRANSACTION skel */
  skel = svn_skel__parse(value.data, value.size, pool);
  if (! skel)
    return svn_fs_base__err_corrupt_lock(fs, lock_token);

  /* Convert skel to native type. */
  SVN_ERR(svn_fs_base__parse_lock_skel(&lock, skel, pool));

  /* Possibly auto-expire the lock. */
  if (lock->expiration_date && (apr_time_now() > lock->expiration_date))
    {
      SVN_ERR(svn_fs_bdb__lock_delete(fs, lock_token, trail, pool));
      return SVN_FS__ERR_LOCK_EXPIRED(fs, lock_token);
    }

  *lock_p = lock;
  return SVN_NO_ERROR;
}
Ejemplo n.º 20
0
svn_error_t *svn_fs_bdb__delete_checksum_rep(svn_fs_t *fs,
                                             svn_checksum_t *checksum,
                                             trail_t *trail,
                                             apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;

  /* We only allow SHA1 checksums in this table. */
  if (checksum->kind != svn_checksum_sha1)
    return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
                            _("Only SHA1 checksums can be used as keys in the "
                              "checksum-reps table.\n"));

  svn_fs_base__checksum_to_dbt(&key, checksum);
  svn_fs_base__trail_debug(trail, "checksum-reps", "del");
  SVN_ERR(BDB_WRAP(fs, "deleting entry from 'checksum-reps' table",
                   bfd->checksum_reps->del(bfd->checksum_reps,
                                           trail->db_txn, &key, 0)));
  return SVN_NO_ERROR;
}
Ejemplo n.º 21
0
svn_error_t *
svn_fs_bdb__lock_add(svn_fs_t *fs,
                     const char *lock_token,
                     svn_lock_t *lock,
                     trail_t *trail,
                     apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  svn_skel_t *lock_skel;
  DBT key, value;

  /* Convert native type to skel. */
  SVN_ERR(svn_fs_base__unparse_lock_skel(&lock_skel, lock, pool));

  svn_fs_base__str_to_dbt(&key, lock_token);
  svn_fs_base__skel_to_dbt(&value, lock_skel, pool);
  svn_fs_base__trail_debug(trail, "lock", "add");
  return BDB_WRAP(fs, "storing lock record",
                  bfd->locks->put(bfd->locks, trail->db_txn,
                                  &key, &value, 0));
}
Ejemplo n.º 22
0
Archivo: fs.c Proyecto: Alkzndr/freebsd
/* Close a database in the filesystem FS.
   DB_PTR is a pointer to the DB pointer in *FS to close.
   NAME is the name of the database, for use in error messages.  */
static svn_error_t *
cleanup_fs_db(svn_fs_t *fs, DB **db_ptr, const char *name)
{
  /* If the BDB environment is panicked, don't do anything, since
     attempting to close the database will fail anyway. */
  base_fs_data_t *bfd = fs->fsap_data;
  if (*db_ptr && !svn_fs_bdb__get_panic(bfd->bdb))
    {
      DB *db = *db_ptr;
      char *msg = apr_psprintf(fs->pool, "closing '%s' database", name);
      int db_err;

      *db_ptr = 0;
      db_err = db->close(db, 0);
      if (db_err == DB_RUNRECOVERY)
        {
          /* We can ignore DB_RUNRECOVERY errors from DB->close, but
             must set the panic flag in the environment baton.  The
             error will be propagated appropriately from
             svn_fs_bdb__close. */
          svn_fs_bdb__set_panic(bfd->bdb);
          db_err = 0;
        }

#if SVN_BDB_HAS_DB_INCOMPLETE
      /* We can ignore DB_INCOMPLETE on db->close and db->sync; it
       * just means someone else was using the db at the same time
       * we were.  See the Berkeley documentation at:
       * http://www.sleepycat.com/docs/ref/program/errorret.html#DB_INCOMPLETE
       * http://www.sleepycat.com/docs/api_c/db_close.html
       */
      if (db_err == DB_INCOMPLETE)
        db_err = 0;
#endif /* SVN_BDB_HAS_DB_INCOMPLETE */

      SVN_ERR(BDB_WRAP(fs, msg, db_err));
    }

  return SVN_NO_ERROR;
}
Ejemplo n.º 23
0
svn_error_t *
svn_fs_bdb__get_node_revision(node_revision_t **noderev_p,
                              svn_fs_t *fs,
                              const svn_fs_id_t *id,
                              trail_t *trail,
                              apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  node_revision_t *noderev;
  svn_skel_t *skel;
  int db_err;
  DBT key, value;

  svn_fs_base__trail_debug(trail, "nodes", "get");
  db_err = bfd->nodes->get(bfd->nodes, trail->db_txn,
                           svn_fs_base__id_to_dbt(&key, id, pool),
                           svn_fs_base__result_dbt(&value),
                           0);
  svn_fs_base__track_dbt(&value, pool);

  /* If there's no such node, return an appropriately specific error.  */
  if (db_err == DB_NOTFOUND)
    return svn_fs_base__err_dangling_id(fs, id);

  /* Handle any other error conditions.  */
  SVN_ERR(BDB_WRAP(fs, N_("reading node revision"), db_err));

  /* If our caller doesn't really care about the return value here,
     just return successfully. */
  if (! noderev_p)
    return SVN_NO_ERROR;

  /* Parse and the NODE-REVISION skel.  */
  skel = svn_skel__parse(value.data, value.size, pool);

  /* Convert to a native FS type. */
  SVN_ERR(svn_fs_base__parse_node_revision_skel(&noderev, skel, pool));
  *noderev_p = noderev;
  return SVN_NO_ERROR;
}
Ejemplo n.º 24
0
svn_error_t *
svn_fs_bdb__delete_txn(svn_fs_t *fs,
                       const char *txn_name,
                       trail_t *trail,
                       apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;
  transaction_t *txn;

  /* Make sure TXN is dead. */
  SVN_ERR(svn_fs_bdb__get_txn(&txn, fs, txn_name, trail, pool));
  if (is_committed(txn))
    return svn_fs_base__err_txn_not_mutable(fs, txn_name);

  /* Delete the transaction from the `transactions' table. */
  svn_fs_base__str_to_dbt(&key, txn_name);
  svn_fs_base__trail_debug(trail, "transactions", "del");
  return BDB_WRAP(fs, "deleting entry from 'transactions' table",
                  bfd->transactions->del(bfd->transactions,
                                         trail->db_txn, &key, 0));
}
Ejemplo n.º 25
0
svn_error_t *
svn_fs_bdb__changes_add(svn_fs_t *fs,
                        const char *key,
                        change_t *change,
                        trail_t *trail,
                        apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, value;
  svn_skel_t *skel;

  /* Convert native type to skel. */
  SVN_ERR(svn_fs_base__unparse_change_skel(&skel, change, pool));

  /* Store a new record into the database. */
  svn_fs_base__str_to_dbt(&query, key);
  svn_fs_base__skel_to_dbt(&value, skel, pool);
  svn_fs_base__trail_debug(trail, "changes", "put");
  return BDB_WRAP(fs, N_("creating change"),
                  bfd->changes->put(bfd->changes, trail->db_txn,
                                    &query, &value, 0));
}
Ejemplo n.º 26
0
svn_error_t *
svn_fs_bdb__string_size(svn_filesize_t *size,
                        svn_fs_t *fs,
                        const char *key,
                        trail_t *trail,
                        apr_pool_t *pool)
{
    int db_err;
    DBT query;
    DBC *cursor;
    apr_size_t length;
    svn_filesize_t total;

    svn_fs_base__str_to_dbt(&query, key);

    SVN_ERR(locate_key(&length, &cursor, &query, fs, trail, pool));

    total = length;
    while (1)
    {
        /* Remember, if any error happens, our cursor has been closed
           for us. */
        db_err = get_next_length(&length, cursor, &query);

        /* No more records? Then return the total length. */
        if (db_err == DB_NOTFOUND)
        {
            *size = total;
            return SVN_NO_ERROR;
        }
        if (db_err)
            return BDB_WRAP(fs, N_("fetching string length"), db_err);

        total += length;
    }

    /* NOTREACHED */
}
Ejemplo n.º 27
0
svn_error_t *
svn_fs_bdb__string_delete(svn_fs_t *fs,
                          const char *key,
                          trail_t *trail,
                          apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    int db_err;
    DBT query;

    svn_fs_base__trail_debug(trail, "strings", "del");
    db_err = bfd->strings->del(bfd->strings, trail->db_txn,
                               svn_fs_base__str_to_dbt(&query, key), 0);

    /* If there's no such node, return an appropriately specific error.  */
    if (db_err == DB_NOTFOUND)
        return svn_error_createf
               (SVN_ERR_FS_NO_SUCH_STRING, 0,
                "No such string '%s'", key);

    /* Handle any other error conditions.  */
    return BDB_WRAP(fs, N_("deleting string"), db_err);
}
Ejemplo n.º 28
0
/* ### only has one caller; might not need to be abstracted */
static svn_error_t *
put_copy(svn_fs_t *fs,
         const copy_t *copy,
         const char *copy_id,
         trail_t *trail,
         apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    svn_skel_t *copy_skel;
    DBT key, value;

    /* Convert native type to skel. */
    SVN_ERR(svn_fs_base__unparse_copy_skel(&copy_skel, copy, pool));

    /* Only in the context of this function do we know that the DB call
       will not attempt to modify COPY_ID, so the cast belongs here.  */
    svn_fs_base__str_to_dbt(&key, copy_id);
    svn_fs_base__skel_to_dbt(&value, copy_skel, pool);
    svn_fs_base__trail_debug(trail, "copies", "put");
    return BDB_WRAP(fs, N_("storing copy record"),
                    bfd->copies->put(bfd->copies, trail->db_txn,
                                     &key, &value, 0));
}
Ejemplo n.º 29
0
svn_error_t *
svn_fs_bdb__put_txn(svn_fs_t *fs,
                    const transaction_t *txn,
                    const char *txn_name,
                    trail_t *trail,
                    apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  svn_skel_t *txn_skel;
  DBT key, value;

  /* Convert native type to skel. */
  SVN_ERR(svn_fs_base__unparse_transaction_skel(&txn_skel, txn, pool));

  /* Only in the context of this function do we know that the DB call
     will not attempt to modify txn_name, so the cast belongs here.  */
  svn_fs_base__str_to_dbt(&key, txn_name);
  svn_fs_base__skel_to_dbt(&value, txn_skel, pool);
  svn_fs_base__trail_debug(trail, "transactions", "put");
  return BDB_WRAP(fs, _("storing transaction record"),
                  bfd->transactions->put(bfd->transactions, trail->db_txn,
                                         &key, &value, 0));
}
Ejemplo n.º 30
0
svn_error_t *
svn_fs_bdb__changes_delete(svn_fs_t *fs,
                           const char *key,
                           trail_t *trail,
                           apr_pool_t *pool)
{
  int db_err;
  DBT query;
  base_fs_data_t *bfd = fs->fsap_data;

  svn_fs_base__trail_debug(trail, "changes", "del");
  db_err = bfd->changes->del(bfd->changes, trail->db_txn,
                             svn_fs_base__str_to_dbt(&query, key), 0);

  /* If there're no changes for KEY, that is acceptable.  Any other
     error should be propagated to the caller, though.  */
  if ((db_err) && (db_err != DB_NOTFOUND))
    {
      SVN_ERR(BDB_WRAP(fs, N_("deleting changes"), db_err));
    }

  return SVN_NO_ERROR;
}