Messages in this thread Patch in this message | | | Date | Tue, 6 Jan 1998 12:56:01 -0500 (EST) | From | "Peter J. Braam" <> | Subject | [PATCH] Coda |
| |
Hi Linus,
1. please rm fs/coda/inode.c
2. find enclosed some patches -- it's getting pretty stable now (we have done lots of building in it now and our shared Wabi runs fine with this).
Peter diff -urN linux-2.1.78.orig/fs/coda/cache.c linux-2.1.78/fs/coda/cache.c --- linux-2.1.78.orig/fs/coda/cache.c Mon Dec 22 11:40:49 1997 +++ linux-2.1.78/fs/coda/cache.c Tue Jan 6 11:41:58 1998 @@ -236,7 +236,7 @@ if ( cnp ) CHECK_CNODE(cnp); } else { - printk("No inode for dentry_delete!\n"); + CDEBUG(D_CACHE, "No inode for dentry_delete!\n"); return; } @@ -254,6 +254,14 @@ return; } +static void coda_zap_cnode(struct cnode *cnp, int flags) +{ + cnp->c_flags |= flags; + coda_cache_clear_cnp(cnp); +} + + + /* the dache will notice the flags and drop entries (possibly with children) the moment they are no longer in use */ void coda_zapfid(struct ViceFid *fid, struct super_block *sb, int flag) @@ -273,9 +281,22 @@ return; } + if ( coda_fid_is_volroot(fid) ) { + struct list_head *lh, *le; + 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); + if ( cnp->c_fid.Volume == fid->Volume) + coda_zap_cnode(cnp, flag); + } + return; + } + + inode = coda_fid_to_inode(fid, sb); if ( !inode ) { - printk("coda_zapfid: no inode!\n"); + CDEBUG(D_CACHE, "coda_zapfid: no inode!\n"); return; } cnp = ITOC(inode); @@ -284,8 +305,7 @@ printk("coda_zapfid: no cnode!\n"); return; } - cnp->c_flags |= flag; - coda_cache_clear_cnp(cnp); + coda_zap_cnode(cnp, flag); } diff -urN linux-2.1.78.orig/fs/coda/cnode.c linux-2.1.78/fs/coda/cnode.c --- linux-2.1.78.orig/fs/coda/cnode.c Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/fs/coda/cnode.c Tue Jan 6 11:07:23 1998 @@ -7,8 +7,8 @@ #include <linux/coda.h> #include <linux/coda_linux.h> -#include <linux/coda_psdev.h> #include <linux/coda_cnode.h> +#include <linux/coda_psdev.h> extern int coda_debug; extern int coda_print_entry; @@ -29,6 +29,7 @@ memset(result, 0, (int) sizeof(struct cnode)); INIT_LIST_HEAD(&(result->c_cnhead)); + INIT_LIST_HEAD(&(result->c_volrootlist)); return result; } @@ -70,6 +71,7 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb) { struct cnode *cnp; + struct coda_sb_info *sbi= coda_sbp(sb); struct coda_vattr attr; int error; ino_t ino; @@ -119,6 +121,9 @@ CHECK_CNODE(cnp); /* fill in the inode attributes */ + if ( coda_fid_is_volroot(fid) ) + list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead); + 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); @@ -148,6 +153,7 @@ ENTRY; CDEBUG(D_INODE, "%s\n", coda_f2s(fid, str)); + nr = coda_f2i(fid); inode = iget(sb, nr); diff -urN linux-2.1.78.orig/fs/coda/coda_linux.c linux-2.1.78/fs/coda/coda_linux.c --- linux-2.1.78.orig/fs/coda/coda_linux.c Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/fs/coda/coda_linux.c Tue Jan 6 11:07:24 1998 @@ -97,6 +97,11 @@ } +int coda_fid_is_volroot(struct ViceFid *fid) +{ + return ( (fid->Vnode == 1) && (fid->Unique == 1 ) ); +} + /* utility functions below */ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr) { @@ -155,7 +160,6 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr) { - umode_t mode; unsigned int valid; /* clean out */ @@ -170,15 +174,16 @@ vattr->va_mtime.tv_nsec = (time_t) -1; vattr->va_ctime.tv_nsec = (time_t) -1; vattr->va_type = C_VNON; - vattr->va_fileid = (long)-1; - vattr->va_gen = (long)-1; - vattr->va_bytes = (long)-1; - vattr->va_nlink = (short)-1; - vattr->va_blocksize = (long)-1; - vattr->va_rdev = (dev_t)-1; + vattr->va_fileid = -1; + vattr->va_gen = -1; + vattr->va_bytes = -1; + vattr->va_nlink = -1; + vattr->va_blocksize = -1; + vattr->va_rdev = -1; vattr->va_flags = 0; /* determine the type */ +#if 0 mode = iattr->ia_mode; if ( S_ISDIR(mode) ) { vattr->va_type = C_VDIR; @@ -190,6 +195,7 @@ /* don't do others */ vattr->va_type = C_VNON; } +#endif /* set those vattrs that need change */ valid = iattr->ia_valid; @@ -219,7 +225,6 @@ } } - void print_vattr(struct coda_vattr *attr) { diff -urN linux-2.1.78.orig/fs/coda/dir.c linux-2.1.78/fs/coda/dir.c --- linux-2.1.78.orig/fs/coda/dir.c Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/fs/coda/dir.c Tue Jan 6 11:37:35 1998 @@ -27,7 +27,7 @@ /* dir inode-ops */ static int coda_create(struct inode *dir, struct dentry *new, int mode); static int coda_lookup(struct inode *dir, struct dentry *target); -static int coda_link(struct inode *old_inode, struct inode *dir_inode, +static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, struct dentry *entry); static int coda_unlink(struct inode *dir_inode, struct dentry *entry); static int coda_symlink(struct inode *dir_inode, struct dentry *entry, @@ -243,19 +243,19 @@ char str[50]; CDEBUG(D_INODE, "create: %s, result %d\n", coda_f2s(&newfid, str), error); + d_drop(de); return error; } error = coda_cnode_make(&result, &newfid, dir->i_sb); if ( error ) { + d_drop(de); result = NULL; return error; } /* invalidate the directory cnode's attributes */ dircnp->c_flags &= ~C_VATTR; -/* cfsnc_zapfid(&(dircnp->c_fid)); */ - d_instantiate(de, result); return 0; } @@ -276,8 +276,10 @@ printk("coda_mkdir: inode is NULL or not a directory\n"); return -ENOENT; } + if ( len > CFS_MAXNAMLEN ) return -ENAMETOOLONG; + if (coda_isroot(dir) && coda_iscontrol(name, len)) return -EPERM; @@ -294,6 +296,7 @@ if ( error ) { CDEBUG(D_INODE, "mkdir error: %s result %d\n", coda_f2s(&newfid, fidstr), error); + d_drop(de); return error; } @@ -301,21 +304,23 @@ coda_f2s(&newfid, fidstr)); error = coda_cnode_make(&inode, &newfid, dir->i_sb); - if ( error ) - return error; + if ( error ) { + d_drop(de); + return error; + } /* invalidate the directory cnode's attributes */ dircnp->c_flags &= ~C_VATTR; -/* cfsnc_zapfid(&(dircnp->c_fid)); */ - dir->i_nlink++; d_instantiate(de, inode); return 0; } -static int coda_link(struct inode *inode, struct inode *dir_inode, +/* try to make de an entry in dir_inodde linked to source_de */ +static int coda_link(struct dentry *source_de, struct inode *dir_inode, struct dentry *de) { + 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; @@ -340,19 +345,17 @@ return -ENAMETOOLONG; } - /* Check for link to/from control object. */ - error = venus_link(dir_inode->i_sb,&(cnp->c_fid), &(dir_cnp->c_fid), (const char *)name, len); if ( ! error ) { - dir_cnp->c_flags &= ~C_VATTR; -/* cfsnc_zapfid(&(dir_cnp->c_fid)); */ -/* cfsnc_zapfid(&(cnp->c_fid)); */ - - inode->i_nlink++; - d_instantiate(de, inode); + dir_cnp->c_flags &= ~C_VATTR; + inode->i_nlink++; + d_instantiate(de, inode); + } else { + d_drop(de); } + CDEBUG(D_INODE, "link result %d\n",error); EXIT; return(error); @@ -382,11 +385,18 @@ 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. + */ + d_drop(de); + error = venus_symlink(dir_inode->i_sb, &(dir_cnp->c_fid), name, len, symname, symlen); - if ( !error ) - d_drop(de); + if ( !error ) { + dir_cnp->c_flags |= C_VATTR; + } CDEBUG(D_INODE, "in symlink result %d\n",error); EXIT; @@ -412,7 +422,6 @@ coda_f2s(&(dircnp->c_fid), fidstr), dir->i_ino); /* this file should no longer be in the namecache! */ -/* cfsnc_zapfile(dircnp, (const char *)name, len); */ error = venus_remove(dir->i_sb, &(dircnp->c_fid), name, len); @@ -423,7 +432,6 @@ /* cache management */ dircnp->c_flags &= ~C_VATTR; -/* cfsnc_zapfid(&(dircnp->c_fid)); */ de->d_inode->i_nlink--; d_delete(de); @@ -436,7 +444,7 @@ struct cnode *dircnp; const char *name = de->d_name.name; int len = de->d_name.len; - int error; + int error, rehash = 0; if (!dir || !S_ISDIR(dir->i_mode)) { printk("coda_rmdir: inode is NULL or not a directory\n"); @@ -456,7 +464,16 @@ return error; } /* Drop the dentry to force a new lookup */ - d_drop(de); + if (!list_empty(&de->d_hash)) { + d_drop(de); + rehash = 1; + } + + /* update i_nlink and free the inode before unlinking; + if rmdir fails a new lookup set i_nlink right.*/ + if (de->d_inode->i_nlink) + de->d_inode->i_nlink --; + d_delete(de); error = venus_rmdir(dir->i_sb, &(dircnp->c_fid), name, len); @@ -465,8 +482,9 @@ return error; } - dir->i_nlink--; - d_delete(de); + if (rehash) + d_add(de, NULL); + /* XXX how can mtime be set? */ return 0; } diff -urN linux-2.1.78.orig/fs/coda/file.c linux-2.1.78/fs/coda/file.c --- linux-2.1.78.orig/fs/coda/file.c Sun Jan 4 03:53:43 1998 +++ linux-2.1.78/fs/coda/file.c Tue Jan 6 11:42:29 1998 @@ -25,10 +25,10 @@ #include <linux/coda_cache.h> /* file operations */ -static int coda_readpage(struct dentry *, struct page *); -static ssize_t coda_file_read(struct file *, char *, size_t, loff_t *); -static ssize_t coda_file_write(struct file *, const char *, size_t, loff_t *); -static int coda_file_mmap(struct file *, struct vm_area_struct *); +static int coda_readpage(struct dentry * dentry, struct page * page); +static ssize_t coda_file_read(struct file *f, char *buf, size_t count, loff_t *off); +static ssize_t coda_file_write(struct file *f, const char *buf, size_t count, loff_t *off); +static int coda_file_mmap(struct file * file, struct vm_area_struct * vma); /* exported from this file */ int coda_fsync(struct file *, struct dentry *dentry); @@ -74,9 +74,11 @@ }; /* File file operations */ -static int coda_readpage(struct dentry *dentry, struct page * page) +static int coda_readpage(struct dentry *de, struct page * page) { - struct inode *open_inode, *inode = dentry->d_inode; + struct inode *inode = de->d_inode; + struct dentry cont_dentry; + struct inode *cont_inode; struct cnode *cnp; ENTRY; @@ -89,12 +91,12 @@ return -ENXIO; } - open_inode = cnp->c_ovp; + cont_inode = cnp->c_ovp; + cont_dentry.d_inode = cont_inode; - CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", inode->i_ino, open_inode->i_ino, page->offset); + CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", inode->i_ino, cont_inode->i_ino, page->offset); - /* N.B. This needs the dentry for open_inode */ - generic_readpage(open_inode, page); + generic_readpage(&cont_dentry, page); EXIT; return 0; } diff -urN linux-2.1.78.orig/fs/coda/inode.c linux-2.1.78/fs/coda/inode.c --- linux-2.1.78.orig/fs/coda/inode.c Tue Dec 2 17:24:04 1997 +++ linux-2.1.78/fs/coda/inode.c Wed Dec 31 19:00:00 1969 @@ -1,34 +0,0 @@ -/* - * Inode operations for Coda filesystem - * Original version: (C) 1996 P. Braam and M. Callahan - * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University - * - * Carnegie Mellon encourages users to contribute improvements to - * the Coda project. Contact Peter Braam (coda@cs.cmu.edu). - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/stat.h> -#include <linux/errno.h> -#include <linux/locks.h> -#include <asm/segment.h> -#include <asm/uaccess.h> -#include <linux/string.h> - -#include <linux/coda.h> -#include <linux/coda_linux.h> -#include <linux/coda_psdev.h> -#include <linux/coda_cnode.h> -#include <linux/coda_namecache.h> - -/* prototypes */ -static int coda_readpage(struct inode *inode, struct page *page); -static int coda_cnode_makectl(struct inode **inode, struct super_block *sb); - - - - - diff -urN linux-2.1.78.orig/fs/coda/psdev.c linux-2.1.78/fs/coda/psdev.c --- linux-2.1.78.orig/fs/coda/psdev.c Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/fs/coda/psdev.c Tue Jan 6 11:07:26 1998 @@ -40,8 +40,8 @@ #include <linux/coda.h> #include <linux/coda_linux.h> -#include <linux/coda_psdev.h> #include <linux/coda_cnode.h> +#include <linux/coda_psdev.h> #include <linux/coda_cache.h> #include <linux/coda_sysctl.h> diff -urN linux-2.1.78.orig/fs/coda/super.c linux-2.1.78/fs/coda/super.c --- linux-2.1.78.orig/fs/coda/super.c Sun Jan 4 03:53:43 1998 +++ linux-2.1.78/fs/coda/super.c Tue Jan 6 11:37:36 1998 @@ -41,7 +41,7 @@ /* VFS super_block ops */ static struct super_block *coda_read_super(struct super_block *, void *, int); static void coda_read_inode(struct inode *); -static int coda_notify_change(struct dentry *, struct iattr *); +static int coda_notify_change(struct dentry *dentry, struct iattr *attr); static void coda_put_inode(struct inode *); static void coda_delete_inode(struct inode *); static void coda_put_super(struct super_block *); @@ -101,6 +101,7 @@ sbi->sbi_psdev = psdev; sbi->sbi_vcomm = vc; INIT_LIST_HEAD(&(sbi->sbi_cchead)); + INIT_LIST_HEAD(&(sbi->sbi_volroothead)); lock_super(sb); sb->u.generic_sbp = sbi; @@ -133,7 +134,6 @@ printk("coda_read_super: rootinode is %ld dev %d\n", root->i_ino, root->i_dev); sbi->sbi_root = root; - /* N.B. check this for failure */ sb->s_root = d_alloc_root(root, NULL); unlock_super(sb); EXIT; @@ -141,6 +141,7 @@ error: EXIT; + MOD_DEC_USE_COUNT; if (sbi) { sbi->sbi_vcomm = NULL; sbi->sbi_root = NULL; @@ -154,7 +155,6 @@ coda_cnode_free(ITOC(root)); } sb->s_dev = 0; - MOD_DEC_USE_COUNT; return NULL; } @@ -209,6 +209,10 @@ } cnp = ITOC(inode); + + if ( coda_fid_is_volroot(&cnp->c_fid) ) + list_del(&cnp->c_volrootlist); + open_inode = cnp->c_ovp; if ( open_inode ) { CDEBUG(D_SUPER, "DELINO cached file: ino %ld count %d.\n", @@ -225,9 +229,9 @@ EXIT; } -static int coda_notify_change(struct dentry *dentry, struct iattr *iattr) +static int coda_notify_change(struct dentry *de, struct iattr *iattr) { - struct inode *inode = dentry->d_inode; + struct inode *inode = de->d_inode; struct cnode *cnp; struct coda_vattr vattr; int error; diff -urN linux-2.1.78.orig/fs/coda/symlink.c linux-2.1.78/fs/coda/symlink.c --- linux-2.1.78.orig/fs/coda/symlink.c Sun Jan 4 03:53:43 1998 +++ linux-2.1.78/fs/coda/symlink.c Tue Jan 6 11:42:02 1998 @@ -24,7 +24,7 @@ #include <linux/coda_cnode.h> #include <linux/coda_cache.h> -static int coda_readlink(struct dentry *dentry, char *buffer, int length); +static int coda_readlink(struct dentry *de, char *buffer, int length); static struct dentry *coda_follow_link(struct dentry *, struct dentry *); struct inode_operations coda_symlink_inode_operations = { @@ -50,9 +50,9 @@ NULL /* revalidate */ }; -static int coda_readlink(struct inode *dentry, char *buffer, int length) +static int coda_readlink(struct dentry *de, char *buffer, int length) { - struct inode *inode = dentry->d_inode; + struct inode *inode = de->d_inode; int len; int error; char *buf; @@ -84,15 +84,15 @@ return error; } -static struct dentry *coda_follow_link(struct dentry *dentry, - struct dentry *base) +static struct dentry *coda_follow_link(struct dentry *de, + struct dentry *base) { - struct inode *inode = dentry->d_inode; + struct inode *inode = de->d_inode; int error; struct cnode *cnp; unsigned int len; + char mem[CFS_MAXPATHLEN]; char *path; - char mem[CFS_MAXPATHLEN]; /* N.B. too big for the stack? */ ENTRY; CDEBUG(D_INODE, "(%x/%ld)\n", inode->i_dev, inode->i_ino); diff -urN linux-2.1.78.orig/include/linux/coda.h linux-2.1.78/include/linux/coda.h --- linux-2.1.78.orig/include/linux/coda.h Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/include/linux/coda.h Tue Jan 6 11:12:24 1998 @@ -16,10 +16,13 @@ #endif #ifdef __linux__ +#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 +#else +#define cdev_t dev_t #endif @@ -146,7 +149,7 @@ struct timespec va_ctime; /* time file changed */ u_long va_gen; /* generation number of file */ u_long va_flags; /* flags defined for file */ - dev_t va_rdev; /* device the special file represents */ + cdev_t va_rdev; /* device special file represents */ u_quad_t va_bytes; /* bytes of disk space held by file */ u_quad_t va_filerev; /* file modification number */ }; @@ -237,7 +240,7 @@ struct cfs_open_out { struct cfs_out_hdr oh; - dev_t dev; + cdev_t dev; ino_t inode; }; diff -urN linux-2.1.78.orig/include/linux/coda_cnode.h linux-2.1.78/include/linux/coda_cnode.h --- linux-2.1.78.orig/include/linux/coda_cnode.h Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/include/linux/coda_cnode.h Tue Jan 6 11:26:51 1998 @@ -26,6 +26,7 @@ u_short c_mmcount; /* count of mmappers */ struct inode *c_ovp; /* open vnode pointer */ struct list_head c_cnhead; /* head of cache entries */ + struct list_head c_volrootlist; /* list of volroot cnoddes */ }; /* flags */ @@ -36,7 +37,6 @@ #define C_ZAPDIR 0x10 void coda_cnode_free(struct cnode *); -struct cnode *coda_cnode_alloc(void); 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); diff -urN linux-2.1.78.orig/include/linux/coda_linux.h linux-2.1.78/include/linux/coda_linux.h --- linux-2.1.78.orig/include/linux/coda_linux.h Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/include/linux/coda_linux.h Tue Jan 6 11:23:31 1998 @@ -45,6 +45,7 @@ /* this file: heloers */ char *coda_f2s(ViceFid *f, char *s); int coda_isroot(struct inode *i); +int coda_fid_is_volroot(struct ViceFid *); int coda_iscontrol(const char *name, size_t length); void coda_load_creds(struct coda_cred *cred); int coda_mycred(struct coda_cred *); diff -urN linux-2.1.78.orig/include/linux/coda_psdev.h linux-2.1.78/include/linux/coda_psdev.h --- linux-2.1.78.orig/include/linux/coda_psdev.h Sun Dec 21 17:45:14 1997 +++ linux-2.1.78/include/linux/coda_psdev.h Tue Jan 6 11:08:14 1998 @@ -26,6 +26,7 @@ struct vcomm * sbi_vcomm; struct inode * sbi_root; struct list_head sbi_cchead; + struct list_head sbi_volroothead; }; /* communication pending/processing queues queues */ | |