/*
- 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
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
+#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
{
int rc;
- cfs_debug("enter backend_write_inode %016zX", 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;
}
goto rollback;
if (sqlite3_changes(bdb->db) != 1) {
- cfs_critical("no such inode %016zX", inode);
+ cfs_critical("no such inode %016" PRIX64, inode);
goto rollback;
}
}
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;
const char *name = (const char *)sqlite3_column_text(stmt, 6);
int namelen = sqlite3_column_bytes(stmt, 6);
if (name == NULL || namelen == 0) {
- cfs_critical("inode has no name (inode = %016zX)", inode);
+ cfs_critical("inode has no name (inode = %016" PRIX64 ")", inode);
goto fail;
}
te = g_malloc0(sizeof(memdb_tree_entry_t) + namelen + 1);
te->data.value = g_memdup(value, size);
} else if (te->type == DT_DIR) {
if (size) {
- cfs_critical("directory inode contains data (inode = %016zX)",
+ cfs_critical("directory inode contains data (inode = %016" PRIX64 ")",
te->inode);
g_free(te);
goto fail;
}
te->data.entries = NULL;
} else {
- cfs_critical("inode has unknown type (inode = %016zX, type = %d)",
+ cfs_critical("inode has unknown type (inode = %016" PRIX64 ", type = %d)",
te->inode, te->type);
g_free(te);
goto fail;
}
- cfs_debug("name %s (inode = %016zX, parent = %016zX)",
+ cfs_debug("name %s (inode = %016" PRIX64 ", parent = %016" PRIX64 ")",
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;
} else if (!(pte->type == DT_DIR || pte->type == 0)) {
cfs_critical("parent is not a directory "
- "(inode = %016zX, parent = %016zX, name = '%s')",
+ "(inode = %016" PRIX64 ", parent = %016" PRIX64 ", name = '%s')",
te->inode, te->parent, te->name);
memdb_tree_entry_free(te);
goto fail;
if ((tmpte = g_hash_table_lookup(index, &te->inode))) {
if (tmpte->type != 0) {
cfs_critical("found strange placeholder for "
- "(inode = %016zX, parent = %016zX, name = '%s', type = '%d')",
+ "(inode = %016" PRIX64 ", parent = %016" PRIX64 ", name = '%s', type = '%d')",
te->inode, te->parent, te->name, tmpte->type);
memdb_tree_entry_free(te);
goto fail;
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 = %016zX, parent = %016zX, 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;
}
while (g_hash_table_iter_next (&iter, &key, &value)) {
memdb_tree_entry_t *te = (memdb_tree_entry_t *)value;
if (te->type == 0) {
- cfs_critical("missing directory inode (inode = %016zX)", te->inode);
+ cfs_critical("missing directory inode (inode = %016" PRIX64 ")", te->inode);
goto fail;
}
}
return rc;
}
- g_mutex_lock (memdb->mutex);
+ g_mutex_lock (&memdb->mutex);
/* first, delete anything not found in master index) */
if (bdb_backend_delete_inode(bdb, slave_inode) != SQLITE_OK)
goto abort;
- cfs_debug("deleted inode %016zX", slave_inode);
+ cfs_debug("deleted inode %016" PRIX64, slave_inode);
}
j++;
}
if (bdb_backend_delete_inode(bdb, slave_inode) != SQLITE_OK)
goto abort;
-
- cfs_debug("deleted inode %016zX", slave_inode);
+
+ cfs_debug("deleted inode %016" PRIX64, slave_inode);
j++;
}
result = TRUE;
ret:
- g_mutex_unlock (memdb->mutex);
+ g_mutex_unlock (&memdb->mutex);
if (index)
g_hash_table_destroy(index);
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;
}
-