Commit 64353a2b authored by Jan Harkes's avatar Jan Harkes Committed by Linus Torvalds

[PATCH] Coda updates [2/5]

Use a global 'epoch' counter to invalidate cached permissions instead of
traversing a racy linked list of all known Coda inodes.
parent 87653883
......@@ -23,11 +23,14 @@
#include <linux/coda_fs_i.h>
#include <linux/coda_cache.h>
static atomic_t permission_epoch = ATOMIC_INIT(0);
/* replace or extend an acl cache hit */
void coda_cache_enter(struct inode *inode, int mask)
{
struct coda_inode_info *cii = ITOC(inode);
cii->c_cached_epoch = atomic_read(&permission_epoch);
if ( !coda_cred_ok(&cii->c_cached_cred) ) {
coda_load_creds(&cii->c_cached_cred);
cii->c_cached_perm = mask;
......@@ -42,22 +45,15 @@ void coda_cache_clear_inode(struct inode *inode)
cii->c_cached_perm = 0;
}
/* remove all acl caches for a principal (or all principals when cred == NULL)*/
void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred)
/* remove all acl caches */
void coda_cache_clear_all(struct super_block *sb)
{
struct coda_sb_info *sbi;
struct coda_inode_info *cii;
struct list_head *tmp;
sbi = coda_sbp(sb);
if (!sbi) BUG();
list_for_each(tmp, &sbi->sbi_cihead)
{
cii = list_entry(tmp, struct coda_inode_info, c_cilist);
if (!cred || coda_cred_eq(cred, &cii->c_cached_cred))
cii->c_cached_perm = 0;
}
atomic_inc(&permission_epoch);
}
......@@ -67,8 +63,9 @@ int coda_cache_check(struct inode *inode, int mask)
struct coda_inode_info *cii = ITOC(inode);
int hit;
hit = ((mask & cii->c_cached_perm) == mask) &&
coda_cred_ok(&cii->c_cached_cred);
hit = (mask & cii->c_cached_perm) == mask &&
coda_cred_ok(&cii->c_cached_cred) &&
cii->c_cached_epoch == atomic_read(&permission_epoch);
return hit;
}
......
......@@ -64,7 +64,6 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
{
struct inode *inode;
struct coda_inode_info *cii;
struct coda_sb_info *sbi = coda_sbp(sb);
unsigned long hash = coda_f2i(fid);
inode = iget5_locked(sb, hash, coda_test_inode, coda_set_inode, fid);
......@@ -77,7 +76,6 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
/* we still need to set i_ino for things like stat(2) */
inode->i_ino = hash;
cii->c_mapcount = 0;
list_add(&cii->c_cilist, &sbi->sbi_cihead);
unlock_new_inode(inode);
}
......
......@@ -46,7 +46,6 @@ static struct inode *coda_alloc_inode(struct super_block *sb)
return NULL;
memset(&ei->c_fid, 0, sizeof(struct ViceFid));
ei->c_flags = 0;
INIT_LIST_HEAD(&ei->c_cilist);
memset(&ei->c_cached_cred, 0, sizeof(struct coda_cred));
ei->c_cached_perm = 0;
return &ei->vfs_inode;
......@@ -170,7 +169,6 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
vc->vc_sb = sb;
sbi->sbi_vcomm = vc;
INIT_LIST_HEAD(&sbi->sbi_cihead);
sb->s_fs_info = sbi;
sb->s_blocksize = 1024; /* XXXXX what do we put here?? */
......@@ -217,7 +215,6 @@ static void coda_put_super(struct super_block *sb)
sbi = coda_sbp(sb);
sbi->sbi_vcomm->vc_sb = NULL;
list_del_init(&sbi->sbi_cihead);
printk("Coda: Bye bye.\n");
kfree(sbi);
......@@ -225,9 +222,6 @@ static void coda_put_super(struct super_block *sb)
static void coda_clear_inode(struct inode *inode)
{
struct coda_inode_info *cii = ITOC(inode);
list_del_init(&cii->c_cilist);
coda_cache_clear_inode(inode);
}
......
......@@ -819,19 +819,14 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
switch (opcode) {
case CODA_FLUSH : {
coda_cache_clear_all(sb, NULL);
coda_cache_clear_all(sb);
shrink_dcache_sb(sb);
coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
return(0);
}
case CODA_PURGEUSER : {
struct coda_cred *cred = &out->coda_purgeuser.cred;
if ( !cred ) {
printk("PURGEUSER: null cred!\n");
return 0;
}
coda_cache_clear_all(sb, cred);
coda_cache_clear_all(sb);
return(0);
}
......
......@@ -13,7 +13,7 @@
/* credential cache */
void coda_cache_enter(struct inode *inode, int mask);
void coda_cache_clear_inode(struct inode *);
void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred);
void coda_cache_clear_all(struct super_block *sb);
int coda_cache_check(struct inode *inode, int mask);
/* for downcalls and attributes and lookups */
......
......@@ -21,6 +21,7 @@ struct coda_inode_info {
u_short c_flags; /* flags (see below) */
struct list_head c_cilist; /* list of all coda inodes */
unsigned int c_mapcount; /* nr of times this inode is mapped */
unsigned int c_cached_epoch;
struct coda_cred c_cached_cred; /* credentials of cached perms */
unsigned int c_cached_perm; /* cached access permissions */
struct inode vfs_inode;
......
......@@ -11,7 +11,6 @@ struct kstatfs;
struct coda_sb_info
{
struct venus_comm *sbi_vcomm;
struct list_head sbi_cihead;
};
/* communication pending/processing queues */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment