(Illustration by Gaich Muramatsu)
Jan, Here is the patched for the kernel code improvements. I think the lockups are gone, the accidental rebuilds are gone and several other problems. It patches well against 86, 88 and 78 (and probably most other kernels). Note that after I patched I had to move the file coda_fs_i.h in place -- probably I don't know an option on patch right. The bad news is that I did get an oops yesterday and I have not found out what it is yet -- but it's better. Peter diff -uNr linux-2.1.86.orig/CREDITS linux/CREDITS --- linux-2.1.86.orig/CREDITS Tue Feb 10 15:37:42 1998 +++ linux/CREDITS Wed Feb 25 08:59:58 1998 @@ -202,6 +202,14 @@ S: Columbus, Ohio 43210 S: USA +N: Peter Braam +E: braam_at_cs.cmu.edu +W: http://coda.cs.cmu.edu/~braam +D: Coda Filesystem +S: Dept of Computer Science +S: 5000 Forbes Ave +S: Pittsburgh PA 15213 + N: Andries Brouwer E: aeb_at_cwi.nl D: random Linux hacker diff -uNr linux-2.1.86.orig/Documentation/filesystems/coda.txt linux/Documentation/filesystems/coda.txt --- linux-2.1.86.orig/Documentation/filesystems/coda.txt Sun Dec 21 17:45:14 1997 +++ linux/Documentation/filesystems/coda.txt Wed Feb 25 08:53:16 1998 @@ -1,3 +1,27 @@ + +NOTE: +This is one of the technical documents describing a component of +Coda -- this document describes the client kernel-Venus interface. + +For more information: + http://www.coda.cs.cmu.edu +For user level software needed to run Coda: + ftp://ftp.coda.cs.cmu.edu + +To run Coda you need to get a user level cache manager for the client, +named Venus, as well as tools to manipulate ACL's, to log in etc. The +client needs to have the Coda filesystem selected in the kernel +configuration. + +The server needs a user level server and at present does not depend on +kernel support. + + + + + + + The Venus kernel interface Peter J. Braam v1.0, Nov 9, 1997 diff -uNr linux-2.1.86.orig/fs/coda/cache.c linux/fs/coda/cache.c --- linux-2.1.86.orig/fs/coda/cache.c Tue Jan 6 13:00:21 1998 +++ linux/fs/coda/cache.c Wed Mar 4 17:21:58 1998 @@ -21,7 +21,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> #include <linux/coda_psdev.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_cache.h> /* Keep various stats */ @@ -42,7 +42,7 @@ list_add(&el->cc_cclist, &sbi->sbi_cchead); } -void coda_cninsert(struct coda_cache *el, struct cnode *cnp) +void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cnp) { ENTRY; if ( !cnp || !el) { @@ -54,23 +54,29 @@ void coda_ccremove(struct coda_cache *el) { -ENTRY; - list_del(&el->cc_cclist); + ENTRY; + if (el->cc_cclist.next && el->cc_cclist.prev) + list_del(&el->cc_cclist); + else + printk("coda_cnremove: trying to remove 0 entry!"); } void coda_cnremove(struct coda_cache *el) { -ENTRY; - list_del(&el->cc_cnlist); + ENTRY; + if (el->cc_cnlist.next && el->cc_cnlist.prev) + list_del(&el->cc_cnlist); + else + printk("coda_cnremove: trying to remove 0 entry!"); } void coda_cache_create(struct inode *inode, int mask) { - struct cnode *cnp = ITOC(inode); + struct coda_inode_info *cnp = ITOC(inode); struct super_block *sb = inode->i_sb; struct coda_cache *cc = NULL; -ENTRY; + ENTRY; CODA_ALLOC(cc, struct coda_cache *, sizeof(*cc)); if ( !cc ) { @@ -85,7 +91,7 @@ struct coda_cache * coda_cache_find(struct inode *inode) { - struct cnode *cnp = ITOC(inode); + struct coda_inode_info *cnp = ITOC(inode); struct list_head *lh, *le; struct coda_cache *cc = NULL; @@ -114,7 +120,7 @@ } } -void coda_cache_clear_cnp(struct cnode *cnp) +void coda_cache_clear_cnp(struct coda_inode_info *cnp) { struct list_head *lh, *le; struct coda_cache *cc; @@ -178,7 +184,7 @@ int coda_cache_check(struct inode *inode, int mask) { - struct cnode *cnp = ITOC(inode); + struct coda_inode_info *cnp = ITOC(inode); struct list_head *lh, *le; struct coda_cache *cc = NULL; @@ -207,9 +213,8 @@ static void coda_flag_children(struct dentry *parent) { struct list_head *child; - struct cnode *cnp; + struct coda_inode_info *cnp; struct dentry *de; - char str[50]; child = parent->d_subdirs.next; while ( child != &parent->d_subdirs ) { @@ -217,7 +222,7 @@ cnp = ITOC(de->d_inode); if (cnp) cnp->c_flags |= C_ZAPFID; - CDEBUG(D_CACHE, "ZAPFID for %s\n", coda_f2s(&cnp->c_fid, str)); + CDEBUG(D_CACHE, "ZAPFID for %s\n", coda_f2s(&cnp->c_fid)); child = child->next; } @@ -228,7 +233,7 @@ void coda_dentry_delete(struct dentry *dentry) { struct inode *inode = dentry->d_inode; - struct cnode *cnp = NULL; + struct coda_inode_info *cnp = NULL; ENTRY; if (inode) { @@ -254,7 +259,7 @@ return; } -static void coda_zap_cnode(struct cnode *cnp, int flags) +static void coda_zap_cnode(struct coda_inode_info *cnp, int flags) { cnp->c_flags |= flags; coda_cache_clear_cnp(cnp); @@ -267,7 +272,7 @@ void coda_zapfid(struct ViceFid *fid, struct super_block *sb, int flag) { struct inode *inode = NULL; - struct cnode *cnp; + struct coda_inode_info *cnp; ENTRY; @@ -286,7 +291,7 @@ struct coda_sb_info *sbi = coda_sbp(sb); le = lh = &sbi->sbi_volroothead; while ( (le = le->next) != lh ) { - cnp = list_entry(le, struct cnode, c_volrootlist); + cnp = list_entry(le, struct coda_inode_info, c_volrootlist); if ( cnp->c_fid.Volume == fid->Volume) coda_zap_cnode(cnp, flag); } @@ -300,11 +305,6 @@ return; } cnp = ITOC(inode); - CHECK_CNODE(cnp); - if ( !cnp ) { - printk("coda_zapfid: no cnode!\n"); - return; - } coda_zap_cnode(cnp, flag); } diff -uNr linux-2.1.86.orig/fs/coda/cnode.c linux/fs/coda/cnode.c --- linux-2.1.86.orig/fs/coda/cnode.c Tue Jan 6 13:00:21 1998 +++ linux/fs/coda/cnode.c Wed Mar 4 17:03:18 1998 @@ -1,5 +1,5 @@ /* cnode related routines for the coda kernel code - Peter Braam, Sep 1996. + (C) 1996 Peter Braam */ #include <linux/types.h> @@ -7,37 +7,14 @@ #include <linux/coda.h> #include <linux/coda_linux.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_psdev.h> extern int coda_debug; extern int coda_print_entry; /* cnode.c */ -static struct cnode *coda_cnode_alloc(void); -/* return pointer to new empty cnode */ -static struct cnode *coda_cnode_alloc(void) -{ - struct cnode *result = NULL; - - CODA_ALLOC(result, struct cnode *, sizeof(struct cnode)); - if ( !result ) { - printk("coda_cnode_alloc: kmalloc returned NULL.\n"); - return result; - } - - memset(result, 0, (int) sizeof(struct cnode)); - INIT_LIST_HEAD(&(result->c_cnhead)); - INIT_LIST_HEAD(&(result->c_volrootlist)); - return result; -} - -/* release cnode memory */ -void coda_cnode_free(struct cnode *cinode) -{ - CODA_FREE(cinode, sizeof(struct cnode)); -} static void coda_fill_inode (struct inode *inode, struct coda_vattr *attr) @@ -70,12 +47,11 @@ */ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb) { - struct cnode *cnp; + struct coda_inode_info *cnp; struct coda_sb_info *sbi= coda_sbp(sb); struct coda_vattr attr; int error; ino_t ino; - char str[50]; ENTRY; @@ -86,7 +62,7 @@ error = venus_getattr(sb, fid, &attr); if ( error ) { printk("coda_cnode_make: coda_getvattr returned %d for %s.\n", - error, coda_f2s(fid, str)); + error, coda_f2s(fid)); *inode = NULL; return error; } @@ -98,27 +74,19 @@ return -ENOMEM; } - /* link the cnode and the vfs inode - if this inode is not linked yet - */ - if ( !(*inode)->u.generic_ip ) { - cnp = coda_cnode_alloc(); - if ( !cnp ) { - printk("coda_cnode_make: coda_cnode_alloc failed.\n"); - clear_inode(*inode); - return -ENOMEM; - } - cnp->c_fid = *fid; - cnp->c_magic = CODA_CNODE_MAGIC; + cnp = ITOC(*inode); + if ( cnp->c_magic == 0 ) { + memset(cnp, 0, (int) sizeof(struct coda_inode_info)); + cnp->c_fid = *fid; + cnp->c_magic = CODA_CNODE_MAGIC; cnp->c_flags = C_VATTR; - cnp->c_vnode = *inode; - (*inode)->u.generic_ip = (void *) cnp; - CDEBUG(D_CNODE, "LINKING: ino %ld, count %d at 0x%x with cnp 0x%x, cnp->c_vnode 0x%x, in->u.generic_ip 0x%x\n", (*inode)->i_ino, (*inode)->i_count, (int) (*inode), (int) cnp, (int)cnp->c_vnode, (int) (*inode)->u.generic_ip); + cnp->c_vnode = *inode; + INIT_LIST_HEAD(&(cnp->c_cnhead)); + INIT_LIST_HEAD(&(cnp->c_volrootlist)); } else { - cnp = (struct cnode *)(*inode)->u.generic_ip; - CDEBUG(D_CNODE, "FOUND linked: ino %ld, count %d, at 0x%x with cnp 0x%x, cnp->c_vnode 0x%x\n", (*inode)->i_ino, (*inode)->i_count, (int) (*inode), (int) cnp, (int)cnp->c_vnode); + printk("coda_cnode make on initialized inode %ld, %s!\n", + (*inode)->i_ino, coda_f2s(&cnp->c_fid)); } - CHECK_CNODE(cnp); /* fill in the inode attributes */ if ( coda_fid_is_volroot(fid) ) @@ -145,14 +113,14 @@ /* convert a fid to an inode. Avoids having a hash table such as present in the Mach minicache */ -struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) { +struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) +{ ino_t nr; struct inode *inode; - struct cnode *cnp; - char str[50]; + struct coda_inode_info *cnp; ENTRY; - CDEBUG(D_INODE, "%s\n", coda_f2s(fid, str)); + CDEBUG(D_INODE, "%s\n", coda_f2s(fid)); nr = coda_f2i(fid); inode = iget(sb, nr); @@ -164,12 +132,13 @@ } /* check if this inode is linked to a cnode */ - cnp = (struct cnode *) inode->u.generic_ip; - if ( cnp == NULL ) { + cnp = ITOC(inode); + + if ( cnp->c_magic != CODA_CNODE_MAGIC ) { iput(inode); - EXIT; return NULL; } + /* make sure fid is the one we want */ if ( !coda_fideq(fid, &(cnp->c_fid)) ) { printk("coda_fid2inode: bad cnode! Tell Peter.\n"); diff -uNr linux-2.1.86.orig/fs/coda/coda_linux.c linux/fs/coda/coda_linux.c --- linux-2.1.86.orig/fs/coda/coda_linux.c Tue Jan 6 13:00:21 1998 +++ linux/fs/coda/coda_linux.c Wed Mar 4 16:40:44 1998 @@ -21,7 +21,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> #include <linux/coda_psdev.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_cache.h> /* initialize the debugging variables */ @@ -30,10 +30,11 @@ int coda_access_cache = 1; /* caller must allocate 36 byte string ! */ -char * coda_f2s(ViceFid *f, char *s) +char * coda_f2s(ViceFid *f) { + static char s[50]; if ( f ) { - sprintf(s, "(%-#10lx,%-#10lx,%-#10lx)", + sprintf(s, "(%10lx,%10lx,%10lx)", f->Volume, f->Vnode, f->Unique); } return s; diff -uNr linux-2.1.86.orig/fs/coda/dir.c linux/fs/coda/dir.c --- linux-2.1.86.orig/fs/coda/dir.c Tue Jan 6 13:00:21 1998 +++ linux/fs/coda/dir.c Wed Mar 4 16:51:41 1998 @@ -21,7 +21,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> #include <linux/coda_psdev.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_cache.h> /* dir inode-ops */ @@ -98,7 +98,7 @@ /* acces routines: lookup, readlink, permission */ static int coda_lookup(struct inode *dir, struct dentry *entry) { - struct cnode *dircnp; + struct coda_inode_info *dircnp; struct inode *res_inode = NULL; struct ViceFid resfid; int dropme = 0; /* to indicate entry should not be cached */ @@ -106,7 +106,6 @@ int error = 0; const char *name = entry->d_name.name; size_t length = entry->d_name.len; - char str[50]; ENTRY; CDEBUG(D_INODE, "name %s, len %d in ino %ld\n", @@ -122,12 +121,12 @@ if ( length > CFS_MAXNAMLEN ) { printk("name too long: lookup, %s (%*s)\n", - coda_f2s(&dircnp->c_fid, str), length, name); + coda_f2s(&dircnp->c_fid), length, name); return -ENAMETOOLONG; } CDEBUG(D_INODE, "lookup: %*s in %s\n", length, name, - coda_f2s(&dircnp->c_fid, str)); + coda_f2s(&dircnp->c_fid)); /* control object, create inode on the fly */ if (coda_isroot(dir) && coda_iscontrol(name, length)) { @@ -150,11 +149,11 @@ return -error; } else if (error != -ENOENT) { CDEBUG(D_INODE, "error for %s(%*s)%d\n", - coda_f2s(&dircnp->c_fid, str), length, name, error); + coda_f2s(&dircnp->c_fid), length, name, error); return error; } CDEBUG(D_INODE, "lookup: %s is (%s) type %d result %d, dropme %d\n", - name, coda_f2s(&resfid, str), type, error, dropme); + name, coda_f2s(&resfid), type, error, dropme); exit: entry->d_time = 0; @@ -169,9 +168,8 @@ int coda_permission(struct inode *inode, int mask) { - struct cnode *cp; + struct coda_inode_info *cp; int error; - char str[50]; ENTRY; @@ -193,7 +191,7 @@ error = venus_access(inode->i_sb, &(cp->c_fid), mask); CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %d\n", - coda_f2s(&(cp->c_fid), str), inode->i_ino, mask, error); + coda_f2s(&(cp->c_fid)), inode->i_ino, mask, error); if ( error == 0 ) { coda_cache_enter(inode, mask); @@ -209,7 +207,7 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode) { int error=0; - struct cnode *dircnp; + struct coda_inode_info *dircnp; const char *name=de->d_name.name; int length=de->d_name.len; struct inode *result = NULL; @@ -232,7 +230,7 @@ if ( length > CFS_MAXNAMLEN ) { char str[50]; printk("name too long: create, %s(%s)\n", - coda_f2s(&dircnp->c_fid, str), name); + coda_f2s(&dircnp->c_fid), name); return -ENAMETOOLONG; } @@ -242,7 +240,7 @@ if ( error ) { char str[50]; CDEBUG(D_INODE, "create: %s, result %d\n", - coda_f2s(&newfid, str), error); + coda_f2s(&newfid), error); d_drop(de); return error; } @@ -262,14 +260,13 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) { - struct cnode *dircnp; + struct coda_inode_info *dircnp; struct inode *inode; struct coda_vattr attr; const char *name = de->d_name.name; int len = de->d_name.len; int error; struct ViceFid newfid; - char fidstr[50]; if (!dir || !S_ISDIR(dir->i_mode)) { @@ -287,7 +284,7 @@ CHECK_CNODE(dircnp); CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n", - name, len, coda_f2s(&(dircnp->c_fid), fidstr), mode); + name, len, coda_f2s(&(dircnp->c_fid)), mode); attr.va_mode = mode; error = venus_mkdir(dir->i_sb, &(dircnp->c_fid), @@ -295,13 +292,13 @@ if ( error ) { CDEBUG(D_INODE, "mkdir error: %s result %d\n", - coda_f2s(&newfid, fidstr), error); + coda_f2s(&newfid), error); d_drop(de); return error; } CDEBUG(D_INODE, "mkdir: new dir has fid %s.\n", - coda_f2s(&newfid, fidstr)); + coda_f2s(&newfid)); error = coda_cnode_make(&inode, &newfid, dir->i_sb); if ( error ) { @@ -323,7 +320,7 @@ struct inode *inode = source_de->d_inode; const char * name = de->d_name.name; int len = de->d_name.len; - struct cnode *dir_cnp, *cnp; + struct coda_inode_info *dir_cnp, *cnp; char str[50]; int error; @@ -337,8 +334,8 @@ cnp = ITOC(inode); CHECK_CNODE(cnp); - CDEBUG(D_INODE, "old: fid: %s\n", coda_f2s(&(cnp->c_fid), str)); - CDEBUG(D_INODE, "directory: %s\n", coda_f2s(&(dir_cnp->c_fid), str)); + CDEBUG(D_INODE, "old: fid: %s\n", coda_f2s(&(cnp->c_fid))); + CDEBUG(D_INODE, "directory: %s\n", coda_f2s(&(dir_cnp->c_fid))); if ( len > CFS_MAXNAMLEN ) { printk("coda_link: name too long. \n"); @@ -367,7 +364,7 @@ { const char *name = de->d_name.name; int len = de->d_name.len; - struct cnode *dir_cnp = ITOC(dir_inode); + struct coda_inode_info *dir_cnp = ITOC(dir_inode); int symlen; int error=0; @@ -407,7 +404,7 @@ int coda_unlink(struct inode *dir, struct dentry *de) { - struct cnode *dircnp; + struct coda_inode_info *dircnp; int error; const char *name = de->d_name.name; int len = de->d_name.len; @@ -419,7 +416,7 @@ CHECK_CNODE(dircnp); CDEBUG(D_INODE, " %s in %s, ino %ld\n", name , - coda_f2s(&(dircnp->c_fid), fidstr), dir->i_ino); + coda_f2s(&(dircnp->c_fid)), dir->i_ino); /* this file should no longer be in the namecache! */ @@ -441,7 +438,7 @@ int coda_rmdir(struct inode *dir, struct dentry *de) { - struct cnode *dircnp; + struct coda_inode_info *dircnp; const char *name = de->d_name.name; int len = de->d_name.len; int error, rehash = 0; @@ -499,7 +496,7 @@ int new_length = new_dentry->d_name.len; struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; - struct cnode *new_cnp, *old_cnp; + struct coda_inode_info *new_cnp, *old_cnp; int error, rehash = 0, update = 1; ENTRY; old_cnp = ITOC(old_dir); @@ -559,7 +556,7 @@ int coda_readdir(struct file *file, void *dirent, filldir_t filldir) { int result = 0; - struct cnode *cnp; + struct coda_inode_info *cnp; struct file open_file; struct dentry open_dentry; struct inode *inode=file->f_dentry->d_inode; @@ -599,7 +596,7 @@ { ino_t ino; dev_t dev; - struct cnode *cnp; + struct coda_inode_info *cnp; int error = 0; struct inode *cont_inode = NULL; unsigned short flags = f->f_flags; @@ -653,7 +650,7 @@ int coda_release(struct inode *i, struct file *f) { - struct cnode *cnp; + struct coda_inode_info *cnp; int error; unsigned short flags = f->f_flags; unsigned short cflags = coda_flags_to_cflags(flags); diff -uNr linux-2.1.86.orig/fs/coda/file.c linux/fs/coda/file.c --- linux-2.1.86.orig/fs/coda/file.c Mon Feb 9 19:12:56 1998 +++ linux/fs/coda/file.c Wed Mar 4 14:53:30 1998 @@ -20,7 +20,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_psdev.h> #include <linux/coda_cache.h> @@ -79,7 +79,7 @@ struct inode *inode = de->d_inode; struct dentry cont_dentry; struct inode *cont_inode; - struct cnode *cnp; + struct coda_inode_info *cnp; ENTRY; @@ -103,7 +103,7 @@ static int coda_file_mmap(struct file * file, struct vm_area_struct * vma) { - struct cnode *cnp; + struct coda_inode_info *cnp; cnp = ITOC(file->f_dentry->d_inode); cnp->c_mmcount++; @@ -113,7 +113,7 @@ static ssize_t coda_file_read(struct file *coda_file, char *buff, size_t count, loff_t *ppos) { - struct cnode *cnp; + struct coda_inode_info *cnp; struct inode *coda_inode = coda_file->f_dentry->d_inode; struct inode *cont_inode = NULL; struct file cont_file; @@ -153,7 +153,7 @@ static ssize_t coda_file_write(struct file *coda_file, const char *buff, size_t count, loff_t *ppos) { - struct cnode *cnp; + struct coda_inode_info *cnp; struct inode *coda_inode = coda_file->f_dentry->d_inode; struct inode *cont_inode = NULL; struct file cont_file; @@ -192,7 +192,7 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry) { - struct cnode *cnp; + struct coda_inode_info *cnp; struct inode *coda_inode = coda_dentry->d_inode; struct inode *cont_inode = NULL; struct file cont_file; @@ -254,7 +254,7 @@ { coda_file->f_pos = open_file->f_pos; /* XXX what about setting the mtime here too? */ - coda_inode->i_mtime = open_inode->i_mtime; + /* coda_inode->i_mtime = open_inode->i_mtime; */ coda_inode->i_size = open_inode->i_size; return; } @@ -264,7 +264,7 @@ { struct super_block *sbptr; - sbptr = get_super(to_kdev_t(dev)); + sbptr = get_super(dev); if ( !sbptr ) { printk("coda_inode_grab: coda_find_super returns NULL.\n"); diff -uNr linux-2.1.86.orig/fs/coda/pioctl.c linux/fs/coda/pioctl.c --- linux-2.1.86.orig/fs/coda/pioctl.c Mon Feb 9 19:12:56 1998 +++ linux/fs/coda/pioctl.c Wed Mar 4 14:53:30 1998 @@ -20,7 +20,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_cache.h> #include <linux/coda_psdev.h> @@ -103,7 +103,7 @@ int error; struct PioctlData data; struct inode *target_inode = NULL; - struct cnode *cnp; + struct coda_inode_info *cnp; ENTRY; /* get the Pioctl data arguments from user space */ @@ -115,22 +115,23 @@ * 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); + CDEBUG(D_PIOCTL, "namei, data.follow = %d\n", + data.follow); if ( data.follow ) { target_de = namei(data.path); } else { target_de = lnamei(data.path); } - - if (!target_de) { + + if ( PTR_ERR(target_de) == -ENOENT ) { CDEBUG(D_PIOCTL, "error: lookup fails.\n"); - return -EINVAL; + return PTR_ERR(target_de); } else { target_inode = target_de->d_inode; } - CDEBUG(D_PIOCTL, "target ino: 0x%ld, dev: %s\n", - target_inode->i_ino, kdevname(target_inode->i_dev)); + CDEBUG(D_PIOCTL, "target ino: 0x%ld, dev: 0x%d\n", + target_inode->i_ino, target_inode->i_dev); /* return if it is not a Coda inode */ if ( target_inode->i_sb != inode->i_sb ) { diff -uNr linux-2.1.86.orig/fs/coda/psdev.c linux/fs/coda/psdev.c --- linux-2.1.86.orig/fs/coda/psdev.c Tue Jan 6 13:00:21 1998 +++ linux/fs/coda/psdev.c Wed Mar 4 14:52:02 1998 @@ -40,7 +40,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_psdev.h> #include <linux/coda_cache.h> #include <linux/coda_sysctl.h> @@ -346,7 +346,8 @@ can profit from setting the C_DYING flag on the root cnode of Coda filesystems */ if (coda_super_info[minor].sbi_root) { - struct cnode *cnp = ITOC(coda_super_info[minor].sbi_root); + struct coda_inode_info *cnp = + ITOC(coda_super_info[minor].sbi_root); cnp->c_flags |= C_DYING; } else vcp->vc_inuse = 0; diff -uNr linux-2.1.86.orig/fs/coda/super.c linux/fs/coda/super.c --- linux-2.1.86.orig/fs/coda/super.c Mon Feb 9 19:12:56 1998 +++ linux/fs/coda/super.c Wed Mar 4 17:12:30 1998 @@ -34,7 +34,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> #include <linux/coda_psdev.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_cache.h> @@ -120,7 +120,7 @@ unlock_super(sb); goto error; } - printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid, str)); + printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid)); /* make root inode */ error = coda_cnode_make(&root, &fid, sb); @@ -131,8 +131,8 @@ goto error; } - printk("coda_read_super: rootinode is %ld dev %s\n", - root->i_ino, kdevname(root->i_dev)); + printk("coda_read_super: rootinode is %ld dev %d\n", + root->i_ino, root->i_dev); sbi->sbi_root = root; sb->s_root = d_alloc_root(root, NULL); unlock_super(sb); @@ -152,7 +152,6 @@ } if (root) { iput(root); - coda_cnode_free(ITOC(root)); } sb->s_dev = 0; return NULL; @@ -182,8 +181,10 @@ /* all filling in of inodes postponed until lookup */ static void coda_read_inode(struct inode *inode) { + struct coda_inode_info *cnp; ENTRY; - inode->u.generic_ip = NULL; + cnp = ITOC(inode); + cnp->c_magic = 0; return; } @@ -191,24 +192,28 @@ { ENTRY; - CDEBUG(D_INODE,"ino: %ld, cnp: %p\n", in->i_ino, in->u.generic_ip); + CDEBUG(D_INODE,"ino: %ld, count %d\n", in->i_ino, in->i_count); + + if ( in->i_count == 1 ) + in->i_nlink = 0; + } static void coda_delete_inode(struct inode *inode) { - struct cnode *cnp; + struct coda_inode_info *cnp; struct inode *open_inode; ENTRY; CDEBUG(D_SUPER, " inode->ino: %ld, count: %d\n", inode->i_ino, inode->i_count); - if ( inode->i_ino == CTL_INO ) { + cnp = ITOC(inode); + if ( inode->i_ino == CTL_INO || cnp->c_magic != CODA_CNODE_MAGIC ) { clear_inode(inode); return; } - cnp = ITOC(inode); if ( coda_fid_is_volroot(&cnp->c_fid) ) list_del(&cnp->c_volrootlist); @@ -224,7 +229,6 @@ coda_cache_clear_cnp(cnp); inode->u.generic_ip = NULL; - coda_cnode_free(cnp); clear_inode(inode); EXIT; } @@ -232,7 +236,7 @@ static int coda_notify_change(struct dentry *de, struct iattr *iattr) { struct inode *inode = de->d_inode; - struct cnode *cnp; + struct coda_inode_info *cnp; struct coda_vattr vattr; int error; @@ -351,7 +355,7 @@ if (MINOR(psdev->i_rdev) >= MAX_CODADEVS) { printk("minor %d not an allocated Coda PSDEV\n", - MINOR(psdev->i_rdev)); + psdev->i_rdev); return 1; } diff -uNr linux-2.1.86.orig/fs/coda/symlink.c linux/fs/coda/symlink.c --- linux-2.1.86.orig/fs/coda/symlink.c Mon Feb 9 19:12:56 1998 +++ linux/fs/coda/symlink.c Wed Mar 4 14:53:29 1998 @@ -21,7 +21,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> #include <linux/coda_psdev.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_cache.h> static int coda_readlink(struct dentry *de, char *buffer, int length); @@ -39,41 +39,41 @@ NULL, /* mknod */ NULL, /* rename */ coda_readlink, /* readlink */ - coda_follow_link, /* follow_link */ + coda_follow_link, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL, /* update page */ - NULL /* revalidate */ + NULL, /* permission */ + NULL, /* smap */ + NULL, /* update page */ + NULL /* revalidate */ }; static int coda_readlink(struct dentry *de, char *buffer, int length) { struct inode *inode = de->d_inode; - int len; + int len; int error; - char *buf; - struct cnode *cp; - ENTRY; - - cp = ITOC(inode); - CHECK_CNODE(cp); - - /* the maximum length we receive is len */ - if ( length > CFS_MAXPATHLEN ) - len = CFS_MAXPATHLEN; + char *buf; + struct coda_inode_info *cp; + ENTRY; + + cp = ITOC(inode); + CHECK_CNODE(cp); + + /* the maximum length we receive is len */ + if ( length > CFS_MAXPATHLEN ) + len = CFS_MAXPATHLEN; else - len = length; + len = length; CODA_ALLOC(buf, char *, len); if ( !buf ) - return -ENOMEM; + return -ENOMEM; error = venus_readlink(inode->i_sb, &(cp->c_fid), buf, &len); - CDEBUG(D_INODE, "result %s\n", buf); + CDEBUG(D_INODE, "result %s\n", buf); if (! error) { copy_to_user(buffer, buf, len); put_user('\0', buffer + len); @@ -89,15 +89,15 @@ { struct inode *inode = de->d_inode; int error; - struct cnode *cnp; + struct coda_inode_info *cnp; unsigned int len; char mem[CFS_MAXPATHLEN]; char *path; ENTRY; - CDEBUG(D_INODE, "(%s/%ld)\n", kdevname(inode->i_dev), inode->i_ino); + CDEBUG(D_INODE, "(%x/%ld)\n", inode->i_dev, inode->i_ino); - cnp = ITOC(inode); - CHECK_CNODE(cnp); + cnp = ITOC(inode); + CHECK_CNODE(cnp); len = CFS_MAXPATHLEN; error = venus_readlink(inode->i_sb, &(cnp->c_fid), mem, &len); diff -uNr linux-2.1.86.orig/fs/coda/sysctl.c linux/fs/coda/sysctl.c --- linux-2.1.86.orig/fs/coda/sysctl.c Sun Dec 21 17:45:14 1997 +++ linux/fs/coda/sysctl.c Wed Mar 4 14:42:30 1998 @@ -24,7 +24,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_psdev.h> #include <linux/coda_cache.h> #include <linux/coda_sysctl.h> diff -uNr linux-2.1.86.orig/fs/coda/upcall.c linux/fs/coda/upcall.c --- linux-2.1.86.orig/fs/coda/upcall.c Sun Dec 21 17:45:14 1997 +++ linux/fs/coda/upcall.c Wed Mar 4 16:51:37 1998 @@ -16,7 +16,8 @@ #include <asm/system.h> #include <asm/segment.h> - +#include <asm/signal.h> +#include <linux/signal.h> #include <linux/types.h> #include <linux/kernel.h> @@ -34,7 +35,7 @@ #include <linux/coda.h> #include <linux/coda_linux.h> #include <linux/coda_psdev.h> -#include <linux/coda_cnode.h> +#include <linux/coda_fs_i.h> #include <linux/coda_cache.h> #define UPARG(op)\ @@ -538,7 +539,7 @@ if (error) { printk("coda_pioctl: Venus returns: %d for %s\n", - error, coda_f2s(fid, str)); + error, coda_f2s(fid)); goto exit; } @@ -586,6 +587,7 @@ static inline void coda_waitfor_upcall(struct vmsg *vmp) { struct wait_queue wait = { current, NULL }; + old_sigset_t pending; vmp->vm_posttime = jiffies; @@ -596,12 +598,26 @@ else current->state = TASK_UNINTERRUPTIBLE; + /* got a reply */ if ( vmp->vm_flags & VM_WRITE ) break; - if (signal_pending(current) && - (jiffies > vmp->vm_posttime + coda_timeout * HZ) ) + + if ( ! signal_pending(current) ) + schedule(); + /* signal is present: after timeout always return */ + if ( jiffies > vmp->vm_posttime + coda_timeout * HZ ) + break; + + spin_lock_irq(¤t->sigmask_lock); + pending = current->blocked.sig[0] & current->signal.sig[0]; + spin_unlock_irq(¤t->sigmask_lock); + + /* if this process really wants to die, let it go */ + if ( sigismember(&pending, SIGKILL) || + sigismember(&pending, SIGINT) ) break; - schedule(); + else + schedule(); } remove_wait_queue(&vmp->vm_sleep, &wait); current->state = TASK_RUNNING; @@ -793,7 +809,7 @@ printk("ZAPDIR: Null fid\n"); return 0; } - CDEBUG(D_DOWNCALL, "zapdir: fid = %s\n", coda_f2s(fid, str)); + CDEBUG(D_DOWNCALL, "zapdir: fid = %s\n", coda_f2s(fid)); clstats(CFS_ZAPDIR); coda_zapfid(fid, sb, C_ZAPDIR); return(0); @@ -806,7 +822,7 @@ printk("ZAPVNODE: Null fid or cred\n"); return 0; } - CDEBUG(D_DOWNCALL, "zapvnode: fid = %s\n", coda_f2s(fid, str)); + CDEBUG(D_DOWNCALL, "zapvnode: fid = %s\n", coda_f2s(fid)); coda_zapfid(fid, sb, C_ZAPFID); coda_cache_clear_cred(sb, cred); clstats(CFS_ZAPVNODE); @@ -820,7 +836,7 @@ printk("ZAPFILE: Null fid\n"); return 0; } - CDEBUG(D_DOWNCALL, "zapfile: fid = %s\n", coda_f2s(fid, str)); + CDEBUG(D_DOWNCALL, "zapfile: fid = %s\n", coda_f2s(fid)); coda_zapfid(fid, sb, C_ZAPFID); return 0; } @@ -831,7 +847,7 @@ printk("PURGEFID: Null fid\n"); return 0; } - CDEBUG(D_DOWNCALL, "purgefid: fid = %s\n", coda_f2s(fid, str)); + CDEBUG(D_DOWNCALL, "purgefid: fid = %s\n", coda_f2s(fid)); clstats(CFS_PURGEFID); coda_zapfid(fid, sb, C_ZAPDIR); return 0; diff -uNr linux-2.1.86.orig/include/linux/coda.h linux/include/linux/coda.h --- linux-2.1.86.orig/include/linux/coda.h Tue Jan 6 13:00:22 1998 +++ linux/include/linux/coda.h Wed Feb 25 08:46:34 1998 @@ -15,16 +15,48 @@ #include <sys/types.h> #endif -#ifdef __linux__ +#ifdef DJGPP +#ifdef KERNEL +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef u_long ino_t; +typedef u_long dev_t; +typedef void * caddr_t; +typedef u_long u_quad_t; + +#define inline + +struct timespec { + long ts_sec; + long ts_nsec; +}; +#else /* DJGPP but not KERNEL */ +#include <sys/types.h> +#include <sys/time.h> +typedef u_long u_quad_t; +#endif /* !KERNEL */ +#endif /* !DJGPP */ + + +#if defined(__linux__) || defined(__CYGWIN32__) #define cdev_t u_quad_t #if !defined(_UQUAD_T_) && (!defined(__GLIBC__) || __GLIBC__ < 2) #define _UQUAD_T_ 1 typedef unsigned long long u_quad_t; -#endif +#endif #else #define cdev_t dev_t #endif +#ifdef __CYGWIN32__ +typedef unsigned char u_int8_t; +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + /* * Cfs constants @@ -69,21 +101,21 @@ /* * File types */ -#define DT_UNKNOWN 0 -#define DT_FIFO 1 -#define DT_CHR 2 -#define DT_DIR 4 -#define DT_BLK 6 -#define DT_REG 8 -#define DT_LNK 10 -#define DT_SOCK 12 -#define DT_WHT 14 +#define CDT_UNKNOWN 0 +#define CDT_FIFO 1 +#define CDT_CHR 2 +#define CDT_DIR 4 +#define CDT_BLK 6 +#define CDT_REG 8 +#define CDT_LNK 10 +#define CDT_SOCK 12 +#define CDT_WHT 14 /* * Convert between stat structure types and directory types. */ -#define IFTODT(mode) (((mode) & 0170000) >> 12) -#define DTTOIF(dirtype) ((dirtype) << 12) +#define IFTOCDT(mode) (((mode) & 0170000) >> 12) +#define CDTTOIF(dirtype) ((dirtype) << 12) #endif @@ -124,7 +156,11 @@ #define _CODACRED_T_ struct coda_cred { vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/ - vgid_t cr_gid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */ +#if defined(__NetBSD__) || defined(__FreeBSD__) + vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */ +#else + vgid_t cr_gid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */ +#endif }; #endif @@ -189,7 +225,8 @@ #define CFS_ZAPDIR ((u_long) 28) #define CFS_ZAPVNODE ((u_long) 29) #define CFS_PURGEFID ((u_long) 30) -#define CFS_NCALLS 31 +#define CFS_OPEN_BY_PATH ((u_long) 31) +#define CFS_NCALLS 32 #define DOWNCALL(opcode) (opcode >= CFS_REPLACE && opcode <= CFS_PURGEFID) @@ -537,6 +574,18 @@ ViceFid OldFid; }; +/* cfs_open_by_path: */ +struct cfs_open_by_path_in { + struct cfs_in_hdr ih; + ViceFid VFid; + int flags; +}; + +struct cfs_open_by_path_out { + struct cfs_out_hdr oh; + int path; +}; + /* * Occasionally, don't cache the fid returned by CFS_LOOKUP. For instance, if * the fid is inconsistent. This case is handled by setting the top bit of the @@ -566,6 +615,7 @@ struct cfs_inactive_in cfs_inactive; struct cfs_vget_in cfs_vget; struct cfs_rdwr_in cfs_rdwr; + struct cfs_open_by_path_in cfs_open_by_path; }; union outputArgs { @@ -587,6 +637,7 @@ struct cfs_purgefid_out cfs_purgefid; struct cfs_rdwr_out cfs_rdwr; struct cfs_replace_out cfs_replace; + struct cfs_open_by_path_out cfs_open_by_path; }; union cfs_downcalls { diff -uNr linux-2.1.86.orig/include/linux/coda_cache.h linux/include/linux/coda_cache.h --- linux-2.1.86.orig/include/linux/coda_cache.h Mon Dec 22 11:40:59 1997 +++ linux/include/linux/coda_cache.h Wed Mar 4 14:45:20 1998 @@ -22,13 +22,13 @@ }; void coda_ccinsert(struct coda_cache *el, struct super_block *sb); -void coda_cninsert(struct coda_cache *el, struct cnode *cnp); +void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cnp); void coda_ccremove(struct coda_cache *el); void coda_cnremove(struct coda_cache *el); void coda_cache_create(struct inode *inode, int mask); struct coda_cache *coda_cache_find(struct inode *inode); void coda_cache_enter(struct inode *inode, int mask); -void coda_cache_clear_cnp(struct cnode *cnp); +void coda_cache_clear_cnp(struct coda_inode_info *cnp); void coda_cache_clear_all(struct super_block *sb); void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred); int coda_cache_check(struct inode *inode, int mask); diff -uNr linux-2.1.86.orig/include/linux/coda_fs_i.h linux/include/linux/coda_fs_i.h --- linux-2.1.86.orig/include/linux/coda_fs_i.h Wed Dec 31 19:00:00 1969 +++ linux/include/linux/coda_fs_i.h Wed Mar 4 17:00:46 1998 @@ -0,0 +1,52 @@ +/* + * coda_fs_i.h + * + * Copyright (C) 1998 Carnegie Mellon University + * + */ + +#ifndef _LINUX_CODA_FS_I +#define _LINUX_CODA_FS_I + +#ifdef __KERNEL__ +#include <linux/types.h> +#include <linux/list.h> +#include <linux/coda.h> + + + +#define CODA_CNODE_MAGIC 0x47114711 +/* + * smb fs inode data (in memory only) + */ +struct coda_inode_info { + struct ViceFid c_fid; /* Coda identifier */ + u_short c_flags; /* flags (see below) */ + u_short c_ocount; /* count of openers */ + u_short c_owrite; /* count of open for write */ + u_short c_mmcount; /* count of mmappers */ + struct inode *c_ovp; /* open inode pointer */ + struct list_head c_cnhead; /* head of cache entries */ + struct list_head c_volrootlist; /* list of volroot cnoddes */ + struct inode *c_vnode; /* inode associated with cnode */ + int c_magic; /* to verify the data structure */ +}; + +/* flags */ +#define C_VATTR 0x1 /* Validity of vattr in the cnode */ +#define C_SYMLINK 0x2 /* Validity of symlink pointer in the cnode */ +#define C_DYING 0x4 /* Set for outstanding cnodes from venus (which died) */ +#define C_ZAPFID 0x8 +#define C_ZAPDIR 0x10 +#define C_INITED 0x20 + +int coda_cnode_make(struct inode **, struct ViceFid *, struct super_block *); +int coda_cnode_makectl(struct inode **inode, struct super_block *sb); +struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb); + +/* inode to cnode */ +#define ITOC(inode) ((struct coda_inode_info *)&((inode)->u.coda_i)) + + +#endif +#endif diff -uNr linux-2.1.86.orig/include/linux/coda_linux.h linux/include/linux/coda_linux.h --- linux-2.1.86.orig/include/linux/coda_linux.h Tue Jan 6 13:00:22 1998 +++ linux/include/linux/coda_linux.h Wed Mar 4 16:52:41 1998 @@ -43,7 +43,7 @@ extern int coda_access_cache; /* this file: heloers */ -char *coda_f2s(ViceFid *f, char *s); +char *coda_f2s(ViceFid *f); int coda_isroot(struct inode *i); int coda_fid_is_volroot(struct ViceFid *); int coda_iscontrol(const char *name, size_t length); @@ -93,22 +93,7 @@ #define EXIT \ if(coda_print_entry) printk("Process %d leaving %s\n",current->pid,__FUNCTION__) - - -#define CHECK_CNODE(c) \ -do { \ - if ( coda_debug ) {\ - struct cnode *cnode = (c); \ - if (!cnode) \ - printk ("%s(%d): cnode is null\n", __FUNCTION__, __LINE__); \ - if (cnode->c_magic != CODA_CNODE_MAGIC) \ - printk ("%s(%d): cnode magic wrong\n", __FUNCTION__, __LINE__); \ - if (!cnode->c_vnode) \ - printk ("%s(%d): cnode has null inode\n", __FUNCTION__, __LINE__); \ - if ( (struct cnode *)cnode->c_vnode->u.generic_ip != cnode ) \ - printk("AAooh, %s(%d) cnode doesn't link right!\n", __FUNCTION__,__LINE__);\ -}} while (0); - +#define CHECK_CNODE(c) do { } while (0); #define CODA_ALLOC(ptr, cast, size) \ do { \ diff -uNr linux-2.1.86.orig/include/linux/fs.h linux/include/linux/fs.h --- linux-2.1.86.orig/include/linux/fs.h Tue Feb 10 16:32:24 1998 +++ linux/include/linux/fs.h Wed Feb 25 13:24:51 1998 @@ -264,6 +264,7 @@ #include <linux/sysv_fs_i.h> #include <linux/affs_fs_i.h> #include <linux/ufs_fs_i.h> +#include <linux/coda_fs_i.h> #include <linux/romfs_fs_i.h> #include <linux/smb_fs_i.h> #include <linux/hfs_fs_i.h> @@ -369,6 +370,7 @@ struct affs_inode_info affs_i; struct ufs_inode_info ufs_i; struct romfs_inode_info romfs_i; + struct coda_inode_info coda_i; struct smb_inode_info smbfs_i; struct hfs_inode_info hfs_i; struct adfs_inode_info adfs_i;Received on 1998-03-06 10:49:13