afs/fs/cachefs replay.c,1.4,1.5 journal.c,1.42,1.43
dump-journal.c,1.18,1.19 block.c,1.9,1.10
dwh at infradead.org
dwh at infradead.org
Fri Sep 12 11:52:41 BST 2003
Update of /home/cvs/afs/fs/cachefs
In directory phoenix.infradead.org:/tmp/cvs-serv32242/fs/cachefs
Modified Files:
replay.c journal.c dump-journal.c block.c
Log Message:
u-journal replaying now basically works
Index: replay.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/replay.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- replay.c 13 Aug 2003 10:05:28 -0000 1.4
+++ replay.c 12 Sep 2003 09:52:38 -0000 1.5
@@ -127,9 +127,12 @@
struct cachefs_replay_find_batch_desc,
desc);
- _enter("{%x},{%lu},%lu,%lu",
+ _enter("{%zx},{%lu},%lu,%lu",
desc->desc.count, page->index, offset, size);
+ if (size > desc->desc.count)
+ size = desc->desc.count;
+
BUG_ON(size != PAGE_SIZE);
BUG_ON(offset != 0);
@@ -284,7 +287,10 @@
unsigned long stop;
void *data;
- kenter("{%x},{%lu},%lu,%lu", desc->count, page->index, offset, size);
+ kenter("{%zx},{%lu},%lu,%lu", desc->count, page->index, offset, size);
+
+ if (size > desc->count)
+ size = desc->count;
BUG_ON(offset % super->layout->ujnl_rsize);
BUG_ON(size % super->layout->ujnl_rsize);
@@ -344,7 +350,10 @@
unsigned long stop;
void *data;
- kenter("{%x},{%lu},%lu,%lu", desc->count, page->index, offset, size);
+ kenter("{%zx},{%lu},%lu,%lu", desc->count, page->index, offset, size);
+
+ if (size > desc->count)
+ size = desc->count;
BUG_ON(offset % super->layout->ujnl_rsize);
BUG_ON(size % super->layout->ujnl_rsize);
@@ -378,6 +387,7 @@
if (replay) {
desc->error = replay(super, jentry, trans);
if (desc->error < 0) {
+ trans->phase = CACHEFS_TRANS_DEAD;
cachefs_trans_put(trans);
break;
}
@@ -419,6 +429,8 @@
read_descriptor_t desc;
loff_t ppos;
+ kenter("{%hx-%hx},,", super->ujnl_head, super->ujnl_tail);
+
if (super->ujnl_head < super->ujnl_tail) {
memset(&desc, 0, sizeof(desc));
desc.count = CACHEFS_ONDISC_UJNL_NUMENTS - super->ujnl_tail;
@@ -499,29 +511,31 @@
return find_batch.desc.error;
}
- kdebug("UJNL: last batch=%d { s=%u f=%u b=%u a=%u }",
+ kdebug("UJNL: last batch=%d { s=%u #=%u f=%u b=%u a=%u }",
super->ujnl_batch,
super->ujnl_serial,
+ find_batch.batch_count,
find_batch.batch_first,
find_batch.batch_end,
find_batch.batch_ack);
- if (find_batch.batch_end == ~0u || find_batch.batch_ack == ~0u) {
- if (find_batch.batch_first == ~0u) {
+ if (find_batch.batch_end == (unsigned short) ~0u ||
+ find_batch.batch_ack == (unsigned short) ~0u) {
+ if (find_batch.batch_first == (unsigned short) ~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) {
+ if (find_batch.batch_ack != (unsigned short) ~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) {
+ if (find_batch.batch_count != super->ujnl_serial + 1) {
clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
printk("CacheFS: corrupted journal:"
" ujnl batch has missing marks\n");
@@ -530,10 +544,11 @@
/* 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);
+ super->ujnl_head = UJNL_WRAP(find_batch.batch_end + 1);
+
+ printk("CacheFS: Need to replay update journal t=%hu h=%hu\n",
+ super->ujnl_tail, super->ujnl_head);
ret = cachefs_ujnl_replay_aux(
super, &ra, cachefs_ujnl_determine_overlap_actor);
@@ -558,18 +573,22 @@
}
/* write all blocks that are marked for writeback */
+ kdebug("write back pages touched by replay");
cachefs_trans_batch_write(super);
+ super->ujnl_head = super->ujnl_tail;
printk("CacheFS: Finished replaying update journal\n");
}
+ else {
+ super->ujnl_head = UJNL_WRAP(find_batch.batch_ack + 1);
+ super->ujnl_tail = super->ujnl_head;
+ }
clear_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags);
kdebug("reload_tracking");
super->ujnl_batch++;
super->ujnl_serial = 0;
- super->ujnl_head = UJNL_WRAP(find_batch.batch_ack + 1);
- super->ujnl_tail = super->ujnl_head;
kdebug("UJNL slot window: next head=%hu tail=%hu",
super->ujnl_head, super->ujnl_tail);
@@ -655,7 +674,7 @@
{
int ix = trans->eff_active;
- _enter("%p{efa=%d},{%u}", trans, ix, block->bix);
+ kenter("%p{efa=%d},{%u}", trans, ix, block->bix);
get_page(block->page);
@@ -678,7 +697,7 @@
struct page *page;
int ret;
- kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+ _enter(",{%hd.%hu}", jentry->batch, jentry->serial);
ret = cachefs_block_read(super, NULL, jentry->block, 0, &block, &page);
if (ret < 0)
@@ -699,7 +718,7 @@
cachefs_put_page(page);
error:
- kleave(" = %d", ret);
+ _leave(" = %d", ret);
return ret;
} /* end cachefs_replay_ujnl_recyc_begin_new() */
@@ -717,7 +736,7 @@
struct page *page;
int ret;
- kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+ _enter(",{%hd.%hu}", jentry->batch, jentry->serial);
ret = 0;
/* we need to break the link from the recycling stack TOS to the new
@@ -744,7 +763,7 @@
}
error:
- kleave(" = %d", ret);
+ _leave(" = %d", ret);
return ret;
} /* end cachefs_replay_ujnl_recyc_transfer() */
@@ -817,12 +836,13 @@
struct cachefs_ondisc_superblock *layout;
struct cachefs_ondisc_free_node *node;
struct cachefs_block *block, *superblock;
+ cachefs_blockix_t bix;
struct page *page, *spage;
- int ret;
+ int loop, changed, ret;
- kenter(",{%hd.%hu}", jentry->batch, jentry->serial);
+ _enter(",{%hd.%hu}", jentry->batch, jentry->serial);
- ret = cachefs_block_read(super, NULL, jentry->auxblock, 0,
+ ret = cachefs_block_read(super, NULL, jentry->block, 0,
&block, &page);
if (ret < 0)
goto error;
@@ -833,8 +853,8 @@
ret = -EINVAL;
if (jentry->entry >= CACHEFS_ONDISC_LEAVES_PER_FREE_NODE ||
- jentry->entry + jentry->count >=
- CACHEFS_ONDISC_LEAVES_PER_FREE_NODE) {
+ jentry->entry + jentry->count > CACHEFS_ONDISC_LEAVES_PER_FREE_NODE
+ ) {
printk("CacheFS:"
" UJNL MakeReady entry specifies out-of-range"
" dest window\n");
@@ -844,8 +864,8 @@
/* we need to make sure the superblock keeps track of the top of the
* ready area */
layout = kmap(spage);
- if (layout->bix_ujournal < jentry->pgnum) {
- layout->bix_ujournal = jentry->pgnum;
+ if (layout->bix_unready < jentry->pgnum) {
+ layout->bix_unready = jentry->pgnum;
cachefs_trans_replays_effect(trans, superblock);
}
kunmap(spage);
@@ -854,15 +874,17 @@
if (BLOCK_VALID(block, page, jentry)) {
node = kmap(page);
- if (memcmp(&node->leaves[jentry->auxblock],
- &jentry->rcyptrs[0],
- jentry->count * sizeof(cachefs_blockix_t)
- ) != 0) {
- memcpy(&node->leaves[jentry->auxblock],
- &jentry->rcyptrs[0],
- jentry->count * sizeof(cachefs_blockix_t));
- cachefs_trans_replays_effect(trans, block);
+ changed = 0;
+ bix = jentry->auxblock;
+ for (loop = 0; loop < jentry->count; loop++, bix++) {
+ if (node->leaves[loop] != bix) {
+ changed = 1;
+ node->leaves[loop] = bix;
+ }
}
+
+ if (changed)
+ cachefs_trans_replays_effect(trans, block);
kunmap(page);
}
@@ -875,7 +897,7 @@
cachefs_block_put(block);
cachefs_put_page(page);
error:
- kleave(" = %d", ret);
+ _leave(" = %d", ret);
return ret;
} /* end cachefs_replay_ujnl_recyc_makeready() */
Index: journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/journal.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- journal.c 18 Jul 2003 08:54:58 -0000 1.42
+++ journal.c 12 Sep 2003 09:52:38 -0000 1.43
@@ -159,6 +159,9 @@
trans->phase = CACHEFS_TRANS_MARKED;
trans->index = 0;
+ atomic_inc(&super->cnt_ujnl_mkrq);
+ atomic_inc(&super->cnt_ujnl_mkgr);
+
_leave(" = %p", trans);
return trans;
} /* end cachefs_trans_alloc_replay() */
@@ -539,6 +542,9 @@
int loop;
if (!trans->eff_active) {
+ cachefs_ujnl_set_phase(trans,
+ CACHEFS_TRANS_DEAD,
+ CACHEFS_TRANS_MARKED);
cachefs_trans_put(trans);
return;
}
@@ -561,20 +567,26 @@
* - mark all modified journalling and data blocks for writeback
* - mark data for COW
*/
-static inline
+static
void cachefs_trans_batch_write_prep_trans(struct cachefs_super *super,
struct cachefs_transaction *trans)
{
struct cachefs_block *block;
int loop;
+ _enter("");
+
/* mark u-journal page */
- block = trans->jblock;
- if (!test_and_set_bit(CACHEFS_BLOCK_WRITEBACK, &block->flags)) {
- list_add_tail(&block->batch_link, &super->batch_writeq);
- block->writeback = block->page;
- get_page(block->writeback);
- flush_dcache_page(block->writeback);
+ if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags)) {
+ block = trans->jblock;
+ if (!test_and_set_bit(CACHEFS_BLOCK_WRITEBACK, &block->flags)
+ ) {
+ list_add_tail(&block->batch_link,
+ &super->batch_writeq);
+ block->writeback = block->page;
+ get_page(block->writeback);
+ flush_dcache_page(block->writeback);
+ }
}
/* mark data blocks */
@@ -615,13 +627,17 @@
struct cachefs_ondisc_update_journal *ajentry;
struct cachefs_transaction *trans;
struct cachefs_block *block;
- struct list_head *_p;
unsigned short jstop;
unsigned long flags;
_enter("");
+ /* permit cachefs_trans_sync() to detect end of batch write */
down(&super->batch_sem);
+
+ /* prevent critical blocks from being reused for netfs data caching
+ * - normally released by cachefs_trans_marker_written()
+ */
down(&super->batch_uj_sem);
spin_lock_irqsave(&super->ujnl_mk_lock, flags);
@@ -637,8 +653,7 @@
BUG_ON(!list_empty(&super->ujnl_markq));
- list_for_each(_p, &super->ujnl_commitq) {
- trans = list_entry(_p, struct cachefs_transaction, sblink);
+ list_for_each_entry(trans, &super->ujnl_commitq, sblink) {
cachefs_trans_batch_write_prep_trans(super, trans);
}
@@ -646,9 +661,7 @@
list_splice_init(&super->ujnl_commitq, &super->ujnl_writeq);
spin_unlock_irqrestore(&super->ujnl_mk_lock, flags);
- list_for_each(_p, &super->batch_writeq) {
- block = list_entry(_p, struct cachefs_block, batch_link);
-
+ list_for_each_entry(block, &super->batch_writeq, batch_link) {
_debug(" >>> block %05u fl=%04lx pg=%p wb=%p",
block->bix, block->flags, block->page,
block->writeback);
@@ -690,12 +703,15 @@
if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags))
cachefs_trans_batch_write_marker(super, jstop, ajentry);
+ else
+ up(&super->batch_uj_sem);
cachefs_trans_batch_write_data(super);
cachefs_trans_batch_process_written_blocks(super, 2);
/* polish off with an ACK */
- jstop = UJNL_WRAP(jstop + 1);
+ if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags))
+ jstop = UJNL_WRAP(jstop + 1);
ajentry->mark = CACHEFS_ONDISC_UJNL_ACK;
ajentry->serial++;
@@ -703,7 +719,7 @@
cachefs_trans_batch_write_ack(super, jstop, ajentry);
kfree(ajentry);
- super->ujnl_tail = UJNL_WRAP(super->ujnl_tail + 2);
+ super->ujnl_tail = UJNL_WRAP(jstop + 1);
/* clean up the transactions that we've now written */
while (!list_empty(&super->ujnl_writeq)) {
@@ -722,6 +738,7 @@
wake_up_all(&super->batch_sync_wq);
+ _leave("");
} /* end cachefs_trans_batch_write() */
/*****************************************************************************/
@@ -1109,6 +1126,10 @@
BUG();
//dump_bio(bio,1);
+
+#if 0
+ BUG(); /* TODO: remove (for replay testing) */
+#endif
submit_bio(WRITE | (1 << BIO_RW_BARRIER), bio);
Index: dump-journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/dump-journal.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- dump-journal.c 10 Sep 2003 14:57:12 -0000 1.18
+++ dump-journal.c 12 Sep 2003 09:52:38 -0000 1.19
@@ -16,6 +16,7 @@
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <stdint.h>
#include "cachefs-layout.h"
@@ -70,6 +71,7 @@
struct cachefs_ondisc_superblock *super;
struct sector *ujournal;
struct stat st;
+ const char *markname;
unsigned numujnl, jsof;
int devfd, loop, delta;
@@ -164,6 +166,13 @@
if (jentry->mark == CACHEFS_ONDISC_UJNL_NULL)
continue;
+ if (jentry->mark >=
+ sizeof(cachefs_ondisc_ujnl_marks) /
+ sizeof(cachefs_ondisc_ujnl_marks[0]))
+ markname = BP_RED "?????????" NORMAL;
+ else
+ markname = cachefs_ondisc_ujnl_marks[jentry->mark];
+
printf("%s%4u" NORMAL
" " CYAN "%5u" GREY "." NORMAL "%-5u" NORMAL
" " "%s" " %4d"
@@ -181,7 +190,7 @@
loop&7 ? NORMAL : GREEN,
loop,
jentry->batch, jentry->serial,
- cachefs_ondisc_ujnl_marks[jentry->mark],jentry->auxmark,
+ markname ,jentry->auxmark,
jentry->ino, jentry->pgnum,
jentry->index, jentry->ixentry,
jentry->block, jentry->entry,
Index: block.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/block.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- block.c 10 Jul 2003 14:21:24 -0000 1.9
+++ block.c 12 Sep 2003 09:52:38 -0000 1.10
@@ -431,11 +431,15 @@
struct rb_node *parent, **p;
unsigned long flags;
- _enter(",%u,",bix);
+ _enter(",%u,", bix);
*_block = NULL;
- BUG_ON(bix > super->sb->s_bdev->bd_inode->i_size / PAGE_SIZE);
+ if (bix > super->sb->s_bdev->bd_inode->i_size / PAGE_SIZE) {
+ printk("CacheFS: trying to insert out of range block %x/%Lx\n",
+ bix, super->sb->s_bdev->bd_inode->i_size / PAGE_SIZE);
+ BUG();
+ }
/* allocate a block record just in case */
newblock = kmem_cache_alloc(cachefs_block_jar, SLAB_KERNEL);
More information about the linux-afs-cvs
mailing list