diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-09-28 22:25:29 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-09-28 22:25:29 +0000 |
commit | 0ae8dceaebe3659ee0c3352c08125f403e77ebca (patch) | |
tree | 5085c389f09da78182b899d19fe1068b619a69dd /fs/coda | |
parent | 273767781288c35c9d679e908672b9996cda4c34 (diff) |
Merge with 2.3.10.
Diffstat (limited to 'fs/coda')
-rw-r--r-- | fs/coda/cache.c | 2 | ||||
-rw-r--r-- | fs/coda/cnode.c | 29 | ||||
-rw-r--r-- | fs/coda/coda_linux.c | 2 | ||||
-rw-r--r-- | fs/coda/dir.c | 8 | ||||
-rw-r--r-- | fs/coda/inode.c | 36 | ||||
-rw-r--r-- | fs/coda/sysctl.c | 50 | ||||
-rw-r--r-- | fs/coda/upcall.c | 48 |
7 files changed, 129 insertions, 46 deletions
diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 1c3b11199..d3412e52c 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c @@ -326,8 +326,8 @@ void coda_flag_inode_children(struct inode *inode, int flag) while ( alias != &inode->i_dentry ) { alias_de = list_entry(alias, struct dentry, d_alias); coda_flag_children(alias_de, flag); - shrink_dcache_parent(alias_de); alias = alias->next; + shrink_dcache_parent(alias_de); } } diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index dd1e03f5f..ffae7746f 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c @@ -14,6 +14,17 @@ extern int coda_debug; extern int coda_print_entry; +inline int coda_fideq(ViceFid *fid1, ViceFid *fid2) +{ + if (fid1->Vnode != fid2->Vnode) + return 0; + if (fid1->Volume != fid2->Volume) + return 0; + if (fid1->Unique != fid2->Unique) + return 0; + return 1; +} + /* cnode.c */ static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr) { @@ -71,8 +82,14 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb) } cnp = ITOC(*inode); - if ( cnp->c_magic != 0 ) { - printk("coda_cnode make on initialized inode %ld, old %s new + /* see if we've got it already */ + if ( cnp->c_magic != 0 && coda_fideq(fid, &cnp->c_fid)) { + return 0; + } + + /* not fresh: collision */ + if ( cnp->c_magic != 0 ) { + printk("coda_cnode_make on initialized inode %ld, old %s new %s!\n", (*inode)->i_ino, coda_f2s(&cnp->c_fid), coda_f2s2(fid)); iput(*inode); @@ -106,14 +123,6 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb) return 0; } -inline int coda_fideq(ViceFid *fid1, ViceFid *fid2) -{ - int eq; - eq = ( (fid1->Vnode == fid2->Vnode) && - (fid1->Volume == fid2->Volume) && - (fid1->Unique == fid2->Unique) ); - return eq; -} void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid, struct ViceFid *newfid) diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c index f684f3a78..5f2f3c467 100644 --- a/fs/coda/coda_linux.c +++ b/fs/coda/coda_linux.c @@ -215,6 +215,8 @@ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr) if (attr->va_ctime.tv_sec != -1) inode->i_ctime = attr->va_ctime.tv_sec; } + + /* * BSD sets attributes that need not be modified to -1. * Linux uses the valid field to indicate what should be diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 4313edb69..10b1cb171 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -800,6 +800,10 @@ static int coda_dentry_revalidate(struct dentry *de, int flags) shrink_dcache_parent(de); + /* propagate for a flush */ + if (cii->c_flags & C_FLUSH) + coda_flag_inode_children(inode, C_FLUSH); + if (de->d_count > 1) { /* pretend it's valid, but don't change the flags */ CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %s\n", @@ -807,10 +811,6 @@ static int coda_dentry_revalidate(struct dentry *de, int flags) return 1; } - /* propagate for a flush */ - if (cii->c_flags & C_FLUSH) - coda_flag_inode_children(inode, C_FLUSH); - /* clear the flags. */ cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 49359f260..604e906a2 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -22,8 +22,6 @@ #include <asm/uaccess.h> #include <linux/fs.h> -#include <linux/stat.h> -#include <asm/uaccess.h> #include <linux/vmalloc.h> #include <asm/segment.h> @@ -75,6 +73,9 @@ static struct super_block * coda_read_super(struct super_block *sb, if ( sbi->sbi_sb ) { printk("Already mounted\n"); + unlock_super(sb); + EXIT; + MOD_DEC_USE_COUNT; return NULL; } @@ -98,7 +99,6 @@ static struct super_block * coda_read_super(struct super_block *sb, printk("coda_read_super: coda_get_rootfid failed with %d\n", error); sb->s_dev = 0; - unlock_super(sb); goto error; } printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid)); @@ -108,7 +108,6 @@ static struct super_block * coda_read_super(struct super_block *sb, if ( error || !root ) { printk("Failure of coda_cnode_make for root: error %d\n", error); sb->s_dev = 0; - unlock_super(sb); goto error; } @@ -121,6 +120,7 @@ static struct super_block * coda_read_super(struct super_block *sb, return sb; error: + unlock_super(sb); EXIT; MOD_DEC_USE_COUNT; if (sbi) { @@ -145,7 +145,6 @@ static void coda_put_super(struct super_block *sb) sb->s_dev = 0; coda_cache_clear_all(sb); sb_info = coda_sbp(sb); -/* sb_info->sbi_vcomm->vc_inuse = 0; You can not do this: psdev_release would see usagecount == 0 and would refuse to decrease MOD_USE_COUNT --pavel */ coda_super_info.sbi_sb = NULL; printk("Coda: Bye bye.\n"); memset(sb_info, 0, sizeof(* sb_info)); @@ -209,7 +208,7 @@ static void coda_delete_inode(struct inode *inode) EXIT; } -static int coda_notify_change(struct dentry *de, struct iattr *iattr) +static int coda_notify_change(struct dentry *de, struct iattr *iattr) { struct inode *inode = de->d_inode; struct coda_inode_info *cii; @@ -238,21 +237,32 @@ static int coda_notify_change(struct dentry *de, struct iattr *iattr) return error; } -/* we need _something_ for this routine. Let's mimic AFS */ static int coda_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) { struct statfs tmp; + int error; + + memset(&tmp, 0, sizeof(struct statfs)); + + error = venus_statfs(sb, &tmp); + if (error) { + /* fake something like AFS does */ + tmp.f_blocks = 9000000; + tmp.f_bfree = 9000000; + tmp.f_bavail = 9000000; + tmp.f_files = 9000000; + tmp.f_ffree = 9000000; + } + + /* and fill in the rest */ tmp.f_type = CODA_SUPER_MAGIC; tmp.f_bsize = 1024; - tmp.f_blocks = 9000000; - tmp.f_bfree = 9000000; - tmp.f_bavail = 9000000 ; - tmp.f_files = 9000000; - tmp.f_ffree = 9000000; - tmp.f_namelen = 0; + tmp.f_namelen = CODA_MAXNAMLEN; + copy_to_user(buf, &tmp, bufsiz); + return 0; } diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c index 79a4c7ebb..e35174e5c 100644 --- a/fs/coda/sysctl.c +++ b/fs/coda/sysctl.c @@ -71,6 +71,7 @@ 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; +int coda_upcall_timestamping = 0; /* keep this in sync with coda.h! */ char *coda_upcall_names[] = { @@ -103,9 +104,12 @@ char *coda_upcall_names[] = { "purgeuser ", /* 26 */ "zapfile ", /* 27 */ "zapdir ", /* 28 */ - "zapvnode ", /* 28 */ + "noop2 ", /* 29 */ "purgefid ", /* 30 */ - "open_by_path" /* 31 */ + "open_by_path", /* 31 */ + "resolve ", /* 32 */ + "reintegrate ", /* 33 */ + "statfs " /* 34 */ }; @@ -133,8 +137,7 @@ void reset_coda_cache_inv_stats( void ) void do_time_stats( struct coda_upcall_stats_entry * pentry, unsigned long runtime ) { - - unsigned long time = runtime * 1000 /HZ; /* time in ms */ + unsigned long time = runtime; /* time in us */ CDEBUG(D_SPECIAL, "time: %ld\n", time); if ( pentry->count == 0 ) { @@ -221,9 +224,12 @@ int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp, { if ( write ) { reset_coda_vfs_stats(); + + filp->f_pos += *lenp; + } else { + *lenp = 0; } - - *lenp = 0; + return 0; } @@ -232,10 +238,19 @@ int do_reset_coda_upcall_stats( ctl_table * table, int write, size_t * lenp ) { if ( write ) { + if (*lenp > 0) { + char c; + if (get_user(c, (char *)buffer)) + return -EFAULT; + coda_upcall_timestamping = (c == '1'); + } reset_coda_upcall_stats(); + + filp->f_pos += *lenp; + } else { + *lenp = 0; } - - *lenp = 0; + return 0; } @@ -245,9 +260,12 @@ int do_reset_coda_permission_stats( ctl_table * table, int write, { if ( write ) { reset_coda_permission_stats(); + + filp->f_pos += *lenp; + } else { + *lenp = 0; } - - *lenp = 0; + return 0; } @@ -257,9 +275,12 @@ int do_reset_coda_cache_inv_stats( ctl_table * table, int write, { if ( write ) { reset_coda_cache_inv_stats(); + + filp->f_pos += *lenp; + } else { + *lenp = 0; } - *lenp = 0; return 0; } @@ -347,12 +368,12 @@ int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset, if ( offset < 160) len += sprintf( buffer + len,"%-79s\n", "======================"); if ( offset < 240) - len += sprintf( buffer + len,"%-79s\n", "upcall\t\t count\tavg time(ms)\tstd deviation(ms)"); + len += sprintf( buffer + len,"%-79s\n", "upcall count avg time(us) std deviation(us)"); if ( offset < 320) - len += sprintf( buffer + len,"%-79s\n", "------\t\t -----\t------------\t-----------------"); + len += sprintf( buffer + len,"%-79s\n", "------ ----- ------------ -----------------"); pos = 320; for ( i = 0 ; i < CODA_NCALLS ; i++ ) { - tmplen += sprintf(tmpbuf,"%s\t%9d\t%10ld\t%10ld", + tmplen += sprintf(tmpbuf,"%s %9d %10ld %10ld", coda_upcall_names[i], coda_upcall_stat[i].count, get_time_average(&coda_upcall_stat[i]), @@ -499,6 +520,7 @@ static void coda_proc_modcount(struct inode *inode, int fill) MOD_INC_USE_COUNT; else MOD_DEC_USE_COUNT; + } #endif diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index a0c1092b2..62fd62e35 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -580,6 +580,33 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid, return error; } +int venus_statfs(struct super_block *sb, struct statfs *sfs) +{ + union inputArgs *inp; + union outputArgs *outp; + int insize, outsize, error; + + insize = max(INSIZE(statfs), OUTSIZE(statfs)); + UPARG(CODA_STATFS); + + error = coda_upcall(coda_sbp(sb), insize, &outsize, inp); + + if (!error) { + sfs->f_blocks = outp->coda_statfs.stat.f_blocks; + sfs->f_bfree = outp->coda_statfs.stat.f_bfree; + sfs->f_bavail = outp->coda_statfs.stat.f_bavail; + sfs->f_files = outp->coda_statfs.stat.f_files; + sfs->f_ffree = outp->coda_statfs.stat.f_ffree; + } else { + printk("coda_statfs: Venus returns: %d\n", error); + } + + if (inp) CODA_FREE(inp, insize); + CDEBUG(D_INODE, " result %d\n",error); + EXIT; + return error; +} + /* * coda_upcall and coda_downcall routines. * @@ -588,10 +615,12 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid, static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp) { DECLARE_WAITQUEUE(wait, current); - unsigned long posttime; + struct timeval begin = { 0, 0 }, end = { 0, 0 }; vmp->uc_posttime = jiffies; - posttime = jiffies; + + if (coda_upcall_timestamping) + do_gettimeofday(&begin); add_wait_queue(&vmp->uc_sleep, &wait); for (;;) { @@ -620,9 +649,20 @@ static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp) remove_wait_queue(&vmp->uc_sleep, &wait); current->state = TASK_RUNNING; - CDEBUG(D_SPECIAL, "posttime: %ld, returned: %ld\n", posttime, jiffies-posttime); - return (jiffies - posttime); + if (coda_upcall_timestamping && begin.tv_sec != 0) { + do_gettimeofday(&end); + + if (end.tv_usec < begin.tv_usec) { + end.tv_usec += 1000000; end.tv_sec--; + } + end.tv_sec -= begin.tv_sec; + end.tv_usec -= begin.tv_usec; + } + + CDEBUG(D_SPECIAL, "begin: %ld.%06ld, elapsed: %ld.%06ld\n", + begin.tv_sec, begin.tv_usec, end.tv_sec, end.tv_usec); + return ((end.tv_sec * 1000000) + end.tv_usec); } |