aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNot Zed <NotZed@HelixCode.com>2000-09-28 19:25:16 +0800
committerMichael Zucci <zucchi@src.gnome.org>2000-09-28 19:25:16 +0800
commit315ea376cbb90d67ac6d4bd8086b2d98339154cb (patch)
tree573f0a5b3f80dc4e6071d71438f3a3d060639c0b
parentf9a01cf88d9383b8715d49470124e3eb11e1d984 (diff)
downloadgsoc2013-evolution-315ea376cbb90d67ac6d4bd8086b2d98339154cb.tar.gz
gsoc2013-evolution-315ea376cbb90d67ac6d4bd8086b2d98339154cb.tar.zst
gsoc2013-evolution-315ea376cbb90d67ac6d4bd8086b2d98339154cb.zip
Make sure we map the 'free' block to a block number when unlinking a block
2000-09-28 Not Zed <NotZed@HelixCode.com> * block.c (ibex_block_free): Make sure we map the 'free' block to a block number when unlinking a block (fixes a lot of assertion failures). (ibex_block_cache_open): Initialise sync flag on root block. If it is not set on open then the index could be in an invalid state, and should be rescanned. (ibex_block_cache_sync): Sync root block last, and set the sync flag. (ibex_block_cache_open): Mirror root block flags in block_cache struct. (ibex_block_cache_sync): Likewise. (ibex_block_read): If we write a dirty block, then we clear the sync flag if its still set; we are no longer synced. svn path=/trunk/; revision=5613
-rw-r--r--libibex/ChangeLog16
-rw-r--r--libibex/block.c59
-rw-r--r--libibex/block.h6
-rw-r--r--libibex/wordindex.c2
4 files changed, 72 insertions, 11 deletions
diff --git a/libibex/ChangeLog b/libibex/ChangeLog
index 1c80c8348b..5e16a0666b 100644
--- a/libibex/ChangeLog
+++ b/libibex/ChangeLog
@@ -1,3 +1,19 @@
+2000-09-28 Not Zed <NotZed@HelixCode.com>
+
+ * block.c (ibex_block_free): Make sure we map the 'free' block to
+ a block number when unlinking a block (fixes a lot of assertion
+ failures).
+ (ibex_block_cache_open): Initialise sync flag on root block. If
+ it is not set on open then the index could be in an invalid state,
+ and should be rescanned.
+ (ibex_block_cache_sync): Sync root block last, and set the sync
+ flag.
+ (ibex_block_cache_open): Mirror root block flags in block_cache
+ struct.
+ (ibex_block_cache_sync): Likewise.
+ (ibex_block_read): If we write a dirty block, then we clear the
+ sync flag if its still set; we are no longer synced.
+
2000-09-19 Not Zed <NotZed@HelixCode.com>
** Merged from IBEX_DISK branch to head.
diff --git a/libibex/block.c b/libibex/block.c
index 53579523bd..d971077dba 100644
--- a/libibex/block.c
+++ b/libibex/block.c
@@ -220,16 +220,28 @@ sync_block(struct _memcache *block_cache, struct _memblock *memblock)
void
ibex_block_cache_sync(struct _memcache *block_cache)
{
- struct _memblock *memblock;
+ struct _memblock *memblock, *rootblock = 0;
memblock = (struct _memblock *)block_cache->nodes.head;
while (memblock->next) {
- if (memblock->flags & BLOCK_DIRTY) {
- sync_block(block_cache, memblock);
+ if (memblock->block == 0) {
+ rootblock = memblock;
+ } else {
+ if (memblock->flags & BLOCK_DIRTY) {
+ sync_block(block_cache, memblock);
+ }
}
memblock = memblock->next;
}
- fsync(block_cache->fd);
+
+ if (rootblock) {
+ struct _root *root = (struct _root *)&rootblock->data;
+ root->flags |= IBEX_ROOT_SYNCF;
+ sync_block(block_cache, rootblock);
+ }
+ if (fsync(block_cache->fd) == 0) {
+ block_cache->flags |= IBEX_ROOT_SYNCF;
+ }
#ifdef IBEX_STATS
dump_stats(block_cache);
@@ -291,6 +303,15 @@ ibex_block_read(struct _memcache *block_cache, blockid_t blockid)
memblock = g_hash_table_lookup(block_cache->index, (void *)blockid);
if (memblock) {
d(printf("foudn blockid in cache %d = %p\n", blockid, &memblock->data));
+#if 0
+ if (blockid == 0) {
+ struct _root *root = &memblock->data;
+ d(printf("superblock state:\n"
+ " roof = %d\n free = %d\n words = %d\n names = %d\n tail = %d",
+ root->roof, root->free, root->words, root->names, root->tail));
+
+ }
+#endif
/* 'access' page */
ibex_list_remove((struct _listnode *)memblock);
ibex_list_addtail(&block_cache->nodes, (struct _listnode *)memblock);
@@ -318,6 +339,18 @@ ibex_block_read(struct _memcache *block_cache, blockid_t blockid)
g_hash_table_remove(block_cache->index, (void *)old->block);
ibex_list_remove((struct _listnode *)old);
if (old->flags & BLOCK_DIRTY) {
+ /* are we about to un-sync the file? update root and sync it */
+ if (block_cache->flags & IBEX_ROOT_SYNCF) {
+ /* TODO: put the rootblock in the block_cache struct, not in the cache */
+ struct _memblock *rootblock = g_hash_table_lookup(block_cache->index, (void *)0);
+ struct _root *root = (struct _root *)&rootblock->data;
+
+ g_assert(rootblock != NULL);
+ root->flags &= ~IBEX_ROOT_SYNCF;
+ sync_block(block_cache, rootblock);
+ if (fsync(block_cache->fd) == 0)
+ block_cache->flags &= ~IBEX_ROOT_SYNCF;
+ }
sync_block(block_cache, old);
}
g_free(old);
@@ -365,8 +398,10 @@ ibex_block_cache_open(const char *name, int flags, int mode)
}
root = (struct _root *)ibex_block_read(block_cache, 0);
- if (root->roof == 0 || memcmp(root->version, "ibx3", 4)) {
- d(printf("Initialising superblock\n"));
+ if (root->roof == 0
+ || memcmp(root->version, "ibx3", 4)
+ || ((root->flags & IBEX_ROOT_SYNCF) == 0)) {
+ (printf("Initialising superblock\n"));
/* reset root data */
memcpy(root->version, "ibx3", 4);
root->roof = 1024;
@@ -374,12 +409,16 @@ ibex_block_cache_open(const char *name, int flags, int mode)
root->words = 0;
root->names = 0;
root->tail = 0; /* list of tail blocks */
+ root->flags = 0;
ibex_block_dirty((struct _block *)root);
+ /* reset the file contents */
+ ftruncate(block_cache->fd, 1024);
} else {
- d(printf("superblock already initialised:\n"
- " roof = %d\n free = %d\n words = %d\n names = %d\n",
- root->roof, root->free, root->words, root->names));
+ (printf("superblock already initialised:\n"
+ " roof = %d\n free = %d\n words = %d\n names = %d\n tail = %d",
+ root->roof, root->free, root->words, root->names, root->tail));
}
+ block_cache->flags = root->flags;
/* this should be moved higher up */
{
struct _IBEXWord *ibex_create_word_index(struct _memcache *bc, blockid_t *wordroot, blockid_t *nameroot);
@@ -435,7 +474,7 @@ ibex_block_free(struct _memcache *block_cache, blockid_t blockid)
struct _root *root = (struct _root *)ibex_block_read(block_cache, 0);
struct _block *block = ibex_block_read(block_cache, blockid);
- block->next = root->free;
+ block->next = block_number(root->free);
root->free = blockid;
ibex_block_dirty((struct _block *)root);
ibex_block_dirty((struct _block *)block);
diff --git a/libibex/block.h b/libibex/block.h
index 40262de6e2..deb6494231 100644
--- a/libibex/block.h
+++ b/libibex/block.h
@@ -25,8 +25,12 @@ struct _root {
blockid_t words; /* root of words index */
blockid_t names; /* root of names index */
+
+ char flags; /* state flags */
};
+#define IBEX_ROOT_SYNCF (1<<0) /* file is synced */
+
/* basic disk structure for (data) blocks */
struct _block {
unsigned int next:32-BLOCK_BITS; /* next block */
@@ -70,6 +74,8 @@ struct _memcache {
GHashTable *index; /* blockid->memblock mapping */
int fd; /* file fd */
+ int flags; /* flags (mirror of root->flags) */
+
#ifdef IBEX_STATS
GHashTable *stats;
#endif
diff --git a/libibex/wordindex.c b/libibex/wordindex.c
index dbde1f4a7f..d988ee1482 100644
--- a/libibex/wordindex.c
+++ b/libibex/wordindex.c
@@ -121,7 +121,7 @@ ibex_create_word_index(struct _memcache *bc, blockid_t *wordroot, blockid_t *nam
return idx;
}
-#if 0
+#if 1
static void
cache_sanity(struct _wordcache *head)
{