int code;
AFS_GLOCK();
- code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred);
+ code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
AFS_GUNLOCK();
return code;
}
* anyway, so the difference between 512K and 1000000 shouldn't matter
* much, and "&" is a lot faster than "%".
*/
-#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
/* nfs on these systems puts an 0 in nsec and stores the nfs usec (aka
dataversion) in va_gen */
attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
- attrs->va_ctime.tv_nsec =0;
- attrs->va_blocksize = PAGESIZE; /* XXX Was 8192 XXX */
+ attrs->va_ctime.tv_nsec = 0;
attrs->va_gen = hgetlo(avc->m.DataVersion);
- attrs->va_flags = 0;
-#else
-#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV)
+#elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV)
attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
- attrs->va_ctime.tv_nsec =
- (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000;
-#if defined(AFS_AIX41_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
- attrs->va_blocksize = PAGESIZE; /* XXX Was 8192 XXX */
+ attrs->va_ctime.tv_nsec = (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000;
#else
- attrs->va_blksize = PAGESIZE; /* XXX Was 8192 XXX */
+ attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec =
+ attrs->va_ctime.tv_usec = (hgetlo(avc->m.DataVersion) & 0x7ffff);
+#endif
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_OSF_ENV)
+ attrs->va_flags = 0;
#endif
+#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)
+ attrs->va_blksize = PAGESIZE; /* XXX Was 8192 XXX */
#else
- attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec =
- attrs->va_ctime.tv_usec =
- (hgetlo(avc->m.DataVersion) & 0x7ffff);
attrs->va_blocksize = PAGESIZE; /* XXX Was 8192 XXX */
#endif
-#endif
#ifdef AFS_DEC_ENV
/* Have to use real device #s in Ultrix, since that's how FS type is
* encoded. If rdev doesn't match Ultrix equivalent of statfs's rdev, then
#else
attrs->va_rdev = 1;
#endif
+
/*
* Below return 0 (and not 1) blocks if the file is zero length. This conforms
* better with the other filesystems that do return 0.
*/
-#if defined(AFS_OSF_ENV)
-#ifdef va_size_rsv
- attrs->va_size_rsv = 0;
-#endif
-/* XXX do this */
-/* attrs->va_gen = avc->m.DataVersion;*/
- attrs->va_flags = 0;
-#endif /* AFS_OSF_ENV || AFS_DARWIN_ENV */
-
#if !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
#if !defined(AFS_HPUX_ENV)
#ifdef AFS_SUN5_ENV
attrs->va_nblocks = (attrs->va_size? ((attrs->va_size + 1023)>>10) << 1 : 0);
-#else
-#if defined(AFS_SGI_ENV)
+#elif defined(AFS_SGI_ENV)
attrs->va_blocks = BTOBB(attrs->va_size);
#else
attrs->va_blocks = (attrs->va_size? ((attrs->va_size + 1023)>>10) << 1 : 0);
#endif
-#endif
#else /* !defined(AFS_HPUX_ENV) */
attrs->va_blocks = (attrs->va_size? ((attrs->va_size + 1023)>>10) : 0);
#endif /* !defined(AFS_HPUX_ENV) */
-#else /* ! AFS_OSF_ENV && !AFS_XBSD_ENV */
+#else /* ! AFS_OSF_ENV && !AFS_DARWIN_ENV && !AFS_XBSD_ENV */
attrs->va_bytes = (attrs->va_size? (attrs->va_size + 1023) : 1024);
#ifdef va_bytes_rsv
attrs->va_bytes_rsv = -1;
#endif
-#endif /* ! AFS_OSF_ENV */
+#endif /* ! AFS_OSF_ENV && !AFS_DARWIN_ENV && !AFS_XBSD_ENV */
#ifdef AFS_LINUX22_ENV
- /* And linux has it's own stash as well. */
+ /* And linux has its own stash as well. */
vattr2inode(AFSTOV(avc), attrs);
#endif
#ifdef notdef
*/
if ((avc->flockCount < 0) && (getpid() != avc->ownslock)) {
#ifdef AFS_AIX41_ENV
- if (onlymine || (getppid() != avc->ownslock)) {
+ if (onlymine || (getppid() != avc->ownslock)) {
#else
- if (onlymine || (u.u_procp->p_ppid != avc->ownslock)) {
+ if (onlymine || (u.u_procp->p_ppid != avc->ownslock)) {
#endif
- ReleaseWriteLock(&avc->lock);
- return 0;
- }
+ ReleaseWriteLock(&avc->lock);
+ return 0;
+ }
}
#endif
if (lockIdcmp2(&flock, avc, NULL, onlymine, clid)) {
- ReleaseWriteLock(&avc->lock);
- return 0;
+ ReleaseWriteLock(&avc->lock);
+ return 0;
}
#ifdef AFS_AIX_ENV
avc->ownslock = 0;
#endif
if (avc->flockCount == 0) {
- ReleaseWriteLock(&avc->lock);
- return 0 /*ENOTTY*/;
- /* no lock held */
+ ReleaseWriteLock(&avc->lock);
+ return 0 /*ENOTTY*/;
+ /* no lock held */
}
/* unlock the lock */
if (avc->flockCount > 0) {
- slpp = &avc->slocks;
- for (slp = *slpp; slp;) {
- if (!lockIdcmp2(&flock, avc, slp, onlymine, clid)) {
- avc->flockCount--;
- tlp = *slpp = slp->next;
- osi_FreeSmallSpace(slp);
- slp = tlp;
- } else {
- slpp = &slp->next;
- slp = *slpp;
+ slpp = &avc->slocks;
+ for (slp = *slpp; slp;) {
+ if (!lockIdcmp2(&flock, avc, slp, onlymine, clid)) {
+ avc->flockCount--;
+ tlp = *slpp = slp->next;
+ osi_FreeSmallSpace(slp);
+ slp = tlp;
+ } else {
+ slpp = &slp->next;
+ slp = *slpp;
+ }
}
- }
}
else if (avc->flockCount == -1) {
- afs_StoreAllSegments(avc, areq, AFS_ASYNC); /* fsync file early */
- avc->flockCount = 0;
- /* And remove the (only) exclusive lock entry from the list... */
- osi_FreeSmallSpace(avc->slocks);
- avc->slocks = 0;
+ afs_StoreAllSegments(avc, areq, AFS_ASYNC); /* fsync file early */
+ avc->flockCount = 0;
+ /* And remove the (only) exclusive lock entry from the list... */
+ osi_FreeSmallSpace(avc->slocks);
+ avc->slocks = 0;
}
if (avc->flockCount == 0) {
do {
tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
if (tc) {
- XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
- RX_AFS_GUNLOCK();
- code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *)
- &avc->fid.Fid, &tsync);
- RX_AFS_GLOCK();
- XSTATS_END_TIME;
+ XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
+ RX_AFS_GUNLOCK();
+ code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *)
+ &avc->fid.Fid, &tsync);
+ RX_AFS_GLOCK();
+ XSTATS_END_TIME;
}
else code = -1;
} while
- (afs_Analyze(tc, code, &avc->fid, areq,
- AFS_STATS_FS_RPCIDX_RELEASELOCK,
- SHARED_LOCK, NULL));
+ (afs_Analyze(tc, code, &avc->fid, areq,
+ AFS_STATS_FS_RPCIDX_RELEASELOCK,
+ SHARED_LOCK, NULL));
}
}
else {
/* handle any closing cleanup stuff */
+int
#ifdef AFS_SGI_ENV
afs_close(OSI_VC_ARG(avc), aflags, lastclose,
#if !defined(AFS_SGI65_ENV)
afs_close(OSI_VC_ARG(avc), aflags, count, acred)
#endif
int count;
+#elif defined(AFS_OBSD_ENV)
+afs_close(OSI_VC_ARG(avc), aflags, acred, aproc)
+ struct proc *aproc;
#else
afs_close(OSI_VC_ARG(avc), aflags, acred)
#endif
if (avc->flockCount) { /* Release Lock */
#if defined(AFS_OSF_ENV) || defined(AFS_SUN_ENV)
HandleFlock(avc, LOCK_UN, &treq, u.u_procp->p_pid, 1/*onlymine*/);
+#elif defined(AFS_OBSD_ENV)
+ HandleFlock(avc, LOCK_UN, &treq, aproc->p_pid, 1/*onlymine*/);
#else
HandleFlock(avc, LOCK_UN, &treq, 0, 1/*onlymine*/);
#endif
}
-
+int
#ifdef AFS_OSF_ENV
afs_fsync(avc, fflags, acred, waitfor)
int fflags;
DFlush(); /* write out dir buffers */
afs_WriteThroughDSlots(); /* write through cacheinfo entries */
afs_FlushActiveVcaches(1);/* keep flocks held & flush nfs writes */
+#ifdef AFS_DISCON_ENV
+ afs_StoreDirtyVcaches();
+#endif
afs_CheckRXEpoch();
last1MinCheck = now;
}
int afs_sysnamecount = 0;
struct volume *Initialafs_freeVolList;
int afs_memvolumes = 0;
+#ifdef AFS_OBSD_ENV
+static struct vnode *volumeVnode;
+#endif
/*
* Initialization order is important. Must first call afs_CacheInit,
/*
- * afs_InitVolumeInfo
- *
- * Description:
- * Set up the volume info storage file.
- *
- * Parameters:
- * afile : the file to be declared to be the volume info storage
- * file for AFS. It must be already truncated to 0 length.
- *
- * Environment:
- * This function is called only during initialization.
+ * LookupInodeByPath
*
- * WARNING: Data will be written to this file over time by AFS.
+ * Look up inode given a file name.
+ * Optionally return the vnode too.
+ * If the vnode is not returned, we rele it.
*/
-
-static int LookupInodeByPath(char *filename, ino_t *inode)
+static int LookupInodeByPath(char *filename, ino_t *inode, struct vnode **fvpp)
{
afs_int32 code;
code = gop_lookupname(filename, AFS_UIOSYS, 0, NULL, &filevp);
if (code) return code;
*inode = afs_vnodeToInumber(filevp);
-#ifdef AFS_DEC_ENV
- grele(filevp);
+ if (fvpp)
+ *fvpp = filevp;
+ else {
+#if defined(AFS_DEC_ENV)
+ grele(filevp);
#else
- AFS_RELE((struct vnode *)filevp);
+ AFS_RELE(filevp);
#endif
+ }
#endif /* AFS_LINUX22_ENV */
return 0;
ino_t inode;
int code;
- code = LookupInodeByPath(afile, &inode);
+ code = LookupInodeByPath(afile, &inode, NULL);
return afs_cellname_init(inode, code);
}
+/*
+ * afs_InitVolumeInfo
+ *
+ * Description:
+ * Set up the volume info storage file.
+ *
+ * Parameters:
+ * afile : the file to be declared to be the volume info storage
+ * file for AFS. It must be already truncated to 0 length.
+ *
+ * Environment:
+ * This function is called only during initialization.
+ *
+ * WARNING: Data will be written to this file over time by AFS.
+ */
+
int afs_InitVolumeInfo(char *afile)
{
int code;
struct osi_file *tfile;
AFS_STATCNT(afs_InitVolumeInfo);
- code = LookupInodeByPath(afile, &volumeInode);
- if (code) return code;
+#if defined(AFS_OBSD_ENV)
+ /*
+ * On Open/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.
+ * If it's AFS, then ->vclean->afs_nbsd_reclaim->FlushVCache->QueueVCB->
+ * GetVolume->FindVolume-> waits on afs_xvolume lock !
+ *
+ * In general, anything that's called with afs_xvolume locked must not
+ * end up calling getnewvnode(). The only cases I've found so far
+ * are things which try to get the volumeInode, and since we keep
+ * it in the cache...
+ */
+ code = LookupInodeByPath(afile, &volumeInode, &volumeVnode);
+#else
+ code = LookupInodeByPath(afile, &volumeInode, NULL);
+#endif
+ if (code)
+ return code;
tfile = afs_CFileOpen(volumeInode);
afs_CFileTruncate(tfile, 0);
afs_CFileClose(tfile);
afs_cacheFiles = afs_cacheBlocks = 0;
pag_epoch = maxIHint = nihints = usedihint = 0;
pagCounter = 0;
+#ifdef AFS_OBSD_ENV
+ AFS_RELE(volumeVnode); /* let it go, finally. */
+ volumeVnode = NULL;
+ if (cacheDev.held_vnode) {
+ AFS_RELE(cacheDev.held_vnode);
+ cacheDev.held_vnode = NULL;
+ }
+#endif
cacheInode = volumeInode = (ino_t)0;
-
cacheInfoModTime = 0;
afs_fsfragsize = 1023;
return tvc;
}
#endif /* AFS_OSF_ENV */
+#ifdef AFS_OBSD_ENV
+ VOP_LOCK(AFSTOV(tvc), LK_EXCLUSIVE | LK_RETRY, curproc);
+ uvm_vnp_uncache(AFSTOV(tvc));
+ VOP_UNLOCK(AFSTOV(tvc), 0, curproc);
+#endif
ObtainWriteLock(&afs_xcbhash, 464);
tvc->states &= ~CUnique;