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
This commit is contained in:
Not Zed
2000-09-28 11:25:16 +00:00
committed by Michael Zucci
parent f9a01cf88d
commit 315ea376cb
4 changed files with 72 additions and 11 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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)
{