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:
parent
718767a4c1
commit
5d33ae7487
@ -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
|
||||
|
@ -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.
|
@ -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.
|
||||
|
@ -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$
|
@ -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_ */
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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);
|
||||
}
|
@ -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_ */
|
@ -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
|
||||
* ...
|
||||
*/
|
@ -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_ */
|
@ -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);
|
||||
}
|
@ -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_ */
|
@ -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);
|
@ -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
@ -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_ */
|
@ -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>
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user