afs/fs/cachefs interface.c,NONE,1.1 super.c,1.24,1.25
rootdir.c,1.8,1.9 main.c,1.12,1.13 inode.c,1.15,1.16
index.c,1.13,1.14 cachetest-main.c,1.6,1.7
cachefs-layout.h,1.20,1.21 cachefs-int.h,1.25,1.26 block.c,1.1,1.2
aops.c,1.24,1.25 Makefile,1.14,1.15
dwh at infradead.org
dwh at infradead.org
Thu Apr 17 13:59:06 BST 2003
Update of /home/cvs/afs/fs/cachefs
In directory phoenix.infradead.org:/tmp/cvs-serv12403/fs/cachefs
Modified Files:
super.c rootdir.c main.c inode.c index.c cachetest-main.c
cachefs-layout.h cachefs-int.h block.c aops.c Makefile
Added Files:
interface.c
Log Message:
wrote first part of proper netfs interface... netfs, index and files can now
be registered with the cache
--- NEW FILE interface.c ---
/* interface.c: network FS interface to cache
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells at redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/module.h>
#include "cachefs-int.h"
LIST_HEAD(cachefs_netfs_list);
LIST_HEAD(cachefs_cache_list);
DECLARE_RWSEM(cachefs_addremove_sem);
static cachefs_match_val_t cachefs_fsdef_index_match(struct cachefs_object *index,
const void *_entry);
static void cachefs_fsdef_index_update(struct cachefs_object *source, void *entry);
static struct cachefs_index_def cachefs_fsdef_index_def = {
.name = ".fsdef",
.data_size = sizeof(struct cachefs_ondisc_fsdef),
.match = cachefs_fsdef_index_match,
.update = cachefs_fsdef_index_update
};
static struct cachefs_object cachefs_fsdef_index = {
.idef = &cachefs_fsdef_index_def,
.sem = __RWSEM_INITIALIZER(cachefs_fsdef_index.sem),
.active_inodes = LIST_HEAD_INIT(cachefs_fsdef_index.active_inodes),
};
/* number expected in cachefs_file::numactive */
static int cachefs_num_active_inodes;
/*****************************************************************************/
/*
* register a network filesystem for caching
*/
int cachefs_register_netfs(struct cachefs_netfs *netfs)
{
struct cachefs_netfs *ptr;
int ret;
kenter("{%s}",netfs->name);
INIT_LIST_HEAD(&netfs->link);
INIT_LIST_HEAD(&netfs->primary_index.active_inodes);
init_rwsem(&netfs->primary_index.sem);
netfs->primary_index.iparent = &cachefs_fsdef_index;
/* check it's not already present */
down_write(&cachefs_addremove_sem);
ret = -EEXIST;
list_for_each_entry(ptr,&cachefs_netfs_list,link) {
if (strcmp(ptr->name,netfs->name)==0)
goto error;
}
list_add(&netfs->link,&cachefs_netfs_list);
ret = 0;
error:
up_write(&cachefs_addremove_sem);
kleave(" = %d",ret);
return ret;
} /* end cachefs_register_netfs() */
EXPORT_SYMBOL(cachefs_register_netfs);
/*****************************************************************************/
/*
* unregister a network filesystem from the cache
*/
void cachefs_unregister_netfs(struct cachefs_netfs *netfs)
{
kenter("{%s.%u}",netfs->name,netfs->version);
down_write(&cachefs_addremove_sem);
list_del(&netfs->link);
cachefs_unregister_object(&netfs->primary_index,0);
up_write(&cachefs_addremove_sem);
kleave("");
} /* end cachefs_unregister_netfs() */
EXPORT_SYMBOL(cachefs_unregister_netfs);
/*****************************************************************************/
/*
* declare a mounted cache as being open for business
* - we don't want to do any memory allocation here, lest we have to try and free super on error
*/
void cachefs_add_cache(struct cachefs_super *super, struct cachefs_active_inode *active)
{
unsigned long flags;
printk("\n\n\n");
kenter("");
/* prepare an active-inode record for the FSDEF index of this cache */
atomic_set(&active->usage,2);
active->super = super;
active->ino = CACHEFS_INO_FSDEF_CATALOGUE;
active->flags = (1 << CACHEFS_ACTIVE_INODE_ISINDEX | 1 << CACHEFS_ACTIVE_INODE_LIVE);
active->storage = NULL;
active->object = &cachefs_fsdef_index;
init_waitqueue_head(&active->initwq);
/* actually do the stuff */
down_write(&cachefs_addremove_sem);
list_add(&super->mnt_link,&cachefs_cache_list);
up_write(&cachefs_addremove_sem);
write_lock_irqsave(&super->ino_tree_lock,flags);
rb_link_node(&active->node,NULL,&super->ino_tree.rb_node);
rb_insert_color(&active->node,&super->ino_tree);
write_unlock_irqrestore(&super->ino_tree_lock,flags);
down_write(&cachefs_fsdef_index.sem);
list_add_tail(&active->link,&cachefs_fsdef_index.active_inodes);
up_write(&cachefs_fsdef_index.sem);
cachefs_num_active_inodes++;
kleave("");
} /* end cachefs_add_cache() */
/*****************************************************************************/
/*
* remove an unmounted cache from the list
*/
void cachefs_del_cache(struct cachefs_super *super)
{
kenter("");
down_write(&cachefs_addremove_sem);
BUG();
list_del_init(&super->mnt_link);
up_write(&cachefs_addremove_sem);
kleave("");
} /* end cachefs_del_cache() */
/*****************************************************************************/
/*
* look the object up in the specified cache
* - the specified object must be write-locked by the caller
* - an inode is created on disc if not present if "create" is true
* - all parent index objects are created if necessary
* - returns -ENODATA if the object doesn't exist and "create" is false
*/
static int cachefs_lookup_object(struct cachefs_object *object,
struct cachefs_super *super,
int create)
{
struct cachefs_active_inode *ipactive, *active, *xactive;
struct cachefs_object *iparent;
struct rb_node *parent, **p;
unsigned long flags;
int ret;
iparent = object->iparent;
if (!iparent) return 0; /* FSDEF entries don't have a parent */
kenter("{%s/%s},",iparent->idef->name,object->idef ? (char*)object->idef->name : "<file>");
/* see if there's an entry for this object already */
list_for_each_entry(active,&object->active_inodes,link) {
kdebug("check entry %p x %p [ino %u]",object,super,active->ino);
if (active->super==super) {
kdebug("found entry");
if (active->ino) {
kleave(" = 0 [found ino %u]",active->ino);
return 0;
}
/* entry is negative */
if (!create)
goto nodata;
goto found_entry;
}
}
/* allocate an entry for this object */
kdebug("alloc entry %p x %p",object,super);
active = kmalloc(sizeof(*active),GFP_KERNEL);
if (!active) {
kleave(" = -ENOMEM");
return -ENOMEM;
}
active->super = super;
active->ino = 0;
active->flags = 1 << CACHEFS_ACTIVE_INODE_LIVE;
active->storage = NULL;
active->object = object;
if (object->idef)
active->flags |= 1 << CACHEFS_ACTIVE_INODE_ISINDEX;
atomic_set(&active->usage,1);
INIT_LIST_HEAD(&active->link);
init_waitqueue_head(&active->initwq);
found_entry:
/* we need to insert an entry for this object in the object's parent index, so the first
* thing to do is to see if the parent index is represented on disc, and if not, create it
* if necessary
*/
down_write(&iparent->sem);
ret = cachefs_lookup_object(iparent,super,create);
if (ret<0) {
if (ret==-ENODATA) {
/* set a negative entry */
list_add_tail(&active->link,&object->active_inodes);
}
up_write(&iparent->sem);
goto error2;
}
/* it should now be present - find it */
list_for_each_entry(ipactive,&iparent->active_inodes,link) {
if (ipactive->super==super && ipactive->ino)
goto found_parent_entry;
}
BUG();
found_parent_entry:
kdebug("found_parent_entry");
/* we only need a read-lock on the parent for the rest of this */
downgrade_write(&iparent->sem);
/* search the parent index for a reference compatible with this object */
ret = cachefs_index_search(ipactive,active);
switch (ret) {
default: goto error;
case 0: goto add_to_active_tree;
case -ENOENT:
/* we can at least set a valid negative entry */
list_add_tail(&active->link,&object->active_inodes);
if (!create) {
up_read(&iparent->sem);
goto nodata;
}
/* we need to add the object to the index */
ret = cachefs_index_add(ipactive,active);
if (ret<0)
goto error;
break;
}
/* add the inode to the active tree */
add_to_active_tree:
kdebug("add_to_active_tree");
parent = NULL;
atomic_inc(&active->usage);
write_lock_irqsave(&super->ino_tree_lock,flags);
p = &super->ino_tree.rb_node;
while (*p) {
parent = *p;
xactive = rb_entry(parent,struct cachefs_active_inode,node);
if (active->ino < xactive->ino)
p = &(*p)->rb_left;
else if (active->ino > xactive->ino)
p = &(*p)->rb_right;
else
BUG();
}
rb_link_node(&active->node,parent,p);
rb_insert_color(&active->node,&super->ino_tree);
write_unlock_irqrestore(&super->ino_tree_lock,flags);
up_read(&iparent->sem);
kleave(" = 0");
return 0;
error:
up_read(&iparent->sem);
error2:
if (list_empty(&active->link)) kfree(active);
kleave(" = %d",ret);
return ret;
nodata:
kleave(" = -ENODATA");
return -ENODATA;
} /* end cachefs_lookup_object() */
/*****************************************************************************/
/*
* select a cache on which to store a file
* - the cache addremove semaphore must be at least read-locked by the caller
*/
static struct cachefs_super *cachefs_select_cache_for_file(void)
{
struct cachefs_super *super;
kenter("");
super = NULL;
if (!list_empty(&cachefs_cache_list))
super = list_entry(cachefs_cache_list.next,struct cachefs_super,mnt_link);
kleave(" = %p",super);
return super;
} /* end cachefs_select_cache_for_file() */
/*****************************************************************************/
/*
* register an object
* - all attached caches will be searched to see if they contain this object
* - index objects aren't stored on disc until there's a dependent file that needs storing
* - file objects are stored in a selected cache immediately, and all the indexes forming the path
* to it are instantiated if necessary
*/
int cachefs_register_object(struct cachefs_object *object)
{
struct cachefs_active_inode *active;
struct cachefs_super *super;
struct list_head *_p, *_n;
int ret = 0;
kenter("{%s}",object->idef?(char*)object->idef->name:"<file>");
INIT_LIST_HEAD(&object->active_inodes);
init_rwsem(&object->sem);
down_read(&cachefs_addremove_sem);
if (list_empty(&cachefs_cache_list)) {
up_read(&cachefs_addremove_sem);
kleave(" = 0 [no caches]");
return 0;
}
down_write(&object->sem);
/* search every cache to see if the object is already present */
list_for_each_entry(super,&cachefs_cache_list,mnt_link) {
ret = cachefs_lookup_object(object,super,0);
switch (ret) {
case 0:
if (!object->idef)
break; /* only want the first file entry */
case -ENODATA:
continue;
default:
goto error;
}
}
/* if this object is a file, select a cache on which to store it */
if (!object->idef) {
super = cachefs_select_cache_for_file();
/* we don't want to keep any negative records for a file other than the one for the
* chosen superblock (which we'll turn into a positive entry)
*/
list_for_each_safe(_p,_n,&object->active_inodes) {
active = list_entry(_p,struct cachefs_active_inode,link);
if (active->super==super || active->ino==0) {
list_del(&active->link);
kfree(active);
}
}
ret = 0;
if (!super)
goto error; /* couldn't decide on a cache */
/* instantiate the file */
ret = cachefs_lookup_object(object,super,1);
switch (ret) {
case 0: break;
case -ENODATA: BUG();
default: goto error;
}
}
/* the caller shouldn't see the fact that we don't have any attached inodes yet */
if (ret==-ENODATA) ret = 0;
error:
up_write(&object->sem);
up_read(&cachefs_addremove_sem);
kleave(" = %d",ret);
return ret;
} /* end cachefs_register_object() */
EXPORT_SYMBOL(cachefs_register_object);
/*****************************************************************************/
/*
* unregister an object from the cache
* - the object will be marked as recyclable on disc if retire is true
*/
void cachefs_unregister_object(struct cachefs_object *object, int retire)
{
kenter("{%s},%d",object->idef?(char*)object->idef->name:"<file>",retire);
BUG();
} /* end cachefs_unregister_object() */
EXPORT_SYMBOL(cachefs_unregister_object);
/*****************************************************************************/
/*
* see if the netfs definition matches
*/
static cachefs_match_val_t cachefs_fsdef_index_match(struct cachefs_object *index,
const void *_entry)
{
const struct cachefs_ondisc_fsdef *fsdef = _entry;
struct cachefs_netfs *netfs = container_of(index,struct cachefs_netfs,primary_index);
kenter("{%s.%u},{%s.%u}",
netfs->name,netfs->version,
fsdef->name,fsdef->version);
if (strncmp(netfs->name,fsdef->name,sizeof(fsdef->name))!=0) {
kleave(" = FAILED");
return CACHEFS_MATCH_FAILED;
}
if (netfs->version==fsdef->version) {
kleave(" = SUCCESS");
return CACHEFS_MATCH_SUCCESS;
}
kleave(" = SUCCESS_DELETE");
return CACHEFS_MATCH_SUCCESS_DELETE;
} /* end cachefs_fsdef_index_match() */
/*****************************************************************************/
/*
* update the netfs definition to be stored on disc
*/
static void cachefs_fsdef_index_update(struct cachefs_object *source, void *entry)
{
struct cachefs_ondisc_fsdef *fsdef = entry;
struct cachefs_netfs *netfs = container_of(source,struct cachefs_netfs,primary_index);
kenter("{%s.%u},",netfs->name,netfs->version);
strncpy(fsdef->name,netfs->name,sizeof(fsdef->name));
fsdef->version = netfs->version;
} /* end cachefs_fsdef_index_update() */
Index: super.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/super.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- super.c 2 Apr 2003 09:12:31 -0000 1.24
+++ super.c 17 Apr 2003 11:59:03 -0000 1.25
@@ -49,7 +49,6 @@
.statfs = cachefs_statfs,
.alloc_inode = cachefs_alloc_inode,
.write_inode = cachefs_write_inode,
- .drop_inode = generic_delete_inode,
.destroy_inode = cachefs_destroy_inode,
.clear_inode = cachefs_clear_inode,
.write_super = cachefs_write_super,
@@ -119,16 +118,29 @@
char *dev_name,
void *options)
{
+ struct cachefs_active_inode *active;
struct super_block *sb;
_enter(",,%s,%p",dev_name,options);
+ /* pre-allocate an active-inode record for the FSDEF index of this cache
+ * - we don't want to have to try and get rid of the superblock due to an error after
+ * we've got it
+ */
+ active = kmalloc(sizeof(*active),GFP_KERNEL);
+ if (!active) {
+ kleave(" = -ENOMEM");
+ return ERR_PTR(-ENOMEM);
+ }
+
/* allocate a device superblock */
sb = get_sb_bdev(fs_type,flags,dev_name,options,cachefs_fill_super);
/* if successful add to the list of available caches */
if (!IS_ERR(sb) && sb->s_fs_info)
- cachefs_add_cache((struct cachefs_super *)sb->s_fs_info);
+ cachefs_add_cache((struct cachefs_super *)sb->s_fs_info,active);
+ else
+ kfree(active);
_leave(" = %p",sb);
return sb;
@@ -260,7 +272,6 @@
super->ujnl_step = bdev_hardsect_size(super->sb->s_bdev);
INIT_LIST_HEAD(&super->mnt_link);
- INIT_LIST_HEAD(&super->cross_indexes);
rwlock_init(&super->blk_tree_lock);
@@ -297,12 +308,7 @@
init_completion(&super->dmn_dead);
init_waitqueue_head(&super->dmn_sleepq);
- /* initialise the fsdef index */
- ret = cachefs_generate_cross_index(super,&cachefs_fsdef,&super->fsdef_index);
- if (ret<0)
- goto error;
-
- super->fsdef_index->entry_id = UINT_MAX;
+ rwlock_init(&super->ino_tree_lock);
/* create the linear-mapping inode */
ret = cachefs_iget(super,CACHEFS_INO_MISC,&inode2);
@@ -408,7 +414,6 @@
wait_for_completion(&super->dmn_dead);
}
- if (super->fsdef_index) kfree(super->fsdef_index);
if (super->alloc_node) page_cache_release(super->alloc_node);
if (super->recycle_node) page_cache_release(super->recycle_node);
if (super->rcm_atm_list) free_page((unsigned long)super->rcm_atm_list);
@@ -697,9 +702,6 @@
wake_up(&super->dmn_sleepq);
wait_for_completion(&super->dmn_dead);
- if (super->fsdef_index)
- kfree(super->fsdef_index);
-
if (super->alloc_node) {
dbgpgfree(super->alloc_node);
page_cache_release(super->alloc_node);
@@ -770,8 +772,6 @@
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) {
memset(inode,0,sizeof(*inode));
- INIT_LIST_HEAD(&inode->index_link);
- INIT_LIST_HEAD(&inode->cache_link);
inode_init_once(&inode->vfs_inode);
}
Index: rootdir.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/rootdir.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- rootdir.c 2 Apr 2003 09:12:31 -0000 1.8
+++ rootdir.c 17 Apr 2003 11:59:04 -0000 1.9
@@ -71,9 +71,9 @@
unsigned char *ptr;
void *content;
char *name;
- int loop, ret;
+ int loop, ret, type;
- kenter(",{%lu},%lu,%lu",page->index,offset,size);
+ _enter(",{%lu},%lu,%lu",page->index,offset,size);
rec = (struct cachefs_readdir_record *) desc->buf;
@@ -120,7 +120,7 @@
for (loop=0; loop<4; loop++) {
int ksize = rec->keys[loop] & CACHEFS_ONDISC_INDEXKEY_KLEN;
- kdebug("- key %04hx",rec->keys[loop]);
+ _debug("- key %04hx",rec->keys[loop]);
if (loop>0) *name++ = ',';
@@ -161,7 +161,7 @@
tmp = rec->dpos_off + (page->index * rec->epp) + offset/rec->esize;
- kdebug("dirent: %d '%s' ino=%u",name-rec->scratch,rec->scratch,xent->ino);
+ _debug("dirent: %d '%s' ino=%u",name-rec->scratch,rec->scratch,xent->ino);
if (name == rec->scratch) {
desc->count -= rec->esize;
@@ -170,12 +170,16 @@
continue;
}
+ type = DT_REG;
+ if (xent->type==CACHEFS_ONDISC_INDEX_INDEXFILE)
+ type = DT_DIR;
+
if (rec->filldir(rec->cookie,
rec->scratch,
name - rec->scratch,
tmp,
xent->ino,
- DT_DIR)<0
+ type)<0
) {
desc->count = 0;
goto done;
@@ -194,7 +198,7 @@
kunmap(page);
done_already:
- kleave(" = %d",ret);
+ _leave(" = %d",ret);
return ret;
} /* end cachefs_readdir_actor() */
@@ -214,7 +218,7 @@
inode = CACHEFS_FS_I(file->f_dentry->d_inode);
- kenter("{%Ld,{%lu}}",file->f_pos,inode->vfs_inode.i_ino);
+ _enter("{%Ld,{%lu}}",file->f_pos,inode->vfs_inode.i_ino);
rec.scratch = (char*) get_zeroed_page(GFP_KERNEL);
dbgpgalloc(rec.scratch);
@@ -286,7 +290,7 @@
desc.buf = (char*) &rec;
desc.error = 0;
- kdebug("do read: isz=%llu pos=%llu count=%u",
+ _debug("do read: isz=%llu pos=%llu count=%u",
inode->vfs_inode.i_size,pos,desc.count);
do_generic_file_read(file,&pos,&desc,cachefs_readdir_actor);
@@ -295,7 +299,7 @@
file->f_pos += ((unsigned)(pos & ~PAGE_MASK) + rec.esize - 1) / rec.esize;
file->f_pos += rec.dpos_off;
- kdebug("done read: err=%d pos=%llu fpos=%llu",desc.error,pos,file->f_pos);
+ _debug("done read: err=%d pos=%llu fpos=%llu",desc.error,pos,file->f_pos);
ret = desc.error;
if (ret<0)
@@ -308,7 +312,7 @@
error:
dbgpgfree(rec.scratch);
free_page((unsigned long) rec.scratch);
- kleave(" = %d",ret);
+ _leave(" = %d",ret);
return ret;
} /* end cachefs_root_readdir() */
@@ -327,7 +331,7 @@
void *content;
int ret;
- kenter(",{%lu},%lu,%lu",page->index,offset,size);
+ _enter(",{%lu},%lu,%lu",page->index,offset,size);
rec = (struct cachefs_lookup_record *) desc->buf;
ret = size;
@@ -372,7 +376,7 @@
desc->count -= ret;
desc->written += ret;
- kleave(" = %d",ret);
+ _leave(" = %d",ret);
return ret;
} /* end cachefs_lookup_actor() */
@@ -397,7 +401,7 @@
dir = CACHEFS_FS_I(_dir);
name = dentry->d_name.name;
- kenter("{%lu},{%s}",dir->vfs_inode.i_ino,name);
+ _enter("{%lu},{%s}",dir->vfs_inode.i_ino,name);
rec.key = NULL;
rec.esize = dir->index_esize;
@@ -487,7 +491,7 @@
goto not_found;
x = isdigit(*name) ? *name-'0' : toupper(*name)-'A'+10;
name++;
- x <<= 0x10;
+ x <<= 4;
if (!isxdigit(*name))
goto not_found;
@@ -576,7 +580,7 @@
ret = -ENOENT;
error:
if (rec.key) free_page((unsigned long) rec.key);
- kleave(" = %d",ret);
+ _leave(" = %d",ret);
return ERR_PTR(ret);
/* get the inode */
@@ -585,14 +589,14 @@
get:
ret = cachefs_iget(dir->vfs_inode.i_sb->s_fs_info,ino,&target);
if (ret<0) {
- kleave(" = %d",ret);
+ _leave(" = %d",ret);
return ERR_PTR(ret);
}
/* instantiate the dentry */
instantiate:
d_add(dentry,&target->vfs_inode);
- kleave(" = NULL");
+ _leave(" = NULL");
return NULL;
} /* end cachefs_root_lookup() */
@@ -609,11 +613,11 @@
unsigned long flags;
int ret;
- kenter("{%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");
- kleave(" = -ENOANO");
+ _leave(" = -ENOANO");
return -ENOANO;
}
@@ -622,7 +626,7 @@
/* mark for reclamation under journalling */
trans = cachefs_trans_alloc(super,GFP_KERNEL);
if (!trans) {
- kleave(" = -ENOMEM");
+ _leave(" = -ENOMEM");
return -ENOMEM;
}
@@ -634,7 +638,7 @@
ret = cachefs_trans_mark(trans);
if (ret<0) {
cachefs_trans_put(trans);
- kleave(" = %d",ret);
+ _leave(" = %d",ret);
return ret;
}
@@ -661,6 +665,6 @@
set_bit(CACHEFS_SUPER_DO_RECLAIM,&super->flags);
wake_up(&super->dmn_sleepq);
- kleave(" = 0");
+ _leave(" = 0");
return 0;
} /* end cachefs_root_rmdir_unlink() */
Index: main.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/main.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- main.c 7 Mar 2003 23:53:38 -0000 1.12
+++ main.c 17 Apr 2003 11:59:04 -0000 1.13
@@ -16,17 +16,6 @@
#include <linux/slab.h>
#include "cachefs-int.h"
-struct cell_data {
- u_int8_t name[64];
- u_int32_t servers[15];
-} cell_data = { "cambridge.redhat.com", { 0x12345678, 0x11223344 } };
-
-static struct cachefs_index cachetest_vldb = {
- .name = "vldb",
- .data_size = 124,
- .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
-};
-
int cachefs_debug = 0;
static int cachefs_init(void);
@@ -39,78 +28,6 @@
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(cachefs_register_netfs);
-EXPORT_SYMBOL(cachefs_unregister_netfs);
-
-static LIST_HEAD(cachefs_netfs_list);
-static rwlock_t cachefs_netfs_list_lock = RW_LOCK_UNLOCKED;
-static LIST_HEAD(cachefs_cache_list);
-static rwlock_t cachefs_cache_list_lock = RW_LOCK_UNLOCKED;
-static DECLARE_RWSEM(cachefs_addremove_sem);
-
-static void cachefs_mesh_cache_and_netfs(struct cachefs_super *super, struct cachefs_netfs *netfs);
-
-static void cachefs_unmesh_cache_and_netfs(struct cachefs_super *super,
- struct cachefs_netfs *netfs);
-
-static int cachefs_fsdef_index_match(const void *_entry, const void *_data);
-
-struct cachefs_netfs cachefs_fsdef = {
- .name = "CacheFS",
- .version = 1,
- .link = LIST_HEAD_INIT(cachefs_fsdef.link),
-};
-
-struct cachefs_index cachefs_fsdef_index = {
- .name = "FSDEF",
- .data_size = sizeof(struct cachefs_ondisc_fsdef),
-};
-
-/*****************************************************************************/
-/*
- * clear the dead space between task_struct and kernel stack
- * - called by supplying -finstrument-functions to gcc
- */
-#if 1
-void __cyg_profile_func_enter (void *this_fn, void *call_site)
-__attribute__((no_instrument_function));
-
-void __cyg_profile_func_enter (void *this_fn, void *call_site)
-{
- asm volatile(" movl %%esp,%%edi \n"
- " andl %0,%%edi \n"
- " addl %1,%%edi \n"
- " movl %%esp,%%ecx \n"
- " subl %%edi,%%ecx \n"
- " shrl $2,%%ecx \n"
- " movl $0xedededed,%%eax \n"
- " rep stosl \n"
- :
- : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
- : "eax", "ecx", "edi", "memory", "cc"
- );
-}
-
-void __cyg_profile_func_exit(void *this_fn, void *call_site)
-__attribute__((no_instrument_function));
-
-void __cyg_profile_func_exit(void *this_fn, void *call_site)
-{
- asm volatile(" movl %%esp,%%edi \n"
- " andl %0,%%edi \n"
- " addl %1,%%edi \n"
- " movl %%esp,%%ecx \n"
- " subl %%edi,%%ecx \n"
- " shrl $2,%%ecx \n"
- " movl $0xdadadada,%%eax \n"
- " rep stosl \n"
- :
- : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
- : "eax", "ecx", "edi", "memory", "cc"
- );
-}
-#endif
-
/*****************************************************************************/
/*
* initialise the fs caching module
@@ -153,318 +70,45 @@
/*****************************************************************************/
/*
- * register a network filesystem for caching
- */
-int cachefs_register_netfs(struct cachefs_netfs *netfs)
-{
- struct cachefs_super *super;
- struct cachefs_netfs *ptr;
- struct list_head *_p;
- unsigned long flags;
- int ret;
-
- kenter("{%s}",netfs->name);
-
- INIT_LIST_HEAD(&netfs->link);
- INIT_LIST_HEAD(&netfs->cross_indexes);
-
- /* check it's not already there */
- down_write(&cachefs_addremove_sem);
-
- ret = -EEXIST;
- read_lock_irqsave(&cachefs_netfs_list_lock,flags);
- list_for_each(_p,&cachefs_netfs_list) {
- ptr = list_entry(_p,struct cachefs_netfs,link);
- if (strcmp(ptr->name,netfs->name)==0)
- break;
- }
- if (_p==&cachefs_netfs_list)
- ret = 0;
- read_unlock_irqrestore(&cachefs_netfs_list_lock,flags);
-
- if (ret==0) {
- write_lock_irqsave(&cachefs_netfs_list_lock,flags);
- list_add(&netfs->link,&cachefs_netfs_list);
- write_unlock_irqrestore(&cachefs_netfs_list_lock,flags);
-
- /* prepare the netfs for caching on every cache we know about already
- * - don't need to lock the caches list as it can only be changed by someone
- * holding the addremove sem, and we've got a write lock on that
- */
- list_for_each(_p,&cachefs_cache_list) {
- super = list_entry(_p,struct cachefs_super,mnt_link);
- cachefs_mesh_cache_and_netfs(super,netfs);
- }
- }
-
- up_write(&cachefs_addremove_sem);
-
- kleave(" = %d",ret);
- return ret;
-} /* end cachefs_register_netfs() */
-
-/*****************************************************************************/
-/*
- * unregister a network filesystem from the cache
- */
-void cachefs_unregister_netfs(struct cachefs_netfs *netfs)
-{
- struct cachefs_super *super;
- struct list_head *_p;
- unsigned long flags;
-
- kenter("{%s}",netfs->name);
-
- down_write(&cachefs_addremove_sem);
-
- list_for_each(_p,&cachefs_cache_list) {
- super = list_entry(_p,struct cachefs_super,mnt_link);
- cachefs_unmesh_cache_and_netfs(super,netfs);
- }
-
- write_lock_irqsave(&cachefs_netfs_list_lock,flags);
- list_del_init(&netfs->link);
- write_unlock_irqrestore(&cachefs_netfs_list_lock,flags);
-
- up_write(&cachefs_addremove_sem);
-
- kleave("");
-} /* end cachefs_unregister_fs() */
-
-/*****************************************************************************/
-/*
- * generate an internal cross-index block from a netfs definition
- */
-int cachefs_generate_cross_index(struct cachefs_super *super,
- struct cachefs_netfs *netfs,
- struct cachefs_cross_index **_cross)
-{
- struct cachefs_cross_index *cross;
-
- kenter(",%s,",netfs->name);
-
- cross = kmalloc(sizeof(struct cachefs_cross_index),GFP_KERNEL);
- if (!cross) {
- kleave(" = -ENOMEM");
- return -ENOMEM;
- }
- memset(cross,0,sizeof(*cross));
-
- cross->netfs = netfs;
- cross->super = super;
-
- INIT_LIST_HEAD(&cross->netfs_link);
- INIT_LIST_HEAD(&cross->super_link);
-
- memcpy(cross->layout.name,netfs->name,sizeof(cross->layout.name));
-
- cross->layout.version = netfs->version;
-
- *_cross = cross;
- kleave(" = 0 [%p]",*_cross);
- return 0;
-} /* end cachefs_generate_cross_index() */
-
-/*****************************************************************************/
-/*
- * make sure a cache and a filesystem are cross-linked
- * - the addremove semaphore must be held write-locked by the caller
- */
-static void cachefs_mesh_cache_and_netfs(struct cachefs_super *super, struct cachefs_netfs *netfs)
-{
- struct cachefs_cross_index *cross;
- int ret;
-
- kenter("%p,{%s}",super,netfs->name);
-
- ret = cachefs_generate_cross_index(super,netfs,&cross);
- if (ret<0) {
- printk("CacheFS: Couldn't generate cross-index: %d\n",ret);
- return;
- }
-
- /* TODO: see if the cache already knows about this filesystem */
- ret = cachefs_index_search(super->fsdef_index,
- CACHEFS_INO_FSDEF_CATALOGUE,
- cachefs_fsdef_index_match,
- &cross->layout);
- if (ret<0) {
- struct cachefs_ondisc_fsdef data;
-
- if (ret!=-ENOENT) {
- printk("CacheFS: Couldn't scan fsdef catalogue: %d\n",ret);
- goto error;
- }
-
- kdebug("FSDEF entry not in cache");
-
- memset(&data,0,sizeof(data));
- strncpy(data.name,netfs->name,sizeof(data.name));
- data.version = netfs->version;
-
- ret = cachefs_index_add(super,CACHEFS_INO_FSDEF_CATALOGUE,netfs->primary,&data);
- if (ret<0) {
- printk("CacheFS: Couldn't add fsdef to catalogue: %d\n",ret);
- goto error;
- }
- kdebug("FSDEF entry added to cache at %d\n",ret);
-
- int cell = cachefs_index_add(super,ret,&cachetest_vldb,&cell_data);
- if (cell<0) {
- printk("CacheFS: Couldn't add CELL to catalogue: %d\n",cell);
- ret = cell;
- goto error;
- }
- kdebug("CELL entry added to cache at %d\n",cell);
-
- }
- else {
- kdebug("FSDEF entry in cache at %d",ret);
- }
-
- /* polish off the definitions */
- cross->entry_id = ret;
-
- write_lock(&cachefs_netfs_list_lock);
- write_lock(&cachefs_cache_list_lock);
-
- list_add(&cross->netfs_link,&netfs->cross_indexes);
- list_add(&cross->super_link,&super->cross_indexes);
-
- write_unlock(&cachefs_cache_list_lock);
- write_unlock(&cachefs_netfs_list_lock);
-
- kleave("");
- return;
-
- error:
- kfree(cross);
- kleave(" [error %d]",ret);
-} /* end cachefs_mesh_cache_and_netfs() */
-
-/*****************************************************************************/
-/*
- * disassociate a cache and a filesystem
- * - the addremove semaphore must be held write-locked by the caller
- */
-static void cachefs_unmesh_cache_and_netfs(struct cachefs_super *super,
- struct cachefs_netfs *netfs)
-{
- struct cachefs_cross_index *cross;
- struct list_head *_p;
-
- kenter("");
-
- /* find and unlink the cross-bonding record */
- cross = NULL;
- write_lock(&cachefs_netfs_list_lock);
- write_lock(&cachefs_cache_list_lock);
-
- list_for_each(_p,&super->cross_indexes) {
- cross = list_entry(_p,struct cachefs_cross_index,super_link);
- if (cross->super==super)
- break;
- }
-
- if (_p==&super->cross_indexes) {
- cross = NULL;
- }
- else {
- list_del_init(&cross->netfs_link);
- list_del_init(&cross->super_link);
- }
-
- write_unlock(&cachefs_cache_list_lock);
- write_unlock(&cachefs_netfs_list_lock);
-
- if (!cross) {
- kleave(" [unattached]");
- return;
- }
-
- dbgfree(cross);
- kfree(cross);
-
- kleave("");
-} /* end cachefs_unmesh_cache_and_netfs() */
-
-/*****************************************************************************/
-/*
- * add a freshly mounted cache to the list
+ * clear the dead space between task_struct and kernel stack
+ * - called by supplying -finstrument-functions to gcc
*/
-void cachefs_add_cache(struct cachefs_super *super)
-{
- struct cachefs_netfs *netfs;
- struct list_head *_p;
-
- printk("\n\n\n");
- kenter("");
-
- down_write(&cachefs_addremove_sem);
-
- list_add(&super->mnt_link,&cachefs_cache_list);
-
- /* prepare the newly mounted cache for caching every cacheable fs we know about already
- * - don't need to lock the fsdefs list as it can only be changed by someone holding the
- * addremove sem, and we've got a write lock on that
- */
- list_for_each(_p,&cachefs_netfs_list) {
- netfs = list_entry(_p,struct cachefs_netfs,link);
- cachefs_mesh_cache_and_netfs(super,netfs);
- }
-
- up_write(&cachefs_addremove_sem);
-
- kleave("");
-} /* end cachefs_add_cache() */
+#if 1
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
-/*****************************************************************************/
-/*
- * remove an unmounted cache from the list
- */
-void cachefs_del_cache(struct cachefs_super *super)
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
{
- struct cachefs_netfs *netfs;
- struct list_head *_p;
-
- kenter("");
-
- down_write(&cachefs_addremove_sem);
-
- list_for_each(_p,&cachefs_netfs_list) {
- netfs = list_entry(_p,struct cachefs_netfs,link);
- cachefs_unmesh_cache_and_netfs(super,netfs);
- }
-
- list_del_init(&super->mnt_link);
-
- up_write(&cachefs_addremove_sem);
+ asm volatile(" movl %%esp,%%edi \n"
+ " andl %0,%%edi \n"
+ " addl %1,%%edi \n"
+ " movl %%esp,%%ecx \n"
+ " subl %%edi,%%ecx \n"
+ " shrl $2,%%ecx \n"
+ " movl $0xedededed,%%eax \n"
+ " rep stosl \n"
+ :
+ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+ : "eax", "ecx", "edi", "memory", "cc"
+ );
+}
- kleave("");
-} /* end cachefs_del_cache() */
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
-/*****************************************************************************/
-/*
- * see if a file definition entry matches a key
- */
-static int cachefs_fsdef_index_match(const void *_entry, const void *_data)
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
{
- const struct cachefs_ondisc_fsdef *entry = _entry;
- const struct cachefs_ondisc_fsdef *data = _data;
- int ret;
-
- kenter("");
-
- ret = 0;
- if (entry->name[0]) {
- if (memcmp(entry->name,data->name,sizeof(entry->name))==0) {
- ret = 1;
-
- if (memcmp(entry,data,sizeof(entry))!=0)
- ret = 2; /* incompatible layout */
- }
- }
-
- kleave(" = %d",ret);
- return ret;
-} /* end cachefs_fsdef_index_match() */
+ asm volatile(" movl %%esp,%%edi \n"
+ " andl %0,%%edi \n"
+ " addl %1,%%edi \n"
+ " movl %%esp,%%ecx \n"
+ " subl %%edi,%%ecx \n"
+ " shrl $2,%%ecx \n"
+ " movl $0xdadadada,%%eax \n"
+ " rep stosl \n"
+ :
+ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+ : "eax", "ecx", "edi", "memory", "cc"
+ );
+}
+#endif
Index: inode.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/inode.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- inode.c 21 Mar 2003 14:01:01 -0000 1.15
+++ inode.c 17 Apr 2003 11:59:04 -0000 1.16
@@ -202,7 +202,7 @@
storage = kmap(inode->storage) + inode->storage_offset;
- inode->vfs_inode.i_mode = S_IFREG | S_IRUGO | S_IWUSR;
+ inode->vfs_inode.i_mode = S_IFREG | S_IRUGO;
inode->vfs_inode.i_uid = 0;
inode->vfs_inode.i_gid = 0;
inode->vfs_inode.i_nlink = 1;
@@ -228,6 +228,7 @@
if (inode->index_esize || inode->vfs_inode.i_ino==CACHEFS_INO_ROOTDIR) {
inode->index_epp = PAGE_SIZE / storage->index_esize;
inode->vfs_inode.i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+ inode->vfs_inode.i_nlink = 2;
inode->vfs_inode.i_op = &cachefs_root_inode_operations;
inode->vfs_inode.i_fop = &cachefs_root_file_operations;
}
@@ -439,7 +440,7 @@
/*****************************************************************************/
/*
- * clear an AFS inode
+ * clear an inode
*/
void cachefs_clear_inode(struct inode *vfs_inode)
{
@@ -447,7 +448,7 @@
inode = CACHEFS_FS_I(vfs_inode);
- kenter("ino=%lu",inode->vfs_inode.i_ino);
+ kenter("{ino=%lu nl=%u}",inode->vfs_inode.i_ino,inode->vfs_inode.i_nlink);
_leave("");
} /* end cachefs_clear_inode() */
Index: index.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/index.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- index.c 2 Apr 2003 09:12:31 -0000 1.13
+++ index.c 17 Apr 2003 11:59:04 -0000 1.14
@@ -29,9 +29,9 @@
#include "cachefs-int.h"
struct cachefs_index_search_record {
+ struct cachefs_object *index;
+ struct cachefs_object *target;
struct cachefs_inode *iinode;
- cachefs_index_match_t matchfnx;
- void *data;
unsigned entsize;
int entry;
};
@@ -82,7 +82,7 @@
xent->state==CACHEFS_ONDISC_INDEX_RECYCLE)
continue;
- if (rec->matchfnx(xent->data,rec->data)) {
+ if (rec->index->idef->match(rec->index,xent->data)) {
rec->entry = offset/tmp + page->index*(PAGE_SIZE/tmp);
desc->count = 0;
ret = 0;
@@ -102,12 +102,12 @@
/*****************************************************************************/
/*
- * search for the specified key in an index in one cache
+ * search for the specified target object in an index in one cache
* - returns -ENOENT if not found
* - returns index number (>=0) if found and updates the atime for that entry
*/
-int cachefs_index_search(struct cachefs_cross_index *cross, unsigned ino,
- cachefs_index_match_t matchfnx, void *data)
+int cachefs_index_search(struct cachefs_active_inode *index,
+ struct cachefs_active_inode *target)
{
struct cachefs_index_search_record rec;
struct file_ra_state ra;
@@ -115,15 +115,15 @@
loff_t pos;
int ret;
- kenter("{%s},%u,",cross->layout.name,ino);
+ kenter("{%s,%u}",index->object->idef->name,index->ino);
/* get the inode */
- ret = cachefs_iget(cross->super,ino,&rec.iinode);
+ ret = cachefs_iget(index->super,index->ino,&rec.iinode);
if (ret<0)
goto error;
- rec.matchfnx = matchfnx;
- rec.data = data;
+ rec.index = index->object;
+ rec.target = target->object;
rec.entry = UINT_MAX;
rec.entsize = rec.iinode->index_esize;
@@ -156,7 +156,6 @@
{
struct cachefs_ondisc_index_entry *xent;
struct cachefs_ondisc_storage *storage;
- struct cachefs_cross_index *cross;
struct cachefs_inode *iinode;
struct cachefs_page *pageio;
u_int32_t entry, next;
@@ -174,7 +173,6 @@
next = storage->freelink;
kunmap(storage);
- cross = iinode->cross_index;
entry = page->index * iinode->index_epp;
content = kmap(page);
@@ -294,12 +292,12 @@
/*****************************************************************************/
/*
* allocate an entry in the specified index file and associate an inode with it
- * - if an index definition is supplied, then the new inode is formatted according to that
- * - if an index definition is not supplied, then the new inode will be a flat data file
+ * - target->object->def determines whether the new inode will be a file or an index
+ * - if an inode is successfully allocated, target->ino will be set with the inode number
*/
int cachefs_index_allocate(struct cachefs_inode *iinode,
- const struct cachefs_index *definition,
- const void *data)
+ struct cachefs_active_inode *index,
+ struct cachefs_active_inode *target)
{
struct cachefs_ondisc_index_entry *xent;
struct cachefs_ondisc_storage *storage;
@@ -309,9 +307,9 @@
unsigned ino, ixentry, offset, inonext, ixnext, ino_offset;
int ret, loop;
- kenter("{%lu},,,",iinode->vfs_inode.i_ino);
+ kenter("{%lu},{%s},",iinode->vfs_inode.i_ino,index->object->idef->name);
- super = iinode->vfs_inode.i_sb->s_fs_info;
+ super = index->super;
inopage = NULL;
ixpage = NULL;
trans = NULL;
@@ -336,7 +334,7 @@
offset = (ixentry % iinode->index_epp) * iinode->index_esize;
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INDEX_ALLOCING;
- if (!definition)
+ if (!target->object->idef)
trans->jentry->mark = CACHEFS_ONDISC_UJNL_INODE_ALLOCING;
trans->jentry->index = iinode->vfs_inode.i_ino;
@@ -369,7 +367,13 @@
xent = kmap(ixpage) + offset;
xent->state = CACHEFS_ONDISC_INDEX_ACTIVE;
xent->ino = ino;
- memcpy(xent->data,data,iinode->index_dsize);
+ xent->type = CACHEFS_ONDISC_INDEX_DATAFILE;
+
+ if (target->object->idef)
+ xent->type = CACHEFS_ONDISC_INDEX_INDEXFILE;
+
+ index->object->idef->update(target->object,xent->data);
+
kunmap(ixpage);
/* modify the index inode storage entry */
@@ -391,7 +395,9 @@
storage->pindex = iinode->vfs_inode.i_ino;
storage->pindex_entry = ixentry;
- if (definition) {
+ if (target->object->idef) {
+ struct cachefs_index_def *definition = target->object->idef;
+
storage->index_dsize = definition->data_size;
storage->index_esize = storage->index_dsize;
storage->index_esize += sizeof(struct cachefs_ondisc_index_entry);
@@ -417,7 +423,7 @@
cachefs_trans_commit(trans);
trans = NULL;
- ret = ino;
+ target->ino = ino;
error:
if (trans) cachefs_trans_put(trans);
@@ -432,22 +438,20 @@
/*
* allocate an entry in the specified index and associate a new inode with it
*/
-int cachefs_index_add(struct cachefs_super *super,
- unsigned iino,
- const struct cachefs_index *definition,
- const void *data)
+int cachefs_index_add(struct cachefs_active_inode *index,
+ struct cachefs_active_inode *target)
{
struct cachefs_inode *iinode;
int ret;
- kenter(",%u,{%s},",iino,definition->name);
+ kenter("{%u,%s},",index->ino,index->object->idef->name);
/* get the index inode */
- ret = cachefs_iget(super,iino,&iinode);
+ ret = cachefs_iget(index->super,index->ino,&iinode);
if (ret<0)
goto error;
- ret = cachefs_index_allocate(iinode,definition,data);
+ ret = cachefs_index_allocate(iinode,index,target);
cachefs_iput(iinode);
error:
@@ -552,4 +556,4 @@
kleave(" = %d",ret);
return ret;
-} /* end cachefs_index_add() */
+} /* end cachefs_index_zap() */
Index: cachetest-main.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachetest-main.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- cachetest-main.c 7 Mar 2003 23:53:38 -0000 1.6
+++ cachetest-main.c 17 Apr 2003 11:59:04 -0000 1.7
@@ -13,8 +13,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/pagemap.h>
+#include <linux/in.h>
#include <linux/cachefs.h>
#define kenter(FMT,...) printk("==> %s("FMT")\n",__FUNCTION__,##__VA_ARGS__)
@@ -31,36 +30,105 @@
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");
-static int cells_match(const void *_entry, const void *_data);
-static int vldb_match(const void *_entry, const void *_data);
-static int files_match(const void *_entry, const void *_data);
+struct afs_cell {
+ char name[64]; /* [KEY] cell name */
+ struct in_addr vlservers[15]; /* VLDB server IP addresses */
+ struct cachefs_object cache; /* caching cookie */
+};
+
+struct afs_volume {
+ char name[64]; /* [KEY] volume name */
+ u_int32_t vids[3]; /* volume IDs */
+ struct in_addr fsservers[8]; /* file server IP addresses */
+ u_int8_t fstypemsks[8]; /* file server volume type masks */
+ struct cachefs_object cache; /* caching cookie */
+};
+
+struct afs_inode {
+ u_int32_t fid; /* [KEY] file ID */
+ struct cachefs_object cache; /* caching cookie */
+};
-static struct cachefs_index cachetest_cells = {
- .name = "cells",
+/* AFS network filesystem
+ * - the primary index contains cell references
+ */
+static cachefs_match_val_t cell_match(struct cachefs_object *target, const void *entry);
+static void cell_update(struct cachefs_object *source, void *entry);
+
+static struct cachefs_index_def cachetest_netfs = {
+ .name = "AFS",
.data_size = 124,
.keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
+ .match = cell_match,
+ .update = cell_update,
+};
+
+static struct cachefs_netfs_operations cachetest_ops = {
};
-static struct cachefs_index cachetest_vldb = {
- .name = "vldb",
+static struct cachefs_netfs cachetest = {
+ .name = "cachetest",
+ .version = 0,
+ .primary_index = { .idef = &cachetest_netfs},
+ .ops = &cachetest_ops,
+};
+
+/* AFS cell
+ * - this is an index containing volume location database references
+ * - objects of this type will be typically embedded in the AFS fs's cell record structures
+ */
+static cachefs_match_val_t vldb_match(struct cachefs_object *target, const void *entry);
+static void vldb_update(struct cachefs_object *source, void *entry);
+
+static struct cachefs_index_def cachetest_cell = {
+ .name = "cell",
.data_size = 124,
.keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
+ .match = vldb_match,
+ .update = vldb_update,
};
-static struct cachefs_index cachetest_files = {
- .name = "files",
+static struct afs_cell afs_mycell = {
+ .name = "cambridge.redhat.com",
+ .cache = {
+ .idef = &cachetest_cell,
+ .iparent = &cachetest.primary_index,
+ },
+};
+
+/* AFS root volume
+ * - this is an index containing file references
+ * - objects of this type will be typically embedded in the AFS fs's volume record structures
+ */
+static cachefs_match_val_t file_match(struct cachefs_object *target, const void *entry);
+static void file_update(struct cachefs_object *source, void *entry);
+
+static struct cachefs_index_def cachetest_volume = {
+ .name = "volume",
.data_size = 4,
.keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 },
+ .match = file_match,
+ .update = file_update,
};
-static struct cachefs_netfs_operations cachetest_ops = {
+static struct afs_volume afs_root_volume = {
+ .name = "#afs.root",
+ .cache = {
+ .idef = &cachetest_volume,
+ .iparent = &afs_mycell.cache,
+ },
};
-static struct cachefs_netfs cachetest = {
- .name = "sillynetfs",
- .version = 0,
- .primary = &cachetest_cells,
- .ops = &cachetest_ops,
+/* AFS root dir
+ * - this is a file (hence .idef is NULL)
+ * - objects of this type will be typically embedded in the AFS fs's inode structures
+ */
+static struct afs_inode afs_root_dir = {
+ .fid = 0x1234abcd,
+ .cache = {
+ .idef = NULL,
+ .iparent = &afs_root_volume.cache,
+ },
};
/*****************************************************************************/
@@ -77,6 +145,21 @@
if (ret<0)
goto error;
+ printk("\n### Register cell object\n");
+ ret = cachefs_register_object(&afs_mycell.cache);
+ if (ret<0)
+ goto error;
+
+ printk("\n### Register volume object\n");
+ ret = cachefs_register_object(&afs_root_volume.cache);
+ if (ret<0)
+ goto error;
+
+ printk("\n### Register file object\n");
+ ret = cachefs_register_object(&afs_root_dir.cache);
+ if (ret<0)
+ goto error;
+
return ret;
error:
@@ -92,6 +175,9 @@
{
printk(KERN_INFO "cachefstest: general fs caching v0.1 tester unregistering.\n");
+ cachefs_unregister_object(&afs_root_dir.cache,0);
+ cachefs_unregister_object(&afs_root_volume.cache,0);
+ cachefs_unregister_object(&afs_mycell.cache,0);
cachefs_unregister_netfs(&cachetest);
} /* end cachefstest_exit() */
@@ -100,31 +186,93 @@
/*
*
*/
-static int cells_match(const void *_entry, const void *_data)
+static cachefs_match_val_t cell_match(struct cachefs_object *target, const void *entry)
{
+ struct afs_cell *cell = container_of(target,struct afs_cell,cache);
+
kenter("");
- return 0;
-} /* end cells_match() */
+
+ if (strncmp(entry,cell->name,sizeof(cell->name))==0)
+ return CACHEFS_MATCH_SUCCESS;
+
+ return CACHEFS_MATCH_FAILED;
+} /* end cell_match() */
+
+/*****************************************************************************/
+/*
+ * update a cell entry from the specified object
+ */
+static void cell_update(struct cachefs_object *source, void *entry)
+{
+ struct afs_cell *cell = container_of(source,struct afs_cell,cache);
+
+ kenter("%p,%p",source,entry);
+
+ strncpy(entry,cell->name,sizeof(cell->name));
+
+} /* end cell_update() */
/*****************************************************************************/
/*
*
*/
-static int vldb_match(const void *_entry, const void *_data)
+static cachefs_match_val_t vldb_match(struct cachefs_object *target, const void *entry)
{
+ struct afs_volume *volume = container_of(target,struct afs_volume,cache);
+
kenter("");
- return 0;
+
+ if (strncmp(entry,volume->name,sizeof(volume->name))==0)
+ return CACHEFS_MATCH_SUCCESS;
+
+ return CACHEFS_MATCH_FAILED;
} /* end vldb_match() */
/*****************************************************************************/
/*
*
*/
-static int files_match(const void *_entry, const void *_data)
+static void vldb_update(struct cachefs_object *source, void *entry)
{
+ struct afs_volume *volume = container_of(source,struct afs_volume,cache);
+
+ kenter("%p,%p",source,entry);
+
+ strncpy(entry,volume->name,sizeof(volume->name));
+
+} /* end vldb_update() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static cachefs_match_val_t file_match(struct cachefs_object *target, const void *entry)
+{
+ struct afs_inode *inode = container_of(target,struct afs_inode,cache);
+ u_int32_t fid = htonl(inode->fid);
+
kenter("");
- return 0;
-} /* end files_match() */
+
+ if (memcmp(entry,&fid,sizeof(fid))==0)
+ return CACHEFS_MATCH_SUCCESS;
+
+ return CACHEFS_MATCH_FAILED;
+} /* end file_match() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void file_update(struct cachefs_object *source, void *entry)
+{
+ struct afs_inode *inode = container_of(source,struct afs_inode,cache);
+ u_int32_t fid = htonl(inode->fid);
+
+ kenter("%p,%p",source,entry);
+
+ memcpy(entry,&fid,sizeof(fid));
+
+} /* end file_update() */
/*****************************************************************************/
/*
Index: cachefs-layout.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-layout.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- cachefs-layout.h 2 Apr 2003 09:12:31 -0000 1.20
+++ cachefs-layout.h 17 Apr 2003 11:59:04 -0000 1.21
@@ -68,10 +68,14 @@
*/
struct cachefs_ondisc_index_entry
{
- u_int32_t state : 8;
-#define CACHEFS_ONDISC_INDEX_FREE 0xf9
-#define CACHEFS_ONDISC_INDEX_RECYCLE 0xe5
-#define CACHEFS_ONDISC_INDEX_ACTIVE 0xbc
+ u_int32_t state : 7;
+#define CACHEFS_ONDISC_INDEX_FREE 0x7e
+#define CACHEFS_ONDISC_INDEX_RECYCLE 0x65
+#define CACHEFS_ONDISC_INDEX_ACTIVE 0x2c
+
+ u_int32_t type : 1;
+#define CACHEFS_ONDISC_INDEX_DATAFILE 0
+#define CACHEFS_ONDISC_INDEX_INDEXFILE 1
u_int32_t ino : 24; /* inode containing catalogue/data */
union {
Index: cachefs-int.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-int.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- cachefs-int.h 2 Apr 2003 09:12:31 -0000 1.25
+++ cachefs-int.h 17 Apr 2003 11:59:04 -0000 1.26
@@ -26,13 +26,16 @@
extern int cachefs_debug;
struct cachefs_super;
-struct cachefs_cross_index;
+struct cachefs_block;
+struct cachefs_active_inode;
extern struct address_space_operations cachefs_addrspace_operations;
extern struct address_space_operations cachefs_vio_addrspace_operations;
extern struct file_operations cachefs_root_file_operations;
extern struct inode_operations cachefs_root_inode_operations;
-extern struct cachefs_netfs cachefs_fsdef;
+extern struct rw_semaphore cachefs_addremove_sem;
+extern struct list_head cachefs_cache_list;
+extern struct list_head cachefs_netfs_list;
extern int cachefs_fs_init(void);
extern void cachefs_fs_exit(void);
@@ -57,10 +60,10 @@
/*
* cachefs superblock private information
*/
-struct cachefs_super {
+struct cachefs_super
+{
struct super_block *sb;
struct list_head mnt_link; /* link in list of mounted caches */
- struct list_head cross_indexes; /* netfs's cached in this cache */
struct cachefs_inode *istorage; /* the storage metadata records file */
struct inode *imisc; /* an inode covering the whole blkdev */
@@ -162,14 +165,15 @@
atomic_t cnt_ujnl_akwr; /* number of ACKs written */
atomic_t cnt_ujnl_free; /* number of marks freed */
- /* dummy index for accessing fsdef file */
- struct cachefs_cross_index *fsdef_index;
+ /* index management */
+ struct rb_root ino_tree; /* tree of active inodes */
+ rwlock_t ino_tree_lock;
/* superblock copy */
struct cachefs_ondisc_superblock *layout;
};
-extern void cachefs_add_cache(struct cachefs_super *super);
+extern void cachefs_add_cache(struct cachefs_super *super, struct cachefs_active_inode *active);
extern void cachefs_del_cache(struct cachefs_super *super);
extern void cachefs_recycle_unready_blocks(struct cachefs_super *super);
@@ -178,30 +182,33 @@
/*****************************************************************************/
/*
- * cache/netfs cross-indexing record
+ * cache file and directory management
+ * - negative entry if .ino==0 (and node will be unused)
*/
-struct cachefs_cross_index
+struct cachefs_active_inode
{
- struct cachefs_netfs *netfs; /* network filesystem definition */
- struct cachefs_super *super; /* device to which refers */
- struct list_head netfs_link; /* link in netfs's list */
- struct list_head super_link; /* link in cache's list */
+ struct rb_node node; /* node in active inode tracking tree */
+ atomic_t usage; /* usage count */
+ struct cachefs_super *super; /* cache in which resident */
+ unsigned ino; /* inode in cache */
+ unsigned long flags;
+#define CACHEFS_ACTIVE_INODE_ISINDEX 0 /* T if inode is index file (F if file) */
+#define CACHEFS_ACTIVE_INODE_LIVE 1 /* T if struct is live */
+#define CACHEFS_ACTIVE_INODE_INITING 2 /* T if struct is being initialised */
+#define CACHEFS_ACTIVE_INODE_RETIRING 3 /* T if inode is being retired */
- struct cachefs_ondisc_fsdef layout; /* raw index description */
- unsigned entry_id; /* fsdef ID (record index) */
+ struct cachefs_block *storage; /* block containing data storage info */
+ wait_queue_head_t initwq; /* initialisation wait queue */
+
+ struct cachefs_object *object; /* netfs's file/index object */
+ struct list_head link; /* link in object->active_inodes */
};
-extern int cachefs_generate_cross_index(struct cachefs_super *super,
- struct cachefs_netfs *netfs,
- struct cachefs_cross_index **_cross);
-
-extern int cachefs_index_search(struct cachefs_cross_index *cross, unsigned ino,
- cachefs_index_match_t matchfnx, void *data);
-
-extern int cachefs_index_add(struct cachefs_super *super,
- unsigned iino,
- const struct cachefs_index *definition,
- const void *data);
+extern int cachefs_index_search(struct cachefs_active_inode *index,
+ struct cachefs_active_inode *target);
+
+extern int cachefs_index_add(struct cachefs_active_inode *index,
+ struct cachefs_active_inode *target);
extern int cachefs_index_zap(struct cachefs_super *super);
@@ -212,9 +219,7 @@
struct cachefs_inode
{
struct inode vfs_inode; /* VFS inode record for this file */
- struct cachefs_cross_index *cross_index; /* index of which this is part (or NULL)*/
- struct list_head index_link; /* link in index's list */
- struct list_head cache_link; /* link in cache's list */
+ struct cachefs_active_inode *active; /* inode management */
unsigned storage_offset; /* data storage record offset */
unsigned short index_dsize; /* size of data in each index entry */
unsigned short index_esize; /* size of index entries */
@@ -256,6 +261,7 @@
struct cachefs_block
{
struct rb_node lookup_node; /* node in superblock's lookup tree */
+ struct cachefs_super *super; /* superblock on which block resides */
cachefs_blockix_t bix; /* index of block on disc */
atomic_t usage; /* usage count */
wait_queue_head_t writewq; /* write completion sleep queue */
@@ -277,6 +283,7 @@
struct list_head batch_link; /* link in batch writer's list */
struct page *page; /* current data for this block */
struct page *writeback; /* source of writeback for this block */
+ struct cachefs_page *ref; /* netfs's ref to this page */
};
extern int cachefs_block_insert(struct cachefs_super *super,
@@ -438,7 +445,7 @@
/*
* debug tracing
*/
-#define dbgprintk(FMT,...) printk("[%-6.6s] "FMT"\n",current->comm ,##__VA_ARGS__)
+#define dbgprintk(FMT,...) printk("[%-5.5hu] "FMT"\n",(u16)jiffies ,##__VA_ARGS__)
#define _dbprintk(FMT,...) do { } while(0)
#define kenter(FMT,...) dbgprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__)
Index: block.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/block.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- block.c 21 Mar 2003 14:01:01 -0000 1.1
+++ block.c 17 Apr 2003 11:59:04 -0000 1.2
@@ -404,7 +404,8 @@
atomic_set(&newblock->usage,1);
init_waitqueue_head(&newblock->writewq);
INIT_LIST_HEAD(&newblock->batch_link);
- newblock->bix = bix;
+ newblock->bix = bix;
+ newblock->super = super;
parent = NULL;
block = NULL;
Index: aops.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/aops.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- aops.c 2 Apr 2003 09:12:31 -0000 1.24
+++ aops.c 17 Apr 2003 11:59:04 -0000 1.25
@@ -69,17 +69,23 @@
.invalidatepage = cachefs_invalidatepage,
};
-int cachefs_get_page_private(struct page *page, struct cachefs_page **_pageio, unsigned gfp_flags)
+int cachefs_get_page_private(struct page *page, struct cachefs_page **_cookie, unsigned gfp_flags)
{
- if (!page->private) {
- page->private = (unsigned long) kmalloc(sizeof(struct cachefs_page),gfp_flags);
- if (!page->private)
+ struct cachefs_page *cookie = (struct cachefs_page*) page->private;
+
+ if (!cookie) {
+ cookie = kmalloc(sizeof(*cookie),gfp_flags);
+ if (!cookie)
return -ENOMEM;
- memset((void*)page->private,0,sizeof(struct cachefs_page));
+
+ memset(cookie,0,sizeof(*cookie));
+ rwlock_init(&cookie->lock);
+
+ page->private = (unsigned long) cookie;
SetPagePrivate(page);
}
- *_pageio = (struct cachefs_page*) page->private;
+ *_cookie = cookie;
return 0;
}
@@ -268,14 +274,14 @@
static int cachefs_do_readpage(struct bio **_bio, struct page *page, unsigned nr_pages,
sector_t *last_block_in_bio)
{
- struct cachefs_page *pageio;
+ struct cachefs_page *cookie;
struct inode *inode = page->mapping->host;
sector_t last_block;
int ret;
_enter("");
- ret = cachefs_get_page_private(page,&pageio,GFP_KERNEL);
+ ret = cachefs_get_page_private(page,&cookie,GFP_KERNEL);
if (ret<0)
goto error;
@@ -294,7 +300,7 @@
}
/* handle a hole */
- if (!pageio->mapped_block) {
+ if (!cookie->mapped_block) {
memset(kmap(page),0,PAGE_SIZE);
flush_dcache_page(page);
kunmap(page);
@@ -303,12 +309,12 @@
}
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)
+ if (*_bio && *last_block_in_bio != cookie->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,
+ ret = cachefs_io_alloc(inode->i_sb,cookie->mapped_block->bix,
nr_pages,GFP_KERNEL,_bio);
if (ret<0)
goto error;
@@ -319,10 +325,10 @@
goto alloc_new;
}
- if (pageio->flags & CACHEFS_PAGE_BOUNDARY)
+ if (cookie->flags & CACHEFS_PAGE_BOUNDARY)
cachefs_io_bio_submit(READ,_bio);
else
- *last_block_in_bio = pageio->mapped_block->bix;
+ *last_block_in_bio = cookie->mapped_block->bix;
}
_leave(" = 0");
@@ -415,19 +421,19 @@
void cachefs_do_writepage(struct bio **_bio, struct page *page,
sector_t *last_block_in_bio, int *_ret)
{
- struct cachefs_page *pageio;
+ struct cachefs_page *cookie;
struct inode *inode = page->mapping->host;
unsigned long end_index;
int ret;
_enter(",{%lu},%llu,",page->index,*last_block_in_bio);
- ret = cachefs_get_page_private(page,&pageio,GFP_KERNEL);
+ ret = cachefs_get_page_private(page,&cookie,GFP_KERNEL);
if (ret<0)
goto error;
/* deal with a block not that's yet mapped */
- if (!pageio->mapped_block) {
+ if (!cookie->mapped_block) {
/* map the page to a block on the blockdev */
BUG_ON(!PageUptodate(page));
@@ -437,8 +443,8 @@
goto out;
}
- if (pageio->flags & CACHEFS_PAGE_NEW)
- BUG();//unmap_underlying_metadata(inode->i_sb->s_bdev,pageio->mapped_block)
+ if (cookie->flags & CACHEFS_PAGE_NEW)
+ BUG();//unmap_underlying_metadata(inode->i_sb->s_bdev,cookie->mapped_block)
/* clear the tail end of the last block */
end_index = inode->i_size >> PAGE_CACHE_SHIFT;
@@ -454,13 +460,13 @@
}
/* dispatch the outstanding BIO if not immediately preceding this page */
- if (*_bio && *last_block_in_bio != pageio->mapped_block->bix-1)
+ if (*_bio && *last_block_in_bio != cookie->mapped_block->bix-1)
cachefs_io_bio_submit(WRITE,_bio);
alloc_new:
if (!*_bio) {
ret = cachefs_io_alloc(inode->i_sb,
- pageio->mapped_block->bix,
+ cookie->mapped_block->bix,
bio_get_nr_vecs(inode->i_sb->s_bdev),
GFP_NOFS|__GFP_HIGH,
_bio);
@@ -477,12 +483,12 @@
BUG_ON(PageWriteback(page));
SetPageWriteback(page);
unlock_page(page);
- if (pageio->flags & CACHEFS_PAGE_BOUNDARY) {
+ if (cookie->flags & CACHEFS_PAGE_BOUNDARY) {
cachefs_io_bio_submit(WRITE,_bio);
// write_boundary_block(inode->i_sb->s_bdev,
-// pageio->mapped_block->bix, 1 << PAGE_CACHE_SHIFT);
+// cookie->mapped_block->bix, 1 << PAGE_CACHE_SHIFT);
} else {
- *last_block_in_bio = pageio->mapped_block->bix;
+ *last_block_in_bio = cookie->mapped_block->bix;
}
goto out;
@@ -619,7 +625,7 @@
*/
static int cachefs_writepage(struct page *page, struct writeback_control *wbc)
{
- struct cachefs_page *pageio;
+ struct cachefs_page *cookie;
unsigned long end_index;
struct inode * const inode = page->mapping->host;
struct bio *bio;
@@ -631,7 +637,7 @@
BUG_ON(!PageUptodate(page));
BUG_ON(PageWriteback(page));
- ret = cachefs_get_page_private(page,&pageio,GFP_NOFS);
+ ret = cachefs_get_page_private(page,&cookie,GFP_NOFS);
if (ret<0)
goto error;
@@ -653,20 +659,20 @@
kunmap_atomic(kaddr, KM_USER0);
}
- if (!pageio->mapped_block) {
+ if (!cookie->mapped_block) {
ret = cachefs_get_block(inode,page,1);
if (ret<0)
goto error;
- if (!pageio->mapped_block) BUG();
+ if (!cookie->mapped_block) BUG();
- if (pageio->flags & CACHEFS_PAGE_NEW) {
+ if (cookie->flags & CACHEFS_PAGE_NEW) {
//unmap_underlying_metadata(bh->b_bdev,bh->b_blocknr);
- pageio->flags &= ~CACHEFS_PAGE_NEW;
+ cookie->flags &= ~CACHEFS_PAGE_NEW;
}
}
- ret = cachefs_io_alloc(inode->i_sb,pageio->mapped_block->bix,1,GFP_NOFS,&bio);
+ ret = cachefs_io_alloc(inode->i_sb,cookie->mapped_block->bix,1,GFP_NOFS,&bio);
if (ret<0)
goto error;
@@ -689,7 +695,7 @@
*/
static int cachefs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
{
- struct cachefs_page *pageio;
+ struct cachefs_page *cookie;
struct inode *inode = page->mapping->host;
struct bio *bio = NULL;
int ret;
@@ -698,21 +704,21 @@
_enter(",{%lu},%u,%u",page->index,from,to);
- ret = cachefs_get_page_private(page,&pageio,GFP_NOFS);
+ ret = cachefs_get_page_private(page,&cookie,GFP_NOFS);
if (ret<0)
goto error;
/* map the page to a disc block and prepare a new page for writing */
- if (!pageio->mapped_block) {
+ if (!cookie->mapped_block) {
ret = cachefs_get_block(inode,page,1);
if (ret<0)
goto error;
- BUG_ON(!pageio->mapped_block);
+ BUG_ON(!cookie->mapped_block);
}
if (!PageUptodate(page)) {
- if (pageio->flags & CACHEFS_PAGE_NEW) {
+ if (cookie->flags & CACHEFS_PAGE_NEW) {
//unmap_underlying_metadata(bh->b_bdev,bh->b_blocknr);
if (from>0 || to<PAGE_SIZE) {
void *kaddr;
@@ -734,7 +740,7 @@
goto error;
bio->bi_bdev = inode->i_sb->s_bdev;
- bio->bi_sector = pageio->mapped_block->bix;
+ bio->bi_sector = cookie->mapped_block->bix;
bio->bi_sector <<= (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
bio->bi_end_io = cachefs_io_end_io_prepare;
bio->bi_private = &cpl;
@@ -747,19 +753,19 @@
wait_for_completion(&cpl);
}
- pageio->flags &= ~CACHEFS_PAGE_NEW;
+ cookie->flags &= ~CACHEFS_PAGE_NEW;
_leave(" = 0");
return 0;
error:
- if (pageio->flags & CACHEFS_PAGE_NEW) {
+ if (cookie->flags & CACHEFS_PAGE_NEW) {
memset(kmap(page),0,PAGE_SIZE);
flush_dcache_page(page);
kunmap(page);
SetPageUptodate(page);
set_page_dirty(page);
- pageio->flags &= ~CACHEFS_PAGE_NEW;
+ cookie->flags &= ~CACHEFS_PAGE_NEW;
}
_leave(" = %d",ret);
@@ -796,7 +802,7 @@
static int cachefs_invalidatepage(struct page *page, unsigned long offset)
{
struct cachefs_block *block;
- struct cachefs_page *pageio;
+ struct cachefs_page *cookie;
int ret = 1;
_enter("{%lu},%lu",page->index,offset);
@@ -805,10 +811,10 @@
if (!PagePrivate(page))
goto out;
- pageio = (struct cachefs_page*) page->private;
- block = xchg(&pageio->mapped_block,NULL);
+ cookie = (struct cachefs_page*) page->private;
+ block = xchg(&cookie->mapped_block,NULL);
ClearPageMappedToDisk(page);
- pageio->flags = 0;
+ cookie->flags = 0;
if (block) cachefs_block_put(page->mapping->host->i_sb->s_fs_info,block);
@@ -832,22 +838,22 @@
*/
static int cachefs_releasepage(struct page *page, int gfp_flags)
{
- struct cachefs_page *pageio;
+ struct cachefs_page *cookie;
_enter("{%lu},%x",page->index,gfp_flags);
if (PagePrivate(page)) {
- pageio = (struct cachefs_page*) page->private;
+ cookie = (struct cachefs_page*) page->private;
page->private = 0;
ClearPagePrivate(page);
ClearPageMappedToDisk(page);
- if (pageio) {
- if (pageio->mapped_block)
+ if (cookie) {
+ if (cookie->mapped_block)
cachefs_block_put(page->mapping->host->i_sb->s_fs_info,
- pageio->mapped_block);
- dbgfree(pageio);
- kfree(pageio);
+ cookie->mapped_block);
+ dbgfree(cookie);
+ kfree(cookie);
}
}
@@ -1091,7 +1097,7 @@
struct cachefs_io_block_path path[4];
struct cachefs_inode *inode = CACHEFS_FS_I(vfs_inode);
struct cachefs_super *super = inode->vfs_inode.i_sb->s_fs_info;
- struct cachefs_page *pageio = __cachefs_get_page_private(page);
+ struct cachefs_page *cookie = __cachefs_get_page_private(page);
const size_t ptrperblk = PAGE_SIZE / sizeof(cachefs_blockix_t);
sector_t iblock;
size_t ptrqty, notboundary = 1;
@@ -1100,7 +1106,7 @@
#if 0
if (inode->vfs_inode.i_ino == CACHEFS_INO_WIBBLE) {
ret = cachefs_block_insert(inode->vfs_inode.i_sb->s_fs_info,page->index+1000,
- &pageio->mapped_block);
+ &cookie->mapped_block);
if (ret==0)
SetPageMappedToDisk(page);
return ret;
@@ -1110,7 +1116,7 @@
_enter("%lu,{%p}%lu,%d",inode->vfs_inode.i_ino,page,page->index,create);
- BUG_ON(pageio->mapped_block);
+ BUG_ON(cookie->mapped_block);
if (page->index/ptrperblk >= ptrperblk) {
_leave(" = -EIO [range]");
@@ -1282,26 +1288,26 @@
}
if (ret<0) {
- if (pageio->mapped_block)
- cachefs_block_put(inode->vfs_inode.i_sb->s_fs_info,pageio->mapped_block);
- pageio->mapped_block = NULL;
+ if (cookie->mapped_block)
+ cachefs_block_put(inode->vfs_inode.i_sb->s_fs_info,cookie->mapped_block);
+ cookie->mapped_block = NULL;
_leave(" = %d",ret);
return ret;
}
/* got the block - set the block offset in the page mapping record */
if (path[0].flags & CACHEFS_BLOCK_NEW)
- pageio->flags |= CACHEFS_PAGE_NEW;
+ cookie->flags |= CACHEFS_PAGE_NEW;
_debug("notboundary = %u",notboundary);
if (!notboundary)
- pageio->flags |= CACHEFS_PAGE_BOUNDARY;
+ cookie->flags |= CACHEFS_PAGE_BOUNDARY;
_leave(" = 0 [bix=%u %c%c%c]",
- pageio->mapped_block->bix,
- pageio->flags & CACHEFS_PAGE_BOUNDARY ?'b':'-',
- pageio->flags & CACHEFS_PAGE_NEW ?'n':'-',
- pageio->flags & CACHEFS_PAGE_BYSECTORS ?'s':'-'
+ cookie->mapped_block->bix,
+ cookie->flags & CACHEFS_PAGE_BOUNDARY ?'b':'-',
+ cookie->flags & CACHEFS_PAGE_NEW ?'n':'-',
+ cookie->flags & CACHEFS_PAGE_BYSECTORS ?'s':'-'
);
return 0;
} /* end cachefs_get_block() */
@@ -1341,3 +1347,57 @@
_leave(" = -EIO");
return -EIO;
} /* end cachefs_get_page() */
+
+/*****************************************************************************/
+/*
+ * read a block from disc into a page provided by a netfs
+ * - returns -ENODATA if there's no cache block mapped
+ */
+int cachefs_file_readpage(struct cachefs_netfs *netfs, struct page *page)
+{
+ struct cachefs_block *block;
+ struct cachefs_page *cookie;
+ struct super_block *sb;
+ unsigned long flags;
+ struct bio *bio;
+ int ret;
+
+ kenter("{%s},{%lu}",netfs->name,page->index);
+
+ ret = netfs->ops->get_page_cookie(page,&cookie);
+ if (ret<0)
+ goto error;
+
+ /* protect against cache removal */
+ read_lock_irqsave(&cookie->lock,flags);
+
+ block = cookie->mapped_block;
+ if (block)
+ cachefs_block_get(block);
+
+ read_unlock_irqrestore(&cookie->lock,flags);
+
+ ret = -ENODATA;
+ if (!block)
+ goto error;
+
+ /* generate a BIO to read the page */
+ ret = -ENOMEM;
+ bio = bio_alloc(GFP_KERNEL,1);
+ if (!bio)
+ goto error;
+
+ sb = block->super->sb;
+
+ bio->bi_bdev = sb->s_bdev;
+ bio->bi_sector = block->bix << (PAGE_SHIFT - sb->s_blocksize_bits);
+ bio->bi_end_io = cachefs_io_end_io_read;
+ //dump_bio(bio,1);
+ submit_bio(READ,bio);
+ ret = 0;
+
+ error:
+ kleave(" = %d",ret);
+ return ret;
+
+} /* end cachefs_file_readpage() */
Index: Makefile
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/Makefile,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- Makefile 2 Apr 2003 09:12:31 -0000 1.14
+++ Makefile 17 Apr 2003 11:59:04 -0000 1.15
@@ -2,13 +2,14 @@
# Makefile for general caching filesystem
#
-#CFLAGS += -finstrument-functions
+CFLAGS += -finstrument-functions
cachefs-objs := \
block.o \
aops.o \
index.o \
inode.o \
+ interface.o \
io.o \
journal.o \
kcachefs_jnld.o \
More information about the linux-afs-cvs
mailing list