Since we're now actively maintaining the Coda module in the FreeBSD source

tree, restyle everything but coda.h (which is more explicitly shared
across systems) into a closer approximation to style(9).

Remove a few more unused function prototypes.

Add or clarify some comments.

MFC after:	1 month
This commit is contained in:
Robert Watson 2008-02-10 11:18:12 +00:00
parent 2db08dbb82
commit 21bb029533
18 changed files with 3892 additions and 3844 deletions

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,21 +14,21 @@
* 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 $
*
* @(#) src/sys/coda/cnode.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*
*/
/*-
@ -53,25 +53,25 @@
MALLOC_DECLARE(M_CODA);
/*
* tmp below since we need struct queue
* tmp below since we need struct queue.
*/
#include <fs/coda/coda_kernel.h>
/*
* Cnode lookup stuff.
*
* NOTE: CODA_CACHESIZE must be a power of 2 for cfshash to work!
*/
#define CODA_CACHESIZE 512
#define CODA_CACHESIZE 512
#define CODA_ALLOC(ptr, cast, size) \
do { \
ptr = (cast)malloc((unsigned long) size, M_CODA, M_WAITOK); \
if (ptr == 0) { \
panic("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
} \
#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)
#define CODA_FREE(ptr, size) free((ptr), M_CODA)
/*
* Used to select debugging statements throughout the cfs code.
@ -82,41 +82,46 @@ extern int coda_vnop_print_entry;
extern int coda_psdev_print_entry;
extern int coda_vfsop_print_entry;
#define CODADBGMSK(N) (1 << N)
#define CODADEBUG(N, STMT) { if (codadebug & CODADBGMSK(N)) { STMT } }
#define myprintf(args) \
do { \
if (coda_printf_delay) \
DELAY(coda_printf_delay);\
printf args ; \
#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) */
CodaFid c_fid; /* file handle */
struct vnode *c_ovp; /* open vnode pointer */
u_short c_ocount; /* count of openers */
u_short c_owrite; /* count of open for write */
struct vattr c_vattr; /* attributes */
char *c_symlink; /* pointer to symbolic link */
u_short c_symlen; /* length of symbolic link */
struct cnode *c_next; /* links if on FreeBSD machine */
struct vnode *c_vnode;
u_short c_flags; /* flags (see below) */
CodaFid c_fid; /* file handle */
struct vnode *c_ovp; /* open vnode pointer */
u_short c_ocount; /* count of openers */
u_short c_owrite; /* count of open for write */
struct vattr c_vattr; /* attributes */
char *c_symlink; /* pointer to symbolic link */
u_short c_symlen; /* length of symbolic link */
struct cnode *c_next; /* links if on 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_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 C_VATTR 0x01 /* Validity of vattr in the cnode */
#define C_SYMLINK 0x02 /* Validity of symlink pointer in the Code */
#define C_WANTED 0x08 /* Set if lock wanted */
#define C_LOCKED 0x10 /* Set if lock held */
#define C_UNMOUNTING 0X20 /* Set if unmounting */
#define C_PURGING 0x40 /* Set if purging a fid */
#define VALID_VATTR(cp) ((cp->c_flags) & C_VATTR)
#define VALID_SYMLINK(cp) ((cp->c_flags) & C_SYMLINK)
#define IS_UNMOUNTING(cp) ((cp)->c_flags & C_UNMOUNTING)
#define VALID_VATTR(cp) ((cp->c_flags) & C_VATTR)
#define VALID_SYMLINK(cp) ((cp->c_flags) & C_SYMLINK)
#define IS_UNMOUNTING(cp) ((cp)->c_flags & C_UNMOUNTING)
struct vcomm {
u_long vc_seq;
@ -125,9 +130,9 @@ struct vcomm {
struct queue vc_replys;
};
#define VC_OPEN(vcp) ((vcp)->vc_requests.forw != NULL)
#define MARK_VC_CLOSED(vcp) (vcp)->vc_requests.forw = NULL;
#define MARK_VC_OPEN(vcp) /* MT */
#define VC_OPEN(vcp) ((vcp)->vc_requests.forw != NULL)
#define MARK_VC_CLOSED(vcp) (vcp)->vc_requests.forw = NULL;
#define MARK_VC_OPEN(vcp) /* MT */
struct coda_clstat {
int ncalls; /* client requests */
@ -137,61 +142,63 @@ struct coda_clstat {
extern struct coda_clstat coda_clstat;
/*
* CODA structure to hold mount/filesystem information
* 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 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
* vfs pointer to mount info.
*/
#define vftomi(vfsp) ((struct coda_mntinfo *)(vfsp->mnt_data))
#define CODA_MOUNTED(vfsp) (vftomi((vfsp)) != (struct coda_mntinfo *)0)
#define vftomi(vfsp) ((struct coda_mntinfo *)(vfsp->mnt_data))
#define CODA_MOUNTED(vfsp) (vftomi((vfsp)) != NULL)
/*
* vnode pointer to mount info
* vnode pointer to mount info.
*/
#define vtomi(vp) ((struct coda_mntinfo *)(vp->v_mount->mnt_data))
#define vtomi(vp) ((struct coda_mntinfo *)(vp->v_mount->mnt_data))
/*
* Used for identifying usage of "Control" object
* 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)
#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
/*
* 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
IS_DOWNCALL = 6,
NOT_DOWNCALL = 7
};
/* cfs_psdev.h */
int coda_call(struct coda_mntinfo *mntinfo, int inSize, int *outSize, caddr_t buffer);
int coda_call(struct coda_mntinfo *mntinfo, int inSize, int *outSize,
caddr_t buffer);
extern int coda_kernel_version;
/* cfs_subr.h */
int handleDownCall(int opcode, union outputArgs *out);
void coda_unmounting(struct mount *whoIam);
int coda_vmflush(struct cnode *cp);
int handleDownCall(int opcode, union outputArgs *out);
void coda_unmounting(struct mount *whoIam);
int coda_vmflush(struct cnode *cp);
/* cfs_vnodeops.h */
struct cnode *make_coda_node(CodaFid *fid, struct mount *vfsp, short type);
int coda_vnodeopstats_init(void);
struct cnode *make_coda_node(CodaFid *fid, struct mount *vfsp, short type);
int coda_vnodeopstats_init(void);
/* sigh */
#define CODA_RDWR ((u_long) 31)
#define CODA_RDWR ((u_long) 31)
#endif /* _CNODE_H_ */
#endif /* _CNODE_H_ */

View File

@ -1,10 +1,10 @@
/*-
* 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
@ -13,18 +13,18 @@
* 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 $
*/
@ -66,17 +66,20 @@ static eventhandler_tag clonetag;
static LIST_HEAD(, coda_mntinfo) coda_mnttbl;
int vcdebug = 1;
#define VCDEBUG if (vcdebug) printf
/* for DEVFS, using bpf & tun drivers as examples*/
/*
* 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;
struct coda_mntinfo *mnt;
switch (type) {
case MOD_LOAD:
@ -84,7 +87,14 @@ codadev_modevent(module_t mod, int type, void *data)
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);
@ -96,8 +106,9 @@ codadev_modevent(module_t mod, int type, void *data)
default:
return (EOPNOTSUPP);
}
return 0;
return (0);
}
static moduledata_t codadev_mod = {
"codadev",
codadev_modevent,
@ -105,37 +116,33 @@ static moduledata_t codadev_mod = {
};
DECLARE_MODULE(codadev, codadev_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
static void coda_fbsd_clone(arg, cred, name, namelen, dev)
void *arg;
struct ucred *cred;
char *name;
int namelen;
struct cdev **dev;
static void
coda_fbsd_clone(void *arg, struct ucred *cred, char *name, int namelen,
struct cdev **dev)
{
int u;
struct coda_mntinfo *mnt;
struct coda_mntinfo *mnt;
int u;
if (*dev != NULL)
return;
if (dev_stdclone(name,NULL,"cfs",&u) != 1)
return;
*dev = make_dev(&codadevsw,unit2minor(u),UID_ROOT,GID_WHEEL,0600,"cfs%d",u);
dev_ref(*dev);
mnt = malloc(sizeof(struct coda_mntinfo), M_CODA, M_WAITOK|M_ZERO);
LIST_INSERT_HEAD(&coda_mnttbl, mnt, mi_list);
mnt->dev = *dev;
if (*dev != NULL)
return;
if (dev_stdclone(name, NULL, "cfs", &u) != 1)
return;
*dev = make_dev(&codadevsw, unit2minor(u), UID_ROOT, GID_WHEEL, 0600,
"cfs%d", u);
dev_ref(*dev);
mnt = malloc(sizeof(struct coda_mntinfo), M_CODA, M_WAITOK|M_ZERO);
LIST_INSERT_HEAD(&coda_mnttbl, mnt, mi_list);
mnt->dev = *dev;
}
struct coda_mntinfo *
dev2coda_mntinfo(struct cdev *dev)
{
struct coda_mntinfo *mnt;
struct coda_mntinfo *mnt;
LIST_FOREACH(mnt, &coda_mnttbl, mi_list) {
if (mnt->dev == dev)
return mnt;
return (mnt);
}
return NULL;
return (NULL);
}

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,21 +14,21 @@
* 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 $
*
* @(#) src/sys/coda/coda_io.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*
*/
/*-
@ -45,15 +45,29 @@
*/
#ifndef _CODAIO_H_
#define _CODAIO_H_
#define _CODAIO_H_
/* Define ioctl commands for vcioctl, /dev/cfs */
/*
* Define ioctl commands for vcioctl, /dev/cfs.
*
* Resize Coda namecache.
*/
#define CODARESIZE _IOW('c', 1, struct coda_resize)
#define CODARESIZE _IOW('c', 1, struct coda_resize ) /* Resize CODA NameCache */
#define CODASTATS _IO('c', 2) /* Collect stats */
#define CODAPRINT _IO('c', 3) /* Print Cache */
#define CODATEST _IO('c', 4) /* Print Cache */
/*
* Collect statistics.
*/
#define CODASTATS _IO('c', 2)
struct coda_resize { int hashsize, heapsize; };
/*
* Print cache.
*/
#define CODAPRINT _IO('c', 3)
#define CODATEST _IO('c', 4)
#endif
struct coda_resize {
int hashsize;
int heapsize;
};
#endif /* !_CODAIO_H_ */

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,53 +14,54 @@
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_kernel.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*
* @(#) src/sys/coda/coda_kernel.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*
*/
/* Macros to manipulate the queue */
/*
* Macros to manipulate the queue.
*
* XXX: It would be good to replace this with use of queue(9) throughout the
* Coda kernel module.
*/
#ifndef INIT_QUEUE
struct queue {
struct queue *forw, *back;
struct queue *forw, *back;
};
#define INIT_QUEUE(head) \
do { \
(head).forw = (struct queue *)&(head); \
(head).back = (struct queue *)&(head); \
#define INIT_QUEUE(head) do { \
(head).forw = (struct queue *)&(head); \
(head).back = (struct queue *)&(head); \
} while (0)
#define GETNEXT(head) (head).forw
#define GETNEXT(head) (head).forw
#define EMPTY(head) ((head).forw == &(head))
#define EOQ(el, head) ((struct queue *)(el) == (struct queue *)&(head))
#define EMPTY(head) ((head).forw == &(head))
#define EOQ(el, head) ((struct queue *)(el) == (struct queue *)&(head))
#define INSQUE(el, head) \
do { \
(el).forw = ((head).back)->forw; \
(el).back = (head).back; \
((head).back)->forw = (struct queue *)&(el); \
(head).back = (struct queue *)&(el); \
#define INSQUE(el, head) do { \
(el).forw = ((head).back)->forw; \
(el).back = (head).back; \
((head).back)->forw = (struct queue *)&(el); \
(head).back = (struct queue *)&(el); \
} while (0)
#define REMQUE(el) \
do { \
((el).forw)->back = (el).back; \
(el).back->forw = (el).forw; \
#define REMQUE(el) do { \
((el).forw)->back = (el).back; \
(el).back->forw = (el).forw; \
} while (0)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,21 +14,21 @@
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
* @(#) src/sys/coda/coda_namecache.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
*
* @(#) src/sys/coda/coda_namecache.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*
*/
/*-
@ -45,107 +45,117 @@
*/
#ifndef _CODA_NC_HEADER_
#define _CODA_NC_HEADER_
#define _CODA_NC_HEADER_
/*
* Coda constants
* Coda constants.
*/
#define CODA_NC_NAMELEN 15 /* longest name stored in cache */
#define CODA_NC_CACHESIZE 256 /* Default cache size */
#define CODA_NC_HASHSIZE 64 /* Must be multiple of 2 */
#define CODA_NC_NAMELEN 15 /* Longest name stored in cache */
#define CODA_NC_CACHESIZE 256 /* Default cache size */
#define CODA_NC_HASHSIZE 64 /* Must be multiple of 2 */
/*
* Hash function for the primary hash.
*/
/*
*
* First try -- (first + last letters + length + (int)cp) mod size
* 2nd try -- same, except dir fid.vnode instead of cp
*/
#define CODA_NC_HASH(name, namelen, cp) \
((name[0] + (name[namelen-1]<<4) + namelen + \
(((int)(intptr_t)cp)>>8)) & (coda_nc_hashsize-1))
#define CODA_NC_HASH(name, namelen, cp) \
((name[0] + (name[namelen-1]<<4) + namelen + (((int)(intptr_t)cp)>>8)) & (coda_nc_hashsize-1))
#define CODA_NAMEMATCH(cp, name, namelen, dcp) \
((namelen == cp->namelen) && (dcp == cp->dcp) && \
(bcmp(cp->name,name,namelen) == 0))
#define CODA_NAMEMATCH(cp, name, namelen, dcp) \
((namelen == cp->namelen) && (dcp == cp->dcp) && \
(bcmp(cp->name,name,namelen) == 0))
/*
* Functions to modify the hash and lru chains.
* insque and remque assume that the pointers are the first thing
* in the list node, thus the trickery for lru.
* Functions to modify the hash and LRU chains. insque and remque assume
* that the pointers are the first thing in the list node, thus the trickery
* for LRU.
*/
#define CODA_NC_HSHINS(elem, pred) insque(elem,pred)
#define CODA_NC_HSHREM(elem) remque(elem)
#define CODA_NC_HSHNUL(elem) (elem)->hash_next = \
#define CODA_NC_HSHINS(elem, pred) insque(elem,pred)
#define CODA_NC_HSHREM(elem) remque(elem)
#define CODA_NC_HSHNUL(elem) (elem)->hash_next = \
(elem)->hash_prev = (elem)
#define CODA_NC_LRUINS(elem, pred) insque(LRU_PART(elem), LRU_PART(pred))
#define CODA_NC_LRUREM(elem) remque(LRU_PART(elem));
#define CODA_NC_LRUGET(lruhead) LRU_TOP((lruhead).lru_prev)
#define CODA_NC_LRUINS(elem, pred) insque(LRU_PART(elem), LRU_PART(pred))
#define CODA_NC_LRUREM(elem) remque(LRU_PART(elem));
#define CODA_NC_LRUGET(lruhead) LRU_TOP((lruhead).lru_prev)
#define CODA_NC_VALID(cncp) (cncp->dcp != (struct cnode *)0)
#define LRU_PART(cncp) (struct coda_cache *) \
((char *)cncp + (2*sizeof(struct coda_cache *)))
#define LRU_TOP(cncp) (struct coda_cache *) \
((char *)cncp - (2*sizeof(struct coda_cache *)))
#define DATA_PART(cncp) (struct coda_cache *) \
((char *)cncp + (4*sizeof(struct coda_cache *)))
#define DATA_SIZE (sizeof(struct coda_cache)-(4*sizeof(struct coda_cache *)))
#define CODA_NC_VALID(cncp) (cncp->dcp != (struct cnode *)0)
#define LRU_PART(cncp) (struct coda_cache *) ((char *)cncp + \
(2*sizeof(struct coda_cache *)))
#define LRU_TOP(cncp) (struct coda_cache *) ((char *)cncp - \
(2*sizeof(struct coda_cache *)))
#define DATA_PART(cncp) (struct coda_cache *) ((char *)cncp + \
(4*sizeof(struct coda_cache *)))
#define DATA_SIZE (sizeof(struct coda_cache) - \
(4*sizeof(struct coda_cache *)))
/*
* Structure for an element in the CODA Name Cache.
* NOTE: I use the position of arguments and their size in the
* implementation of the functions CODA_NC_LRUINS, CODA_NC_LRUREM, and
* DATA_PART.
*
* NOTE: I use the position of arguments and their size in the implementation
* of the functions CODA_NC_LRUINS, CODA_NC_LRUREM, and DATA_PART.
*/
struct coda_cache {
struct coda_cache *hash_next,*hash_prev; /* Hash list */
struct coda_cache {
struct coda_cache *hash_next, *hash_prev; /* Hash list */
struct coda_cache *lru_next, *lru_prev; /* LRU list */
struct cnode *cp; /* vnode of the file */
struct cnode *dcp; /* parent's cnode */
struct ucred *cred; /* user credentials */
char name[CODA_NC_NAMELEN]; /* segment name */
int namelen; /* length of name */
char name[CODA_NC_NAMELEN]; /* segment name */
int namelen; /* length of name */
};
struct coda_lru { /* Start of LRU chain */
char *dummy1, *dummy2; /* place holders */
struct coda_cache *lru_next, *lru_prev; /* position of pointers is important */
};
struct coda_hash { /* Start of Hash chain */
struct coda_cache *hash_next, *hash_prev; /* NOTE: chain pointers must be first */
int length; /* used for tuning purposes */
};
/*
* Symbols to aid in debugging the namecache code. Assumes the existence
* of the variable coda_nc_debug, which is defined in cfs_namecache.c
/*
* Start of an LRU chain -- notice position of pointers.
*/
#define CODA_NC_DEBUG(N, STMT) { if (coda_nc_debug & (1 <<N)) { STMT } }
struct coda_lru {
char *dummy1, *dummy2;
struct coda_cache *lru_next, *lru_prev;
};
/* Prototypes of functions exported within cfs */
void coda_nc_init(void);
void coda_nc_enter(struct cnode *, const char *, int, struct ucred *, struct cnode *);
struct cnode *coda_nc_lookup(struct cnode *, const char *, int, struct ucred *);
/*
* Start of Hash chain -- notice position of pointers -- chain pointers must
* be first.
*/
struct coda_hash {
struct coda_cache *hash_next, *hash_prev;
int length; /* Used for tuning purposes. */
};
void coda_nc_zapParentfid(CodaFid *, enum dc_status);
void coda_nc_zapfid(CodaFid *, enum dc_status);
void coda_nc_zapvnode(CodaFid *, struct ucred *, enum dc_status);
void coda_nc_zapfile(struct cnode *, const char *, int);
void coda_nc_purge_user(uid_t, enum dc_status);
void coda_nc_flush(enum dc_status);
/*
* Symbols to aid in debugging the namecache code. Assumes the existence of
* the variable coda_nc_debug, which is defined in cfs_namecache.c
*/
#define CODA_NC_DEBUG(N, STMT) do { \
if (coda_nc_debug & (1 << N)) { \
STMT \
} \
} while (0)
void print_coda_nc(void);
void coda_nc_gather_stats(void);
int coda_nc_resize(int, int, enum dc_status);
void coda_nc_name(struct cnode *cp);
/*
* Prototypes of functions exported within cfs.
*/
void coda_nc_init(void);
void coda_nc_enter(struct cnode *, const char *, int, struct ucred *,
struct cnode *);
struct cnode *coda_nc_lookup(struct cnode *, const char *, int,
struct ucred *);
void coda_nc_zapParentfid(CodaFid *, enum dc_status);
void coda_nc_zapfid(CodaFid *, enum dc_status);
void coda_nc_zapvnode(CodaFid *, struct ucred *, enum dc_status);
void coda_nc_zapfile(struct cnode *, const char *, int);
void coda_nc_purge_user(uid_t, enum dc_status);
void coda_nc_flush(enum dc_status);
void print_coda_nc(void);
void coda_nc_gather_stats(void);
int coda_nc_resize(int, int, enum dc_status);
void coda_nc_name(struct cnode *cp);
/*
* Global variables tracking and controlling Coda namecache operation.
@ -155,42 +165,41 @@ extern int coda_nc_initialized; /* Set if cache has been initialized */
extern int coda_nc_use; /* Indicate use of CODA Name Cache */
/*
* Structure to contain statistics on the cache usage
* Structure to contain statistics on the cache usage.
*/
struct coda_nc_statistics {
unsigned hits;
unsigned misses;
unsigned enters;
unsigned dbl_enters;
unsigned long_name_enters;
unsigned long_name_lookups;
unsigned long_remove;
unsigned lru_rm;
unsigned zapPfids;
unsigned zapFids;
unsigned zapFile;
unsigned zapUsers;
unsigned Flushes;
unsigned Sum_bucket_len;
unsigned Sum2_bucket_len;
unsigned Max_bucket_len;
unsigned Num_zero_len;
unsigned Search_len;
u_int hits;
u_int misses;
u_int enters;
u_int dbl_enters;
u_int long_name_enters;
u_int long_name_lookups;
u_int long_remove;
u_int lru_rm;
u_int zapPfids;
u_int zapFids;
u_int zapFile;
u_int zapUsers;
u_int Flushes;
u_int Sum_bucket_len;
u_int Sum2_bucket_len;
u_int Max_bucket_len;
u_int Num_zero_len;
u_int Search_len;
};
#define CODA_NC_FIND ((u_long) 1)
#define CODA_NC_REMOVE ((u_long) 2)
#define CODA_NC_INIT ((u_long) 3)
#define CODA_NC_ENTER ((u_long) 4)
#define CODA_NC_LOOKUP ((u_long) 5)
#define CODA_NC_ZAPPFID ((u_long) 6)
#define CODA_NC_ZAPFID ((u_long) 7)
#define CODA_NC_ZAPVNODE ((u_long) 8)
#define CODA_NC_ZAPFILE ((u_long) 9)
#define CODA_NC_PURGEUSER ((u_long) 10)
#define CODA_NC_FLUSH ((u_long) 11)
#define CODA_NC_PRINTCODA_NC ((u_long) 12)
#define CODA_NC_PRINTSTATS ((u_long) 13)
#define CODA_NC_FIND ((u_long) 1)
#define CODA_NC_REMOVE ((u_long) 2)
#define CODA_NC_INIT ((u_long) 3)
#define CODA_NC_ENTER ((u_long) 4)
#define CODA_NC_LOOKUP ((u_long) 5)
#define CODA_NC_ZAPPFID ((u_long) 6)
#define CODA_NC_ZAPFID ((u_long) 7)
#define CODA_NC_ZAPVNODE ((u_long) 8)
#define CODA_NC_ZAPFILE ((u_long) 9)
#define CODA_NC_PURGEUSER ((u_long) 10)
#define CODA_NC_FLUSH ((u_long) 11)
#define CODA_NC_PRINTCODA_NC ((u_long) 12)
#define CODA_NC_PRINTSTATS ((u_long) 13)
#endif
#endif /* !_CODA_NC_HEADER_ */

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,30 +14,34 @@
* 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 $
*
* @(#) 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.
* 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:
/*-
* vfsops:
* mount: not currently bounced to Venus
* umount: nope
* root: only first call, rest is cached.
@ -45,16 +49,16 @@
* 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
#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:
/*-
* vnodeops:
* open: all to venus
* close: all to venus
* rdrw: bogus. Maybe redirected to UFS.
@ -80,48 +84,47 @@
* 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
#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?) */
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.
* With each call to the minicache, we'll bump the counters whenver a call is
* satisfied internally (through the cache or through a redirect), and
* whenever an operation is caused internally. Then, we can add the total
* operations caught by the minicache to the world-wide totals, and leave a
* caveat for the specific graphs later.
*/
#endif /* !_CODA_OPSTATS_H_ */

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,21 +14,21 @@
* 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 $
*
* @(#) src/sys/coda/coda_pioctl.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*
*/
/*-
@ -42,29 +42,28 @@
/*
* ITC Remote filesystem - vice ioctl interface module
*/
/*
* TODO: Find /usr/local/include/viceioctl.h.
*
* TODO: Find /usr/local/include/viceioctl.h.
*/
#ifndef _SYS_PIOCTL_H_
#define _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
/*
* 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))
#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.
/*
* 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))
#define _VALIDVICEIOCTL(com) (com >= _VICEIOCTL(0) && com <= _VICEIOCTL(255))
#endif
#endif /* !_SYS_PIOCTL_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,26 +14,33 @@
* that credit is given to Carnegie Mellon University in all documents
* and publicity pertaining to direct or indirect use of this code or its
* derivatives.
*
*
* CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
* SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
* FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
* ANY DERIVATIVE WORK.
*
*
* Carnegie Mellon encourages users of this software to return any
* improvements or extensions that they make, and to grant Carnegie
* Mellon the rights to redistribute these changes without encumbrance.
*
*
* @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
#ifndef _CODA_PSDEV_H_
#define _CODA_PSDEV_H_
/*
* Prototypes for cfs device operations.
*/
d_open_t vc_open;
d_close_t vc_close;
d_read_t vc_read;
d_write_t vc_write;
d_ioctl_t vc_ioctl;
d_poll_t vc_poll;
#endif /* !_CODA_PSDEV_H_ */

View File

@ -1,10 +1,10 @@
/*-
* 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
@ -13,20 +13,21 @@
* 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
@ -40,15 +41,16 @@
* 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.
/*-
* 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
* 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>
@ -66,22 +68,21 @@ __FBSDID("$FreeBSD$");
#include <fs/coda/coda_subr.h>
#include <fs/coda/coda_namecache.h>
int coda_active = 0;
int coda_reuse = 0;
int coda_new = 0;
static int coda_active = 0;
static int coda_reuse = 0;
static int coda_new = 0;
struct cnode *coda_freelist = NULL;
struct cnode *coda_cache[CODA_CACHESIZE];
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)
#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)
#define coda_hash(fid) (coda_f2i(fid) & (CODA_CACHESIZE-1))
#define IS_DIR(cnode) (cnode.opaque[2] & 0x1)
#endif
/*
@ -90,210 +91,208 @@ struct cnode *coda_cache[CODA_CACHESIZE];
struct cnode *
coda_alloc(void)
{
struct cnode *cp;
struct cnode *cp;
if (coda_freelist) {
cp = coda_freelist;
coda_freelist = CNODE_NEXT(cp);
coda_reuse++;
}
else {
CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
/* 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));
if (coda_freelist != NULL) {
cp = coda_freelist;
coda_freelist = CNODE_NEXT(cp);
coda_reuse++;
} else {
CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
return(cp);
/*
* 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(cp)
register struct cnode *cp;
coda_free(struct cnode *cp)
{
CNODE_NEXT(cp) = coda_freelist;
coda_freelist = cp;
CNODE_NEXT(cp) = coda_freelist;
coda_freelist = cp;
}
/*
* Put a cnode in the hash table
* Put a cnode in the hash table.
*/
void
coda_save(cp)
struct cnode *cp;
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
* Remove a cnode from the hash table.
*/
void
coda_unsave(cp)
struct cnode *cp;
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);
}
struct cnode *ptr;
struct cnode *ptrprev = NULL;
ptr = coda_cache[coda_hash(&cp->c_fid)];
while (ptr != NULL) {
if (ptr == cp) {
if (ptrprev == NULL)
coda_cache[coda_hash(&cp->c_fid)] =
CNODE_NEXT(ptr);
else
CNODE_NEXT(ptrprev) = CNODE_NEXT(ptr);
CNODE_NEXT(cp) = (struct cnode *)NULL;
return;
}
ptrprev = ptr;
ptr = CNODE_NEXT(ptr);
}
}
/*
* Lookup a cnode by fid. If the cnode is dying, it is bogus so skip it.
*
* NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95
*/
struct cnode *
coda_find(fid)
CodaFid *fid;
coda_find(CodaFid *fid)
{
struct cnode *cp;
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);
cp = coda_cache[coda_hash(fid)];
while (cp) {
if (coda_fid_eq(&(cp->c_fid), fid) && (!IS_UNMOUNTING(cp))) {
coda_active++;
return (cp);
}
cp = CNODE_NEXT(cp);
}
return (NULL);
}
/*
* coda_kill is called as a side effect to vcopen. To prevent any
* cnodes left around from an earlier run of a venus or warden from
* causing problems with the new instance, mark any outstanding cnodes
* as dying. Future operations on these cnodes should fail (excepting
* coda_inactive of course!). Since multiple venii/wardens can be
* running, only kill the cnodes for a particular entry in the
* coda_mnttbl. -- DCS 12/1/94 */
* coda_kill is called as a side effect to vcopen. To prevent any cnodes
* left around from an earlier run of a venus or warden from causing problems
* with the new instance, mark any outstanding cnodes as dying. Future
* operations on these cnodes should fail (excepting coda_inactive of
* course!). Since multiple venii/wardens can be running, only kill the
* cnodes for a particular entry in the coda_mnttbl. -- DCS 12/1/94
*/
int
coda_kill(whoIam, dcstat)
struct mount *whoIam;
enum dc_status dcstat;
coda_kill(struct mount *whoIam, enum dc_status dcstat)
{
int hash, count = 0;
struct cnode *cp;
/*
* Algorithm is as follows:
/*-
* 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.
*/
/* This is slightly overkill, but should work. Eventually it'd be
* nice to only flush those entries from the namecache that
* reference a vnode in this vfs. */
coda_nc_flush(dcstat);
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
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);
#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)))); );
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;
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.
* There are two reasons why a cnode may be in use, it may be in the name
* cache or it may be executing.
*/
void
coda_flush(dcstat)
enum dc_status dcstat;
coda_flush(enum dc_status dcstat)
{
int hash;
struct cnode *cp;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_FLUSH]++;
coda_nc_flush(dcstat); /* flush files from the name cache */
int hash;
struct cnode *cp;
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
if (!IS_DIR(cp->c_fid)) /* only files can be executed */
coda_vmflush(cp);
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_FLUSH]++;
/*
* Flush files from the name cache.
*/
coda_nc_flush(dcstat);
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.
* 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(whoIam)
struct mount *whoIam;
{
int hash;
struct cnode *cp;
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
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);
printf("coda_unmounting: Unlocking "
"%p\n", cp);
cp->c_flags &= ~(C_LOCKED|C_WANTED);
wakeup((caddr_t) cp);
}
@ -303,10 +302,9 @@ coda_unmounting(whoIam)
}
}
#ifdef DEBUG
#ifdef DEBUG
void
coda_checkunmounting(mp)
struct mount *mp;
coda_checkunmounting(struct mount *mp)
{
struct vnode *vp, *nvp;
struct cnode *cp;
@ -332,21 +330,22 @@ coda_checkunmounting(mp)
}
void
coda_cacheprint(whoIam)
struct mount *whoIam;
{
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));
printf("coda_cacheprint: coda_ctlvp %p, cp %p", coda_ctlvp,
VTOC(coda_ctlvp));
coda_nc_name(VTOC(coda_ctlvp));
printf("\n");
for (hash = 0; hash < CODA_CACHESIZE; hash++) {
for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
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);
printf("coda_cacheprint: vp %p, cp %p",
CTOV(cp), cp);
coda_nc_name(cp);
printf("\n");
count++;
@ -357,202 +356,201 @@ coda_cacheprint(whoIam)
}
#endif
/*
* There are 6 cases where invalidations occur. The semantics of each
* is listed here.
/*-
* 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.
* CODA_FLUSH -- Flush all entries from the name cache and the cnode
* cache.
*
* 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.
* CODA_PURGEUSER -- Flush all entries from the name cache for a specific
* user. This call is a result of token expiration.
*
* 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 next two are the result of callbacks on a file or directory:
*
* The sixth allows Venus to replace local fids with global ones
* during reintegration.
* CODA_ZAPDIR -- Flush the attributes for the dir from its cnode. Zap
* all children of this directory from the namecache.
*
* CODA_REPLACE -- replace one CodaFid with another throughout the name cache
* CODA_ZAPFILE -- Flush the attributes for a file.
*
* The fifth is a result of Venus detecting an inconsistent file:
*
* CODA_PURGEFID -- Flush the attribute for the file; if it is a dir (odd
* vnode), purge its children from the namecache; remove
* the file from the namecache.
*
* The sixth allows Venus to replace local fids with global ones during
* reintegration.
*
* CODA_REPLACE -- Replace one CodaFid with another throughout the name
* cache.
*/
int handleDownCall(opcode, out)
int opcode; union outputArgs *out;
int handleDownCall(int opcode, union outputArgs *out)
{
int error;
int error;
/* Handle invalidate requests. */
switch (opcode) {
case CODA_FLUSH : {
/*
* Handle invalidate requests.
*/
switch (opcode) {
case CODA_FLUSH: {
coda_flush(IS_DOWNCALL);
coda_flush(IS_DOWNCALL);
CODADEBUG(CODA_FLUSH,coda_testflush();) /* print remaining cnodes */
return(0);
}
case CODA_PURGEUSER : {
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_PURGEUSER]++;
/* XXX - need to prevent fsync's */
/* 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. */
#ifdef CODA_COMPAT_5
coda_nc_purge_user(out->coda_purgeuser.cred.cr_uid, IS_DOWNCALL);
coda_nc_purge_user(out->coda_purgeuser.cred.cr_uid,
IS_DOWNCALL);
#else
coda_nc_purge_user(out->coda_purgeuser.uid, IS_DOWNCALL);
coda_nc_purge_user(out->coda_purgeuser.uid, IS_DOWNCALL);
#endif
return(0);
}
case CODA_ZAPFILE : {
struct cnode *cp;
return (0);
}
error = 0;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_ZAPFILE]++;
cp = coda_find(&out->coda_zapfile.Fid);
if (cp != NULL) {
vref(CTOV(cp));
cp->c_flags &= ~C_VATTR;
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (CTOV(cp)->v_vflag & VV_TEXT)
error = coda_vmflush(cp);
CODADEBUG(CODA_ZAPFILE,
myprintf(("zapfile: fid = %s, refcnt = %d, error = %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1, error)););
if (vrefcnt(CTOV(cp)) == 1) {
cp->c_flags |= C_PURGING;
}
vrele(CTOV(cp));
}
return(error);
}
case CODA_ZAPDIR : {
struct cnode *cp;
case CODA_ZAPFILE: {
struct cnode *cp;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_ZAPDIR]++;
cp = coda_find(&out->coda_zapdir.Fid);
if (cp != NULL) {
vref(CTOV(cp));
cp->c_flags &= ~C_VATTR;
coda_nc_zapParentfid(&out->coda_zapdir.Fid, IS_DOWNCALL);
CODADEBUG(CODA_ZAPDIR, myprintf((
"zapdir: fid = %s, refcnt = %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1)););
if (vrefcnt(CTOV(cp)) == 1) {
cp->c_flags |= C_PURGING;
}
vrele(CTOV(cp));
}
return(0);
}
case CODA_PURGEFID : {
struct cnode *cp;
error = 0;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_PURGEFID]++;
cp = coda_find(&out->coda_purgefid.Fid);
if (cp != NULL) {
vref(CTOV(cp));
if (IS_DIR(out->coda_purgefid.Fid)) { /* Vnode is a directory */
coda_nc_zapParentfid(&out->coda_purgefid.Fid,IS_DOWNCALL);
}
cp->c_flags &= ~C_VATTR;
coda_nc_zapfid(&out->coda_purgefid.Fid, IS_DOWNCALL);
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (!(IS_DIR(out->coda_purgefid.Fid))
&& (CTOV(cp)->v_vflag & VV_TEXT)) {
error = coda_vmflush(cp);
}
CODADEBUG(CODA_PURGEFID, myprintf((
"purgefid: fid = %s, refcnt = %d, error = %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1, error)););
if (vrefcnt(CTOV(cp)) == 1) {
cp->c_flags |= C_PURGING;
}
vrele(CTOV(cp));
}
return(error);
error = 0;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_ZAPFILE]++;
cp = coda_find(&out->coda_zapfile.Fid);
if (cp != NULL) {
vref(CTOV(cp));
cp->c_flags &= ~C_VATTR;
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (CTOV(cp)->v_vflag & VV_TEXT)
error = coda_vmflush(cp);
CODADEBUG(CODA_ZAPFILE,
myprintf(("zapfile: fid = %s, refcnt = %d, error = "
"%d\n", coda_f2s(&cp->c_fid),
CTOV(cp)->v_usecount - 1, error)););
if (vrefcnt(CTOV(cp)) == 1)
cp->c_flags |= C_PURGING;
vrele(CTOV(cp));
}
return (error);
}
case CODA_REPLACE : {
struct cnode *cp = NULL;
case CODA_ZAPDIR: {
struct cnode *cp;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_REPLACE]++;
cp = coda_find(&out->coda_replace.OldFid);
if (cp != NULL) {
/* remove the cnode from the hash table, replace the fid, and reinsert */
vref(CTOV(cp));
coda_unsave(cp);
cp->c_fid = out->coda_replace.NewFid;
coda_save(cp);
CODADEBUG(CODA_REPLACE, myprintf((
"replace: oldfid = %s, newfid = %s, cp = %p\n",
coda_f2s(&out->coda_replace.OldFid),
coda_f2s(&cp->c_fid), cp));) vrele(CTOV(cp));
}
return (0);
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_ZAPDIR]++;
cp = coda_find(&out->coda_zapdir.Fid);
if (cp != NULL) {
vref(CTOV(cp));
cp->c_flags &= ~C_VATTR;
coda_nc_zapParentfid(&out->coda_zapdir.Fid,
IS_DOWNCALL);
CODADEBUG(CODA_ZAPDIR, myprintf(("zapdir: fid = %s, "
"refcnt = %d\n", coda_f2s(&cp->c_fid),
CTOV(cp)->v_usecount - 1)););
if (vrefcnt(CTOV(cp)) == 1)
cp->c_flags |= C_PURGING;
vrele(CTOV(cp));
}
return (0);
}
default:
myprintf(("handleDownCall: unknown opcode %d\n", opcode));
return (EINVAL);
}
case CODA_PURGEFID: {
struct cnode *cp;
error = 0;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_PURGEFID]++;
cp = coda_find(&out->coda_purgefid.Fid);
if (cp != NULL) {
vref(CTOV(cp));
if (IS_DIR(out->coda_purgefid.Fid))
coda_nc_zapParentfid(&out->coda_purgefid.Fid,
IS_DOWNCALL);
cp->c_flags &= ~C_VATTR;
coda_nc_zapfid(&out->coda_purgefid.Fid, IS_DOWNCALL);
ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall");
if (!(IS_DIR(out->coda_purgefid.Fid))
&& (CTOV(cp)->v_vflag & VV_TEXT))
error = coda_vmflush(cp);
CODADEBUG(CODA_PURGEFID, myprintf(("purgefid: fid "
"= %s, refcnt = %d, error = %d\n",
coda_f2s(&cp->c_fid),
CTOV(cp)->v_usecount - 1, error)););
if (vrefcnt(CTOV(cp)) == 1)
cp->c_flags |= C_PURGING;
vrele(CTOV(cp));
}
return (error);
}
case CODA_REPLACE: {
struct cnode *cp = NULL;
coda_clstat.ncalls++;
coda_clstat.reqs[CODA_REPLACE]++;
cp = coda_find(&out->coda_replace.OldFid);
if (cp != NULL) {
/*
* Remove the cnode from the hash table, replace the
* fid, and reinsert.
*/
vref(CTOV(cp));
coda_unsave(cp);
cp->c_fid = out->coda_replace.NewFid;
coda_save(cp);
CODADEBUG(CODA_REPLACE, myprintf(("replace: oldfid "
"= %s, newfid = %s, cp = %p\n",
coda_f2s(&out->coda_replace.OldFid),
coda_f2s(&cp->c_fid), cp)););
vrele(CTOV(cp));
}
return (0);
}
default:
myprintf(("handleDownCall: unknown opcode %d\n", opcode));
return (EINVAL);
}
}
/* coda_grab_vnode: lives in either cfs_mach.c or cfs_nbsd.c */
int
coda_vmflush(cp)
struct cnode *cp;
coda_vmflush(struct cnode *cp)
{
return 0;
}
/*
* kernel-internal debugging switches
*/
void coda_debugon(void)
{
codadebug = -1;
coda_nc_debug = -1;
coda_vnop_print_entry = 1;
coda_psdev_print_entry = 1;
coda_vfsop_print_entry = 1;
}
void coda_debugoff(void)
{
codadebug = 0;
coda_nc_debug = 0;
coda_vnop_print_entry = 0;
coda_psdev_print_entry = 0;
coda_vfsop_print_entry = 0;
return (0);
}
/*
* Kernel-internal debugging switches.
*/
void
coda_debugon(void)
{
codadebug = -1;
coda_nc_debug = -1;
coda_vnop_print_entry = 1;
coda_psdev_print_entry = 1;
coda_vfsop_print_entry = 1;
}
void
coda_debugoff(void)
{
codadebug = 0;
coda_nc_debug = 0;
coda_vnop_print_entry = 0;
coda_psdev_print_entry = 0;
coda_vfsop_print_entry = 0;
}
/*-
* Utilities used by both client and server
* Standard levels:
* 0) no debugging

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,32 +14,36 @@
* 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 $
*
* @(#) src/sys/coda/coda_subr.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
struct cnode *coda_alloc(void);
void coda_free(struct cnode *cp);
struct cnode *coda_find(CodaFid *fid);
void coda_flush(enum dc_status dcstat);
void coda_testflush(void);
void coda_checkunmounting(struct mount *mp);
void coda_cacheprint(struct mount *whoIam);
void coda_debugon(void);
void coda_debugoff(void);
int coda_kill(struct mount *whoIam, enum dc_status dcstat);
void coda_save(struct cnode *cp);
void coda_unsave(struct cnode *cp);
#ifndef _CODA_SUBR_H_
#define _CODA_SUBR_H_
struct cnode *coda_alloc(void);
void coda_free(struct cnode *cp);
struct cnode *coda_find(CodaFid *fid);
void coda_flush(enum dc_status dcstat);
void coda_testflush(void);
void coda_checkunmounting(struct mount *mp);
void coda_cacheprint(struct mount *whoIam);
void coda_debugon(void);
void coda_debugoff(void);
int coda_kill(struct mount *whoIam, enum dc_status dcstat);
void coda_save(struct cnode *cp);
void coda_unsave(struct cnode *cp);
#endif /* !_CODA_SUBR_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,119 +14,69 @@
* 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 $
*
* @(#) src/sys/coda/coda_venus.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
* $FreeBSD$
*
*/
int
venus_root(void *mdp,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid);
#ifndef _CODA_VENUS_H_
#define _CODA_VENUS_H_
int
venus_open(void *mdp, CodaFid *fid, int flag,
struct ucred *cred, struct proc *p,
/*out*/ struct vnode **vp);
int venus_root(void *mdp, struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid);
int venus_open(void *mdp, CodaFid *fid, int flag, struct ucred *cred,
struct proc *p, /*out*/ struct vnode **vp);
int venus_close(void *mdp, CodaFid *fid, int flag, struct ucred *cred,
struct proc *p);
void venus_read(void);
void venus_write(void);
int venus_ioctl(void *mdp, CodaFid *fid, int com, int flag, caddr_t data,
struct ucred *cred, struct proc *p);
int venus_getattr(void *mdp, CodaFid *fid, struct ucred *cred,
struct proc *p, /*out*/ struct vattr *vap);
int venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap,
struct ucred *cred, struct proc *p);
int venus_access(void *mdp, CodaFid *fid, int mode, struct ucred *cred,
struct proc *p);
int venus_readlink(void *mdp, CodaFid *fid, struct ucred *cred,
struct proc *p, /*out*/ char **str, int *len);
int venus_fsync(void *mdp, CodaFid *fid, struct proc *p);
int venus_lookup(void *mdp, CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p, /*out*/ CodaFid *VFid,
int *vtype);
int venus_create(void *mdp, CodaFid *fid, const char *nm, int len,
int exclusive, int mode, struct vattr *va, struct ucred *cred,
struct proc *p, /*out*/ CodaFid *VFid, struct vattr *attr);
int venus_remove(void *mdp, CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p);
int venus_link(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm,
int len, struct ucred *cred, struct proc *p);
int venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid, const char *nm,
int len, const char *tnm, int tlen, struct ucred *cred,
struct proc *p);
int venus_mkdir(void *mdp, CodaFid *fid, const char *nm, int len,
struct vattr *va, struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, struct vattr *ova);
int venus_rmdir(void *mdp, CodaFid *fid, const char *nm, int len,
struct ucred *cred, struct proc *p);
int venus_symlink(void *mdp, CodaFid *fid, const char *lnm, int llen,
const char *nm, int len, struct vattr *va, struct ucred *cred,
struct proc *p);
int venus_readdir(void *mdp, CodaFid *fid, int count, int offset,
struct ucred *cred, struct proc *p, /*out*/ char *buffer,
int *len);
int venus_fhtovp(void *mdp, CodaFid *fid, struct ucred *cred,
struct proc *p, /*out*/ CodaFid *VFid, int *vtype);
int
venus_close(void *mdp, CodaFid *fid, int flag,
struct ucred *cred, struct proc *p);
void
venus_read(void);
void
venus_write(void);
int
venus_ioctl(void *mdp, CodaFid *fid,
int com, int flag, caddr_t data,
struct ucred *cred, struct proc *p);
int
venus_getattr(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ struct vattr *vap);
int
venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap,
struct ucred *cred, struct proc *p);
int
venus_access(void *mdp, CodaFid *fid, int mode,
struct ucred *cred, struct proc *p);
int
venus_readlink(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ char **str, int *len);
int
venus_fsync(void *mdp, CodaFid *fid, struct proc *p);
int
venus_lookup(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, int *vtype);
int
venus_create(void *mdp, CodaFid *fid,
const char *nm, int len, int exclusive, int mode, struct vattr *va,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, struct vattr *attr);
int
venus_remove(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p);
int
venus_link(void *mdp, CodaFid *fid, CodaFid *tfid,
const char *nm, int len,
struct ucred *cred, struct proc *p);
int
venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid,
const char *nm, int len, const char *tnm, int tlen,
struct ucred *cred, struct proc *p);
int
venus_mkdir(void *mdp, CodaFid *fid,
const char *nm, int len, struct vattr *va,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, struct vattr *ova);
int
venus_rmdir(void *mdp, CodaFid *fid,
const char *nm, int len,
struct ucred *cred, struct proc *p);
int
venus_symlink(void *mdp, CodaFid *fid,
const char *lnm, int llen, const char *nm, int len, struct vattr *va,
struct ucred *cred, struct proc *p);
int
venus_readdir(void *mdp, CodaFid *fid,
int count, int offset,
struct ucred *cred, struct proc *p,
/*out*/ char *buffer, int *len);
int
venus_fhtovp(void *mdp, CodaFid *fid,
struct ucred *cred, struct proc *p,
/*out*/ CodaFid *VFid, int *vtype);
#endif /* !_CODA_VENUS_H_ */

View File

@ -1,10 +1,10 @@
/*-
* 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
@ -13,20 +13,21 @@
* 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
@ -37,7 +38,7 @@
/*
* This code was written for the Coda filesystem at Carnegie Mellon
* University. Contributers include David Steere, James Kistler, and
* M. Satyanarayanan.
* M. Satyanarayanan.
*/
#include <sys/cdefs.h>
@ -64,337 +65,332 @@ MALLOC_DEFINE(M_CODA, "coda", "Various Coda Structures");
int codadebug = 0;
int coda_vfsop_print_entry = 0;
#define ENTRY if(coda_vfsop_print_entry) myprintf(("Entered %s\n",__func__))
#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 */
/*
* Structure to keep statistics of internally generated/satisfied calls.
*/
static struct coda_op_stats coda_vfsopstats[CODA_VFSOPS_SIZE];
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++)
#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)
{
register int i;
for (i=0;i<CODA_VFSOPS_SIZE;i++) {
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;
return (0);
}
static const char *coda_opts[] = { "from", NULL };
/*
* cfs mount vfsop
*
* Set up mount info record and attach it to vfs struct.
*/
/*ARGSUSED*/
int
coda_mount(struct mount *vfsp, struct thread *td)
{
struct vnode *dvp;
struct cnode *cp;
struct cdev *dev;
struct coda_mntinfo *mi;
struct vnode *rootvp;
CodaFid rootfid = INVAL_FID;
CodaFid ctlfid = CTL_FID;
int error;
struct nameidata ndp;
ENTRY;
char *from;
struct vnode *dvp;
struct cnode *cp;
struct cdev *dev;
struct coda_mntinfo *mi;
struct vnode *rootvp;
CodaFid rootfid = INVAL_FID;
CodaFid ctlfid = CTL_FID;
int error;
struct nameidata ndp;
ENTRY;
char *from;
if (vfs_filteropt(vfsp->mnt_optnew, coda_opts))
return (EINVAL);
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);
}
from = vfs_getopts(vfsp->mnt_optnew, "from", &error);
if (error)
return (error);
coda_vfsopstats_init();
coda_vnodeopstats_init();
MARK_ENTRY(CODA_MOUNT_STATS);
if (CODA_MOUNTED(vfsp)) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
return(EBUSY);
}
/* Validate mount device. Similar to getmdev(). */
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, from, td);
error = namei(&ndp);
dvp = ndp.ni_vp;
if (error) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
return (error);
}
if (dvp->v_type != VCHR) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
/*
* Validate mount device. Similar to getmdev().
*/
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, from, td);
error = namei(&ndp);
dvp = ndp.ni_vp;
if (error) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
return (error);
}
if (dvp->v_type != VCHR) {
MARK_INT_FAIL(CODA_MOUNT_STATS);
vrele(dvp);
NDFREE(&ndp, NDF_ONLY_PNBUF);
return (ENXIO);
}
dev = dvp->v_rdev;
vrele(dvp);
NDFREE(&ndp, NDF_ONLY_PNBUF);
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);
/*
* 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);
}
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);
/*
* 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() */
/* Add vfs and rootvp to chain of vfs hanging off mntinfo */
mi->mi_vfsp = vfsp;
mi->mi_rootvp = rootvp;
vfs_mountedfrom(vfsp, from);
/* error is currently guaranteed to be zero, but in case some
code changes... */
CODADEBUG(1,
myprintf(("coda_omount returned %d\n",error)););
if (error)
MARK_INT_FAIL(CODA_MOUNT_STATS);
else
MARK_INT_SAT(CODA_MOUNT_STATS);
return(error);
/*
* 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(vfsp, mntflags, td)
struct mount *vfsp;
int mntflags;
struct thread *td;
coda_unmount(struct mount *vfsp, int mntflags, struct thread *td)
{
struct coda_mntinfo *mi = vftomi(vfsp);
int active, error = 0;
ENTRY;
MARK_ENTRY(CODA_UMOUNT_STATS);
if (!CODA_MOUNTED(vfsp)) {
MARK_INT_FAIL(CODA_UMOUNT_STATS);
return(EINVAL);
}
if (mi->mi_vfsp == vfsp) { /* We found the victim */
if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp)))
return (EBUSY); /* Venus is still running */
struct coda_mntinfo *mi = vftomi(vfsp);
int active, error = 0;
#ifdef DEBUG
printf("coda_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp));
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, td);
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, td);
#ifdef CODA_VERBOSE
printf("coda_unmount: active = %d, vflush active %d\n", active, error);
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; */
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;
/*
* 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);
if (error)
MARK_INT_FAIL(CODA_UMOUNT_STATS);
else
MARK_INT_SAT(CODA_UMOUNT_STATS);
return (error);
}
return (EINVAL);
}
/*
* find root of cfs
* Find root of cfs.
*/
int
coda_root(vfsp, flags, vpp, td)
struct mount *vfsp;
int flags;
struct vnode **vpp;
struct thread *td;
coda_root(struct mount *vfsp, int flags, struct vnode **vpp,
struct thread *td)
{
struct coda_mntinfo *mi = vftomi(vfsp);
struct vnode **result;
int error;
struct proc *p = td->td_proc;
CodaFid VFid;
static const CodaFid invalfid = INVAL_FID;
ENTRY;
MARK_ENTRY(CODA_ROOT_STATS);
result = NULL;
if (vfsp == mi->mi_vfsp) {
/*
* Cache the root across calls. We only need to pass the request
* on to Venus if the root vnode is the dummy we installed in
* coda_omount() with all c_fid members zeroed.
*
* XXX In addition, we assume that the first call to coda_root()
* is from vfs_omount()
* (before the call to checkdirs()) and return the dummy root
* node to avoid a deadlock. This bug is fixed in the Coda CVS
* repository but not in any released versions as of 6 Mar 2003.
*/
if (memcmp(&VTOC(mi->mi_rootvp)->c_fid, &invalfid,
sizeof(CodaFid)) != 0 || mi->mi_started == 0)
{ /* Found valid root. */
*vpp = mi->mi_rootvp;
mi->mi_started = 1;
struct coda_mntinfo *mi = vftomi(vfsp);
struct vnode **result;
int error;
struct proc *p = td->td_proc;
CodaFid VFid;
static const CodaFid invalfid = INVAL_FID;
/* On Mach, this is vref. On FreeBSD, vref + vn_lock. */
ENTRY;
MARK_ENTRY(CODA_ROOT_STATS);
result = NULL;
if (vfsp == mi->mi_vfsp) {
/*
* Cache the root across calls. We only need to pass the
* request on to Venus if the root vnode is the dummy we
* installed in coda_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(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);
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);
goto exit;
} else if (error == ENODEV || error == EINTR) {
/* Gross hack here! */
/*
* If Venus fails to respond to the CODA_ROOT call, coda_call returns
* ENODEV. Return the uninitialized root vnode to allow vfs
* operations such as unmount to continue. Without this hack,
* there is no way to do an unmount if Venus dies before a
* successful CODA_ROOT call is done. All vnode operations
* will fail.
*/
*vpp = mi->mi_rootvp;
vref(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
MARK_INT_FAIL(CODA_ROOT_STATS);
error = 0;
goto exit;
} else {
CODADEBUG( CODA_ROOT, myprintf(("error %d in CODA_ROOT\n", error)); );
MARK_INT_FAIL(CODA_ROOT_STATS);
goto exit;
}
exit:
return(error);
} 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(vfsp, sbp, td)
register struct mount *vfsp;
struct statfs *sbp;
struct thread *td;
coda_statfs(struct mount *vfsp, struct statfs *sbp, struct thread *td)
{
ENTRY;
MARK_ENTRY(CODA_STATFS_STATS);
if (!CODA_MOUNTED(vfsp)) {
MARK_INT_FAIL(CODA_STATFS_STATS);
return(EINVAL);
}
/* XXX - what to do about f_flags, others? --bnoble */
/* Below This is what AFS does
#define CODA_SFS_SIZ 0x895440
*/
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);
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(vfsp, waitfor, td)
struct mount *vfsp;
int waitfor;
struct thread *td;
coda_sync(struct mount *vfsp, int waitfor, struct thread *td)
{
ENTRY;
MARK_ENTRY(CODA_SYNC_STATS);
MARK_INT_SAT(CODA_SYNC_STATS);
return(0);
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.
/*
* 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
@ -402,54 +398,48 @@ coda_sync(vfsp, waitfor, td)
* vfs_fhtovp_t prototype.
*/
int
coda_fhtovp(vfsp, fhp, nam, vpp, exflagsp, creadanonp)
register struct mount *vfsp;
struct fid *fhp;
struct mbuf *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **creadanonp;
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 = 0;
int error;
struct thread *td = curthread; /* XXX -mach */
struct proc *p = td->td_proc;
CodaFid VFid;
int vtype;
struct cfid *cfid = (struct cfid *)fhp;
struct cnode *cp = NULL;
int error;
struct thread *td = curthread; /* XXX -mach */
struct proc *p = td->td_proc;
CodaFid VFid;
int vtype;
ENTRY;
MARK_ENTRY(CODA_VGET_STATS);
/* Check for vget of control object. */
if (IS_CTL_FID(&cfid->cfid_fid)) {
*vpp = coda_ctlvp;
vref(coda_ctlvp);
MARK_INT_SAT(CODA_VGET_STATS);
return(0);
}
error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, td->td_ucred, p, &VFid, &vtype);
if (error) {
CODADEBUG(CODA_VGET, myprintf(("vget error %d\n",error));)
*vpp = (struct vnode *)0;
} else {
CODADEBUG(CODA_VGET,
myprintf(("vget: %s type %d result %d\n",
coda_f2s(&VFid), vtype, error)); )
cp = make_coda_node(&VFid, vfsp, vtype);
*vpp = CTOV(cp);
}
return(error);
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_mount = coda_mount,
.vfs_root = coda_root,
.vfs_statfs = coda_statfs,
.vfs_sync = coda_sync,
.vfs_unmount = coda_unmount,
};
VFS_SET(coda_vfsops, coda, VFCF_NETWORK);

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,44 +14,47 @@
* 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 $
*
* @(#) 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.
*
* This overlays the fid structure (see vfs.h); only used below and will
* probably go away.
*/
struct cfid {
u_short cfid_len;
u_short padding;
CodaFid cfid_fid;
u_short cfid_len;
u_short padding;
CodaFid cfid_fid;
};
struct mbuf;
struct mount;
int coda_vfsopstats_init(void);
int coda_fhtovp(struct mount *, struct fid *, struct mbuf *, struct vnode **,
int *, struct ucred **);
int coda_vfsopstats_init(void);
int coda_fhtovp(struct mount *, struct fid *, struct mbuf *,
struct vnode **, int *, struct ucred **);
vfs_mount_t coda_mount;
vfs_unmount_t coda_unmount;
vfs_root_t coda_root;
vfs_statfs_t coda_statfs;
vfs_sync_t coda_sync;
#endif /* !_CODA_VFSOPS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
/*-
*
*
* 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
@ -14,24 +14,23 @@
* 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
@ -42,42 +41,44 @@
/*
* This code was written for the Coda filesystem at Carnegie Mellon
* University. Contributers include David Steere, James Kistler, and
* M. Satyanarayanan.
* 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;
/* 1.3 int cfs_select(void *);*/
vop_getattr_t coda_getattr;
vop_setattr_t coda_setattr;
vop_access_t coda_access;
int coda_abortop(void *);
vop_readlink_t coda_readlink;
vop_fsync_t coda_fsync;
vop_inactive_t coda_inactive;
vop_lookup_t coda_lookup;
vop_create_t coda_create;
vop_remove_t coda_remove;
vop_link_t coda_link;
vop_rename_t coda_rename;
vop_mkdir_t coda_mkdir;
vop_rmdir_t coda_rmdir;
vop_symlink_t coda_symlink;
vop_readdir_t coda_readdir;
vop_strategy_t coda_strategy;
vop_reclaim_t coda_reclaim;
vop_lock1_t coda_lock;
vop_unlock_t coda_unlock;
vop_islocked_t coda_islocked;
int coda_vop_error(void *);
vop_pathconf_t coda_pathconf;
/*
* 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_lookup_t coda_lookup;
vop_create_t coda_create;
vop_remove_t coda_remove;
vop_link_t coda_link;
vop_rename_t coda_rename;
vop_mkdir_t coda_mkdir;
vop_rmdir_t coda_rmdir;
vop_symlink_t coda_symlink;
vop_readdir_t coda_readdir;
vop_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);
int coda_grab_vnode(struct cdev *dev, ino_t ino, struct vnode **vpp);
void coda_print_cred(struct ucred *cred);
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_ */