freebsd-20040310

Support for FreeBSD 5.x client.
Both 4.x and 5.x now use vnodes from the system pool instead of attaching
a private vnode to the vcache.
Most of this is from Garrett Wollman <wollman@khavrinen.lcs.mit.edu>,
I just did some integration and made it work again on 4.x.
This commit is contained in:
Jim Rees 2004-03-10 23:01:50 +00:00
parent 9eea027e69
commit d0f33e1d88
40 changed files with 885 additions and 3463 deletions

29
README
View File

@ -33,13 +33,13 @@ A. Creating the proper directory structure.
alpha_dux40
alpha_dux50 (only tested on 5.0A, does not work with 5.1)
i386_fbsd_42, i386_fbsd_43, i386_fbsd_44, i386_fbsd_45,
i386_fbsd_46, i386_fbsd_47, i386_fbsd_50
(gnu make is required for building on FreeBSD)
i386_fbsd_46, i386_fbsd_47, i386_fbsd_50, i386_fbsd_51,
i386_fbsd_52
i386_linux22
i386_linux24
i386_umlinux22
i386_umlinux24
i386_obsd31, i386_obsd32, i386_obsd33
i386_obsd31, i386_obsd32, i386_obsd33, i386_obsd34
rs_aix42
sgi_65 (file server not tested)
sun4_413 (No client support, no fileserver support, db servers only)
@ -155,7 +155,9 @@ E HP-UX 11.0 Notes
F OpenBSD Notes
For now, you need kernel source installed to build OpenAFS.
You need kernel source installed to build OpenAFS. Use the
--with-bsd-kernel-headers= configure option if your kernel source is not
in /usr/src/sys.
There is a package builder in src/packaging/OpenBSD. "sh buildpkg.sh"
should make a package for the client. Use pkg_add to install. The
@ -170,3 +172,22 @@ F OpenBSD Notes
sys/kern/vfs_syscalls.c to a printf and build a new kernel.
You can't run arla and OpenAFS at the same time.
G FreeBSD Notes
The FreeBSD client is very new and untested. Do not trust it for
production work.
You need kernel source installed to build OpenAFS. Use the
--with-bsd-kernel-headers= configure option if your kernel source is not
in /usr/src/sys.
You also need access to your kernel build directory for the opt_global.h
include file. Use the --with-bsd-kernel-build= configure option if your
kernel build is not GENERIC in the standard place.
There is no client package, but you may be able to modify the OpenBSD
package builder (see "OpenBSD Notes" above) or install by hand.
There is no server package, but I am told that "make install" will put
server binaries in /usr/afs.

View File

@ -44,6 +44,9 @@ AC_ARG_WITH(linux-kernel-headers,
AC_ARG_WITH(bsd-kernel-headers,
[ --with-bsd-kernel-headers=path use the kernel headers found at path(optional, defaults to /usr/src/sys)]
)
AC_ARG_WITH(bsd-kernel-build,
[ --with-bsd-kernel-build=path use the kernel build found at path(optional, defaults to KSRC/i386/compile/GENERIC)]
)
AC_ARG_ENABLE(kernel-module,
[ --disable-kernel-module disable compilation of the kernel module (defaults to enabled)],, enable_kernel_module="yes"
)
@ -774,6 +777,19 @@ else
BSD_KERNEL_PATH="/usr/src/sys"
fi
if test "x$with_bsd_kernel_build" != "x"; then
BSD_KERNEL_BUILD="$with_bsd_kernel_build"
else
case $AFS_SYSNAME in
i386_fbsd_4?)
BSD_KERNEL_BUILD="${BSD_KERNEL_PATH}/compile/GENERIC"
;;
i386_fbsd_5?)
BSD_KERNEL_BUILD="${BSD_KERNEL_PATH}/i386/compile/GENERIC"
;;
esac
fi
# Fast restart
if test "$enable_supergroups" = "yes"; then
AC_DEFINE(SUPERGROUPS, 1, [define if you want to have support for nested pts groups])
@ -919,6 +935,7 @@ AC_SUBST(ENABLE_KERNEL_MODULE)
AC_SUBST(LIB_AFSDB)
AC_SUBST(LINUX_KERNEL_PATH)
AC_SUBST(BSD_KERNEL_PATH)
AC_SUBST(BSD_KERNEL_BUILD)
AC_SUBST(LINUX_VERSION)
AC_SUBST(MKAFS_OSTYPE)
AC_SUBST(TOP_OBJDIR)

View File

@ -28,11 +28,10 @@ extern struct mount *afs_cacheVfsp;
void *
osi_UFSOpen(afs_int32 ainode)
{
struct inode *ip;
register struct osi_file *afile = NULL;
struct osi_file *afile;
struct vnode *vp;
extern int cacheDiskType;
afs_int32 code = 0;
int dummy;
afs_int32 code;
AFS_STATCNT(osi_UFSOpen);
if (cacheDiskType != AFS_FCACHE_TYPE_UFS)
@ -40,24 +39,24 @@ osi_UFSOpen(afs_int32 ainode)
afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file));
AFS_GUNLOCK();
#if defined(AFS_FBSD50_ENV)
code = VFS_VGET(afs_cacheVfsp, (ino_t) ainode, LK_EXCLUSIVE, &afile->vnode);
code = VFS_VGET(afs_cacheVfsp, (ino_t) ainode, LK_EXCLUSIVE, &vp);
#else
code =
igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, (ino_t) ainode, &ip,
&dummy);
code = VFS_VGET(afs_cacheVfsp, (ino_t) ainode, &vp);
#endif
AFS_GLOCK();
if (code == 0 && vp->v_type == VNON)
code = ENOENT;
if (code) {
osi_FreeSmallSpace(afile);
osi_Panic("UFSOpen: igetinode failed");
}
#if defined(AFS_FBSD50_ENV)
VOP_UNLOCK(afile->vnode, 0, curthread);
VOP_UNLOCK(vp, 0, curthread);
#else
afile->vnode = ITOV(ip);
VOP_UNLOCK(afile->vnode, 0, curproc);
VOP_UNLOCK(vp, 0, curproc);
#endif
afile->size = VTOI(afile->vnode)->i_size;
afile->vnode = vp;
afile->size = VTOI(vp)->i_size;
afile->offset = 0;
afile->proc = NULL;
afile->inum = ainode; /* for hint validity checking */
@ -73,7 +72,9 @@ afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
MObtainWriteLock(&afs_xosi, 320);
AFS_GUNLOCK();
#if defined(AFS_FBSD50_ENV)
vn_lock(afile->vnode, LK_EXCLUSIVE | LK_RETRY, curthread);
code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
VOP_UNLOCK(afile->vnode, LK_EXCLUSIVE, curthread);
#else
code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
#endif
@ -104,25 +105,41 @@ int
osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
{
struct vattr tvattr;
struct vnode *vp;
register afs_int32 code;
struct osi_stat tstat;
AFS_STATCNT(osi_Truncate);
/* This routine only shrinks files, and most systems
MObtainWriteLock(&afs_xosi, 321);
vp = afile->vnode;
/*
* This routine only shrinks files, and most systems
* have very slow truncates, even when the file is already
* small enough. Check now and save some time.
*/
code = afs_osi_Stat(afile, &tstat);
if (code || tstat.size <= asize)
return code;
MObtainWriteLock(&afs_xosi, 321);
VATTR_NULL(&tvattr);
tvattr.va_size = asize;
AFS_GUNLOCK();
#if defined(AFS_FBSD50_ENV)
code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
#else
code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
#endif
if (code != 0 || tvattr.va_size <= asize)
goto out;
VATTR_NULL(&tvattr);
tvattr.va_size = asize;
#if defined(AFS_FBSD50_ENV)
code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curthread);
#else
code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curproc);
#endif
out:
#if defined(AFS_FBSD50_ENV)
VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
#else
VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
#endif
AFS_GLOCK();
MReleaseWriteLock(&afs_xosi);

View File

@ -53,14 +53,14 @@ getinode(fs, dev, inode, ipp, perror)
#else
simple_lock(&mountlist_slock);
#endif
if (mp = TAILQ_FIRST(&mountlist))
if ((mp = TAILQ_FIRST(&mountlist)) != NULL)
do {
/*
* XXX Also do the test for MFS
*/
#undef m_data
#undef m_next
if (mp->mnt_stat.f_type == MOUNT_UFS) {
if (!strcmp(mp->mnt_stat.f_fstypename, MOUNT_UFS)) {
ump = VFSTOUFS(mp);
if (ump->um_fs == NULL)
break;

View File

@ -21,8 +21,9 @@
#include <sys/lock.h>
#include <sys/time.h>
/* #include <kern/sched_prim.h> */
/* #include <sys/unix_defs.h> */
#if defined(AFS_FBSD50_ENV)
#include <sys/mutex.h>
#endif
extern struct simplelock afs_rxglobal_lock;
@ -42,7 +43,13 @@ extern struct simplelock afs_rxglobal_lock;
#define iodone biodone
#endif
#define osi_vnhold(avc,r) do { VN_HOLD((struct vnode *)(avc)); } while (0)
#define osi_vnhold(avc,r) vref(AFSTOV(avc))
#undef vSetVfsp
#define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp)
#undef vSetType
#define vSetType(vc, type) AFSTOV(vc)->v_type = (type)
#undef vType
#define vType(vc) AFSTOV(vc)->v_type
#undef gop_lookupname
#define gop_lookupname osi_lookupname
@ -52,7 +59,12 @@ extern struct simplelock afs_rxglobal_lock;
#define afs_strcat(s1, s2) strcat((s1), (s2))
#ifdef KERNEL
extern struct lock afs_global_lock;
#undef afs_osi_Alloc_NoSleep
#define afs_osi_Alloc_NoSleep(size) osi_fbsd_alloc((size), 0)
#define VN_RELE(vp) vrele(vp)
#define VN_HOLD(vp) VREF(vp)
#if defined(AFS_FBSD50_ENV)
#define VT_AFS "afs"
@ -64,26 +76,16 @@ extern struct lock afs_global_lock;
#define simple_unlock(x) mtx_unlock(x)
#define gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(cred),(aresid), curthread)
extern struct thread *afs_global_owner;
#define AFS_GLOCK() \
do { \
osi_Assert(curthread); \
lockmgr(&afs_global_lock, LK_EXCLUSIVE, 0, curthread); \
osi_Assert(afs_global_owner == 0); \
afs_global_owner = curthread; \
} while (0)
#define AFS_GUNLOCK() \
do { \
osi_Assert(curthread); \
osi_Assert(afs_global_owner == curthread); \
afs_global_owner = 0; \
lockmgr(&afs_global_lock, LK_RELEASE, 0, curthread); \
} while(0)
#define ISAFS_GLOCK() (afs_global_owner == curthread && curthread)
extern struct mtx afs_global_mtx;
#define AFS_GLOCK() mtx_lock(&afs_global_mtx)
#define AFS_GUNLOCK() mtx_unlock(&afs_global_mtx)
#define ISAFS_GLOCK() (mtx_owned(&afs_global_mtx))
#else /* FBSD50 */
extern struct lock afs_global_lock;
#define osi_curcred() (curproc->p_cred->pc_ucred)
#define afs_suser() (!suser(curproc))
#define getpid() curproc
#define gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(aresid), curproc)

View File

@ -30,30 +30,19 @@ RCSID
#define curproc curthread
#endif
#ifndef AFS_FBSD50_ENV
/*
* afs_suser() returns true if the caller is superuser, false otherwise.
*
* Note that it must NOT set errno.
*/
afs_suser()
{
int error;
if (suser(curproc) == 0) {
return (1);
}
return (0);
}
#endif
int
osi_lookupname(char *aname, enum uio_seg seg, int followlink,
struct vnode **dirvpp, struct vnode **vpp)
{
struct nameidata n;
int flags, error;
int flags, error, wasowned;
#ifdef AFS_FBSD50_ENV
wasowned = mtx_owned(&afs_global_mtx);
if (wasowned)
mtx_unlock(&afs_global_mtx);
#endif
flags = 0;
flags = LOCKLEAF;
if (followlink)
@ -62,8 +51,13 @@ osi_lookupname(char *aname, enum uio_seg seg, int followlink,
flags |= NOFOLLOW;
/* if (dirvpp) flags|=WANTPARENT; *//* XXX LOCKPARENT? */
NDINIT(&n, LOOKUP, flags, seg, aname, curproc);
if (error = namei(&n))
if ((error = namei(&n)) != 0) {
#ifdef AFS_FBSD50_ENV
if (wasowned)
mtx_lock(&afs_global_mtx);
#endif
return error;
}
*vpp = n.ni_vp;
/*
if (dirvpp)
@ -72,6 +66,10 @@ osi_lookupname(char *aname, enum uio_seg seg, int followlink,
/* should we do this? */
VOP_UNLOCK(n.ni_vp, 0, curproc);
NDFREE(&n, NDF_ONLY_PNBUF);
#ifdef AFS_FBSD50_ENV
if (wasowned)
mtx_lock(&afs_global_mtx);
#endif
return 0;
}
@ -103,3 +101,74 @@ afs_osi_SetTime(osi_timeval_t * atv)
AFS_GLOCK();
#endif
}
/*
* Replace all of the bogus special-purpose memory allocators...
*/
void *
osi_fbsd_alloc(size_t size, int dropglobal)
{
void *rv;
#ifdef AFS_FBSD50_ENV
int wasowned;
if (dropglobal) {
wasowned = mtx_owned(&afs_global_mtx);
if (wasowned)
mtx_unlock(&afs_global_mtx);
rv = malloc(size, M_AFS, M_WAITOK);
if (wasowned)
mtx_lock(&afs_global_mtx);
} else
#endif
rv = malloc(size, M_AFS, M_NOWAIT);
return (rv);
}
void
osi_fbsd_free(void *p)
{
free(p, M_AFS);
}
void
osi_AllocMoreSSpace(afs_int32 preallocs)
{
;
}
void
osi_FreeLargeSpace(void *p)
{
osi_fbsd_free(p);
}
void
osi_FreeSmallSpace(void *p)
{
osi_fbsd_free(p);
}
void *
osi_AllocLargeSpace(size_t size)
{
AFS_ASSERT_GLOCK();
AFS_STATCNT(osi_AllocLargeSpace);
return (osi_fbsd_alloc(size, 1));
}
void *
osi_AllocSmallSpace(size_t size)
{
AFS_ASSERT_GLOCK();
AFS_STATCNT(osi_AllocSmallSpace);
return (osi_fbsd_alloc(size, 1));
}
void
shutdown_osinet(void)
{
;
}

View File

@ -37,8 +37,8 @@ afs_module_handler(module_t mod, int what, void *arg)
{
static sy_call_t *old_handler;
static int inited = 0;
int error;
error = 0;
int error = 0;
switch (what) {
case MOD_LOAD:
if (inited) {
@ -60,8 +60,10 @@ afs_module_handler(module_t mod, int what, void *arg)
vfs_register(&afs_vfsconf); /* doesn't fail */
vfs_add_vnodeops(&afs_vnodeop_opv_desc);
osi_Init();
#if 0
sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
sysent[SYS_ioctl].sy_call = afs_xioctl;
#endif
old_handler = sysent[AFS_SYSCALL].sy_call;
sysent[AFS_SYSCALL].sy_call = afs3_syscall;
sysent[AFS_SYSCALL].sy_narg = 5;
@ -86,8 +88,10 @@ afs_module_handler(module_t mod, int what, void *arg)
break;
}
vfs_rm_vnodeops(&afs_vnodeop_opv_desc);
#if 0
sysent[SYS_ioctl].sy_call = ioctl;
sysent[SYS_setgroups].sy_call = setgroups;
#endif
sysent[AFS_SYSCALL].sy_narg = 0;
sysent[AFS_SYSCALL].sy_call = old_handler;
break;

View File

@ -20,8 +20,14 @@ extern afs_rwlock_t afs_xosi;
/* osi_misc.c */
extern int osi_lookupname(char *aname, enum uio_seg seg, int followlink,
struct vnode **dirvpp, struct vnode **vpp);
extern void *osi_fbsd_alloc(size_t size, int dropglobal);
extern void osi_fbsd_free(void *p);
/* osi_vfsops.c */
#ifdef AFS_FBSD50_ENV
extern int afs_statfs(struct mount *mp, struct statfs *abp, struct thread *th);
#else
extern int afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p);
#endif
#endif /* _OSI_PROTO_H_ */

View File

@ -18,32 +18,52 @@ RCSID
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
#ifndef AFS_FBSD50_ENV
static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
static char waitV;
#endif
void
afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
{
AFS_STATCNT(osi_InitWaitHandle);
achandle->proc = (caddr_t) 0;
#ifdef AFS_FBSD50_ENV
cv_init(&achandle->wh_condvar, "afscondvar");
achandle->wh_inited = 1;
#else
achandle->proc = NULL;
#endif
}
/* cancel osi_Wait */
/* XXX
* I can't tell -- is this supposed to be cv_signal() or cv_waitq_remove()?
* Or perhaps cv_broadcast()?
* Assuming cv_signal() is the desired meaning. -GAW
*/
void
afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
{
#ifndef AFS_FBSD50_ENV
caddr_t proc;
#endif
AFS_STATCNT(osi_CancelWait);
#ifdef AFS_FBSD50_ENV
/* XXX should not be necessary */
if (!achandle->wh_inited)
return;
AFS_ASSERT_GLOCK();
cv_signal(&achandle->wh_condvar);
#else
proc = achandle->proc;
if (proc == 0)
return;
achandle->proc = (caddr_t) 0; /* so dude can figure out he was signalled */
achandle->proc = NULL; /* so dude can figure out he was signalled */
afs_osi_Wakeup(&waitV);
#endif
}
/* afs_osi_Wait
@ -54,31 +74,56 @@ int
afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
{
int code;
#ifdef AFS_FBSD50_ENV
struct timeval tv;
int ticks;
#else
afs_int32 endTime;
#endif
AFS_STATCNT(osi_Wait);
#ifdef AFS_FBSD50_ENV
tv.tv_sec = ams / 1000;
tv.tv_usec = (ams % 1000) * 1000;
ticks = tvtohz(&tv);
AFS_ASSERT_GLOCK();
if (ahandle == NULL) {
/* This is nasty and evil and rude. */
code = msleep(&tv, &afs_global_mtx, (aintok ? PPAUSE|PCATCH : PVFS),
"afswait", ticks);
} else {
if (!ahandle->wh_inited)
afs_osi_InitWaitHandle(ahandle); /* XXX should not be needed */
if (aintok)
code = cv_timedwait_sig(&ahandle->wh_condvar, &afs_global_mtx,
ticks);
else
code = cv_timedwait(&ahandle->wh_condvar, &afs_global_mtx, ticks);
}
#else
endTime = osi_Time() + (ams / 1000);
if (ahandle)
ahandle->proc = (caddr_t) curproc;
do {
AFS_ASSERT_GLOCK();
code = 0;
code = osi_TimedSleep(&waitV, ams, aintok);
if (code)
break; /* if something happened, quit now */
/* if we we're cancelled, quit now */
if (ahandle && (ahandle->proc == (caddr_t) 0)) {
if (ahandle && (ahandle->proc == NULL)) {
/* we've been signalled */
break;
}
} while (osi_Time() < endTime);
#endif
return code;
}
/*
* All this gluck should probably also be replaced with CVs.
*/
typedef struct afs_event {
struct afs_event *next; /* next in hash chain */
char *event; /* lwp event: an address */
@ -140,9 +185,13 @@ afs_osi_Sleep(void *event)
seq = evp->seq;
while (seq == evp->seq) {
AFS_ASSERT_GLOCK();
#ifdef AFS_FBSD50_ENV
msleep(event, &afs_global_mtx, PVFS, "afsslp", 0);
#else
AFS_GUNLOCK();
tsleep(event, PVFS, "afs_osi_Sleep", 0);
AFS_GLOCK();
#endif
}
relevent(evp);
}
@ -154,6 +203,7 @@ afs_osi_SleepSig(void *event)
return 0;
}
#ifndef AFS_FBSD50_ENV
/* osi_TimedSleep
*
* Arguments:
@ -188,7 +238,7 @@ osi_TimedSleep(char *event, afs_int32 ams, int aintok)
relevent(evp);
return code;
}
#endif /* not AFS_FBSD50_ENV */
int
afs_osi_Wakeup(void *event)

View File

@ -16,48 +16,22 @@ struct vcache *afs_globalVp = 0;
struct mount *afs_globalVFS = 0;
int afs_pbuf_freecnt = -1;
int
afs_quotactl()
{
return EOPNOTSUPP;
}
#ifdef AFS_FBSD50_ENV
#define THREAD_OR_PROC struct thread *p
#else
#define THREAD_OR_PROC struct proc *p
#endif
int
afs_fhtovp(mp, fhp, vpp)
struct mount *mp;
struct fid *fhp;
struct vnode **vpp;
{
return (EINVAL);
}
int
afs_vptofh(vp, fhp)
struct vnode *vp;
struct fid *fhp;
{
return (EINVAL);
}
int
afs_start(mp, flags, p)
struct mount *mp;
int flags;
struct proc *p;
afs_start(struct mount *mp, int flags, THREAD_OR_PROC)
{
afs_pbuf_freecnt = nswbuf / 2 + 1;
return (0); /* nothing to do. ? */
}
int
afs_mount(mp, path, data, ndp, p)
register struct mount *mp;
char *path;
caddr_t data;
struct nameidata *ndp;
struct proc *p;
afs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
THREAD_OR_PROC)
{
/* ndp contains the mounted-from device. Just ignore it.
* we also don't care about our proc struct. */
@ -91,12 +65,16 @@ afs_mount(mp, path, data, ndp, p)
}
int
afs_unmount(mp, flags, p)
struct mount *mp;
int flags;
struct proc *p;
afs_unmount(struct mount *mp, int flags, THREAD_OR_PROC)
{
/*
* Release any remaining vnodes on this mount point.
* The `1' means that we hold one extra reference on
* the root vnode (this is just a guess right now).
* This has to be done outside the global lock.
*/
vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0);
AFS_GLOCK();
AFS_STATCNT(afs_unmount);
afs_globalVFS = 0;
@ -114,24 +92,27 @@ afs_root(struct mount *mp, struct vnode **vpp)
register struct vcache *tvp = 0;
#ifdef AFS_FBSD50_ENV
struct thread *td = curthread;
struct ucred cr = *td->td_ucred;
struct ucred *cr = td->td_ucred;
#else
struct proc *p = curproc;
struct ucred cr = *p->p_cred->pc_ucred;
struct ucred *cr = p->p_cred->pc_ucred;
#endif
AFS_GLOCK();
AFS_STATCNT(afs_root);
crhold(cr);
if (afs_globalVp && (afs_globalVp->states & CStatd)) {
tvp = afs_globalVp;
error = 0;
} else {
tryagain:
if (afs_globalVp) {
afs_PutVCache(afs_globalVp);
/* vrele() needed here or not? */
afs_globalVp = NULL;
}
if (!(error = afs_InitReq(&treq, &cr)) && !(error = afs_CheckInit())) {
if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
/* we really want this to stay around */
if (tvp)
@ -141,57 +122,45 @@ afs_root(struct mount *mp, struct vnode **vpp)
}
}
if (tvp) {
osi_vnhold(tvp, 0);
AFS_GUNLOCK();
struct vnode *vp = AFSTOV(tvp);
#ifdef AFS_FBSD50_ENV
vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, td);
ASSERT_VI_UNLOCKED(vp, "afs_root");
#endif
AFS_GUNLOCK();
/*
* I'm uncomfortable about this. Shouldn't this happen at a
* higher level, and shouldn't we busy the top-level directory
* to prevent recycling?
*/
#ifdef AFS_FBSD50_ENV
error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
vp->v_vflag |= VV_ROOT;
#else
vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
error = vget(vp, LK_EXCLUSIVE | LK_RETRY, p);
vp->v_flag |= VROOT;
#endif
AFS_GLOCK();
if (error != 0)
goto tryagain;
afs_globalVFS = mp;
*vpp = AFSTOV(tvp);
tvp->v.v_flag |= VROOT;
*vpp = vp;
}
afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
ICL_TYPE_INT32, error);
AFS_GUNLOCK();
crfree(cr);
return error;
}
int
afs_vget(mp, lfl, vp)
struct mount *mp;
struct vnode *vp;
int lfl;
{
#ifdef AFS_FBSD50_ENV
return EOPNOTSUPP;
#else
int error;
printf("vget called. help!\n");
if (vp->v_usecount < 0) {
vprint("bad usecount", vp);
panic("afs_vget");
}
error = vget(vp, lfl, curproc);
if (!error)
insmntque(vp, afs_globalVFS); /* take off free list */
return error;
#endif
}
int
afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p)
afs_statfs(struct mount *mp, struct statfs *abp, THREAD_OR_PROC)
{
AFS_GLOCK();
AFS_STATCNT(afs_statfs);
#if 0
abp->f_type = MOUNT_AFS;
#endif
abp->f_bsize = mp->vfs_bsize;
abp->f_iosize = mp->vfs_bsize;
@ -217,22 +186,11 @@ afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p)
}
int
afs_sync(mp, waitfor, cred, p)
struct mount *mp;
int waitfor;
struct ucred *cred;
struct prioc *p;
afs_sync(struct mount *mp, int waitfor, struct ucred *cred, THREAD_OR_PROC)
{
return 0;
}
int
afs_sysctl()
{
return EOPNOTSUPP;
}
int
afs_init(struct vfsconf *vfc)
{
@ -244,18 +202,17 @@ struct vfsops afs_vfsops = {
afs_start,
afs_unmount,
afs_root,
afs_quotactl,
vfs_stdquotactl,
afs_statfs,
afs_sync,
afs_vget,
afs_fhtovp,
#ifdef AFS_FBSD50_ENV
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
#endif
afs_vptofh,
vfs_stdvptofh,
afs_init,
#ifdef AFS_FBSD50_ENV
vfs_stduninit,
vfs_stdextattrctl,
#ifdef AFS_FBSD50_ENV
NULL,
#endif
afs_sysctl
};

View File

@ -32,6 +32,33 @@ RCSID
#include <limits.h>
#include <float.h>
/*
* FreeBSD implementation notes:
* Most of these operations require us to frob vm_objects. Most
* functions require that the object be locked (with VM_OBJECT_LOCK)
* on entry and leave it locked on exit. In order to get the
* vm_object itself we call VOP_GETVOBJECT on the vnode; the
* locking protocol requires that we do so with the heavy vnode lock
* held and the vnode interlock unlocked, and it returns the same
* way.
*
* The locking protocol for vnodes is defined in
* kern/vnode_if.src and sys/vnode.h; the locking is still a work in
* progress, so some fields are (as of 5.1) still protected by Giant
* rather than an explicit lock.
*/
#ifdef AFS_FBSD50_ENV
#define lock_vnode(v) vn_lock((v), LK_EXCLUSIVE | LK_RETRY, curthread)
#define unlock_vnode(v) VOP_UNLOCK((v), 0, curthread)
#else
#define lock_vnode(v) vn_lock((v), LK_EXCLUSIVE | LK_RETRY, curproc)
#define unlock_vnode(v) VOP_UNLOCK((v), 0, curproc)
/* need splvm() protection? */
#define VM_OBJECT_LOCK(o)
#define VM_OBJECT_UNLOCK(o)
#endif
/* Try to discard pages, in order to recycle a vcache entry.
*
* We also make some sanity checks: ref count, open count, held locks.
@ -47,6 +74,8 @@ RCSID
* therefore obsolescent.
*
* OSF/1 Locking: VN_LOCK has been called.
* XXX - should FreeBSD have done this, too? Certainly looks like it.
* Maybe better to just call vnode_pager_setsize()?
*/
int
osi_VM_FlushVCache(struct vcache *avc, int *slept)
@ -65,8 +94,9 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept)
AFS_GUNLOCK();
vp = AFSTOV(avc);
simple_lock(&vp->v_interlock);
lock_vnode(vp);
if (VOP_GETVOBJECT(vp, &obj) == 0) {
VM_OBJECT_LOCK(obj);
vm_object_page_remove(obj, 0, 0, FALSE);
#if 0
if (obj->ref_count == 0) {
@ -76,8 +106,9 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept)
SetAfsVnode(vp);
}
#endif
VM_OBJECT_UNLOCK(obj);
}
simple_unlock(&vp->v_interlock);
unlock_vnode(vp);
AFS_GLOCK();
return 0;
@ -99,25 +130,37 @@ osi_VM_StoreAllSegments(struct vcache *avc)
AFS_GUNLOCK();
tries = 5;
vp = AFSTOV(avc);
/*
* I don't understand this. Why not just call vm_object_page_clean()
* and be done with it? I particularly don't understand why we're calling
* vget() here. Is there some reason to believe that the vnode might
* be being recycled at this point? I don't think there's any need for
* this loop, either -- if we keep the vnode locked all the time,
* that and the object lock will prevent any new pages from appearing.
* The loop is what causes the race condition. -GAW
*/
do {
anyio = 0;
simple_lock(&vp->v_interlock);
lock_vnode(vp);
if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) {
/* XXX - obj locking? */
unlock_vnode(vp);
#ifdef AFS_FBSD50_ENV
if (!vget(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread)) {
if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) {
#else
if (!vget
(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ,
curproc)) {
if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) {
#endif
if (VOP_GETVOBJECT(vp, &obj) == 0) {
VM_OBJECT_LOCK(obj);
vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
VM_OBJECT_UNLOCK(obj);
anyio = 1;
}
vput(vp);
}
} else
simple_unlock(&vp->v_interlock);
unlock_vnode(vp);
} while (anyio && (--tries > 0));
AFS_GLOCK();
ObtainWriteLock(&avc->lock, 94);
@ -145,29 +188,41 @@ osi_VM_TryToSmush(struct vcache *avc, struct AFS_UCRED *acred, int sync)
vp = AFSTOV(avc);
do {
anyio = 0;
simple_lock(&vp->v_interlock);
lock_vnode(vp);
/* See the comments above. */
if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) {
/* XXX - obj locking */
unlock_vnode(vp);
#ifdef AFS_FBSD50_ENV
if (!vget(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread)) {
if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) {
#else
if (!vget
(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ,
curproc)) {
if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) {
#endif
if (VOP_GETVOBJECT(vp, &obj) == 0) {
VM_OBJECT_LOCK(obj);
/*
* Do we really want OBJPC_SYNC? OBJPC_INVAL would be
* faster, if invalidation is really what we are being
* asked to do. (It would make more sense, too, since
* otherwise this function is practically identical to
* osi_VM_StoreAllSegments().) -GAW
*/
vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
VM_OBJECT_UNLOCK(obj);
anyio = 1;
}
vput(vp);
}
} else
simple_unlock(&vp->v_interlock);
unlock_vnode(vp);
} while (anyio && (--tries > 0));
simple_lock(&vp->v_interlock);
lock_vnode(vp);
if (VOP_GETVOBJECT(vp, &obj) == 0) {
VM_OBJECT_LOCK(obj);
vm_object_page_remove(obj, 0, 0, FALSE);
VM_OBJECT_UNLOCK(obj);
}
simple_unlock(&vp->v_interlock);
unlock_vnode(vp);
/*vinvalbuf(AFSTOV(avc),0, NOCRED, curproc, 0,0); */
AFS_GLOCK();
ObtainWriteLock(&avc->lock, 59);
@ -184,11 +239,12 @@ osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp)
struct vm_object *obj;
vp = AFSTOV(avc);
simple_lock(&vp->v_interlock);
ASSERT_VOP_LOCKED(vp, __func__);
if (VOP_GETVOBJECT(vp, &obj) == 0) {
VM_OBJECT_LOCK(obj);
vm_object_page_remove(obj, 0, 0, FALSE);
VM_OBJECT_UNLOCK(obj);
}
simple_unlock(&vp->v_interlock);
/*vinvalbuf(AFSTOV(avc),0, NOCRED, curproc, 0,0); */
}

View File

@ -1,3 +1,49 @@
/*
* A large chunk of this file appears to be copied directly from
* sys/nfsclient/nfs_bio.c, which has the following license:
*/
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
*/
/*
* Pursuant to a statement of U.C. Berkeley dated 1999-07-22, this license
* is amended to drop clause (3) above.
*/
#include <afsconfig.h>
#include <afs/param.h>
@ -9,6 +55,7 @@ RCSID
#include <afs/afs_stats.h> /* statistics */
#include <sys/malloc.h>
#include <sys/namei.h>
#include <sys/unistd.h>
#ifndef AFS_FBSD50_ENV
#include <vm/vm_zone.h>
#endif
@ -31,6 +78,7 @@ int afs_vop_write(struct vop_write_args *);
int afs_vop_getpages(struct vop_getpages_args *);
int afs_vop_putpages(struct vop_putpages_args *);
int afs_vop_ioctl(struct vop_ioctl_args *);
static int afs_vop_pathconf(struct vop_pathconf_args *);
int afs_vop_poll(struct vop_poll_args *);
#ifndef AFS_FBSD50_ENV
int afs_vop_mmap(struct vop_mmap_args *);
@ -59,7 +107,7 @@ int afs_vop_advlock(struct vop_advlock_args *);
/* Global vfs data structures for AFS. */
vop_t **afs_vnodeop_p;
struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
{&vop_default_desc, (vop_t *) vop_eopnotsupp},
{&vop_default_desc, (vop_t *) vop_defaultop},
{&vop_access_desc, (vop_t *) afs_vop_access}, /* access */
{&vop_advlock_desc, (vop_t *) afs_vop_advlock}, /* advlock */
{&vop_bmap_desc, (vop_t *) afs_vop_bmap}, /* bmap */
@ -76,10 +124,8 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
{&vop_getvobject_desc, (vop_t *) vop_stdgetvobject},
{&vop_putpages_desc, (vop_t *) afs_vop_putpages}, /* write */
{&vop_inactive_desc, (vop_t *) afs_vop_inactive}, /* inactive */
{&vop_islocked_desc, (vop_t *) afs_vop_islocked}, /* islocked */
{&vop_lease_desc, (vop_t *) vop_null},
{&vop_link_desc, (vop_t *) afs_vop_link}, /* link */
{&vop_lock_desc, (vop_t *) afs_vop_lock}, /* lock */
{&vop_lookup_desc, (vop_t *) afs_vop_lookup}, /* lookup */
{&vop_mkdir_desc, (vop_t *) afs_vop_mkdir}, /* mkdir */
{&vop_mknod_desc, (vop_t *) afs_vop_mknod}, /* mknod */
@ -87,6 +133,7 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
{&vop_mmap_desc, (vop_t *) afs_vop_mmap}, /* mmap */
#endif
{&vop_open_desc, (vop_t *) afs_vop_open}, /* open */
{&vop_pathconf_desc, (vop_t *) afs_vop_pathconf}, /* pathconf */
{&vop_poll_desc, (vop_t *) afs_vop_poll}, /* select */
{&vop_print_desc, (vop_t *) afs_vop_print}, /* print */
{&vop_read_desc, (vop_t *) afs_vop_read}, /* read */
@ -99,7 +146,6 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
{&vop_setattr_desc, (vop_t *) afs_vop_setattr}, /* setattr */
{&vop_strategy_desc, (vop_t *) afs_vop_strategy}, /* strategy */
{&vop_symlink_desc, (vop_t *) afs_vop_symlink}, /* symlink */
{&vop_unlock_desc, (vop_t *) afs_vop_unlock}, /* unlock */
{&vop_write_desc, (vop_t *) afs_vop_write}, /* write */
{&vop_ioctl_desc, (vop_t *) afs_vop_ioctl}, /* XXX ioctl */
/*{ &vop_seek_desc, afs_vop_seek }, *//* seek */
@ -122,7 +168,98 @@ struct vnodeopv_desc afs_vnodeop_opv_desc =
#define a_p a_td
#endif
/*
* Mosty copied from sys/ufs/ufs/ufs_vnops.c:ufs_pathconf().
* We should know the correct answers to these questions with
* respect to the AFS protocol (which may differ from the UFS
* values) but for the moment this will do.
*/
static int
afs_vop_pathconf(struct vop_pathconf_args *ap)
{
int error;
error = 0;
switch (ap->a_name) {
case _PC_LINK_MAX:
*ap->a_retval = LINK_MAX;
break;
case _PC_NAME_MAX:
*ap->a_retval = NAME_MAX;
break;
case _PC_PATH_MAX:
*ap->a_retval = PATH_MAX;
break;
case _PC_PIPE_BUF:
*ap->a_retval = PIPE_BUF;
break;
case _PC_CHOWN_RESTRICTED:
*ap->a_retval = 1;
break;
case _PC_NO_TRUNC:
*ap->a_retval = 1;
break;
#ifdef _PC_ACL_EXTENDED
case _PC_ACL_EXTENDED:
*ap->a_retval = 0;
break;
case _PC_ACL_PATH_MAX:
*ap->a_retval = 3;
break;
#endif
#ifdef _PC_MAC_PRESENT
case _PC_MAC_PRESENT:
*ap->a_retval = 0;
break;
#endif
#ifdef _PC_ASYNC_IO
case _PC_ASYNC_IO:
/* _PC_ASYNC_IO should have been handled by upper layers. */
KASSERT(0, ("_PC_ASYNC_IO should not get here"));
error = EINVAL;
break;
case _PC_PRIO_IO:
*ap->a_retval = 0;
break;
case _PC_SYNC_IO:
*ap->a_retval = 0;
break;
#endif
#ifdef _PC_ALLOC_SIZE_MIN
case _PC_ALLOC_SIZE_MIN:
*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_bsize;
break;
#endif
#ifdef _PC_FILESIZEBITS
case _PC_FILESIZEBITS:
*ap->a_retval = 32; /* XXX */
break;
#endif
#ifdef _PC_REC_INCR_XFER_SIZE
case _PC_REC_INCR_XFER_SIZE:
*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
break;
case _PC_REC_MAX_XFER_SIZE:
*ap->a_retval = -1; /* means ``unlimited'' */
break;
case _PC_REC_MIN_XFER_SIZE:
*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
break;
case _PC_REC_XFER_ALIGN:
*ap->a_retval = PAGE_SIZE;
break;
#endif
#ifdef _PC_SYMLINK_MAX
case _PC_SYMLINK_MAX:
*ap->a_retval = MAXPATHLEN;
break;
#endif
default:
error = EINVAL;
break;
}
return (error);
}
int
afs_vop_lookup(ap)
@ -397,15 +534,16 @@ afs_vop_read(ap)
return code;
}
/* struct vop_getpages_args {
* struct vnode *a_vp;
* vm_page_t *a_m;
* int a_count;
* int a_reqpage;
* vm_oofset_t a_offset;
* };
*/
int
afs_vop_getpages(ap)
struct vop_getpages_args /* {
* struct vnode *a_vp;
* vm_page_t *a_m;
* int a_count;
* int a_reqpage;
* vm_oofset_t a_offset;
* } */ *ap;
afs_vop_getpages(struct vop_getpages_args *ap)
{
int code;
int i, nextoff, size, toff, npages;
@ -413,9 +551,16 @@ afs_vop_getpages(ap)
struct iovec iov;
struct buf *bp;
vm_offset_t kva;
struct vcache *avc = VTOAFS(ap->a_vp);
vm_object_t object;
struct vnode *vp;
struct vcache *avc;
if (avc->v.v_object == NULL) {
#ifdef AFS_FBSD50_ENV
GIANT_REQUIRED;
#endif
vp = ap->a_vp;
avc = VTOAFS(vp);
if ((object = vp->v_object) == NULL) {
printf("afs_getpages: called with non-merged cache vnode??\n");
return VM_PAGER_ERROR;
}
@ -429,6 +574,10 @@ afs_vop_getpages(ap)
{
vm_page_t m = ap->a_m[ap->a_reqpage];
#ifdef AFS_FBSD50_ENV
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
#endif
if (m->valid != 0) {
/* handled by vm_fault now */
/* vm_page_zero_invalid(m, TRUE); */
@ -436,12 +585,26 @@ afs_vop_getpages(ap)
if (i != ap->a_reqpage)
vm_page_free(ap->a_m[i]);
}
#ifdef AFS_FBSD50_ENV
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
#endif
return (0);
}
#ifdef AFS_FBSD50_ENV
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
#endif
}
bp = getpbuf(&afs_pbuf_freecnt);
kva = (vm_offset_t) bp->b_data;
pmap_qenter(kva, ap->a_m, npages);
#ifdef AFS_FBSD50_ENV
cnt.v_vnodein++;
cnt.v_vnodepgsin += npages;
#endif
iov.iov_base = (caddr_t) kva;
iov.iov_len = ap->a_count;
uio.uio_iov = &iov;
@ -455,6 +618,7 @@ afs_vop_getpages(ap)
#else
uio.uio_procp = curproc;
#endif
AFS_GLOCK();
afs_BozonLock(&avc->pvnLock, avc);
osi_FlushPages(avc, osi_curcred()); /* hold bozon lock, but not basic vnode lock */
@ -464,14 +628,28 @@ afs_vop_getpages(ap)
pmap_qremove(kva, npages);
relpbuf(bp, &afs_pbuf_freecnt);
if (code && (uio.uio_resid == ap->a_count)) {
#ifdef AFS_FBSD50_ENV
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
#endif
for (i = 0; i < npages; ++i) {
if (i != ap->a_reqpage)
vm_page_free(ap->a_m[i]);
}
#ifdef AFS_FBSD50_ENV
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
#endif
return VM_PAGER_ERROR;
}
size = ap->a_count - uio.uio_resid;
#ifdef AFS_FBSD50_ENV
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
#endif
for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
vm_page_t m;
nextoff = toff + PAGE_SIZE;
@ -519,6 +697,10 @@ afs_vop_getpages(ap)
}
}
}
#ifdef AFS_FBSD50_ENV
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
#endif
return 0;
}
@ -543,16 +725,22 @@ afs_vop_write(ap)
return code;
}
/*-
* struct vop_putpages_args {
* struct vnode *a_vp;
* vm_page_t *a_m;
* int a_count;
* int a_sync;
* int *a_rtvals;
* vm_oofset_t a_offset;
* };
*/
/*
* All of the pages passed to us in ap->a_m[] are already marked as busy,
* so there is no additional locking required to set their flags. -GAW
*/
int
afs_vop_putpages(ap)
struct vop_putpages_args /* {
* struct vnode *a_vp;
* vm_page_t *a_m;
* int a_count;
* int a_sync;
* int *a_rtvals;
* vm_oofset_t a_offset;
* } */ *ap;
afs_vop_putpages(struct vop_putpages_args *ap)
{
int code;
int i, size, npages, sync;
@ -560,22 +748,36 @@ afs_vop_putpages(ap)
struct iovec iov;
struct buf *bp;
vm_offset_t kva;
struct vcache *avc = VTOAFS(ap->a_vp);
struct vnode *vp;
struct vcache *avc;
if (avc->v.v_object == NULL) {
#ifdef AFS_FBSD50_ENV
GIANT_REQUIRED;
#endif
vp = ap->a_vp;
avc = VTOAFS(vp);
/* Perhaps these two checks should just be KASSERTs instead... */
if (vp->v_object == NULL) {
printf("afs_putpages: called with non-merged cache vnode??\n");
return VM_PAGER_ERROR;
return VM_PAGER_ERROR; /* XXX I think this is insufficient */
}
if (vType(avc) != VREG) {
printf("afs_putpages: not VREG");
return VM_PAGER_ERROR;
return VM_PAGER_ERROR; /* XXX I think this is insufficient */
}
npages = btoc(ap->a_count);
for (i = 0; i < npages; i++)
ap->a_rtvals[i] = VM_PAGER_AGAIN;
bp = getpbuf(&afs_pbuf_freecnt);
kva = (vm_offset_t) bp->b_data;
pmap_qenter(kva, ap->a_m, npages);
#ifdef AFS_FBSD50_ENV
cnt.v_vnodeout++;
cnt.v_vnodepgsout += ap->a_count;
#endif
iov.iov_base = (caddr_t) kva;
iov.iov_len = ap->a_count;
uio.uio_iov = &iov;
@ -600,16 +802,16 @@ afs_vop_putpages(ap)
code = afs_write(avc, &uio, sync, osi_curcred(), 0);
afs_BozonUnlock(&avc->pvnLock, avc);
AFS_GUNLOCK();
pmap_qremove(kva, npages);
pmap_qremove(kva, npages);
relpbuf(bp, &afs_pbuf_freecnt);
if (!code) {
size = ap->a_count - uio.uio_resid;
for (i = 0; i < round_page(size) / PAGE_SIZE; i++) {
ap->a_rtvals[i] = VM_PAGER_OK;
ap->a_m[i]->dirty = 0;
vm_page_undirty(ap->a_m[i]);
}
return VM_PAGER_ERROR;
}
return ap->a_rtvals[0];
}
@ -933,26 +1135,44 @@ afs_vop_rmdir(ap)
return error;
}
/* struct vop_symlink_args {
* struct vnode *a_dvp;
* struct vnode **a_vpp;
* struct componentname *a_cnp;
* struct vattr *a_vap;
* char *a_target;
* };
*/
int
afs_vop_symlink(ap)
struct vop_symlink_args /* {
* struct vnode *a_dvp;
* struct vnode **a_vpp;
* struct componentname *a_cnp;
* struct vattr *a_vap;
* char *a_target;
* } */ *ap;
afs_vop_symlink(struct vop_symlink_args *ap)
{
register struct vnode *dvp = ap->a_dvp;
int error = 0;
/* NFS ignores a_vpp; so do we. */
struct vnode *dvp;
struct vnode *newvp;
struct vcache *vcp;
int error;
GETNAME();
AFS_GLOCK();
dvp = ap->a_dvp;
newvp = NULL;
error =
afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
if (error == 0) {
error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
if (error == 0) {
newvp = AFSTOV(vcp);
#ifdef AFS_FBSD50_ENV
vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread);
#else
vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_proc);
#endif
}
}
AFS_GUNLOCK();
DROPNAME();
*(ap->a_vpp) = newvp;
return error;
}
@ -1043,69 +1263,43 @@ afs_vop_inactive(ap)
return 0;
}
/*
* struct vop_reclaim_args {
* struct vnode *a_vp;
* };
*/
int
afs_vop_reclaim(ap)
struct vop_reclaim_args /* {
* struct vnode *a_vp;
* } */ *ap;
{
#ifdef AFS_DO_FLUSH_IN_RECLAIM
int error, sl;
#endif
register struct vnode *vp = ap->a_vp;
cache_purge(vp); /* just in case... */
#ifdef AFS_DO_FLUSH_IN_RECLAIM
AFS_GLOCK();
error = afs_FlushVCache(VTOAFS(vp), &sl); /* tosses our stuff from vnode */
AFS_GUNLOCK();
ubc_unlink(vp);
if (!error && vp->v_data)
panic("afs_reclaim: vnode not cleaned");
return error;
#else
if (vp->v_usecount == 2) {
vprint("reclaim count==2", vp);
} else if (vp->v_usecount == 1) {
vprint("reclaim count==1", vp);
} else
vprint("reclaim bad count", vp);
return 0;
#endif
}
int
afs_vop_lock(ap)
struct vop_lock_args /* {
* struct vnode *a_vp;
* } */ *ap;
{
register struct vnode *vp = ap->a_vp;
register struct vcache *avc = VTOAFS(vp);
#ifdef AFS_FBSD50_ENV
if (!strcmp(vp->v_tag, "none"))
#else
if (vp->v_tag == VT_NON)
#endif
return (ENOENT);
return (lockmgr(&avc->rwlock, ap->a_flags, &vp->v_interlock, ap->a_p));
}
int
afs_vop_unlock(ap)
struct vop_unlock_args /* {
* struct vnode *a_vp;
* } */ *ap;
afs_vop_reclaim(struct vop_reclaim_args *ap)
{
/* copied from ../OBSD/osi_vnodeops.c:afs_nbsd_reclaim() */
int code, slept;
struct vnode *vp = ap->a_vp;
struct vcache *avc = VTOAFS(vp);
return (lockmgr
(&avc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
ap->a_p));
int haveGlock = ISAFS_GLOCK();
int haveVlock = CheckLock(&afs_xvcache);
if (!haveGlock)
AFS_GLOCK();
if (!haveVlock)
ObtainWriteLock(&afs_xvcache, 901);
#ifndef AFS_DISCON_ENV
code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
#else
/* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
code = afs_FlushVS(avc);
#endif
if (!haveVlock)
ReleaseWriteLock(&afs_xvcache);
if (!haveGlock)
AFS_GUNLOCK();
/*
* XXX Pretend it worked, to prevent panic on shutdown
* Garrett, please fix - Jim Rees
*/
if (code)
printf("afs_vop_reclaim: afs_FlushVCache failed code %d\n", code);
return 0;
}
int
@ -1175,16 +1369,6 @@ afs_vop_print(ap)
return 0;
}
int
afs_vop_islocked(ap)
struct vop_islocked_args /* {
* struct vnode *a_vp;
* } */ *ap;
{
struct vcache *vc = VTOAFS(ap->a_vp);
return lockstatus(&vc->rwlock, ap->a_p);
}
/*
* Advisory record locking support (fcntl() POSIX style)
*/

View File

@ -1,5 +0,0 @@
#if defined(AFS_FBSD50_ENV)
#include "vnode_if_5x.h"
#else
#include "vnode_if_4x.h"
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -37,19 +37,21 @@ osi_UFSOpen(afs_int32 ainode)
if (cacheDiskType != AFS_FCACHE_TYPE_UFS)
osi_Panic("UFSOpen called for non-UFS cache\n");
afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file));
AFS_GUNLOCK();
code = VFS_VGET(cacheDev.mp, (ino_t) ainode, &vp);
if (vp->v_type == VNON)
AFS_GLOCK();
if (code == 0 && vp->v_type == VNON)
code = ENOENT;
if (code) {
osi_FreeSmallSpace(afile);
osi_Panic("UFSOpen: igetinode failed");
}
VOP_UNLOCK(vp, 0, curproc);
afile->vnode = vp;
afile->size = VTOI(vp)->i_ffs_size;
afile->offset = 0;
afile->proc = NULL;
afile->inum = ainode; /* for hint validity checking */
VOP_UNLOCK(vp, 0, curproc);
return (void *)afile;
}

View File

@ -404,11 +404,13 @@ afs_nbsd_ref(struct vnode *vp)
void
afs_nbsd_rele(struct vnode *vp)
{
AFS_GUNLOCK();
if (vp->v_usecount <= 0) {
vprint("rele'ing unheld node", vp);
panic("afs_rele");
}
vrele(vp);
AFS_GLOCK();
}
int

View File

@ -545,15 +545,11 @@ struct SimpleLocks {
#define VPageCleaning 0x2 /* Solaris - Cache Trunc Daemon sez keep out */
#define CPSIZE 2
#if defined(AFS_FBSD_ENV)
#define vrefCount v.v_usecount
#else
#if defined(AFS_OBSD_ENV)
#if defined(AFS_XBSD_ENV)
#define vrefCount v->v_usecount
#else
#define vrefCount v.v_count
#endif /* AFS_OBSD_ENV */
#endif /* AFS_FBSD_ENV */
#endif /* AFS_XBSD_ENV */
#ifdef AFS_LINUX24_ENV
#define VREFCOUNT(v) atomic_read(&((vnode_t *) v)->v_count)
@ -598,7 +594,7 @@ struct vtodc {
extern afs_uint32 afs_stampValue; /* stamp for pair's usage */
#define MakeStamp() (++afs_stampValue)
#if defined(AFS_OBSD_ENV)
#if defined(AFS_XBSD_ENV)
#define VTOAFS(v) ((struct vcache *)(v)->v_data)
#define AFSTOV(vc) ((vc)->v)
#else
@ -616,7 +612,7 @@ extern afs_uint32 afs_stampValue; /* stamp for pair's usage */
* !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
*/
struct vcache {
#if defined(AFS_OBSD_ENV)
#if defined(AFS_XBSD_ENV)
struct vnode *v;
#else
struct vnode v; /* Has reference count in v.v_count */

View File

@ -64,13 +64,12 @@ simple_lock_data_t afs_global_lock;
struct lock__bsd__ afs_global_lock;
#endif
#if defined(AFS_XBSD_ENV)
#if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD50_ENV)
struct lock afs_global_lock;
#ifdef AFS_FBSD50_ENV
struct thread *afs_global_owner;
#else
struct proc *afs_global_owner;
#endif
#ifdef AFS_FBSD50_ENV
struct mtx afs_global_mtx;
#endif
#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)

View File

@ -41,7 +41,7 @@ char *afs_sysnamelist[MAXNUMSYSNAMES]; /* For support of a list of sysname */
int afs_sysnamecount = 0;
struct volume *Initialafs_freeVolList;
int afs_memvolumes = 0;
#ifdef AFS_OBSD_ENV
#if defined(AFS_XBSD_ENV)
static struct vnode *volumeVnode;
#endif
@ -295,9 +295,9 @@ afs_InitVolumeInfo(char *afile)
struct osi_file *tfile;
AFS_STATCNT(afs_InitVolumeInfo);
#if defined(AFS_OBSD_ENV)
#if defined(AFS_XBSD_ENV)
/*
* On Open/NetBSD, we can get into big trouble if we don't hold the volume file
* On Open/Free/NetBSD, we can get into big trouble if we don't hold the volume file
* vnode. SetupVolume holds afs_xvolume lock exclusive.
* SetupVolume->GetVolSlot->UFSGetVolSlot->{GetVolCache or WriteVolCache}
* ->osi_UFSOpen->VFS_VGET()->ffs_vget->getnewvnode->vgone on some vnode.
@ -368,20 +368,14 @@ afs_InitCacheInfo(register char *afile)
{
#if defined(AFS_SUN56_ENV)
struct statvfs64 st;
#else
#if defined(AFS_HPUX102_ENV)
#elif defined(AFS_HPUX102_ENV)
struct k_statvfs st;
#else
#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) ||defined(AFS_HPUX100_ENV)
#elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) ||defined(AFS_HPUX100_ENV)
struct statvfs st;
#else
#if defined(AFS_DUX40_ENV)
#elif defined(AFS_DUX40_ENV)
struct nstatfs st;
#else
struct statfs st;
#endif /* DUX40 */
#endif /* SUN5 SGI */
#endif /* HP 10.20 */
#endif /* SUN56 */
#if defined(AFS_SGI_ENV)
@ -424,15 +418,17 @@ afs_InitCacheInfo(register char *afile)
afs_fsfragsize = st.f_bsize - 1;
#endif
}
#ifdef AFS_LINUX20_ENV
#if defined(AFS_LINUX20_ENV)
cacheInode = filevp->i_ino;
afs_cacheSBp = filevp->i_sb;
#else
#ifdef AFS_OBSD_ENV
#elif defined(AFS_XBSD_ENV)
cacheInode = VTOI(filevp)->i_number;
cacheDev.mp = filevp->v_mount;
cacheDev.held_vnode = filevp;
AFS_HOLD(filevp); /* Make sure mount point stays busy. XXX */
vref(filevp); /* Make sure mount point stays busy. XXX */
#if !defined(AFS_OBSD_ENV)
afs_cacheVfsp = filevp->v_vfsp;
#endif
#else
#if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
afs_InitDualFSCacheOps(filevp);
@ -440,7 +436,6 @@ afs_InitCacheInfo(register char *afile)
cacheInode = afs_vnodeToInumber(filevp);
cacheDev.dev = afs_vnodeToDev(filevp);
afs_cacheVfsp = filevp->v_vfsp;
#endif /* AFS_OBSD_ENV */
#endif /* AFS_LINUX20_ENV */
AFS_RELE(filevp);
#endif /* AFS_LINUX22_ENV */
@ -494,10 +489,12 @@ afs_ResourceInit(int preallocs)
RWLOCK_INIT(&afs_icl_lock, "afs_icl_lock");
RWLOCK_INIT(&afs_xinterface, "afs_xinterface");
LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock");
#ifndef AFS_FBSD_ENV
#ifndef AFS_AIX32_ENV
LOCK_INIT(&osi_fsplock, "osi_fsplock");
#endif
LOCK_INIT(&osi_flplock, "osi_flplock");
#endif
RWLOCK_INIT(&afs_xconn, "afs_xconn");
afs_CellInit();
@ -669,11 +666,11 @@ shutdown_cache(void)
afs_cacheFiles = afs_cacheBlocks = 0;
pag_epoch = maxIHint = nihints = usedihint = 0;
pagCounter = 0;
#ifdef AFS_OBSD_ENV
AFS_RELE(volumeVnode); /* let it go, finally. */
#if defined(AFS_XBSD_ENV)
vrele(volumeVnode); /* let it go, finally. */
volumeVnode = NULL;
if (cacheDev.held_vnode) {
AFS_RELE(cacheDev.held_vnode);
vrele(cacheDev.held_vnode);
cacheDev.held_vnode = NULL;
}
#endif

View File

@ -57,6 +57,8 @@ osi_Init(void)
#elif defined(AFS_OSF_ENV)
usimple_lock_init(&afs_global_lock);
afs_global_owner = (thread_t) 0;
#elif defined(AFS_FBSD50_ENV)
mtx_init(&afs_global_mtx, "AFS global lock", NULL, MTX_DEF);
#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
lockinit(&afs_global_lock, PLOCK, "afs global lock", 0, 0);
afs_global_owner = 0;
@ -433,6 +435,8 @@ afs_osi_Alloc(size_t x)
AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
#ifdef AFS_LINUX20_ENV
return osi_linux_alloc(x, 1);
#elif defined(AFS_FBSD_ENV)
return osi_fbsd_alloc(x, 1);
#else
size = x;
tm = (struct osimem *)AFS_KALLOC(size);
@ -479,6 +483,8 @@ afs_osi_Free(void *x, size_t asize)
AFS_STATS(afs_stats_cmperf.OutStandingMemUsage -= asize);
#if defined(AFS_LINUX20_ENV)
osi_linux_free(x);
#elif defined(AFS_FBSD_ENV)
osi_fbsd_free(x);
#else
AFS_KFREE((struct osimem *)x, asize);
#endif

View File

@ -13,6 +13,10 @@
#include "h/types.h"
#include "h/param.h"
#ifdef AFS_FBSD50_ENV
#include <sys/condvar.h>
#endif
#ifdef AFS_LINUX20_ENV
#ifndef _LINUX_CODA_FS_I
#define _LINUX_CODA_FS_I
@ -68,11 +72,9 @@ struct osi_file {
};
struct osi_dev {
#ifdef AFS_OBSD_ENV
#if defined(AFS_XBSD_ENV)
struct mount *mp;
struct vnode *held_vnode;
#elif defined(AFS_FBSD50_ENV)
struct cdev *dev;
#elif defined(AFS_AIX42_ENV)
dev_t dev;
#else
@ -81,7 +83,12 @@ struct osi_dev {
};
struct afs_osi_WaitHandle {
#ifdef AFS_FBSD50_ENV
struct cv wh_condvar;
int wh_inited; /* XXX */
#else
caddr_t proc; /* process waiting */
#endif
};
#define osi_SetFileProc(x,p) ((x)->proc=(p))

View File

@ -19,6 +19,7 @@ RCSID
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
#ifndef AFS_FBSD_ENV
#ifdef AFS_AIX41_ENV
#include "sys/lockl.h"
#include "sys/sleep.h"
@ -368,3 +369,4 @@ shutdown_osinet(void)
LOCK_INIT(&osi_flplock, "osi_flplock");
}
}
#endif

View File

@ -465,8 +465,12 @@ extern void afs_osi_RxkRegister(void);
extern void afs_osi_MaskSignals(void);
extern void afs_osi_UnmaskRxkSignals(void);
extern void *afs_osi_Alloc(size_t x);
#ifndef afs_osi_Alloc_NoSleep
extern void *afs_osi_Alloc_NoSleep(size_t x);
#endif
#ifndef afs_osi_Free
extern void afs_osi_Free(void *x, size_t asize);
#endif
extern void afs_osi_FreeStr(char *x);
extern void osi_Init(void);
extern int osi_Active(register struct vcache *avc);
@ -503,9 +507,11 @@ extern void afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p);
extern afs_int32 PagInCred(const struct AFS_UCRED *cred);
/* afs_osi_alloc.c */
#ifndef AFS_FBSD_ENV
extern afs_int32 afs_preallocs;
extern afs_lock_t osi_fsplock;
extern afs_lock_t osi_flplock;
#endif
extern void osi_FreeLargeSpace(void *adata);
extern void osi_FreeMediumSpace(void *adata);
extern void osi_FreeSmallSpace(void *adata);

View File

@ -153,7 +153,7 @@ afs_FlushVCache(struct vcache *avc, int *slept)
afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
avc->linkData = NULL;
}
#if defined(AFS_OBSD_ENV)
#if defined(AFS_XBSD_ENV)
/* OK, there are no internal vrefCounts, so there shouldn't
* be any more refs here. */
if (avc->v) {
@ -801,36 +801,6 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
continue; /* start over - may have raced. */
}
}
#elif defined(AFS_FBSD50_ENV)
if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
if (!(VOP_LOCK(&tvc->v, LK_EXCLUSIVE, curthread))) {
if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
VREFCOUNT_DEC(tvc);
AFS_GUNLOCK(); /* perhaps inline inactive for locking */
VOP_INACTIVE(&tvc->v, curthread);
AFS_GLOCK();
} else {
VOP_UNLOCK(&tvc->v, 0, curthread);
}
}
}
#elif defined(AFS_FBSD_ENV) && !defined(AFS_FBSD50_ENV)
if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
if (!(VOP_LOCK(&tvc->v, LK_EXCLUSIVE, curproc))) {
if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
VREFCOUNT_DEC(tvc);
AFS_GUNLOCK(); /* perhaps inline inactive for locking */
VOP_INACTIVE(&tvc->v, curproc);
AFS_GLOCK();
} else {
VOP_UNLOCK(&tvc->v, 0, curproc);
}
}
}
#elif defined(AFS_LINUX22_ENV)
if (tvc != afs_globalVp && VREFCOUNT(tvc) && tvc->opens == 0)
afs_TryFlushDcacheChildren(tvc);
@ -838,12 +808,13 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
if (VREFCOUNT(tvc) == 0 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
#ifdef AFS_OBSD_ENV
#if defined(AFS_XBSD_ENV)
/*
* vgone() reclaims the vnode, which calls afs_FlushVCache(),
* then it puts the vnode on the free list.
* If we don't do this we end up with a cleaned vnode that's
* not on the free list.
* XXX assume FreeBSD is the same for now.
*/
vgone(AFSTOV(tvc));
code = fv_slept = 0;
@ -907,7 +878,7 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
vm_info_ptr = tvc->v.v_vm_info;
#endif /* AFS_MACH_ENV */
#if defined(AFS_OBSD_ENV)
#if defined(AFS_XBSD_ENV)
if (tvc->v)
panic("afs_NewVCache(): free vcache with vnode attached");
#endif
@ -932,6 +903,36 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
afs_nbsd_getnewvnode(tvc); /* includes one refcount */
AFS_GLOCK();
lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
#endif
#ifdef AFS_FBSD_ENV
{
struct vnode *vp;
AFS_GUNLOCK();
#ifdef AFS_FBSD50_ENV
if (getnewvnode(MOUNT_AFS, afs_globalVFS, afs_vnodeop_p, &vp))
#else
if (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &vp))
#endif
panic("afs getnewvnode"); /* can't happen */
AFS_GLOCK();
if (tvc->v != NULL) {
/* I'd like to know if this ever happens...
We don't drop global for the rest of this function,
so if we do lose the race, the other thread should
have found the same vnode and finished initializing
the vcache entry. Is it conceivable that this vcache
entry could be recycled during this interval? If so,
then there probably needs to be some sort of additional
mutual exclusion (an Embryonic flag would suffice).
-GAW */
printf("afs_NewVCache: lost the race\n");
return (tvc);
}
tvc->v = vp;
tvc->v->v_data = tvc;
lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
}
#endif
tvc->parentVnode = 0;
tvc->mvid = NULL;
@ -957,9 +958,9 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
/* Hold it for the LRU (should make count 2) */
VN_HOLD(AFSTOV(tvc));
#else /* AFS_OSF_ENV */
#ifndef AFS_OBSD_ENV
#if !defined(AFS_XBSD_ENV)
VREFCOUNT_SET(tvc, 1); /* us */
#endif /* AFS_OBSD_ENV */
#endif /* AFS_XBSD_ENV */
#endif /* AFS_OSF_ENV */
#ifdef AFS_AIX32_ENV
LOCK_INIT(&tvc->pvmlock, "vcache pvmlock");
@ -1039,14 +1040,6 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
tvc->v.v_freelist.tqe_next = 0;
tvc->v.v_freelist.tqe_prev = (struct vnode **)0xdeadb;
/*tvc->vrefCount++; */
#endif
#ifdef AFS_FBSD_ENV
lockinit(&tvc->rwlock, PINOD, "vcache rwlock", 0, 0);
cache_purge(AFSTOV(tvc));
tvc->v.v_data = tvc;
tvc->v.v_tag = VT_AFS;
tvc->v.v_usecount++; /* steal an extra ref for now so vfree never happens */
/* This extra ref is dealt with above... */
#endif
/*
* The proper value for mvstat (for root fids) is setup by the caller.
@ -1801,6 +1794,40 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
uvm_vnp_uncache(AFSTOV(tvc));
VOP_UNLOCK(AFSTOV(tvc), 0, curproc);
#endif
#ifdef AFS_FBSD_ENV
/*
* XXX - I really don't like this. Should try to understand better.
* It seems that sometimes, when we get called, we already hold the
* lock on the vnode (e.g., from afs_getattr via afs_VerifyVCache).
* We can't drop the vnode lock, because that could result in a race.
* Sometimes, though, we get here and don't hold the vnode lock.
* I hate code paths that sometimes hold locks and sometimes don't.
* In any event, the dodge we use here is to check whether the vnode
* is locked, and if it isn't, then we gain and drop it around the call
* to vinvalbuf; otherwise, we leave it alone.
*/
{
struct vnode *vp;
int iheldthelock;
vp = AFSTOV(tvc);
#ifdef AFS_FBSD50_ENV
iheldthelock = VOP_ISLOCKED(vp, curthread);
if (!iheldthelock)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
vinvalbuf(vp, V_SAVE, osi_curcred(), curthread, PINOD, 0);
if (!iheldthelock)
VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
#else
iheldthelock = VOP_ISLOCKED(vp, curproc);
if (!iheldthelock)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
vinvalbuf(vp, V_SAVE, osi_curcred(), curproc, PINOD, 0);
if (!iheldthelock)
VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
#endif
}
#endif
ObtainWriteLock(&afs_xcbhash, 464);
tvc->states &= ~CUnique;

View File

@ -79,8 +79,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -100,9 +102,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -81,8 +81,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -102,9 +104,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -83,8 +83,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -104,9 +106,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -84,8 +84,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -105,9 +107,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -85,8 +85,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -106,9 +108,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -87,8 +87,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -108,9 +110,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -88,8 +88,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -109,9 +111,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -79,7 +79,7 @@
#ifdef _KERNEL
#define AFS_GLOBAL_SUNLOCK 1
#define AFS_VFS34 1 /* What is VFS34??? */
#define AFS_SHORTGID 1 /* are group id's short? */
#define AFS_SHORTGID 0 /* are group id's short? */
#define afsio_iov uio_iov
#define afsio_iovcnt uio_iovcnt
#define afsio_offset uio_offset
@ -89,8 +89,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
#define AFS_KFREE(x,y) free(x,M_AFS)
#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
#undef AFS_KALLOC_NOSLEEP
#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@ -110,9 +112,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };
@ -169,7 +168,7 @@ enum vcexcl { NONEXCL, EXCL };
#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_51
#define AFSLITTLE_ENDIAN 1
#define AFS_HAVE_FFS 1 /* Use system's ffs. */
#define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */
#define AFS_HAVE_STATVFS 1 /* System doesn't support statvfs */
#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */
#define afsio_iov uio_iov

View File

@ -113,9 +113,6 @@
#define p_rcred p_ucred
#define VN_RELE(vp) vrele(((struct vnode *)(vp)))
#define VN_HOLD(vp) VREF(((struct vnode *)(vp)))
#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__)
enum vcexcl { NONEXCL, EXCL };

View File

@ -29,14 +29,19 @@ AFS_OS_NONFSOBJS = \
# System specific build commands and flags
KSRC = @BSD_KERNEL_PATH@
KBLD = @BSD_KERNEL_BUILD@
KDEFS=-Wall -ansi -nostdinc -I/usr/include -D_KERNEL -DKLD_MODULE \
-elf -mpreferred-stack-boundary=2 \
<i386_fbsd_42 i386_fbsd_43 i386_fbsd_44 i386_fbsd_45 i386_fbsd_46 i386_fbsd_47>
-fformat-extensions
-fformat-extensions \
-include ${KBLD}/opt_global.h
<all -i386_fbsd_42 -i386_fbsd_43 -i386_fbsd_44 -i386_fbsd_45 -i386_fbsd_46 -i386_fbsd_47>
-mno-align-long-strings -fformat-extensions -fno-common -ffreestanding
-mno-align-long-strings -fformat-extensions -fno-common -ffreestanding \
-I${KBLD} -include opt_global.h -fno-strict-aliasing
<all>
DBUG = -O2
#DBUG = -O -g
DEFINES= -DAFSDEBUG -DKERNEL -DAFS -DVICE -DNFS -DUFS -DINET -DQUOTA -DGETMOUNT
OPTF=${OPT}
OPTF2=${OPT2}
@ -140,5 +145,12 @@ setdef0.o: setdef0.c
$(CRULE_NOOPT)
setdef1.o: setdef1.c
$(CRULE_NOOPT)
# vnode_if.h build rules:
<i386_fbsd_42 i386_fbsd_43 i386_fbsd_44 i386_fbsd_45 i386_fbsd_46 i386_fbsd_47>
vnode_if.h: ${KSRC}/kern/vnode_if.src
perl5 ${KSRC}/kern/vnode_if.pl -h ${KSRC}/kern/vnode_if.src
<all -i386_fbsd_42 -i386_fbsd_43 -i386_fbsd_44 -i386_fbsd_45 -i386_fbsd_46 -i386_fbsd_47>
vnode_if.h: ${KSRC}/kern/vnode_if.src
awk -f ${KSRC}/tools/vnode_if.awk ${KSRC}/kern/vnode_if.src -h
<all>

View File

@ -10,16 +10,16 @@ include @TOP_OBJDIR@/src/config/Makefile.config
# System specific build commands and flags
CC = gcc
CC = @CC@
DEFINES= -D_REENTRANT -DKERNEL -DUKERNEL
KOPTS=
CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES) $(KOPTS) ${DBUG}
OPTF=-O
# WEBOPTS = -I../nsapi -DNETSCAPE_NSAPI -DNET_SSL -DXP_UNIX -DMCC_HTTPD
TEST_CFLAGS=-pthread -D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV
TEST_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV
TEST_LDFLAGS=
TEST_LIBS=
TEST_LIBS=-lc_r
LIBUAFS = libuafs.a
LIBJUAFS = libjuafs.a

View File

@ -83,10 +83,20 @@ osi_StopListener(void)
{
struct proc *p;
/*
* Have to drop global lock to safely do this.
* soclose() is currently protected by Giant,
* but pfind and psignal are MPSAFE.
*/
AFS_GUNLOCK();
soclose(rx_socket);
p = pfind(rxk_ListenerPid);
if (p)
psignal(p, SIGUSR1);
#ifdef AFS_FBSD50_ENV
PROC_UNLOCK(p);
#endif
AFS_GLOCK();
}
int

View File

@ -780,6 +780,8 @@ rxk_NewSocket(short aport)
#if (defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)) && defined(KERNEL_FUNNEL)
thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
#endif
AFS_ASSERT_GLOCK();
AFS_GUNLOCK();
#if defined(AFS_HPUX102_ENV)
#if defined(AFS_HPUX110_ENV)
/* we need a file associated with the socket so sosend in NetSend
@ -811,6 +813,7 @@ rxk_NewSocket(short aport)
if (code)
goto bad;
memset(&myaddr, 0, sizeof myaddr);
myaddr.sin_family = AF_INET;
myaddr.sin_port = aport;
myaddr.sin_addr.s_addr = 0;
@ -856,6 +859,7 @@ rxk_NewSocket(short aport)
if (code) {
printf("sobind fails (%d)\n", (int)code);
soclose(newSocket);
AFS_GLOCK();
goto bad;
}
#else /* defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) */
@ -890,12 +894,14 @@ rxk_NewSocket(short aport)
#endif /* else AFS_DARWIN_ENV */
#endif /* else AFS_HPUX110_ENV */
AFS_GLOCK();
#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
#endif
return (struct osi_socket *)newSocket;
bad:
AFS_GLOCK();
#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
#endif

View File

@ -561,9 +561,15 @@ extern void rx_SetNoJumbo(void);
/* EXTERNAL PROTOTYPES - include here cause it causes too many issues to
include the afs_prototypes.h file - just make sure they match */
#ifndef afs_osi_Alloc
extern void *afs_osi_Alloc(size_t x);
#endif
#ifndef afs_osi_Alloc_NoSleep
extern void *afs_osi_Alloc_NoSleep(size_t x);
#endif
#ifndef afs_osi_Free
extern void afs_osi_Free(void *x, size_t asize);
#endif
#ifndef afs_osi_Wakeup
extern int afs_osi_Wakeup(void *event);
#endif

View File

@ -96,7 +96,9 @@
/* keep here for now, 64 bit issues */
extern void *afs_osi_Alloc(size_t x);
#ifndef afs_osi_Alloc_NoSleep
extern void *afs_osi_Alloc_NoSleep(size_t x);
#endif
extern void afs_osi_Free(void *x, size_t asize);
#endif