[pve-devel] r5468 - in pve-cluster/trunk/data: . src
svn-commits at proxmox.com
svn-commits at proxmox.com
Mon Jan 31 14:44:09 CET 2011
Author: dietmar
Date: 2011-01-31 14:44:09 +0100 (Mon, 31 Jan 2011)
New Revision: 5468
Modified:
pve-cluster/trunk/data/ChangeLog
pve-cluster/trunk/data/src/cfs-plug-memdb.c
pve-cluster/trunk/data/src/cfs-utils.c
pve-cluster/trunk/data/src/cfs-utils.h
pve-cluster/trunk/data/src/database.c
pve-cluster/trunk/data/src/dcdb.c
pve-cluster/trunk/data/src/dcdb.h
pve-cluster/trunk/data/src/dfsm.c
pve-cluster/trunk/data/src/dfsm.h
pve-cluster/trunk/data/src/memdb.c
pve-cluster/trunk/data/src/memdb.h
Log:
* src/dcdb.c (dcdb_deliver): implement a simple distributed lock
manager for short lived locks (no fencing, see README).
Modified: pve-cluster/trunk/data/ChangeLog
===================================================================
--- pve-cluster/trunk/data/ChangeLog 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/ChangeLog 2011-01-31 13:44:09 UTC (rev 5468)
@@ -1,3 +1,8 @@
+2011-01-31 Proxmox Support Team <support at proxmox.com>
+
+ * src/dcdb.c (dcdb_deliver): implement a simple distributed lock
+ manager for short lived locks (no fencing, see README).
+
2011-01-19 root <root at maui.maurer-it.com>
* perl/Cluster.pm (log_msg): fixes for taint mode (untaint $0)
Modified: pve-cluster/trunk/data/src/cfs-plug-memdb.c
===================================================================
--- pve-cluster/trunk/data/src/cfs-plug-memdb.c 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/cfs-plug-memdb.c 2011-01-31 13:44:09 UTC (rev 5468)
@@ -365,14 +365,35 @@
res = -EIO;
+ memdb_tree_entry_t *te = memdb_getattr(mdb->memdb, path);
uint32_t mtime = tv[1].tv_sec;
+
+ gboolean unlock_req = FALSE;
+
+ if (te && mtime == 0 && te->type == DT_DIR &&
+ path_is_lockdir(path)) {
+ unlock_req = TRUE;
+ }
+
if (mdb->dfsm) {
+ guchar csum[32];
+ if (unlock_req && memdb_tree_entry_csum(te, csum))
+ dcdb_send_unlock(mdb->dfsm, path, csum, TRUE);
+
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_MTIME, path,
NULL, NULL, 0, mtime, 0);
} else {
- res = memdb_mtime(mdb->memdb, path, 0, mtime);
+ uint32_t ctime = time(NULL);
+ if (unlock_req && memdb_lock_expired(mdb->memdb, path)) {
+ res = memdb_delete(mdb->memdb, path, 0, ctime);
+ } else {
+ res = memdb_mtime(mdb->memdb, path, 0, mtime);
+ }
}
+ if (te)
+ g_free(te);
+
return res;
}
Modified: pve-cluster/trunk/data/src/cfs-utils.c
===================================================================
--- pve-cluster/trunk/data/src/cfs-utils.c 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/cfs-utils.c 2011-01-31 13:44:09 UTC (rev 5468)
@@ -431,3 +431,8 @@
return FALSE;
}
+gboolean
+path_is_lockdir(const char *path)
+{
+ return (strncmp(path, "priv/lock/", 10) == 0) && (strlen(path) > 10);
+}
Modified: pve-cluster/trunk/data/src/cfs-utils.h
===================================================================
--- pve-cluster/trunk/data/src/cfs-utils.h 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/cfs-utils.h 2011-01-31 13:44:09 UTC (rev 5468)
@@ -113,4 +113,7 @@
gboolean
path_is_private(const char *path);
+gboolean
+path_is_lockdir(const char *path);
+
#endif /* _PVE_CFS_UTILS_H_ */
Modified: pve-cluster/trunk/data/src/database.c
===================================================================
--- pve-cluster/trunk/data/src/database.c 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/database.c 2011-01-31 13:44:09 UTC (rev 5468)
@@ -436,6 +436,7 @@
}
sqlite3_reset(stmt);
+
return TRUE;
fail:
@@ -582,6 +583,9 @@
result = FALSE;
goto ret;
}
+
+ memdb_update_locks(memdb);
+
result = TRUE;
ret:
Modified: pve-cluster/trunk/data/src/dcdb.c
===================================================================
--- pve-cluster/trunk/data/src/dcdb.c 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dcdb.c 2011-01-31 13:44:09 UTC (rev 5468)
@@ -47,6 +47,64 @@
GList *updates;
} dcdb_sync_info_t;
+void
+dcdb_send_unlock(
+ dfsm_t *dfsm,
+ const char *path,
+ const guchar csum[32],
+ gboolean request)
+{
+ g_return_if_fail(dfsm != NULL);
+ g_return_if_fail(path != NULL);
+ g_return_if_fail(csum != NULL);
+
+ struct iovec iov[2];
+
+ iov[0].iov_base = (char *)csum;
+ iov[0].iov_len = 32;
+
+ iov[1].iov_base = (char *)path;
+ iov[1].iov_len = strlen(path) + 1;
+
+ if (!cfs_is_quorate())
+ return;
+
+ dcdb_message_t msg_type = request ?
+ DCDB_MESSAGE_CFS_UNLOCK_REQUEST : DCDB_MESSAGE_CFS_UNLOCK;
+
+ dfsm_send_message_sync(dfsm, msg_type, iov, 2, NULL);
+}
+
+static gboolean
+dcdb_parse_unlock_request(
+ const void *msg,
+ size_t msg_len,
+ const char **path,
+ const guchar **csum)
+
+{
+ g_return_val_if_fail(msg != NULL, FALSE);
+ g_return_val_if_fail(path != NULL, FALSE);
+ g_return_val_if_fail(csum != NULL, FALSE);
+
+ if (msg_len < 33) {
+ cfs_critical("received short unlock message (%lu < 33)", msg_len);
+ return FALSE;
+ }
+
+ *csum = msg;
+ msg += 32; msg_len -= 32;
+
+ *path = msg;
+ if ((*path)[msg_len - 1] != 0) {
+ cfs_critical("received mailformed unlock message - 'path' not terminated");
+ *path = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
int
dcdb_send_fuse_message(
dfsm_t *dfsm,
@@ -750,11 +808,43 @@
goto leave;
}
- const char *path, *to, *buf;
+ const char *path, *to, *buf;
guint32 size, offset, flags;
+ const guchar *csum;
- if (msg_type == DCDB_MESSAGE_CFS_WRITE) {
+ if (msg_type == DCDB_MESSAGE_CFS_UNLOCK_REQUEST ||
+ msg_type == DCDB_MESSAGE_CFS_UNLOCK) {
+ msg_result = 0; /* ignored anyways */
+
+ if (!dcdb_parse_unlock_request(msg, msg_len, &path, &csum))
+ goto leave;
+ guchar cur_csum[32];
+ memdb_tree_entry_t *te = memdb_getattr(memdb, path);
+
+ if (te && te->type == DT_DIR &&
+ path_is_lockdir(path) && memdb_tree_entry_csum(te, cur_csum) &&
+ (memcmp(csum, cur_csum, 32) == 0)) {
+
+ if (msg_type == DCDB_MESSAGE_CFS_UNLOCK) {
+
+ cfs_debug("got valid unlock message");
+
+ msg_result = memdb_delete(memdb, path, nodeid, msg_time);
+
+ } else if (dfsm_lowest_nodeid(dfsm)) {
+
+ cfs_debug("got valid unlock request message");
+
+ if (memdb_lock_expired(memdb, path)) {
+ cfs_debug("sending unlock message");
+ dcdb_send_unlock(dfsm, path, csum, FALSE);
+ }
+ }
+ }
+
+ } else if (msg_type == DCDB_MESSAGE_CFS_WRITE) {
+
if (!dcdb_parse_fuse_message(msg, msg_len, &path, &to, &buf,
&size, &offset, &flags))
goto leave;
Modified: pve-cluster/trunk/data/src/dcdb.h
===================================================================
--- pve-cluster/trunk/data/src/dcdb.h 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dcdb.h 2011-01-31 13:44:09 UTC (rev 5468)
@@ -38,9 +38,11 @@
DCDB_MESSAGE_CFS_RENAME = 4,
DCDB_MESSAGE_CFS_CREATE = 5,
DCDB_MESSAGE_CFS_MTIME = 6,
+ DCDB_MESSAGE_CFS_UNLOCK_REQUEST = 7,
+ DCDB_MESSAGE_CFS_UNLOCK = 8,
} dcdb_message_t;
-#define DCDB_VALID_MESSAGE_TYPE(mt) (mt >= DCDB_MESSAGE_CFS_WRITE && mt <= DCDB_MESSAGE_CFS_MTIME)
+#define DCDB_VALID_MESSAGE_TYPE(mt) (mt >= DCDB_MESSAGE_CFS_WRITE && mt <= DCDB_MESSAGE_CFS_UNLOCK)
dfsm_t *dcdb_new(memdb_t *memdb);
@@ -58,5 +60,11 @@
guint32 offset,
guint32 flags);
+void
+dcdb_send_unlock_request(
+ dfsm_t *dfsm,
+ const char *path,
+ const guchar csum[32],
+ gboolean request);
#endif /* _PVE_DCDB_H_ */
Modified: pve-cluster/trunk/data/src/dfsm.c
===================================================================
--- pve-cluster/trunk/data/src/dfsm.c 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dfsm.c 2011-01-31 13:44:09 UTC (rev 5468)
@@ -1278,6 +1278,17 @@
return NULL;
}
+gboolean
+dfsm_lowest_nodeid(dfsm_t *dfsm)
+{
+ g_return_val_if_fail(dfsm != NULL, FALSE);
+
+ if (dfsm->lowest_nodeid && (dfsm->lowest_nodeid == dfsm->nodeid))
+ return TRUE;
+
+ return FALSE;
+}
+
cs_error_t
dfsm_verify_request(dfsm_t *dfsm)
{
Modified: pve-cluster/trunk/data/src/dfsm.h
===================================================================
--- pve-cluster/trunk/data/src/dfsm.h 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dfsm.h 2011-01-31 13:44:09 UTC (rev 5468)
@@ -174,6 +174,9 @@
dfsm_send_update_complete(dfsm_t *dfsm);
gboolean
+dfsm_lowest_nodeid(dfsm_t *dfsm);
+
+gboolean
dfsm_nodeid_is_local(
dfsm_t *dfsm,
uint32_t nodeid,
Modified: pve-cluster/trunk/data/src/memdb.c
===================================================================
--- pve-cluster/trunk/data/src/memdb.c 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/memdb.c 2011-01-31 13:44:09 UTC (rev 5468)
@@ -38,6 +38,8 @@
#include "memdb.h"
#include "status.h"
+#define CFS_LOCK_TIMEOUT (60*2)
+
memdb_tree_entry_t *
memdb_tree_entry_new(
const char *name)
@@ -97,7 +99,17 @@
g_free(te);
}
+void
+memdb_lock_info_free(memdb_lock_info_t *li)
+{
+ g_return_if_fail(li != NULL);
+ if (li->path)
+ g_free(li->path);
+
+ g_free(li);
+}
+
static gint
memdb_tree_compare(
gconstpointer v1,
@@ -327,6 +339,79 @@
return ret;
}
+gboolean
+memdb_lock_expired(
+ memdb_t *memdb,
+ const char *path)
+{
+ g_return_val_if_fail(memdb != NULL, FALSE);
+ g_return_val_if_fail(memdb->locks != NULL, FALSE);
+ g_return_val_if_fail(path != NULL, FALSE);
+
+ memdb_lock_info_t *li;
+ uint32_t ctime = time(NULL);
+
+ if ((li = g_hash_table_lookup(memdb->locks, path))) {
+ if ((ctime > li->ltime) && ((ctime - li->ltime) > CFS_LOCK_TIMEOUT))
+ return TRUE;
+ } else {
+ li = g_new0(memdb_lock_info_t, 1);
+ li->path = g_strdup(path);
+ li->ltime = ctime;
+ g_hash_table_replace(memdb->locks, li->path, li);
+ }
+
+ return FALSE;
+}
+
+void
+memdb_update_locks(memdb_t *memdb)
+{
+ g_return_if_fail(memdb != NULL);
+ g_return_if_fail(memdb->locks != NULL);
+
+ memdb_tree_entry_t *te, *parent;
+
+ if (!(te = memdb_lookup_path(memdb, "priv/lock", &parent)))
+ return;
+
+ if (te->type != DT_DIR)
+ return;
+
+
+ GHashTable *old = memdb->locks;
+ memdb->locks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)memdb_lock_info_free);
+ GHashTableIter iter;
+ GHashTable *ht = te->data.entries;
+
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, ht);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+
+ memdb_tree_entry_t *lock_te = (memdb_tree_entry_t *)value;
+ if (lock_te->type != DT_DIR)
+ continue;
+
+ memdb_lock_info_t *li;
+ li = g_new0(memdb_lock_info_t, 1);
+ li->path = g_strdup_printf("priv/lock/%s", lock_te->name);
+
+ memdb_lock_info_t *oldli;
+ if ((oldli = g_hash_table_lookup(memdb->locks, lock_te->name))) {
+ li->ltime = oldli->ltime;
+ } else {
+ li->ltime = time(NULL);
+ }
+ g_hash_table_insert(memdb->locks, li->path, li);
+ }
+
+ if (old)
+ g_hash_table_destroy(old);
+
+}
+
gboolean
memdb_recreate_vmlist(
memdb_t *memdb)
@@ -395,6 +480,9 @@
g_hash_table_replace(memdb->index, &memdb->root->inode, memdb->root);
+ memdb->locks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)memdb_lock_info_free);
+
if (!(memdb->bdb = bdb_backend_open(dbfilename, memdb->root, memdb->index))) {
memdb_close(memdb);
return NULL;
@@ -407,6 +495,8 @@
return NULL;
}
+ memdb_update_locks(memdb);
+
cfs_debug("memdb open '%s' successful (version = %016zX)",
dbfilename, memdb->root->version);
@@ -426,6 +516,9 @@
if (memdb->index)
g_hash_table_destroy(memdb->index);
+ if (memdb->locks)
+ g_hash_table_destroy(memdb->locks);
+
if (memdb->dbfilename)
g_free(memdb->dbfilename);
@@ -513,6 +606,11 @@
goto ret;
}
+ if (strcmp(dirname, "priv/lock") == 0) {
+ g_hash_table_remove(memdb->locks, path);
+ memdb_lock_expired(memdb, path); // insert a new entry
+ }
+
ret = 0;
ret:
@@ -771,6 +869,18 @@
goto ret;
}
+ /* NOTE: we use utime(0,0) to trigger 'unlock', so we do not
+ * allow to change mtime for locks (only it mtime is newer).
+ * See README for details about locks.
+ */
+ if (mtime < te->mtime && te->type == DT_DIR &&
+ strcmp(dirname, "priv/lock") == 0) {
+ cfs_debug("dir is locked");
+ ret = -EACCES;
+ goto ret;
+ }
+
+
memdb->root->version++;
memdb->root->mtime = mtime;
memdb->root->writer = writer;
@@ -992,6 +1102,12 @@
}
}
+ /* we do not allow rename for locks */
+ if (from_te->type == DT_DIR && path_is_lockdir(from)) {
+ ret = -EACCES;
+ goto ret;
+ }
+
if ((to_te = memdb_lookup_path(memdb, to, &to_parent))) {
if ((ret = unlink_tree_entry(memdb, to_parent, to_te)) != 0)
@@ -1114,6 +1230,8 @@
ret = -ENOTEMPTY;
goto ret;
}
+
+ g_hash_table_remove(memdb->locks, path);
}
record_memdb_change(path);
@@ -1272,6 +1390,35 @@
return copy;
}
+gboolean
+memdb_tree_entry_csum(
+ memdb_tree_entry_t *te,
+ guchar csum[32])
+{
+ g_return_val_if_fail(te != NULL, FALSE);
+ g_return_val_if_fail(csum != NULL, FALSE);
+
+ GChecksum *sha256 = g_checksum_new(G_CHECKSUM_SHA256);
+
+ g_checksum_update(sha256, (unsigned char*)&te->inode, sizeof(te->inode));
+ g_checksum_update(sha256, (unsigned char*)&te->version, sizeof(te->version));
+ g_checksum_update(sha256, (unsigned char*)&te->writer, sizeof(te->writer));
+ g_checksum_update(sha256, (unsigned char*)&te->mtime, sizeof(te->mtime));
+ g_checksum_update(sha256, (unsigned char*)&te->size, sizeof(te->size));
+ g_checksum_update(sha256, (unsigned char*)&te->type, sizeof(te->type));
+ g_checksum_update(sha256, (unsigned char*)&te->parent, sizeof(te->parent));
+ g_checksum_update(sha256, (unsigned char*)te->name, strlen(te->name));
+
+ if (te->type == DT_REG && te->size)
+ g_checksum_update(sha256, (unsigned char*)te->data.value, te->size);
+
+ size_t csum_len = 32;
+ g_checksum_get_digest(sha256, csum, &csum_len);
+ g_checksum_free(sha256);
+
+ return TRUE;
+}
+
gboolean
memdb_compute_checksum(
GHashTable *index,
Modified: pve-cluster/trunk/data/src/memdb.h
===================================================================
--- pve-cluster/trunk/data/src/memdb.h 2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/memdb.h 2011-01-31 13:44:09 UTC (rev 5468)
@@ -47,7 +47,7 @@
union {
GHashTable *entries;
gpointer value;
- } data;
+ } data;
char name[0];
};
@@ -69,148 +69,183 @@
typedef struct db_backend db_backend_t;
typedef struct {
+ char *path;
+ guint32 ltime;
+} memdb_lock_info_t;
+
+typedef struct {
char *dbfilename;
gboolean errors;
memdb_tree_entry_t *root;
GHashTable *index; /* map version ==> memdb_tree_entry */
+ GHashTable *locks; /* contains memdb_lock_info_t */
GMutex *mutex;
db_backend_t *bdb;
} memdb_t;
-memdb_t *memdb_open(
- const char *dbfilename);
+memdb_t *
+memdb_open(const char *dbfilename);
-void memdb_close(
- memdb_t *memdb);
+void
+memdb_close(memdb_t *memdb);
-gboolean memdb_checkpoint(
- memdb_t *memdb);
+gboolean
+memdb_checkpoint(memdb_t *memdb);
-gboolean memdb_recreate_vmlist(
- memdb_t *memdb);
+gboolean
+memdb_recreate_vmlist(memdb_t *memdb);
-int memdb_statfs(
- memdb_t *memdb,
+gboolean
+memdb_lock_expired(
+ memdb_t *memdb,
+ const char *path);
+
+void
+memdb_update_locks(memdb_t *memdb);
+
+int
+memdb_statfs(
+ memdb_t *memdb,
struct statvfs *stbuf);
-int memdb_mkdir(
- memdb_t *memdb,
- const char *path,
- guint32 writer,
+int
+memdb_mkdir(
+ memdb_t *memdb,
+ const char *path,
+ guint32 writer,
guint32 mtime);
-int
+int
memdb_mtime(
- memdb_t *memdb,
- const char *path,
- guint32 writer,
+ memdb_t *memdb,
+ const char *path,
+ guint32 writer,
guint32 mtime);
-GList *memdb_readdir(
- memdb_t *memdb,
+GList *
+memdb_readdir(
+ memdb_t *memdb,
const char *path);
-void memdb_dirlist_free(
- GList *dirlist);
+void
+memdb_dirlist_free(GList *dirlist);
-void tree_entry_debug(
- memdb_tree_entry_t *te);
+void
+tree_entry_debug(memdb_tree_entry_t *te);
-void tree_entry_print(
- memdb_tree_entry_t *te);
+void
+tree_entry_print(memdb_tree_entry_t *te);
-memdb_tree_entry_t *memdb_tree_entry_new(
- const char *name);
+memdb_tree_entry_t *
+memdb_tree_entry_new(const char *name);
-memdb_tree_entry_t *memdb_tree_entry_copy(
- memdb_tree_entry_t *te,
+memdb_tree_entry_t *
+memdb_tree_entry_copy(
+ memdb_tree_entry_t *te,
gboolean with_data);
-void memdb_tree_entry_free(
- memdb_tree_entry_t *te);
+void
+memdb_tree_entry_free(memdb_tree_entry_t *te);
-int memdb_delete(
- memdb_t *memdb,
- const char *path,
- guint32 writer,
+int
+memdb_delete(
+ memdb_t *memdb,
+ const char *path,
+ guint32 writer,
guint32 mtime);
-int memdb_read(
- memdb_t *memdb,
- const char *path,
+int
+memdb_read(
+ memdb_t *memdb,
+ const char *path,
gpointer *data_ret);
-int memdb_create(
- memdb_t *memdb,
+int
+memdb_create(
+ memdb_t *memdb,
const char *path,
guint32 writer,
guint32 mtime);
-int memdb_write(
- memdb_t *memdb,
- const char *path,
- guint32 writer,
+int
+memdb_write(
+ memdb_t *memdb,
+ const char *path,
+ guint32 writer,
guint32 mtime,
- gconstpointer data,
- size_t count,
- off_t offset,
+ gconstpointer data,
+ size_t count,
+ off_t offset,
gboolean truncate);
-memdb_tree_entry_t *memdb_getattr(
- memdb_t *memdb,
+memdb_tree_entry_t *
+memdb_getattr(
+ memdb_t *memdb,
const char *path);
-int memdb_rename(
- memdb_t *memdb,
- const char *from,
- const char *to,
- guint32 writer,
+int
+memdb_rename(
+ memdb_t *memdb,
+ const char *from,
+ const char *to,
+ guint32 writer,
guint32 mtime);
-void memdb_dump (
+void
+memdb_dump (
memdb_t *memdb);
-gboolean memdb_compute_checksum(
- GHashTable *index,
- memdb_tree_entry_t *root,
- guchar *csum,
+gboolean
+memdb_compute_checksum(
+ GHashTable *index,
+ memdb_tree_entry_t *root,
+ guchar *csum,
size_t csum_len);
-memdb_index_t *memdb_encode_index(
- GHashTable *index,
+memdb_index_t *
+memdb_encode_index(
+ GHashTable *index,
memdb_tree_entry_t *root);
-void memdb_dump_index (
- memdb_index_t *idx);
+void
+memdb_dump_index (memdb_index_t *idx);
-memdb_index_t *memdb_index_copy(
- memdb_index_t *idx);
+memdb_index_t *
+memdb_index_copy(memdb_index_t *idx);
-db_backend_t *bdb_backend_open(
+gboolean
+memdb_tree_entry_csum(
+ memdb_tree_entry_t *te,
+ guchar csum[32]);
+
+db_backend_t *
+bdb_backend_open(
const char *filename,
memdb_tree_entry_t *root,
GHashTable *index);
-void bdb_backend_close(
- db_backend_t *bdb);
+void
+bdb_backend_close(db_backend_t *bdb);
-int bdb_backend_write(
+int
+bdb_backend_write(
db_backend_t *bdb,
- guint64 inode,
- guint64 parent,
- guint64 version,
+ guint64 inode,
+ guint64 parent,
+ guint64 version,
guint32 writer,
guint32 mtime,
- guint32 size,
- char type,
+ guint32 size,
+ char type,
char *name,
gpointer value,
guint64 delete_inode);
-gboolean bdb_backend_commit_update(
- memdb_t *memdb,
- memdb_index_t *master,
- memdb_index_t *slave,
+gboolean
+bdb_backend_commit_update(
+ memdb_t *memdb,
+ memdb_index_t *master,
+ memdb_index_t *slave,
GList *inodes);
More information about the pve-devel
mailing list