diff options
author | Not Zed <NotZed@HelixCode.com> | 2000-09-28 19:25:16 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2000-09-28 19:25:16 +0800 |
commit | 315ea376cbb90d67ac6d4bd8086b2d98339154cb (patch) | |
tree | 573f0a5b3f80dc4e6071d71438f3a3d060639c0b | |
parent | f9a01cf88d9383b8715d49470124e3eb11e1d984 (diff) | |
download | gsoc2013-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/ChangeLog | 16 | ||||
-rw-r--r-- | libibex/block.c | 59 | ||||
-rw-r--r-- | libibex/block.h | 6 | ||||
-rw-r--r-- | libibex/wordindex.c | 2 |
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) { |