#include <sys/malloc.h>
#include <sys/namei.h>
#include <sys/ubc.h>
-#if defined(AFS_DARWIN70_ENV)
#include <vfs/vfs_support.h>
-#endif /* defined(AFS_DARWIN70_ENV) */
#ifdef AFS_DARWIN80_ENV
#include <sys/vnode_if.h>
#include <sys/kauth.h>
int afs_vop_symlink(struct VOPPROT(symlink_args) *);
int afs_vop_readdir(struct VOPPROT(readdir_args) *);
int afs_vop_readlink(struct VOPPROT(readlink_args) *);
-#if !defined(AFS_DARWIN70_ENV)
-extern int ufs_abortop(struct vop_abortop_args *);
-#endif /* !defined(AFS_DARWIN70_ENV) */
int afs_vop_inactive(struct VOPPROT(inactive_args) *);
int afs_vop_reclaim(struct VOPPROT(reclaim_args) *);
int afs_vop_strategy(struct VOPPROT(strategy_args) *);
{VOPPREF(readdir_desc), (VOPFUNC)afs_vop_readdir}, /* readdir */
{VOPPREF(readlink_desc), (VOPFUNC)afs_vop_readlink}, /* readlink */
#ifndef AFS_DARWIN80_ENV
-#if defined(AFS_DARWIN70_ENV)
{VOPPREF(abortop_desc), (VOPFUNC)nop_abortop }, /* abortop */
-#else /* ! defined(AFS_DARWIN70_ENV) */
- /* Yes, we use the ufs_abortop call. It just releases the namei
- * buffer stuff */
- {VOPPREF(abortop_desc), (VOPFUNC)ufs_abortop}, /* abortop */
-#endif /* defined(AFS_DARWIN70_ENV) */
#endif
{VOPPREF(inactive_desc), (VOPFUNC)afs_vop_inactive}, /* inactive */
{VOPPREF(reclaim_desc), (VOPFUNC)afs_vop_reclaim}, /* reclaim */
if (vnode_get(vp)) {
/* being terminated. kernel won't give us a ref. Now what? our
callers don't expect us to fail */
-#if 1
- panic("vn_hold on terminating vnode");
-#else
if (haveGlock) AFS_GLOCK();
return;
-#endif
}
if (vnode_ref(vp)) {
-#if 1
- panic("vn_hold on terminating vnode");
-#else
vnode_put(vp);
if (haveGlock) AFS_GLOCK();
return;
-#endif
}
vnode_put(vp);
#else
int error;
struct vcache *vcp;
struct vnode *vp, *dvp;
- register int flags = ap->a_cnp->cn_flags;
+ int flags = ap->a_cnp->cn_flags;
int lockparent; /* 1 => lockparent flag is set */
int wantparent; /* 1 => wantparent or lockparent flag */
struct proc *p;
#ifdef AFS_DARWIN80_ENV
vcp = VTOAFS(ap->a_dvp);
+ /*
+ * ._ file attribute mirroring touches this.
+ * we can't flag the vcache as there is none, so fail here.
+ * needed for fsevents support.
+ */
+ if (ap->a_context == afs_osi_ctxtp)
+ return ENOENT;
if (vcp->mvstat != 1) {
error = cache_lookup(ap->a_dvp, ap->a_vpp, ap->a_cnp);
if (error == -1)
return (error);
}
#ifdef AFS_DARWIN80_ENV
- if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0))) {
+ if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0, 0))) {
DROPNAME();
*ap->a_vpp = 0;
return error;
{
int error = 0;
struct vcache *vcp;
- register struct vnode *dvp = ap->a_dvp;
+ struct vnode *dvp = ap->a_dvp;
struct proc *p;
GETNAME();
p = vop_cn_proc;
if (vcp) {
#ifdef AFS_DARWIN80_ENV
- if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0))) {
+ if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0, 0))) {
DROPNAME();
*ap->a_vpp=0;
return error;
int error;
struct vnode *vp = ap->a_vp;
struct vcache *vc = VTOAFS(vp);
-#if defined(AFS_DARWIN14_ENV) && !defined(AFS_DARWIN80_ENV)
+#if !defined(AFS_DARWIN80_ENV)
int didhold = 0;
/*----------------------------------------------------------------
* osi_VM_TryReclaim() removes the ubcinfo of a vnode, but that vnode
if (vp->v_type == VREG && !(vp->v_flag & VSYSTEM)
&& vp->v_ubcinfo->ui_refcount < 2)
didhold = ubc_hold(vp);
-#endif /* AFS_DARWIN14_ENV */
+#endif /* !AFS_DARWIN80_ENV */
AFS_GLOCK();
error = afs_open(&vc, ap->a_mode, vop_cred);
#ifdef DIAGNOSTIC
#endif
osi_FlushPages(vc, vop_cred);
AFS_GUNLOCK();
-#if defined(AFS_DARWIN14_ENV) && !defined(AFS_DARWIN80_ENV)
+#if !defined(AFS_DARWIN80_ENV)
if (error && didhold)
ubc_rele(vp);
-#endif /* AFS_DARWIN14_ENV */
+#endif /* !AFS_DARWIN80_ENV */
return error;
}
int code;
struct vnode *vp = ap->a_vp;
struct vcache *avc = VTOAFS(vp);
+ /* allows faking FSE_CONTENT_MODIFIED */
+ if (afs_osi_ctxtp == ap->a_context)
+ return 0;
AFS_GLOCK();
if (vop_cred)
code = afs_close(avc, ap->a_fflag, vop_cred);
struct vcache * tvc = VTOAFS(ap->a_vp);
int bits=0;
int cmb = CHECK_MODE_BITS;
+#ifdef AFS_DARWIN80_ENV
+ /*
+ * needed for fsevents. ._ file attribute mirroring touches this.
+ * we can't flag the vcache, as there is none, so fail here.
+ */
+ if (ap->a_context == afs_osi_ctxtp)
+ return ENOENT;
+#endif
AFS_GLOCK();
afs_InitFakeStat(&fakestate);
if ((code = afs_InitReq(&treq, vop_cred)))
/* we can't check for KAUTH_VNODE_TAKE_OWNERSHIP, so we always permit it */
code = afs_AccessOK(tvc, bits, &treq, cmb);
-#if defined(AFS_DARWIN80_ENV)
- /* In a dropbox, cp on 10.4 behaves badly, looping on EACCES */
- /* In a dropbox, Finder may reopen the file. Let it. */
- if (code == 0 && ((bits &~(PRSFS_READ|PRSFS_WRITE)) == 0)) {
+ /*
+ * Special cased dropbox handling:
+ * cp on 10.4 behaves badly, looping on EACCES
+ * Finder may reopen the file. Let it.
+ */
+ if (code == 0 && ((bits &~(PRSFS_READ|PRSFS_WRITE)) == 0))
code = afs_AccessOK(tvc, PRSFS_ADMINISTER|PRSFS_INSERT|bits, &treq, cmb);
- }
-#endif
+ /* Finder also treats dropboxes as insert+delete. fake it out. */
+ if (code == 0 && (bits == (PRSFS_INSERT|PRSFS_DELETE)))
+ code = afs_AccessOK(tvc, PRSFS_INSERT, &treq, cmb);
+
if (code == 1 && vnode_vtype(ap->a_vp) == VREG &&
ap->a_action & KAUTH_VNODE_EXECUTE &&
(tvc->f.m.Mode & 0100) != 0100) {
{
int code;
- AFS_GLOCK();
- code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, vop_cred);
- /* This is legit; it just forces the fstrace event to happen */
- code = afs_CheckCode(code, NULL, 58);
- AFS_GUNLOCK();
+#ifdef AFS_DARWIN80_ENV
+ /* CEvent excludes the fsevent. our context excludes the ._ */
+ if ((VTOAFS(ap->a_vp)->f.states & CEvent) ||
+ (ap->a_context == afs_osi_ctxtp)){
+ struct vcache *avc = VTOAFS(ap->a_vp);
+ int isglock = ISAFS_GLOCK();
+
+ /* this is needed because of how and when we re-enter */
+ if (!isglock)
+ AFS_GLOCK();
+ /* do minimal work to return fake result for fsevents */
+ if (afs_fakestat_enable && VTOAFS(ap->a_vp)->mvstat == 1) {
+ struct afs_fakestat_state fakestat;
+ struct vrequest treq;
+
+ code = afs_InitReq(&treq, vop_cred);
+ if (code) {
+ if (!isglock)
+ AFS_GUNLOCK();
+ return code;
+ }
+ afs_InitFakeStat(&fakestat);
+ /* expects GLOCK */
+ code = afs_TryEvalFakeStat(&avc, &fakestat, &treq);
+ if (code) {
+ if (!isglock)
+ AFS_GUNLOCK();
+ afs_PutFakeStat(&fakestat);
+ return code;
+ }
+ }
+ code = afs_CopyOutAttrs(avc, ap->a_vap);
+ if (!isglock)
+ AFS_GUNLOCK();
+ if (0 && !code) {
+ /* tweak things so finder will recheck */
+ (ap->a_vap)->va_gid = ((ap->a_vap)->va_gid == 1) ? 2 : 1;
+ (ap->a_vap)->va_mode &= ~(VSGID);
+ }
+ } else
+#endif
+ {
+ AFS_GLOCK();
+ code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, vop_cred);
+ /* This is legit; it just forces the fstrace event to happen */
+ code = afs_CheckCode(code, NULL, 58);
+ AFS_GUNLOCK();
+ }
#ifdef AFS_DARWIN80_ENV
VATTR_SET_SUPPORTED(ap->a_vap, va_type);
VATTR_SET_SUPPORTED(ap->a_vap, va_mode);
* struct proc *a_p;
* } */ *ap;
{
- int code;
+ int code, pass = 0;
+ struct vcache *avc = VTOAFS(ap->a_vp);
+#ifdef AFS_DARWIN80_ENV
+ /* fsevents tries to set attributes. drop it. */
+ if (ap->a_context == afs_osi_ctxtp)
+ return 0;
+#endif
AFS_GLOCK();
- code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, vop_cred);
+retry:
+ code = afs_setattr(avc, ap->a_vap, vop_cred);
/* This is legit; it just forces the fstrace event to happen */
code = afs_CheckCode(code, NULL, 59);
+ if (!pass && code == EINVAL && (VATTR_IS_ACTIVE(ap->a_vap, va_mode) &&
+ (vType(avc) == VLNK))) {
+ VATTR_CLEAR_ACTIVE(ap->a_vap, va_mode);
+ pass++;
+ goto retry;
+ }
AFS_GUNLOCK();
return code;
}
#endif
AFS_GLOCK();
osi_FlushPages(avc, vop_cred); /* hold bozon lock, but not basic vnode lock */
- code = afs_read(avc, ap->a_uio, vop_cred, 0, 0, 0);
+ code = afs_read(avc, ap->a_uio, vop_cred, 0);
AFS_GUNLOCK();
return code;
}
* int a_flags;
* } */ *ap;
{
- register struct vnode *vp = ap->a_vp;
+ struct vnode *vp = ap->a_vp;
upl_t pl = ap->a_pl;
size_t size = ap->a_size;
off_t f_offset = ap->a_f_offset;
#endif
AFS_GLOCK();
osi_FlushPages(tvc, vop_cred); /* hold bozon lock, but not basic vnode lock */
- code = afs_read(tvc, uio, cred, 0, 0, 0);
+ code = afs_read(tvc, uio, cred, 0);
if (code == 0) {
ObtainWriteLock(&tvc->lock, 2);
tvc->f.states |= CMAPPED;
* int a_flags
* } */ *ap;
{
- register struct vnode *vp = ap->a_vp;
+ struct vnode *vp = ap->a_vp;
upl_t pl = ap->a_pl;
size_t size = ap->a_size;
off_t f_offset = ap->a_f_offset;
auio.uio_resid = aiov.iov_len = iosize;
aiov.iov_base = (caddr_t) ioaddr;
#endif
-#if 1 /* USV [ */
{
- /*
+ /* USV?
* check for partial page and clear the
* contents past end of the file before
* releasing it in the VM page cache
memset((caddr_t) (ioaddr + pl_offset + io), 0, size - io);
}
}
-#endif /* ] USV */
AFS_GLOCK();
osi_FlushPages(tvc, vop_cred); /* hold bozon lock, but not basic vnode lock */
{
int wait = ap->a_waitfor == MNT_WAIT;
int error;
- register struct vnode *vp = ap->a_vp;
+ struct vnode *vp = ap->a_vp;
int haveGlock = ISAFS_GLOCK();
+ /* in order to recycle faked vnodes for bulkstat */
+ if (VTOAFS(vp) == NULL)
+ return ENOTSUP;
+
/* afs_vop_lookup glocks, can call us through vinvalbuf from GetVCache */
if (!haveGlock) AFS_GLOCK();
if (vop_cred)
* } */ *ap;
{
int error = 0;
- register struct vnode *vp = ap->a_vp;
- register struct vnode *dvp = ap->a_dvp;
+ struct vnode *vp = ap->a_vp;
+ struct vnode *dvp = ap->a_dvp;
#ifdef AFS_DARWIN80_ENV
if (ap->a_flags & VNODE_REMOVE_NODELETEBUSY) {
* } */ *ap;
{
int error = 0;
- register struct vnode *dvp = ap->a_tdvp;
- register struct vnode *vp = ap->a_vp;
+ struct vnode *dvp = ap->a_tdvp;
+ struct vnode *vp = ap->a_vp;
struct proc *p;
GETNAME();
struct componentname *tcnp = ap->a_tcnp;
char *tname;
struct vnode *tvp = ap->a_tvp;
- register struct vnode *tdvp = ap->a_tdvp;
+ struct vnode *tdvp = ap->a_tdvp;
struct vnode *fvp = ap->a_fvp;
- register struct vnode *fdvp = ap->a_fdvp;
+ struct vnode *fdvp = ap->a_fdvp;
struct proc *p;
p = cn_proc(fcnp);
#ifdef AFS_DARWIN80_ENV
-/* generic code tests for v_mount equality, so we don't have to, but we don't
- get the multiple-mount "benefits" of the old behavior
-*/
+ /*
+ * generic code tests for v_mount equality, so we don't have to, but we
+ * don't get the multiple-mount "benefits" of the old behavior
+ * the generic code doesn't do this, so we really should, but all the
+ * vrele's are wrong...
+ */
#else
/* Check for cross-device rename.
* For AFS, this means anything not in AFS-space
error = EXDEV;
goto abortit;
}
-#endif
-#ifdef AFS_DARWIN80_ENV
- /* the generic code doesn't do this, so we really should, but all the
- vrele's are wrong... */
-#else
/*
* if fvp == tvp, we're just removing one name of a pair of
* directory entries for the same element. convert call into rename.
vput(tdvp);
vput(tvp);
/* Delete source. */
-#if defined(AFS_DARWIN80_ENV)
-
- MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
- memcpy(fname, fcnp->cn_nameptr, fcnp->cn_namelen);
- fname[fcnp->cn_namelen] = '\0';
- AFS_GLOCK();
- error = afs_remove(VTOAFS(fdvp), fname, vop_cn_cred);
- AFS_GUNLOCK();
- FREE(fname, M_TEMP);
- cache_purge(fvp);
-#else
vrele(fdvp);
vrele(fvp);
fcnp->cn_flags &= ~MODMASK;
return (ENOENT);
}
error=VOP_REMOVE(fdvp, fvp, fcnp);
-#endif
if (fdvp == fvp)
vrele(fdvp);
vput(fvp);
return (error);
}
-#endif
-#if !defined(AFS_DARWIN80_ENV)
if (error = vn_lock(fvp, LK_EXCLUSIVE, p))
goto abortit;
#endif
/* XXX use "from" or "to" creds? NFS uses "to" creds */
error =
afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, cn_cred(tcnp));
- AFS_GUNLOCK();
#if !defined(AFS_DARWIN80_ENV)
+ AFS_GUNLOCK();
VOP_UNLOCK(fvp, 0, p);
-#endif
-#ifdef notdef
- if (error == EXDEV) {
- /* The idea would be to have a userspace handler like afsdb to
- * run mv as the user, thus:
- */
- printf("su %d -c /bin/mv /afs/.:mount/%d:%d:%d:%d/%s /afs/.:mount/%d:%d:%d:%d/%s\n",
- afs_cr_uid(cn_cred(tcnp)), fvc->f.fid.Cell, fvc->f.fid.Fid.Volume,
- fvc->f.fid.Fid.Vnode, fvc->f.fid.Fid.Unique, fname,
- tvc->f.fid.Cell, tvc->f.fid.Fid.Volume, tvc->f.fid.Fid.Vnode,
- tvc->f.fid.Fid.Unique, tname);
- }
-#endif
-#ifdef AFS_DARWIN80_ENV
- cache_purge(fdvp);
- cache_purge(fvp);
- cache_purge(tdvp);
- if (tvp) {
- cache_purge(tvp);
- if (!error) {
- vnode_recycle(tvp);
- }
- }
- if (!error)
- cache_enter(tdvp, fvp, tcnp);
-#else
if (error)
goto abortit; /* XXX */
if (tdvp == tvp)
vput(tvp);
vrele(fdvp);
vrele(fvp);
+#else
+ if (error == EXDEV) {
+ struct brequest *tb;
+ struct afs_uspc_param mvReq;
+ struct vcache *tvc;
+ struct vcache *fvc = VTOAFS(fdvp);
+ int code = 0;
+ struct afs_fakestat_state fakestate;
+ int fakestatdone = 0;
+
+ tvc = VTOAFS(tdvp);
+
+ /* unrewritten mount point? */
+ if (tvc->mvstat == 1) {
+ if (tvc->mvid && (tvc->f.states & CMValid)) {
+ struct vrequest treq;
+
+ afs_InitFakeStat(&fakestate);
+ code = afs_InitReq(&treq, vop_cred);
+ if (!code) {
+ fakestatdone = 1;
+ code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
+ } else
+ afs_PutFakeStat(&fakestate);
+ }
+ }
+
+ if (!code) {
+ /* at some point in the future we should allow other types */
+ mvReq.reqtype = AFS_USPC_UMV;
+ mvReq.req.umv.id = afs_cr_uid(cn_cred(tcnp));
+ mvReq.req.umv.idtype = IDTYPE_UID;
+ mvReq.req.umv.sCell = fvc->f.fid.Cell;
+ mvReq.req.umv.sVolume = fvc->f.fid.Fid.Volume;
+ mvReq.req.umv.sVnode = fvc->f.fid.Fid.Vnode;
+ mvReq.req.umv.sUnique = fvc->f.fid.Fid.Unique;
+ mvReq.req.umv.dCell = tvc->f.fid.Cell;
+ mvReq.req.umv.dVolume = tvc->f.fid.Fid.Volume;
+ mvReq.req.umv.dVnode = tvc->f.fid.Fid.Vnode;
+ mvReq.req.umv.dUnique = tvc->f.fid.Fid.Unique;
+
+ /*
+ * su %d -c mv /afs/.:mount/%d:%d:%d:%d/%s
+ * /afs/.:mount/%d:%d:%d:%d/%s where:
+ * mvReq.req.umv.id, fvc->f.fid.Cell, fvc->f.fid.Fid.Volume,
+ * fvc->f.fid.Fid.Vnode, fvc->f.fid.Fid.Unique, fname,
+ * tvc->f.fid.Cell, tvc->f.fid.Fid.Volume, tvc->f.fid.Fid.Vnode,
+ * tvc->f.fid.Fid.Unique, tname
+ */
+
+ tb = afs_BQueue(BOP_MOVE, NULL, 0, 1, cn_cred(tcnp),
+ 0L, 0L, &mvReq, fname, tname);
+ /* wait to collect result */
+ while ((tb->flags & BUVALID) == 0) {
+ tb->flags |= BUWAIT;
+ afs_osi_Sleep(tb);
+ }
+ /* if we succeeded, clear the error. otherwise, EXDEV */
+ if (mvReq.retval == 0)
+ error = 0;
+
+ afs_BRelease(tb);
+ }
+
+ if (fakestatdone)
+ afs_PutFakeStat(&fakestate);
+ }
+ AFS_GUNLOCK();
+
+ cache_purge(fdvp);
+ cache_purge(fvp);
+ cache_purge(tdvp);
+ if (tvp) {
+ cache_purge(tvp);
+ if (!error) {
+ vnode_recycle(tvp);
+ }
+ }
+ if (!error)
+ cache_enter(tdvp, fvp, tcnp);
#endif
FREE(fname, M_TEMP);
FREE(tname, M_TEMP);
* struct vattr *a_vap;
* } */ *ap;
{
- register struct vnode *dvp = ap->a_dvp;
- register struct vattr *vap = ap->a_vap;
+ struct vnode *dvp = ap->a_dvp;
+ struct vattr *vap = ap->a_vap;
int error = 0;
struct vcache *vcp;
struct proc *p;
}
if (vcp) {
#ifdef AFS_DARWIN80_ENV
- afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0);
+ afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0, 0);
#endif
*ap->a_vpp = AFSTOV(vcp);
#ifndef AFS_DARWIN80_ENV /* XXX needed for multi-mount thing, but can't have it yet */
* } */ *ap;
{
int error = 0;
- register struct vnode *vp = ap->a_vp;
- register struct vnode *dvp = ap->a_dvp;
+ struct vnode *vp = ap->a_vp;
+ struct vnode *dvp = ap->a_dvp;
GETNAME();
if (dvp == vp) {
* char *a_target;
* } */ *ap;
{
- register struct vnode *dvp = ap->a_dvp;
+ struct vnode *dvp = ap->a_dvp;
int error = 0;
/* NFS ignores a_vpp; so do we. */
* struct proc *a_p;
* } */ *ap;
{
- register struct vnode *vp = ap->a_vp;
+ struct vnode *vp = ap->a_vp;
struct vcache *tvc = VTOAFS(vp);
#ifndef AFS_DARWIN80_ENV
if (prtactive && vp->v_usecount != 0)
{
int error = 0;
int sl, writelocked;
- register struct vnode *vp = ap->a_vp;
+ struct vnode *vp = ap->a_vp;
struct vcache *tvc = VTOAFS(vp);
osi_Assert(!ISAFS_GLOCK());
case _PC_PIPE_BUF:
return EINVAL;
break;
-#if defined(AFS_DARWIN70_ENV)
case _PC_NAME_CHARS_MAX:
*ap->a_retval = NAME_MAX;
break;
case _PC_CASE_PRESERVING:
*ap->a_retval = 1;
break;
-#endif /* defined(AFS_DARWIN70_ENV) */
default:
return EINVAL;
}
* struct vnode *a_vp;
* } */ *ap;
{
- register struct vnode *vp = ap->a_vp;
- register struct vcache *avc = VTOAFS(vp);
+ struct vnode *vp = ap->a_vp;
+ struct vcache *avc = VTOAFS(vp);
if (vp->v_tag == VT_NON)
return (ENOENT);
* struct proc *a_p;
* } */ *ap;
{
- printf("stray afs_vop_truncate\n");
- return EOPNOTSUPP;
+ /* printf("stray afs_vop_truncate\n"); */
+ return ENOTSUP;
}
int
* int a_waitfor;
* } */ *ap;
{
- printf("stray afs_vop_update\n");
- return EOPNOTSUPP;
+ /* printf("stray afs_vop_update\n"); */
+ return ENOTSUP;
}
int
* struct vnode *a_vp;
* } */ *ap;
{
- register struct vnode *vp = ap->a_vp;
- register struct vcache *vc = VTOAFS(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct vcache *vc = VTOAFS(ap->a_vp);
int s = vc->f.states;
printf("tag %d, fid: %ld.%x.%x.%x, opens %d, writers %d", vp->v_tag,
vc->f.fid.Cell, vc->f.fid.Fid.Volume, vc->f.fid.Fid.Vnode,
printf("\n UBC: ");
if (UBCINFOEXISTS(vp)) {
printf("exists, ");
-#ifdef AFS_DARWIN14_ENV
printf("refs %d%s%s", vp->v_ubcinfo->ui_refcount,
ubc_issetflags(vp, UI_HASOBJREF) ? " HASOBJREF" : "",
ubc_issetflags(vp, UI_WASMAPPED) ? " WASMAPPED" : "");
-#else
- printf("holdcnt %d", vp->v_ubcinfo->ui_holdcnt);
-#endif
} else
printf("does not exist");
}
struct vnode_fsparam par;
memset(&par, 0, sizeof(struct vnode_fsparam));
-#if 0
- AFS_GLOCK();
- ObtainWriteLock(&avc->lock,342);
- if (avc->f.states & CStatd) {
- par.vnfs_vtype = avc->f.m.Type;
- par.vnfs_vops = afs_vnodeop_p;
- par.vnfs_filesize = avc->f.m.Length;
- if (!ac->cnp)
- par.vnfs_flags = VNFS_NOCACHE;
- dead = 0;
- } else {
- par.vnfs_vtype = VNON;
- par.vnfs_vops = afs_dead_vnodeop_p;
- par.vnfs_flags = VNFS_NOCACHE|VNFS_CANTCACHE;
- dead = 1;
- }
- ReleaseWriteLock(&avc->lock);
- AFS_GUNLOCK();
- par.vnfs_dvp = ac->dvp;
- par.vnfs_cnp = ac->cnp;
- par.vnfs_markroot = ac->markroot;
-#else
par.vnfs_vtype = VNON;
par.vnfs_vops = afs_dead_vnodeop_p;
par.vnfs_flags = VNFS_NOCACHE|VNFS_CANTCACHE;
-#endif
par.vnfs_mp = afs_globalVFS;
par.vnfs_fsnode = avc;
vnode_addfsref(vp);
vnode_ref(vp);
avc->v = vp;
-#if 0
- if (dead) {
- vnode_recycle(vp); /* terminate as soon as iocount drops */
- avc->f.states |= CDeadVnode;
- } else if (!ac->markroot && !ac->cnp) {
- /* the caller doesn't know anything about this vnode. if markroot
- should have been set and wasn't, bad things may happen, so encourage
- it to recycle */
- vnode_recycle(vp);
- }
-#else
vnode_recycle(vp); /* terminate as soon as iocount drops */
avc->f.states |= CDeadVnode;
-#endif
}
return error;
#else
#ifdef AFS_DARWIN80_ENV
/* if this fails, then tvc has been unrefed and may have been freed.
Don't touch! */
-int
-afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct componentname *cnp, int isroot) {
- vnode_t ovp;
- vnode_t nvp;
- int error;
- struct vnode_fsparam par;
- AFS_GLOCK();
- ObtainWriteLock(&avc->lock,325);
- ovp = AFSTOV(avc);
- if (!(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON) {
- AFS_GUNLOCK();
+int
+afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp,
+ struct componentname *cnp, int isroot, int locked)
+{
+ vnode_t ovp;
+ vnode_t nvp;
+ int error;
+ struct vnode_fsparam par;
+
+ if (!locked) {
+ AFS_GLOCK();
+ ObtainWriteLock(&avc->lock,325);
+ }
+ ovp = AFSTOV(avc);
+
+ if (!(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON) {
+ AFS_GUNLOCK();
#if 0 /* unsupported */
if (dvp && cnp)
- vnode_update_identity(ovp, dvp, cnp->cn_nameptr, cnp->cn_namelen,
- cnp->cn_hash,
- VNODE_UPDATE_PARENT|VNODE_UPDATE_NAME);
+ vnode_update_identity(ovp, dvp, cnp->cn_nameptr, cnp->cn_namelen,
+ cnp->cn_hash,
+ VNODE_UPDATE_PARENT|VNODE_UPDATE_NAME);
#endif
/* Can end up in reclaim... drop GLOCK */
- vnode_rele(ovp);
+ vnode_rele(ovp);
AFS_GLOCK();
- ReleaseWriteLock(&avc->lock);
+ if (!locked) {
+ ReleaseWriteLock(&avc->lock);
+ AFS_GUNLOCK();
+ }
+ return 0;
+ }
+
+ if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
+ panic("vcache %p should not be CDeadVnode", avc);
+ AFS_GUNLOCK();
+ memset(&par, 0, sizeof(struct vnode_fsparam));
+ par.vnfs_mp = afs_globalVFS;
+ par.vnfs_vtype = avc->f.m.Type;
+ par.vnfs_vops = afs_vnodeop_p;
+ par.vnfs_filesize = avc->f.m.Length;
+ par.vnfs_fsnode = avc;
+ par.vnfs_dvp = dvp;
+ if (cnp && (cnp->cn_flags & ISDOTDOT) == 0)
+ par.vnfs_cnp = cnp;
+ if (!dvp || !cnp || (cnp->cn_flags & MAKEENTRY) == 0)
+ par.vnfs_flags = VNFS_NOCACHE;
+ if (isroot)
+ par.vnfs_markroot = 1;
+ error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &nvp);
+ if (!error) {
+ vnode_addfsref(nvp);
+ if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
+ printf("vcache %p should not be CDeadVnode", avc);
+ if (avc->v == ovp) {
+ if (!(avc->f.states & CVInit)) {
+ vnode_clearfsnode(ovp);
+ vnode_removefsref(ovp);
+ }
+ /* we're discarding on a fixup. mark for recycle */
+ if (!(avc->f.states & CDeadVnode))
+ vnode_recycle(ovp);
+ }
+ avc->v = nvp;
+ avc->f.states &=~ CDeadVnode;
+ /* If we were carrying an extra ref for dirty, hold/push it. */
+ if (avc->f.ddirty_flags) {
+ vnode_get(nvp);
+ vnode_ref(nvp);
+ }
+ /* If we were carrying an extra ref for shadow, hold/push it. */
+ if (avc->f.shadow.vnode) {
+ vnode_get(nvp);
+ vnode_ref(nvp);
+ }
+ }
+ /* Drop any extra dirty ref on the old vnode */
+ if (avc->f.ddirty_flags) {
+ vnode_put(ovp);
+ vnode_rele(ovp);
+ }
+ /* Drop any extra shadow ref on the old vnode */
+ if (avc->f.shadow.vnode) {
+ vnode_put(ovp);
+ vnode_rele(ovp);
+ }
+ /* If it's ref'd still, unmark stat'd to force new lookup */
+ if ((vnode_vtype(ovp) != avc->f.m.Type) && VREFCOUNT_GT(avc, 1))
+ avc->f.states &= ~CStatd;
+
+ vnode_put(ovp);
+ vnode_rele(ovp);
+ AFS_GLOCK();
+ if (!locked)
+ ReleaseWriteLock(&avc->lock);
+ if (!error)
+ afs_osi_Wakeup(&avc->f.states);
+ if (!locked)
AFS_GUNLOCK();
- return 0;
- }
- if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
- panic("vcache %p should not be CDeadVnode", avc);
- AFS_GUNLOCK();
- memset(&par, 0, sizeof(struct vnode_fsparam));
- par.vnfs_mp = afs_globalVFS;
- par.vnfs_vtype = avc->f.m.Type;
- par.vnfs_vops = afs_vnodeop_p;
- par.vnfs_filesize = avc->f.m.Length;
- par.vnfs_fsnode = avc;
- par.vnfs_dvp = dvp;
- if (cnp && (cnp->cn_flags & ISDOTDOT) == 0)
- par.vnfs_cnp = cnp;
- if (!dvp || !cnp || (cnp->cn_flags & MAKEENTRY) == 0)
- par.vnfs_flags = VNFS_NOCACHE;
- if (isroot)
- par.vnfs_markroot = 1;
- error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &nvp);
- if (!error) {
- vnode_addfsref(nvp);
- if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
- printf("vcache %p should not be CDeadVnode", avc);
- if (avc->v == ovp) {
- if (!(avc->f.states & CVInit)) {
- vnode_clearfsnode(ovp);
- vnode_removefsref(ovp);
- }
- }
- avc->v = nvp;
- avc->f.states &=~ CDeadVnode;
- }
- vnode_put(ovp);
- vnode_rele(ovp);
- AFS_GLOCK();
- ReleaseWriteLock(&avc->lock);
- if (!error)
- afs_osi_Wakeup(&avc->f.states);
- AFS_GUNLOCK();
- return error;
+ return error;
}
#endif