Garbage collect CODAFS bits which are now completely disconnected from

the tree since few months.

This patch is not targeted for MFC.
This commit is contained in:
attilio 2013-03-02 16:30:18 +00:00
parent 718767a4c1
commit 5d33ae7487
22 changed files with 2 additions and 6161 deletions

View File

@ -38,6 +38,8 @@
# xargs -n1 | sort | uniq -d;
# done
# 20130302: CODAFS support removed
OLD_FILES+=usr/share/man/man4/coda.4.gz
# 20130302: XFS support removed
OLD_FILES+=usr/share/man/man5/xfs.5.gz
# 20130116: removed long unused directories for .1aout section manpages

View File

@ -1,82 +0,0 @@
.\" Copyright (c) 2008 Robert N. M. Watson
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd January 21, 2008
.Dt CODA 4
.Os
.Sh NAME
.Nm coda
.Nd Coda Distributed File System
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following lines in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "options CODA"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
coda_load="YES"
.Ed
.Pp
To load as a kernel loadable module after boot:
.Pp
.Dl "kldload coda"
.Sh DESCRIPTION
The
.Nm
kernel module allows the experimental, third-party Coda distributed file
system client to be used with
.Fx .
The module allows the userspace Coda client daemon, Venus, to present the
Coda distributed file system namespace via the local
.Pa /coda
file system mountpoint via the
.Pa /dev/cfs0
special device.
.Pp
To use Coda, the Coda client software package must also be installed; more
information on Coda may be found in the Coda documentation distributed with
that package.
.Sh SEE ALSO
.Xr loader.conf 5 ,
.Xr kldload 8
.Sh HISTORY
Support for
.Nm
first appeared in
.Fx 3.0 .
.Sh AUTHORS
This manual page was written by
.An Robert Watson Aq rwatson@FreeBSD.org .
.Sh BUGS
The
Coda distributed file system is considered experimental, and production
deployment should occur only after careful consideration of the risks of
deploying experimental software.

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,16 +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_subr.
Make MPSAFE
$FreeBSD$

View File

@ -1,206 +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);
/*
* 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 == NULL) \
panic("kernel malloc returns 0 at %s:%d\n", __FILE__, \
__LINE__); \
} while (0)
#define CODA_FREE(ptr, size) free((ptr), M_CODA)
/*
* Used to select debugging statements throughout the cfs code.
*/
extern int codadebug;
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) do { \
if (codadebug & CODADBGMSK(N)) { \
STMT \
} \
} while (0)
#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) */
struct 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 */
uid_t c_cached_uid; /* cached uid */
accmode_t c_cached_mode; /* cached access mode */
struct cnode *c_next; /* links if on FreeBSD 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_ACCCACHE 0x04 /* Validity of access cache */
#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 VALID_ACCCACHE(cp) ((cp->c_flags) & C_ACCCACHE)
#define IS_UNMOUNTING(cp) ((cp)->c_flags & C_UNMOUNTING)
struct vcomm {
u_long vc_seq;
struct selinfo vc_selproc;
TAILQ_HEAD(, vmsg) vc_requests;
TAILQ_HEAD(, vmsg) vc_replies;
int vc_open;
};
#define VC_OPEN(vcp) ((vcp)->vc_open == 1)
#define MARK_VC_CLOSED(vcp) (vcp)->vc_open = 0
#define MARK_VC_OPEN(vcp) (vcp)->vc_open = 1
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)) != NULL)
/*
* 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(struct coda_mntinfo *mnt, 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(struct CodaFid *fid, struct mount *vfsp,
short type);
int coda_vnodeopstats_init(void);
/* sigh */
#define CODA_RDWR ((u_long) 31)
#endif /* _CNODE_H_ */

View File

@ -1,838 +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_
#ifdef _KERNEL
#include "opt_coda.h" /* for CODA_COMPAT_5 option */
#endif
/* 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
typedef u_int32_t cuid_t;
typedef u_int32_t cgid_t;
/*
* 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 int d_fileno; /* file number of entry */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* file type, see below */
unsigned 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
struct CodaFid {
u_long Volume;
u_long Vnode;
u_long Unique;
};
static __inline__ ino_t coda_f2i(struct CodaFid *fid)
{
if (!fid) return 0;
return (fid->Unique + (fid->Vnode<<10) + (fid->Volume<<20));
}
static __inline__ char * coda_f2s(struct 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 (struct CodaFid *fid1, struct 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 */
struct CodaFid {
u_int32_t opaque[4];
};
static __inline__ ino_t coda_f2i(struct 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(struct 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 (struct CodaFid *fid1, struct 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 {
long va_type; /* vnode type (for create) */
u_short va_mode; /* files access mode and type */
short va_nlink; /* number of references to file */
cuid_t va_uid; /* owner user id */
cgid_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, 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;
pid_t pgid;
cuid_t uid;
};
#endif
/* Really important that opcode and unique are 1st two fields! */
struct coda_out_hdr {
u_int32_t opcode;
u_int32_t unique;
u_int32_t result;
};
/* coda_root: NO_IN */
struct coda_root_out {
struct coda_out_hdr oh;
struct 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;
struct 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;
struct CodaFid Fid;
int flags;
};
struct coda_close_out {
struct coda_out_hdr out;
};
/* coda_ioctl: */
struct coda_ioctl_in {
struct coda_in_hdr ih;
struct 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;
struct 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;
struct 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;
struct 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;
struct CodaFid Fid;
int name; /* Place holder for data. */
int flags;
};
struct coda_lookup_out {
struct coda_out_hdr oh;
struct CodaFid Fid;
int vtype;
};
/* coda_create: */
struct coda_create_in {
struct coda_in_hdr ih;
struct 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;
struct CodaFid Fid;
struct coda_vattr attr;
};
/* coda_remove: NO_OUT */
struct coda_remove_in {
struct coda_in_hdr ih;
struct 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;
struct CodaFid sourceFid; /* cnode to link *to* */
struct 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;
struct CodaFid sourceFid;
int srcname;
struct CodaFid destFid;
int destname;
};
struct coda_rename_out {
struct coda_out_hdr out;
};
/* coda_mkdir: */
struct coda_mkdir_in {
struct coda_in_hdr ih;
struct CodaFid Fid;
struct coda_vattr attr;
int name; /* Place holder for data. */
};
struct coda_mkdir_out {
struct coda_out_hdr oh;
struct CodaFid Fid;
struct coda_vattr attr;
};
/* coda_rmdir: NO_OUT */
struct coda_rmdir_in {
struct coda_in_hdr ih;
struct 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;
struct 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;
struct 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;
struct 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;
struct CodaFid Fid;
};
struct coda_fsync_out {
struct coda_out_hdr out;
};
/* coda_inactive: NO_OUT */
struct coda_inactive_in {
struct coda_in_hdr ih;
struct CodaFid Fid;
};
/* coda_vget: */
struct coda_vget_in {
struct coda_in_hdr ih;
struct CodaFid Fid;
};
struct coda_vget_out {
struct coda_out_hdr oh;
struct 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
cuid_t uid;
#endif
};
/* coda_zapfile: */
/* CODA_ZAPFILE is a venus->kernel call */
struct coda_zapfile_out {
struct coda_out_hdr oh;
struct CodaFid Fid;
};
/* coda_zapdir: */
/* CODA_ZAPDIR is a venus->kernel call */
struct coda_zapdir_out {
struct coda_out_hdr oh;
struct 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
struct CodaFid Fid;
};
/* coda_purgefid: */
/* CODA_PURGEFID is a venus->kernel call */
struct coda_purgefid_out {
struct coda_out_hdr oh;
struct 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;
struct CodaFid NewFid;
struct CodaFid OldFid;
};
/* coda_open_by_fd: */
struct coda_open_by_fd_in {
struct coda_in_hdr ih;
struct CodaFid Fid;
int flags;
};
struct coda_open_by_fd_out {
struct coda_out_hdr oh;
int fd;
#ifdef _KERNEL
/* not passed from userspace but used in-kernel only */
struct vnode *vp;
#endif
};
/* coda_open_by_path: */
struct coda_open_by_path_in {
struct coda_in_hdr ih;
struct 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 */
unsigned short in_size; /* Size of input buffer <= 8K */
unsigned short out_size; /* Maximum size of output buffer, <= 8K */
};
#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_VOL -1
#define CTL_VNO -1
#define CTL_UNI -1
#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[1] == CTL_VOL && \
(fidp)->opaque[2] == CTL_VNO && \
(fidp)->opaque[3] == CTL_UNI)
#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,148 +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 <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,
.d_flags = D_NEEDGIANT,
.d_open = vc_open,
.d_close = vc_close,
.d_read = vc_read,
.d_write = vc_write,
.d_ioctl = vc_ioctl,
.d_poll = vc_poll,
.d_name = "coda",
};
static eventhandler_tag clonetag;
static LIST_HEAD(, coda_mntinfo) coda_mnttbl;
/*
* For DEVFS, using bpf & tun drivers as examples.
*
* XXX: Why use a cloned interface, aren't we really just interested in
* having a single /dev/cfs0? It's not clear the coda module knows what to
* do with more than one.
*/
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:
/*
* XXXRW: At the very least, a busy check should occur here
* to prevent untimely unload. Much more serious collection
* of allocated memory needs to take place; right now we leak
* like a sieve.
*/
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(void *arg, struct ucred *cred, char *name, int namelen,
struct cdev **dev)
{
struct coda_mntinfo *mnt;
int u;
if (*dev != NULL)
return;
if (dev_stdclone(name, NULL, "cfs", &u) != 1)
return;
*dev = make_dev(&codadevsw, 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,73 +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.
*
* Resize Coda namecache.
*/
#define CODARESIZE _IOW('c', 1, struct coda_resize)
/*
* Collect statistics.
*/
#define CODASTATS _IO('c', 2)
/*
* Print cache.
*/
#define CODAPRINT _IO('c', 3)
#define CODATEST _IO('c', 4)
struct coda_resize {
int hashsize;
int heapsize;
};
#endif /* !_CODAIO_H_ */

View File

@ -1,130 +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$
*
*/
#ifndef _CODA_OPSTATS_H_
#define _CODA_OPSTATS_H_
/*
* 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.
*/
#endif /* !_CODA_OPSTATS_H_ */

View File

@ -1,69 +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 /* !_SYS_PIOCTL_H_ */

View File

@ -1,675 +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$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/capability.h>
#include <sys/conf.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 <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_io.h>
#include <fs/coda/coda_psdev.h>
/*
* Variables to determine how Coda sleeps and whether or not it is
* interruptible when it does sleep waiting for Venus.
*/
/* #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 do { \
if (coda_psdev_print_entry) \
myprintf(("Entered %s\n", __func__)); \
} while (0)
struct vmsg {
TAILQ_ENTRY(vmsg) 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 deref */
int vm_unique;
caddr_t vm_sleep; /* Not used by Mach. */
};
#define VM_READ 1
#define VM_WRITE 2
#define VM_INTR 4 /* Unused. */
int
vc_open(struct cdev *dev, int flag, int mode, struct thread *td)
{
struct vcomm *vcp;
struct coda_mntinfo *mnt;
ENTRY;
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));
TAILQ_INIT(&vcp->vc_requests);
TAILQ_INIT(&vcp->vc_replies);
MARK_VC_OPEN(vcp);
mnt->mi_vfsp = NULL;
mnt->mi_rootvp = NULL;
return (0);
}
int
vc_close(struct cdev *dev, int flag, int mode, struct thread *td)
{
struct vcomm *vcp;
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 == NULL) {
/*
* Just a simple open/close with 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);
/*
* Wakeup clients so they can return.
*/
outstanding_upcalls = 0;
TAILQ_FOREACH_SAFE(vmp, &vcp->vc_requests, vm_chain, nvmp) {
/*
* 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);
}
TAILQ_FOREACH(vmp, &vcp->vc_replies, 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);
#endif
(void) tsleep(&outstanding_upcalls, coda_call_sleep,
"coda_umount", 0);
#ifdef CODA_VERBOSE
printf("postsleep: outstanding_upcalls = %d\n",
outstanding_upcalls);
#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_read(struct cdev *dev, struct uio *uiop, int flag)
{
struct vcomm *vcp;
struct vmsg *vmp;
int error = 0;
ENTRY;
vcp = &dev2coda_mntinfo(dev)->mi_vcomm;
/*
* Get message at head of request queue.
*/
vmp = TAILQ_FIRST(&vcp->vc_requests);
if (vmp == NULL)
return (0); /* Nothing to read */
/*
* Move the input args into userspace.
*
* XXXRW: This is not safe in the presence of >1 reader, as vmp is
* still on the head of the list.
*/
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;
}
TAILQ_REMOVE(&vcp->vc_requests, 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;
TAILQ_INSERT_TAIL(&vcp->vc_replies, vmp, vm_chain);
return (error);
}
int
vc_write(struct cdev *dev, struct uio *uiop, int flag)
{
struct vcomm *vcp;
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(dev2coda_mntinfo(dev), opcode, &pbuf));
}
/*
* Look for the message on the (waiting for) reply queue.
*/
TAILQ_FOREACH(vmp, &vcp->vc_replies, vm_chain) {
if (vmp->vm_unique == seq)
break;
}
if (vmp == NULL) {
if (codadebug)
myprintf(("vcwrite: msg (%ld, %ld) not found\n",
opcode, seq));
return (ESRCH);
}
/*
* Remove the message from the reply queue.
*/
TAILQ_REMOVE(&vcp->vc_replies, 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 < %zd)\n",
vmp->vm_outSize, uiop->uio_resid));
/*
* Notify caller of the error.
*/
wakeup(&vmp->vm_sleep);
return (EINVAL);
}
/*
* Save the value.
*/
buf[0] = uiop->uio_resid;
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, CAP_WRITE,
tmp->fd, &fp);
if (!error) {
/*
* XXX: Since the whole driver runs with
* Giant, don't actually need to acquire it
* explicitly here yet.
*/
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_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *t)
{
ENTRY;
switch(cmd) {
case CODARESIZE:
return (ENODEV);
case CODASTATS:
return (ENODEV);
case CODAPRINT:
return (ENODEV);
case CIOC_KERNEL_VERSION:
switch (*(u_int *)addr) {
case 0:
*(u_int *)addr = coda_kernel_version;
return (0);
case 1:
case 2:
if (coda_kernel_version != *(u_int *)addr)
return (ENOENT);
else
return (0);
default:
return (ENOENT);
}
default:
return (EINVAL);
}
}
int
vc_poll(struct cdev *dev, int events, struct thread *td)
{
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 (!TAILQ_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(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
/*
* Unlikely, but could be a race condition with a dying warden.
*/
if (mntinfo == NULL)
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.
*/
TAILQ_INSERT_TAIL(&vcp->vc_requests, vmp, vm_chain);
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));
TAILQ_REMOVE(&vcp->vc_requests, 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));
TAILQ_REMOVE(&vcp->vc_requests, 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!
*
* XXXRW: Actually, the tail.
*/
TAILQ_INSERT_TAIL(&vcp->vc_requests, svmp, vm_chain);
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,46 +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$
*/
#ifndef _CODA_PSDEV_H_
#define _CODA_PSDEV_H_
/*
* Prototypes for cfs device operations.
*/
d_open_t vc_open;
d_close_t vc_close;
d_read_t vc_read;
d_write_t vc_write;
d_ioctl_t vc_ioctl;
d_poll_t vc_poll;
#endif /* !_CODA_PSDEV_H_ */

View File

@ -1,628 +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 <fs/coda/coda.h>
#include <fs/coda/cnode.h>
#include <fs/coda/coda_subr.h>
static int coda_active = 0;
static int coda_reuse = 0;
static int coda_new = 0;
static struct cnode *coda_freelist = NULL;
static 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 != NULL) {
cp = coda_freelist;
coda_freelist = CNODE_NEXT(cp);
coda_reuse++;
} else {
CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
/*
* FreeBSD 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(struct cnode *cp)
{
CNODE_NEXT(cp) = coda_freelist;
coda_freelist = cp;
}
/*
* Put a cnode in the hash table.
*/
void
coda_save(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(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(struct 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);
}
/*
* Clear all cached access control decisions from Coda.
*/
static void
coda_acccache_purge(struct mount *mnt)
{
struct cnode *cp;
int hash;
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL;
cp = CNODE_NEXT(cp)) {
if (CTOV(cp)->v_mount == mnt && VALID_ACCCACHE(cp)) {
CODADEBUG(CODA_FLUSH, myprintf(("acccache "
"purge fid %s uid %d mode 0x%x\n",
coda_f2s(&cp->c_fid), cp->c_cached_uid,
(int)cp->c_cached_mode)););
cp->c_flags &= ~C_ACCCACHE;
}
}
}
}
/*
* When a user loses their tokens (or other related events), we invalidate
* any cached access rights in the access cache. In the Linux version of
* Coda, we maintain a global epoch and simply bump it to invalidate all
* cached results generated in the epoch. For now, we walk all cnodes and
* manually invalidate just that uid in FreeBSD.
*/
static void
coda_acccache_purgeuser(struct mount *mnt, uid_t uid)
{
struct cnode *cp;
int hash;
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL;
cp = CNODE_NEXT(cp)) {
if (CTOV(cp)->v_mount == mnt &&
VALID_ACCCACHE(cp) && (cp->c_cached_uid == uid)) {
CODADEBUG(CODA_PURGEUSER, myprintf((
"acccache purgeuser fid %s uid %d mode "
"0x%x\n", coda_f2s(&cp->c_fid),
cp->c_cached_uid, (int)cp->c_cached_mode)););
cp->c_flags &= ~C_ACCCACHE;
}
}
}
}
/*
* 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
*
* XXX: I don't believe any special behavior is required with respect to the
* global namecache here, as /coda will have unmounted and hence cache_flush
* will have run...?
*/
int
coda_kill(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.
*
* XXXRW: Perhaps we no longer need to purge the name cache when
* using the VFS name cache, as unmount will do that.
*/
cache_purgevfs(whoIam);
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(struct coda_mntinfo *mnt, enum dc_status dcstat)
{
int hash;
struct cnode *cp;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_FLUSH]++;
coda_acccache_purge(mnt->mi_vfsp);
cache_purgevfs(mnt->mi_vfsp);
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL;
cp = CNODE_NEXT(cp)) {
/*
* Only files that can be executed need to be flushed
* from the VM.
*
* NOTE: Currently this doesn't do anything, but
* perhaps it should?
*/
if (!IS_DIR(cp->c_fid))
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. FreeBSD kernels
* may try to fsync them now that venus is dead, which would be a bad thing.
*/
void
coda_unmounting(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(struct mount *mp)
{
struct vnode *vp, *nvp;
struct cnode *cp;
int count = 0, bad = 0;
MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
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);
}
}
void
coda_cacheprint(struct mount *whoIam)
{
int hash;
struct cnode *cp;
int count = 0;
printf("coda_cacheprint: coda_ctlvp %p, cp %p", coda_ctlvp,
VTOC(coda_ctlvp));
#if 0
coda_nc_name(VTOC(coda_ctlvp));
#endif
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);
#if 0
coda_nc_name(cp);
#endif
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(struct coda_mntinfo *mnt, int opcode, union outputArgs *out)
{
int error;
/*
* Handle invalidate requests.
*/
switch (opcode) {
case CODA_FLUSH: {
coda_flush(mnt, IS_DOWNCALL);
/* Print any remaining cnodes. */
CODADEBUG(CODA_FLUSH, coda_testflush(););
return (0);
}
case CODA_PURGEUSER: {
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_PURGEUSER]++;
/* XXX - need to prevent fsync's. */
/*
* Purge any access cache entries for the uid.
*/
#ifdef CODA_COMPAT_5
coda_acccache_purgeuser(mnt->mi_vfsp,
out->coda_purgeuser.cred.cr_uid);
#else
coda_acccache_purgeuser(mnt->mi_vfsp,
out->coda_purgeuser.uid);
#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));
cache_purge(CTOV(cp));
cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (VOP_IS_TEXT(CTOV(cp)))
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));
cache_purge(CTOV(cp));
cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
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));
cache_purge(CTOV(cp));
cp->c_flags &= ~(C_VATTR | C_ACCCACHE);
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (!(IS_DIR(out->coda_purgefid.Fid))
&& VOP_IS_TEXT(CTOV(cp)))
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. Clear the attribute cache as
* the "inode number" may have changed (it's just a
* hash of the fid, and the fid is changing).
*/
vref(CTOV(cp));
coda_unsave(cp);
cp->c_fid = out->coda_replace.NewFid;
cp->c_flags &= ~C_VATTR;
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);
}
}
int
coda_vmflush(struct cnode *cp)
{
return (0);
}
/*
* Kernel-internal debugging switches.
*/
void
coda_debugon(void)
{
codadebug = -1;
coda_vnop_print_entry = 1;
coda_psdev_print_entry = 1;
coda_vfsop_print_entry = 1;
}
void
coda_debugoff(void)
{
codadebug = 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,49 +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$
*/
#ifndef _CODA_SUBR_H_
#define _CODA_SUBR_H_
struct cnode *coda_alloc(void);
void coda_free(struct cnode *cp);
struct cnode *coda_find(struct CodaFid *fid);
void coda_flush(struct coda_mntinfo *mnt, 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);
#endif /* !_CODA_SUBR_H_ */

View File

@ -1,705 +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 <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; \
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) do { \
(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; \
} \
} while (0)
#else
#define INIT_IN(in, op, ident, p) do { \
(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; \
} while (0)
#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*/ struct 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, struct 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, struct 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, struct 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;
if (iap->vi.in_size > VC_MAXMSGSIZE ||
iap->vi.out_size > VC_MAXMSGSIZE) {
CODA_FREE(inp, coda_ioctl_size);
return (EINVAL);
}
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, struct CodaFid *fid, struct ucred *cred,
struct vattr *vap)
{
struct proc *p;
DECL(coda_getattr); /* sets Isize & Osize */
ALLOC(coda_getattr); /* sets inp & outp */
/*
* Send the open to venus.
*/
p = curthread->td_proc;
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, struct 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.
*/
p = curthread->td_proc;
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, struct CodaFid *fid, accmode_t accmode,
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: FreeBSD and Venus internals use the "data" in the low 3
* bits. Hence, the conversion.
*
* XXX: We cast accmode_t variable into an int.
*/
inp->flags = (int)accmode>>6;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_access_size);
return (error);
}
int
venus_readlink(void *mdp, struct 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, struct 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.
*
* XXX: should be cached mount cred.
*/
INIT_IN(&inp->ih, CODA_FSYNC, NOCRED, p);
inp->Fid = *fid;
error = coda_call(mdp, Isize, &Osize, (char *)inp);
CODA_FREE(inp, coda_fsync_size);
return (error);
}
int
venus_lookup(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p, /*out*/ struct 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, struct CodaFid *fid, const char *nm, int len,
int exclusive, int mode, struct vattr *va, struct ucred *cred,
struct proc *p, /*out*/ struct 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, struct 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, struct CodaFid *fid, struct 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, struct CodaFid *fid, struct 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, struct CodaFid *fid, const char *nm, int len,
struct vattr *va, struct ucred *cred, struct proc *p,
/*out*/ struct 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, struct 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, struct 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);
}
/*
* XXX: Unused.
*/
int
venus_readdir(void *mdp, struct 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, struct CodaFid *fid, struct ucred *cred,
struct proc *p, /*out*/ struct 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,83 +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$
*/
#ifndef _CODA_VENUS_H_
#define _CODA_VENUS_H_
int venus_root(void *mdp, struct ucred *cred, struct proc *p,
/*out*/ struct CodaFid *VFid);
int venus_open(void *mdp, struct CodaFid *fid, int flag,
struct ucred *cred, struct proc *p, /*out*/ struct vnode **vp);
int venus_close(void *mdp, struct CodaFid *fid, int flag,
struct ucred *cred, struct proc *p);
void venus_read(void);
void venus_write(void);
int venus_ioctl(void *mdp, struct CodaFid *fid, int com, int flag,
caddr_t data, struct ucred *cred, struct proc *p);
int venus_getattr(void *mdp, struct CodaFid *fid, struct ucred *cred,
struct vattr *vap);
int venus_setattr(void *mdp, struct CodaFid *fid, struct vattr *vap,
struct ucred *cred);
int venus_access(void *mdp, struct CodaFid *fid, int mode,
struct ucred *cred, struct proc *p);
int venus_readlink(void *mdp, struct CodaFid *fid, struct ucred *cred,
struct proc *p, /*out*/ char **str, int *len);
int venus_fsync(void *mdp, struct CodaFid *fid, struct proc *p);
int venus_lookup(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p, /*out*/ struct CodaFid *VFid,
int *vtype);
int venus_create(void *mdp, struct CodaFid *fid, const char *nm, int len,
int exclusive, int mode, struct vattr *va, struct ucred *cred,
struct proc *p, /*out*/ struct CodaFid *VFid,
struct vattr *attr);
int venus_remove(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p);
int venus_link(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
const char *nm, int len, struct ucred *cred, struct proc *p);
int venus_rename(void *mdp, struct CodaFid *fid, struct CodaFid *tfid,
const char *nm, int len, const char *tnm, int tlen,
struct ucred *cred, struct proc *p);
int venus_mkdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct vattr *va, struct ucred *cred, struct proc *p,
/*out*/ struct CodaFid *VFid, struct vattr *ova);
int venus_rmdir(void *mdp, struct CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p);
int venus_symlink(void *mdp, struct 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, struct CodaFid *fid, int count, int offset,
struct ucred *cred, struct proc *p, /*out*/ char *buffer,
int *len);
int venus_fhtovp(void *mdp, struct CodaFid *fid, struct ucred *cred,
struct proc *p, /*out*/ struct CodaFid *VFid, int *vtype);
#endif /* !_CODA_VENUS_H_ */

View File

@ -1,446 +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/fcntl.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 <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");
int codadebug = 0;
int coda_vfsop_print_entry = 0;
#define ENTRY do { \
if (coda_vfsop_print_entry) \
myprintf(("Entered %s\n", __func__)); \
} while (0)
struct vnode *coda_ctlvp;
/*
* Structure to keep statistics of internally generated/satisfied calls.
*/
static 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++)
int
coda_vfsopstats_init(void)
{
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 vnode *dvp;
struct cnode *cp;
struct cdev *dev;
struct coda_mntinfo *mi;
struct vnode *rootvp;
struct CodaFid rootfid = INVAL_FID;
struct 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, curthread);
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 = 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_mount returned %d\n", error)););
if (error)
MARK_INT_FAIL(CODA_MOUNT_STATS);
else
MARK_INT_SAT(CODA_MOUNT_STATS);
return (error);
}
int
coda_unmount(struct mount *vfsp, int mntflags)
{
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);
mi->mi_rootvp = NULL;
vrele(coda_ctlvp);
coda_ctlvp = NULL;
active = coda_kill(vfsp, NOT_DOWNCALL);
error = vflush(mi->mi_vfsp, 0, FORCECLOSE, curthread);
#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;
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(struct mount *vfsp, int flags, struct vnode **vpp)
{
struct coda_mntinfo *mi = vftomi(vfsp);
int error;
struct proc *p;
struct thread *td;
struct CodaFid VFid;
static const struct CodaFid invalfid = INVAL_FID;
td = curthread;
p = td->td_proc;
ENTRY;
MARK_ENTRY(CODA_ROOT_STATS);
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_mount() with all c_fid members zeroed.
*
* XXX In addition, we assume that the first call to
* coda_root() is from vfs_mount() (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(struct CodaFid)) != 0 || mi->mi_started == 0) {
/*
* Found valid root.
*/
*vpp = mi->mi_rootvp;
mi->mi_started = 1;
/*
* On Mach, this is vref. On FreeBSD, vref +
* vn_lock.
*/
vref(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
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;
vref(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
MARK_INT_SAT(CODA_ROOT_STATS);
} 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;
vref(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
MARK_INT_FAIL(CODA_ROOT_STATS);
error = 0;
} else {
CODADEBUG(CODA_ROOT, myprintf(("error %d in CODA_ROOT\n",
error)););
MARK_INT_FAIL(CODA_ROOT_STATS);
}
return (error);
}
/*
* Get filesystem statistics.
*/
int
coda_statfs(struct mount *vfsp, struct statfs *sbp)
{
ENTRY;
MARK_ENTRY(CODA_STATFS_STATS);
if (!CODA_MOUNTED(vfsp)) {
MARK_INT_FAIL(CODA_STATFS_STATS);
return (EINVAL);
}
/*
* XXX - what to do about f_flags, others? --bnoble
*
* We just make up free space counts that are sufficiently large.
*/
sbp->f_flags = 0;
sbp->f_bsize = 8192; /* XXX */
sbp->f_iosize = 8192; /* XXX */
#define CODA_SFS_SIZ 0x8AB75D
sbp->f_blocks = CODA_SFS_SIZ;
sbp->f_bfree = CODA_SFS_SIZ;
sbp->f_bavail = CODA_SFS_SIZ;
sbp->f_files = CODA_SFS_SIZ;
sbp->f_ffree = CODA_SFS_SIZ;
MARK_INT_SAT(CODA_STATFS_STATS);
return (0);
}
/*
* Flush any pending I/O.
*/
int
coda_sync(struct mount *vfsp, int waitfor)
{
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.
*
* XXX: coda_fhtovp is currently not hooked up, so no NFS export for Coda.
* We leave it here in the hopes that someone will find it someday and hook
* it up. Among other things, it will need some reworking to match the
* vfs_fhtovp_t prototype.
*/
int
coda_fhtovp(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 = NULL;
int error;
struct thread *td = curthread; /* XXX -mach */
struct proc *p = td->td_proc;
struct 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 = NULL;
} 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);
}
struct vfsops coda_vfsops = {
.vfs_mount = coda_mount,
.vfs_root = coda_root,
.vfs_statfs = coda_statfs,
.vfs_sync = coda_sync,
.vfs_unmount = coda_unmount,
};
VFS_SET(coda_vfsops, coda, VFCF_NETWORK);

View File

@ -1,60 +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$
*/
#ifndef _CODA_VFSOPS_H_
#define _CODA_VFSOPS_H_
/*
* 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;
struct 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_statfs_t coda_statfs;
vfs_sync_t coda_sync;
#endif /* !_CODA_VFSOPS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +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.
*/
#ifndef _CODA_VNOPS_H_
#define _CODA_VNOPS_H_
/*
* FreeBSD 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;
vop_getattr_t coda_getattr;
vop_setattr_t coda_setattr;
vop_access_t coda_access;
vop_readlink_t coda_readlink;
vop_fsync_t coda_fsync;
vop_inactive_t coda_inactive;
vop_cachedlookup_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_strategy_t coda_strategy;
vop_reclaim_t coda_reclaim;
vop_lock1_t coda_lock;
vop_unlock_t coda_unlock;
vop_islocked_t coda_islocked;
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);
void coda_print_cred(struct ucred *cred);
#endif /* !_CODA_VNOPS_H_ */

View File

@ -1,10 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../fs/coda
KMOD= coda
SRCS= vnode_if.h \
coda_fbsd.c coda_psdev.c coda_subr.c coda_venus.c coda_vfsops.c \
coda_vnops.c opt_coda.h
.include <bsd.kmod.mk>

View File

@ -1,13 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../fs/coda
KMOD= coda5
SRCS= vnode_if.h \
coda_fbsd.c coda_psdev.c coda_subr.c \
coda_venus.c coda_vfsops.c coda_vnops.c \
opt_coda.h
CFLAGS+= -DCODA5_MODULE
.include <bsd.kmod.mk>