1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-24 07:40:52 +00:00

Complete repo-copy and move of Coda from src/sys/coda to src/sys/fs/coda

by removing files from src/sys/coda, and updating include paths in the
new location, kernel configuration, and  Makefiles.  In one case add
$FreeBSD$.

Discussed with:		anderson, Jan Harkes <jaharkes@cs.cmu.edu>
Approved by:		re (kensmith)
Repo-copy madness:	simon
This commit is contained in:
Robert Watson 2007-07-12 21:04:58 +00:00
parent d21e51d059
commit 00f05dc847
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171416
33 changed files with 46 additions and 7148 deletions

View File

@ -8,7 +8,7 @@ SUBDIR= boot
.endif
# Directories to include in cscope name file and TAGS.
CSCOPEDIRS= bsm cam coda compat conf contrib crypto ddb dev fs geom gnu \
CSCOPEDIRS= bsm cam compat conf contrib crypto ddb dev fs geom gnu \
i4b isa kern libkern modules net net80211 netatalk netatm \
netgraph netinet netinet6 netipsec netipx netnatm netncp \
netsmb nfs nfsclient nfs4client rpc pccard pci security sys \

View File

@ -1,62 +0,0 @@
$FreeBSD$
Announcing the Availability of the
Coda Distributed
Filesystem
for
BSD Unix Systems
Coda is a distributed filesystem like NFS and AFS. It is
freely available, like NFS. But it functions much like AFS in being a
"stateful" filesystem. Coda and AFS cache files on your local
machine to improve performance. But Coda goes a step further than AFS
by letting you access the cached files when there is no available
network, viz. disconnected laptops and network outages. In Coda, both
the client and server are outside the kernel which makes them easier
to experiment with.
To get more information on Coda, I would like to refer people to
http://www.coda.cs.cmu.edu
There is a wealth of documents, papers, and theses there. There is
also a good introduction to the Coda File System in
http://www.coda.cs.cmu.edu/ljpaper/lj.html
Coda was originally developed as an academic prototype/testbed. It is
being polished and rewritten where necessary. Coda is a work in
progress and does have bugs. It is, though, very usable. Our
interest is in making Coda available to as many people as possible and
to have Coda evolve and flourish.
The bulk of the Coda filesystem code supports the Coda client
program, the Coda server program and the utilities needed by both.
All these programs are unix programs and can run equally well on any
Unix platform. Our main development thrust is improving these
programs. There is a small part of Coda that deals with the kernel to
filesystem interface. This code is OS specific (but should not be
platform specific).
Coda is currently available for several OS's and platforms:
Freebsd-2.2.5: i386
Freebsd-2.2.6: i386
Freebsd -current: i386
linux 2.0: i386 & sparc
linux 2.1: i386 & sparc
NetBSD 1.3: i386
NetBSD -current: i386
The relevant sources, binaries, and docs can be found in
ftp://ftp.coda.cs.cmu.edu/pub/coda/
We intend to come out with new Coda releases often, not daily. We
don't want to slight any OS/platform not mentioned above. We are just
limited in our resources as to what we can support internally. We
will be happy to integrate OpenBSD support as well as other OS
support. Also, adding platform support should be relatively easy and
we can discuss this. The only difficulty is that Coda has a light weight
process package. It does some manipulations in assembler which would
have to be redone for a different platform.
There are several mailing lists @coda.cs.cmu.edu that discuss coda:
coda-announce and linux-coda. We are going to revise linux-coda to be
OS neutral, since it is mainly Coda we want to discuss. We appreciate
comments, feedback, bug reports, bug fixes, enhancements, etc.

View File

@ -1,17 +0,0 @@
OOPS:
FreeBSD does not fsync!!!
Near term:
Fix bug in executing/mapping new files.
cfs_mount bug: interaction with cfs_inactive no cfs_unsave.
vref/vn_lock == vget except no VXWANT which may be on.
Review locks: vn_lock/VOP_UNLOCK/lockmgr ...
Medium term:
Add missing VFS methods.
Do performance profile.
Tune hash algorithm used in cfs_namecache.
Tune hash algorithm used in cfs_subr.
Eventually:
Use standard queue macros.

View File

@ -1,207 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/cnode.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*-
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon University.
* Contributers include David Steere, James Kistler, and M. Satyanarayanan.
*/
#ifndef _CNODE_H_
#define _CNODE_H_
#include <sys/vnode.h>
#include <sys/lock.h>
MALLOC_DECLARE(M_CODA);
/*
* tmp below since we need struct queue
*/
#include <coda/coda_kernel.h>
/*
* Cnode lookup stuff.
* NOTE: CODA_CACHESIZE must be a power of 2 for cfshash to work!
*/
#define CODA_CACHESIZE 512
#define CODA_ALLOC(ptr, cast, size) \
do { \
ptr = (cast)malloc((unsigned long) size, M_CODA, M_WAITOK); \
if (ptr == 0) { \
panic("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
} \
} while (0)
#define CODA_FREE(ptr, size) free((ptr), M_CODA)
/*
* global cache state control
*/
extern int coda_nc_use;
/*
* Used to select debugging statements throughout the cfs code.
*/
extern int codadebug;
extern int coda_nc_debug;
extern int coda_printf_delay;
extern int coda_vnop_print_entry;
extern int coda_psdev_print_entry;
extern int coda_vfsop_print_entry;
#define CODADBGMSK(N) (1 << N)
#define CODADEBUG(N, STMT) { if (codadebug & CODADBGMSK(N)) { STMT } }
#define myprintf(args) \
do { \
if (coda_printf_delay) \
DELAY(coda_printf_delay);\
printf args ; \
} while (0)
struct cnode {
struct vnode *c_vnode;
u_short c_flags; /* flags (see below) */
CodaFid c_fid; /* file handle */
struct vnode *c_ovp; /* open vnode pointer */
u_short c_ocount; /* count of openers */
u_short c_owrite; /* count of open for write */
struct vattr c_vattr; /* attributes */
char *c_symlink; /* pointer to symbolic link */
u_short c_symlen; /* length of symbolic link */
struct cnode *c_next; /* links if on NetBSD machine */
};
#define VTOC(vp) ((struct cnode *)(vp)->v_data)
#define CTOV(cp) ((struct vnode *)((cp)->c_vnode))
/* flags */
#define C_VATTR 0x01 /* Validity of vattr in the cnode */
#define C_SYMLINK 0x02 /* Validity of symlink pointer in the Code */
#define C_WANTED 0x08 /* Set if lock wanted */
#define C_LOCKED 0x10 /* Set if lock held */
#define C_UNMOUNTING 0X20 /* Set if unmounting */
#define C_PURGING 0x40 /* Set if purging a fid */
#define VALID_VATTR(cp) ((cp->c_flags) & C_VATTR)
#define VALID_SYMLINK(cp) ((cp->c_flags) & C_SYMLINK)
#define IS_UNMOUNTING(cp) ((cp)->c_flags & C_UNMOUNTING)
struct vcomm {
u_long vc_seq;
struct selinfo vc_selproc;
struct queue vc_requests;
struct queue vc_replys;
};
#define VC_OPEN(vcp) ((vcp)->vc_requests.forw != NULL)
#define MARK_VC_CLOSED(vcp) (vcp)->vc_requests.forw = NULL;
#define MARK_VC_OPEN(vcp) /* MT */
struct coda_clstat {
int ncalls; /* client requests */
int nbadcalls; /* upcall failures */
int reqs[CODA_NCALLS]; /* count of each request */
};
extern struct coda_clstat coda_clstat;
/*
* CODA structure to hold mount/filesystem information
*/
struct coda_mntinfo {
struct vnode *mi_rootvp;
struct mount *mi_vfsp;
struct vcomm mi_vcomm;
struct cdev *dev;
int mi_started;
LIST_ENTRY(coda_mntinfo) mi_list;
};
struct coda_mntinfo *dev2coda_mntinfo(struct cdev *dev);
/*
* vfs pointer to mount info
*/
#define vftomi(vfsp) ((struct coda_mntinfo *)(vfsp->mnt_data))
#define CODA_MOUNTED(vfsp) (vftomi((vfsp)) != (struct coda_mntinfo *)0)
/*
* vnode pointer to mount info
*/
#define vtomi(vp) ((struct coda_mntinfo *)(vp->v_mount->mnt_data))
/*
* Used for identifying usage of "Control" object
*/
extern struct vnode *coda_ctlvp;
#define IS_CTL_VP(vp) ((vp) == coda_ctlvp)
#define IS_CTL_NAME(vp, name, l)((l == CODA_CONTROLLEN) \
&& ((vp) == vtomi((vp))->mi_rootvp) \
&& strncmp(name, CODA_CONTROL, l) == 0)
/*
* An enum to tell us whether something that will remove a reference
* to a cnode was a downcall or not
*/
enum dc_status {
IS_DOWNCALL = 6,
NOT_DOWNCALL = 7
};
/* cfs_psdev.h */
int coda_call(struct coda_mntinfo *mntinfo, int inSize, int *outSize, caddr_t buffer);
extern int coda_kernel_version;
/* cfs_subr.h */
int handleDownCall(int opcode, union outputArgs *out);
void coda_unmounting(struct mount *whoIam);
int coda_vmflush(struct cnode *cp);
/* cfs_vnodeops.h */
struct cnode *make_coda_node(CodaFid *fid, struct mount *vfsp, short type);
int coda_vnodeopstats_init(void);
/* coda_vfsops.h */
struct mount *devtomp(struct cdev *dev);
/* sigh */
#define CODA_RDWR ((u_long) 31)
#endif /* _CNODE_H_ */

View File

@ -1,830 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*
*
* Based on cfs.h from Mach, but revamped for increased simplicity.
* Linux modifications by Peter Braam, Aug 1996
*/
#ifndef _CODA_HEADER_
#define _CODA_HEADER_
#include "opt_coda.h" /* for CODA_COMPAT_5 option */
/* Avoid CODA_COMPAT_5 redefinition in coda5 module */
#if defined (CODA5_MODULE) && !defined(CODA_COMPAT_5)
#define CODA_COMPAT_5
#endif
/* Catch new _KERNEL defn for NetBSD */
#ifdef __NetBSD__
#include <sys/types.h>
#endif
#ifndef CODA_MAXSYMLINKS
#define CODA_MAXSYMLINKS 10
#endif
#if defined(DJGPP) || defined(__CYGWIN32__)
#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 struct cdev *;
typedef void * caddr_t;
#ifdef DOS
typedef unsigned __int64 u_quad_t;
#else
typedef unsigned long long u_quad_t;
#endif
#define inline
struct timespec {
long ts_sec;
long ts_nsec;
};
#else /* DJGPP but not _KERNEL */
#include <sys/types.h>
#include <sys/time.h>
typedef unsigned long long u_quad_t;
#endif /* !_KERNEL */
#endif /* !DJGPP */
#if defined(__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
#ifdef __CYGWIN32__
typedef unsigned char u_int8_t;
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif
/*
* Cfs constants
*/
#define CODA_MAXNAMLEN 255
#define CODA_MAXPATHLEN 1024
#define CODA_MAXSYMLINK 10
/* these are Coda's version of O_RDONLY etc combinations
* to deal with VFS open modes
*/
#define C_O_READ 0x001
#define C_O_WRITE 0x002
#define C_O_TRUNC 0x010
#define C_O_EXCL 0x100
#define C_O_CREAT 0x200
/* these are to find mode bits in Venus */
#define C_M_READ 00400
#define C_M_WRITE 00200
/* for access Venus will use */
#define C_A_C_OK 8 /* Test for writing upon create. */
#define C_A_R_OK 4 /* Test for read permission. */
#define C_A_W_OK 2 /* Test for write permission. */
#define C_A_X_OK 1 /* Test for execute permission. */
#define C_A_F_OK 0 /* Test for existence. */
#ifndef _VENUS_DIRENT_T_
#define _VENUS_DIRENT_T_ 1
struct venus_dirent {
unsigned long d_fileno; /* file number of entry */
unsigned short d_reclen; /* length of this record */
char d_type; /* file type, see below */
char d_namlen; /* length of string in d_name */
char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
};
#undef DIRSIZ
#define DIRSIZ(dp) ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) + \
(((dp)->d_namlen+1 + 3) &~ 3))
/*
* File types
*/
#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 IFTOCDT(mode) (((mode) & 0170000) >> 12)
#define CDTTOIF(dirtype) ((dirtype) << 12)
#endif
#ifdef CODA_COMPAT_5
typedef struct {
u_long Volume;
u_long Vnode;
u_long Unique;
} CodaFid;
static __inline__ ino_t coda_f2i(CodaFid *fid)
{
if (!fid) return 0;
return (fid->Unique + (fid->Vnode<<10) + (fid->Volume<<20));
}
static __inline__ char * coda_f2s(CodaFid *fid)
{
static char fid_str [35];
snprintf (fid_str, 35, "[%lx.%lx.%lx]", fid->Volume,
fid->Vnode, fid->Unique);
return fid_str;
}
static __inline__ int coda_fid_eq (CodaFid *fid1, CodaFid *fid2)
{
return (fid1->Volume == fid2->Volume &&
fid1->Vnode == fid2->Vnode &&
fid1->Unique == fid2->Unique);
}
struct coda_cred {
u_int32_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/
u_int32_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
};
#else /* CODA_COMPAT_5 */
typedef struct {
u_int32_t opaque[4];
} CodaFid;
static __inline__ ino_t coda_f2i(CodaFid *fid)
{
if ( ! fid )
return 0;
return (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]);
}
static __inline__ char * coda_f2s(CodaFid *fid)
{
static char fid_str [35];
snprintf (fid_str, 35, "[%x.%x.%x.%x]", fid->opaque[0],
fid->opaque[1], fid->opaque[2], fid->opaque[3]);
return fid_str;
}
static __inline__ int coda_fid_eq (CodaFid *fid1, CodaFid *fid2)
{
return (fid1->opaque[0] == fid2->opaque[0] &&
fid1->opaque[1] == fid2->opaque[1] &&
fid1->opaque[2] == fid2->opaque[2] &&
fid1->opaque[3] == fid2->opaque[3]);
}
#endif /* CODA_COMPAT_5 */
#ifndef _VENUS_VATTR_T_
#define _VENUS_VATTR_T_
/*
* Vnode types. VNON means no type.
*/
enum coda_vtype { C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
struct coda_vattr {
int va_type; /* vnode type (for create) */
u_short va_mode; /* files access mode and type */
short va_nlink; /* number of references to file */
uid_t va_uid; /* owner user id */
gid_t va_gid; /* owner group id */
long va_fileid; /* file id */
u_quad_t va_size; /* file size in bytes */
long va_blocksize; /* blocksize preferred for i/o */
struct timespec va_atime; /* time of last access */
struct timespec va_mtime; /* time of last modification */
struct timespec va_ctime; /* time file changed */
u_long va_gen; /* generation number of file */
u_long va_flags; /* flags defined for file */
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 */
};
#endif
/* structure used by CODA_STATFS for getting cache information from venus */
struct coda_statfs {
int32_t f_blocks;
int32_t f_bfree;
int32_t f_bavail;
int32_t f_files;
int32_t f_ffree;
};
/*
* Kernel <--> Venus communications.
*/
#define CODA_ROOT 2
#define CODA_OPEN_BY_FD 3
#define CODA_OPEN 4
#define CODA_CLOSE 5
#define CODA_IOCTL 6
#define CODA_GETATTR 7
#define CODA_SETATTR 8
#define CODA_ACCESS 9
#define CODA_LOOKUP 10
#define CODA_CREATE 11
#define CODA_REMOVE 12
#define CODA_LINK 13
#define CODA_RENAME 14
#define CODA_MKDIR 15
#define CODA_RMDIR 16
#define CODA_READDIR 17
#define CODA_SYMLINK 18
#define CODA_READLINK 19
#define CODA_FSYNC 20
#define CODA_INACTIVE 21
#define CODA_VGET 22
#define CODA_SIGNAL 23
#define CODA_REPLACE 24
#define CODA_FLUSH 25
#define CODA_PURGEUSER 26
#define CODA_ZAPFILE 27
#define CODA_ZAPDIR 28
#define CODA_PURGEFID 30
#define CODA_OPEN_BY_PATH 31
#define CODA_RESOLVE 32
#define CODA_REINTEGRATE 33
#define CODA_STATFS 34
#define CODA_NCALLS 35
#define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
#define VC_MAXDATASIZE 8192
#define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +\
VC_MAXDATASIZE
#define CIOC_KERNEL_VERSION _IOWR('c', 10, sizeof (int))
#if 0
/* don't care about kernel version number */
#define CODA_KERNEL_VERSION 0
/* The old venus 4.6 compatible interface */
#define CODA_KERNEL_VERSION 1
#endif /* realms/cells */
#ifdef CODA_COMPAT_5
/* venus_lookup gets an extra parameter to aid windows.*/
#define CODA_KERNEL_VERSION 2
#else
/* 128-bit fids for realms */
#define CODA_KERNEL_VERSION 3
#endif
/*
* Venus <-> Coda RPC arguments
*/
#ifdef CODA_COMPAT_5
struct coda_in_hdr {
unsigned long opcode;
unsigned long unique; /* Keep multiple outstanding msgs distinct */
u_short pid; /* Common to all */
u_short pgid; /* Common to all */
u_short sid; /* Common to all */
struct coda_cred cred; /* Common to all */
};
#else
struct coda_in_hdr {
u_int32_t opcode;
u_int32_t unique; /* Keep multiple outstanding msgs distinct */
pid_t pid; /* Common to all */
pid_t pgid; /* Common to all */
uid_t uid; /* Common to all */
};
#endif
/* Really important that opcode and unique are 1st two fields! */
struct coda_out_hdr {
unsigned long opcode;
unsigned long unique;
unsigned long result;
};
/* coda_root: NO_IN */
struct coda_root_out {
struct coda_out_hdr oh;
CodaFid Fid;
};
struct coda_root_in {
struct coda_in_hdr in;
};
/* coda_sync: */
/* Nothing needed for coda_sync */
/* coda_open: */
struct coda_open_in {
struct coda_in_hdr ih;
CodaFid Fid;
int flags;
};
struct coda_open_out {
struct coda_out_hdr oh;
cdev_t dev;
ino_t inode;
};
/* coda_close: */
struct coda_close_in {
struct coda_in_hdr ih;
CodaFid Fid;
int flags;
};
struct coda_close_out {
struct coda_out_hdr out;
};
/* coda_ioctl: */
struct coda_ioctl_in {
struct coda_in_hdr ih;
CodaFid Fid;
int cmd;
int len;
int rwflag;
char *data; /* Place holder for data. */
};
struct coda_ioctl_out {
struct coda_out_hdr oh;
int len;
caddr_t data; /* Place holder for data. */
};
/* coda_getattr: */
struct coda_getattr_in {
struct coda_in_hdr ih;
CodaFid Fid;
};
struct coda_getattr_out {
struct coda_out_hdr oh;
struct coda_vattr attr;
};
/* coda_setattr: NO_OUT */
struct coda_setattr_in {
struct coda_in_hdr ih;
CodaFid Fid;
struct coda_vattr attr;
};
struct coda_setattr_out {
struct coda_out_hdr out;
};
/* coda_access: NO_OUT */
struct coda_access_in {
struct coda_in_hdr ih;
CodaFid Fid;
int flags;
};
struct coda_access_out {
struct coda_out_hdr out;
};
/* lookup flags */
#define CLU_CASE_SENSITIVE 0x01
#define CLU_CASE_INSENSITIVE 0x02
/* coda_lookup: */
struct coda_lookup_in {
struct coda_in_hdr ih;
CodaFid Fid;
int name; /* Place holder for data. */
int flags;
};
struct coda_lookup_out {
struct coda_out_hdr oh;
CodaFid Fid;
int vtype;
};
/* coda_create: */
struct coda_create_in {
struct coda_in_hdr ih;
CodaFid Fid;
struct coda_vattr attr;
int excl;
int mode;
int name; /* Place holder for data. */
};
struct coda_create_out {
struct coda_out_hdr oh;
CodaFid Fid;
struct coda_vattr attr;
};
/* coda_remove: NO_OUT */
struct coda_remove_in {
struct coda_in_hdr ih;
CodaFid Fid;
int name; /* Place holder for data. */
};
struct coda_remove_out {
struct coda_out_hdr out;
};
/* coda_link: NO_OUT */
struct coda_link_in {
struct coda_in_hdr ih;
CodaFid sourceFid; /* cnode to link *to* */
CodaFid destFid; /* Directory in which to place link */
int tname; /* Place holder for data. */
};
struct coda_link_out {
struct coda_out_hdr out;
};
/* coda_rename: NO_OUT */
struct coda_rename_in {
struct coda_in_hdr ih;
CodaFid sourceFid;
int srcname;
CodaFid destFid;
int destname;
};
struct coda_rename_out {
struct coda_out_hdr out;
};
/* coda_mkdir: */
struct coda_mkdir_in {
struct coda_in_hdr ih;
CodaFid Fid;
struct coda_vattr attr;
int name; /* Place holder for data. */
};
struct coda_mkdir_out {
struct coda_out_hdr oh;
CodaFid Fid;
struct coda_vattr attr;
};
/* coda_rmdir: NO_OUT */
struct coda_rmdir_in {
struct coda_in_hdr ih;
CodaFid Fid;
int name; /* Place holder for data. */
};
struct coda_rmdir_out {
struct coda_out_hdr out;
};
/* coda_readdir: */
struct coda_readdir_in {
struct coda_in_hdr ih;
CodaFid Fid;
int count;
int offset;
};
struct coda_readdir_out {
struct coda_out_hdr oh;
int size;
caddr_t data; /* Place holder for data. */
};
/* coda_symlink: NO_OUT */
struct coda_symlink_in {
struct coda_in_hdr ih;
CodaFid Fid; /* Directory to put symlink in */
int srcname;
struct coda_vattr attr;
int tname;
};
struct coda_symlink_out {
struct coda_out_hdr out;
};
/* coda_readlink: */
struct coda_readlink_in {
struct coda_in_hdr ih;
CodaFid Fid;
};
struct coda_readlink_out {
struct coda_out_hdr oh;
int count;
caddr_t data; /* Place holder for data. */
};
/* coda_fsync: NO_OUT */
struct coda_fsync_in {
struct coda_in_hdr ih;
CodaFid Fid;
};
struct coda_fsync_out {
struct coda_out_hdr out;
};
/* coda_inactive: NO_OUT */
struct coda_inactive_in {
struct coda_in_hdr ih;
CodaFid Fid;
};
/* coda_vget: */
struct coda_vget_in {
struct coda_in_hdr ih;
CodaFid Fid;
};
struct coda_vget_out {
struct coda_out_hdr oh;
CodaFid Fid;
int vtype;
};
/* CODA_SIGNAL is out-of-band, doesn't need data. */
/* CODA_INVALIDATE is a venus->kernel call */
/* CODA_FLUSH is a venus->kernel call */
/* coda_purgeuser: */
/* CODA_PURGEUSER is a venus->kernel call */
struct coda_purgeuser_out {
struct coda_out_hdr oh;
#ifdef CODA_COMPAT_5
struct coda_cred cred;
#else
uid_t uid;
#endif
};
/* coda_zapfile: */
/* CODA_ZAPFILE is a venus->kernel call */
struct coda_zapfile_out {
struct coda_out_hdr oh;
CodaFid Fid;
};
/* coda_zapdir: */
/* CODA_ZAPDIR is a venus->kernel call */
struct coda_zapdir_out {
struct coda_out_hdr oh;
CodaFid Fid;
};
/* coda_zapnode: */
/* CODA_ZAPVNODE is a venus->kernel call */
struct coda_zapvnode_out {
struct coda_out_hdr oh;
#ifdef CODA_COMPAT_5
struct coda_cred cred;
#endif
CodaFid Fid;
};
/* coda_purgefid: */
/* CODA_PURGEFID is a venus->kernel call */
struct coda_purgefid_out {
struct coda_out_hdr oh;
CodaFid Fid;
};
/* coda_replace: */
/* CODA_REPLACE is a venus->kernel call */
struct coda_replace_out { /* coda_replace is a venus->kernel call */
struct coda_out_hdr oh;
CodaFid NewFid;
CodaFid OldFid;
};
/* coda_open_by_fd: */
struct coda_open_by_fd_in {
struct coda_in_hdr ih;
CodaFid Fid;
int flags;
};
struct coda_open_by_fd_out {
struct coda_out_hdr oh;
int fd;
struct vnode *vp;
};
/* coda_open_by_path: */
struct coda_open_by_path_in {
struct coda_in_hdr ih;
CodaFid Fid;
int flags;
};
struct coda_open_by_path_out {
struct coda_out_hdr oh;
int path;
};
/* coda_statfs: NO_IN */
struct coda_statfs_in {
struct coda_in_hdr ih;
};
struct coda_statfs_out {
struct coda_out_hdr oh;
struct coda_statfs stat;
};
/*
* Occasionally, we don't cache the fid returned by CODA_LOOKUP.
* For instance, if the fid is inconsistent.
* This case is handled by setting the top bit of the type result parameter.
*/
#define CODA_NOCACHE 0x80000000
union inputArgs {
struct coda_in_hdr ih; /* NB: every struct below begins with an ih */
struct coda_open_in coda_open;
struct coda_close_in coda_close;
struct coda_ioctl_in coda_ioctl;
struct coda_getattr_in coda_getattr;
struct coda_setattr_in coda_setattr;
struct coda_access_in coda_access;
struct coda_lookup_in coda_lookup;
struct coda_create_in coda_create;
struct coda_remove_in coda_remove;
struct coda_link_in coda_link;
struct coda_rename_in coda_rename;
struct coda_mkdir_in coda_mkdir;
struct coda_rmdir_in coda_rmdir;
struct coda_readdir_in coda_readdir;
struct coda_symlink_in coda_symlink;
struct coda_readlink_in coda_readlink;
struct coda_fsync_in coda_fsync;
struct coda_vget_in coda_vget;
struct coda_open_by_fd_in coda_open_by_fd;
struct coda_open_by_path_in coda_open_by_path;
struct coda_statfs_in coda_statfs;
};
union outputArgs {
struct coda_out_hdr oh; /* NB: every struct below begins with an oh */
struct coda_root_out coda_root;
struct coda_open_out coda_open;
struct coda_ioctl_out coda_ioctl;
struct coda_getattr_out coda_getattr;
struct coda_lookup_out coda_lookup;
struct coda_create_out coda_create;
struct coda_mkdir_out coda_mkdir;
struct coda_readdir_out coda_readdir;
struct coda_readlink_out coda_readlink;
struct coda_vget_out coda_vget;
struct coda_purgeuser_out coda_purgeuser;
struct coda_zapfile_out coda_zapfile;
struct coda_zapdir_out coda_zapdir;
struct coda_zapvnode_out coda_zapvnode;
struct coda_purgefid_out coda_purgefid;
struct coda_replace_out coda_replace;
struct coda_open_by_fd_out coda_open_by_fd;
struct coda_open_by_path_out coda_open_by_path;
struct coda_statfs_out coda_statfs;
};
union coda_downcalls {
/* CODA_INVALIDATE is a venus->kernel call */
/* CODA_FLUSH is a venus->kernel call */
struct coda_purgeuser_out purgeuser;
struct coda_zapfile_out zapfile;
struct coda_zapdir_out zapdir;
struct coda_zapvnode_out zapvnode;
struct coda_purgefid_out purgefid;
struct coda_replace_out replace;
};
/*
* Used for identifying usage of "Control" and pioctls
*/
#define PIOCPARM_MASK 0x0000ffff
struct ViceIoctl {
caddr_t in, out; /* Data to be transferred in, or out */
short in_size; /* Size of input buffer <= 2K */
short out_size; /* Maximum size of output buffer, <= 2K */
};
#if defined(__CYGWIN32__) || defined(DJGPP)
struct PioctlData {
unsigned long cmd;
const char *path;
int follow;
struct ViceIoctl vi;
};
#else
struct PioctlData {
const char *path;
int follow;
struct ViceIoctl vi;
};
#endif
#define CODA_CONTROL ".CONTROL"
#define CODA_CONTROLLEN 8
#define CTL_INO -1
#define CTL_FILE "/coda/.CONTROL"
#ifdef CODA_COMPAT_5
#define CTL_FID { -1, -1, -1 }
#define IS_CTL_FID(fidp) ((fidp)->Volume == -1 &&\
(fidp)->Vnode == -1 &&\
(fidp)->Unique == -1)
#define INVAL_FID { 0, 0, 0 }
#else
#define CTL_FID { { -1, -1, -1, -1 } }
#define IS_CTL_FID(fidp) ((fidp)->opaque[0] == -1 &&\
(fidp)->opaque[1] == -1 &&\
(fidp)->opaque[2] == -1 &&\
(fidp)->opaque[3] == -1)
#define INVAL_FID { { 0, 0, 0, 0 } }
#endif
/* Data passed to mount */
#define CODA_MOUNT_VERSION 1
struct coda_mount_data {
int version;
int fd; /* Opened device */
};
#endif

View File

@ -1,141 +0,0 @@
/*-
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_fbsd.cr,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/ucred.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vnode_pager.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_vnops.h>
#include <coda/coda_psdev.h>
static struct cdevsw codadevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_open = vc_nb_open,
.d_close = vc_nb_close,
.d_read = vc_nb_read,
.d_write = vc_nb_write,
.d_ioctl = vc_nb_ioctl,
.d_poll = vc_nb_poll,
.d_name = "Coda",
};
static eventhandler_tag clonetag;
static LIST_HEAD(, coda_mntinfo) coda_mnttbl;
int vcdebug = 1;
#define VCDEBUG if (vcdebug) printf
/* for DEVFS, using bpf & tun drivers as examples*/
static void coda_fbsd_clone(void *arg, struct ucred *cred, char *name,
int namelen, struct cdev **dev);
static int
codadev_modevent(module_t mod, int type, void *data)
{
struct coda_mntinfo *mnt;
switch (type) {
case MOD_LOAD:
LIST_INIT(&coda_mnttbl);
clonetag = EVENTHANDLER_REGISTER(dev_clone, coda_fbsd_clone,
0, 1000);
break;
case MOD_UNLOAD:
EVENTHANDLER_DEREGISTER(dev_clone, clonetag);
while ((mnt = LIST_FIRST(&coda_mnttbl)) != NULL) {
LIST_REMOVE(mnt, mi_list);
destroy_dev(mnt->dev);
free(mnt, M_CODA);
}
break;
default:
return (EOPNOTSUPP);
}
return 0;
}
static moduledata_t codadev_mod = {
"codadev",
codadev_modevent,
NULL
};
DECLARE_MODULE(codadev, codadev_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
static void coda_fbsd_clone(arg, cred, name, namelen, dev)
void *arg;
struct ucred *cred;
char *name;
int namelen;
struct cdev **dev;
{
int u;
struct coda_mntinfo *mnt;
if (*dev != NULL)
return;
if (dev_stdclone(name,NULL,"cfs",&u) != 1)
return;
*dev = make_dev(&codadevsw,unit2minor(u),UID_ROOT,GID_WHEEL,0600,"cfs%d",u);
dev_ref(*dev);
mnt = malloc(sizeof(struct coda_mntinfo), M_CODA, M_WAITOK|M_ZERO);
LIST_INSERT_HEAD(&coda_mnttbl, mnt, mi_list);
mnt->dev = *dev;
}
struct coda_mntinfo *
dev2coda_mntinfo(struct cdev *dev)
{
struct coda_mntinfo *mnt;
LIST_FOREACH(mnt, &coda_mnttbl, mi_list) {
if (mnt->dev == dev)
return mnt;
}
return NULL;
}

View File

@ -1,59 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_io.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*-
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon University.
* Contributers include David Steere, James Kistler, and M. Satyanarayanan.
*/
#ifndef _CODAIO_H_
#define _CODAIO_H_
/* Define ioctl commands for vcioctl, /dev/cfs */
#define CODARESIZE _IOW('c', 1, struct coda_resize ) /* Resize CODA NameCache */
#define CODASTATS _IO('c', 2) /* Collect stats */
#define CODAPRINT _IO('c', 3) /* Print Cache */
#define CODATEST _IO('c', 4) /* Print Cache */
struct coda_resize { int hashsize, heapsize; };
#endif

View File

@ -1,66 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_kernel.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/* Macros to manipulate the queue */
#ifndef INIT_QUEUE
struct queue {
struct queue *forw, *back;
};
#define INIT_QUEUE(head) \
do { \
(head).forw = (struct queue *)&(head); \
(head).back = (struct queue *)&(head); \
} while (0)
#define GETNEXT(head) (head).forw
#define EMPTY(head) ((head).forw == &(head))
#define EOQ(el, head) ((struct queue *)(el) == (struct queue *)&(head))
#define INSQUE(el, head) \
do { \
(el).forw = ((head).back)->forw; \
(el).back = (head).back; \
((head).back)->forw = (struct queue *)&(el); \
(head).back = (struct queue *)&(el); \
} while (0)
#define REMQUE(el) \
do { \
((el).forw)->back = (el).back; \
(el).back->forw = (el).forw; \
} while (0)
#endif

View File

@ -1,758 +0,0 @@
/*-
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_namecache.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*/
/*-
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon University.
* Contributers include David Steere, James Kistler, and M. Satyanarayanan.
*/
/*
* This module contains the routines to implement the CODA name cache. The
* purpose of this cache is to reduce the cost of translating pathnames
* into Vice FIDs. Each entry in the cache contains the name of the file,
* the vnode (FID) of the parent directory, and the cred structure of the
* user accessing the file.
*
* The first time a file is accessed, it is looked up by the local Venus
* which first insures that the user has access to the file. In addition
* we are guaranteed that Venus will invalidate any name cache entries in
* case the user no longer should be able to access the file. For these
* reasons we do not need to keep access list information as well as a
* cred structure for each entry.
*
* The table can be accessed through the routines cnc_init(), cnc_enter(),
* cnc_lookup(), cnc_rmfidcred(), cnc_rmfid(), cnc_rmcred(), and cnc_purge().
* There are several other routines which aid in the implementation of the
* hash table.
*/
/*
* NOTES: rvb@cs
* 1. The name cache holds a reference to every vnode in it. Hence files can not be
* closed or made inactive until they are released.
* 2. coda_nc_name(cp) was added to get a name for a cnode pointer for debugging.
* 3. coda_nc_find() has debug code to detect when entries are stored with different
* credentials. We don't understand yet, if/how entries are NOT EQ but still
* EQUAL
* 4. I wonder if this name cache could be replace by the vnode name cache.
* The latter has no zapping functions, so probably not.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/ucred.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_namecache.h>
#ifdef DEBUG
#include <coda/coda_vnops.h>
#endif
/*
* Declaration of the name cache data structure.
*/
int coda_nc_use = 1; /* Indicate use of CODA Name Cache */
int coda_nc_size = CODA_NC_CACHESIZE; /* size of the cache */
int coda_nc_hashsize = CODA_NC_HASHSIZE; /* size of the primary hash */
struct coda_cache *coda_nc_heap; /* pointer to the cache entries */
struct coda_hash *coda_nc_hash; /* hash table of coda_cache pointers */
struct coda_lru coda_nc_lru; /* head of lru chain */
struct coda_nc_statistics coda_nc_stat; /* Keep various stats */
/*
* for testing purposes
*/
int coda_nc_debug = 0;
/*
* Entry points for the CODA Name Cache
*/
static struct coda_cache *coda_nc_find(struct cnode *dcp, const char *name, int namelen,
struct ucred *cred, int hash);
static void coda_nc_remove(struct coda_cache *cncp, enum dc_status dcstat);
/*
* Initialize the cache, the LRU structure and the Hash structure(s)
*/
#define TOTAL_CACHE_SIZE (sizeof(struct coda_cache) * coda_nc_size)
#define TOTAL_HASH_SIZE (sizeof(struct coda_hash) * coda_nc_hashsize)
int coda_nc_initialized = 0; /* Initially the cache has not been initialized */
void
coda_nc_init(void)
{
int i;
/* zero the statistics structure */
bzero(&coda_nc_stat, (sizeof(struct coda_nc_statistics)));
#ifdef CODA_VERBOSE
printf("CODA NAME CACHE: CACHE %d, HASH TBL %d\n", CODA_NC_CACHESIZE, CODA_NC_HASHSIZE);
#endif
CODA_ALLOC(coda_nc_heap, struct coda_cache *, TOTAL_CACHE_SIZE);
CODA_ALLOC(coda_nc_hash, struct coda_hash *, TOTAL_HASH_SIZE);
coda_nc_lru.lru_next =
coda_nc_lru.lru_prev = (struct coda_cache *)LRU_PART(&coda_nc_lru);
for (i=0; i < coda_nc_size; i++) { /* initialize the heap */
CODA_NC_LRUINS(&coda_nc_heap[i], &coda_nc_lru);
CODA_NC_HSHNUL(&coda_nc_heap[i]);
coda_nc_heap[i].cp = coda_nc_heap[i].dcp = (struct cnode *)0;
}
for (i=0; i < coda_nc_hashsize; i++) { /* initialize the hashtable */
CODA_NC_HSHNUL((struct coda_cache *)&coda_nc_hash[i]);
}
coda_nc_initialized++;
}
/*
* Auxillary routines -- shouldn't be entry points
*/
static struct coda_cache *
coda_nc_find(dcp, name, namelen, cred, hash)
struct cnode *dcp;
const char *name;
int namelen;
struct ucred *cred;
int hash;
{
/*
* hash to find the appropriate bucket, look through the chain
* for the right entry (especially right cred, unless cred == 0)
*/
struct coda_cache *cncp;
int count = 1;
CODA_NC_DEBUG(CODA_NC_FIND,
myprintf(("coda_nc_find(dcp %p, name %s, len %d, cred %p, hash %d\n",
dcp, name, namelen, cred, hash));)
for (cncp = coda_nc_hash[hash].hash_next;
cncp != (struct coda_cache *)&coda_nc_hash[hash];
cncp = cncp->hash_next, count++)
{
if ((CODA_NAMEMATCH(cncp, name, namelen, dcp)) &&
((cred == 0) || (cncp->cred == cred)))
{
/* compare cr_uid instead */
coda_nc_stat.Search_len += count;
return(cncp);
}
#ifdef DEBUG
else if (CODA_NAMEMATCH(cncp, name, namelen, dcp)) {
printf("coda_nc_find: name %s, new cred = %p, cred = %p\n",
name, cred, cncp->cred);
printf("nref %d, nuid %d, ngid %d // oref %d, ocred %d, ogid %d\n",
cred->cr_ref, cred->cr_uid, cred->cr_gid,
cncp->cred->cr_ref, cncp->cred->cr_uid, cncp->cred->cr_gid);
print_cred(cred);
print_cred(cncp->cred);
}
#endif
}
return((struct coda_cache *)0);
}
/*
* Enter a new (dir cnode, name) pair into the cache, updating the
* LRU and Hash as needed.
*/
void
coda_nc_enter(dcp, name, namelen, cred, cp)
struct cnode *dcp;
const char *name;
int namelen;
struct ucred *cred;
struct cnode *cp;
{
struct coda_cache *cncp;
int hash;
if (coda_nc_use == 0) /* Cache is off */
return;
CODA_NC_DEBUG(CODA_NC_ENTER,
myprintf(("Enter: dcp %p cp %p name %s cred %p \n",
dcp, cp, name, cred)); )
if (namelen > CODA_NC_NAMELEN) {
CODA_NC_DEBUG(CODA_NC_ENTER,
myprintf(("long name enter %s\n",name));)
coda_nc_stat.long_name_enters++; /* record stats */
return;
}
hash = CODA_NC_HASH(name, namelen, dcp);
cncp = coda_nc_find(dcp, name, namelen, cred, hash);
if (cncp != (struct coda_cache *) 0) {
coda_nc_stat.dbl_enters++; /* duplicate entry */
return;
}
coda_nc_stat.enters++; /* record the enters statistic */
/* Grab the next element in the lru chain */
cncp = CODA_NC_LRUGET(coda_nc_lru);
CODA_NC_LRUREM(cncp); /* remove it from the lists */
if (CODA_NC_VALID(cncp)) {
/* Seems really ugly, but we have to decrement the appropriate
hash bucket length here, so we have to find the hash bucket
*/
coda_nc_hash[CODA_NC_HASH(cncp->name, cncp->namelen, cncp->dcp)].length--;
coda_nc_stat.lru_rm++; /* zapped a valid entry */
CODA_NC_HSHREM(cncp);
vrele(CTOV(cncp->dcp));
vrele(CTOV(cncp->cp));
crfree(cncp->cred);
}
/*
* Put a hold on the current vnodes and fill in the cache entry.
*/
vref(CTOV(cp));
vref(CTOV(dcp));
cncp->dcp = dcp;
cncp->cp = cp;
cncp->namelen = namelen;
cncp->cred = crhold(cred);
bcopy(name, cncp->name, (unsigned)namelen);
/* Insert into the lru and hash chains. */
CODA_NC_LRUINS(cncp, &coda_nc_lru);
CODA_NC_HSHINS(cncp, &coda_nc_hash[hash]);
coda_nc_hash[hash].length++; /* Used for tuning */
CODA_NC_DEBUG(CODA_NC_PRINTCODA_NC, print_coda_nc(); )
}
/*
* Find the (dir cnode, name) pair in the cache, if it's cred
* matches the input, return it, otherwise return 0
*/
struct cnode *
coda_nc_lookup(dcp, name, namelen, cred)
struct cnode *dcp;
const char *name;
int namelen;
struct ucred *cred;
{
int hash;
struct coda_cache *cncp;
if (coda_nc_use == 0) /* Cache is off */
return((struct cnode *) 0);
if (namelen > CODA_NC_NAMELEN) {
CODA_NC_DEBUG(CODA_NC_LOOKUP,
myprintf(("long name lookup %s\n",name));)
coda_nc_stat.long_name_lookups++; /* record stats */
return((struct cnode *) 0);
}
/* Use the hash function to locate the starting point,
then the search routine to go down the list looking for
the correct cred.
*/
hash = CODA_NC_HASH(name, namelen, dcp);
cncp = coda_nc_find(dcp, name, namelen, cred, hash);
if (cncp == (struct coda_cache *) 0) {
coda_nc_stat.misses++; /* record miss */
return((struct cnode *) 0);
}
coda_nc_stat.hits++;
/* put this entry at the end of the LRU */
CODA_NC_LRUREM(cncp);
CODA_NC_LRUINS(cncp, &coda_nc_lru);
/* move it to the front of the hash chain */
/* don't need to change the hash bucket length */
CODA_NC_HSHREM(cncp);
CODA_NC_HSHINS(cncp, &coda_nc_hash[hash]);
CODA_NC_DEBUG(CODA_NC_LOOKUP,
printf("lookup: dcp %p, name %s, cred %p = cp %p\n",
dcp, name, cred, cncp->cp); )
return(cncp->cp);
}
static void
coda_nc_remove(cncp, dcstat)
struct coda_cache *cncp;
enum dc_status dcstat;
{
/*
* remove an entry -- vrele(cncp->dcp, cp), crfree(cred),
* remove it from it's hash chain, and
* place it at the head of the lru list.
*/
CODA_NC_DEBUG(CODA_NC_REMOVE,
myprintf(("coda_nc_remove %s from parent %s\n",
cncp->name, coda_f2s(&cncp->dcp->c_fid))); )
CODA_NC_HSHREM(cncp);
CODA_NC_HSHNUL(cncp); /* have it be a null chain */
if ((dcstat == IS_DOWNCALL) && (vrefcnt(CTOV(cncp->dcp)) == 1)) {
cncp->dcp->c_flags |= C_PURGING;
}
vrele(CTOV(cncp->dcp));
if ((dcstat == IS_DOWNCALL) && (vrefcnt(CTOV(cncp->cp)) == 1)) {
cncp->cp->c_flags |= C_PURGING;
}
vrele(CTOV(cncp->cp));
crfree(cncp->cred);
bzero(DATA_PART(cncp),DATA_SIZE);
/* Put the null entry just after the least-recently-used entry */
/* LRU_TOP adjusts the pointer to point to the top of the structure. */
CODA_NC_LRUREM(cncp);
CODA_NC_LRUINS(cncp, LRU_TOP(coda_nc_lru.lru_prev));
}
/*
* Remove all entries with a parent which has the input fid.
*/
void
coda_nc_zapParentfid(fid, dcstat)
CodaFid *fid;
enum dc_status dcstat;
{
/* To get to a specific fid, we might either have another hashing
function or do a sequential search through the cache for the
appropriate entries. The later may be acceptable since I don't
think callbacks or whatever Case 1 covers are frequent occurences.
*/
struct coda_cache *cncp, *ncncp;
int i;
if (coda_nc_use == 0) /* Cache is off */
return;
CODA_NC_DEBUG(CODA_NC_ZAPPFID,
myprintf(("ZapParent: fid %s\n", coda_f2s(fid))); )
coda_nc_stat.zapPfids++;
for (i = 0; i < coda_nc_hashsize; i++) {
/*
* Need to save the hash_next pointer in case we remove the
* entry. remove causes hash_next to point to itself.
*/
for (cncp = coda_nc_hash[i].hash_next;
cncp != (struct coda_cache *)&coda_nc_hash[i];
cncp = ncncp) {
ncncp = cncp->hash_next;
if (coda_fid_eq(&(cncp->dcp->c_fid), fid)) {
coda_nc_hash[i].length--; /* Used for tuning */
coda_nc_remove(cncp, dcstat);
}
}
}
}
/*
* Remove all entries which have the same fid as the input
*/
void
coda_nc_zapfid(fid, dcstat)
CodaFid *fid;
enum dc_status dcstat;
{
/* See comment for zapParentfid. This routine will be used
if attributes are being cached.
*/
struct coda_cache *cncp, *ncncp;
int i;
if (coda_nc_use == 0) /* Cache is off */
return;
CODA_NC_DEBUG(CODA_NC_ZAPFID,
myprintf(("Zapfid: fid %s\n", coda_f2s(fid))); )
coda_nc_stat.zapFids++;
for (i = 0; i < coda_nc_hashsize; i++) {
for (cncp = coda_nc_hash[i].hash_next;
cncp != (struct coda_cache *)&coda_nc_hash[i];
cncp = ncncp) {
ncncp = cncp->hash_next;
if (coda_fid_eq(&cncp->cp->c_fid, fid)) {
coda_nc_hash[i].length--; /* Used for tuning */
coda_nc_remove(cncp, dcstat);
}
}
}
}
/*
* Remove all entries which match the fid and the cred
*/
void
coda_nc_zapvnode(fid, cred, dcstat)
CodaFid *fid;
struct ucred *cred;
enum dc_status dcstat;
{
/* See comment for zapfid. I don't think that one would ever
want to zap a file with a specific cred from the kernel.
We'll leave this one unimplemented.
*/
if (coda_nc_use == 0) /* Cache is off */
return;
CODA_NC_DEBUG(CODA_NC_ZAPVNODE,
myprintf(("Zapvnode: fid %s cred %p\n",
coda_f2s(fid), cred)); )
}
/*
* Remove all entries which have the (dir vnode, name) pair
*/
void
coda_nc_zapfile(dcp, name, namelen)
struct cnode *dcp;
const char *name;
int namelen;
{
/* use the hash function to locate the file, then zap all
entries of it regardless of the cred.
*/
struct coda_cache *cncp;
int hash;
if (coda_nc_use == 0) /* Cache is off */
return;
CODA_NC_DEBUG(CODA_NC_ZAPFILE,
myprintf(("Zapfile: dcp %p name %s \n",
dcp, name)); )
if (namelen > CODA_NC_NAMELEN) {
coda_nc_stat.long_remove++; /* record stats */
return;
}
coda_nc_stat.zapFile++;
hash = CODA_NC_HASH(name, namelen, dcp);
cncp = coda_nc_find(dcp, name, namelen, 0, hash);
while (cncp) {
coda_nc_hash[hash].length--; /* Used for tuning */
coda_nc_remove(cncp, NOT_DOWNCALL);
cncp = coda_nc_find(dcp, name, namelen, 0, hash);
}
}
/*
* Remove all the entries for a particular user. Used when tokens expire.
* A user is determined by his/her effective user id (id_uid).
*/
void
coda_nc_purge_user(uid, dcstat)
uid_t uid;
enum dc_status dcstat;
{
/*
* I think the best approach is to go through the entire cache
* via HASH or whatever and zap all entries which match the
* input cred. Or just flush the whole cache. It might be
* best to go through on basis of LRU since cache will almost
* always be full and LRU is more straightforward.
*/
struct coda_cache *cncp, *ncncp;
int hash;
if (coda_nc_use == 0) /* Cache is off */
return;
CODA_NC_DEBUG(CODA_NC_PURGEUSER,
myprintf(("ZapDude: uid %x\n", uid)); )
coda_nc_stat.zapUsers++;
for (cncp = CODA_NC_LRUGET(coda_nc_lru);
cncp != (struct coda_cache *)(&coda_nc_lru);
cncp = ncncp) {
ncncp = CODA_NC_LRUGET(*cncp);
if ((CODA_NC_VALID(cncp)) &&
((cncp->cred)->cr_uid == uid)) {
/* Seems really ugly, but we have to decrement the appropriate
hash bucket length here, so we have to find the hash bucket
*/
hash = CODA_NC_HASH(cncp->name, cncp->namelen, cncp->dcp);
coda_nc_hash[hash].length--; /* For performance tuning */
coda_nc_remove(cncp, dcstat);
}
}
}
/*
* Flush the entire name cache. In response to a flush of the Venus cache.
*/
void
coda_nc_flush(dcstat)
enum dc_status dcstat;
{
/* One option is to deallocate the current name cache and
call init to start again. Or just deallocate, then rebuild.
Or again, we could just go through the array and zero the
appropriate fields.
*/
/*
* Go through the whole lru chain and kill everything as we go.
* I don't use remove since that would rebuild the lru chain
* as it went and that seemed unneccesary.
*/
struct coda_cache *cncp;
int i;
if (coda_nc_use == 0) /* Cache is off */
return;
coda_nc_stat.Flushes++;
for (cncp = CODA_NC_LRUGET(coda_nc_lru);
cncp != (struct coda_cache *)&coda_nc_lru;
cncp = CODA_NC_LRUGET(*cncp)) {
if (CODA_NC_VALID(cncp)) {
CODA_NC_HSHREM(cncp); /* only zero valid nodes */
CODA_NC_HSHNUL(cncp);
if ((dcstat == IS_DOWNCALL)
&& (vrefcnt(CTOV(cncp->dcp)) == 1))
{
cncp->dcp->c_flags |= C_PURGING;
}
vrele(CTOV(cncp->dcp));
ASSERT_VOP_LOCKED(CTOV(cncp->cp), "coda_nc_flush");
if (CTOV(cncp->cp)->v_vflag & VV_TEXT) {
if (coda_vmflush(cncp->cp))
CODADEBUG(CODA_FLUSH,
myprintf(("coda_nc_flush: %s busy\n",
coda_f2s(&cncp->cp->c_fid))); )
}
if ((dcstat == IS_DOWNCALL)
&& (vrefcnt(CTOV(cncp->cp)) == 1))
{
cncp->cp->c_flags |= C_PURGING;
}
vrele(CTOV(cncp->cp));
crfree(cncp->cred);
bzero(DATA_PART(cncp),DATA_SIZE);
}
}
for (i = 0; i < coda_nc_hashsize; i++)
coda_nc_hash[i].length = 0;
}
/*
* Debugging routines
*/
/*
* This routine should print out all the hash chains to the console.
*/
void
print_coda_nc(void)
{
int hash;
struct coda_cache *cncp;
for (hash = 0; hash < coda_nc_hashsize; hash++) {
myprintf(("\nhash %d\n",hash));
for (cncp = coda_nc_hash[hash].hash_next;
cncp != (struct coda_cache *)&coda_nc_hash[hash];
cncp = cncp->hash_next) {
myprintf(("cp %p dcp %p cred %p name %s\n",
cncp->cp, cncp->dcp,
cncp->cred, cncp->name));
}
}
}
void
coda_nc_gather_stats(void)
{
int i, max = 0, sum = 0, temp, zeros = 0, ave, n;
for (i = 0; i < coda_nc_hashsize; i++) {
if (coda_nc_hash[i].length) {
sum += coda_nc_hash[i].length;
} else {
zeros++;
}
if (coda_nc_hash[i].length > max)
max = coda_nc_hash[i].length;
}
/*
* When computing the Arithmetic mean, only count slots which
* are not empty in the distribution.
*/
coda_nc_stat.Sum_bucket_len = sum;
coda_nc_stat.Num_zero_len = zeros;
coda_nc_stat.Max_bucket_len = max;
if ((n = coda_nc_hashsize - zeros) > 0)
ave = sum / n;
else
ave = 0;
sum = 0;
for (i = 0; i < coda_nc_hashsize; i++) {
if (coda_nc_hash[i].length) {
temp = coda_nc_hash[i].length - ave;
sum += temp * temp;
}
}
coda_nc_stat.Sum2_bucket_len = sum;
}
/*
* The purpose of this routine is to allow the hash and cache sizes to be
* changed dynamically. This should only be used in controlled environments,
* it makes no effort to lock other users from accessing the cache while it
* is in an improper state (except by turning the cache off).
*/
int
coda_nc_resize(hashsize, heapsize, dcstat)
int hashsize, heapsize;
enum dc_status dcstat;
{
if ((hashsize % 2) || (heapsize % 2)) { /* Illegal hash or cache sizes */
return(EINVAL);
}
coda_nc_use = 0; /* Turn the cache off */
coda_nc_flush(dcstat); /* free any cnodes in the cache */
/* WARNING: free must happen *before* size is reset */
CODA_FREE(coda_nc_heap,TOTAL_CACHE_SIZE);
CODA_FREE(coda_nc_hash,TOTAL_HASH_SIZE);
coda_nc_hashsize = hashsize;
coda_nc_size = heapsize;
coda_nc_init(); /* Set up a cache with the new size */
coda_nc_use = 1; /* Turn the cache back on */
return(0);
}
#ifdef DEBUG
char coda_nc_name_buf[CODA_MAXNAMLEN+1];
void
coda_nc_name(struct cnode *cp)
{
struct coda_cache *cncp, *ncncp;
int i;
if (coda_nc_use == 0) /* Cache is off */
return;
for (i = 0; i < coda_nc_hashsize; i++) {
for (cncp = coda_nc_hash[i].hash_next;
cncp != (struct coda_cache *)&coda_nc_hash[i];
cncp = ncncp) {
ncncp = cncp->hash_next;
if (cncp->cp == cp) {
bcopy(cncp->name, coda_nc_name_buf, cncp->namelen);
coda_nc_name_buf[cncp->namelen] = 0;
printf(" is %s (%p,%p)@%p",
coda_nc_name_buf, cncp->cp, cncp->dcp, cncp);
}
}
}
}
#endif

View File

@ -1,194 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_namecache.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*-
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon University.
* Contributers include David Steere, James Kistler, and M. Satyanarayanan.
*/
#ifndef _CODA_NC_HEADER_
#define _CODA_NC_HEADER_
/*
* Coda constants
*/
#define CODA_NC_NAMELEN 15 /* longest name stored in cache */
#define CODA_NC_CACHESIZE 256 /* Default cache size */
#define CODA_NC_HASHSIZE 64 /* Must be multiple of 2 */
/*
* Hash function for the primary hash.
*/
/*
* First try -- (first + last letters + length + (int)cp) mod size
* 2nd try -- same, except dir fid.vnode instead of cp
*/
#ifdef oldhash
#define CODA_NC_HASH(name, namelen, cp) \
((name[0] + name[namelen-1] + namelen + (int)(intptr_t)(cp)) & (coda_nc_hashsize-1))
#else
#define CODA_NC_HASH(name, namelen, cp) \
((name[0] + (name[namelen-1]<<4) + namelen + (((int)(intptr_t)cp)>>8)) & (coda_nc_hashsize-1))
#endif
#define CODA_NAMEMATCH(cp, name, namelen, dcp) \
((namelen == cp->namelen) && (dcp == cp->dcp) && \
(bcmp(cp->name,name,namelen) == 0))
/*
* Functions to modify the hash and lru chains.
* insque and remque assume that the pointers are the first thing
* in the list node, thus the trickery for lru.
*/
#define CODA_NC_HSHINS(elem, pred) insque(elem,pred)
#define CODA_NC_HSHREM(elem) remque(elem)
#define CODA_NC_HSHNUL(elem) (elem)->hash_next = \
(elem)->hash_prev = (elem)
#define CODA_NC_LRUINS(elem, pred) insque(LRU_PART(elem), LRU_PART(pred))
#define CODA_NC_LRUREM(elem) remque(LRU_PART(elem));
#define CODA_NC_LRUGET(lruhead) LRU_TOP((lruhead).lru_prev)
#define CODA_NC_VALID(cncp) (cncp->dcp != (struct cnode *)0)
#define LRU_PART(cncp) (struct coda_cache *) \
((char *)cncp + (2*sizeof(struct coda_cache *)))
#define LRU_TOP(cncp) (struct coda_cache *) \
((char *)cncp - (2*sizeof(struct coda_cache *)))
#define DATA_PART(cncp) (struct coda_cache *) \
((char *)cncp + (4*sizeof(struct coda_cache *)))
#define DATA_SIZE (sizeof(struct coda_cache)-(4*sizeof(struct coda_cache *)))
/*
* Structure for an element in the CODA Name Cache.
* NOTE: I use the position of arguments and their size in the
* implementation of the functions CODA_NC_LRUINS, CODA_NC_LRUREM, and
* DATA_PART.
*/
struct coda_cache {
struct coda_cache *hash_next,*hash_prev; /* Hash list */
struct coda_cache *lru_next, *lru_prev; /* LRU list */
struct cnode *cp; /* vnode of the file */
struct cnode *dcp; /* parent's cnode */
struct ucred *cred; /* user credentials */
char name[CODA_NC_NAMELEN]; /* segment name */
int namelen; /* length of name */
};
struct coda_lru { /* Start of LRU chain */
char *dummy1, *dummy2; /* place holders */
struct coda_cache *lru_next, *lru_prev; /* position of pointers is important */
};
struct coda_hash { /* Start of Hash chain */
struct coda_cache *hash_next, *hash_prev; /* NOTE: chain pointers must be first */
int length; /* used for tuning purposes */
};
/*
* Symbols to aid in debugging the namecache code. Assumes the existence
* of the variable coda_nc_debug, which is defined in cfs_namecache.c
*/
#define CODA_NC_DEBUG(N, STMT) { if (coda_nc_debug & (1 <<N)) { STMT } }
/* Prototypes of functions exported within cfs */
extern void coda_nc_init(void);
extern void coda_nc_enter(struct cnode *, const char *, int, struct ucred *, struct cnode *);
extern struct cnode *coda_nc_lookup(struct cnode *, const char *, int, struct ucred *);
extern void coda_nc_zapParentfid(CodaFid *, enum dc_status);
extern void coda_nc_zapfid(CodaFid *, enum dc_status);
extern void coda_nc_zapvnode(CodaFid *, struct ucred *, enum dc_status);
extern void coda_nc_zapfile(struct cnode *, const char *, int);
extern void coda_nc_purge_user(uid_t, enum dc_status);
extern void coda_nc_flush(enum dc_status);
extern void print_coda_nc(void);
extern void coda_nc_gather_stats(void);
extern int coda_nc_resize(int, int, enum dc_status);
extern void coda_nc_name(struct cnode *cp);
/*
* Structure to contain statistics on the cache usage
*/
struct coda_nc_statistics {
unsigned hits;
unsigned misses;
unsigned enters;
unsigned dbl_enters;
unsigned long_name_enters;
unsigned long_name_lookups;
unsigned long_remove;
unsigned lru_rm;
unsigned zapPfids;
unsigned zapFids;
unsigned zapFile;
unsigned zapUsers;
unsigned Flushes;
unsigned Sum_bucket_len;
unsigned Sum2_bucket_len;
unsigned Max_bucket_len;
unsigned Num_zero_len;
unsigned Search_len;
};
#define CODA_NC_FIND ((u_long) 1)
#define CODA_NC_REMOVE ((u_long) 2)
#define CODA_NC_INIT ((u_long) 3)
#define CODA_NC_ENTER ((u_long) 4)
#define CODA_NC_LOOKUP ((u_long) 5)
#define CODA_NC_ZAPPFID ((u_long) 6)
#define CODA_NC_ZAPFID ((u_long) 7)
#define CODA_NC_ZAPVNODE ((u_long) 8)
#define CODA_NC_ZAPFILE ((u_long) 9)
#define CODA_NC_PURGEUSER ((u_long) 10)
#define CODA_NC_FLUSH ((u_long) 11)
#define CODA_NC_PRINTCODA_NC ((u_long) 12)
#define CODA_NC_PRINTSTATS ((u_long) 13)
#endif

View File

@ -1,127 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_opstats.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*
* operation stats: what the minicache can intercept that
* *isn't* seen by venus. These stats are kept to augment
* the stats maintained by the Volume-Session mechanism.
*/
/* vfsops:
* mount: not currently bounced to Venus
* umount: nope
* root: only first call, rest is cached.
* statfs: none (bogus)
* sync: none (bogus)
* vget: all
*/
#define CODA_MOUNT_STATS 0
#define CODA_UMOUNT_STATS 1
#define CODA_ROOT_STATS 2
#define CODA_STATFS_STATS 3
#define CODA_SYNC_STATS 4
#define CODA_VGET_STATS 5
#define CODA_VFSOPS_SIZE 6
/* vnodeops:
* open: all to venus
* close: all to venus
* rdrw: bogus. Maybe redirected to UFS.
* May call open/close for internal opens/closes
* (Does exec not call open?)
* ioctl: causes a lookupname
* passes through
* select: can't get there from here.
* getattr: can be satsified by cache
* setattr: all go through
* access: can be satisfied by cache
* readlink: can be satisfied by cache
* fsync: passes through
* inactive: passes through
* lookup: can be satisfied by cache
* create: passes through
* remove: passes through
* link: passes through
* rename: passes through
* mkdir: passes through
* rmdir: passes through
* symlink: passes through
* readdir: may be redirected to UFS
* may cause an "internal" open/close
*/
#define CODA_OPEN_STATS 0
#define CODA_CLOSE_STATS 1
#define CODA_RDWR_STATS 2
#define CODA_IOCTL_STATS 3
#define CODA_SELECT_STATS 4
#define CODA_GETATTR_STATS 5
#define CODA_SETATTR_STATS 6
#define CODA_ACCESS_STATS 7
#define CODA_READLINK_STATS 8
#define CODA_FSYNC_STATS 9
#define CODA_INACTIVE_STATS 10
#define CODA_LOOKUP_STATS 11
#define CODA_CREATE_STATS 12
#define CODA_REMOVE_STATS 13
#define CODA_LINK_STATS 14
#define CODA_RENAME_STATS 15
#define CODA_MKDIR_STATS 16
#define CODA_RMDIR_STATS 17
#define CODA_SYMLINK_STATS 18
#define CODA_READDIR_STATS 19
#define CODA_VNODEOPS_SIZE 20
/*
* I propose the following structres:
*/
struct coda_op_stats {
int opcode; /* vfs opcode */
long entries; /* number of times call attempted */
long sat_intrn; /* number of times call satisfied by cache */
long unsat_intrn; /* number of times call failed in cache, but
was not bounced to venus proper. */
long gen_intrn; /* number of times call generated internally */
/* (do we need that?) */
};
/*
* With each call to the minicache, we'll bump the counters whenver
* a call is satisfied internally (through the cache or through a
* redirect), and whenever an operation is caused internally.
* Then, we can add the total operations caught by the minicache
* to the world-wide totals, and leave a caveat for the specific
* graphs later.
*/

View File

@ -1,70 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_pioctl.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*-
* Mach Operating System
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* ITC Remote filesystem - vice ioctl interface module
*/
/*
* TODO: Find /usr/local/include/viceioctl.h.
*/
#ifndef _SYS_PIOCTL_H_
#define _SYS_PIOCTL_H_
/* The 2K limits above are a consequence of the size of the kernel buffer
used to buffer requests from the user to venus--2*MAXPATHLEN.
The buffer pointers may be null, or the counts may be 0 if there
are no input or output parameters
*/
#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
/* Use this macro to define up to 256 vice ioctl's. These ioctl's
all potentially have in/out parameters--this depends upon the
values in the ViceIoctl structure. This structure is itself passed
into the kernel by the normal ioctl parameter passing mechanism.
*/
#define _VALIDVICEIOCTL(com) (com >= _VICEIOCTL(0) && com <= _VICEIOCTL(255))
#endif

View File

@ -1,695 +0,0 @@
/*-
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*/
/*-
* Mach Operating System
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon
* University. Contributers include David Steere, James Kistler, and
* M. Satyanarayanan. */
/*
* These routines define the psuedo device for communication between
* Coda's Venus and Minicache in Mach 2.6. They used to be in cfs_subr.c,
* but I moved them to make it easier to port the Minicache without
* porting coda. -- DCS 10/12/94
*/
/* These routines are the device entry points for Venus. */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
extern int coda_nc_initialized; /* Set if cache has been initialized */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/file.h> /* must come after sys/malloc.h */
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/poll.h>
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_namecache.h>
#include <coda/coda_io.h>
#include <coda/coda_psdev.h>
#define CTL_C
#ifdef CTL_C
#include <sys/signalvar.h>
#endif
int coda_psdev_print_entry = 0;
static
int outstanding_upcalls = 0;
int coda_call_sleep = PZERO - 1;
#ifdef CTL_C
int coda_pcatch = PCATCH;
#else
#endif
#define ENTRY if(coda_psdev_print_entry) myprintf(("Entered %s\n",__func__))
void vcodaattach(int n);
struct vmsg {
struct queue vm_chain;
caddr_t vm_data;
u_short vm_flags;
u_short vm_inSize; /* Size is at most 5000 bytes */
u_short vm_outSize;
u_short vm_opcode; /* copied from data to save ptr lookup */
int vm_unique;
caddr_t vm_sleep; /* Not used by Mach. */
};
#define VM_READ 1
#define VM_WRITE 2
#define VM_INTR 4
/* vcodaattach: do nothing */
void
vcodaattach(n)
int n;
{
}
int
vc_nb_open(dev, flag, mode, td)
struct cdev *dev;
int flag;
int mode;
struct thread *td; /* NetBSD only */
{
struct vcomm *vcp;
struct coda_mntinfo *mnt;
ENTRY;
if (!coda_nc_initialized)
coda_nc_init();
mnt = dev2coda_mntinfo(dev);
KASSERT(mnt, ("Coda: tried to open uninitialized cfs device"));
vcp = &mnt->mi_vcomm;
if (VC_OPEN(vcp))
return(EBUSY);
bzero(&(vcp->vc_selproc), sizeof (struct selinfo));
INIT_QUEUE(vcp->vc_requests);
INIT_QUEUE(vcp->vc_replys);
MARK_VC_OPEN(vcp);
mnt->mi_vfsp = NULL;
mnt->mi_rootvp = NULL;
return(0);
}
int
vc_nb_close (dev, flag, mode, td)
struct cdev *dev;
int flag;
int mode;
struct thread *td;
{
register struct vcomm *vcp;
register struct vmsg *vmp, *nvmp = NULL;
struct coda_mntinfo *mi;
int err;
ENTRY;
mi = dev2coda_mntinfo(dev);
KASSERT(mi, ("Coda: closing unknown cfs device"));
vcp = &mi->mi_vcomm;
KASSERT(VC_OPEN(vcp), ("Coda: closing unopened cfs device"));
/* prevent future operations on this vfs from succeeding by auto-
* unmounting any vfs mounted via this device. This frees user or
* sysadm from having to remember where all mount points are located.
* Put this before WAKEUPs to avoid queuing new messages between
* the WAKEUP and the unmount (which can happen if we're unlucky)
*/
if (!mi->mi_rootvp) {
/* just a simple open/close w no mount */
MARK_VC_CLOSED(vcp);
return 0;
}
/* Let unmount know this is for real */
VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING;
coda_unmounting(mi->mi_vfsp);
outstanding_upcalls = 0;
/* Wakeup clients so they can return. */
for (vmp = (struct vmsg *)GETNEXT(vcp->vc_requests);
!EOQ(vmp, vcp->vc_requests);
vmp = nvmp)
{
nvmp = (struct vmsg *)GETNEXT(vmp->vm_chain);
/* Free signal request messages and don't wakeup cause
no one is waiting. */
if (vmp->vm_opcode == CODA_SIGNAL) {
CODA_FREE((caddr_t)vmp->vm_data, (u_int)VC_IN_NO_DATA);
CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg));
continue;
}
outstanding_upcalls++;
wakeup(&vmp->vm_sleep);
}
for (vmp = (struct vmsg *)GETNEXT(vcp->vc_replys);
!EOQ(vmp, vcp->vc_replys);
vmp = (struct vmsg *)GETNEXT(vmp->vm_chain))
{
outstanding_upcalls++;
wakeup(&vmp->vm_sleep);
}
MARK_VC_CLOSED(vcp);
if (outstanding_upcalls) {
#ifdef CODA_VERBOSE
printf("presleep: outstanding_upcalls = %d\n", outstanding_upcalls);
(void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0);
printf("postsleep: outstanding_upcalls = %d\n", outstanding_upcalls);
#else
(void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0);
#endif
}
err = dounmount(mi->mi_vfsp, flag, td);
if (err)
myprintf(("Error %d unmounting vfs in vcclose(%s)\n",
err, devtoname(dev)));
return 0;
}
int
vc_nb_read(dev, uiop, flag)
struct cdev *dev;
struct uio *uiop;
int flag;
{
register struct vcomm * vcp;
register struct vmsg *vmp;
int error = 0;
ENTRY;
vcp = &dev2coda_mntinfo(dev)->mi_vcomm;
/* Get message at head of request queue. */
if (EMPTY(vcp->vc_requests))
return(0); /* Nothing to read */
vmp = (struct vmsg *)GETNEXT(vcp->vc_requests);
/* Move the input args into userspace */
uiop->uio_rw = UIO_READ;
error = uiomove(vmp->vm_data, vmp->vm_inSize, uiop);
if (error) {
myprintf(("vcread: error (%d) on uiomove\n", error));
error = EINVAL;
}
#ifdef OLD_DIAGNOSTIC
if (vmp->vm_chain.forw == 0 || vmp->vm_chain.back == 0)
panic("vc_nb_read: bad chain");
#endif
REMQUE(vmp->vm_chain);
/* If request was a signal, free up the message and don't
enqueue it in the reply queue. */
if (vmp->vm_opcode == CODA_SIGNAL) {
if (codadebug)
myprintf(("vcread: signal msg (%d, %d)\n",
vmp->vm_opcode, vmp->vm_unique));
CODA_FREE((caddr_t)vmp->vm_data, (u_int)VC_IN_NO_DATA);
CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg));
return(error);
}
vmp->vm_flags |= VM_READ;
INSQUE(vmp->vm_chain, vcp->vc_replys);
return(error);
}
int
vc_nb_write(dev, uiop, flag)
struct cdev *dev;
struct uio *uiop;
int flag;
{
register struct vcomm * vcp;
register struct vmsg *vmp;
struct coda_out_hdr *out;
u_long seq;
u_long opcode;
int buf[2];
int error = 0;
ENTRY;
vcp = &dev2coda_mntinfo(dev)->mi_vcomm;
/* Peek at the opcode, unique without transfering the data. */
uiop->uio_rw = UIO_WRITE;
error = uiomove((caddr_t)buf, sizeof(int) * 2, uiop);
if (error) {
myprintf(("vcwrite: error (%d) on uiomove\n", error));
return(EINVAL);
}
opcode = buf[0];
seq = buf[1];
if (codadebug)
myprintf(("vcwrite got a call for %ld.%ld\n", opcode, seq));
if (DOWNCALL(opcode)) {
union outputArgs pbuf;
/* get the rest of the data. */
uiop->uio_rw = UIO_WRITE;
error = uiomove((caddr_t)&pbuf.coda_purgeuser.oh.result, sizeof(pbuf) - (sizeof(int)*2), uiop);
if (error) {
myprintf(("vcwrite: error (%d) on uiomove (Op %ld seq %ld)\n",
error, opcode, seq));
return(EINVAL);
}
return handleDownCall(opcode, &pbuf);
}
/* Look for the message on the (waiting for) reply queue. */
for (vmp = (struct vmsg *)GETNEXT(vcp->vc_replys);
!EOQ(vmp, vcp->vc_replys);
vmp = (struct vmsg *)GETNEXT(vmp->vm_chain))
{
if (vmp->vm_unique == seq) break;
}
if (EOQ(vmp, vcp->vc_replys)) {
if (codadebug)
myprintf(("vcwrite: msg (%ld, %ld) not found\n", opcode, seq));
return(ESRCH);
}
/* Remove the message from the reply queue */
REMQUE(vmp->vm_chain);
/* move data into response buffer. */
out = (struct coda_out_hdr *)vmp->vm_data;
/* Don't need to copy opcode and uniquifier. */
/* get the rest of the data. */
if (vmp->vm_outSize < uiop->uio_resid) {
myprintf(("vcwrite: more data than asked for (%d < %d)\n",
vmp->vm_outSize, uiop->uio_resid));
wakeup(&vmp->vm_sleep); /* Notify caller of the error. */
return(EINVAL);
}
buf[0] = uiop->uio_resid; /* Save this value. */
uiop->uio_rw = UIO_WRITE;
error = uiomove((caddr_t) &out->result, vmp->vm_outSize - (sizeof(int) * 2), uiop);
if (error) {
myprintf(("vcwrite: error (%d) on uiomove (op %ld seq %ld)\n",
error, opcode, seq));
return(EINVAL);
}
/* I don't think these are used, but just in case. */
/* XXX - aren't these two already correct? -bnoble */
out->opcode = opcode;
out->unique = seq;
vmp->vm_outSize = buf[0]; /* Amount of data transferred? */
vmp->vm_flags |= VM_WRITE;
error = 0;
if (opcode == CODA_OPEN_BY_FD) {
struct coda_open_by_fd_out *tmp = (struct coda_open_by_fd_out *)out;
struct file *fp;
struct vnode *vp = NULL;
if (tmp->oh.result == 0) {
error = getvnode(uiop->uio_td->td_proc->p_fd, tmp->fd, &fp);
if (!error) {
mtx_lock(&Giant);
vp = fp->f_vnode;
VREF(vp);
fdrop(fp, uiop->uio_td);
mtx_unlock(&Giant);
}
}
tmp->vp = vp;
}
wakeup(&vmp->vm_sleep);
return(error);
}
int
vc_nb_ioctl(dev, cmd, addr, flag, td)
struct cdev *dev;
u_long cmd;
caddr_t addr;
int flag;
struct thread *td;
{
ENTRY;
switch(cmd) {
case CODARESIZE: {
struct coda_resize *data = (struct coda_resize *)addr;
return(coda_nc_resize(data->hashsize, data->heapsize, IS_DOWNCALL));
break;
}
case CODASTATS:
if (coda_nc_use) {
coda_nc_gather_stats();
return(0);
} else {
return(ENODEV);
}
break;
case CODAPRINT:
if (coda_nc_use) {
print_coda_nc();
return(0);
} else {
return(ENODEV);
}
break;
case CIOC_KERNEL_VERSION:
switch (*(u_int *)addr) {
case 0:
*(u_int *)addr = coda_kernel_version;
return 0;
break;
case 1:
case 2:
if (coda_kernel_version != *(u_int *)addr)
return ENOENT;
else
return 0;
default:
return ENOENT;
}
break;
default :
return(EINVAL);
break;
}
}
int
vc_nb_poll(dev, events, td)
struct cdev *dev;
int events;
struct thread *td;
{
register struct vcomm *vcp;
int event_msk = 0;
ENTRY;
vcp = &dev2coda_mntinfo(dev)->mi_vcomm;
event_msk = events & (POLLIN|POLLRDNORM);
if (!event_msk)
return(0);
if (!EMPTY(vcp->vc_requests))
return(events & (POLLIN|POLLRDNORM));
selrecord(td, &(vcp->vc_selproc));
return(0);
}
/*
* Statistics
*/
struct coda_clstat coda_clstat;
/*
* Key question: whether to sleep interuptably or uninteruptably when
* waiting for Venus. The former seems better (cause you can ^C a
* job), but then GNU-EMACS completion breaks. Use tsleep with no
* timeout, and no longjmp happens. But, when sleeping
* "uninterruptibly", we don't get told if it returns abnormally
* (e.g. kill -9).
*/
int
coda_call(mntinfo, inSize, outSize, buffer)
struct coda_mntinfo *mntinfo; int inSize; int *outSize; caddr_t buffer;
{
struct vcomm *vcp;
struct vmsg *vmp;
int error;
#ifdef CTL_C
struct thread *td = curthread;
struct proc *p = td->td_proc;
sigset_t psig_omask;
sigset_t tempset;
int i;
#endif
if (mntinfo == NULL) {
/* Unlikely, but could be a race condition with a dying warden */
return ENODEV;
}
vcp = &(mntinfo->mi_vcomm);
coda_clstat.ncalls++;
coda_clstat.reqs[((struct coda_in_hdr *)buffer)->opcode]++;
if (!VC_OPEN(vcp))
return(ENODEV);
CODA_ALLOC(vmp,struct vmsg *,sizeof(struct vmsg));
/* Format the request message. */
vmp->vm_data = buffer;
vmp->vm_flags = 0;
vmp->vm_inSize = inSize;
vmp->vm_outSize
= *outSize ? *outSize : inSize; /* |buffer| >= inSize */
vmp->vm_opcode = ((struct coda_in_hdr *)buffer)->opcode;
vmp->vm_unique = ++vcp->vc_seq;
if (codadebug)
myprintf(("Doing a call for %d.%d\n",
vmp->vm_opcode, vmp->vm_unique));
/* Fill in the common input args. */
((struct coda_in_hdr *)buffer)->unique = vmp->vm_unique;
/* Append msg to request queue and poke Venus. */
INSQUE(vmp->vm_chain, vcp->vc_requests);
selwakeuppri(&(vcp->vc_selproc), coda_call_sleep);
/* We can be interrupted while we wait for Venus to process
* our request. If the interrupt occurs before Venus has read
* the request, we dequeue and return. If it occurs after the
* read but before the reply, we dequeue, send a signal
* message, and return. If it occurs after the reply we ignore
* it. In no case do we want to restart the syscall. If it
* was interrupted by a venus shutdown (vcclose), return
* ENODEV. */
/* Ignore return, We have to check anyway */
#ifdef CTL_C
/* This is work in progress. Setting coda_pcatch lets tsleep reawaken
on a ^c or ^z. The problem is that emacs sets certain interrupts
as SA_RESTART. This means that we should exit sleep handle the
"signal" and then go to sleep again. Mostly this is done by letting
the syscall complete and be restarted. We are not idempotent and
can not do this. A better solution is necessary.
*/
i = 0;
PROC_LOCK(p);
psig_omask = td->td_sigmask;
do {
error = msleep(&vmp->vm_sleep, &p->p_mtx,
(coda_call_sleep|coda_pcatch), "coda_call",
hz*2);
if (error == 0)
break;
else if (error == EWOULDBLOCK) {
#ifdef CODA_VERBOSE
printf("coda_call: tsleep TIMEOUT %d sec\n", 2+2*i);
#endif
}
else {
SIGEMPTYSET(tempset);
SIGADDSET(tempset, SIGIO);
if (SIGSETEQ(td->td_siglist, tempset)) {
SIGADDSET(td->td_sigmask, SIGIO);
#ifdef CODA_VERBOSE
printf("coda_call: tsleep returns %d SIGIO, cnt %d\n",
error, i);
#endif
} else {
SIGDELSET(tempset, SIGIO);
SIGADDSET(tempset, SIGALRM);
if (SIGSETEQ(td->td_siglist, tempset)) {
SIGADDSET(td->td_sigmask, SIGALRM);
#ifdef CODA_VERBOSE
printf("coda_call: tsleep returns %d SIGALRM, cnt %d\n",
error, i);
#endif
}
else {
#ifdef CODA_VERBOSE
printf("coda_call: tsleep returns %d, cnt %d\n",
error, i);
#endif
#ifdef notyet
tempset = td->td_siglist;
SIGSETNAND(tempset, td->td_sigmask);
printf("coda_call: siglist = %p, sigmask = %p, mask %p\n",
td->td_siglist, td->td_sigmask,
tempset);
break;
SIGSETOR(td->td_sigmask, td->td_siglist);
tempset = td->td_siglist;
SIGSETNAND(tempset, td->td_sigmask);
printf("coda_call: new mask, siglist = %p, sigmask = %p, mask %p\n",
td->td_siglist, td->td_sigmask,
tempset);
#endif
}
}
}
} while (error && i++ < 128 && VC_OPEN(vcp));
td->td_sigmask = psig_omask;
signotify(td);
PROC_UNLOCK(p);
#else
(void) tsleep(&vmp->vm_sleep, coda_call_sleep, "coda_call", 0);
#endif
if (VC_OPEN(vcp)) { /* Venus is still alive */
/* Op went through, interrupt or not... */
if (vmp->vm_flags & VM_WRITE) {
error = 0;
*outSize = vmp->vm_outSize;
}
else if (!(vmp->vm_flags & VM_READ)) {
/* Interrupted before venus read it. */
#ifdef CODA_VERBOSE
if (1)
#else
if (codadebug)
#endif
myprintf(("interrupted before read: op = %d.%d, flags = %x\n",
vmp->vm_opcode, vmp->vm_unique, vmp->vm_flags));
REMQUE(vmp->vm_chain);
error = EINTR;
}
else {
/* (!(vmp->vm_flags & VM_WRITE)) means interrupted after
upcall started */
/* Interrupted after start of upcall, send venus a signal */
struct coda_in_hdr *dog;
struct vmsg *svmp;
#ifdef CODA_VERBOSE
if (1)
#else
if (codadebug)
#endif
myprintf(("Sending Venus a signal: op = %d.%d, flags = %x\n",
vmp->vm_opcode, vmp->vm_unique, vmp->vm_flags));
REMQUE(vmp->vm_chain);
error = EINTR;
CODA_ALLOC(svmp, struct vmsg *, sizeof (struct vmsg));
CODA_ALLOC((svmp->vm_data), char *, sizeof (struct coda_in_hdr));
dog = (struct coda_in_hdr *)svmp->vm_data;
svmp->vm_flags = 0;
dog->opcode = svmp->vm_opcode = CODA_SIGNAL;
dog->unique = svmp->vm_unique = vmp->vm_unique;
svmp->vm_inSize = sizeof (struct coda_in_hdr);
/*??? rvb */ svmp->vm_outSize = sizeof (struct coda_in_hdr);
if (codadebug)
myprintf(("coda_call: enqueing signal msg (%d, %d)\n",
svmp->vm_opcode, svmp->vm_unique));
/* insert at head of queue! */
INSQUE(svmp->vm_chain, vcp->vc_requests);
selwakeuppri(&(vcp->vc_selproc), coda_call_sleep);
}
}
else { /* If venus died (!VC_OPEN(vcp)) */
if (codadebug)
myprintf(("vcclose woke op %d.%d flags %d\n",
vmp->vm_opcode, vmp->vm_unique, vmp->vm_flags));
error = ENODEV;
}
CODA_FREE(vmp, sizeof(struct vmsg));
if (outstanding_upcalls > 0 && (--outstanding_upcalls == 0))
wakeup(&outstanding_upcalls);
if (!error)
error = ((struct coda_out_hdr *)buffer)->result;
return(error);
}

View File

@ -1,39 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
int vc_nb_open(struct cdev *dev, int flag, int mode, struct thread *p);
int vc_nb_close (struct cdev *dev, int flag, int mode, struct thread *p);
int vc_nb_read(struct cdev *dev, struct uio *uiop, int flag);
int vc_nb_write(struct cdev *dev, struct uio *uiop, int flag);
int vc_nb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p);
int vc_nb_poll(struct cdev *dev, int events, struct thread *p);

View File

@ -1,573 +0,0 @@
/*-
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_subr.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*/
/*-
* Mach Operating System
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon
* University. Contributers include David Steere, James Kistler, and
* M. Satyanarayanan.
*/
/* NOTES: rvb
* 1. Added coda_unmounting to mark all cnodes as being UNMOUNTING. This has to
* be done before dounmount is called. Because some of the routines that
* dounmount calls before coda_unmounted might try to force flushes to venus.
* The vnode pager does this.
* 2. coda_unmounting marks all cnodes scanning coda_cache.
* 3. cfs_checkunmounting (under DEBUG) checks all cnodes by chasing the vnodes
* under the /coda mount point.
* 4. coda_cacheprint (under DEBUG) prints names with vnode/cnode address
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/mount.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_subr.h>
#include <coda/coda_namecache.h>
int coda_active = 0;
int coda_reuse = 0;
int coda_new = 0;
struct cnode *coda_freelist = NULL;
struct cnode *coda_cache[CODA_CACHESIZE];
#define CNODE_NEXT(cp) ((cp)->c_next)
#ifdef CODA_COMPAT_5
#define coda_hash(fid) \
(((fid)->Volume + (fid)->Vnode) & (CODA_CACHESIZE-1))
#define IS_DIR(cnode) (cnode.Vnode & 0x1)
#else
#define coda_hash(fid) (coda_f2i(fid) & (CODA_CACHESIZE-1))
#define IS_DIR(cnode) (cnode.opaque[2] & 0x1)
#endif
/*
* Allocate a cnode.
*/
struct cnode *
coda_alloc(void)
{
struct cnode *cp;
if (coda_freelist) {
cp = coda_freelist;
coda_freelist = CNODE_NEXT(cp);
coda_reuse++;
}
else {
CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
/* NetBSD vnodes don't have any Pager info in them ('cause there are
no external pagers, duh!) */
#define VNODE_VM_INFO_INIT(vp) /* MT */
VNODE_VM_INFO_INIT(CTOV(cp));
coda_new++;
}
bzero(cp, sizeof (struct cnode));
return(cp);
}
/*
* Deallocate a cnode.
*/
void
coda_free(cp)
register struct cnode *cp;
{
CNODE_NEXT(cp) = coda_freelist;
coda_freelist = cp;
}
/*
* Put a cnode in the hash table
*/
void
coda_save(cp)
struct cnode *cp;
{
CNODE_NEXT(cp) = coda_cache[coda_hash(&cp->c_fid)];
coda_cache[coda_hash(&cp->c_fid)] = cp;
}
/*
* Remove a cnode from the hash table
*/
void
coda_unsave(cp)
struct cnode *cp;
{
struct cnode *ptr;
struct cnode *ptrprev = NULL;
ptr = coda_cache[coda_hash(&cp->c_fid)];
while (ptr != NULL) {
if (ptr == cp) {
if (ptrprev == NULL) {
coda_cache[coda_hash(&cp->c_fid)]
= CNODE_NEXT(ptr);
} else {
CNODE_NEXT(ptrprev) = CNODE_NEXT(ptr);
}
CNODE_NEXT(cp) = (struct cnode *)NULL;
return;
}
ptrprev = ptr;
ptr = CNODE_NEXT(ptr);
}
}
/*
* Lookup a cnode by fid. If the cnode is dying, it is bogus so skip it.
* NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95
*/
struct cnode *
coda_find(fid)
CodaFid *fid;
{
struct cnode *cp;
cp = coda_cache[coda_hash(fid)];
while (cp) {
if (coda_fid_eq(&(cp->c_fid), fid) &&
(!IS_UNMOUNTING(cp)))
{
coda_active++;
return(cp);
}
cp = CNODE_NEXT(cp);
}
return(NULL);
}
/*
* coda_kill is called as a side effect to vcopen. To prevent any
* cnodes left around from an earlier run of a venus or warden from
* causing problems with the new instance, mark any outstanding cnodes
* as dying. Future operations on these cnodes should fail (excepting
* coda_inactive of course!). Since multiple venii/wardens can be
* running, only kill the cnodes for a particular entry in the
* coda_mnttbl. -- DCS 12/1/94 */
int
coda_kill(whoIam, dcstat)
struct mount *whoIam;
enum dc_status dcstat;
{
int hash, count = 0;
struct cnode *cp;
/*
* Algorithm is as follows:
* Second, flush whatever vnodes we can from the name cache.
*
* Finally, step through whatever is left and mark them dying.
* This prevents any operation at all.
*/
/* This is slightly overkill, but should work. Eventually it'd be
* nice to only flush those entries from the namecache that
* reference a vnode in this vfs. */
coda_nc_flush(dcstat);
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
if (CTOV(cp)->v_mount == whoIam) {
#ifdef DEBUG
printf("coda_kill: vp %p, cp %p\n", CTOV(cp), cp);
#endif
count++;
CODADEBUG(CODA_FLUSH,
myprintf(("Live cnode fid %s flags %d count %d\n",
coda_f2s(&cp->c_fid),
cp->c_flags,
vrefcnt(CTOV(cp)))); );
}
}
}
return count;
}
/*
* There are two reasons why a cnode may be in use, it may be in the
* name cache or it may be executing.
*/
void
coda_flush(dcstat)
enum dc_status dcstat;
{
int hash;
struct cnode *cp;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_FLUSH]++;
coda_nc_flush(dcstat); /* flush files from the name cache */
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
if (!IS_DIR(cp->c_fid)) /* only files can be executed */
coda_vmflush(cp);
}
}
}
/*
* As a debugging measure, print out any cnodes that lived through a
* name cache flush.
*/
void
coda_testflush(void)
{
int hash;
struct cnode *cp;
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash];
cp != NULL;
cp = CNODE_NEXT(cp)) {
myprintf(("Live cnode fid %s count %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount));
}
}
}
/*
* First, step through all cnodes and mark them unmounting.
* NetBSD kernels may try to fsync them now that venus
* is dead, which would be a bad thing.
*
*/
void
coda_unmounting(whoIam)
struct mount *whoIam;
{
int hash;
struct cnode *cp;
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
if (CTOV(cp)->v_mount == whoIam) {
if (cp->c_flags & (C_LOCKED|C_WANTED)) {
printf("coda_unmounting: Unlocking %p\n", cp);
cp->c_flags &= ~(C_LOCKED|C_WANTED);
wakeup((caddr_t) cp);
}
cp->c_flags |= C_UNMOUNTING;
}
}
}
}
#ifdef DEBUG
void
coda_checkunmounting(mp)
struct mount *mp;
{
struct vnode *vp, *nvp;
struct cnode *cp;
int count = 0, bad = 0;
MNT_ILOCK(mp);
MNT_VNODE_FOREACH(vp, mp, nvp) {
VI_LOCK(vp);
if (vp->v_iflag & VI_DOOMED) {
VI_UNLOCK(vp);
continue;
}
cp = VTOC(vp);
count++;
if (!(cp->c_flags & C_UNMOUNTING)) {
bad++;
printf("vp %p, cp %p missed\n", vp, cp);
cp->c_flags |= C_UNMOUNTING;
}
VI_UNLOCK(vp);
}
MNT_IUNLOCK(mp);
}
void
coda_cacheprint(whoIam)
struct mount *whoIam;
{
int hash;
struct cnode *cp;
int count = 0;
printf("coda_cacheprint: coda_ctlvp %p, cp %p", coda_ctlvp, VTOC(coda_ctlvp));
coda_nc_name(VTOC(coda_ctlvp));
printf("\n");
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
if (CTOV(cp)->v_mount == whoIam) {
printf("coda_cacheprint: vp %p, cp %p", CTOV(cp), cp);
coda_nc_name(cp);
printf("\n");
count++;
}
}
}
printf("coda_cacheprint: count %d\n", count);
}
#endif
/*
* There are 6 cases where invalidations occur. The semantics of each
* is listed here.
*
* CODA_FLUSH -- flush all entries from the name cache and the cnode cache.
* CODA_PURGEUSER -- flush all entries from the name cache for a specific user
* This call is a result of token expiration.
*
* The next two are the result of callbacks on a file or directory.
* CODA_ZAPDIR -- flush the attributes for the dir from its cnode.
* Zap all children of this directory from the namecache.
* CODA_ZAPFILE -- flush the attributes for a file.
*
* The fifth is a result of Venus detecting an inconsistent file.
* CODA_PURGEFID -- flush the attribute for the file
* If it is a dir (odd vnode), purge its
* children from the namecache
* remove the file from the namecache.
*
* The sixth allows Venus to replace local fids with global ones
* during reintegration.
*
* CODA_REPLACE -- replace one CodaFid with another throughout the name cache
*/
int handleDownCall(opcode, out)
int opcode; union outputArgs *out;
{
int error;
/* Handle invalidate requests. */
switch (opcode) {
case CODA_FLUSH : {
coda_flush(IS_DOWNCALL);
CODADEBUG(CODA_FLUSH,coda_testflush();) /* print remaining cnodes */
return(0);
}
case CODA_PURGEUSER : {
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_PURGEUSER]++;
/* XXX - need to prevent fsync's */
#ifdef CODA_COMPAT_5
coda_nc_purge_user(out->coda_purgeuser.cred.cr_uid, IS_DOWNCALL);
#else
coda_nc_purge_user(out->coda_purgeuser.uid, IS_DOWNCALL);
#endif
return(0);
}
case CODA_ZAPFILE : {
struct cnode *cp;
error = 0;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_ZAPFILE]++;
cp = coda_find(&out->coda_zapfile.Fid);
if (cp != NULL) {
vref(CTOV(cp));
cp->c_flags &= ~C_VATTR;
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (CTOV(cp)->v_vflag & VV_TEXT)
error = coda_vmflush(cp);
CODADEBUG(CODA_ZAPFILE,
myprintf(("zapfile: fid = %s, refcnt = %d, error = %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1, error)););
if (vrefcnt(CTOV(cp)) == 1) {
cp->c_flags |= C_PURGING;
}
vrele(CTOV(cp));
}
return(error);
}
case CODA_ZAPDIR : {
struct cnode *cp;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_ZAPDIR]++;
cp = coda_find(&out->coda_zapdir.Fid);
if (cp != NULL) {
vref(CTOV(cp));
cp->c_flags &= ~C_VATTR;
coda_nc_zapParentfid(&out->coda_zapdir.Fid, IS_DOWNCALL);
CODADEBUG(CODA_ZAPDIR, myprintf((
"zapdir: fid = %s, refcnt = %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1)););
if (vrefcnt(CTOV(cp)) == 1) {
cp->c_flags |= C_PURGING;
}
vrele(CTOV(cp));
}
return(0);
}
case CODA_PURGEFID : {
struct cnode *cp;
error = 0;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_PURGEFID]++;
cp = coda_find(&out->coda_purgefid.Fid);
if (cp != NULL) {
vref(CTOV(cp));
if (IS_DIR(out->coda_purgefid.Fid)) { /* Vnode is a directory */
coda_nc_zapParentfid(&out->coda_purgefid.Fid,IS_DOWNCALL);
}
cp->c_flags &= ~C_VATTR;
coda_nc_zapfid(&out->coda_purgefid.Fid, IS_DOWNCALL);
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (!(IS_DIR(out->coda_purgefid.Fid))
&& (CTOV(cp)->v_vflag & VV_TEXT)) {
error = coda_vmflush(cp);
}
CODADEBUG(CODA_PURGEFID, myprintf((
"purgefid: fid = %s, refcnt = %d, error = %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1, error)););
if (vrefcnt(CTOV(cp)) == 1) {
cp->c_flags |= C_PURGING;
}
vrele(CTOV(cp));
}
return(error);
}
case CODA_REPLACE : {
struct cnode *cp = NULL;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_REPLACE]++;
cp = coda_find(&out->coda_replace.OldFid);
if (cp != NULL) {
/* remove the cnode from the hash table, replace the fid, and reinsert */
vref(CTOV(cp));
coda_unsave(cp);
cp->c_fid = out->coda_replace.NewFid;
coda_save(cp);
CODADEBUG(CODA_REPLACE, myprintf((
"replace: oldfid = %s, newfid = %s, cp = %p\n",
coda_f2s(&out->coda_replace.OldFid),
coda_f2s(&cp->c_fid), cp));) vrele(CTOV(cp));
}
return (0);
}
default:
myprintf(("handleDownCall: unknown opcode %d\n", opcode));
return (EINVAL);
}
}
/* coda_grab_vnode: lives in either cfs_mach.c or cfs_nbsd.c */
int
coda_vmflush(cp)
struct cnode *cp;
{
return 0;
}
/*
* kernel-internal debugging switches
*/
void coda_debugon(void)
{
codadebug = -1;
coda_nc_debug = -1;
coda_vnop_print_entry = 1;
coda_psdev_print_entry = 1;
coda_vfsop_print_entry = 1;
}
void coda_debugoff(void)
{
codadebug = 0;
coda_nc_debug = 0;
coda_vnop_print_entry = 0;
coda_psdev_print_entry = 0;
coda_vfsop_print_entry = 0;
}
/*
* Utilities used by both client and server
* Standard levels:
* 0) no debugging
* 1) hard failures
* 2) soft failures
* 3) current test software
* 4) main procedure entry points
* 5) main procedure exit points
* 6) utility procedure entry points
* 7) utility procedure exit points
* 8) obscure procedure entry points
* 9) obscure procedure exit points
* 10) random stuff
* 11) all <= 1
* 12) all <= 2
* 13) all <= 3
* ...
*/

View File

@ -1,45 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_subr.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
struct cnode *coda_alloc(void);
void coda_free(struct cnode *cp);
struct cnode *coda_find(CodaFid *fid);
void coda_flush(enum dc_status dcstat);
void coda_testflush(void);
void coda_checkunmounting(struct mount *mp);
void coda_cacheprint(struct mount *whoIam);
void coda_debugon(void);
void coda_debugoff(void);
int coda_kill(struct mount *whoIam, enum dc_status dcstat);
void coda_save(struct cnode *cp);
void coda_unsave(struct cnode *cp);

View File

@ -1,671 +0,0 @@
/*-
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/cfs/coda_venus.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#include <sys/ioccom.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sx.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_venus.h>
#include <coda/coda_pioctl.h>
#define DECL_NO_IN(name) \
struct coda_in_hdr *inp; \
struct name ## _out *outp; \
int name ## _size = sizeof (struct coda_in_hdr); \
int Isize = sizeof (struct coda_in_hdr); \
int Osize = sizeof (struct name ## _out); \
int error
#define DECL(name) \
struct name ## _in *inp; \
struct name ## _out *outp; \
int name ## _size = sizeof (struct name ## _in); \
int Isize = sizeof (struct name ## _in); \
int Osize = sizeof (struct name ## _out); \
int error
#define DECL_NO_OUT(name) \
struct name ## _in *inp; \
struct coda_out_hdr *outp; \
int name ## _size = sizeof (struct name ## _in); \
int Isize = sizeof (struct name ## _in); \
int Osize = sizeof (struct coda_out_hdr); \
int error
#define ALLOC_NO_IN(name) \
if (Osize > name ## _size) \
name ## _size = Osize; \
CODA_ALLOC(inp, struct coda_in_hdr *, name ## _size);\
outp = (struct name ## _out *) inp
#define ALLOC(name) \
if (Osize > name ## _size) \
name ## _size = Osize; \
CODA_ALLOC(inp, struct name ## _in *, name ## _size);\
outp = (struct name ## _out *) inp
#define ALLOC_NO_OUT(name) \
if (Osize > name ## _size) \
name ## _size = Osize; \
CODA_ALLOC(inp, struct name ## _in *, name ## _size);\
outp = (struct coda_out_hdr *) inp
#define STRCPY(struc, name, len) \
bcopy(name, (char *)inp + (int)inp->struc, len); \
((char*)inp + (int)inp->struc)[len++] = 0; \
Isize += len
#ifdef CODA_COMPAT_5
#define INIT_IN(in, op, ident, p) \
(in)->opcode = (op); \
sx_slock(&proctree_lock); \
(in)->pid = p ? p->p_pid : -1; \
(in)->pgid = p ? p->p_pgid : -1; \
(in)->sid = (p && p->p_session && p->p_session->s_leader) ? (p->p_session->s_leader->p_pid) : -1; \
sx_sunlock(&proctree_lock); \
if (ident != NOCRED) { \
(in)->cred.cr_uid = ident->cr_uid; \
(in)->cred.cr_groupid = ident->cr_gid; \
} else { \
bzero(&((in)->cred),sizeof(struct coda_cred)); \
(in)->cred.cr_uid = -1; \
(in)->cred.cr_groupid = -1; \
}
#else
#define INIT_IN(in, op, ident, p) \
(in)->opcode = (op); \
(in)->pid = p ? p->p_pid : -1; \
(in)->pgid = p ? p->p_pgid : -1; \
if (ident != NOCRED) { \
(in)->uid = ident->cr_uid; \
} else { \
(in)->uid = -1; \
}
#endif
#define CNV_OFLAG(to, from) \
do { \
to = 0; \
if (from & FREAD) to |= C_O_READ; \
if (from & FWRITE) to |= C_O_WRITE; \
if (from & O_TRUNC) to |= C_O_TRUNC; \
if (from & O_EXCL) to |= C_O_EXCL; \
if (from & O_CREAT) to |= C_O_CREAT; \
} while (0)
#define CNV_VV2V_ATTR(top, fromp) \
do { \
(top)->va_type = (fromp)->va_type; \
(top)->va_mode = (fromp)->va_mode; \
(top)->va_nlink = (fromp)->va_nlink; \
(top)->va_uid = (fromp)->va_uid; \
(top)->va_gid = (fromp)->va_gid; \
(top)->va_fsid = VNOVAL; \
(top)->va_fileid = (fromp)->va_fileid; \
(top)->va_size = (fromp)->va_size; \
(top)->va_blocksize = (fromp)->va_blocksize; \
(top)->va_atime = (fromp)->va_atime; \
(top)->va_mtime = (fromp)->va_mtime; \
(top)->va_ctime = (fromp)->va_ctime; \
(top)->va_gen = (fromp)->va_gen; \
(top)->va_flags = (fromp)->va_flags; \
(top)->va_rdev = (fromp)->va_rdev; \
(top)->va_bytes = (fromp)->va_bytes; \
(top)->va_filerev = (fromp)->va_filerev; \
(top)->va_vaflags = VNOVAL; \
(top)->va_spare = VNOVAL; \
} while (0)
#define CNV_V2VV_ATTR(top, fromp) \
do { \
(top)->va_type = (fromp)->va_type; \
(top)->va_mode = (fromp)->va_mode; \
(top)->va_nlink = (fromp)->va_nlink; \
(top)->va_uid = (fromp)->va_uid; \
(top)->va_gid = (fromp)->va_gid; \
(top)->va_fileid = (fromp)->va_fileid; \
(top)->va_size = (fromp)->va_size; \
(top)->va_blocksize = (fromp)->va_blocksize; \
(top)->va_atime = (fromp)->va_atime; \
(top)->va_mtime = (fromp)->va_mtime; \
(top)->va_ctime = (fromp)->va_ctime; \
(top)->va_gen = (fromp)->va_gen; \
(top)->va_flags = (fromp)->va_flags; \
(top)->va_rdev = (fromp)->va_rdev; \
(top)->va_bytes = (fromp)->va_bytes; \
(top)->va_filerev = (fromp)->va_filerev; \
} while (0)
int coda_kernel_version = CODA_KERNEL_VERSION;
int
venus_root(void *mdp,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid)
{
DECL_NO_IN(coda_root); /* sets Isize & Osize */
ALLOC_NO_IN(coda_root); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(inp, CODA_ROOT, cred, p);
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error)
*VFid = outp->Fid;
CODA_FREE(inp, coda_root_size);
return error;
}
int
venus_open(void *mdp, CodaFid *fid, int flag,
struct ucred *cred, struct proc *p,
/*out*/ struct vnode **vp)
{
int cflag;
DECL(coda_open_by_fd); /* sets Isize & Osize */
ALLOC(coda_open_by_fd); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_OPEN_BY_FD, cred, p);
inp->Fid = *fid;
CNV_OFLAG(cflag, flag);
inp->flags = cflag;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
*vp = error ? NULL : outp->vp;
CODA_FREE(inp, coda_open_by_fd_size);
return error;
}
int
venus_close(void *mdp, CodaFid *fid, int flag,
struct ucred *cred, struct proc *p)
{
int cflag;
DECL_NO_OUT(coda_close); /* sets Isize & Osize */
ALLOC_NO_OUT(coda_close); /* sets inp & outp */
INIT_IN(&inp->ih, CODA_CLOSE, cred, p);
inp->Fid = *fid;
CNV_OFLAG(cflag, flag);
inp->flags = cflag;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_close_size);
return error;
}
/*
* these two calls will not exist!!! the container file is read/written
* directly.
*/
void
venus_read(void)
{
}
void
venus_write(void)
{
}
/*
* this is a bit sad too. the ioctl's are for the control file, not for
* normal files.
*/
int
venus_ioctl(void *mdp, CodaFid *fid,
int com, int flag, caddr_t data,
struct ucred *cred, struct proc *p)
{
DECL(coda_ioctl); /* sets Isize & Osize */
struct PioctlData *iap = (struct PioctlData *)data;
int tmp;
coda_ioctl_size = VC_MAXMSGSIZE;
ALLOC(coda_ioctl); /* sets inp & outp */
INIT_IN(&inp->ih, CODA_IOCTL, cred, p);
inp->Fid = *fid;
/* command was mutated by increasing its size field to reflect the
* path and follow args. we need to subtract that out before sending
* the command to venus.
*/
inp->cmd = (com & ~(IOCPARM_MASK << 16));
tmp = ((com >> 16) & IOCPARM_MASK) - sizeof (char *) - sizeof (int);
inp->cmd |= (tmp & IOCPARM_MASK) << 16;
inp->rwflag = flag;
inp->len = iap->vi.in_size;
inp->data = (char *)(sizeof (struct coda_ioctl_in));
error = copyin(iap->vi.in, (char*)inp + (long)inp->data,
iap->vi.in_size);
if (error) {
CODA_FREE(inp, coda_ioctl_size);
return(error);
}
Osize = VC_MAXMSGSIZE;
error = coda_call(mdp, Isize + iap->vi.in_size, &Osize, (char *)inp);
/* copy out the out buffer. */
if (!error) {
if (outp->len > iap->vi.out_size) {
error = EINVAL;
} else {
error = copyout((char *)outp + (long)outp->data,
iap->vi.out, iap->vi.out_size);
}
}
CODA_FREE(inp, coda_ioctl_size);
return error;
}
int
venus_getattr(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ struct vattr *vap)
{
DECL(coda_getattr); /* sets Isize & Osize */
ALLOC(coda_getattr); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_GETATTR, cred, p);
inp->Fid = *fid;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error) {
CNV_VV2V_ATTR(vap, &outp->attr);
}
CODA_FREE(inp, coda_getattr_size);
return error;
}
int
venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_setattr); /* sets Isize & Osize */
ALLOC_NO_OUT(coda_setattr); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_SETATTR, cred, p);
inp->Fid = *fid;
CNV_V2VV_ATTR(&inp->attr, vap);
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_setattr_size);
return error;
}
int
venus_access(void *mdp, CodaFid *fid, int mode,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_access); /* sets Isize & Osize */
ALLOC_NO_OUT(coda_access); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_ACCESS, cred, p);
inp->Fid = *fid;
/* NOTE:
* NetBSD and Venus internals use the "data" in the low 3 bits.
* Hence, the conversion.
*/
inp->flags = mode>>6;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_access_size);
return error;
}
int
venus_readlink(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ char **str, int *len)
{
DECL(coda_readlink); /* sets Isize & Osize */
coda_readlink_size += CODA_MAXPATHLEN;
ALLOC(coda_readlink); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_READLINK, cred, p);
inp->Fid = *fid;
Osize += CODA_MAXPATHLEN;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error) {
CODA_ALLOC(*str, char *, outp->count);
*len = outp->count;
bcopy((char *)outp + (long)outp->data, *str, *len);
}
CODA_FREE(inp, coda_readlink_size);
return error;
}
int
venus_fsync(void *mdp, CodaFid *fid, struct proc *p)
{
DECL_NO_OUT(coda_fsync); /* sets Isize & Osize */
ALLOC_NO_OUT(coda_fsync); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_FSYNC, NOCRED, p); /* XXX: should be cached mount cred */
inp->Fid = *fid;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_fsync_size);
return error;
}
int
venus_lookup(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, int *vtype)
{
DECL(coda_lookup); /* sets Isize & Osize */
coda_lookup_size += len + 1;
ALLOC(coda_lookup); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_LOOKUP, cred, p);
inp->Fid = *fid;
/* NOTE:
* Between version 1 and version 2 we have added an extra flag field
* to this structure. But because the string was at the end and because
* of the wierd way we represent strings by having the slot point to
* where the string characters are in the "heap", we can just slip the
* flag parameter in after the string slot pointer and veni that don't
* know better won't see this new flag field ...
* Otherwise we'd need two different venus_lookup functions.
*/
inp->name = Isize;
inp->flags = CLU_CASE_SENSITIVE; /* doesn't really matter for BSD */
STRCPY(name, nm, len); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error) {
*VFid = outp->Fid;
*vtype = outp->vtype;
}
CODA_FREE(inp, coda_lookup_size);
return error;
}
int
venus_create(void *mdp, CodaFid *fid,
const char *nm, int len, int exclusive, int mode, struct vattr *va,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, struct vattr *attr)
{
DECL(coda_create); /* sets Isize & Osize */
coda_create_size += len + 1;
ALLOC(coda_create); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_CREATE, cred, p);
inp->Fid = *fid;
inp->excl = exclusive ? C_O_EXCL : 0;
inp->mode = mode;
CNV_V2VV_ATTR(&inp->attr, va);
inp->name = Isize;
STRCPY(name, nm, len); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error) {
*VFid = outp->Fid;
CNV_VV2V_ATTR(attr, &outp->attr);
}
CODA_FREE(inp, coda_create_size);
return error;
}
int
venus_remove(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_remove); /* sets Isize & Osize */
coda_remove_size += len + 1;
ALLOC_NO_OUT(coda_remove); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_REMOVE, cred, p);
inp->Fid = *fid;
inp->name = Isize;
STRCPY(name, nm, len); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_remove_size);
return error;
}
int
venus_link(void *mdp, CodaFid *fid, CodaFid *tfid,
const char *nm, int len,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_link); /* sets Isize & Osize */
coda_link_size += len + 1;
ALLOC_NO_OUT(coda_link); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_LINK, cred, p);
inp->sourceFid = *fid;
inp->destFid = *tfid;
inp->tname = Isize;
STRCPY(tname, nm, len); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_link_size);
return error;
}
int
venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid,
const char *nm, int len, const char *tnm, int tlen,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_rename); /* sets Isize & Osize */
coda_rename_size += len + 1 + tlen + 1;
ALLOC_NO_OUT(coda_rename); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_RENAME, cred, p);
inp->sourceFid = *fid;
inp->destFid = *tfid;
inp->srcname = Isize;
STRCPY(srcname, nm, len); /* increments Isize */
inp->destname = Isize;
STRCPY(destname, tnm, tlen); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_rename_size);
return error;
}
int
venus_mkdir(void *mdp, CodaFid *fid,
const char *nm, int len, struct vattr *va,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, struct vattr *ova)
{
DECL(coda_mkdir); /* sets Isize & Osize */
coda_mkdir_size += len + 1;
ALLOC(coda_mkdir); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_MKDIR, cred, p);
inp->Fid = *fid;
CNV_V2VV_ATTR(&inp->attr, va);
inp->name = Isize;
STRCPY(name, nm, len); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error) {
*VFid = outp->Fid;
CNV_VV2V_ATTR(ova, &outp->attr);
}
CODA_FREE(inp, coda_mkdir_size);
return error;
}
int
venus_rmdir(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_rmdir); /* sets Isize & Osize */
coda_rmdir_size += len + 1;
ALLOC_NO_OUT(coda_rmdir); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_RMDIR, cred, p);
inp->Fid = *fid;
inp->name = Isize;
STRCPY(name, nm, len); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_rmdir_size);
return error;
}
int
venus_symlink(void *mdp, CodaFid *fid,
const char *lnm, int llen, const char *nm, int len, struct vattr *va,
struct ucred *cred, struct proc *p)
{
DECL_NO_OUT(coda_symlink); /* sets Isize & Osize */
coda_symlink_size += llen + 1 + len + 1;
ALLOC_NO_OUT(coda_symlink); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_SYMLINK, cred, p);
inp->Fid = *fid;
CNV_V2VV_ATTR(&inp->attr, va);
inp->srcname = Isize;
STRCPY(srcname, lnm, llen); /* increments Isize */
inp->tname = Isize;
STRCPY(tname, nm, len); /* increments Isize */
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_symlink_size);
return error;
}
int
venus_readdir(void *mdp, CodaFid *fid,
int count, int offset,
struct ucred *cred, struct proc *p,
/*out*/ char *buffer, int *len)
{
DECL(coda_readdir); /* sets Isize & Osize */
coda_readdir_size = VC_MAXMSGSIZE;
ALLOC(coda_readdir); /* sets inp & outp */
/* send the open to venus. */
INIT_IN(&inp->ih, CODA_READDIR, cred, p);
inp->Fid = *fid;
inp->count = count;
inp->offset = offset;
Osize = VC_MAXMSGSIZE;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error) {
bcopy((char *)outp + (long)outp->data, buffer, outp->size);
*len = outp->size;
}
CODA_FREE(inp, coda_readdir_size);
return error;
}
int
venus_fhtovp(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, int *vtype)
{
DECL(coda_vget); /* sets Isize & Osize */
ALLOC(coda_vget); /* sets inp & outp */
/* Send the open to Venus. */
INIT_IN(&inp->ih, CODA_VGET, cred, p);
inp->Fid = *fid;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
if (!error) {
*VFid = outp->Fid;
*vtype = outp->vtype;
}
CODA_FREE(inp, coda_vget_size);
return error;
}

View File

@ -1,132 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_venus.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
int
venus_root(void *mdp,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid);
int
venus_open(void *mdp, CodaFid *fid, int flag,
struct ucred *cred, struct proc *p,
/*out*/ struct vnode **vp);
int
venus_close(void *mdp, CodaFid *fid, int flag,
struct ucred *cred, struct proc *p);
void
venus_read(void);
void
venus_write(void);
int
venus_ioctl(void *mdp, CodaFid *fid,
int com, int flag, caddr_t data,
struct ucred *cred, struct proc *p);
int
venus_getattr(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ struct vattr *vap);
int
venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap,
struct ucred *cred, struct proc *p);
int
venus_access(void *mdp, CodaFid *fid, int mode,
struct ucred *cred, struct proc *p);
int
venus_readlink(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ char **str, int *len);
int
venus_fsync(void *mdp, CodaFid *fid, struct proc *p);
int
venus_lookup(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, int *vtype);
int
venus_create(void *mdp, CodaFid *fid,
const char *nm, int len, int exclusive, int mode, struct vattr *va,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, struct vattr *attr);
int
venus_remove(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p);
int
venus_link(void *mdp, CodaFid *fid, CodaFid *tfid,
const char *nm, int len,
struct ucred *cred, struct proc *p);
int
venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid,
const char *nm, int len, const char *tnm, int tlen,
struct ucred *cred, struct proc *p);
int
venus_mkdir(void *mdp, CodaFid *fid,
const char *nm, int len, struct vattr *va,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, struct vattr *ova);
int
venus_rmdir(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p);
int
venus_symlink(void *mdp, CodaFid *fid,
const char *lnm, int llen, const char *nm, int len, struct vattr *va,
struct ucred *cred, struct proc *p);
int
venus_readdir(void *mdp, CodaFid *fid,
int count, int offset,
struct ucred *cred, struct proc *p,
/*out*/ char *buffer, int *len);
int
venus_fhtovp(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, int *vtype);

View File

@ -1,520 +0,0 @@
/*-
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/cfs/coda_vfsops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*/
/*-
* Mach Operating System
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon
* University. Contributers include David Steere, James Kistler, and
* M. Satyanarayanan.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_vfsops.h>
#include <coda/coda_venus.h>
#include <coda/coda_subr.h>
#include <coda/coda_opstats.h>
MALLOC_DEFINE(M_CODA, "coda", "Various Coda Structures");
int codadebug = 0;
int coda_vfsop_print_entry = 0;
#define ENTRY if(coda_vfsop_print_entry) myprintf(("Entered %s\n",__func__))
struct vnode *coda_ctlvp;
/* structure to keep statistics of internally generated/satisfied calls */
struct coda_op_stats coda_vfsopstats[CODA_VFSOPS_SIZE];
#define MARK_ENTRY(op) (coda_vfsopstats[op].entries++)
#define MARK_INT_SAT(op) (coda_vfsopstats[op].sat_intrn++)
#define MARK_INT_FAIL(op) (coda_vfsopstats[op].unsat_intrn++)
#define MARK_INT_GEN(op) (coda_vfsopstats[op].gen_intrn++)
extern int coda_nc_initialized; /* Set if cache has been initialized */
extern int vc_nb_open(struct cdev *, int, int, struct thread *);
int
coda_vfsopstats_init(void)
{
register int i;
for (i=0;i<CODA_VFSOPS_SIZE;i++) {
coda_vfsopstats[i].opcode = i;
coda_vfsopstats[i].entries = 0;
coda_vfsopstats[i].sat_intrn = 0;
coda_vfsopstats[i].unsat_intrn = 0;
coda_vfsopstats[i].gen_intrn = 0;
}
return 0;
}
static const char *coda_opts[] = { "from", NULL };
/*
* cfs mount vfsop
* Set up mount info record and attach it to vfs struct.
*/
/*ARGSUSED*/
int
coda_mount(struct mount *vfsp, struct thread *td)
{
struct vnode *dvp;
struct cnode *cp;
struct cdev *dev;
struct coda_mntinfo *mi;
struct vnode *rootvp;
CodaFid rootfid = INVAL_FID;
CodaFid ctlfid = CTL_FID;
int error;
struct nameidata ndp;
ENTRY;
char *from;
if (vfs_filteropt(vfsp->mnt_optnew, coda_opts))
return (EINVAL);
from = vfs_getopts(vfsp->mnt_optnew, "from", &error);
if (error)
return (error);
coda_vfsopstats_init();
coda_vnodeopstats_init();
MARK_ENTRY(CODA_MOUNT_STATS);
if (CODA_MOUNTED(vfsp)) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
return(EBUSY);
}
/* Validate mount device. Similar to getmdev(). */
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, from, td);
error = namei(&ndp);
dvp = ndp.ni_vp;
if (error) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
return (error);
}
if (dvp->v_type != VCHR) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
vrele(dvp);
NDFREE(&ndp, NDF_ONLY_PNBUF);
return(ENXIO);
}
dev = dvp->v_rdev;
vrele(dvp);
NDFREE(&ndp, NDF_ONLY_PNBUF);
/*
* Initialize the mount record and link it to the vfs struct
*/
mi = dev2coda_mntinfo(dev);
if (!mi) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
printf("Coda mount: %s is not a cfs device\n", from);
return(ENXIO);
}
if (!VC_OPEN(&mi->mi_vcomm)) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
return(ENODEV);
}
/* No initialization (here) of mi_vcomm! */
vfsp->mnt_data = (qaddr_t)mi;
vfs_getnewfsid (vfsp);
mi->mi_vfsp = vfsp;
mi->mi_started = 0; /* XXX See coda_root() */
/*
* Make a root vnode to placate the Vnode interface, but don't
* actually make the CODA_ROOT call to venus until the first call
* to coda_root in case a server is down while venus is starting.
*/
cp = make_coda_node(&rootfid, vfsp, VDIR);
rootvp = CTOV(cp);
rootvp->v_vflag |= VV_ROOT;
cp = make_coda_node(&ctlfid, vfsp, VREG);
coda_ctlvp = CTOV(cp);
/* Add vfs and rootvp to chain of vfs hanging off mntinfo */
mi->mi_vfsp = vfsp;
mi->mi_rootvp = rootvp;
vfs_mountedfrom(vfsp, from);
/* error is currently guaranteed to be zero, but in case some
code changes... */
CODADEBUG(1,
myprintf(("coda_omount returned %d\n",error)););
if (error)
MARK_INT_FAIL(CODA_MOUNT_STATS);
else
MARK_INT_SAT(CODA_MOUNT_STATS);
return(error);
}
int
coda_unmount(vfsp, mntflags, td)
struct mount *vfsp;
int mntflags;
struct thread *td;
{
struct coda_mntinfo *mi = vftomi(vfsp);
int active, error = 0;
ENTRY;
MARK_ENTRY(CODA_UMOUNT_STATS);
if (!CODA_MOUNTED(vfsp)) {
MARK_INT_FAIL(CODA_UMOUNT_STATS);
return(EINVAL);
}
if (mi->mi_vfsp == vfsp) { /* We found the victim */
if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp)))
return (EBUSY); /* Venus is still running */
#ifdef DEBUG
printf("coda_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp));
#endif
vrele(mi->mi_rootvp);
active = coda_kill(vfsp, NOT_DOWNCALL);
ASSERT_VOP_LOCKED(mi->mi_rootvp, "coda_unmount");
mi->mi_rootvp->v_vflag &= ~VV_ROOT;
error = vflush(mi->mi_vfsp, 0, FORCECLOSE, td);
#ifdef CODA_VERBOSE
printf("coda_unmount: active = %d, vflush active %d\n", active, error);
#endif
error = 0;
/* I'm going to take this out to allow lookups to go through. I'm
* not sure it's important anyway. -- DCS 2/2/94
*/
/* vfsp->VFS_DATA = NULL; */
/* No more vfsp's to hold onto */
mi->mi_vfsp = NULL;
mi->mi_rootvp = NULL;
if (error)
MARK_INT_FAIL(CODA_UMOUNT_STATS);
else
MARK_INT_SAT(CODA_UMOUNT_STATS);
return(error);
}
return (EINVAL);
}
/*
* find root of cfs
*/
int
coda_root(vfsp, flags, vpp, td)
struct mount *vfsp;
int flags;
struct vnode **vpp;
struct thread *td;
{
struct coda_mntinfo *mi = vftomi(vfsp);
struct vnode **result;
int error;
struct proc *p = td->td_proc;
CodaFid VFid;
static const CodaFid invalfid = INVAL_FID;
ENTRY;
MARK_ENTRY(CODA_ROOT_STATS);
result = NULL;
if (vfsp == mi->mi_vfsp) {
/*
* Cache the root across calls. We only need to pass the request
* on to Venus if the root vnode is the dummy we installed in
* coda_omount() with all c_fid members zeroed.
*
* XXX In addition, we assume that the first call to coda_root()
* is from vfs_omount()
* (before the call to checkdirs()) and return the dummy root
* node to avoid a deadlock. This bug is fixed in the Coda CVS
* repository but not in any released versions as of 6 Mar 2003.
*/
if (memcmp(&VTOC(mi->mi_rootvp)->c_fid, &invalfid,
sizeof(CodaFid)) != 0 || mi->mi_started == 0)
{ /* Found valid root. */
*vpp = mi->mi_rootvp;
mi->mi_started = 1;
/* On Mach, this is vref. On NetBSD, VOP_LOCK */
#if 1
vref(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE, td);
#else
vget(*vpp, LK_EXCLUSIVE, td);
#endif
MARK_INT_SAT(CODA_ROOT_STATS);
return(0);
}
}
error = venus_root(vftomi(vfsp), td->td_ucred, p, &VFid);
if (!error) {
/*
* Save the new rootfid in the cnode, and rehash the cnode into the
* cnode hash with the new fid key.
*/
coda_unsave(VTOC(mi->mi_rootvp));
VTOC(mi->mi_rootvp)->c_fid = VFid;
coda_save(VTOC(mi->mi_rootvp));
*vpp = mi->mi_rootvp;
#if 1
vref(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE, td);
#else
vget(*vpp, LK_EXCLUSIVE, td);
#endif
MARK_INT_SAT(CODA_ROOT_STATS);
goto exit;
} else if (error == ENODEV || error == EINTR) {
/* Gross hack here! */
/*
* If Venus fails to respond to the CODA_ROOT call, coda_call returns
* ENODEV. Return the uninitialized root vnode to allow vfs
* operations such as unmount to continue. Without this hack,
* there is no way to do an unmount if Venus dies before a
* successful CODA_ROOT call is done. All vnode operations
* will fail.
*/
*vpp = mi->mi_rootvp;
#if 1
vref(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE, td);
#else
vget(*vpp, LK_EXCLUSIVE, td);
#endif
MARK_INT_FAIL(CODA_ROOT_STATS);
error = 0;
goto exit;
} else {
CODADEBUG( CODA_ROOT, myprintf(("error %d in CODA_ROOT\n", error)); );
MARK_INT_FAIL(CODA_ROOT_STATS);
goto exit;
}
exit:
return(error);
}
/*
* Get filesystem statistics.
*/
int
coda_nb_statfs(vfsp, sbp, td)
register struct mount *vfsp;
struct statfs *sbp;
struct thread *td;
{
ENTRY;
/* MARK_ENTRY(CODA_STATFS_STATS); */
if (!CODA_MOUNTED(vfsp)) {
/* MARK_INT_FAIL(CODA_STATFS_STATS);*/
return(EINVAL);
}
bzero(sbp, sizeof(struct statfs));
/* XXX - what to do about f_flags, others? --bnoble */
/* Below This is what AFS does
#define NB_SFS_SIZ 0x895440
*/
/* Note: Normal fs's have a bsize of 0x400 == 1024 */
sbp->f_type = vfsp->mnt_vfc->vfc_typenum;
sbp->f_bsize = 8192; /* XXX */
sbp->f_iosize = 8192; /* XXX */
#define NB_SFS_SIZ 0x8AB75D
sbp->f_blocks = NB_SFS_SIZ;
sbp->f_bfree = NB_SFS_SIZ;
sbp->f_bavail = NB_SFS_SIZ;
sbp->f_files = NB_SFS_SIZ;
sbp->f_ffree = NB_SFS_SIZ;
bcopy((caddr_t)&(vfsp->mnt_stat.f_fsid), (caddr_t)&(sbp->f_fsid), sizeof (fsid_t));
snprintf(sbp->f_mntonname, sizeof(sbp->f_mntonname), "/coda");
snprintf(sbp->f_fstypename, sizeof(sbp->f_fstypename), "coda");
/* MARK_INT_SAT(CODA_STATFS_STATS); */
return(0);
}
/*
* Flush any pending I/O.
*/
int
coda_sync(vfsp, waitfor, td)
struct mount *vfsp;
int waitfor;
struct thread *td;
{
ENTRY;
MARK_ENTRY(CODA_SYNC_STATS);
MARK_INT_SAT(CODA_SYNC_STATS);
return(0);
}
/*
* fhtovp is now what vget used to be in 4.3-derived systems. For
* some silly reason, vget is now keyed by a 32 bit ino_t, rather than
* a type-specific fid.
*/
int
coda_fhtovp(vfsp, fhp, nam, vpp, exflagsp, creadanonp)
register struct mount *vfsp;
struct fid *fhp;
struct mbuf *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **creadanonp;
{
struct cfid *cfid = (struct cfid *)fhp;
struct cnode *cp = 0;
int error;
struct thread *td = curthread; /* XXX -mach */
struct proc *p = td->td_proc;
CodaFid VFid;
int vtype;
ENTRY;
MARK_ENTRY(CODA_VGET_STATS);
/* Check for vget of control object. */
if (IS_CTL_FID(&cfid->cfid_fid)) {
*vpp = coda_ctlvp;
vref(coda_ctlvp);
MARK_INT_SAT(CODA_VGET_STATS);
return(0);
}
error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, td->td_ucred, p, &VFid, &vtype);
if (error) {
CODADEBUG(CODA_VGET, myprintf(("vget error %d\n",error));)
*vpp = (struct vnode *)0;
} else {
CODADEBUG(CODA_VGET,
myprintf(("vget: %s type %d result %d\n",
coda_f2s(&VFid), vtype, error)); )
cp = make_coda_node(&VFid, vfsp, vtype);
*vpp = CTOV(cp);
}
return(error);
}
/*
* To allow for greater ease of use, some vnodes may be orphaned when
* Venus dies. Certain operations should still be allowed to go
* through, but without propagating ophan-ness. So this function will
* get a new vnode for the file from the current run of Venus. */
int
getNewVnode(vpp)
struct vnode **vpp;
{
struct cfid cfid;
struct coda_mntinfo *mi = vftomi((*vpp)->v_mount);
ENTRY;
cfid.cfid_len = (short)sizeof(CodaFid);
cfid.cfid_fid = VTOC(*vpp)->c_fid; /* Structure assignment. */
/* XXX ? */
/* We're guessing that if set, the 1st element on the list is a
* valid vnode to use. If not, return ENODEV as venus is dead.
*/
if (mi->mi_vfsp == NULL)
return ENODEV;
return coda_fhtovp(mi->mi_vfsp, (struct fid*)&cfid, NULL, vpp,
NULL, NULL);
}
#include <ufs/ufs/extattr.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/ufsmount.h>
/* get the mount structure corresponding to a given device. Assume
* device corresponds to a UFS. Return NULL if no device is found.
*/
struct mount *devtomp(dev)
struct cdev *dev;
{
struct mount *mp;
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
if (((VFSTOUFS(mp))->um_dev == dev)) {
/* mount corresponds to UFS and the device matches one we want */
return(mp);
}
}
/* mount structure wasn't found */
return(NULL);
}
struct vfsops coda_vfsops = {
.vfs_mount = coda_mount,
.vfs_root = coda_root,
.vfs_statfs = coda_nb_statfs,
.vfs_sync = coda_sync,
.vfs_unmount = coda_unmount,
};
VFS_SET(coda_vfsops, coda, VFCF_NETWORK);

View File

@ -1,62 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/cfs/coda_vfsops.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*
* cfid structure:
* This overlays the fid structure (see vfs.h)
* Only used below and will probably go away.
*/
struct cfid {
u_short cfid_len;
u_short padding;
CodaFid cfid_fid;
};
struct mbuf;
struct mount;
int coda_vfsopstats_init(void);
int coda_fhtovp(struct mount *, struct fid *, struct mbuf *, struct vnode **,
int *, struct ucred **);
vfs_mount_t coda_mount;
vfs_unmount_t coda_unmount;
vfs_root_t coda_root;
vfs_quotactl_t coda_quotactl;
vfs_statfs_t coda_nb_statfs;
vfs_sync_t coda_sync;
vfs_vget_t coda_vget;
vfs_init_t coda_init;
int getNewVnode(struct vnode **vpp);

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +0,0 @@
/*-
*
* Coda: an Experimental Distributed File System
* Release 3.1
*
* Copyright (c) 1987-1998 Carnegie Mellon University
* All Rights Reserved
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation, and
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_vnops.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* This code was written for the Coda filesystem at Carnegie Mellon
* University. Contributers include David Steere, James Kistler, and
* M. Satyanarayanan.
*/
/* NetBSD interfaces to the vnodeops */
vop_open_t coda_open;
vop_close_t coda_close;
vop_read_t coda_read;
vop_write_t coda_write;
vop_ioctl_t coda_ioctl;
/* 1.3 int cfs_select(void *);*/
vop_getattr_t coda_getattr;
vop_setattr_t coda_setattr;
vop_access_t coda_access;
int coda_abortop(void *);
vop_readlink_t coda_readlink;
vop_fsync_t coda_fsync;
vop_inactive_t coda_inactive;
vop_lookup_t coda_lookup;
vop_create_t coda_create;
vop_remove_t coda_remove;
vop_link_t coda_link;
vop_rename_t coda_rename;
vop_mkdir_t coda_mkdir;
vop_rmdir_t coda_rmdir;
vop_symlink_t coda_symlink;
vop_readdir_t coda_readdir;
vop_bmap_t coda_bmap;
vop_strategy_t coda_strategy;
vop_reclaim_t coda_reclaim;
vop_lock1_t coda_lock;
vop_unlock_t coda_unlock;
vop_islocked_t coda_islocked;
int coda_vop_error(void *);
int coda_vop_nop(void *);
vop_pathconf_t coda_pathconf;
int coda_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw rw,
int ioflag, struct ucred *cred, struct thread *td);
int coda_grab_vnode(struct cdev *dev, ino_t ino, struct vnode **vpp);
void print_vattr(struct vattr *attr);
void print_cred(struct ucred *cred);

View File

@ -103,13 +103,6 @@ cam/scsi/scsi_ses.c optional ses
cam/scsi/scsi_sg.c optional sg
cam/scsi/scsi_targ_bh.c optional targbh
cam/scsi/scsi_target.c optional targ
coda/coda_fbsd.c optional vcoda
coda/coda_namecache.c optional vcoda
coda/coda_psdev.c optional vcoda
coda/coda_subr.c optional vcoda
coda/coda_venus.c optional vcoda
coda/coda_vfsops.c optional vcoda
coda/coda_vnops.c optional vcoda
contrib/altq/altq/altq_cbq.c optional altq \
compile-with "${NORMAL_C} -I$S/contrib/pf"
contrib/altq/altq/altq_cdnr.c optional altq
@ -1158,6 +1151,13 @@ dev/wi/if_wi_pci.c optional wi pci
dev/wl/if_wl.c optional wl isa
dev/xe/if_xe.c optional xe
dev/xe/if_xe_pccard.c optional xe pccard
fs/coda/coda_fbsd.c optional vcoda
fs/coda/coda_namecache.c optional vcoda
fs/coda/coda_psdev.c optional vcoda
fs/coda/coda_subr.c optional vcoda
fs/coda/coda_venus.c optional vcoda
fs/coda/coda_vfsops.c optional vcoda
fs/coda/coda_vnops.c optional vcoda
fs/deadfs/dead_vnops.c standard
fs/devfs/devfs_devs.c standard
fs/devfs/devfs_rule.c standard

View File

@ -55,7 +55,7 @@ MALLOC_DECLARE(M_CODA);
/*
* tmp below since we need struct queue
*/
#include <coda/coda_kernel.h>
#include <fs/coda/coda_kernel.h>
/*
* Cnode lookup stuff.

View File

@ -45,10 +45,10 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vnode_pager.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_vnops.h>
#include <coda/coda_psdev.h>
#include <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_vnops.h>
#include <fs/coda/coda_psdev.h>
static struct cdevsw codadevsw = {
.d_version = D_VERSION,

View File

@ -86,12 +86,12 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_namecache.h>
#include <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_namecache.h>
#ifdef DEBUG
#include <coda/coda_vnops.h>
#include <fs/coda/coda_vnops.h>
#endif
/*

View File

@ -67,11 +67,11 @@ extern int coda_nc_initialized; /* Set if cache has been initialized */
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_namecache.h>
#include <coda/coda_io.h>
#include <coda/coda_psdev.h>
#include <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_namecache.h>
#include <fs/coda/coda_io.h>
#include <fs/coda/coda_psdev.h>
#define CTL_C

View File

@ -61,10 +61,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/mount.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_subr.h>
#include <coda/coda_namecache.h>
#include <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_subr.h>
#include <fs/coda/coda_namecache.h>
int coda_active = 0;
int coda_reuse = 0;

View File

@ -41,10 +41,10 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/sx.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_venus.h>
#include <coda/coda_pioctl.h>
#include <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_venus.h>
#include <fs/coda/coda_pioctl.h>
#define DECL_NO_IN(name) \
struct coda_in_hdr *inp; \

View File

@ -53,12 +53,12 @@ __FBSDID("$FreeBSD$");
#include <sys/namei.h>
#include <sys/proc.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_vfsops.h>
#include <coda/coda_venus.h>
#include <coda/coda_subr.h>
#include <coda/coda_opstats.h>
#include <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_vfsops.h>
#include <fs/coda/coda_venus.h>
#include <fs/coda/coda_subr.h>
#include <fs/coda/coda_opstats.h>
MALLOC_DEFINE(M_CODA, "coda", "Various Coda Structures");

View File

@ -64,14 +64,14 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_vnops.h>
#include <coda/coda_venus.h>
#include <coda/coda_opstats.h>
#include <coda/coda_subr.h>
#include <coda/coda_namecache.h>
#include <coda/coda_pioctl.h>
#include <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_vnops.h>
#include <fs/coda/coda_venus.h>
#include <fs/coda/coda_opstats.h>
#include <fs/coda/coda_subr.h>
#include <fs/coda/coda_namecache.h>
#include <fs/coda/coda_pioctl.h>
/*
* These flags select various performance enhancements.

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../coda
.PATH: ${.CURDIR}/../../fs/coda
KMOD= coda
SRCS= vnode_if.h \

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../coda
.PATH: ${.CURDIR}/../../fs/coda
KMOD= coda5
SRCS= vnode_if.h \