afs/fs/cachefs vjournal.c,1.4,1.5 rootdir.c,1.15,1.16
recycling.c,1.28,1.29 journal.c,1.40,1.41 index.c,1.28,1.29
dump-journal.c,1.14,1.15 cachefs-layout.h,1.31,1.32aops.c,1.43,1.44
dwh at infradead.org
dwh at infradead.org
Thu Jul 17 14:02:15 BST 2003
Update of /home/cvs/afs/fs/cachefs
In directory phoenix.infradead.org:/tmp/cvs-serv22848/fs/cachefs
Modified Files:
vjournal.c rootdir.c recycling.c journal.c index.c
dump-journal.c cachefs-layout.h aops.c
Log Message:
improve/debug reclaimation and recycling and allocation stack tracking
Index: vjournal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/vjournal.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- vjournal.c 4 Jul 2003 09:04:43 -0000 1.4
+++ vjournal.c 17 Jul 2003 12:02:13 -0000 1.5
@@ -225,6 +225,7 @@
if (ret < 0)
goto error_free;
+ wait_on_page_locked(vjentry->vpage);
cachefs_block_modify(super, vjentry->vblock, &vjentry->vpage);
memset(kmap(vjentry->vpage) + vjentry->ventry, 0,
sizeof(struct cachefs_ondisc_validity_journal));
Index: rootdir.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/rootdir.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- rootdir.c 17 Jul 2003 08:49:39 -0000 1.15
+++ rootdir.c 17 Jul 2003 12:02:13 -0000 1.16
@@ -681,9 +681,10 @@
BUG_ON(trans->jentry->index != dir->i_ino);
- trans->jentry->pgnum = trans->jentry->index / index->index_epp;
+ trans->jentry->pgnum = trans->jentry->ixentry / index->index_epp;
trans->jentry->entry =
- (trans->jentry->index % index->index_epp) * index->index_esize;
+ (trans->jentry->ixentry % index->index_epp) *
+ index->index_esize;
ret = cachefs_get_page(index, trans->jentry->pgnum, &ixpage);
if (ret < 0) {
Index: recycling.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/recycling.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- recycling.c 16 Jul 2003 11:19:39 -0000 1.28
+++ recycling.c 17 Jul 2003 12:02:13 -0000 1.29
@@ -78,14 +78,23 @@
}
trans->jentry->mark = CACHEFS_ONDISC_UJNL_RECYC_BEGIN_NEW;
+ trans->jentry->index = super->recycle_cur;
+ trans->jentry->ixentry = super->recycle_cur_n;
trans->jentry->block = bix;
- trans->jentry->auxblock = super->recycle_cur;
trans->jentry->upblock = upblock;
trans->jentry->upentry = upentry;
trans->jentry->pgnum =
super->layout->bix_unready + used_unready_node;
+ trans->changed |= CACHEFS_TRANS_CHANGED_RECYCLE;
+ trans->jentry->recycle_cur = bix;
+
+ if (upblock) {
+ trans->changed |= CACHEFS_TRANS_CHANGED_RCMPTR;
+ trans->jentry->rcm_ptrnext = upentry;
+ }
+
/* mark the beginning of the operation */
ret = cachefs_trans_mark(trans);
if (ret<0)
@@ -95,12 +104,11 @@
cachefs_block_modify(super, block, &page);
node = (struct cachefs_ondisc_free_node *) kmap(page);
- node->next = super->recycle_cur;
- node->count = super->recycle_cur_n;
+ node->next = trans->jentry->index;
+ node->count = trans->jentry->ixentry;
kunmap(page);
- super->recycle_cur = bix;
- super->recycle_room = CACHEFS_ONDISC_LEAVES_PER_FREE_NODE;
+ super->recycle_room = CACHEFS_ONDISC_LEAVES_PER_FREE_NODE;
page = xchg(&super->recycle_node, page);
block = xchg(&super->recycle_block, block);
@@ -250,15 +258,17 @@
trans->jentry->mark = CACHEFS_ONDISC_UJNL_RECYC_TRANSFER;
trans->jentry->block = allocTOS;
- super->recycle_cur = 0;
- super->alloc_cur = allocTOS;
- super->alloc_leaf = 0;
+
+ trans->jentry->recycle_cur = 0;
+ trans->jentry->alloc_cur = allocTOS;
+ trans->jentry->alloc_leaf = 0;
+
+ trans->changed |=
+ CACHEFS_TRANS_CHANGED_RECYCLE |
+ CACHEFS_TRANS_CHANGED_ALLOC;
ret = cachefs_trans_mark(trans);
if (ret < 0) {
- super->recycle_cur = allocTOS;
- super->alloc_cur = 0;
- super->alloc_leaf = 0;
printk("CacheFS: failed to mark ujnl: %d\n", ret);
_leave(" [error %d]", ret);
return;
@@ -307,15 +317,12 @@
trans->jentry->block = allocTOS;
trans->jentry->upblock = super->recycle_cur;
- super->recycle_cur = 0;
- super->alloc_cur = allocTOS;
- super->alloc_leaf = 0;
+ trans->jentry->alloc_cur = allocTOS;
+ trans->jentry->alloc_leaf = 0;
+ trans->changed |= CACHEFS_TRANS_CHANGED_ALLOC;
ret = cachefs_trans_mark(trans);
if (ret < 0) {
- super->recycle_cur = allocTOS;
- super->alloc_cur = 0;
- super->alloc_leaf = 0;
printk("CacheFS: failed to mark ujnl: %d\n", ret);
dbgpgfree(page);
page_cache_release(page);
@@ -351,21 +358,21 @@
/*****************************************************************************/
/*
- * recycle the dependents of the block currently in the recycling bin and then
- * recycle the block itself
+ * recycle the dependents of the page currently being reclaimed
*/
-static void cachefs_recycle_pointer_array(struct cachefs_super *super)
+static void cachefs_recycle_pointer_array(struct cachefs_super *super,
+ struct cachefs_transaction **_trans)
{
struct cachefs_ondisc_free_node *node;
struct cachefs_transaction *trans;
struct cachefs_block *block;
cachefs_blockix_t *indirect, *jeptr;
- struct page *page;
unsigned limit, count, src, dst, max;
int ret;
- kenter("{room=%u block=%u:%hu-%hu},",
+ kenter("{room=%u page=%lx block=%x:%hu-%hu},",
super->recycle_room,
+ super->rcm_curpage->index,
super->rcm_block,
super->rcm_ptrnext,
super->rcm_ptrstop);
@@ -374,17 +381,9 @@
max -= sizeof(struct cachefs_ondisc_update_journal);
max /= sizeof(cachefs_blockix_t);
- /* load the pointer block page */
- ret = cachefs_block_read(super, NULL, super->rcm_block, 0,
- NULL, &page);
- if (ret < 0) {
- kleave(" [error %d]", ret);
- return;
- }
-
- wait_on_page_locked(page);
-
- indirect = (cachefs_blockix_t*) kmap(page);
+ ret = 0;
+ wait_on_page_locked(super->rcm_curpage);
+ indirect = (cachefs_blockix_t *) kmap(super->rcm_curpage);
/* find an occupied pointer */
for (src = super->rcm_ptrnext; src < super->rcm_ptrstop; src++)
@@ -397,17 +396,12 @@
found:
/* make sure there's a recycling block with space available */
if (super->recycle_room == 0) {
- /* recycle the first dependent page as the new recycling
- * node */
- super->rcm_ptrnext = src;
ret = cachefs_recycle_begin_new_node(super, indirect[src],
super->rcm_block, src);
goto out;
}
- trans = cachefs_trans_alloc(super, GFP_KERNEL);
- if (!trans)
- goto out;
+ trans = *_trans;
cachefs_trans_affects_block(trans, super->recycle_block, 0, PAGE_SIZE);
@@ -440,14 +434,16 @@
}
trans->jentry->count = count;
+ trans->jentry->rcm_ptrnext = src;
ret = cachefs_trans_mark(trans);
if (ret < 0) {
printk("kcachefsd: Failed to mark journal: %d\n", ret);
- cachefs_trans_put(trans);
goto out;
}
+ *_trans = NULL;
+
super->recycle_room -= count;
super->recycle_cur_n += count;
if (super->recycle_room == 0)
@@ -465,16 +461,10 @@
kunmap(super->recycle_node);
- super->rcm_ptrnext = src;
-
cachefs_trans_commit(trans);
- trans = NULL;
out:
- kunmap(page);
- dbgpgfree(page);
- page_cache_release(page);
-
+ kunmap(super->rcm_curpage);
kleave(" [error %d]", ret);
} /* end cachefs_recycle_pointer_array() */
@@ -487,18 +477,19 @@
* - index entry pointing to inode being reclaimed
* - metadata record of index (we've got a new free index entry)
*/
-static int cachefs_recycle_reclaim_inode_metadata(struct cachefs_super *super)
+static int cachefs_recycle_reclaim_inode_metadata(struct cachefs_super *super,
+ struct cachefs_transaction **_trans)
{
struct cachefs_ondisc_index_entry *xent;
struct cachefs_ondisc_ujnl_index *jindex;
struct cachefs_ondisc_metadata *metadata;
- struct cachefs_transaction *trans = NULL;
+ struct cachefs_transaction *trans;
struct cachefs_inode *iinode = NULL;
struct page *ixpage = NULL;
unsigned iino, ixentry, offset;
int ret;
- kenter("{%u}", super->rcm_ino);
+ kenter("{%x}", super->rcm_ino);
/* find the parent index entry */
metadata = cachefs_metadata_preread(super->rcm_inode);
@@ -524,17 +515,13 @@
}
/* do the release under journalling */
- ret = -ENOMEM;
- trans = cachefs_trans_alloc(super, GFP_KERNEL);
- if (!trans)
- goto error;
+ trans = *_trans;
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->ino = super->rcm_ino;
if (iinode) {
trans->jentry->index = iino;
@@ -570,10 +557,18 @@
cachefs_trans_affects_inode(trans, super->rcm_inode);
cachefs_trans_affects_inode(trans, super->imetadata);
+ trans->jentry->rcm_ino = 0;
+ trans->jentry->rcm_indirect = 0;
+ trans->jentry->rcm_block = 0;
+ trans->jentry->rcm_ptrnext = 0;
+ trans->jentry->rcm_ptrstop = 0;
+
ret = cachefs_trans_mark(trans);
if (ret < 0)
goto error;
+ *_trans = NULL;
+
/* free up the parent index entry */
if (iinode) {
cachefs_page_modify(super, &ixpage);
@@ -604,15 +599,13 @@
/* modify the metadata inode metadata entry */
metadata = cachefs_metadata_prewrite(super->imetadata);
- metadata->freelink = super->rcm_ino;
+ metadata->freelink = trans->jentry->ino;
cachefs_metadata_postwrite(super->imetadata);
/* do the writing */
cachefs_trans_commit(trans);
- trans = NULL;
error:
- cachefs_trans_put(trans);
cachefs_put_page(ixpage);
cachefs_iput(iinode);
@@ -631,175 +624,197 @@
* - update journal keeps track of recycling point
* - rcm_ino, rcm_indirect, rcm_block, rcm_ptrnext & rcm_ptrstop
* - work out which block we're actually dealing with from rcm_indirect:
- * FROM TO WHAT
- * 0 - not started yet
- * 1 - reclaiming index entries
- * 2 - pointers in single indirect block
- * 3 3+N-1 pointers in dblindirect subblocks 0...N-1
- * 3+N - pointers in dblindirect block
- * 3+N+1 - all pointers in inode struct
- * 3+N+2 - inode itself
+ * FROM TO WHAT
+ * 0 - reclaiming index entries
+ * 1 - pointers in single indirect block
+ * 2 2+N-1 pointers in dblindirect subblocks 0...N-1
+ * 2+N - pointers in dblindirect block
+ * 2+N+1 - all pointers in inode struct
+ * 2+N+2 - inode itself
*/
static void cachefs_recycle_reclaim_inode(struct cachefs_super *super)
{
struct cachefs_ondisc_metadata *metadata;
- cachefs_blockix_t bix, *pbix;
- struct page *page, *dpage;
- unsigned indirect;
- unsigned short next, stop;
- int ret, loop;
+ struct cachefs_transaction *trans;
+ struct page *dpage;
+ int ret = 0, loop;
const unsigned N = PAGE_SIZE / sizeof(cachefs_blockix_t);
- kenter("{%u,%u,%u:%hu-%hu}",
+ kenter("{%x,%u,%x:%hu-%hu}",
super->rcm_ino, super->rcm_indirect, super->rcm_block,
super->rcm_ptrnext, super->rcm_ptrstop);
BUG_ON(!super->rcm_ino);
- if (super->rcm_ptrnext == super->rcm_ptrstop && super->rcm_curpage) {
- put_page(super->rcm_curpage);
+ if (super->rcm_ptrnext == super->rcm_ptrstop) {
+ cachefs_put_page(super->rcm_curpage);
super->rcm_curpage = NULL;
}
- indirect = super->rcm_indirect;
- bix = 0;
- next = 0;
- stop = PAGE_SIZE / sizeof(cachefs_blockix_t);
-
- ret = 0;
+ trans = cachefs_trans_alloc(super, GFP_KERNEL);
+ if (!trans) {
+ kleave(" [ENOMEM");
+ return;
+ }
- again:
- indirect++;
+ trans->jentry->ino = super->rcm_ino;
+ trans->jentry->rcm_ino = super->rcm_ino;
+ trans->jentry->rcm_indirect = super->rcm_indirect;
+ trans->jentry->rcm_block = super->rcm_block;
+ trans->jentry->rcm_ptrstop = super->rcm_ptrstop;
+ trans->jentry->rcm_ptrnext = super->rcm_ptrnext;
+
+ trans->changed |=
+ CACHEFS_TRANS_CHANGED_RCMBLOCK |
+ CACHEFS_TRANS_CHANGED_RCMPTR;
/* 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_reclaim_one_entry(super) < 0)
- goto error2;
- goto again;
- }
+ if (trans->jentry->rcm_indirect == 0) {
+ kdebug("-- step 0.%u", trans->jentry->rcm_block);
+
+ if (super->rcm_inode->index_dsize != 0)
+ if (cachefs_index_reclaim_one_entry(super, &trans) < 0)
+ goto error2;
+ goto advance;
+ }
+
+ /* continue a partially complete pointer array */
+ if (trans->jentry->rcm_ptrstop > 0 &&
+ super->rcm_ptrnext < super->rcm_ptrstop)
+ goto process_pointer_array;
+
+ advance:
+ trans->jentry->rcm_indirect++;
+ kdebug("-- step %u", trans->jentry->rcm_indirect);
/* process the single indirect block */
- if (indirect == 2) {
+ if (trans->jentry->rcm_indirect == 1) {
metadata = cachefs_metadata_preread(super->rcm_inode);
- bix = metadata->single_indirect;
+ trans->jentry->rcm_block = metadata->single_indirect;
cachefs_metadata_postread(super->rcm_inode);
- if (!bix)
- goto again;
- goto pointer_array;
+ if (!trans->jentry->rcm_block)
+ goto advance;
+ goto start_pointer_array;
}
/* deal with double indirection */
- if (indirect <= 3 + N) {
+ if (trans->jentry->rcm_indirect <= 2 + N) {
+ cachefs_blockix_t *pbix, dblbix;
+
metadata = cachefs_metadata_preread(super->rcm_inode);
- bix = metadata->double_indirect;
+ dblbix = metadata->double_indirect;
cachefs_metadata_postread(super->rcm_inode);
- if (!bix) {
- indirect = 3 + N;
- goto again;
+ if (!dblbix) {
+ trans->jentry->rcm_indirect = 2 + N;
+ goto advance;
}
- ret = cachefs_block_read(super, NULL, bix, 0, NULL, &dpage);
+ ret = cachefs_block_read(super, NULL, dblbix, 0, NULL, &dpage);
if (ret < 0)
goto error;
/* start processing a double indirect subblock */
- if (indirect <= 3 + N - 1) {
+ if (trans->jentry->rcm_indirect <= 2 + N - 1) {
wait_on_page_locked(dpage);
- bix = 0;
+ trans->jentry->rcm_block = 0;
pbix = kmap(dpage);
- for (loop = indirect - 2; loop < N; loop++) {
- bix = pbix[loop];
- if (bix)
+ for (loop = trans->jentry->rcm_indirect - 2;
+ loop < N;
+ loop++) {
+ trans->jentry->rcm_block = pbix[loop];
+ if (trans->jentry->rcm_block)
break;
}
kunmap(dpage);
- indirect = loop + 3;
- if (bix) {
+ trans->jentry->rcm_indirect = loop + 3;
+ if (trans->jentry->rcm_block) {
put_page(dpage);
- goto pointer_array;
+ goto start_pointer_array;
}
}
/* start processing the double indirect block */
- page = dpage;
- bix = __cachefs_get_page_block(dpage)->bix;
- goto pointer_array2;
+ super->rcm_curpage = dpage;
+ super->rcm_block = __cachefs_get_page_block(dpage)->bix;
+ goto process_pointer_array;
}
/* reclaim all the block pointers in the inode metadata record */
- if (indirect == 3 + N + 1) {
- bix = super->rcm_inode->metadata->bix;
- next = super->rcm_inode->metadata_offset;
- next += offsetof(struct cachefs_ondisc_metadata,
- triple_indirect);
- next /= sizeof(cachefs_blockix_t);
-
- stop = super->rcm_inode->metadata_offset;
- stop += super->layout->metadata_size;
- stop /= sizeof(cachefs_blockix_t);
+ if (trans->jentry->rcm_indirect == 2 + N + 1) {
+ trans->jentry->rcm_block = super->rcm_inode->metadata->bix;
+ trans->jentry->rcm_ptrnext = super->rcm_inode->metadata_offset;
+ trans->jentry->rcm_ptrnext +=
+ offsetof(struct cachefs_ondisc_metadata,
+ triple_indirect);
+ trans->jentry->rcm_ptrnext /= sizeof(cachefs_blockix_t);
+
+ trans->jentry->rcm_ptrstop = super->rcm_inode->metadata_offset;
+ trans->jentry->rcm_ptrstop += super->layout->metadata_size;
+ trans->jentry->rcm_ptrstop /= sizeof(cachefs_blockix_t);
down_read(&super->rcm_inode->metadata_sem);
- page = super->rcm_inode->metadata_page;
- get_page(page);
+ super->rcm_curpage = super->rcm_inode->metadata_page;
+ get_page(super->rcm_curpage);
up_read(&super->rcm_inode->metadata_sem);
- goto pointer_array2;
+ goto process_pointer_array;
}
/* reclaim the inode itself */
- if (cachefs_recycle_reclaim_inode_metadata(super) < 0) {
- indirect--;
- bix = 0;
- next = 0;
- stop = 0;
- page = NULL;
- goto set;
- }
+ ret = cachefs_recycle_reclaim_inode_metadata(super, &trans);
+ if (ret < 0)
+ goto error;
- /* finished this inode */
cachefs_iput(super->rcm_inode);
- super->rcm_inode = NULL;
- super->rcm_ino = 0;
- super->rcm_indirect = 0;
- super->rcm_block = 0;
- super->rcm_ptrnext = 0;
- super->rcm_ptrstop = 0;
+ super->rcm_inode = NULL;
+
+ cachefs_trans_put(trans);
kleave("");
return;
- pointer_array:
- ret = cachefs_block_read(super, NULL, bix, 0, NULL, &page);
+ start_pointer_array:
+ ret = cachefs_block_read(super, NULL, trans->jentry->rcm_block, 0,
+ NULL, &super->rcm_curpage);
if (ret < 0)
goto error;
- pointer_array2:
- cachefs_recycle_pointer_array(super);
+ process_pointer_array:
+ down(&super->ujnl_alloc_sem);
+ super->rcm_ino = trans->jentry->rcm_ino;
+ super->rcm_indirect = trans->jentry->rcm_indirect;
+ super->rcm_block = trans->jentry->rcm_block;
+ super->rcm_ptrstop = trans->jentry->rcm_ptrstop;
+ super->rcm_ptrnext = trans->jentry->rcm_ptrnext;
+ up(&super->ujnl_alloc_sem);
- set:
- super->rcm_indirect = indirect;
- super->rcm_block = bix;
- super->rcm_ptrnext = next;
- super->rcm_ptrstop = stop;
- super->rcm_curpage = page;
+ cachefs_recycle_pointer_array(super, &trans);
+ cachefs_trans_put(trans);
kleave("");
return;
error:
if (ret == -EIO) {
/* just sweep any buggy block under the rug */
- printk("CacheFS: discarding block %u due to I/O error\n", bix);
- goto again;
+ printk("CacheFS: discarding block %u due to I/O error\n",
+ trans ? trans->jentry->rcm_block : super->rcm_block);
+ goto advance;
}
error2:
- kdebug("[error %d]", ret);
- goto set;
+ if (trans) {
+ down(&super->ujnl_alloc_sem);
+ super->rcm_ino = trans->jentry->rcm_ino;
+ super->rcm_indirect = trans->jentry->rcm_indirect;
+ super->rcm_block = trans->jentry->rcm_block;
+ super->rcm_ptrstop = trans->jentry->rcm_ptrstop;
+ super->rcm_ptrnext = trans->jentry->rcm_ptrnext;
+ up(&super->ujnl_alloc_sem);
+ cachefs_trans_put(trans);
+ }
+ kleave("[error %d]", ret);
} /* end cachefs_recycle_reclaim_inode() */
/*****************************************************************************/
@@ -811,13 +826,13 @@
struct cachefs_transaction *trans;
int ret;
- kenter("{%u,%u,%u:%hu-%hu}",
+ kenter("{%x,%u,%x:%hu-%hu}",
super->rcm_ino, super->rcm_indirect, super->rcm_block,
super->rcm_ptrnext, super->rcm_ptrstop);
/* recycle the next chunk of an inode we're busy reclaiming */
if (super->rcm_ino) {
- kdebug("do reclaim");
+ kdebug("do reclaim: %x", super->rcm_ino);
if (!super->rcm_inode) {
ret = cachefs_iget(super, super->rcm_ino,
&super->rcm_inode);
@@ -845,6 +860,16 @@
trans->jentry->ino = super->rcm_imm_buf[super->rcm_imm_tail];
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INODE_RECLAIMING;
+ trans->jentry->rcm_ino = trans->jentry->ino;
+ trans->jentry->rcm_indirect = 0;
+ trans->jentry->rcm_block = 0;
+ trans->jentry->rcm_ptrnext = 0;
+ trans->jentry->rcm_ptrstop = 0;
+
+ trans->changed |=
+ CACHEFS_TRANS_CHANGED_RCMBLOCK |
+ CACHEFS_TRANS_CHANGED_RCMPTR;
+
ret = cachefs_trans_mark(trans);
if (ret < 0) {
kdebug("[error %d]", ret);
@@ -852,12 +877,6 @@
goto done;
}
- super->rcm_ino = trans->jentry->ino;
- super->rcm_indirect = 0;
- super->rcm_block = 0;
- super->rcm_ptrnext = 0;
- super->rcm_ptrstop = 0;
-
cachefs_trans_commit(trans);
super->rcm_imm_tail =
@@ -866,7 +885,6 @@
goto done;
}
-
done:
if (super->rcm_ino ||
super->rcm_imm_head != super->rcm_imm_tail
@@ -906,6 +924,8 @@
goto error;
trans->jentry->mark = CACHEFS_ONDISC_UJNL_DATA_UNALLOCING;
+ trans->jentry->index = super->recycle_cur;
+ trans->jentry->ixentry = super->recycle_cur_n;
trans->jentry->ino = vjentry->ino;
trans->jentry->auxmark = vjentry->vslot;
trans->jentry->block = vjentry->bix;
@@ -939,6 +959,9 @@
goto error_free;
cachefs_trans_affects_block(trans, rcyblock, 0, PAGE_SIZE);
+
+ trans->jentry->recycle_cur = vjentry->bix;
+ trans->changed |= CACHEFS_TRANS_CHANGED_RECYCLE;
}
else {
/* we can add into an existing recycling node */
@@ -964,15 +987,14 @@
memset(kmap(uppage) + vjentry->upentry, 0, sizeof(cachefs_blockix_t));
kunmap(uppage);
- if (trans->jentry->auxentry == UINT_MAX) {
+ if (trans->changed & CACHEFS_TRANS_CHANGED_RECYCLE) {
/* new recycling node */
node = kmap(rcypage);
- node->next = super->recycle_cur;
- node->count = super->recycle_cur_n;
+ node->next = trans->jentry->index;
+ node->count = trans->jentry->ixentry;
kunmap(rcypage);
- super->recycle_cur = vjentry->bix;
- super->recycle_room = CACHEFS_ONDISC_LEAVES_PER_FREE_NODE;
+ super->recycle_room = CACHEFS_ONDISC_LEAVES_PER_FREE_NODE;
rcypage = xchg(&super->recycle_node, rcypage);
rcyblock = xchg(&super->recycle_block, rcyblock);
}
Index: journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/journal.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- journal.c 10 Jul 2003 14:21:24 -0000 1.40
+++ journal.c 17 Jul 2003 12:02:13 -0000 1.41
@@ -381,19 +381,45 @@
trans->serial = super->ujnl_serial++;
super->ujnl_head = next;
+ /* some recorded values in the superblock should only be updated with
+ * the lock held */
+ if (trans->changed & CACHEFS_TRANS_CHANGED_ALLOC) {
+ super->alloc_leaf = trans->jentry->alloc_leaf;
+ super->alloc_cur = trans->jentry->alloc_cur;
+ } else {
+ trans->jentry->alloc_leaf = super->alloc_leaf;
+ trans->jentry->alloc_cur = super->alloc_cur;
+ }
+
+ if (trans->changed & CACHEFS_TRANS_CHANGED_RECYCLE) {
+ super->recycle_cur = trans->jentry->recycle_cur;
+ } else {
+ trans->jentry->recycle_cur = super->recycle_cur;
+ }
+
+ if (trans->changed & CACHEFS_TRANS_CHANGED_RCMBLOCK) {
+ super->rcm_ino = trans->jentry->rcm_ino;
+ super->rcm_indirect = trans->jentry->rcm_indirect;
+ super->rcm_block = trans->jentry->rcm_block;
+ super->rcm_ptrstop = trans->jentry->rcm_ptrstop;
+ } else {
+ trans->jentry->rcm_ino = super->rcm_ino;
+ trans->jentry->rcm_indirect = super->rcm_indirect;
+ trans->jentry->rcm_block = super->rcm_block;
+ trans->jentry->rcm_ptrstop = super->rcm_ptrstop;
+ }
+
+ if (trans->changed & CACHEFS_TRANS_CHANGED_RCMPTR) {
+ super->rcm_ptrnext = trans->jentry->rcm_ptrnext;
+ } else {
+ trans->jentry->rcm_ptrnext = super->rcm_ptrnext;
+ }
+
up(&super->ujnl_alloc_sem);
trans->index = index;
trans->jentry->batch = trans->batch;
trans->jentry->serial = trans->serial;
- trans->jentry->alloc_leaf = super->alloc_leaf;
- trans->jentry->alloc_cur = super->alloc_cur;
- trans->jentry->recycle_cur = super->recycle_cur;
- trans->jentry->rcm_ino = super->rcm_ino;
- trans->jentry->rcm_indirect = super->rcm_indirect;
- trans->jentry->rcm_block = super->rcm_block;
- trans->jentry->rcm_ptrnext = super->rcm_ptrnext;
- trans->jentry->rcm_ptrstop = super->rcm_ptrstop;
/* transfer the journal entry to the page it's going to be written
* from */
@@ -433,6 +459,7 @@
/* record a mark in the validity journal */
if (trans->vjentry) {
+ wait_on_page_locked(trans->vjentry->vpage);
cachefs_block_modify(super, trans->vjentry->vblock,
&trans->vjentry->vpage);
vjentry = kmap(trans->vjentry->vpage) + trans->vjentry->ventry;
Index: index.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/index.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- index.c 16 Jul 2003 10:44:21 -0000 1.28
+++ index.c 17 Jul 2003 12:02:13 -0000 1.29
@@ -640,7 +640,7 @@
/* fill the inode definition */
metadata = kmap(inopage) + ino_offset;
- memset(metadata, 0, sizeof(super->imetadata->index_esize));
+ memset(metadata, 0, super->imetadata->index_esize);
metadata->header.state = CACHEFS_ONDISC_INDEX_ACTIVE;
metadata->header.ino = 0xfefefe;
@@ -689,24 +689,27 @@
* mark the next inode pinned by an entry in the index currently being
* reclaimed as being obsolete
*/
-int cachefs_index_reclaim_one_entry(struct cachefs_super *super)
+int cachefs_index_reclaim_one_entry(struct cachefs_super *super,
+ struct cachefs_transaction **_trans)
{
struct cachefs_ondisc_index_entry *xent;
struct cachefs_ondisc_metadata *metadata;
- struct cachefs_transaction *trans = NULL;
+ struct cachefs_transaction *trans;
struct cachefs_inode *inode = NULL;
unsigned long flags;
struct page *page = NULL;
unsigned pgnum, offset, ino;
int ret;
- _enter("{%u,%u}", super->rcm_ino, super->rcm_block);
+ kenter("{%x,%x}", super->rcm_ino, super->rcm_block);
+ try_next_block:
pgnum = super->rcm_block / super->rcm_inode->index_epp;
offset = super->rcm_block % super->rcm_inode->index_epp;
+ offset *= super->rcm_inode->index_esize;
if (pgnum >= (super->rcm_inode->vfs_inode.i_size >> PAGE_SHIFT)) {
- _leave(" = 0");
+ kleave(" = 0");
return 0; /* done them all */
}
@@ -718,25 +721,39 @@
super->rcm_block =
(pgnum + 1) * super->rcm_inode->index_epp;
}
- _leave(" = %d", ret);
+ kleave(" = %d", ret);
return ret;
}
- offset *= super->rcm_inode->index_esize;
+ try_next_entry:
xent = kmap(page) + offset;
ino = xent->ino;
+ BUG_ON(ino == 0 && xent->state != CACHEFS_ONDISC_INDEX_FREE);
+ BUG_ON(ino != 0 && xent->state == CACHEFS_ONDISC_INDEX_FREE);
kunmap(page);
+ if (!ino) {
+ kdebug("skip slot %u", super->rcm_block);
+ super->rcm_block++;
+
+ offset += super->rcm_inode->index_esize;
+ if (offset + super->rcm_inode->index_esize <= PAGE_SIZE)
+ goto try_next_entry;
+
+ cachefs_put_page(page);
+ page = NULL;
+ goto try_next_block;
+ }
+
ret = cachefs_iget(super, ino, &inode);
- if (ret < 0)
- goto error_skip;
+ if (ret < 0) {
+ if (ret == -EIO)
+ super->rcm_block++;
+ goto error;
+ }
/* journal what we're going to do */
- trans = cachefs_trans_alloc(super, GFP_KERNEL);
- if (!trans) {
- _leave(" = -ENOMEM");
- return -ENOMEM;
- }
+ trans = *_trans;
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INODE_MARK_RECLAIM;
trans->jentry->ino = inode->vfs_inode.i_ino;
@@ -750,9 +767,13 @@
cachefs_trans_affects_inode(trans, inode);
+ trans->jentry->rcm_block = super->rcm_block + 1;
+
ret = cachefs_trans_mark(trans);
if (ret < 0)
- goto error_skip;
+ goto error;
+
+ *_trans = NULL;
/* modify the inode metadata entry */
metadata = cachefs_metadata_prewrite(inode);
@@ -762,14 +783,14 @@
cachefs_metadata_postwrite(inode);
cachefs_trans_commit(trans);
- trans = NULL;
/* add to the immediate-reclaim table if possible */
spin_lock_irqsave(&super->rcm_lock, flags);
if (CIRC_SPACE(super->rcm_imm_head,
super->rcm_imm_tail,
- CACHEFS_RCM_IMM_BUFSIZE) > 0) {
+ CACHEFS_RCM_IMM_BUFSIZE) > 0
+ ) {
super->rcm_imm_buf[super->rcm_imm_head] =
inode->vfs_inode.i_ino;
super->rcm_imm_head =
@@ -782,16 +803,12 @@
spin_unlock_irqrestore(&super->rcm_lock, flags);
- super->rcm_block++;
ret = -EAGAIN;
- error_skip:
+ error:
cachefs_iput(inode);
- cachefs_trans_put(trans);
cachefs_put_page(page);
- if (ret == -EIO)
- super->rcm_block++;
- _leave(" = %d", ret);
+ kleave(" = %d [%u]", ret, super->rcm_block);
return ret;
} /* end cachefs_index_reclaim_one_entry() */
Index: dump-journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/dump-journal.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- dump-journal.c 10 Jul 2003 14:21:24 -0000 1.14
+++ dump-journal.c 17 Jul 2003 12:02:13 -0000 1.15
@@ -141,13 +141,13 @@
" CNT"
" ALLOC[LEAF]"
" RECYCLE "
- " RCYBLOCK:NEXT-STOP\n");
+ " RCMBLOCK:NEXT-STOP\n");
printf("===="
" ==========="
" ========= ===="
" ======== ========"
- " ============="
+ " =============="
" ============="
" ============="
" ============="
@@ -168,15 +168,15 @@
printf("%s%4u" NORMAL
" " CYAN "%5u" GREY "." NORMAL "%-5u" NORMAL
" " "%s" " %4d"
- " " YELLOW "%8x" NORMAL " %8u"
- " " YELLOW "%8x" GREY ":" NORMAL "%-4hu"
- " " YELLOW "%8d" GREY "+" NORMAL "%-4hu"
- " " YELLOW "%8d" GREY "+" NORMAL "%-4hu"
- " " YELLOW "%8d" GREY "+" NORMAL "%-4hu"
+ " " YELLOW "%8x" NORMAL " %8x"
+ " " YELLOW "%8x" GREY ":" NORMAL "%-5hu"
+ " " YELLOW "%8x" GREY "+" NORMAL "%-4hu"
+ " " YELLOW "%8x" GREY "+" NORMAL "%-4hu"
+ " " YELLOW "%8x" GREY "+" NORMAL "%-4hu"
" " YELLOW "%4hu" NORMAL ""
- " " GREEN "%8u" NORMAL "[%-4hu]"
- " " CYAN "%8u" NORMAL ""
- " " RED "%8u" GREY ":" NORMAL
+ " " GREEN "%8x" NORMAL "[%-4hu]"
+ " " CYAN "%8x" NORMAL ""
+ " " RED "%8x" GREY ":" NORMAL
"%4hu" GREY"-"NORMAL "%-4hu"
"\n",
loop&7 ? NORMAL : GREEN,
Index: cachefs-layout.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-layout.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- cachefs-layout.h 16 Jul 2003 10:44:21 -0000 1.31
+++ cachefs-layout.h 17 Jul 2003 12:02:13 -0000 1.32
@@ -210,7 +210,8 @@
/* beginning new recycle_stk front node
* - block = block being begun
- * - auxblock = old front recycling node
+ * - index = old front recycling node
+ * - ixentry = old front recycling node's count
* - upblock = block from which transferred (or 0 if from unready list)
* - upentry = entry in upblock[]
* - pgnum = new super->layout.bix_unready
@@ -325,6 +326,8 @@
CACHEFS_ONDISC_UJNL_DATA_WRITTEN,
/* data block being unallocated
+ * - index = old front recycling node
+ * - ixentry = old front recycling node's count
* - ino = inode to which block belongs
* - pgnum = which page of inode being unallocated
* - block = block being recycled
Index: aops.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/aops.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- aops.c 16 Jul 2003 11:19:39 -0000 1.43
+++ aops.c 17 Jul 2003 12:02:13 -0000 1.44
@@ -923,8 +923,8 @@
struct cachefs_ondisc_metadata *metadata;
struct cachefs_super *super = sb->s_fs_info;
struct cachefs_block *block;
- cachefs_blockix_t alloc2os = 0, old_alloc_cur;
- u_int32_t next_count = 0, old_alloc_leaf;
+ cachefs_blockix_t alloc2os = 0;
+ u_int32_t next_count = 0;
int ret;
u8 *data;
@@ -1005,10 +1005,9 @@
BUG_ON(super->alloc_leaf > CACHEFS_ONDISC_LEAVES_PER_FREE_NODE);
- /* choose either a dependent block or the now empty node */
- old_alloc_cur = super->alloc_cur;
- old_alloc_leaf = super->alloc_leaf;
+ step->transaction->changed |= CACHEFS_TRANS_CHANGED_ALLOC;
+ /* choose either a dependent block or the now empty node */
if (super->alloc_leaf == CACHEFS_ONDISC_LEAVES_PER_FREE_NODE) {
/* no dependent blocks left - take the alloc node itself */
block = super->alloc_block;
@@ -1018,12 +1017,12 @@
BUG_ON(!jentry->block);
node = kmap(super->alloc_node);
- super->alloc_cur = node->next;
- super->alloc_leaf = 0;
+ jentry->alloc_cur = node->next;
+ jentry->alloc_leaf = 0;
next_count = node->count;
kunmap(node);
- alloc2os = super->alloc_cur;
+ alloc2os = jentry->alloc_cur;
if (step->page)
cachefs_block_set(super,
@@ -1034,11 +1033,14 @@
else {
/* take the next dependent page */
node = kmap(super->alloc_node);
- jentry->block = node->leaves[super->alloc_leaf++];
+ jentry->block = node->leaves[super->alloc_leaf];
alloc2os = node->next;
kunmap(node);
BUG_ON(!jentry->block);
+ jentry->alloc_cur = super->alloc_cur;
+ jentry->alloc_leaf = super->alloc_leaf + 1;
+
if (!step->page) {
ret = cachefs_block_read(super, NULL, jentry->block, 1,
&block, &step->page);
@@ -1085,11 +1087,8 @@
}
/* make sure the journal is marked on disc before doing anything else */
- if (cachefs_trans_mark(step->transaction) < 0) {
- super->alloc_cur = old_alloc_cur;
- super->alloc_leaf = old_alloc_leaf;
+ if (cachefs_trans_mark(step->transaction) < 0)
goto error_block;
- }
if (step->flags & CACHEFS_BLOCK_INIT_NETFSDATA) {
set_bit(CACHEFS_BLOCK_NETFSDATA, &block->flags);
@@ -1133,7 +1132,7 @@
}
/* clean up the alloc stack tracking */
- if (old_alloc_leaf == CACHEFS_ONDISC_LEAVES_PER_FREE_NODE) {
+ if (super->alloc_leaf == 0) {
struct page *dead;
/* move the allocation stack to the 2OS */
More information about the linux-afs-cvs
mailing list