afs/fs/cachefs rootdir.c,1.13,1.14 replay.c,1.1,1.2
recycling.c,1.25,1.26 journal.c,1.39,1.40 interface.c,1.15,1.16
index.c,1.26,1.27 dump-journal.c,1.13,1.14
cachefs-layout.h,1.29,1.30 cachefs-int.h,1.38,1.39 block.c,1.8,1.9
dwh at infradead.org
dwh at infradead.org
Thu Jul 10 16:21:26 BST 2003
Update of /home/cvs/afs/fs/cachefs
In directory phoenix.infradead.org:/tmp/cvs-serv15220/fs/cachefs
Modified Files:
rootdir.c replay.c recycling.c journal.c interface.c index.c
dump-journal.c cachefs-layout.h cachefs-int.h block.c
Log Message:
started fleshing out the replaying properly
fixed a few bugs (including those introduced by the above)
Index: rootdir.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/rootdir.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- rootdir.c 9 Jul 2003 10:39:50 -0000 1.13
+++ rootdir.c 10 Jul 2003 14:21:23 -0000 1.14
@@ -641,14 +641,17 @@
*/
static int cachefs_root_rmdir_unlink(struct inode *dir, struct dentry *dentry)
{
+ struct cachefs_ondisc_index_entry *xent;
struct cachefs_ondisc_metadata *metadata;
struct cachefs_transaction *trans;
- struct cachefs_inode *inode;
struct cachefs_super *super = dir->i_sb->s_fs_info;
+ struct cachefs_inode *inode, *index;
unsigned long flags;
+ struct page *ixpage;
int ret;
- _enter("{%lx},{%s,%p}", dir->i_ino, dentry->d_name.name, dentry->d_inode);
+ _enter("{%lx},{%s,%p}",
+ dir->i_ino, dentry->d_name.name, dentry->d_inode);
if (!dentry->d_inode) {
printk("&&& no inode &&&\n");
@@ -657,6 +660,7 @@
}
inode = CACHEFS_FS_I(dentry->d_inode);
+ index = CACHEFS_FS_I(dir);
/* mark for reclamation under journalling */
trans = cachefs_trans_alloc(super, GFP_KERNEL);
@@ -667,20 +671,52 @@
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INODE_MARK_RECLAIM;
trans->jentry->ino = inode->vfs_inode.i_ino;
+ trans->jentry->auxblock = inode->metadata->bix;
+ trans->jentry->auxentry = inode->metadata_offset;
+
+ metadata = cachefs_metadata_preread(inode);
+ trans->jentry->index = metadata->pindex;
+ trans->jentry->ixentry = metadata->pindex_entry;
+ cachefs_metadata_postread(inode);
+
+ BUG_ON(trans->jentry->index != dir->i_ino);
+
+ trans->jentry->pgnum = trans->jentry->index / index->index_epp;
+ trans->jentry->entry =
+ (trans->jentry->index % index->index_epp) * index->index_esize;
+
+ ret = cachefs_get_page(index, trans->jentry->pgnum, &ixpage);
+ if (ret < 0) {
+ cachefs_trans_put(trans);
+ _leave(" = %d", ret);
+ return ret;
+ }
+
+ trans->jentry->block = __cachefs_get_page_block(ixpage)->bix;
cachefs_trans_affects_inode(trans, inode);
+ cachefs_trans_affects_page(trans, __cachefs_page_get_private(ixpage),
+ trans->jentry->entry, sizeof(*xent));
ret = cachefs_trans_mark(trans);
if (ret < 0) {
+ cachefs_put_page(ixpage);
cachefs_trans_put(trans);
_leave(" = %d", ret);
return ret;
}
+ cachefs_page_modify(super, &ixpage);
+
/* modify the inode metadata entry */
metadata = cachefs_metadata_prewrite(inode);
metadata->header.state = CACHEFS_ONDISC_INDEX_RECYCLE;
cachefs_metadata_postwrite(inode);
+
+ /* modify the index entry */
+ xent = kmap(ixpage) + trans->jentry->entry;
+ xent->state = CACHEFS_ONDISC_INDEX_RECYCLE;
+ kunmap(ixpage);
cachefs_trans_commit(trans);
Index: replay.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/replay.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- replay.c 9 Jul 2003 10:39:50 -0000 1.1
+++ replay.c 10 Jul 2003 14:21:23 -0000 1.2
@@ -18,6 +18,9 @@
#include "cachefs-int.h"
#define UJNL_WRAP(X) ((X) & (CACHEFS_ONDISC_UJNL_NUMENTS - 1))
+#define BLOCK_VALID(BLOCK,JENTRY) \
+ ((BLOCK) && \
+ (u_int16_t) (unsigned long) (BLOCK)->ref <= (JENTRY)->serial)
struct cachefs_replay_find_batch_desc {
read_descriptor_t desc;
@@ -63,9 +66,6 @@
static int cachefs_replay_ujnl_index_extending(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans);
-static int cachefs_replay_ujnl_index_creating(struct cachefs_super *super,
- struct cachefs_ondisc_update_journal *jentry,
- struct cachefs_transaction *trans);
static int cachefs_replay_ujnl_index_modifying(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans);
@@ -102,7 +102,7 @@
[CACHEFS_ONDISC_UJNL_INDIRECT_ALLOCING] = cachefs_replay_ujnl_indirect_allocing,
[CACHEFS_ONDISC_UJNL_INDIRECT_FREEING] = cachefs_replay_ujnl_indirect_freeing,
[CACHEFS_ONDISC_UJNL_INDEX_EXTENDING] = cachefs_replay_ujnl_index_extending,
- [CACHEFS_ONDISC_UJNL_INDEX_CREATING] = cachefs_replay_ujnl_index_creating,
+ [CACHEFS_ONDISC_UJNL_INDEX_CREATING] = cachefs_replay_ujnl_inode_creating,
[CACHEFS_ONDISC_UJNL_INDEX_UPDATING] = cachefs_replay_ujnl_index_modifying
};
@@ -469,6 +469,7 @@
{
struct cachefs_replay_find_batch_desc find_batch;
struct cachefs_ondisc_free_node *node;
+ struct cachefs_block *block;
struct file_ra_state ra;
loff_t ppos;
int loop, ret;
@@ -507,54 +508,65 @@
find_batch.batch_end,
find_batch.batch_ack);
- if (find_batch.batch_end != ~0u && find_batch.batch_ack != ~0u)
- goto reload_tracking;
+ if (find_batch.batch_end == ~0u || find_batch.batch_ack == ~0u) {
+ if (find_batch.batch_first == ~0u) {
+ clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
+ printk("CacheFS: corrupted journal:"
+ " ujnl batch has no start entry\n");
+ return -EINVAL;
+ }
- if (find_batch.batch_first == ~0u) {
- clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
- printk("CacheFS: corrupted journal:"
- " ujnl batch has no start entry\n");
- return -EINVAL;
- }
+ if (find_batch.batch_ack != ~0u) {
+ clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
+ printk("CacheFS: corrupted journal:"
+ " ujnl batch has ACK but no end marker\n");
+ return -EINVAL;
+ }
- if (find_batch.batch_ack != ~0u) {
- clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
- printk("CacheFS: corrupted journal:"
- " ujnl batch has ACK but no end marker\n");
- return -EINVAL;
- }
+ if (find_batch.batch_count != super->ujnl_serial) {
+ clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
+ printk("CacheFS: corrupted journal:"
+ " ujnl batch has missing marks\n");
+ return -EINVAL;
+ }
- if (find_batch.batch_count != super->ujnl_serial) {
- clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
- printk("CacheFS: corrupted journal:"
- " ujnl batch has missing marks\n");
- return -EINVAL;
- }
+ /* all checks bear out that we have a valid - though incomplete
+ * - update journal batch */
+ printk("CacheFS: Need to replay update journal\n");
+
+ super->ujnl_tail = find_batch.batch_first;
+ super->ujnl_head = UJNL_WRAP(find_batch.batch_end - 1);
+
+ ret = cachefs_ujnl_replay_aux(
+ super, &ra, cachefs_ujnl_determine_overlap_actor);
+
+ if (ret == 0)
+ ret = cachefs_ujnl_replay_aux(
+ super, &ra, cachefs_ujnl_replay_actor);
+
+ while (!list_empty(&super->ujnl_replayq)) {
+ block = list_entry(super->ujnl_replayq.next,
+ struct cachefs_block, batch_link);
+
+ list_del_init(&block->batch_link);
+ block->ref = NULL;
+ cachefs_block_put(block);
+ }
- /* all checks bear out that we have a valid - though incomplete -
- * update journal batch */
- super->ujnl_tail = find_batch.batch_first;
- super->ujnl_head = UJNL_WRAP(find_batch.batch_end - 1);
-
- ret = cachefs_ujnl_replay_aux(super, &ra,
- cachefs_ujnl_determine_overlap_actor);
- if (ret < 0) {
- clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
- return ret;
- }
+ if (ret < 0) {
+ clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
+ printk("CacheFS: Failed to replay update journal\n");
+ return ret;
+ }
- ret = cachefs_ujnl_replay_aux(super, &ra,
- cachefs_ujnl_replay_actor);
- if (ret < 0) {
- clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
- return ret;
+ /* write all blocks that are marked for writeback */
+ cachefs_trans_batch_write(super);
+
+ printk("CacheFS: Finished replaying update journal\n");
}
- /* write all blocks that are marked for writeback */
- cachefs_trans_batch_write(super);
clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
- reload_tracking:
kdebug("reload_tracking");
super->ujnl_batch++;
super->ujnl_serial = 0;
@@ -632,7 +644,7 @@
}
- _leave(" = 0");
+ kleave(" = 0");
return 0;
} /* end cachefs_ujnl_replay() */
@@ -676,7 +688,7 @@
/* we need to fix up the recycling block node header if the block is
* currently part of one of the recycling chains */
- if ((u_int16_t) (unsigned long) block->ref <= jentry->serial) {
+ if (BLOCK_VALID(block, jentry)) {
node = kmap(page);
if (node->next != jentry->auxblock) {
@@ -719,7 +731,7 @@
if (ret < 0)
goto error;
- if ((u_int16_t) (unsigned long) block->ref <= jentry->serial) {
+ if (BLOCK_VALID(block, jentry)) {
node = kmap(page);
if (node->next || node->count) {
@@ -771,7 +783,7 @@
goto error2;
}
- if ((u_int16_t) (unsigned long) block->ref <= jentry->serial) {
+ if (BLOCK_VALID(block, jentry)) {
node = kmap(page);
if (memcmp(&node->leaves[jentry->auxblock],
@@ -842,7 +854,7 @@
kunmap(spage);
/* we need to reload the pointers cached into the recycling block */
- if ((u_int16_t) (unsigned long) block->ref <= jentry->serial) {
+ if (BLOCK_VALID(block, jentry)) {
node = kmap(page);
if (memcmp(&node->leaves[jentry->auxblock],
@@ -872,85 +884,358 @@
/*****************************************************************************/
/*
- * replay the creation of a new data inode
- * - since we don't know what index data was associated with it, all we can do
- * is mark it for reclamation
+ * replay the creation of a new data or index inode
*/
static int cachefs_replay_ujnl_inode_creating(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans)
{
- return -ENOANO;
+ struct cachefs_ondisc_index_entry *xent;
+ struct cachefs_ondisc_ujnl_index *jindex;
+ struct cachefs_ondisc_metadata *metadata;
+ struct cachefs_block *metameta, *inometa, *indexmeta, *indexdata;
+ struct page *metapage, *inompage, *ixmpage, *ixdatapage;
+ u_int32_t type;
+ int ret;
+
+ kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+
+ jindex = &jentry->ixdata[0];
+
+ ret = cachefs_block_read(super, NULL, 1, 0, &metameta, &metapage);
+ if (ret < 0)
+ goto error;
+
+ ret = cachefs_block_read(super, NULL, jentry->auxblock, 0,
+ &inometa, &inompage);
+ if (ret < 0)
+ goto error2;
+
+ ret = cachefs_block_read(super, NULL, jentry->upblock, 0,
+ &indexmeta, &ixmpage);
+ if (ret < 0)
+ goto error3;
+
+ ret = cachefs_block_read(super, NULL, jentry->block, 0,
+ &indexdata, &ixdatapage);
+ if (ret < 0)
+ goto error4;
+
+ type = CACHEFS_ONDISC_INDEX_DATAFILE;
+ if (jentry->mark == CACHEFS_ONDISC_UJNL_INDEX_CREATING)
+ type = CACHEFS_ONDISC_INDEX_INDEXFILE;
+
+ /* make sure the metadata file's freelink pointer is correct */
+ if (BLOCK_VALID(metameta, jentry)) {
+ metadata = kmap(metapage);
+ if (metadata->freelink != jindex->next_ino) {
+ metadata->freelink = jindex->next_ino;
+ cachefs_trans_replays_effect(trans, metameta);
+ }
+ kunmap(metapage);
+ }
+
+ /* make sure the index file's freelink pointer is correct */
+ if (BLOCK_VALID(indexmeta, jentry)) {
+ metadata = kmap(ixmpage);
+ if (metadata->freelink != jindex->next_index ||
+ metadata->size != jentry->size) {
+ metadata->freelink = jindex->next_index;
+ metadata->size = jentry->size;
+ cachefs_trans_replays_effect(trans, indexmeta);
+ }
+ kunmap(ixmpage);
+ }
+
+ /* make sure the new inode's metadata contains the right data */
+ if (BLOCK_VALID(inometa, jentry)) {
+ metadata = kmap(inompage);
+ if (metadata->header.state != CACHEFS_ONDISC_INDEX_ACTIVE ||
+ metadata->header.type != type ||
+ metadata->header.ino != 0xfefdfc ||
+ metadata->freelink != UINT_MAX ||
+ metadata->pindex != jentry->index ||
+ metadata->pindex_entry != jentry->ixentry ||
+ memcmp(&metadata->index,
+ &jindex->def,
+ sizeof(metadata->index)) != 0
+ ) {
+ metadata->header.state = CACHEFS_ONDISC_INDEX_ACTIVE;
+ metadata->header.type = type;
+ metadata->header.ino = 0xfefdfc;
+ metadata->freelink = UINT_MAX;
+ metadata->atime = CURRENT_TIME.tv_sec;
+ metadata->pindex = jentry->index;
+ metadata->pindex_entry = jentry->ixentry;
+
+ memcpy(&metadata->index,
+ &jindex->def,
+ sizeof(metadata->index));
+
+ cachefs_trans_replays_effect(trans, inometa);
+ }
+ kunmap(inompage);
+ }
+
+ /* make sure the index data is written into the index entry */
+ if (BLOCK_VALID(indexdata, jentry)) {
+ xent = kmap(ixdatapage);
+ if (xent->state != CACHEFS_ONDISC_INDEX_ACTIVE ||
+ xent->type != type ||
+ xent->ino != jentry->ino ||
+ memcmp(xent->data, jindex->data, jindex->def.dsize) != 0
+ ) {
+ xent->state = CACHEFS_ONDISC_INDEX_ACTIVE;
+ xent->type = type;
+ xent->ino = jentry->ino;
+
+ memcpy(xent->data, jindex->data, jindex->def.dsize);
+
+ cachefs_trans_replays_effect(trans, indexdata);
+ }
+ kunmap(ixdatapage);
+ }
+
+ cachefs_block_put(indexdata);
+ cachefs_put_page(ixdatapage);
+ error4:
+ cachefs_block_put(indexmeta);
+ cachefs_put_page(ixmpage);
+ error3:
+ cachefs_block_put(inometa);
+ cachefs_put_page(inompage);
+ error2:
+ cachefs_block_put(metameta);
+ cachefs_put_page(metapage);
+ error:
+ kleave(" = %d", ret);
+ return ret;
} /* end cachefs_replay_ujnl_inode_creating() */
/*****************************************************************************/
/*
* replay the updating of the information stored in an inode
- * - since we don't know what changes were to be made, we can't actually do
- * anything, so we trust that the inode version number will suffice to cause
- * an update upon accessing if need be
*/
static int cachefs_replay_ujnl_inode_updating(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans)
{
- return 0;
+ kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+
+ /* we don't do this yet */
+ return -EINVAL;
} /* end cachefs_replay_ujnl_inode_updating() */
/*****************************************************************************/
/*
- * not yet supported
+ * replay the deletion of an inode and its associated index entry
*/
static int cachefs_replay_ujnl_inode_deleting(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans)
{
- return -EIO;
+ struct cachefs_ondisc_index_entry *xent;
+ struct cachefs_ondisc_ujnl_index *jindex;
+ struct cachefs_ondisc_metadata *metadata;
+ struct cachefs_block *metameta, *inometa;
+ struct cachefs_block *indexmeta = NULL, *indexdata = NULL;
+ struct page *metapage, *inompage, *ixmpage = NULL, *ixdatapage = NULL;
+ int ret;
+
+ kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+
+ jindex = &jentry->ixdata[0];
+
+ ret = cachefs_block_read(super, NULL, 1, 0, &metameta, &metapage);
+ if (ret < 0)
+ goto error;
+
+ ret = cachefs_block_read(super, NULL, jentry->auxblock, 0,
+ &inometa, &inompage);
+ if (ret < 0)
+ goto error2;
+
+ if (jentry->index) {
+ ret = cachefs_block_read(super, NULL, jentry->upblock, 0,
+ &indexmeta, &ixmpage);
+ if (ret < 0)
+ goto error3;
+
+ ret = cachefs_block_read(super, NULL, jentry->block, 0,
+ &indexdata, &ixdatapage);
+ if (ret < 0)
+ goto error4;
+ }
+
+ /* make sure the metadata file's freelink pointer is correct */
+ if (BLOCK_VALID(metameta, jentry)) {
+ metadata = kmap(metapage);
+ if (metadata->freelink != jindex->next_ino) {
+ metadata->freelink = jindex->next_ino;
+ cachefs_trans_replays_effect(trans, metameta);
+ }
+ kunmap(metapage);
+ }
+
+ /* make sure the index file's freelink pointer is correct */
+ if (BLOCK_VALID(indexmeta, jentry)) {
+ metadata = kmap(ixmpage);
+ if (metadata->freelink != jindex->next_index ||
+ metadata->size != jentry->size) {
+ metadata->freelink = jindex->next_index;
+ metadata->size = jentry->size;
+ cachefs_trans_replays_effect(trans, indexmeta);
+ }
+ kunmap(ixmpage);
+ }
+
+ /* make sure the deleted inode's metadata contains the right data */
+ if (BLOCK_VALID(inometa, jentry)) {
+ metadata = kmap(inompage);
+ if (metadata->header.state != CACHEFS_ONDISC_INDEX_FREE ||
+ metadata->header.type != 0 ||
+ metadata->header.ino != 0xfefdfc ||
+ metadata->freelink != jindex->next_ino ||
+ metadata->pindex != 0 ||
+ metadata->pindex_entry != 0
+ ) {
+ memset(metadata, 0, super->layout->metadata_size);
+
+ metadata->header.state = CACHEFS_ONDISC_INDEX_FREE;
+ metadata->header.ino = 0xfefdfc;
+ metadata->freelink = jindex->next_ino;
+ metadata->atime = CURRENT_TIME.tv_sec;
+ metadata->pindex = 0;
+ metadata->pindex_entry = 0;
+
+ cachefs_trans_replays_effect(trans, inometa);
+ }
+ kunmap(inompage);
+ }
+
+ /* make sure the index data is written into the index entry */
+ if (BLOCK_VALID(indexdata, jentry)) {
+ xent = kmap(ixdatapage);
+ if (xent->state != CACHEFS_ONDISC_INDEX_FREE ||
+ xent->type != 0 ||
+ xent->ino != 0 ||
+ xent->freelink[0] != jindex->next_index
+ ) {
+ xent->state = CACHEFS_ONDISC_INDEX_FREE;
+ xent->type = 0;
+ xent->ino = 0;
+ xent->freelink[0] = jindex->next_index;
+
+ cachefs_trans_replays_effect(trans, indexdata);
+ }
+ kunmap(ixdatapage);
+ }
+
+ cachefs_block_put(indexdata);
+ cachefs_put_page(ixdatapage);
+ error4:
+ cachefs_block_put(indexmeta);
+ cachefs_put_page(ixmpage);
+ error3:
+ cachefs_block_put(inometa);
+ cachefs_put_page(inompage);
+ error2:
+ cachefs_block_put(metameta);
+ cachefs_put_page(metapage);
+ error:
+ kleave(" = %d", ret);
+ return ret;
} /* end cachefs_replay_ujnl_inode_deleting() */
/*****************************************************************************/
/*
- * replay an inode being marked for reclamation
+ * replay the marking of an inode for reclamation
*/
static int cachefs_replay_ujnl_inode_mark_reclaim(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans)
{
- return -ENOANO;
+ struct cachefs_ondisc_index_entry *xent;
+ struct cachefs_ondisc_ujnl_index *jindex;
+ struct cachefs_ondisc_metadata *metadata;
+ struct cachefs_block *inometa, *indexdata;
+ struct page *inompage, *ixdatapage;
+ int ret;
+
+ kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+
+ jindex = &jentry->ixdata[0];
+
+ ret = cachefs_block_read(super, NULL, jentry->auxblock, 0,
+ &inometa, &inompage);
+ if (ret < 0)
+ goto error;
+
+ ret = cachefs_block_read(super, NULL, jentry->block, 0,
+ &indexdata, &ixdatapage);
+ if (ret < 0)
+ goto error2;
+
+ /* make sure the inode's metadata is set to the right state */
+ if (BLOCK_VALID(inometa, jentry)) {
+ metadata = kmap(inompage);
+ if (metadata->header.state != CACHEFS_ONDISC_INDEX_RECYCLE) {
+ metadata->header.state = CACHEFS_ONDISC_INDEX_FREE;
+
+ cachefs_trans_replays_effect(trans, inometa);
+ }
+ kunmap(inompage);
+ }
+
+ /* make sure the index entry is also set to the right state */
+ if (BLOCK_VALID(indexdata, jentry)) {
+ xent = kmap(ixdatapage);
+ if (xent->state != CACHEFS_ONDISC_INDEX_FREE) {
+ xent->state = CACHEFS_ONDISC_INDEX_FREE;
+
+ cachefs_trans_replays_effect(trans, indexdata);
+ }
+ kunmap(ixdatapage);
+ }
+
+ cachefs_block_put(indexdata);
+ cachefs_put_page(ixdatapage);
+ error2:
+ cachefs_block_put(inometa);
+ cachefs_put_page(inompage);
+ error:
+ kleave(" = %d", ret);
+ return ret;
} /* end cachefs_replay_ujnl_inode_mark_reclaim() */
/*****************************************************************************/
/*
- *
+ * replay the initiation of inode reclamation
*/
static int cachefs_replay_ujnl_inode_reclaiming(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans)
{
- return -ENOANO;
+ kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+
+ /* nothing needs to be done here - it's all handled implicitly by the
+ * caller */
+ return 0;
+
} /* end cachefs_replay_ujnl_inode_reclaiming() */
/*****************************************************************************/
/*
- *
+ * replay the extension of an index file
*/
static int cachefs_replay_ujnl_index_extending(struct cachefs_super *super,
struct cachefs_ondisc_update_journal *jentry,
struct cachefs_transaction *trans)
{
- return -ENOANO;
-} /* end cachefs_replay_ujnl_index_extending() */
+
-/*****************************************************************************/
-/*
- *
- */
-static int cachefs_replay_ujnl_index_creating(struct cachefs_super *super,
- struct cachefs_ondisc_update_journal *jentry,
- struct cachefs_transaction *trans)
-{
return -ENOANO;
-} /* end cachefs_replay_ujnl_index_creating() */
+} /* end cachefs_replay_ujnl_index_extending() */
/*****************************************************************************/
/*
Index: recycling.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/recycling.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- recycling.c 9 Jul 2003 10:39:50 -0000 1.25
+++ recycling.c 10 Jul 2003 14:21:24 -0000 1.26
@@ -481,6 +481,7 @@
static int cachefs_recycle_reclaim_inode_metadata(struct cachefs_super *super)
{
struct cachefs_ondisc_index_entry *xent;
+ struct cachefs_ondisc_ujnl_index *jindex;
struct cachefs_ondisc_metadata *metadata;
struct cachefs_transaction *trans = NULL;
struct cachefs_inode *iinode = NULL;
@@ -519,37 +520,44 @@
if (!trans)
goto error;
+ jindex = &trans->jentry->ixdata[0];
+ jindex->next_ino = UINT_MAX;
+ jindex->next_index = UINT_MAX;
+
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INODE_DELETING;
- trans->jentry->index = iino;
- trans->jentry->ixentry = ixentry;
trans->jentry->ino = super->rcm_ino;
- trans->jentry->entry = offset;
-
- if (ixpage) {
- trans->jentry->pgnum = ixpage->index;
- trans->jentry->block = __cachefs_get_page_block(ixpage)->bix;
- }
if (iinode) {
- trans->jentry->size = iinode->vfs_inode.i_size;
- trans->jentry->count = iinode->index_esize;
+ trans->jentry->index = iino;
+ trans->jentry->ixentry = ixentry;
+ trans->jentry->pgnum = ixpage->index;
+ trans->jentry->block =
+ __cachefs_get_page_block(ixpage)->bix;
+ trans->jentry->entry = offset;
+ trans->jentry->upblock = iinode->metadata->bix;
+ trans->jentry->upentry = iinode->metadata_offset;
+ trans->jentry->size = iinode->vfs_inode.i_size;
+ trans->jentry->count = iinode->index_dsize;
metadata = cachefs_metadata_preread(iinode);
- trans->jentry->upblock = metadata->freelink;
+ jindex->next_index = metadata->freelink;
cachefs_metadata_postread(iinode);
cachefs_trans_affects_page(trans,
__cachefs_page_get_private(ixpage),
- offset,
- iinode->index_esize);
+ trans->jentry->entry,
+ trans->jentry->count);
cachefs_trans_affects_inode(trans, iinode);
}
metadata = cachefs_metadata_preread(super->imetadata);
- trans->jentry->auxblock = metadata->freelink;
+ jindex->next_ino = metadata->freelink;
cachefs_metadata_postread(super->imetadata);
+ trans->jentry->auxblock = super->rcm_inode->metadata->bix;
+ trans->jentry->auxentry = super->rcm_inode->metadata_offset;
+
cachefs_trans_affects_inode(trans, super->rcm_inode);
cachefs_trans_affects_inode(trans, super->imetadata);
@@ -563,14 +571,15 @@
xent = kmap(ixpage) + offset;
xent->state = CACHEFS_ONDISC_INDEX_FREE;
+ xent->type = 0;
xent->ino = 0;
- xent->freelink[0] = trans->jentry->upblock;
+ xent->freelink[0] = jindex->next_index;
memset(xent->data, 0, iinode->index_dsize);
kunmap(ixpage);
/* modify the index inode metadata entry */
metadata = cachefs_metadata_prewrite(iinode);
- metadata->freelink = ixentry;
+ metadata->freelink = ixentry;
cachefs_metadata_postwrite(iinode);
}
@@ -579,7 +588,7 @@
memset(metadata, 0, sizeof(super->imetadata->index_esize));
metadata->header.state = CACHEFS_ONDISC_INDEX_FREE;
- metadata->freelink = trans->jentry->auxblock;
+ metadata->freelink = jindex->next_ino;
metadata->mtime = CURRENT_TIME.tv_sec;
metadata->atime = CURRENT_TIME.tv_sec;
cachefs_metadata_postwrite(super->rcm_inode);
@@ -654,12 +663,12 @@
again:
indirect++;
- /* clear out then entries in an index */
+ /* iterate through an index clearing out the entries it contains */
if (indirect == 1) {
if (super->rcm_inode->index_dsize == 0)
goto again;
- if (cachefs_index_zap(super) < 0)
+ if (cachefs_index_reclaim_one_entry(super) < 0)
goto error2;
goto again;
}
@@ -780,7 +789,7 @@
goto again;
}
error2:
- kleave(" [error %d]", ret);
+ kdebug("[error %d]", ret);
goto set;
} /* end cachefs_recycle_reclaim_inode() */
Index: journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/journal.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- journal.c 9 Jul 2003 10:39:50 -0000 1.39
+++ journal.c 10 Jul 2003 14:21:24 -0000 1.40
@@ -104,6 +104,8 @@
_enter("");
+ BUG_ON(super->dmn_die > 0);
+
trans = kmalloc(sizeof(struct cachefs_transaction), gfp);
if (!trans) {
_leave(" = 0 [ENOMEM]");
@@ -277,6 +279,8 @@
*/
down_read(&super->batch_ctrl_sem);
+ BUG_ON(super->dmn_die > 0);
+
/* make sure any changes we make to memory don't end up on disc just
* yet, either:
* (1) wait for the page to be written back to disc, or:
@@ -1138,13 +1142,20 @@
_enter("");
- /* see if any blocks are ready to be cleaned up */
+ /* see if any blocks are ready to be cleaned up
+ * - note the checks made on the three queues must be done atomically
+ * or else list_move_tail() may cause a problem by having a node in
+ * transit
+ */
try_again:
+ spin_lock_irqsave(&super->batch_qlock, flags);
+
if (list_empty(&super->batch_writeq))
wait = 0;
if (list_empty(&super->batch_doneq) &&
list_empty(&super->batch_errorq)) {
+ spin_unlock_irqrestore(&super->batch_qlock, flags);
if (!wait) {
_leave(" [nothing]");
return;
@@ -1161,6 +1172,8 @@
remove_wait_queue(&super->batch_done_wq, &myself);
set_current_state(TASK_RUNNING);
+
+ spin_lock_irqsave(&super->batch_qlock, flags);
}
if (wait == 1)
@@ -1168,8 +1181,6 @@
/* clean up as many blocks as we can */
error = 0;
-
- spin_lock_irqsave(&super->batch_qlock, flags);
if (!list_empty(&super->batch_errorq)) {
list_splice_init(&super->batch_errorq, &myblocks);
Index: interface.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/interface.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- interface.c 9 Jul 2003 10:39:50 -0000 1.15
+++ interface.c 10 Jul 2003 14:21:24 -0000 1.16
@@ -211,7 +211,11 @@
}
spin_unlock(&super->ino_list_lock);
- /* mark all active blocks a being withdrawn */
+ /* make sure all pages pinned by operations on behalf of the netfs are
+ * written to disc */
+ cachefs_trans_sync(super, CACHEFS_TRANS_SYNC_WAIT_FOR_ACK);
+
+ /* mark all active blocks as being withdrawn */
cachefs_block_withdraw(super);
/* we now have to destroy all the active inodes pertaining to this
@@ -648,7 +652,6 @@
return;
}
}
-
}
/* if no parent cookie, then don't create one here either */
@@ -1278,7 +1281,10 @@
pageio->flags = 0;
write_unlock(&pageio->lock);
- BUG_ON(block->ref != pageio);
+ if (unlikely(block->ref != pageio)) {
+ printk("%p != %p", block->ref, pageio);
+ BUG();
+ }
/* locking order needs to be reversed */
write_lock(&block->ref_lock);
Index: index.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/index.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- index.c 9 Jul 2003 10:39:50 -0000 1.26
+++ index.c 10 Jul 2003 14:21:24 -0000 1.27
@@ -58,6 +58,8 @@
_enter(",{%lx},%u,%u,%u", ixpage->index, ixentry, ixoffset, ino);
+ kdebug("SEARCH/DELETE %u", ino);
+
super = ixpage->mapping->host->i_sb->s_fs_info;
ret = cachefs_iget(super, ino, &inode);
@@ -66,6 +68,8 @@
return;
}
+ BUG_ON(!list_empty(&inode->cookie_link));
+
ret = -ENOMEM;
trans = cachefs_trans_alloc(super, GFP_KERNEL);
if (!trans)
@@ -76,10 +80,10 @@
trans->jentry->index = rec->iinode->vfs_inode.i_ino;
trans->jentry->ixentry = ixentry;
trans->jentry->pgnum = ixpage->index;
- trans->jentry->block = inode->metadata->bix;
- trans->jentry->entry = inode->metadata_offset;
- trans->jentry->upblock = __cachefs_get_page_block(ixpage)->bix;
- trans->jentry->upentry = ixoffset;
+ trans->jentry->block = __cachefs_get_page_block(ixpage)->bix;
+ trans->jentry->entry = ixoffset;
+ trans->jentry->auxblock = inode->metadata->bix;
+ trans->jentry->auxentry = inode->metadata_offset;
cachefs_trans_affects_page(trans, __cachefs_page_get_private(ixpage),
ixoffset, sizeof(*xent));
@@ -535,8 +539,8 @@
struct cachefs_cookie *cookie,
unsigned *_newino)
{
- struct cachefs_ondisc_ujnl_index *jindex;
struct cachefs_ondisc_index_entry *xent;
+ struct cachefs_ondisc_ujnl_index *jindex;
struct cachefs_ondisc_metadata *metadata;
struct cachefs_search_result *srch;
struct cachefs_transaction *trans;
@@ -578,6 +582,9 @@
offset = (ixentry % index->index_epp) * index->index_esize;
+ ino_offset = ino % super->imetadata->index_epp;
+ ino_offset <<= super->layout->metadata_bits;
+
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INDEX_CREATING;
if (!cookie->idef)
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INODE_CREATING;
@@ -590,11 +597,13 @@
trans->jentry->block = __cachefs_get_page_block(ixpage)->bix;
trans->jentry->entry = offset;
trans->jentry->count = index->index_esize;
- trans->jentry->auxblock = inonext;
- trans->jentry->upblock = ixnext;
+ trans->jentry->auxblock = __cachefs_get_page_block(inopage)->bix;
+ trans->jentry->auxentry = ino_offset;
+ trans->jentry->upblock = index->metadata->bix;
+ trans->jentry->upentry = index->metadata_offset;
- ino_offset = ino % super->imetadata->index_epp;
- ino_offset <<= super->layout->metadata_bits;
+ jindex->next_ino = inonext;
+ jindex->next_index = ixnext;
cachefs_trans_affects_page(trans, __cachefs_page_get_private(ixpage),
offset, index->index_esize);
@@ -646,7 +655,7 @@
if (cookie->idef)
xent->type = CACHEFS_ONDISC_INDEX_INDEXFILE;
- memcpy(xent->data, jindex->data, jindex->def.dsize);
+ memcpy(xent->data, jindex->data, index->index_dsize);
kunmap(ixpage);
@@ -707,7 +716,7 @@
* mark the next inode pinned by an entry in the index currently being
* reclaimed as being obsolete
*/
-int cachefs_index_zap(struct cachefs_super *super)
+int cachefs_index_reclaim_one_entry(struct cachefs_super *super)
{
struct cachefs_ondisc_index_entry *xent;
struct cachefs_ondisc_metadata *metadata;
@@ -760,6 +769,11 @@
trans->jentry->ino = inode->vfs_inode.i_ino;
trans->jentry->index = super->rcm_ino;
trans->jentry->ixentry = super->rcm_block;
+ trans->jentry->pgnum = page->index;
+ trans->jentry->block = __cachefs_get_page_block(page)->bix;
+ trans->jentry->entry = offset;
+ trans->jentry->auxblock = inode->metadata->bix;
+ trans->jentry->auxentry = inode->metadata_offset;
cachefs_trans_affects_inode(trans, inode);
@@ -807,4 +821,4 @@
_leave(" = %d", ret);
return ret;
-} /* end cachefs_index_zap() */
+} /* end cachefs_index_reclaim_one_entry() */
Index: dump-journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/dump-journal.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- dump-journal.c 9 Jul 2003 10:39:50 -0000 1.13
+++ dump-journal.c 10 Jul 2003 14:21:24 -0000 1.14
@@ -169,7 +169,7 @@
" " CYAN "%5u" GREY "." NORMAL "%-5u" NORMAL
" " "%s" " %4d"
" " YELLOW "%8x" NORMAL " %8u"
- " " YELLOW "%8u" GREY ":" NORMAL "%-4hu"
+ " " YELLOW "%8x" GREY ":" NORMAL "%-4hu"
" " YELLOW "%8d" GREY "+" NORMAL "%-4hu"
" " YELLOW "%8d" GREY "+" NORMAL "%-4hu"
" " YELLOW "%8d" GREY "+" NORMAL "%-4hu"
Index: cachefs-layout.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-layout.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- cachefs-layout.h 9 Jul 2003 10:39:50 -0000 1.29
+++ cachefs-layout.h 10 Jul 2003 14:21:24 -0000 1.30
@@ -248,19 +248,46 @@
* - block = block holding index entry being allocated
* - entry = offset of entry in block
* - ino = inode being attached to hold index contents
- * - upblock = next free index file entry
- * - count = size of entry in block
+ * - auxblock = metadata file block holding inode metadata
+ * - auxentry = offset of entry in auxblock
+ * - upblock = metadata file block holding index metadata
+ * - upentry = offset of entry in upblock
+ * - count = size of index entry in block
+ * - ixdata = index data
+ * - next_ino = next free metadata file entry
+ * - next_index = next free index file entry
*/
CACHEFS_ONDISC_UJNL_INODE_CREATING,
/* data file being updated */
CACHEFS_ONDISC_UJNL_INODE_UPDATING,
- /* data or index file being deleted */
+ /* data or index file being deleted
+ * - index = parent index being attached to [opt]
+ * - ixentry = entry in parent index [opt]
+ * - pgnum = page in file holding index entry being allocated [opt]
+ * - block = block holding index entry being allocated [opt]
+ * - entry = offset of entry in block [opt]
+ * - ino = inode being attached to hold index contents
+ * - auxblock = metadata file block holding inode metadata
+ * - auxentry = offset of entry in auxblock
+ * - upblock = metadata file block holding index metadata [opt]
+ * - upentry = offset of entry in upblock [opt]
+ * - count = size of index entry in block [opt]
+ * - next_ino = next free metadata file entry
+ * - next_index = next free index file entry [opt]
+ */
CACHEFS_ONDISC_UJNL_INODE_DELETING,
/* inode being marked for reclamation
* - ino = target inode
+ * - index = inode's parent index
+ * - ixentry = inode's parent index entry
+ * - pgnum = page in index holding entry being marked
+ * - block = metadata file block holding index metadata
+ * - entry = offset of entry in upblock
+ * - auxblock = metadata file block holding inode metadata
+ * - auxentry = offset of entry in auxblock
*/
CACHEFS_ONDISC_UJNL_INODE_MARK_RECLAIM,
@@ -268,6 +295,11 @@
* - ino = target inode
* - index = inode's parent index
* - ixentry = inode's parent index entry
+ * - pgnum = page in index holding entry being marked
+ * - block = metadata file block holding index metadata
+ * - entry = offset of entry in upblock
+ * - auxblock = metadata file block holding inode metadata
+ * - auxentry = offset of entry in auxblock
*/
CACHEFS_ONDISC_UJNL_INODE_RECLAIMING,
@@ -337,8 +369,14 @@
* - block = block holding index entry being allocated
* - entry = offset of entry in block
* - ino = inode being attached to hold index contents
- * - upblock = next free index file entry
- * - count = size of entry in block
+ * - auxblock = metadata file block holding inode metadata
+ * - auxentry = offset of entry in auxblock
+ * - upblock = metadata file block holding index metadata
+ * - upentry = offset of entry in upblock
+ * - count = size of index entry in block
+ * - ixdata = index definition and data
+ * - next_ino = next free metadata file entry
+ * - next_index = next free index file entry
*/
CACHEFS_ONDISC_UJNL_INDEX_CREATING,
@@ -349,6 +387,7 @@
* - block = block holding index entry being allocated
* - entry = offset of entry in block
* - count = size of entry in block
+ * - ixdata = revised index data
*/
CACHEFS_ONDISC_UJNL_INDEX_UPDATING,
@@ -357,6 +396,8 @@
struct cachefs_ondisc_ujnl_index {
struct cachefs_ondisc_index_def def;
+ u_int32_t next_ino; /* next inode entry */
+ u_int32_t next_index; /* next index entry */
u_int8_t data[0];
};
Index: cachefs-int.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-int.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- cachefs-int.h 9 Jul 2003 10:39:50 -0000 1.38
+++ cachefs-int.h 10 Jul 2003 14:21:24 -0000 1.39
@@ -451,7 +451,7 @@
struct cachefs_cookie *cookie,
unsigned *_newino);
-extern int cachefs_index_zap(struct cachefs_super *super);
+extern int cachefs_index_reclaim_one_entry(struct cachefs_super *super);
/*****************************************************************************/
/*
Index: block.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/block.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- block.c 4 Jul 2003 09:04:44 -0000 1.8
+++ block.c 10 Jul 2003 14:21:24 -0000 1.9
@@ -435,6 +435,8 @@
*_block = NULL;
+ BUG_ON(bix > super->sb->s_bdev->bd_inode->i_size / PAGE_SIZE);
+
/* allocate a block record just in case */
newblock = kmem_cache_alloc(cachefs_block_jar, SLAB_KERNEL);
if (!newblock)
More information about the linux-afs-cvs
mailing list