afs/fs/cachefs super.c,1.31,1.32 kcachefsd.c,1.11,1.12
journal.c,1.34,1.35 interface.c,1.12,1.13 inode.c,1.19,1.20
index.c,1.21,1.22 cachetest-main.c,1.10,1.11 block.c,1.6,1.7
aops.c,1.35,1.36
dwh at infradead.org
dwh at infradead.org
Tue Jun 10 19:49:52 BST 2003
Update of /home/cvs/afs/fs/cachefs
In directory phoenix.infradead.org:/tmp/cvs-serv4409/fs/cachefs
Modified Files:
super.c kcachefsd.c journal.c interface.c inode.c index.c
cachetest-main.c block.c aops.c
Log Message:
fix some oopses
Index: super.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/super.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- super.c 2 Jun 2003 09:17:42 -0000 1.31
+++ super.c 10 Jun 2003 17:49:49 -0000 1.32
@@ -736,9 +736,10 @@
remove_wait_queue(&super->vjnl_alloc_wq,&myself);
}
+ super->dmn_die = 1;
cachefs_trans_sync(super,1);
- super->dmn_die = 1;
+ super->dmn_die = 2;
wake_up(&super->dmn_sleepq);
wait_for_completion(&super->dmn_dead);
Index: kcachefsd.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/kcachefsd.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- kcachefsd.c 23 May 2003 14:07:31 -0000 1.11
+++ kcachefsd.c 10 Jun 2003 17:49:49 -0000 1.12
@@ -74,17 +74,22 @@
discard_my_signals();
/* see if there's work to be done */
- if (!super->alloc_node ||
- super->layout->bix_unready < super->layout->bix_end ||
- test_bit(CACHEFS_SUPER_BATCH_TIMER,&super->flags) ||
- test_bit(CACHEFS_SUPER_DO_RECLAIM,&super->flags) ||
+ if (super->dmn_die == 0) {
+ if (!super->alloc_node ||
+ super->layout->bix_unready < super->layout->bix_end ||
+ test_bit(CACHEFS_SUPER_DO_RECLAIM,&super->flags)
+ )
+ break;
+ }
+
+ if (test_bit(CACHEFS_SUPER_BATCH_TIMER,&super->flags) ||
!list_empty(&super->vjnl_unallocq) ||
!list_empty(&super->vjnl_writtenq)
)
break;
/* deal with the server being asked to die */
- if (super->dmn_die) {
+ if (super->dmn_die > 1) {
remove_wait_queue(&super->dmn_sleepq,&myself);
_leave("");
complete_and_exit(&super->dmn_dead,0);
@@ -102,20 +107,27 @@
/* actually do some work */
_debug("@@@ Begin Cache Management");
- /* decant the recycling queue */
- if (test_and_clear_bit(CACHEFS_SUPER_DO_RECLAIM,&super->flags))
- cachefs_recycle_reclaim(super);
-
- /* transfer blocks from the unready data if possible */
- if (super->layout->bix_unready<super->layout->bix_end) {
- cachefs_recycle_unready_blocks(super);
- if (super->layout->bix_unready==super->layout->bix_end) {
- printk("CacheFS: all blocks now added to recycling stack\n");
- cachefs_debug = 1;
- }
- else {
- yield();
+ if (super->dmn_die == 0) {
+ /* decant the recycling queue */
+ if (test_and_clear_bit(CACHEFS_SUPER_DO_RECLAIM,&super->flags))
+ cachefs_recycle_reclaim(super);
+
+ /* transfer blocks from the unready data if possible */
+ if (super->layout->bix_unready<super->layout->bix_end) {
+ cachefs_recycle_unready_blocks(super);
+ if (super->layout->bix_unready==super->layout->bix_end) {
+ printk("CacheFS:"
+ " all blocks now added to recycling stack\n");
+ cachefs_debug = 1;
+ }
+ else {
+ yield();
+ }
}
+
+ /* if there's no next node, then get one */
+ if (!super->alloc_node)
+ cachefs_recycle_transfer_stack(super);
}
/* deal with validity journal changes */
@@ -125,15 +137,11 @@
if (!list_empty(&super->vjnl_writtenq))
cachefs_vj_note_write_completion(super);
- /* if there's no next node, then get one */
- if (!super->alloc_node)
- cachefs_recycle_transfer_stack(super);
-
/* write a batch of metadata if it's time to do so */
if (test_bit(CACHEFS_SUPER_BATCH_TIMER,&super->flags))
cachefs_trans_batch_write(super);
-// super->dmn_die = 1;
+// super->dmn_die = 2;
_debug("@@@ End Cache Management");
Index: journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/journal.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- journal.c 9 Jun 2003 16:07:43 -0000 1.34
+++ journal.c 10 Jun 2003 17:49:49 -0000 1.35
@@ -388,7 +388,8 @@
trans->jentry->count,
trans->jentry->alloc_cur, trans->jentry->alloc_leaf,
trans->jentry->recycle_cur,
- trans->jentry->rcyblock, trans->jentry->rcynext, trans->jentry->rcystop
+ trans->jentry->rcm_block, trans->jentry->rcm_ptrnext,
+ trans->jentry->rcm_ptrstop
);
/* link the transaction into the marked list */
@@ -1508,7 +1509,7 @@
struct file_ra_state ra;
read_descriptor_t desc;
loff_t ppos;
- int loop;
+ int loop, ret;
kenter("");
@@ -1642,19 +1643,19 @@
/* reload the front nodes for the allocation and recycling stacks */
if (super->alloc_cur) {
- super->alloc_node =
- read_cache_page(super->imisc->i_mapping,
- super->alloc_cur,
- (filler_t*)super->imisc->i_mapping->a_ops->readpage,
- NULL);
-
- dbgpgalloc(super->alloc_node);
- if (IS_ERR(super->alloc_node)) {
- printk("CacheFS: failed to reload alloc stack: %ld\n",
- PTR_ERR(super->alloc_node));
- return PTR_ERR(super->alloc_node);
+ ret = cachefs_block_read(super,
+ CACHEFS_FS_I(super->imisc),
+ super->alloc_cur,
+ 0,
+ &super->alloc_block,
+ &super->alloc_node);
+
+ if (ret<0) {
+ printk("CacheFS: failed to reload alloc stack: %d\n",ret);
+ return ret;
}
+ dbgpgalloc(super->alloc_node);
wait_on_page_locked(super->alloc_node);
node = kmap(super->alloc_node);
@@ -1665,19 +1666,19 @@
}
if (super->recycle_cur) {
- super->recycle_node =
- read_cache_page(super->imisc->i_mapping,
- super->recycle_cur,
- (filler_t*)super->imisc->i_mapping->a_ops->readpage,
- NULL);
-
- dbgpgalloc(super->recycle_node);
- if (IS_ERR(super->recycle_node)) {
- printk("CacheFS: failed to reload alloc stack: %ld\n",
- PTR_ERR(super->recycle_node));
- return PTR_ERR(super->recycle_node);
+ ret = cachefs_block_read(super,
+ CACHEFS_FS_I(super->imisc),
+ super->recycle_cur,
+ 0,
+ &super->recycle_block,
+ &super->recycle_node);
+
+ if (ret<0) {
+ printk("CacheFS: failed to reload recycling stack: %d\n",ret);
+ return ret;
}
+ dbgpgalloc(super->recycle_node);
wait_on_page_locked(super->recycle_node);
node = kmap(super->recycle_node);
Index: interface.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/interface.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- interface.c 9 Jun 2003 13:52:03 -0000 1.12
+++ interface.c 10 Jun 2003 17:49:49 -0000 1.13
@@ -831,7 +831,7 @@
* - if the cookie is not backed by a file:
* - -ENOBUFS will be returned and nothing more will be done
* - else if the page is backed by a block in the cache:
- * - a read will be started which will call end_io_data on completion
+ * - a read will be started which will call end_io_func on completion
* - the wb-journal will be searched for an entry pertaining to this block
* - if an entry is found:
* - 1 will be returned
@@ -928,7 +928,7 @@
write_unlock(&pageio->mapped_block->ref_lock);
/* new block allocated, but no data */
- _debug("no data [bix=%u]",pageio->mapped_block->bix);
+ _debug("no data [bix=%u ref=%p]",pageio->mapped_block->bix,pageio);
up_read(&cookie->sem);
_leave(" = -ENODATA");
return -ENODATA;
@@ -1090,7 +1090,7 @@
return -ENOBUFS;
write:
- _debug("write [bix=%u]",block->bix);
+ _debug("write [bix=%u ref=%p]",block->bix,pageio);
cachefs_block_get(block);
set_bit(CACHEFS_BLOCK_NETFSBUSY,&block->flags);
@@ -1152,7 +1152,7 @@
* - if the block backing the page still has a vjentry then the block will be
* recycled
*/
-void __cachefs_uncache_page(struct cachefs_cookie *cookie, struct page *page)
+void cachefs_uncache_page(struct cachefs_cookie *cookie, struct page *page)
{
struct cachefs_block *block, *xblock;
struct cachefs_page *pageio;
@@ -1179,8 +1179,11 @@
block = pageio->mapped_block;
if (block) {
pageio->mapped_block = NULL; /* pin the block */
+ pageio->flags = 0;
write_unlock(&pageio->lock);
+ BUG_ON(block->ref != pageio);
+
/* locking order needs to be reversed */
write_lock(&block->ref_lock);
write_lock(&pageio->lock);
@@ -1197,6 +1200,6 @@
_leave("");
return;
-} /* end __cachefs_uncache_page() */
+} /* end cachefs_uncache_page() */
-EXPORT_SYMBOL(__cachefs_uncache_page);
+EXPORT_SYMBOL(cachefs_uncache_page);
Index: inode.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/inode.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- inode.c 4 Jun 2003 14:25:41 -0000 1.19
+++ inode.c 10 Jun 2003 17:49:49 -0000 1.20
@@ -116,6 +116,8 @@
inode->index_esize = inode->index_dsize;
inode->index_epp = PAGE_SIZE / inode->index_esize;
+ __set_bit(CACHEFS_ACTIVE_INODE_ISINDEX,&inode->flags);
+
/* read the page containing this inode's meta-data */
pos = inode->vfs_inode.i_ino << super->layout->metadata_bits;
ret = cachefs_get_page(inode,pos/PAGE_SIZE,&inode->metadata_page);
@@ -234,6 +236,8 @@
inode->vfs_inode.i_nlink = 2;
inode->vfs_inode.i_op = &cachefs_root_inode_operations;
inode->vfs_inode.i_fop = &cachefs_root_file_operations;
+
+ __set_bit(CACHEFS_ACTIVE_INODE_ISINDEX,&inode->flags);
}
_leave(" = %d",ret);
Index: index.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/index.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- index.c 4 Jun 2003 14:25:41 -0000 1.21
+++ index.c 10 Jun 2003 17:49:49 -0000 1.22
@@ -245,7 +245,7 @@
newentry = metadata->freelink;
cachefs_metadata_postread(iinode);
- _debug("free entry: %u",newentry);
+ _debug("free entry: %u [size %Lu]",newentry,iinode->vfs_inode.i_size);
/* we may need to extend the index file */
if (newentry==UINT_MAX) {
@@ -293,6 +293,8 @@
}
}
+ BUG_ON(!__cachefs_get_page_block(page));
+
*_page = page;
*_newentry = newentry;
@@ -306,7 +308,7 @@
return 0;
error2:
- page_cache_release(page);
+ cachefs_put_page(page);
error:
_leave(" = %d",ret);
return ret;
@@ -464,9 +466,9 @@
*_newino = ino;
error:
- if (trans) cachefs_trans_put(trans);
- if (inopage) page_cache_release(inopage);
- if (ixpage) page_cache_release(ixpage);
+ cachefs_trans_put(trans);
+ cachefs_put_page(inopage);
+ cachefs_put_page(ixpage);
_leave(" = %d",ret);
return ret;
@@ -562,13 +564,14 @@
ret = -EAGAIN;
error_skip:
- if (inode) cachefs_iput(inode);
- if (trans) cachefs_trans_put(trans);
- if (page) put_page(page);
- if (ret==-EIO) super->rcm_block++;
+ cachefs_iput(inode);
+ cachefs_trans_put(trans);
+ cachefs_put_page(page);
+ if (ret==-EIO)
+ super->rcm_block++;
+
_leave(" = %d",ret);
return ret;
-
} /* end cachefs_index_zap() */
/*****************************************************************************/
Index: cachetest-main.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachetest-main.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- cachetest-main.c 3 Jun 2003 17:45:27 -0000 1.10
+++ cachetest-main.c 10 Jun 2003 17:49:49 -0000 1.11
@@ -133,8 +133,11 @@
.lock = RW_LOCK_UNLOCKED,
};
-static void afs_page_cache_write_complete(void *cookie_data, struct page *page, void *data);
-static void afs_page_cache_read_complete(void *cookie_data, struct page *page, void *data);
+static void afs_page_cache_write_complete(void *cookie_data, struct page *page, void *data,
+ int error);
+
+static void afs_page_cache_read_complete(void *cookie_data, struct page *page, void *data,
+ int error);
/*****************************************************************************/
/*
@@ -229,8 +232,8 @@
{
printk(KERN_INFO "cachefstest: general fs caching v0.1 tester unregistering.\n");
- cachefs_uncache_page(afs_root_dir.cache,afs_data_page ,&afs_data_page_cookie );
- cachefs_uncache_page(afs_root_dir.cache,afs_data_page2,&afs_data_page2_cookie);
+ cachefs_uncache_page(afs_root_dir.cache,afs_data_page);
+ cachefs_uncache_page(afs_root_dir.cache,afs_data_page2);
__free_pages(afs_data_page,1);
@@ -337,9 +340,10 @@
/*
*
*/
-static void afs_page_cache_write_complete(void *cookie_data, struct page *page, void *data)
+static void afs_page_cache_write_complete(void *cookie_data, struct page *page, void *data,
+ int error)
{
- kenter("%p,%p,%p",cookie_data,page,data);
+ kenter("%p,%p,%p,%d",cookie_data,page,data,error);
} /* end afs_page_cache_write_complete() */
@@ -347,9 +351,10 @@
/*
*
*/
-static void afs_page_cache_read_complete(void *cookie_data, struct page *page, void *data)
+static void afs_page_cache_read_complete(void *cookie_data, struct page *page, void *data,
+ int error)
{
- kenter("%p,%p,%p",cookie_data,page,data);
+ kenter("%p,%p,%p,%d",cookie_data,page,data,error);
} /* end afs_page_cache_write_complete() */
Index: block.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/block.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- block.c 4 Jun 2003 14:25:41 -0000 1.6
+++ block.c 10 Jun 2003 17:49:49 -0000 1.7
@@ -599,6 +599,8 @@
write_lock(&block->ref_lock);
pageio = block->ref;
if (pageio) {
+ BUG_ON(pageio->mapped_block != block);
+
write_lock(&pageio->lock);
xblock = pageio->mapped_block;
pageio->mapped_block = NULL;
Index: aops.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/aops.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- aops.c 9 Jun 2003 15:03:34 -0000 1.35
+++ aops.c 10 Jun 2003 17:49:49 -0000 1.36
@@ -55,6 +55,8 @@
static int cachefs_writepages(struct address_space *mapping, struct writeback_control *wbc);
static int cachefs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to);
static int cachefs_commit_write(struct file *file, struct page *page, unsigned from, unsigned to);
+static int cachefs_invalidatepage(struct page *page, unsigned long offset);
+static int cachefs_releasepage(struct page *page, int gfp_flags);
struct address_space_operations cachefs_addrspace_operations = {
.readpage = cachefs_readpage,
@@ -292,56 +294,62 @@
goto error;
last_block = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (page->index < last_block) {
- if (inode->i_ino==CACHEFS_INO_METADATA && page->index==0) {
- ret = cachefs_block_set2(inode->i_sb->s_fs_info,1,page,pageio,NULL);
- if (ret<0)
- goto error;
- }
- else {
- ret = cachefs_get_block(inode,page,pageio,0);
- if (ret<0)
- goto error;
- }
- }
+ if (page->index >= last_block)
+ goto hole;
- /* handle a hole */
- if (!pageio->mapped_block) {
- memset(kmap(page),0,PAGE_SIZE);
- flush_dcache_page(page);
- kunmap(page);
- SetPageUptodate(page);
- unlock_page(page);
+ if (inode->i_ino == CACHEFS_INO_METADATA && page->index == 0) {
+ ret = cachefs_block_set2(inode->i_sb->s_fs_info,1,page,pageio,NULL);
+ if (ret<0)
+ goto error;
}
else {
- /* this page will go to BIO. Do we need to send this BIO off first? */
- if (*_bio && *last_block_in_bio != pageio->mapped_block->bix-1)
- cachefs_io_bio_submit(READ,_bio);
-
- alloc_new:
- if (!*_bio) {
- ret = cachefs_io_alloc(inode->i_sb,pageio->mapped_block->bix,
- nr_pages,GFP_KERNEL,_bio);
- if (ret<0)
- goto error;
- }
+ ret = cachefs_get_block(inode,page,pageio,0);
+ if (ret<0)
+ goto error;
+ }
- if (!bio_add_page(*_bio,page,PAGE_SIZE,0)) {
- cachefs_io_bio_submit(READ,_bio);
- goto alloc_new;
- }
+ /* handle a hole */
+ if (!pageio->mapped_block)
+ goto hole;
- if (test_bit(CACHEFS_PAGE_BOUNDARY,&pageio->flags))
- cachefs_io_bio_submit(READ,_bio);
- else
- *last_block_in_bio = pageio->mapped_block->bix;
+ /* this page will go to BIO. Do we need to send this BIO off first? */
+ if (*_bio && *last_block_in_bio != pageio->mapped_block->bix-1)
+ cachefs_io_bio_submit(READ,_bio);
+
+ alloc_new:
+ if (!*_bio) {
+ ret = cachefs_io_alloc(inode->i_sb,pageio->mapped_block->bix,
+ nr_pages,GFP_KERNEL,_bio);
+ if (ret<0)
+ goto error;
}
+ if (!bio_add_page(*_bio,page,PAGE_SIZE,0)) {
+ cachefs_io_bio_submit(READ,_bio);
+ goto alloc_new;
+ }
+
+ if (test_bit(CACHEFS_PAGE_BOUNDARY,&pageio->flags))
+ cachefs_io_bio_submit(READ,_bio);
+ else
+ *last_block_in_bio = pageio->mapped_block->bix;
+
_leave(" = 0");
return 0;
+ hole:
+ ret = -ENODATA;
+ if (test_bit(CACHEFS_ACTIVE_INODE_ISINDEX,&CACHEFS_FS_I(inode)->flags)) {
+ printk("CacheFS: found unexpected hole in index/metadata file: ino=%lu pg=%lu\n",
+ inode->i_ino,page->index);
+ ret = -EIO;
+ }
+
error:
- if (*_bio) cachefs_io_bio_submit(READ,_bio);
+ if (*_bio)
+ cachefs_io_bio_submit(READ,_bio);
+ unlock_page(page);
+
_leave("= %d",ret);
return ret;
} /* end cachefs_do_readpage() */
@@ -805,7 +813,7 @@
/*
* invalidate part or all of a page
*/
-int cachefs_invalidatepage(struct page *page, unsigned long offset)
+static int cachefs_invalidatepage(struct page *page, unsigned long offset)
{
struct cachefs_block *block;
struct cachefs_page *pageio;
@@ -837,13 +845,11 @@
return ret;
} /* end cachefs_invalidatepage() */
-EXPORT_SYMBOL(cachefs_invalidatepage);
-
/*****************************************************************************/
/*
* release a page and cleanup its private data
*/
-int cachefs_releasepage(struct page *page, int gfp_flags)
+static int cachefs_releasepage(struct page *page, int gfp_flags)
{
struct cachefs_block *block;
struct cachefs_page *pageio;
@@ -868,8 +874,6 @@
return 0;
} /* end cachefs_releasepage() */
-EXPORT_SYMBOL(cachefs_releasepage);
-
/*****************************************************************************/
/*
* allocate a block
@@ -960,6 +964,7 @@
if (super->alloc_leaf==CACHEFS_ONDISC_LEAVES_PER_FREE_NODE) {
/* no dependent blocks left - take the alloc node itself */
block = super->alloc_block;
+ BUG_ON(!block);
jentry->block = super->alloc_cur;
BUG_ON(!jentry->block);
@@ -1101,6 +1106,7 @@
test_bit(CACHEFS_BLOCK_CRITICAL,&block->flags)
) {
cachefs_trans_sync(super,0);
+ // TODO: wait for CRITICAL to be unset
}
cachefs_block_put(block);
More information about the linux-afs-cvs
mailing list