Commit 839e0e16 authored by Jan Harkes's avatar Jan Harkes Committed by Linus Torvalds

[PATCH] 2.5.6-pre2 - Coda fixes and cleanups

Here is a batch of accumulated bugfixes and cleanups for the Coda kernel
module. Patch is against 2.5.6-pre2, I could also send these as separate
patches.

bugfix: Fix coda_dentry_revalidate bug

    Due to a bad test, coda_dentry_revalidate was forcing revalidation
    of cacheable inodes, and allowed caching of non-cacheable inodes.

bugfix: Corrected i_mtime/i_ctime setting

    i_mtime and i_ctime were not always updated when writing to a file,
    or when modifying inode attributes.

cleanup/optimization: Avoid getattr upcalls

    We can use coda_iget directly instead of coda_cnode_make when an
    upcall returns attributes and avoid the getattr upcall altogether.

cleanup: Removed debugging messages

    CDEBUG macros haven't been useful ever since the initial development
    when they were introduced. They are too verbose for debugging
    purposes. Removing these saves about a third of the compiled size of
    the module.

    Removed print_entry variable that was used by ENTRY/EXIT macros
    which are already gone.

cleanup/optimization: Readdir simplification

    Relying on the fact that the pagecache is already buffering far more
    efficiently, simplified coda_readdir implementation. We can now fill
    the complete userbuffer instead of returning after reading only 2KB.

    Passing dir entry types that are present in the venus_dirent
    structure to the user as well.

cleanup: Removed redundant permissions statistics counters.

    The permission check count is about identical to the 'permission'
    field in the VFS stats, and the permission hit counter can trivially
    be derived from upcall_stats.access - vfs_stats.permission. Removed
    these redundant counters.

cleanup: Removed useless test for c_flags in coda_revalidate_inode.

    We already know c_flags is set due to earlier tests.
parent fecb0199
......@@ -71,7 +71,6 @@ int coda_cache_check(struct inode *inode, int mask)
hit = ((mask & cii->c_cached_perm) == mask) &&
coda_cred_ok(&cii->c_cached_cred);
CDEBUG(D_CACHE, "%s for ino %ld\n", hit ? "HIT" : "MISS", inode->i_ino);
return hit;
}
......@@ -102,9 +101,6 @@ static void coda_flag_children(struct dentry *parent, int flag)
/* don't know what to do with negative dentries */
if ( ! de->d_inode )
continue;
CDEBUG(D_DOWNCALL, "%d for %*s/%*s\n", flag,
de->d_name.len, de->d_name.name,
de->d_parent->d_name.len, de->d_parent->d_name.name);
coda_flag_inode(de->d_inode, flag);
}
spin_unlock(&dcache_lock);
......
......@@ -11,9 +11,6 @@
#include <linux/coda_fs_i.h>
#include <linux/coda_psdev.h>
extern int coda_debug;
extern int coda_print_entry;
inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
{
if (fid1->Vnode != fid2->Vnode) return 0;
......@@ -42,11 +39,6 @@ static struct inode_operations coda_symlink_inode_operations = {
/* cnode.c */
static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
{
CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
if (coda_debug & D_SUPER )
print_vattr(attr);
coda_vattr_to_iattr(inode, attr);
if (S_ISREG(inode->i_mode)) {
......@@ -72,10 +64,8 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
inode = iget4(sb, ino, coda_inocmp, fid);
if ( !inode ) {
CDEBUG(D_CNODE, "coda_iget: no inode\n");
if (!inode)
return ERR_PTR(-ENOMEM);
}
/* check if the inode is already initialized */
cii = ITOC(inode);
......@@ -105,9 +95,6 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
/* We get inode numbers from Venus -- see venus source */
error = venus_getattr(sb, fid, &attr);
if ( error ) {
CDEBUG(D_CNODE,
"coda_cnode_make: coda_getvattr returned %d for %s.\n",
error, coda_f2s(fid));
*inode = NULL;
return error;
}
......@@ -117,10 +104,6 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
printk("coda_cnode_make: coda_iget failed\n");
return PTR_ERR(*inode);
}
CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
(*inode)->i_ino, atomic_read(&(*inode)->i_count),
coda_f2s(&ITOC(*inode)->c_fid));
return 0;
}
......@@ -155,8 +138,6 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
return NULL;
}
CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
nr = coda_f2i(fid);
inode = iget4(sb, nr, coda_inocmp, fid);
if ( !inode ) {
......@@ -177,7 +158,6 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
/* we shouldn't see inode collisions anymore */
if ( !coda_fideq(fid, &cii->c_fid) ) BUG();
CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
return inode;
}
......
......@@ -24,9 +24,6 @@
#include <linux/coda_fs_i.h>
/* initialize the debugging variables */
int coda_debug;
int coda_print_entry;
int coda_access_cache = 1;
int coda_fake_statfs;
/* print a fid */
......@@ -92,35 +89,23 @@ unsigned short coda_flags_to_cflags(unsigned short flags)
{
unsigned short coda_flags = 0;
if ( (flags & O_ACCMODE) == O_RDONLY ){
CDEBUG(D_FILE, "--> C_O_READ added\n");
if ((flags & O_ACCMODE) == O_RDONLY)
coda_flags |= C_O_READ;
}
if ( (flags & O_ACCMODE) == O_RDWR ) {
CDEBUG(D_FILE, "--> C_O_READ | C_O_WRITE added\n");
if ((flags & O_ACCMODE) == O_RDWR)
coda_flags |= C_O_READ | C_O_WRITE;
}
if ( (flags & O_ACCMODE) == O_WRONLY ){
CDEBUG(D_FILE, "--> C_O_WRITE added\n");
if ((flags & O_ACCMODE) == O_WRONLY)
coda_flags |= C_O_WRITE;
}
if ( flags & O_TRUNC ) {
CDEBUG(D_FILE, "--> C_O_TRUNC added\n");
if (flags & O_TRUNC)
coda_flags |= C_O_TRUNC;
}
if ( flags & O_CREAT ) {
CDEBUG(D_FILE, "--> C_O_CREAT added\n");
if (flags & O_CREAT)
coda_flags |= C_O_CREAT;
}
if ( flags & O_EXCL ) {
if (flags & O_EXCL)
coda_flags |= C_O_EXCL;
CDEBUG(D_FILE, "--> C_O_EXCL added\n");
}
return coda_flags;
}
......
......@@ -50,11 +50,7 @@ static int coda_dentry_revalidate(struct dentry *de, int);
static int coda_dentry_delete(struct dentry *);
/* support routines */
static void coda_prepare_fakefile(struct file *coda_file,
struct dentry *open_dentry,
struct file *open_file);
static int coda_venus_readdir(struct file *filp, void *dirent,
filldir_t filldir);
static int coda_venus_readdir(struct file *filp, filldir_t filldir, void *dirent);
int coda_fsync(struct file *, struct dentry *dentry, int datasync);
int coda_hasmknod;
......@@ -109,16 +105,10 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
return ERR_PTR(-ENAMETOOLONG);
}
CDEBUG(D_INODE, "name %s, len %ld in ino %ld, fid %s\n",
name, (long)length, dir->i_ino, coda_i2s(dir));
lock_kernel();
/* control object, create inode on the fly */
if (coda_isroot(dir) && coda_iscontrol(name, length)) {
error = coda_cnode_makectl(&res_inode, dir->i_sb);
CDEBUG(D_SPECIAL,
"Lookup on CTL object; dir ino %ld, count %d\n",
dir->i_ino, atomic_read(&dir->i_count));
dropme = 1;
goto exit;
}
......@@ -130,8 +120,6 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
if (!error) {
if (type & CODA_NOCACHE) {
type &= (~CODA_NOCACHE);
CDEBUG(D_INODE, "dropme set for %s\n",
coda_f2s(&resfid));
dropme = 1;
}
......@@ -141,13 +129,9 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
return ERR_PTR(error);
}
} else if (error != -ENOENT) {
CDEBUG(D_INODE, "error for %s(%*s)%d\n",
coda_i2s(dir), (int)length, name, error);
unlock_kernel();
return ERR_PTR(error);
}
CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n",
name, coda_f2s(&resfid), type, error, dropme);
exit:
entry->d_time = 0;
......@@ -164,28 +148,19 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
int coda_permission(struct inode *inode, int mask)
{
umode_t mode = inode->i_mode;
int error;
coda_vfs_stat.permission++;
if (!mask)
return 0;
if ( mask == 0 )
return 0;
coda_vfs_stat.permission++;
if ( coda_access_cache ) {
coda_permission_stat.count++;
if (coda_cache_check(inode, mask))
return 0;
if ( coda_cache_check(inode, mask) ) {
coda_permission_stat.hit_count++;
return 0;
}
}
CDEBUG(D_INODE, "mask is %o\n", mask);
error = venus_access(inode->i_sb, coda_i2f(inode), mask);
CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %d\n",
coda_i2s(inode), inode->i_ino, mask, error);
if (!error)
coda_cache_enter(inode, mask);
......@@ -203,7 +178,7 @@ static inline void coda_dir_changed(struct inode *dir, int link)
/* optimistically we can also act as if our nose bleeds. The
* granularity of the mtime is coarse anyways so we might actually be
* right most of the time. Note: we only do this for directories. */
dir->i_mtime = CURRENT_TIME;
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
#endif
if (link)
dir->i_nlink += link;
......@@ -215,15 +190,13 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode)
int error=0;
const char *name=de->d_name.name;
int length=de->d_name.len;
struct inode *result = NULL;
struct inode *inode;
struct ViceFid newfid;
struct coda_vattr attrs;
lock_kernel();
coda_vfs_stat.create++;
CDEBUG(D_INODE, "name: %s, length %d, mode %o\n", name, length, mode);
if (coda_isroot(dir) && coda_iscontrol(name, length)) {
unlock_kernel();
return -EPERM;
......@@ -233,25 +206,22 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode)
0, mode, 0, &newfid, &attrs);
if ( error ) {
CDEBUG(D_INODE, "create: %s, result %d\n",
coda_f2s(&newfid), error);
unlock_kernel();
d_drop(de);
return error;
}
error = coda_cnode_make(&result, &newfid, dir->i_sb);
if ( error ) {
inode = coda_iget(dir->i_sb, &newfid, &attrs);
if ( IS_ERR(inode) ) {
unlock_kernel();
d_drop(de);
result = NULL;
return error;
return PTR_ERR(inode);
}
/* invalidate the directory cnode's attributes */
coda_dir_changed(dir, 0);
unlock_kernel();
d_instantiate(de, result);
d_instantiate(de, inode);
return 0;
}
......@@ -260,7 +230,7 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
int error=0;
const char *name=de->d_name.name;
int length=de->d_name.len;
struct inode *result = NULL;
struct inode *inode;
struct ViceFid newfid;
struct coda_vattr attrs;
......@@ -270,9 +240,6 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
lock_kernel();
coda_vfs_stat.create++;
CDEBUG(D_INODE, "name: %s, length %d, mode %o, rdev %x\n",
name, length, mode, rdev);
if (coda_isroot(dir) && coda_iscontrol(name, length)) {
unlock_kernel();
return -EPERM;
......@@ -282,32 +249,29 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
0, mode, rdev, &newfid, &attrs);
if ( error ) {
CDEBUG(D_INODE, "mknod: %s, result %d\n",
coda_f2s(&newfid), error);
d_drop(de);
unlock_kernel();
d_drop(de);
return error;
}
error = coda_cnode_make(&result, &newfid, dir->i_sb);
if ( error ) {
d_drop(de);
result = NULL;
inode = coda_iget(dir->i_sb, &newfid, &attrs);
if ( IS_ERR(inode) ) {
unlock_kernel();
return error;
d_drop(de);
return PTR_ERR(inode);
}
/* invalidate the directory cnode's attributes */
coda_dir_changed(dir, 0);
unlock_kernel();
d_instantiate(de, result);
d_instantiate(de, inode);
return 0;
}
static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
{
struct inode *inode;
struct coda_vattr attr;
struct coda_vattr attrs;
const char *name = de->d_name.name;
int len = de->d_name.len;
int error;
......@@ -321,29 +285,21 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
return -EPERM;
}
CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n",
name, len, coda_i2s(dir), mode);
attr.va_mode = mode;
attrs.va_mode = mode;
error = venus_mkdir(dir->i_sb, coda_i2f(dir),
name, len, &newfid, &attr);
name, len, &newfid, &attrs);
if ( error ) {
CDEBUG(D_INODE, "mkdir error: %s result %d\n",
coda_f2s(&newfid), error);
d_drop(de);
unlock_kernel();
return error;
d_drop(de);
return error;
}
CDEBUG(D_INODE, "mkdir: new dir has fid %s.\n",
coda_f2s(&newfid));
error = coda_cnode_make(&inode, &newfid, dir->i_sb);
if ( error ) {
d_drop(de);
inode = coda_iget(dir->i_sb, &newfid, &attrs);
if ( IS_ERR(inode) ) {
unlock_kernel();
return error;
d_drop(de);
return PTR_ERR(inode);
}
/* invalidate the directory cnode's attributes */
......@@ -370,9 +326,6 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
return -EPERM;
}
CDEBUG(D_INODE, "old: fid: %s\n", coda_i2s(inode));
CDEBUG(D_INODE, "directory: %s\n", coda_i2s(dir_inode));
error = venus_link(dir_inode->i_sb, coda_i2f(inode),
coda_i2f(dir_inode), (const char *)name, len);
......@@ -387,7 +340,6 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
inode->i_nlink++;
out:
CDEBUG(D_INODE, "link result %d\n",error);
unlock_kernel();
return(error);
}
......@@ -415,8 +367,6 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
return -ENAMETOOLONG;
}
CDEBUG(D_INODE, "symname: %s, length: %d\n", symname, symlen);
/*
* This entry is now negative. Since we do not create
* an inode for the entry we have to drop it.
......@@ -429,7 +379,6 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
if ( !error )
coda_dir_changed(dir_inode, 0);
CDEBUG(D_INODE, "in symlink result %d\n",error);
unlock_kernel();
return error;
}
......@@ -444,12 +393,8 @@ int coda_unlink(struct inode *dir, struct dentry *de)
lock_kernel();
coda_vfs_stat.unlink++;
CDEBUG(D_INODE, " %s in %s, dirino %ld\n", name ,
coda_i2s(dir), dir->i_ino);
error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
if ( error ) {
CDEBUG(D_INODE, "upc returned error %d\n", error);
unlock_kernel();
return error;
}
......@@ -477,7 +422,6 @@ int coda_rmdir(struct inode *dir, struct dentry *de)
error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
if ( error ) {
CDEBUG(D_INODE, "upc returned error %d\n", error);
unlock_kernel();
return error;
}
......@@ -504,11 +448,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
lock_kernel();
coda_vfs_stat.rename++;
CDEBUG(D_INODE, "old: %s, (%d length), new: %s"
"(%d length). old:d_count: %d, new:d_count: %d\n",
old_name, old_length, new_name, new_length,
atomic_read(&old_dentry->d_count), atomic_read(&new_dentry->d_count));
error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
coda_i2f(new_dir), old_length, new_length,
(const char *) old_name, (const char *)new_name);
......@@ -526,8 +465,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
coda_flag_inode(new_dir, C_VATTR);
}
}
CDEBUG(D_INODE, "result %d\n", error);
unlock_kernel();
return error;
......@@ -535,155 +472,108 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
/* file operations for directories */
int coda_readdir(struct file *file, void *dirent, filldir_t filldir)
int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir)
{
int result = 0;
struct dentry *cdentry;
struct inode *cinode, *inode = file->f_dentry->d_inode;
struct file *cfile, fakefile;
struct coda_inode_info *cii = ITOC(inode);
struct dentry *coda_dentry = coda_file->f_dentry;
struct inode *coda_inode = coda_dentry->d_inode;
struct coda_inode_info *cii = ITOC(coda_inode);
struct file *host_file = cii->c_container;
BUG_ON(!host_file);
coda_vfs_stat.readdir++;
cfile = cii->c_container;
if (!cfile) BUG();
/* Access to both host and coda f_pos fields is serialized on the
* coda_file->f_dentry->d_inode->i_sem which has already been taken by
* vfs_readdir. Userspace shouldn't 'play' with the container file as
* long as the file is held open. */
host_file->f_pos = coda_file->f_pos;
cinode = cii->c_container->f_dentry->d_inode;
if ( S_ISREG(cinode->i_mode) ) {
if ( !host_file->f_op->readdir )
/* Venus: we must read Venus dirents from the file */
cdentry = cii->c_container->f_dentry;
coda_prepare_fakefile(file, cdentry, &fakefile);
result = coda_venus_readdir(&fakefile, dirent, filldir);
file->f_pos = fakefile.f_pos;
file->f_version = fakefile.f_version;
} else {
/* potemkin case: we are handed a directory inode */
result = vfs_readdir(file, filldir, dirent);
}
result = coda_venus_readdir(host_file, filldir, dirent);
else
/* potemkin case: we were handed a directory inode */
result = vfs_readdir(host_file, filldir, dirent);
coda_file->f_pos = host_file->f_pos;
return result;
}
/* support routines */
/* instantiate a fake file to pass to coda_venus_readdir */
static void coda_prepare_fakefile(struct file *coda_file,
struct dentry *cont_dentry,
struct file *fake_file)
static inline unsigned int CDT2DT(unsigned char cdt)
{
fake_file->f_dentry = cont_dentry;
fake_file->f_pos = coda_file->f_pos;
fake_file->f_version = coda_file->f_version;
fake_file->f_op = cont_dentry->d_inode->i_fop;
fake_file->f_flags = coda_file->f_flags;
return ;
unsigned int dt;
switch(cdt) {
case CDT_UNKNOWN: dt = DT_UNKNOWN; break;
case CDT_FIFO: dt = DT_FIFO; break;
case CDT_CHR: dt = DT_CHR; break;
case CDT_DIR: dt = DT_DIR; break;
case CDT_BLK: dt = DT_BLK; break;
case CDT_REG: dt = DT_REG; break;
case CDT_LNK: dt = DT_LNK; break;
case CDT_SOCK: dt = DT_SOCK; break;
case CDT_WHT: dt = DT_WHT; break;
default: dt = DT_UNKNOWN; break;
}
return dt;
}
/*
* this structure is manipulated by filldir in vfs layer.
* the count holds the remaining amount of space in the getdents buffer,
* beyond the current_dir pointer.
*
* What structure is this comment referring to?? -JH
*/
/* should be big enough to hold any single directory entry */
#define DIR_BUFSIZE 2048
static int coda_venus_readdir(struct file *filp, void *getdent,
filldir_t filldir)
/* support routines */
static int coda_venus_readdir(struct file *filp, filldir_t filldir,
void *getdent)
{
int bufsize;
int offset = filp->f_pos; /* offset in the directory file */
int count = 0;
int pos = 0; /* offset in the block we read */
int result = 0; /* either an error or # of entries returned */
int errfill;
char *buff = NULL;
struct venus_dirent *vdirent;
int string_offset = (int) (&((struct venus_dirent *)(0))->d_name);
int i;
CODA_ALLOC(buff, char *, DIR_BUFSIZE);
if ( !buff ) {
printk("coda_venus_readdir: out of memory.\n");
return -ENOMEM;
}
/* we use this routine to read the file into our buffer */
bufsize = kernel_read(filp, filp->f_pos, buff, DIR_BUFSIZE);
if ( bufsize < 0) {
printk("coda_venus_readdir: cannot read directory %d.\n",
bufsize);
result = bufsize;
goto exit;
}
if ( bufsize == 0) {
result = 0;
goto exit;
}
/* Parse and write into user space. Filldir tells us when done! */
CDEBUG(D_FILE, "buffsize: %d offset %d, count %d.\n",
bufsize, offset, count);
i = 0;
result = 0;
while ( pos + string_offset < bufsize && i < 1024) {
vdirent = (struct venus_dirent *) (buff + pos);
/* test if the name is fully in the buffer */
if ( pos + string_offset + (int) vdirent->d_namlen >= bufsize ){
if ( result == 0 )
printk("CODA: Invalid directory cfino: %ld\n",
filp->f_dentry->d_inode->i_ino);
break;
}
/* now we are certain that we can read the entry from buff */
/* if we don't have a null entry, copy it */
if ( vdirent->d_fileno && vdirent->d_reclen ) {
int namlen = vdirent->d_namlen;
off_t offs = filp->f_pos;
ino_t ino = vdirent->d_fileno;
char *name = vdirent->d_name;
errfill = filldir(getdent, name, namlen,
offs, ino, DT_UNKNOWN);
CDEBUG(D_FILE, "entry %d: ino %ld, namlen %d, reclen %d, type %d, pos %d, string_offs %d, name %*s, offset %d, result: %d, errfill: %d.\n", i,vdirent->d_fileno, vdirent->d_namlen, vdirent->d_reclen, vdirent->d_type, pos, string_offset, vdirent->d_namlen, vdirent->d_name, (u_int) offs, result, errfill);
/* errfill means no space for filling in this round */
if ( errfill < 0 ) {
result = 0;
break;
}
/* adjust count */
result++;
}
/* next one */
filp->f_pos += vdirent->d_reclen;
if ( filp->f_pos > filp->f_dentry->d_inode->i_size )
break;
if ( !vdirent->d_reclen ) {
printk("CODA: Invalid directory, cfino: %ld\n",
filp->f_dentry->d_inode->i_ino);
result = -EINVAL;
int result = 0; /* # of entries returned */
struct venus_dirent *vdir;
unsigned long vdir_size =
(unsigned long)(&((struct venus_dirent *)0)->d_name);
int ret;
vdir = (struct venus_dirent *)kmalloc(sizeof(*vdir), GFP_KERNEL);
if (!vdir) return -ENOMEM;
while(1) {
/* we use this routine to read the file into our buffer */
ret = kernel_read(filp, filp->f_pos, (char *)vdir,
sizeof(*vdir));
if (ret < 0) {
printk("coda_venus_readdir: read dir failed %d\n", ret);
break;
}
pos += (unsigned int) vdirent->d_reclen;
i++;
}
if ( i >= 1024 ) {
printk("Repeating too much in readdir %ld\n",
filp->f_dentry->d_inode->i_ino);
result = -EINVAL;
}
if (ret == 0) break; /* end of directory file reached */
/* catch truncated reads */
if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
printk("coda_venus_readdir: short read: %ld\n",
filp->f_dentry->d_inode->i_ino);
ret = -EBADF;
break;
}
/* validate whether the directory file actually makes sense */
if (vdir->d_reclen < vdir_size + vdir->d_namlen ||
vdir->d_namlen > CODA_MAXNAMLEN) {
printk("coda_venus_readdir: Invalid directory: %ld\n",
filp->f_dentry->d_inode->i_ino);
ret = -EBADF;
break;
}
exit:
CODA_FREE(buff, DIR_BUFSIZE);
return result;
/* skip null entries */
if (vdir->d_fileno) {
unsigned int d_type = CDT2DT(vdir->d_type);
ret = filldir(getdent, vdir->d_name, vdir->d_namlen,
filp->f_pos, vdir->d_fileno, d_type);
/* failure means no space for filling in this round */
if (ret < 0) break;
result++;
}
/* we'll always have progress because d_reclen is unsigned and
* we've already established it is non-zero. */
filp->f_pos += vdir->d_reclen;
}
kfree(vdir);
return result ? result : ret;
}
/* called when a cache lookup succeeds */
......@@ -701,7 +591,7 @@ static int coda_dentry_revalidate(struct dentry *de, int flags)
goto bad;
cii = ITOC(de->d_inode);
if (cii->c_flags & (C_PURGE | C_FLUSH))
if (!(cii->c_flags & (C_PURGE | C_FLUSH)))
goto out;
shrink_dcache_parent(de);
......@@ -710,12 +600,9 @@ static int coda_dentry_revalidate(struct dentry *de, int flags)
if (cii->c_flags & C_FLUSH)
coda_flag_inode_children(inode, C_FLUSH);
if (atomic_read(&de->d_count) > 1) {
if (atomic_read(&de->d_count) > 1)
/* pretend it's valid, but don't change the flags */
CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %s\n",
de->d_inode->i_ino, coda_f2s(&cii->c_fid));
goto out;
}
/* clear the flags. */
cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
......@@ -741,9 +628,6 @@ static int coda_dentry_delete(struct dentry * dentry)
flags = (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
if (is_bad_inode(dentry->d_inode) || flags) {
CDEBUG(D_DOWNCALL, "bad inode, unhashing %s/%s, %ld\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
dentry->d_inode->i_ino);
return 1;
}
return 0;
......@@ -766,10 +650,6 @@ int coda_revalidate_inode(struct dentry *dentry)
struct inode *inode = dentry->d_inode;
struct coda_inode_info *cii = ITOC(inode);
CDEBUG(D_INODE, "revalidating: %*s/%*s\n",
dentry->d_name.len, dentry->d_name.name,
dentry->d_parent->d_name.len, dentry->d_parent->d_name.name);
lock_kernel();
if ( !cii->c_flags )
goto ok;
......@@ -798,9 +678,7 @@ int coda_revalidate_inode(struct dentry *dentry)
if (inode->i_ino != old_ino)
goto return_bad_inode;
if ( cii->c_flags )
coda_flag_inode_children(inode, C_FLUSH);
coda_flag_inode_children(inode, C_FLUSH);
cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
}
......
......@@ -69,6 +69,7 @@ coda_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
cfile->f_flags = flags;
inode->i_size = cinode->i_size;
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
up(&inode->i_sem);
return ret;
......@@ -103,12 +104,8 @@ int coda_open(struct inode *i, struct file *f)
lock_kernel();
coda_vfs_stat.open++;
CDEBUG(D_SPECIAL, "OPEN inode number: %ld, count %d, flags %o.\n",
f->f_dentry->d_inode->i_ino, atomic_read(&f->f_dentry->d_count), flags);
error = venus_open(i->i_sb, coda_i2f(i), coda_flags, &fh);
if (error || !fh) {
CDEBUG(D_FILE, "coda_open: venus_open result %d\n", error);
unlock_kernel();
return error;
}
......@@ -132,12 +129,6 @@ int coda_open(struct inode *i, struct file *f)
f->private_data = cred;
}
CDEBUG(D_FILE, "result %d, coda i->i_count is %d, cii->contcount is %d for ino %ld\n",
error, atomic_read(&i->i_count), cii->c_contcount, i->i_ino);
CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %p\n",
fh->f_dentry->d_inode->i_ino,
atomic_read(&fh->f_dentry->d_inode->i_count),
fh->f_dentry->d_inode->i_op);
unlock_kernel();
return 0;
}
......@@ -174,8 +165,6 @@ int coda_flush(struct file *file)
cinode = cfile->f_dentry->d_inode;
CDEBUG(D_FILE, "FLUSH coda (file %p ct %d)\n", file, fcnt);
err = venus_store(inode->i_sb, coda_i2f(inode), cflags,
(struct coda_cred *)file->private_data);
if (err == -EOPNOTSUPP) {
......@@ -183,7 +172,6 @@ int coda_flush(struct file *file)
err = 0;
}
CDEBUG(D_FILE, "coda_flush: result: %d\n", err);
return err;
}
......
......@@ -245,10 +245,6 @@ static void coda_clear_inode(struct inode *inode)
{
struct coda_inode_info *cii = ITOC(inode);
CDEBUG(D_SUPER, " inode->ino: %ld, count: %d\n",
inode->i_ino, atomic_read(&inode->i_count));
CDEBUG(D_DOWNCALL, "clearing inode: %ld, %x\n", inode->i_ino, cii->c_flags);
if (cii->c_container) BUG();
list_del_init(&cii->c_cilist);
......@@ -264,9 +260,9 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr)
memset(&vattr, 0, sizeof(vattr));
inode->i_ctime = CURRENT_TIME;
coda_iattr_to_vattr(iattr, &vattr);
vattr.va_type = C_VNON; /* cannot set type */
CDEBUG(D_SUPER, "vattr.va_mode %o\n", vattr.va_mode);
/* Venus is responsible for truncating the container-file!!! */
error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr);
......@@ -275,7 +271,6 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr)
coda_vattr_to_iattr(inode, &vattr);
coda_cache_clear_inode(inode);
}
CDEBUG(D_SUPER, "inode.i_mode %o, error %d\n", inode->i_mode, error);
return error;
}
......
......@@ -65,8 +65,6 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
* Look up the pathname. Note that the pathname is in
* user memory, and namei takes care of this
*/
CDEBUG(D_PIOCTL, "namei, data.follow = %d\n",
data.follow);
if ( data.follow ) {
error = user_path_walk(data.path, &nd);
} else {
......@@ -74,15 +72,11 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
}
if ( error ) {
CDEBUG(D_PIOCTL, "error: lookup fails.\n");
return error;
} else {
target_inode = nd.dentry->d_inode;
}
CDEBUG(D_PIOCTL, "target ino: 0x%ld, dev: 0x%x\n",
target_inode->i_ino, kdev_val(target_inode->i_dev));
/* return if it is not a Coda inode */
if ( target_inode->i_sb != inode->i_sb ) {
path_release(&nd);
......@@ -94,9 +88,6 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);
CDEBUG(D_PIOCTL, "ioctl on inode %ld\n", target_inode->i_ino);
CDEBUG(D_DOWNCALL, "dput on ino: %ld, icount %d, dcount %d\n", target_inode->i_ino,
atomic_read(&target_inode->i_count), atomic_read(&nd.dentry->d_count));
path_release(&nd);
return error;
}
......
......@@ -114,9 +114,6 @@ static ssize_t coda_psdev_write(struct file *file, const char *buf,
if (copy_from_user(&hdr, buf, 2 * sizeof(u_long)))
return -EFAULT;
CDEBUG(D_PSDEV, "(process,opc,uniq)=(%d,%ld,%ld), nbytes %ld\n",
current->pid, hdr.opcode, hdr.unique, (long)nbytes);
if (DOWNCALL(hdr.opcode)) {
struct super_block *sb = NULL;
union outputArgs *dcbuf;
......@@ -124,11 +121,9 @@ static ssize_t coda_psdev_write(struct file *file, const char *buf,
sb = vcp->vc_sb;
if ( !sb ) {
CDEBUG(D_PSDEV, "coda_psdev_write: downcall, no SB!\n");
count = nbytes;
goto out;
}
CDEBUG(D_PSDEV, "handling downcall\n");
if ( nbytes < sizeof(struct coda_out_hdr) ) {
printk("coda_downcall opc %ld uniq %ld, not enough!\n",
......@@ -182,8 +177,6 @@ static ssize_t coda_psdev_write(struct file *file, const char *buf,
goto out;
}
CDEBUG(D_PSDEV,"Eureka: uniq %ld on queue!\n", hdr.unique);
/* move data into response buffer. */
if (req->uc_outSize < nbytes) {
printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %ld, uniq: %ld.\n",
......@@ -209,10 +202,6 @@ static ssize_t coda_psdev_write(struct file *file, const char *buf,
outp->fh = fget(outp->fd);
}
CDEBUG(D_PSDEV,
"Found! Count %ld for (opc,uniq)=(%ld,%ld), upc_req at %p\n",
(long)count, hdr.opcode, hdr.unique, &req);
wake_up(&req->uc_sleep);
out:
return(count ? count : retval);
......@@ -277,9 +266,6 @@ static ssize_t coda_psdev_read(struct file * file, char * buf,
goto out;
}
CDEBUG(D_PSDEV, "vcread: signal msg (%d, %d)\n",
req->uc_opcode, req->uc_unique);
CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
upc_free(req);
out:
......@@ -315,8 +301,6 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
file->private_data = vcp;
CDEBUG(D_PSDEV, "device %i - inuse: %d\n", idx, vcp->vc_inuse);
unlock_kernel();
return 0;
}
......@@ -335,14 +319,12 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
return -1;
}
CDEBUG(D_PSDEV, "psdev_release: inuse %d\n", vcp->vc_inuse);
if (--vcp->vc_inuse) {
unlock_kernel();
return 0;
}
/* Wakeup clients so they can return. */
CDEBUG(D_PSDEV, "wake up pending clients\n");
lh = vcp->vc_pending.next;
next = lh;
while ( (lh = next) != &vcp->vc_pending) {
......@@ -359,13 +341,11 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
}
lh = &vcp->vc_processing;
CDEBUG(D_PSDEV, "wake up processing clients\n");
while ( (lh = lh->next) != &vcp->vc_processing) {
req = list_entry(lh, struct upc_req, uc_chain);
req->uc_flags |= REQ_ABORT;
wake_up(&req->uc_sleep);
}
CDEBUG(D_PSDEV, "Done.\n");
unlock_kernel();
return 0;
......
......@@ -37,26 +37,18 @@ static struct ctl_table_header *fs_table_header;
#define FS_CODA 1 /* Coda file system */
#define CODA_DEBUG 1 /* control debugging */
#define CODA_ENTRY 2 /* control enter/leave pattern */
#define CODA_TIMEOUT 3 /* timeout on upcalls to become intrble */
#define CODA_MC 4 /* use/do not use the access cache */
#define CODA_HARD 5 /* mount type "hard" or "soft" */
#define CODA_VFS 6 /* vfs statistics */
#define CODA_UPCALL 7 /* upcall statistics */
#define CODA_PERMISSION 8 /* permission statistics */
#define CODA_CACHE_INV 9 /* cache invalidation statistics */
#define CODA_FAKE_STATFS 10 /* don't query venus for actual cache usage */
static ctl_table coda_table[] = {
{CODA_DEBUG, "debug", &coda_debug, sizeof(int), 0644, NULL, &proc_dointvec},
{CODA_ENTRY, "printentry", &coda_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
{CODA_MC, "accesscache", &coda_access_cache, sizeof(int), 0644, NULL, &proc_dointvec},
{CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &proc_dointvec},
{CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &proc_dointvec},
{CODA_VFS, "vfs_stats", NULL, 0, 0644, NULL, &do_reset_coda_vfs_stats},
{CODA_UPCALL, "upcall_stats", NULL, 0, 0644, NULL, &do_reset_coda_upcall_stats},
{CODA_PERMISSION, "permission_stats", NULL, 0, 0644, NULL, &do_reset_coda_permission_stats},
{CODA_CACHE_INV, "cache_inv_stats", NULL, 0, 0644, NULL, &do_reset_coda_cache_inv_stats},
{CODA_FAKE_STATFS, "fake_statfs", &coda_fake_statfs, sizeof(int), 0600, NULL, &proc_dointvec},
{ 0 }
......@@ -68,7 +60,6 @@ static ctl_table fs_table[] = {
};
struct coda_vfs_stats coda_vfs_stat;
struct coda_permission_stats coda_permission_stat;
struct coda_cache_inv_stats coda_cache_inv_stat;
struct coda_upcall_stats_entry coda_upcall_stat[CODA_NCALLS];
struct coda_upcallstats coda_callstats;
......@@ -126,11 +117,6 @@ void reset_coda_upcall_stats( void )
memset( &coda_upcall_stat, 0, sizeof( coda_upcall_stat ) );
}
void reset_coda_permission_stats( void )
{
memset( &coda_permission_stat, 0, sizeof( coda_permission_stat ) );
}
void reset_coda_cache_inv_stats( void )
{
memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) );
......@@ -141,7 +127,6 @@ void do_time_stats( struct coda_upcall_stats_entry * pentry,
unsigned long runtime )
{
unsigned long time = runtime; /* time in us */
CDEBUG(D_SPECIAL, "time: %ld\n", time);
if ( pentry->count == 0 ) {
pentry->time_sum = pentry->time_squared_sum = 0;
......@@ -257,21 +242,6 @@ int do_reset_coda_upcall_stats( ctl_table * table, int write,
return 0;
}
int do_reset_coda_permission_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp )
{
if ( write ) {
reset_coda_permission_stats();
filp->f_pos += *lenp;
} else {
*lenp = 0;
}
return 0;
}
int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp )
......@@ -394,35 +364,6 @@ int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
return len;
}
int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
int length)
{
int len=0;
off_t begin;
struct coda_permission_stats * ps = & coda_permission_stat;
/* this works as long as we are below 1024 characters! */
len += sprintf( buffer,
"Coda permission statistics\n"
"==========================\n\n"
"count\t\t%9d\n"
"hit count\t%9d\n",
ps->count,
ps->hit_count );
begin = offset;
*start = buffer + begin;
len -= begin;
if ( len > length )
len = length;
if ( len < 0 )
len = 0;
return len;
}
int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
int length)
{
......@@ -484,7 +425,6 @@ void coda_sysctl_init()
memset(&coda_callstats, 0, sizeof(coda_callstats));
reset_coda_vfs_stats();
reset_coda_upcall_stats();
reset_coda_permission_stats();
reset_coda_cache_inv_stats();
#ifdef CONFIG_PROC_FS
......@@ -493,7 +433,6 @@ void coda_sysctl_init()
proc_fs_coda->owner = THIS_MODULE;
coda_proc_create("vfs_stats", coda_vfs_stats_get_info);
coda_proc_create("upcall_stats", coda_upcall_stats_get_info);
coda_proc_create("permission_stats", coda_permission_stats_get_info);
coda_proc_create("cache_inv_stats", coda_cache_inv_stats_get_info);
}
#endif
......@@ -516,7 +455,6 @@ void coda_sysctl_clean()
#if CONFIG_PROC_FS
remove_proc_entry("cache_inv_stats", proc_fs_coda);
remove_proc_entry("permission_stats", proc_fs_coda);
remove_proc_entry("upcall_stats", proc_fs_coda);
remove_proc_entry("vfs_stats", proc_fs_coda);
remove_proc_entry("coda", proc_root_fs);
......
......@@ -89,8 +89,6 @@ int venus_rootfid(struct super_block *sb, ViceFid *fidp)
printk("coda_get_rootfid: error %d\n", error);
} else {
*fidp = (ViceFid) outp->coda_root.VFid;
CDEBUG(D_SUPER, "VolumeId: %lx, VnodeId: %lx.\n",
fidp->Volume, fidp->Vnode);
}
CODA_FREE(inp, insize);
......@@ -131,7 +129,6 @@ int venus_setattr(struct super_block *sb, struct ViceFid *fid,
error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
CDEBUG(D_SUPER, " result %d\n", error);
CODA_FREE(inp, insize);
return error;
}
......@@ -313,8 +310,6 @@ int venus_rename(struct super_block *sb, struct ViceFid *old_fid,
memcpy((char *)(inp) + offset, new_name, new_length);
*((char *)inp + offset + new_length) = '\0';
CDEBUG(D_INODE, "destname in packet: %s\n",
(char *)inp + (int) inp->coda_rename.destname);
error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
CODA_FREE(inp, insize);
......@@ -426,7 +421,6 @@ int venus_readlink(struct super_block *sb, struct ViceFid *fid,
*(buffer + retlen) = '\0';
}
CDEBUG(D_INODE, " result %d\n",error);
CODA_FREE(inp, insize);
return error;
}
......@@ -455,7 +449,6 @@ int venus_link(struct super_block *sb, struct ViceFid *fid,
error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
CDEBUG(D_INODE, " result %d\n",error);
CODA_FREE(inp, insize);
return error;
}
......@@ -491,7 +484,6 @@ int venus_symlink(struct super_block *sb, struct ViceFid *fid,
error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
CDEBUG(D_INODE, " result %d\n",error);
CODA_FREE(inp, insize);
return error;
}
......@@ -580,9 +572,6 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
/* Copy out the OUT buffer. */
if (outp->coda_ioctl.len > data->vi.out_size) {
CDEBUG(D_FILE, "return len %d <= request len %d\n",
outp->coda_ioctl.len,
data->vi.out_size);
error = -EINVAL;
} else {
error = verify_area(VERIFY_WRITE, data->vi.out,
......@@ -623,7 +612,6 @@ int venus_statfs(struct super_block *sb, struct statfs *sfs)
printk("coda_statfs: Venus returns: %d\n", error);
}
CDEBUG(D_INODE, " result %d\n",error);
CODA_FREE(inp, insize);
return error;
}
......@@ -684,10 +672,6 @@ static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp,
end.tv_usec -= begin.tv_usec;
}
CDEBUG(D_SPECIAL, "begin: %ld.%06ld, elapsed: %ld.%06ld\n",
begin.tv_sec, (unsigned long)begin.tv_usec,
end.tv_sec, (unsigned long)end.tv_usec);
return ((end.tv_sec * 1000000) + end.tv_usec);
}
......@@ -738,10 +722,6 @@ static int coda_upcall(struct coda_sb_info *sbi,
/* Append msg to pending queue and poke Venus. */
list_add(&(req->uc_chain), vcommp->vc_pending.prev);
CDEBUG(D_UPCALL,
"Proc %d wake Venus for(opc,uniq) =(%d,%d) msg at %p.zzz.\n",
current->pid, req->uc_opcode, req->uc_unique, req);
wake_up_interruptible(&vcommp->vc_waitq);
/* We can be interrupted while we wait for Venus to process
* our request. If the interrupt occurs before Venus has read
......@@ -756,29 +736,17 @@ static int coda_upcall(struct coda_sb_info *sbi,
runtime = coda_waitfor_upcall(req, vcommp);
coda_upcall_stats(((union inputArgs *)buffer)->ih.opcode, runtime);
CDEBUG(D_TIMING, "opc: %d time: %ld uniq: %d size: %d\n",
req->uc_opcode, jiffies - req->uc_posttime,
req->uc_unique, req->uc_outSize);
CDEBUG(D_UPCALL,
"..process %d woken up by Venus for req at %p, data at %p\n",
current->pid, req, req->uc_data);
if (vcommp->vc_inuse) { /* i.e. Venus is still alive */
/* Op went through, interrupt or not... */
if (req->uc_flags & REQ_WRITE) {
out = (union outputArgs *)req->uc_data;
/* here we map positive Venus errors to kernel errors */
error = -out->oh.result;
CDEBUG(D_UPCALL,
"upcall: (u,o,r) (%ld, %ld, %ld) out at %p\n",
out->oh.unique, out->oh.opcode, out->oh.result, out);
*outSize = req->uc_outSize;
goto exit;
}
if ( !(req->uc_flags & REQ_READ) && signal_pending(current)) {
/* Interrupted before venus read it. */
CDEBUG(D_UPCALL,
"Interrupted before read:(op,un) (%d.%d), flags = %x\n",
req->uc_opcode, req->uc_unique, req->uc_flags);
list_del(&(req->uc_chain));
/* perhaps the best way to convince the app to
give up? */
......@@ -790,10 +758,6 @@ static int coda_upcall(struct coda_sb_info *sbi,
union inputArgs *sig_inputArgs;
struct upc_req *sig_req;
CDEBUG(D_UPCALL,
"Sending Venus a signal: op = %d.%d, flags = %x\n",
req->uc_opcode, req->uc_unique, req->uc_flags);
list_del(&(req->uc_chain));
error = -ENOMEM;
sig_req = upc_alloc();
......@@ -815,9 +779,6 @@ static int coda_upcall(struct coda_sb_info *sbi,
sig_req->uc_unique = sig_inputArgs->ih.unique;
sig_req->uc_inSize = sizeof(struct coda_in_hdr);
sig_req->uc_outSize = sizeof(struct coda_in_hdr);
CDEBUG(D_UPCALL,
"coda_upcall: enqueing signal msg (%d, %d)\n",
sig_req->uc_opcode, sig_req->uc_unique);
/* insert at head of queue! */
list_add(&(sig_req->uc_chain), &vcommp->vc_pending);
......@@ -876,16 +837,13 @@ static int coda_upcall(struct coda_sb_info *sbi,
int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
{
/* Handle invalidation requests. */
if ( !sb || !sb->s_root || !sb->s_root->d_inode) {
CDEBUG(D_DOWNCALL, "coda_downcall: opcode %d, no sb!\n", opcode);
if ( !sb || !sb->s_root || !sb->s_root->d_inode)
return 0;
}
switch (opcode) {
case CODA_FLUSH : {
clstats(CODA_FLUSH);
CDEBUG(D_DOWNCALL, "CODA_FLUSH\n");
coda_cache_clear_all(sb, NULL);
shrink_dcache_sb(sb);
coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
......@@ -894,7 +852,6 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
case CODA_PURGEUSER : {
struct coda_cred *cred = &out->coda_purgeuser.cred;
CDEBUG(D_DOWNCALL, "CODA_PURGEUSER\n");
if ( !cred ) {
printk("PURGEUSER: null cred!\n");
return 0;
......@@ -907,19 +864,14 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
case CODA_ZAPDIR : {
struct inode *inode;
ViceFid *fid = &out->coda_zapdir.CodaFid;
CDEBUG(D_DOWNCALL, "zapdir: fid = %s...\n", coda_f2s(fid));
clstats(CODA_ZAPDIR);
inode = coda_fid_to_inode(fid, sb);
if (inode) {
CDEBUG(D_DOWNCALL, "zapdir: inode = %ld children flagged\n",
inode->i_ino);
coda_flag_inode_children(inode, C_PURGE);
CDEBUG(D_DOWNCALL, "zapdir: inode = %ld cache cleared\n", inode->i_ino);
coda_flag_inode(inode, C_VATTR);
iput(inode);
} else
CDEBUG(D_DOWNCALL, "zapdir: no inode\n");
}
return(0);
}
......@@ -928,27 +880,20 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
struct inode *inode;
struct ViceFid *fid = &out->coda_zapfile.CodaFid;
clstats(CODA_ZAPFILE);
CDEBUG(D_DOWNCALL, "zapfile: fid = %s\n", coda_f2s(fid));
inode = coda_fid_to_inode(fid, sb);
if ( inode ) {
CDEBUG(D_DOWNCALL, "zapfile: inode = %ld\n",
inode->i_ino);
coda_flag_inode(inode, C_VATTR);
iput(inode);
} else
CDEBUG(D_DOWNCALL, "zapfile: no inode\n");
}
return 0;
}
case CODA_PURGEFID : {
struct inode *inode;
ViceFid *fid = &out->coda_purgefid.CodaFid;
CDEBUG(D_DOWNCALL, "purgefid: fid = %s\n", coda_f2s(fid));
clstats(CODA_PURGEFID);
inode = coda_fid_to_inode(fid, sb);
if ( inode ) {
CDEBUG(D_DOWNCALL, "purgefid: inode = %ld\n",
inode->i_ino);
coda_flag_inode_children(inode, C_PURGE);
/* catch the dentries later if some are still busy */
......@@ -956,8 +901,7 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
d_prune_aliases(inode);
iput(inode);
} else
CDEBUG(D_DOWNCALL, "purgefid: no inode\n");
}
return 0;
}
......@@ -966,16 +910,11 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
ViceFid *oldfid = &out->coda_replace.OldFid;
ViceFid *newfid = &out->coda_replace.NewFid;
clstats(CODA_REPLACE);
CDEBUG(D_DOWNCALL, "CODA_REPLACE\n");
inode = coda_fid_to_inode(oldfid, sb);
if ( inode ) {
CDEBUG(D_DOWNCALL, "replacefid: inode = %ld\n",
inode->i_ino);
coda_replace_fid(inode, oldfid, newfid);
iput(inode);
}else
CDEBUG(D_DOWNCALL, "purgefid: no inode\n");
}
return 0;
}
}
......
......@@ -34,6 +34,7 @@ struct coda_inode_info {
#define C_PURGE 0x8
int coda_cnode_make(struct inode **, struct ViceFid *, struct super_block *);
struct inode *coda_iget(struct super_block *sb, struct ViceFid *fid, struct coda_vattr *attr);
int coda_cnode_makectl(struct inode **inode, struct super_block *sb);
struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb);
void coda_replace_fid(struct inode *, ViceFid *, ViceFid *);
......
......@@ -44,8 +44,6 @@ int coda_notify_change(struct dentry *, struct iattr *);
int coda_isnullfid(ViceFid *fid);
/* global variables */
extern int coda_debug;
extern int coda_print_entry;
extern int coda_access_cache;
extern int coda_fake_statfs;
......@@ -70,44 +68,19 @@ int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2);
void coda_sysctl_init(void);
void coda_sysctl_clean(void);
/* debugging masks */
#define D_SUPER 1 /* print results returned by Venus */
#define D_INODE 2 /* print entry and exit into procedure */
#define D_FILE 4
#define D_CACHE 8 /* cache debugging */
#define D_MALLOC 16 /* print malloc, de-alloc information */
#define D_CNODE 32
#define D_UPCALL 64 /* up and downcall debugging */
#define D_PSDEV 128
#define D_PIOCTL 256
#define D_SPECIAL 512
#define D_TIMING 1024
#define D_DOWNCALL 2048
#define CDEBUG(mask, format, a...) \
do { \
if (coda_debug & mask) { \
printk("(%s,l. %d): ", __FUNCTION__, __LINE__); \
printk(format, ## a); } \
} while (0)
#define CODA_ALLOC(ptr, cast, size) \
do { \
if (size < PAGE_SIZE) { \
ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \
CDEBUG(D_MALLOC, "kmalloced: %lx at %p.\n", (long)size, ptr); \
} else { \
ptr = (cast)vmalloc((unsigned long) size); \
CDEBUG(D_MALLOC, "vmalloced: %lx at %p .\n", (long)size, ptr);} \
if (ptr == 0) { \
#define CODA_ALLOC(ptr, cast, size) do { \
if (size < PAGE_SIZE) \
ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \
else \
ptr = (cast)vmalloc((unsigned long) size); \
if (!ptr) \
printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
} \
else memset( ptr, 0, size ); \
else memset( ptr, 0, size ); \
} while (0)
#define CODA_FREE(ptr,size) do {if (size < PAGE_SIZE) { kfree((ptr)); CDEBUG(D_MALLOC, "kfreed: %lx at %p.\n", (long) size, ptr); } else { vfree((ptr)); CDEBUG(D_MALLOC, "vfreed: %lx at %p.\n", (long) size, ptr);} } while (0)
#define CODA_FREE(ptr,size) \
do { if (size < PAGE_SIZE) kfree((ptr)); else vfree((ptr)); } while (0)
/* inode to cnode access functions */
......
......@@ -24,14 +24,12 @@ void coda_upcall_stats(int opcode, unsigned long jiffies);
*
* /proc/fs/coda/vfs_stats
* upcall_stats
* permission_stats
* cache_inv_stats
*
* these four files are presented to reset the statistics to 0:
*
* /proc/sys/coda/vfs_stats
* upcall_stats
* permission_stats
* cache_inv_stats
*/
......@@ -70,15 +68,6 @@ struct coda_upcall_stats_entry
unsigned long time_squared_sum;
};
/* cache hits for permissions statistics */
struct coda_permission_stats
{
int count;
int hit_count;
};
/* cache invalidation statistics */
struct coda_cache_inv_stats
{
......@@ -93,14 +82,12 @@ struct coda_cache_inv_stats
/* these global variables hold the actual statistics data */
extern struct coda_vfs_stats coda_vfs_stat;
extern struct coda_permission_stats coda_permission_stat;
extern struct coda_cache_inv_stats coda_cache_inv_stat;
extern int coda_upcall_timestamping;
/* reset statistics to 0 */
void reset_coda_vfs_stats( void );
void reset_coda_upcall_stats( void );
void reset_coda_permission_stats( void );
void reset_coda_cache_inv_stats( void );
/* some utitlities to make it easier for you to do statistics for time */
......@@ -121,9 +108,6 @@ int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
int do_reset_coda_upcall_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp );
int do_reset_coda_permission_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp );
int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp );
......@@ -133,8 +117,6 @@ int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
int length);
int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
int length);
int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
int length);
int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
int length);
......
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