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:
@ -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.
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user