(Illustration by Gaich Muramatsu)
I goofed up; here are the patches. Peter --- linux/fs/coda/cache.c.orig Mon May 4 20:09:22 1998 +++ linux/fs/coda/cache.c Tue May 26 20:12:36 1998 @@ -267,8 +267,7 @@ while ( alias != &inode->i_dentry ) { alias_de = list_entry(alias, struct dentry, d_alias); if ( !alias_de ) { - printk("Corrupt alias list for %*s\n", - alias_de->d_name.len, alias_de->d_name.name); + printk("Null alias list for inode %ld\n", inode->i_ino); return; } coda_flag_children(alias_de, flag); --- linux/fs/coda/cnode.c.orig Wed Mar 18 00:19:05 1998 +++ linux/fs/coda/cnode.c Tue May 26 20:12:36 1998 @@ -15,7 +15,7 @@ /* cnode.c */ -static void coda_fill_inode (struct inode *inode, struct coda_vattr *attr) +static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr) { CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino); @@ -54,8 +54,8 @@ ENTRY; /* - * We get inode numbers from Venus -- see venus source - */ + * We get inode numbers from Venus -- see venus source + */ error = venus_getattr(sb, fid, &attr); if ( error ) { @@ -82,16 +82,26 @@ INIT_LIST_HEAD(&(cnp->c_cnhead)); INIT_LIST_HEAD(&(cnp->c_volrootlist)); } else { - printk("coda_cnode make on initialized inode %ld, %s!\n", + cnp->c_flags = 0; + CDEBUG(D_CNODE, "coda_cnode make on initialized" + "inode %ld, %s!\n", (*inode)->i_ino, coda_f2s(&cnp->c_fid)); } /* fill in the inode attributes */ - if ( coda_fid_is_volroot(fid) ) + if ( coda_f2i(fid) != ino ) { + if ( !coda_fid_is_weird(fid) ) + printk("Coda: unknown weird fid: ino %ld, fid %s." + "Tell Peter.", ino, coda_f2s(&cnp->c_fid)); list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead); + CDEBUG(D_CNODE, "Added %ld ,%s to volroothead\n", + ino, coda_f2s(&cnp->c_fid)); + } coda_fill_inode(*inode, &attr); - CDEBUG(D_CNODE, "Done linking: ino %ld, at 0x%x with cnp 0x%x, cnp->c_vnode 0x%x\n", (*inode)->i_ino, (int) (*inode), (int) cnp, (int)cnp->c_vnode); + CDEBUG(D_CNODE, "Done linking: ino %ld, at 0x%x with cnp 0x%x," + "cnp->c_vnode 0x%x\n", (*inode)->i_ino, (int) (*inode), + (int) cnp, (int)cnp->c_vnode); EXIT; return 0; @@ -132,7 +142,7 @@ } - if ( coda_fid_is_volroot(fid) ) { + if ( coda_fid_is_weird(fid) ) { struct coda_inode_info *cii; struct list_head *lh, *le; struct coda_sb_info *sbi = coda_sbp(sb); @@ -141,7 +151,7 @@ while ( (le = le->next) != lh ) { cii = list_entry(le, struct coda_inode_info, c_volrootlist); - if ( cii->c_fid.Volume == fid->Volume) { + if ( coda_fideq(&cii->c_fid, fid) ) { inode = cii->c_vnode; CDEBUG(D_INODE, "volume root, found %ld\n", cii->c_vnode->i_ino); return cii->c_vnode; @@ -151,7 +161,7 @@ return NULL; } - /* fid is not volume root, hence ino is computable */ + /* fid is not weird: ino should be computable */ nr = coda_f2i(fid); inode = iget(sb, nr); if ( !inode ) { @@ -173,9 +183,9 @@ These have the same inode as the root of the volume they mount, but the fid will be wrong. */ - if ( !coda_fideq(fid, &(cnp->c_fid)) && - !coda_fid_is_volroot(&(cnp->c_fid))) { - printk("coda_fid2inode: bad cnode! Tell Peter.\n"); + if ( !coda_fideq(fid, &(cnp->c_fid)) ) { + printk("coda_fid2inode: bad cnode (ino %ld, fid %s)" + "Tell Peter.\n", nr, coda_f2s(fid)); iput(inode); return NULL; } --- linux/fs/coda/coda_linux.c.orig Mon May 4 20:09:22 1998 +++ linux/fs/coda/coda_linux.c Tue May 26 20:12:36 1998 @@ -65,6 +65,36 @@ { return ( (fid->Vnode == 1) && (fid->Unique == 1 ) ); } + +int coda_fid_is_weird(struct ViceFid *fid) +{ + /* volume roots */ + if ( (fid->Vnode == 1) && (fid->Unique == 1 ) ) + return 1; + /* tmpfid unique (simulate.cc) */ + if ( fid->Unique == 0xffffffff ) + return 1; + /* LocalFakeVnode (local.h) */ + if ( fid->Vnode == 0xfffffffd ) + return 1; + /* LocalFileVnode (venus.private.h) */ + if ( fid->Vnode == 0xfffffffe ) + return 1; + /* local fake vid (local.h) */ + if ( fid->Volume == 0xffffffff ) + return 1; + /* local DirVnode (venus.private.h) */ + if ( fid->Vnode == 0xffffffff ) + return 1; + /* FakeVnode (venus.private.h) */ + if ( fid->Vnode == 0xfffffffc ) + return 1; + + return 0; + +} + + /* put the current process credentials in the cred */ void coda_load_creds(struct coda_cred *cred) @@ -94,14 +124,26 @@ { unsigned short coda_flags = 0; - if ( flags & (O_RDONLY | O_RDWR) ) + if ( (flags & 0xf) == O_RDONLY ) + coda_flags |= C_O_READ; + + if ( flags & O_RDWR ) coda_flags |= C_O_READ; - if ( flags & (O_WRONLY | O_RDWR) ) + if ( flags & (O_WRONLY | O_RDWR) ){ + CDEBUG(D_FILE, "--> C_O_WRITE added\n"); coda_flags |= C_O_WRITE; + } - if ( flags & O_TRUNC ) + if ( flags & O_TRUNC ) { + CDEBUG(D_FILE, "--> C_O_TRUNC added\n"); coda_flags |= C_O_TRUNC; + } + + if ( flags & O_EXCL ) { + coda_flags |= C_O_EXCL; + CDEBUG(D_FILE, "--> C_O_EXCL added\n"); + } return coda_flags; } --- linux/fs/coda/dir.c.orig Mon May 4 20:09:22 1998 +++ linux/fs/coda/dir.c Tue May 26 20:12:36 1998 @@ -167,8 +167,10 @@ entry->d_time = 0; entry->d_op = &coda_dentry_operations; d_add(entry, res_inode); - if ( dropme ) + if ( dropme ) { d_drop(entry); + ITOC(res_inode)->c_flags |= C_VATTR; + } EXIT; return 0; } @@ -264,7 +266,7 @@ } /* invalidate the directory cnode's attributes */ - dircnp->c_flags &= ~C_VATTR; + dircnp->c_flags |= C_VATTR; d_instantiate(de, result); return 0; } @@ -320,7 +322,7 @@ } /* invalidate the directory cnode's attributes */ - dircnp->c_flags &= ~C_VATTR; + dircnp->c_flags |= C_VATTR; dir->i_nlink++; d_instantiate(de, inode); return 0; @@ -359,7 +361,7 @@ (const char *)name, len); if ( ! error ) { - dir_cnp->c_flags &= ~C_VATTR; + dir_cnp->c_flags |= C_VATTR; inode->i_nlink++; d_instantiate(de, inode); } else { @@ -442,7 +444,7 @@ } /* cache management */ - dircnp->c_flags &= ~C_VATTR; + dircnp->c_flags |= C_VATTR; de->d_inode->i_nlink--; d_delete(de); @@ -618,7 +620,7 @@ struct coda_inode_info *cnp; int error = 0; struct inode *cont_inode = NULL; - unsigned short flags = f->f_flags; + unsigned short flags = f->f_flags & (~O_EXCL); unsigned short coda_flags = coda_flags_to_cflags(flags); ENTRY; @@ -672,7 +674,7 @@ { struct coda_inode_info *cnp; int error; - unsigned short flags = f->f_flags; + unsigned short flags = (f->f_flags) & (~O_EXCL); unsigned short cflags = coda_flags_to_cflags(flags); ENTRY; @@ -814,7 +816,7 @@ if (is_bad_inode(inode)) return 0; cii = ITOC(de->d_inode); - if (cii->c_flags & C_PURGE) + if (cii->c_flags & (C_PURGE | C_VATTR)) valid = 0; } return valid || coda_isroot(de->d_inode); @@ -838,7 +840,7 @@ } /* this baby may be lost if: - - it's type changed + - it's type changed - it's ino changed */ old_mode = inode->i_mode; @@ -852,7 +854,7 @@ return -EIO; } - cii->c_flags &= ~C_VATTR; + cii->c_flags &= ~(C_VATTR | C_PURGE); return 0; } --- linux/fs/coda/file.c.orig Mon May 4 20:09:22 1998 +++ linux/fs/coda/file.c Tue May 26 20:12:36 1998 @@ -192,13 +192,14 @@ return -1; } - cnp->c_flags &= ~C_VATTR; - down(&cont_inode->i_sem); result = cont_file.f_op->write(&cont_file , buff, count, &(cont_file.f_pos)); up(&cont_inode->i_sem); coda_restore_codafile(coda_inode, coda_file, cont_inode, &cont_file); + + if (result) + cnp->c_flags |= C_VATTR; return result; } --- linux/fs/coda/inode.c.orig Sat Apr 4 12:45:14 1998 +++ linux/fs/coda/inode.c Tue May 26 20:12:36 1998 @@ -161,6 +161,8 @@ ENTRY; + + sb->s_dev = 0; coda_cache_clear_all(sb); sb_info = coda_sbp(sb); sb_info->sbi_vcomm->vc_inuse = 0; --- linux/fs/coda/psdev.c.orig Tue May 26 20:08:18 1998 +++ linux/fs/coda/psdev.c Tue May 26 20:12:36 1998 @@ -401,10 +401,18 @@ #ifdef CONFIG_PROC_FS -extern struct proc_dir_entry proc_sys_root; +struct proc_dir_entry proc_sys_root = { + PROC_SYS, 3, "sys", /* inode, name */ + S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, /* mode, nlink, uid, gid */ + 0, &proc_dir_inode_operations, /* size, ops */ + NULL, NULL, /* get_info, fill_inode */ + NULL, /* next */ + NULL, NULL /* parent, subdir */ +}; -struct proc_dir_entry proc_fs_coda = { - PROC_FS_CODA, 4, "coda", + +struct proc_dir_entry proc_sys_coda = { + 0, 4, "coda", S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, 0, &proc_dir_inode_operations, NULL, NULL, @@ -412,8 +420,8 @@ NULL, NULL }; -struct proc_dir_entry proc_sys_coda = { - 0, 4, "coda", +struct proc_dir_entry proc_fs = { + PROC_FS, 2, "fs", S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, 0, &proc_dir_inode_operations, NULL, NULL, @@ -421,8 +429,17 @@ NULL, NULL }; -struct proc_dir_entry proc_fs = { - PROC_FS, 2, "fs", +/* + * target directory structure: + /proc/fs/ + /proc/fs/coda + /proc/fs/coda/{vfs_stats, + +*/ + + +struct proc_dir_entry proc_fs_coda = { + PROC_FS_CODA, 4, "coda", S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, 0, &proc_dir_inode_operations, NULL, NULL, @@ -430,15 +447,6 @@ NULL, NULL }; -#if 0 -struct proc_dir_entry proc_coda_ncstats = { - 0 , 12, "coda-ncstats", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - cfsnc_nc_info - }; -#endif - struct proc_dir_entry proc_coda_vfs = { PROC_VFS_STATS , 9, "vfs_stats", S_IFREG | S_IRUGO, 1, 0, 0, @@ -521,9 +529,7 @@ proc_register(&proc_fs_coda,&proc_coda_upcall); proc_register(&proc_fs_coda,&proc_coda_permission); proc_register(&proc_fs_coda,&proc_coda_cache_inv); -#if 0 - proc_register(&proc_fs_coda, &proc_coda_ncstats); -#endif + proc_register(&proc_sys_root,&proc_sys_coda); proc_register(&proc_sys_coda,&proc_coda_vfs_control); proc_register(&proc_sys_coda,&proc_coda_upcall_control); @@ -578,12 +584,9 @@ proc_unregister(&proc_sys_coda, proc_coda_cache_inv_control.low_ino); proc_unregister(&proc_sys_coda, proc_coda_permission_control.low_ino); proc_unregister(&proc_sys_coda, proc_coda_upcall_control.low_ino); - proc_unregister(&proc_sys_coda,proc_coda_vfs_control.low_ino); + proc_unregister(&proc_sys_coda, proc_coda_vfs_control.low_ino); proc_unregister(&proc_sys_root, proc_sys_coda.low_ino); -#if 0 - proc_unregister(&proc_fs_coda, proc_coda_ncstats.low_ino); -#endif proc_unregister(&proc_fs_coda, proc_coda_cache_inv.low_ino); proc_unregister(&proc_fs_coda, proc_coda_permission.low_ino); proc_unregister(&proc_fs_coda, proc_coda_upcall.low_ino); --- linux/fs/coda/stats.c.orig Tue May 5 13:52:17 1998 +++ linux/fs/coda/stats.c Tue May 26 20:12:36 1998 @@ -7,6 +7,7 @@ * */ +#include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/sysctl.h> --- linux/fs/coda/upcall.c.orig Mon May 4 20:09:22 1998 +++ linux/fs/coda/upcall.c Tue May 26 20:12:36 1998 @@ -777,8 +777,6 @@ * force a new lookup for all the children of this dir. - * CFS_ZAPVNODE -- intended to be a zapfile for just one cred. - Not used? * * The next is a result of Venus detecting an inconsistent file. * CFS_PURGEFID -- flush the attribute for the file @@ -792,81 +790,85 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb) { - /* Handle invalidate requests. */ - switch (opcode) { - case CFS_FLUSH : { - clstats(CFS_FLUSH); - CDEBUG(D_DOWNCALL, "CFS_FLUSH\n"); - coda_cache_clear_all(sb); - shrink_dcache_sb(sb); - return(0); - } - case CFS_PURGEUSER : { - struct coda_cred *cred = &out->cfs_purgeuser.cred; - CDEBUG(D_DOWNCALL, "CFS_PURGEUSER\n"); - if ( !cred ) { - printk("PURGEUSER: null cred!\n"); - return 0; - } - clstats(CFS_PURGEUSER); - coda_cache_clear_cred(sb, cred); - return(0); - } - case CFS_ZAPDIR : { - struct inode *inode; - ViceFid *fid = &out->cfs_zapdir.CodaFid; - if ( !fid ) { - printk("ZAPDIR: Null fid\n"); - return 0; - } - CDEBUG(D_DOWNCALL, "zapdir: fid = %s\n", coda_f2s(fid)); - clstats(CFS_ZAPDIR); - inode = coda_fid_to_inode(fid, sb); - coda_flag_inode(inode, C_VATTR); - coda_cache_clear_inode(inode); - coda_flag_alias_children(inode, C_PURGE); - return(0); - } - - case CFS_ZAPVNODE : - case CFS_ZAPFILE : { - struct inode *inode; - struct ViceFid *fid = &out->cfs_zapfile.CodaFid; - clstats(CFS_ZAPFILE); - if ( !fid ) { - printk("ZAPFILE: Null fid\n"); - return 0; - } - CDEBUG(D_DOWNCALL, "zapfile: fid = %s\n", coda_f2s(fid)); - inode = coda_fid_to_inode(fid, sb); - coda_flag_inode(inode, C_VATTR); - coda_cache_clear_inode(inode); - return 0; - } - case CFS_PURGEFID : { - struct inode *inode; - ViceFid *fid = &out->cfs_purgefid.CodaFid; - if ( !fid ) { - printk("PURGEFID: Null fid\n"); - return 0; - } - CDEBUG(D_DOWNCALL, "purgefid: fid = %s\n", coda_f2s(fid)); - clstats(CFS_PURGEFID); - inode = coda_fid_to_inode(fid, sb); - coda_flag_inode(inode, C_PURGE); - coda_cache_clear_inode(inode); - return 0; - } - case CFS_REPLACE : { - printk("CFS_REPLACCE\n"); - clstats(CFS_REPLACE); - CDEBUG(D_DOWNCALL, "CFS_REPLACE\n"); - coda_cache_clear_all(sb); - shrink_dcache_sb(sb); - return (0); - } - } - return 0; + /* Handle invalidation requests. */ + if ( !sb ) { + printk("coda_downcall: opcode %d, no sb!\n", opcode); + return 0; + } + + switch (opcode) { + + case CFS_FLUSH : { + clstats(CFS_FLUSH); + CDEBUG(D_DOWNCALL, "CFS_FLUSH\n"); + coda_cache_clear_all(sb); + shrink_dcache_sb(sb); + return(0); + } + + case CFS_PURGEUSER : { + struct coda_cred *cred = &out->cfs_purgeuser.cred; + CDEBUG(D_DOWNCALL, "CFS_PURGEUSER\n"); + if ( !cred ) { + printk("PURGEUSER: null cred!\n"); + return 0; + } + clstats(CFS_PURGEUSER); + coda_cache_clear_cred(sb, cred); + return(0); + } + + case CFS_ZAPDIR : { + struct inode *inode; + ViceFid *fid = &out->cfs_zapdir.CodaFid; + CDEBUG(D_DOWNCALL, "zapdir: fid = %s\n", coda_f2s(fid)); + clstats(CFS_ZAPDIR); + + inode = coda_fid_to_inode(fid, sb); + if ( inode ) { + coda_flag_inode(inode, C_VATTR); + coda_cache_clear_inode(inode); + coda_flag_alias_children(inode, C_PURGE); + } + return(0); + } + + case CFS_ZAPFILE : { + struct inode *inode; + struct ViceFid *fid = &out->cfs_zapfile.CodaFid; + clstats(CFS_ZAPFILE); + CDEBUG(D_DOWNCALL, "zapfile: fid = %s\n", coda_f2s(fid)); + inode = coda_fid_to_inode(fid, sb); + if ( inode ) { + coda_flag_inode(inode, C_VATTR); + coda_cache_clear_inode(inode); + } + return 0; + } + + case CFS_PURGEFID : { + struct inode *inode; + ViceFid *fid = &out->cfs_purgefid.CodaFid; + CDEBUG(D_DOWNCALL, "purgefid: fid = %s\n", coda_f2s(fid)); + clstats(CFS_PURGEFID); + inode = coda_fid_to_inode(fid, sb); + if ( inode ) { + coda_flag_inode(inode, C_PURGE); + coda_cache_clear_inode(inode); + } + return 0; + } + + case CFS_REPLACE : { + printk("CFS_REPLACCE\n"); + clstats(CFS_REPLACE); + CDEBUG(D_DOWNCALL, "CFS_REPLACE\n"); + coda_cache_clear_all(sb); + shrink_dcache_sb(sb); + return (0); + } + } + return 0; } --- linux/include/linux/coda.h.orig Wed Mar 18 00:19:05 1998 +++ linux/include/linux/coda.h Tue May 26 20:12:36 1998 @@ -148,8 +148,8 @@ #ifndef _VUID_T_ #define _VUID_T_ -typedef u_long vuid_t; -typedef u_long vgid_t; +typedef unsigned int vuid_t; +typedef unsigned int vgid_t; #endif /*_VUID_T_ */ #ifndef _CODACRED_T_ @@ -223,7 +223,7 @@ #define CFS_PURGEUSER ((u_long) 26) #define CFS_ZAPFILE ((u_long) 27) #define CFS_ZAPDIR ((u_long) 28) -#define CFS_ZAPVNODE ((u_long) 29) +/* #define CFS_ZAPVNODE ((u_long) 29) obsolete */ #define CFS_PURGEFID ((u_long) 30) #define CFS_OPEN_BY_PATH ((u_long) 31) #define CFS_NCALLS 32 --- linux/include/linux/coda_linux.h.orig Wed Mar 18 00:19:05 1998 +++ linux/include/linux/coda_linux.h Tue May 26 20:12:36 1998 @@ -48,6 +48,7 @@ char *coda_f2s(ViceFid *f); int coda_isroot(struct inode *i); int coda_fid_is_volroot(struct ViceFid *); +int coda_fid_is_weird(struct ViceFid *fid); int coda_iscontrol(const char *name, size_t length);Received on 1998-05-26 23:51:44