* shutdown_vcache
*
*/
-#include "../afs/param.h" /*Should be always first*/
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
#include "../afs/sysincludes.h" /*Standard vendor system headers*/
#include "../afs/afsincludes.h" /*AFS-based standard headers*/
#include "../afs/afs_stats.h"
#ifdef AFS_OSF_ENV
extern struct mount *afs_globalVFS;
extern struct vnodeops Afs_vnodeops;
+#elif defined(AFS_DARWIN_ENV)
+extern struct mount *afs_globalVFS;
#else
extern struct vfs *afs_globalVFS;
#endif /* AFS_OSF_ENV */
/* This should put it back on the vnode free list since usecount is 1 */
afs_vcount--;
vSetType(avc, VREG);
- if (avc->vrefCount > 0) {
+ if (VREFCOUNT(avc) > 0) {
VN_UNLOCK((struct vnode *)avc);
AFS_RELE((struct vnode *)avc);
} else {
int vmax = 2 * afs_cacheStats;
int vn = VCACHE_FREE;
+ AFS_GUNLOCK();
+ shrink_dcache_sb(afs_globalVFS);
+ AFS_GLOCK();
+
i = 0;
for(tq = VLRU.prev; tq != &VLRU && vn > 0; tq = uq) {
tvc = QTOV(tq);
if (tvc == afs_globalVp)
continue;
- if ( tvc->vrefCount && tvc->opens == 0 ) {
+ if ( VREFCOUNT(tvc) && tvc->opens == 0 ) {
struct inode *ip = (struct inode*)tvc;
if (list_empty(&ip->i_dentry)) {
vn --;
refpanic ("Exceeded pool of AFS vnodes(VLRU cycle?)");
else if (QNext(uq) != tq)
refpanic ("VLRU inconsistent");
- else if (tvc->vrefCount < 1)
+ else if (VREFCOUNT(tvc) < 1)
refpanic ("refcnt 0 on VLRU");
- if ( tvc->vrefCount == 1 && tvc->opens == 0
+ if ( VREFCOUNT(tvc) == 1 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
code = afs_FlushVCache(tvc, &fv_slept);
if (code == 0) {
else if (QNext(uq) != tq)
refpanic("VLRU inconsistent");
- if (tvc->vrefCount == 0 && tvc->opens == 0
+#ifdef AFS_DARWIN_ENV
+ if (tvc->opens == 0 && ((tvc->states & CUnlinkedDel) == 0) &&
+ VREFCOUNT(tvc) == 1 && UBCINFOEXISTS(&tvc->v)) {
+ osi_VM_TryReclaim(tvc, &fv_slept);
+ if (fv_slept) {
+ uq = VLRU.prev;
+ i = 0;
+ continue; /* start over - may have raced. */
+ }
+ }
+#endif
+ if (VREFCOUNT(tvc) == 0 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
code = afs_FlushVCache(tvc, &fv_slept);
if (code == 0) {
#endif /* AFS_MACH_ENV */
#if defined(AFS_SGI_ENV)
{ char name[METER_NAMSZ];
- bzero(tvc, sizeof(struct vcache));
+ memset(tvc, 0, sizeof(struct vcache));
tvc->v.v_number = ++afsvnumbers;
tvc->vc_rwlockid = OSI_NO_LOCKID;
initnsema(&tvc->vc_rwlock, 1, makesname(name, "vrw", tvc->v.v_number));
#endif /* AFS_MACH_ENV */
#if !defined(AFS_SGI_ENV) && !defined(AFS_OSF_ENV)
- bzero((char *)tvc, sizeof(struct vcache));
+ memset((char *)tvc, 0, sizeof(struct vcache));
#else
tvc->uncred = 0;
#endif
/* Hold it for the LRU (should make count 2) */
VN_HOLD((struct vnode *)tvc);
#else /* AFS_OSF_ENV */
- tvc->vrefCount = 1; /* us */
+ VREFCOUNT_SET(tvc, 1); /* us */
#endif /* AFS_OSF_ENV */
#ifdef AFS_AIX32_ENV
LOCK_INIT(&tvc->pvmlock, "vcache pvmlock");
#ifdef AFS_AIX_ENV
/* Don't forget to free the gnode space */
tvc->v.v_gnode = gnodepnt = (struct gnode *) osi_AllocSmallSpace(sizeof(struct gnode));
- bzero((char *)gnodepnt, sizeof(struct gnode));
+ memset((char *)gnodepnt, 0, sizeof(struct gnode));
#endif
#ifdef AFS_SGI64_ENV
- bzero((void*)&(tvc->vc_bhv_desc), sizeof(tvc->vc_bhv_desc));
+ memset((void*)&(tvc->vc_bhv_desc), 0, sizeof(tvc->vc_bhv_desc));
bhv_desc_init(&(tvc->vc_bhv_desc), tvc, tvc, &Afs_vnodeops);
#ifdef AFS_SGI65_ENV
vn_bhv_head_init(&(tvc->v.v_bh), "afsvp");
#else
SetAfsVnode((struct vnode *)tvc);
#endif /* AFS_SGI64_ENV */
+#ifdef AFS_DARWIN_ENV
+ tvc->v.v_ubcinfo = UBC_INFO_NULL;
+ lockinit(&tvc->rwlock, PINOD, "vcache rwlock", 0, 0);
+ cache_purge((struct vnode *)tvc);
+ tvc->v.v_data=tvc;
+ tvc->v.v_tag=VT_AFS;
+ /* VLISTNONE(&tvc->v); */
+ tvc->v.v_freelist.tqe_next=0;
+ tvc->v.v_freelist.tqe_prev=(struct vnode **)0xdeadb;
+ /*tvc->vrefCount++;*/
+#endif
/*
* The proper value for mvstat (for root fids) is setup by the caller.
*/
sema_init(&ip->i_zombie, 1);
init_waitqueue_head(&ip->i_wait);
spin_lock_init(&ip->i_data.i_shared_lock);
- INIT_LIST_HEAD(&ip->i_data.pages);
+#ifdef STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK
+ spin_lock_init(&ip->i_data.page_lock);
+#endif
+ INIT_LIST_HEAD(&ip->i_data.clean_pages);
+ INIT_LIST_HEAD(&ip->i_data.dirty_pages);
+ INIT_LIST_HEAD(&ip->i_data.locked_pages);
+ INIT_LIST_HEAD(&ip->i_dirty_buffers);
ip->i_data.host = (void*) ip;
ip->i_mapping = &ip->i_data;
+#ifdef STRUCT_INODE_HAS_I_TRUNCATE_SEM
+ init_rwsem(&ip->i_truncate_sem);
+#endif
#else
sema_init(&ip->i_atomic_write, 1);
init_waitqueue(&ip->i_wait);
#endif
tvc->h1.dchint = 0;
osi_dnlc_purgedp(tvc); /* this may be overkill */
- bzero((char *)&(tvc->quick),sizeof(struct vtodc));
- bzero((char *)&(tvc->callsort),sizeof(struct afs_q));
+ memset((char *)&(tvc->quick), 0, sizeof(struct vtodc));
+ memset((char *)&(tvc->callsort), 0, sizeof(struct afs_q));
tvc->slocks = (struct SimpleLocks *)0;
i = VCHash(afid);
/*
* That's because if we come in via the CUnlinkedDel bit state path we'll be have 0 refcnt
*/
- osi_Assert(tvc->vrefCount > 0);
+ osi_Assert(VREFCOUNT(tvc) > 0);
AFS_RWLOCK((vnode_t *)tvc, VRWLOCK_WRITE);
#endif
ObtainWriteLock(&tvc->lock,52);
AFS_FAST_RELE(tvc);
if (didCore) {
#ifdef AFS_GFS_ENV
- tvc->vrefCount--;
+ VREFCOUNT_DEC(tvc);
#else
AFS_RELE((struct vnode *)tvc);
#endif
crfree(cred);
}
}
+#ifdef AFS_DARWIN_ENV
+ if (VREFCOUNT(tvc) == 1 && UBCINFOEXISTS(&tvc->v)) {
+ if (tvc->opens) panic("flushactive open, hasubc, but refcnt 1");
+ osi_VM_TryReclaim(tvc,0);
+ }
+#endif
}
}
ReleaseReadLock(&afs_xvcache);
vcache2inode(tvc);
#endif
ReleaseWriteLock(&tvc->lock);
+#ifdef AFS_DARWIN_ENV
+ osi_VM_Setup(tvc);
+#endif
return tvc;
}
/* stat the file */
afs_RemoveVCB(afid);
{
- struct AFSFetchStatus OutStatus;
- code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
+ struct AFSFetchStatus OutStatus;
+
+ if (afs_DynrootNewVnode(tvc, &OutStatus)) {
+ afs_ProcessFS(tvc, &OutStatus, areq);
+ tvc->states |= CStatd | CUnique;
+ code = 0;
+ } else {
+ code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
+ }
}
if (code) {
}
ReleaseWriteLock(&tvc->lock);
+#ifdef AFS_DARWIN_ENV
+ osi_VM_Setup(avc);
+#endif
return tvc;
} /*afs_GetVCache*/
afs_ProcessFS(tvc, &OutStatus, areq);
ReleaseWriteLock(&tvc->lock);
+#ifdef AFS_DARWIN_ENV
+ osi_VM_Setup(tvc);
+#endif
return tvc;
}
return code;
}
+#if 0
/*
* afs_StuffVcache
*
*/
afs_PutVCache(tvc, WRITE_LOCK);
} /*afs_StuffVcache*/
+#endif
/*
* afs_PutVCache
if (tvc && (tvc->states & CStatd))
vcache2inode(tvc); /* mainly to reset i_nlink */
#endif
+#ifdef AFS_DARWIN_ENV
+ if (tvc)
+ osi_VM_Setup(tvc);
+#endif
return tvc;
} /*afs_FindVCache*/
#if !defined(AFS_OSF_ENV)
/* Allocate and thread the struct vcache entries */
tvp = (struct vcache *) afs_osi_Alloc(astatSize * sizeof(struct vcache));
- bzero((char *)tvp, sizeof(struct vcache)*astatSize);
+ memset((char *)tvp, 0, sizeof(struct vcache)*astatSize);
Initial_freeVCList = tvp;
freeVCList = &(tvp[0]);
vms_delete(tvc->segid);
AFS_GLOCK();
tvc->segid = tvc->vmh = NULL;
- if (tvc->vrefCount) osi_Panic("flushVcache: vm race");
+ if (VREFCOUNT(tvc)) osi_Panic("flushVcache: vm race");
}
if (tvc->credp) {
crfree(tvc->credp);