/*
- Copyright (C) 2010 Proxmox Server Solutions GmbH
+ Copyright (C) 2010 - 2020 Proxmox Server Solutions GmbH
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
{
int rc;
- cfs_debug("enter backend_write_inode %016" PRIX64, inode);
+ cfs_debug(
+ "enter backend_write_inode %016" PRIX64 " '%s', size %"PRIu32"",
+ inode,
+ name,
+ size
+ );
if ((rc = sqlite3_bind_int64(stmt, 1, inode)) != SQLITE_OK) {
cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
return rc;
}
- /* question: can we use SQLITE_STATIC instead? */
- if ((rc = sqlite3_bind_text(stmt, 7, name, -1, SQLITE_TRANSIENT)) != SQLITE_OK) {
+ if ((rc = sqlite3_bind_text(stmt, 7, name, -1, SQLITE_STATIC)) != SQLITE_OK) {
cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
return rc;
}
- if ((rc = sqlite3_bind_blob(stmt, 8, value, size, SQLITE_TRANSIENT)) != SQLITE_OK) {
+ if ((rc = sqlite3_bind_blob(stmt, 8, value, size, SQLITE_STATIC)) != SQLITE_OK) {
cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
return rc;
}
g_return_val_if_fail(root->version == 0, FALSE);
g_return_val_if_fail(g_hash_table_size(index) == 1, FALSE);
- int rc;
-
sqlite3_stmt *stmt = bdb->stmt_load_all;
+ int rc;
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
memdb_tree_entry_t *te;
te->name, te->inode, te->parent);
if (te->inode == 0) {
- if (te->name && !strcmp(te->name, VERSIONFILENAME)) {
+ if (!strcmp(te->name, VERSIONFILENAME)) {
root->version = te->version;
root->writer = te->writer;
root->mtime = te->mtime;
te->data.entries = g_hash_table_new(g_str_hash, g_str_equal);
}
}
-
- if (g_hash_table_lookup(pte->data.entries, te->name)) {
- cfs_critical("found entry with duplicate name "
- "(inode = %016" PRIX64 ", parent = %016" PRIX64 ", name = '%s')",
- te->inode, te->parent, te->name);
+
+ memdb_tree_entry_t *existing;
+ if ((existing = g_hash_table_lookup(pte->data.entries, te->name))) {
+ cfs_critical(
+ "found entry with duplicate name '%s' - "
+ "A:(inode = 0x%016"PRIX64", parent = 0x%016"PRIX64", v./mtime = 0x%"PRIX64"/0x%"PRIi32")"
+ " vs. "
+ "B:(inode = 0x%016"PRIX64", parent = 0x%016"PRIX64", v./mtime = 0x%"PRIX64"/0x%"PRIi32")",
+ te->name,
+ existing->inode, existing->parent, existing->version, existing->mtime,
+ te->inode, te->parent, te->version, te->mtime
+ );
goto fail;
}
if (bdb_backend_delete_inode(bdb, slave_inode) != SQLITE_OK)
goto abort;
-
+
cfs_debug("deleted inode %016" PRIX64, slave_inode);
j++;
if (!(bdb->db = bdb_create(filename)))
goto fail;
- rc = sqlite3_prepare_v2(bdb->db, sql_insert_entry, -1, &bdb->stmt_insert_entry, NULL);
+ // tell the query planner that the prepared statement will be retained for a long time and
+ // probably reused many times
+ const unsigned int flags = SQLITE_PREPARE_PERSISTENT;
+
+ rc = sqlite3_prepare_v3(bdb->db, sql_insert_entry, -1, flags, &bdb->stmt_insert_entry, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_insert_entry' failed: %s\n",
sqlite3_errmsg(bdb->db));
goto fail;
}
- rc = sqlite3_prepare_v2(bdb->db, sql_update_entry, -1, &bdb->stmt_update_entry, NULL);
+ rc = sqlite3_prepare_v3(bdb->db, sql_update_entry, -1, flags, &bdb->stmt_update_entry, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_update_entry' failed: %s\n",
sqlite3_errmsg(bdb->db));
goto fail;
}
- rc = sqlite3_prepare_v2(bdb->db, sql_replace_entry, -1, &bdb->stmt_replace_entry, NULL);
+ rc = sqlite3_prepare_v3(bdb->db, sql_replace_entry, -1, flags, &bdb->stmt_replace_entry, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_replace_entry' failed: %s\n",
sqlite3_errmsg(bdb->db));
goto fail;
}
- rc = sqlite3_prepare_v2(bdb->db, sql_delete_entry, -1, &bdb->stmt_delete_entry, NULL);
+ rc = sqlite3_prepare_v3(bdb->db, sql_delete_entry, -1, flags, &bdb->stmt_delete_entry, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_delete_entry' failed: %s\n",
sqlite3_errmsg(bdb->db));
goto fail;
}
- rc = sqlite3_prepare_v2(bdb->db, sql_begin, -1, &bdb->stmt_begin, NULL);
+ rc = sqlite3_prepare_v3(bdb->db, sql_begin, -1, flags, &bdb->stmt_begin, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_begin' failed: %s\n",
sqlite3_errmsg(bdb->db));
goto fail;
}
- rc = sqlite3_prepare_v2(bdb->db, sql_commit, -1, &bdb->stmt_commit, NULL);
+ rc = sqlite3_prepare_v3(bdb->db, sql_commit, -1, flags, &bdb->stmt_commit, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_commit' failed: %s\n",
sqlite3_errmsg(bdb->db));
goto fail;
}
- rc = sqlite3_prepare_v2(bdb->db, sql_rollback, -1, &bdb->stmt_rollback, NULL);
+ rc = sqlite3_prepare_v3(bdb->db, sql_rollback, -1, flags, &bdb->stmt_rollback, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_rollback' failed: %s\n",
sqlite3_errmsg(bdb->db));
goto fail;
}
- rc = sqlite3_prepare_v2(bdb->db, sql_load_all, -1, &bdb->stmt_load_all, NULL);
+ rc = sqlite3_prepare_v3(bdb->db, sql_load_all, -1, flags, &bdb->stmt_load_all, NULL);
if (rc != SQLITE_OK) {
cfs_critical("sqlite3_prepare 'sql_load_all' failed: %s\n",
sqlite3_errmsg(bdb->db));
return bdb;
fail:
-
bdb_backend_close(bdb);
-
+
return NULL;
}
-