#include <afsconfig.h>
#include "afs/param.h"
-RCSID
- ("$Header$");
#include "afs/sysincludes.h" /*Standard vendor system headers */
#include "afsincludes.h" /*AFS-based standard headers */
afs_int32 afs_discardDCCount; /*!< Count of elts in discardDCList */
struct dcache *afs_freeDSList; /*!< Free list for disk slots */
struct dcache *afs_Initial_freeDSList; /*!< Initial list for above */
-#if defined(LINUX_USE_FH)
-struct fid cacheitems_fh;
-int cacheitems_fh_type;
-#else
-ino_t cacheInode; /*!< Inode for CacheItems file */
-#endif
+afs_dcache_id_t cacheInode; /*!< Inode for CacheItems file */
struct osi_file *afs_cacheInodep = 0; /*!< file for CacheItems inode */
struct afs_q afs_DLRU; /*!< dcache LRU */
afs_int32 afs_dhashsize = 1024;
afs_int32 afs_cacheStats; /*!< Stat entries in cache */
afs_int32 afs_blocksUsed; /*!< Number of blocks in use */
afs_int32 afs_blocksDiscarded; /*!<Blocks freed but not truncated */
-afs_int32 afs_fsfragsize = 1023; /*!< Underlying Filesystem minimum unit
+afs_int32 afs_fsfragsize = AFS_MIN_FRAGSIZE; /*!< Underlying Filesystem minimum unit
*of disk allocation usually 1K
*this value is (truefrag -1 ) to
*save a bunch of subtracts... */
int dcacheDisabled = 0;
-static int afs_UFSCacheFetchProc(struct rx_call *, struct osi_file *,
- afs_size_t, struct dcache *,
- struct vcache *, afs_size_t *,
- afs_size_t *, afs_int32);
-
-static int afs_UFSCacheStoreProc(struct rx_call *, struct osi_file *,
- afs_int32, struct vcache *,
- int *, afs_size_t *,
- afs_size_t *);
-
struct afs_cacheOps afs_UfsCacheOps = {
-#if defined(LINUX_USE_FH)
- osi_UFSOpen_fh,
-#else
+#if defined(AFS_SGI_ENV) && !defined(__c99)
osi_UFSOpen,
-#endif
osi_UFSTruncate,
afs_osi_Read,
afs_osi_Write,
osi_UFSClose,
afs_UFSRead,
afs_UFSWrite,
- afs_UFSCacheFetchProc,
- afs_UFSCacheStoreProc,
afs_UFSGetDSlot,
afs_UFSGetVolSlot,
afs_UFSHandleLink,
+#else
+ .open = osi_UFSOpen,
+ .truncate = osi_UFSTruncate,
+ .fread = afs_osi_Read,
+ .fwrite = afs_osi_Write,
+ .close = osi_UFSClose,
+ .vread = afs_UFSRead,
+ .vwrite = afs_UFSWrite,
+ .GetDSlot = afs_UFSGetDSlot,
+ .GetVolSlot = afs_UFSGetVolSlot,
+ .HandleLink = afs_UFSHandleLink,
+#endif
};
struct afs_cacheOps afs_MemCacheOps = {
+#if (defined(AFS_SGI_ENV) && !defined(__c99))
afs_MemCacheOpen,
afs_MemCacheTruncate,
afs_MemReadBlk,
afs_MemCacheClose,
afs_MemRead,
afs_MemWrite,
- afs_MemCacheFetchProc,
- afs_MemCacheStoreProc,
afs_MemGetDSlot,
afs_MemGetVolSlot,
afs_MemHandleLink,
+#else
+ .open = afs_MemCacheOpen,
+ .truncate = afs_MemCacheTruncate,
+ .fread = afs_MemReadBlk,
+ .fwrite = afs_MemWriteBlk,
+ .close = afs_MemCacheClose,
+ .vread = afs_MemRead,
+ .vwrite = afs_MemWrite,
+ .GetDSlot = afs_MemGetDSlot,
+ .GetVolSlot = afs_MemGetVolSlot,
+ .HandleLink = afs_MemHandleLink,
+#endif
};
int cacheDiskType; /*Type of backing disk for cache */
afs_TruncateDaemonRunning = 1;
while (1) {
cb_lowat = PERCENT((CM_DCACHESPACEFREEPCT - CM_DCACHEEXTRAPCT), afs_cacheBlocks);
- MObtainWriteLock(&afs_xdcache, 266);
+ ObtainWriteLock(&afs_xdcache, 266);
if (afs_CacheTooFull) {
int space_needed, slots_needed;
/* if we get woken up, we should try to clean something out */
if (!afs_CacheIsTooFull())
afs_CacheTooFull = 0;
} /* end of cache cleanup */
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/*
* This is a defensive check to try to avoid starving threads
afs_stats_AddTo(CTD_stats.CTD_sleepTime, CTD_tmpTime);
}
if (afs_termState == AFSOP_STOP_TRUNCDAEMON) {
-#ifdef AFS_AFSDB_ENV
afs_termState = AFSOP_STOP_AFSDB;
-#else
- afs_termState = AFSOP_STOP_RXEVENT;
-#endif
afs_osi_Wakeup(&afs_termState);
break;
}
afs_size_t tchunkoffset = 0;
afid = &tdc->f.fid;
/* xdcache is lower than the xvcache lock */
- MReleaseWriteLock(&afs_xdcache);
- MObtainReadLock(&afs_xvcache);
+ ReleaseWriteLock(&afs_xdcache);
+ ObtainReadLock(&afs_xvcache);
tvc = afs_FindVCache(afid, 0, 0 /* no stats, no vlru */ );
- MReleaseReadLock(&afs_xvcache);
- MObtainWriteLock(&afs_xdcache, 527);
+ ReleaseReadLock(&afs_xvcache);
+ ObtainWriteLock(&afs_xdcache, 527);
skip = 0;
if (tdc->refCount > 1)
skip = 1;
if (!skip && (chunkFlags & IFAnyPages)) {
int code;
- MReleaseWriteLock(&afs_xdcache);
- MObtainWriteLock(&tvc->vlock, 543);
+ ReleaseWriteLock(&afs_xdcache);
+ ObtainWriteLock(&tvc->vlock, 543);
if (tvc->multiPage) {
skip = 1;
goto endmultipage;
tvc->vstates |= VPageCleaning;
/* block getting new pages */
tvc->activeV++;
- MReleaseWriteLock(&tvc->vlock);
+ ReleaseWriteLock(&tvc->vlock);
/* One last recheck */
- MObtainWriteLock(&afs_xdcache, 333);
+ ObtainWriteLock(&afs_xdcache, 333);
chunkFlags = afs_indexFlags[tdc->index];
if (tdc->refCount > 1 || (chunkFlags & IFDataMod)
|| (osi_Active(tvc) && (tvc->f.states & CDCLock)
&& (chunkFlags & IFAnyPages))) {
skip = 1;
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
goto endputpage;
}
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
code = osi_VM_GetDownD(tvc, tdc);
- MObtainWriteLock(&afs_xdcache, 269);
+ ObtainWriteLock(&afs_xdcache, 269);
/* we actually removed all pages, clean and dirty */
if (code == 0) {
afs_indexFlags[tdc->index] &=
~(IFDirtyPages | IFAnyPages);
} else
skip = 1;
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
endputpage:
- MObtainWriteLock(&tvc->vlock, 544);
+ ObtainWriteLock(&tvc->vlock, 544);
if (--tvc->activeV == 0
&& (tvc->vstates & VRevokeWait)) {
tvc->vstates &= ~VRevokeWait;
afs_osi_Wakeup((char *)&tvc->vstates);
}
endmultipage:
- MReleaseWriteLock(&tvc->vlock);
+ ReleaseWriteLock(&tvc->vlock);
} else
#endif /* AFS_SUN5_ENV */
{
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
}
afs_PutVCache(tvc); /*XXX was AFS_FAST_RELE?*/
- MObtainWriteLock(&afs_xdcache, 528);
+ ObtainWriteLock(&afs_xdcache, 528);
if (afs_indexFlags[tdc->index] &
(IFDataMod | IFDirtyPages | IFAnyPages))
skip = 1;
AFS_STATCNT(afs_FreeDiscardedDCache);
- MObtainWriteLock(&afs_xdcache, 510);
+ ObtainWriteLock(&afs_xdcache, 510);
if (!afs_blocksDiscarded) {
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
return;
}
afs_stats_cmperf.cacheBlocksDiscarded = afs_blocksDiscarded;
/* We can lock because we just took it off the free list */
ObtainWriteLock(&tdc->lock, 626);
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/*
* Truncate the element to reclaim its space
*/
-#if defined(LINUX_USE_FH)
- tfile = afs_CFileOpen(&tdc->f.fh, tdc->f.fh_type);
-#else
- tfile = afs_CFileOpen(tdc->f.inode);
-#endif
+ tfile = afs_CFileOpen(&tdc->f.inode);
afs_CFileTruncate(tfile, 0);
afs_CFileClose(tfile);
afs_AdjustSize(tdc, 0);
/*
* Free the element we just truncated
*/
- MObtainWriteLock(&afs_xdcache, 511);
+ ObtainWriteLock(&afs_xdcache, 511);
afs_indexFlags[tdc->index] &= ~IFDiscarded;
afs_FreeDCache(tdc);
tdc->f.states &= ~(DRO|DBackup|DRW);
ReleaseWriteLock(&tdc->lock);
afs_PutDCache(tdc);
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
}
/*!
* Both pvnLock and lock are write held.
*/
void
-afs_TryToSmush(register struct vcache *avc, struct AFS_UCRED *acred, int sync)
+afs_TryToSmush(register struct vcache *avc, afs_ucred_t *acred, int sync)
{
register struct dcache *tdc;
register int index;
* Get the hash chain containing all dce's for this fid
*/
i = DVHash(&avc->f.fid);
- MObtainWriteLock(&afs_xdcache, 277);
+ ObtainWriteLock(&afs_xdcache, 277);
for (index = afs_dvhashTbl[i]; index != NULLIDX; index = i) {
i = afs_dvnextTbl[index]; /* next pointer this hash table */
if (afs_indexUnique[index] == avc->f.fid.Fid.Unique) {
}
ReleaseWriteLock(&avc->vlock);
#endif
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/*
* It's treated like a callback so that when we do lookups we'll
* invalidate the unique bit if any
totalChunks, (totalLength + 1));
*/
i = DVHash(&avc->f.fid);
- MObtainWriteLock(&afs_xdcache, 1001);
+ ObtainWriteLock(&afs_xdcache, 1001);
for (index = afs_dvhashTbl[i]; index != NULLIDX; index = i) {
i = afs_dvnextTbl[index];
if (afs_indexUnique[index] == avc->f.fid.Fid.Unique) {
afs_PutDCache(tdc);
}
}
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/*printf("Missing %d chunks\n", totalChunks);*/
* after write-locking the dcache.
*/
i = DCHash(&avc->f.fid, chunk);
- MObtainWriteLock(&afs_xdcache, 278);
+ ObtainWriteLock(&afs_xdcache, 278);
for (index = afs_dchashTbl[i]; index != NULLIDX;) {
if (afs_indexUnique[index] == avc->f.fid.Fid.Unique) {
tdc = afs_GetDSlot(index, NULL);
if (index != NULLIDX) {
hset(afs_indexTimes[tdc->index], afs_indexCounter);
hadd32(afs_indexCounter, 1);
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
return tdc;
}
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
return NULL;
} /*afs_FindDCache */
-/*
- * afs_UFSCacheStoreProc
- *
- * Description:
- * Called upon store.
- *
- * Parameters:
- * acall : Ptr to the Rx call structure involved.
- * afile : Ptr to the related file descriptor.
- * alen : Size of the file in bytes.
- * avc : Ptr to the vcache entry.
- * shouldWake : is it "safe" to return early from close() ?
- * abytesToXferP : Set to the number of bytes to xfer.
- * NOTE: This parameter is only used if AFS_NOSTATS
- * is not defined.
- * abytesXferredP : Set to the number of bytes actually xferred.
- * NOTE: This parameter is only used if AFS_NOSTATS
- * is not defined.
- *
- * Environment:
- * Nothing interesting.
- */
-static int
-afs_UFSCacheStoreProc(register struct rx_call *acall, struct osi_file *afile,
- register afs_int32 alen, struct vcache *avc,
- int *shouldWake, afs_size_t * abytesToXferP,
- afs_size_t * abytesXferredP)
-{
- afs_int32 code, got;
- register char *tbuffer;
- register int tlen;
-
- AFS_STATCNT(UFS_CacheStoreProc);
-
-#ifndef AFS_NOSTATS
- /*
- * In this case, alen is *always* the amount of data we'll be trying
- * to ship here.
- */
- (*abytesToXferP) = alen;
- (*abytesXferredP) = 0;
-#endif /* AFS_NOSTATS */
-
- afs_Trace4(afs_iclSetp, CM_TRACE_STOREPROC, ICL_TYPE_POINTER, avc,
- ICL_TYPE_FID, &(avc->f.fid), ICL_TYPE_OFFSET,
- ICL_HANDLE_OFFSET(avc->f.m.Length), ICL_TYPE_INT32, alen);
- tbuffer = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
- while (alen > 0) {
- tlen = (alen > AFS_LRALLOCSIZ ? AFS_LRALLOCSIZ : alen);
- got = afs_osi_Read(afile, -1, tbuffer, tlen);
- if ((got < 0)
-#if defined(KERNEL_HAVE_UERROR)
- || (got != tlen && getuerror())
-#endif
- ) {
- osi_FreeLargeSpace(tbuffer);
- return EIO;
- }
- afs_Trace2(afs_iclSetp, CM_TRACE_STOREPROC2, ICL_TYPE_OFFSET,
- ICL_HANDLE_OFFSET(*tbuffer), ICL_TYPE_INT32, got);
- RX_AFS_GUNLOCK();
- code = rx_Write(acall, tbuffer, got); /* writing 0 bytes will
- * push a short packet. Is that really what we want, just because the
- * data didn't come back from the disk yet? Let's try it and see. */
- RX_AFS_GLOCK();
-#ifndef AFS_NOSTATS
- (*abytesXferredP) += code;
-#endif /* AFS_NOSTATS */
- if (code != got) {
- code = rx_Error(acall);
- osi_FreeLargeSpace(tbuffer);
- return code ? code : -33;
- }
- alen -= got;
- /*
- * If file has been locked on server, we can allow the store
- * to continue.
- */
- if (shouldWake && *shouldWake && (rx_GetRemoteStatus(acall) & 1)) {
- *shouldWake = 0; /* only do this once */
- afs_wakeup(avc);
- }
- }
- afs_Trace4(afs_iclSetp, CM_TRACE_STOREPROC, ICL_TYPE_POINTER, avc,
- ICL_TYPE_FID, &(avc->f.fid), ICL_TYPE_OFFSET,
- ICL_HANDLE_OFFSET(avc->f.m.Length), ICL_TYPE_INT32, alen);
- osi_FreeLargeSpace(tbuffer);
- return 0;
-
-} /* afs_UFSCacheStoreProc */
-
-
-/*
- * afs_UFSCacheFetchProc
- *
- * Description:
- * Routine called on fetch; also tells people waiting for data
- * that more has arrived.
- *
- * Parameters:
- * acall : Ptr to the Rx call structure.
- * afile : File descriptor for the cache file.
- * abase : Base offset to fetch.
- * adc : Ptr to the dcache entry for the file, write-locked.
- * avc : Ptr to the vcache entry for the file.
- * abytesToXferP : Set to the number of bytes to xfer.
- * NOTE: This parameter is only used if AFS_NOSTATS
- * is not defined.
- * abytesXferredP : Set to the number of bytes actually xferred.
- * NOTE: This parameter is only used if AFS_NOSTATS
- * is not defined.
- *
- * Environment:
- * Nothing interesting.
- */
-
-static int
-afs_UFSCacheFetchProc(register struct rx_call *acall, struct osi_file *afile,
- afs_size_t abase, struct dcache *adc,
- struct vcache *avc, afs_size_t * abytesToXferP,
- afs_size_t * abytesXferredP, afs_int32 lengthFound)
-{
- afs_int32 length;
- register afs_int32 code;
- register char *tbuffer;
- register int tlen;
- int moredata = 0;
-
- AFS_STATCNT(UFS_CacheFetchProc);
- osi_Assert(WriteLocked(&adc->lock));
- afile->offset = 0; /* Each time start from the beginning */
- length = lengthFound;
-#ifndef AFS_NOSTATS
- (*abytesToXferP) = 0;
- (*abytesXferredP) = 0;
-#endif /* AFS_NOSTATS */
- tbuffer = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
- adc->validPos = abase;
- do {
- if (moredata) {
- RX_AFS_GUNLOCK();
- code = rx_Read(acall, (char *)&length, sizeof(afs_int32));
- RX_AFS_GLOCK();
- length = ntohl(length);
- if (code != sizeof(afs_int32)) {
- osi_FreeLargeSpace(tbuffer);
- code = rx_Error(acall);
- return (code ? code : -1); /* try to return code, not -1 */
- }
- }
- /*
- * The fetch protocol is extended for the AFS/DFS translator
- * to allow multiple blocks of data, each with its own length,
- * to be returned. As long as the top bit is set, there are more
- * blocks expected.
- *
- * We do not do this for AFS file servers because they sometimes
- * return large negative numbers as the transfer size.
- */
- if (avc->f.states & CForeign) {
- moredata = length & 0x80000000;
- length &= ~0x80000000;
- } else {
- moredata = 0;
- }
-#ifndef AFS_NOSTATS
- (*abytesToXferP) += length;
-#endif /* AFS_NOSTATS */
- while (length > 0) {
- tlen = (length > AFS_LRALLOCSIZ ? AFS_LRALLOCSIZ : length);
-#ifdef RX_KERNEL_TRACE
- afs_Trace1(afs_iclSetp, CM_TRACE_TIMESTAMP, ICL_TYPE_STRING,
- "before rx_Read");
-#endif
- RX_AFS_GUNLOCK();
- code = rx_Read(acall, tbuffer, tlen);
- RX_AFS_GLOCK();
-#ifdef RX_KERNEL_TRACE
- afs_Trace1(afs_iclSetp, CM_TRACE_TIMESTAMP, ICL_TYPE_STRING,
- "after rx_Read");
-#endif
-#ifndef AFS_NOSTATS
- (*abytesXferredP) += code;
-#endif /* AFS_NOSTATS */
- if (code != tlen) {
- osi_FreeLargeSpace(tbuffer);
- afs_Trace3(afs_iclSetp, CM_TRACE_FETCH64READ,
- ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, code,
- ICL_TYPE_INT32, length);
- return -34;
- }
- code = afs_osi_Write(afile, -1, tbuffer, tlen);
- if (code != tlen) {
- osi_FreeLargeSpace(tbuffer);
- return EIO;
- }
- abase += tlen;
- length -= tlen;
- adc->validPos = abase;
- if (afs_osi_Wakeup(&adc->validPos) == 0)
- afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAKE, ICL_TYPE_STRING,
- __FILE__, ICL_TYPE_INT32, __LINE__,
- ICL_TYPE_POINTER, adc, ICL_TYPE_INT32,
- adc->dflags);
- }
- } while (moredata);
- osi_FreeLargeSpace(tbuffer);
- return 0;
-
-} /* afs_UFSCacheFetchProc */
-
/*!
* Get a fresh dcache from the free or discarded list.
*
*
* \return The new dcache.
*/
-struct dcache *afs_AllocDCache(struct vcache *avc,
- afs_int32 chunk,
- afs_int32 lock,
- struct VenusFid *ashFid)
+struct dcache *
+afs_AllocDCache(struct vcache *avc, afs_int32 chunk, afs_int32 lock,
+ struct VenusFid *ashFid)
{
struct dcache *tdc = NULL;
afs_uint32 size = 0;
afs_stats_cmperf.cacheBlocksDiscarded = afs_blocksDiscarded;
if (lock & 2) {
/* Truncate the chunk so zeroes get filled properly */
-#if defined(LINUX_USE_FH)
- file = afs_CFileOpen(&tdc->f.fh, tdc->f.fh_type);
-#else
- file = afs_CFileOpen(tdc->f.inode);
-#endif
+ file = afs_CFileOpen(&tdc->f.inode);
afs_CFileTruncate(file, 0);
afs_CFileClose(file);
afs_AdjustSize(tdc, 0);
* The vcache entry pointed to by avc is unlocked upon entry.
*/
-struct tlocal1 {
- struct AFSVolSync tsync;
- struct AFSFetchStatus OutStatus;
- struct AFSCallBack CallBack;
-};
-
/*
* Update the vnode-to-dcache hint if we can get the vnode lock
* right away. Assumes dcache entry is at least read-locked.
register struct vrequest *areq, afs_size_t * aoffset,
afs_size_t * alen, int aflags)
{
- register afs_int32 i, code, code1 = 0, shortcut;
+ register afs_int32 i, code, shortcut;
#if defined(AFS_AIX32_ENV) || defined(AFS_SGI_ENV)
register afs_int32 adjustsize = 0;
#endif
afs_int32 us;
afs_int32 chunk;
afs_size_t maxGoodLength; /* amount of good data at server */
- struct rx_call *tcall;
afs_size_t Position = 0;
-#ifdef AFS_64BIT_CLIENT
- afs_size_t tsize;
- afs_size_t lengthFound; /* as returned from server */
-#endif /* AFS_64BIT_CLIENT */
afs_int32 size, tlen; /* size of segment to transfer */
- struct tlocal1 *tsmall = 0;
+ struct afs_FetchOutput *tsmall = 0;
register struct dcache *tdc;
register struct osi_file *file;
register struct afs_conn *tc;
int doReallyAdjustSize = 0;
int overWriteWholeChunk = 0;
- XSTATS_DECLS;
#ifndef AFS_NOSTATS
- struct afs_stats_xferData *xferP; /* Ptr to this op's xfer struct */
- osi_timeval_t xferStartTime, /*FS xfer start time */
- xferStopTime; /*FS xfer stop time */
- afs_size_t bytesToXfer; /* # bytes to xfer */
- afs_size_t bytesXferred; /* # bytes actually xferred */
struct afs_stats_AccessInfo *accP; /*Ptr to access record in stats */
int fromReplica; /*Are we reading from a replica? */
int numFetchLoops; /*# times around the fetch/analyze loop */
* entries from the free list, and thereby assuming them to be not
* referenced and not locked.
*/
- MObtainReadLock(&afs_xdcache);
+ ObtainReadLock(&afs_xdcache);
dcLocked = (0 == NBObtainSharedLock(&tdc->lock, 601));
if (dcLocked && (tdc->index != NULLIDX)
tdc->refCount++;
ReleaseWriteLock(&tdc->tlock);
- MReleaseReadLock(&afs_xdcache);
+ ReleaseReadLock(&afs_xdcache);
shortcut = 1;
if (hsame(tdc->f.versionNo, avc->f.m.DataVersion)
&& !(tdc->dflags & DFFetching)) {
afs_stats_cmperf.dcacheHits++;
- MObtainWriteLock(&afs_xdcache, 559);
+ ObtainWriteLock(&afs_xdcache, 559);
QRemove(&tdc->lruq);
QAdd(&afs_DLRU, &tdc->lruq);
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/* Locks held:
* avc->lock(R) if setLocks && !slowPass
} else {
if (dcLocked)
ReleaseSharedLock(&tdc->lock);
- MReleaseReadLock(&afs_xdcache);
+ ReleaseReadLock(&afs_xdcache);
}
if (!shortcut)
/* check to make sure our space is fine */
afs_MaybeWakeupTruncateDaemon();
- MObtainWriteLock(&afs_xdcache, 280);
+ ObtainWriteLock(&afs_xdcache, 280);
us = NULLIDX;
for (index = afs_dchashTbl[i]; index != NULLIDX;) {
if (afs_indexUnique[index] == avc->f.fid.Fid.Unique) {
afs_dcnextTbl[index] = afs_dchashTbl[i];
afs_dchashTbl[i] = index;
}
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
ObtainSharedLock(&tdc->lock, 606);
break; /* leaving refCount high for caller */
}
#endif
osi_Panic("getdcache");
}
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/*
* Locks held:
* avc->lock(R) if setLocks
tdc->dflags = DFEntryMod;
tdc->mflags = 0;
afs_MaybeWakeupTruncateDaemon();
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
ConvertWToSLock(&tdc->lock);
}
}
#endif /* AFS_SGI_ENV */
if (AFS_CHUNKTOBASE(chunk) + adjustsize >= avc->f.m.Length &&
#else /* defined(AFS_AIX32_ENV) || defined(AFS_SGI_ENV) */
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV)
+#if defined(AFS_SUN5_ENV)
if ((doAdjustSize || (AFS_CHUNKTOBASE(chunk) >= avc->f.m.Length)) &&
#else
if (AFS_CHUNKTOBASE(chunk) >= avc->f.m.Length &&
if (doReallyAdjustSize || overWriteWholeChunk) {
/* no data in file to read at this position */
UpgradeSToWLock(&tdc->lock, 607);
-
-#if defined(LINUX_USE_FH)
- file = afs_CFileOpen(&tdc->f.fh, tdc->f.fh_type);
-#else
- file = afs_CFileOpen(tdc->f.inode);
-#endif
+ file = afs_CFileOpen(&tdc->f.inode);
afs_CFileTruncate(file, 0);
afs_CFileClose(file);
afs_AdjustSize(tdc, 0);
* fetch the whole file.
*/
DZap(tdc); /* pages in cache may be old */
-#if defined(LINUX_USE_FH)
- file = afs_CFileOpen(&tdc->f.fh, tdc->f.fh_type);
-#else
- file = afs_CFileOpen(tdc->f.inode);
-#endif
+ file = afs_CFileOpen(&tdc->f.inode);
afs_RemoveVCB(&avc->f.fid);
tdc->f.states |= DWriting;
tdc->dflags |= DFFetching;
tdc->dflags);
}
tsmall =
- (struct tlocal1 *)osi_AllocLargeSpace(sizeof(struct tlocal1));
+ (struct afs_FetchOutput *)osi_AllocLargeSpace(sizeof(struct afs_FetchOutput));
setVcacheStatus = 0;
#ifndef AFS_NOSTATS
/*
tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
if (tc) {
- afs_int32 length_hi, length, bytes;
#ifndef AFS_NOSTATS
numFetchLoops++;
if (fromReplica)
setNewCallback = 1;
}
i = osi_Time();
- RX_AFS_GUNLOCK();
- tcall = rx_NewCall(tc->id);
- RX_AFS_GLOCK();
-
- XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHDATA);
-#ifdef AFS_64BIT_CLIENT
- length_hi = code = 0;
- if (!afs_serverHasNo64Bit(tc)) {
- tsize = size;
- RX_AFS_GUNLOCK();
- code =
- StartRXAFS_FetchData64(tcall,
- (struct AFSFid *)&avc->f.fid.
- Fid, Position, tsize);
- if (code != 0) {
- RX_AFS_GLOCK();
- afs_Trace2(afs_iclSetp, CM_TRACE_FETCH64CODE,
- ICL_TYPE_POINTER, avc, ICL_TYPE_INT32,
- code);
- } else {
- bytes =
- rx_Read(tcall, (char *)&length_hi,
- sizeof(afs_int32));
- RX_AFS_GLOCK();
- if (bytes == sizeof(afs_int32)) {
- length_hi = ntohl(length_hi);
- } else {
- length_hi = 0;
- code = rx_Error(tcall);
- RX_AFS_GUNLOCK();
- code1 = rx_EndCall(tcall, code);
- RX_AFS_GLOCK();
- tcall = (struct rx_call *)0;
- }
- }
- }
- if (code == RXGEN_OPCODE || afs_serverHasNo64Bit(tc)) {
- if (Position > 0x7FFFFFFF) {
- code = EFBIG;
- } else {
- afs_int32 pos;
- pos = Position;
- RX_AFS_GUNLOCK();
- if (!tcall)
- tcall = rx_NewCall(tc->id);
- code =
- StartRXAFS_FetchData(tcall, (struct AFSFid *)
- &avc->f.fid.Fid, pos,
- size);
- RX_AFS_GLOCK();
- }
- afs_serverSetNo64Bit(tc);
- }
- if (code == 0) {
- RX_AFS_GUNLOCK();
- bytes =
- rx_Read(tcall, (char *)&length,
- sizeof(afs_int32));
- RX_AFS_GLOCK();
- if (bytes == sizeof(afs_int32)) {
- length = ntohl(length);
- } else {
- code = rx_Error(tcall);
- }
- }
- FillInt64(lengthFound, length_hi, length);
- afs_Trace3(afs_iclSetp, CM_TRACE_FETCH64LENG,
- ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, code,
- ICL_TYPE_OFFSET,
- ICL_HANDLE_OFFSET(lengthFound));
-#else /* AFS_64BIT_CLIENT */
- RX_AFS_GUNLOCK();
- code =
- StartRXAFS_FetchData(tcall,
- (struct AFSFid *)&avc->f.fid.Fid,
- Position, size);
- RX_AFS_GLOCK();
- if (code == 0) {
- RX_AFS_GUNLOCK();
- bytes =
- rx_Read(tcall, (char *)&length,
- sizeof(afs_int32));
- RX_AFS_GLOCK();
- if (bytes == sizeof(afs_int32)) {
- length = ntohl(length);
- } else {
- code = rx_Error(tcall);
- }
- }
-#endif /* AFS_64BIT_CLIENT */
- if (code == 0) {
-
-#ifndef AFS_NOSTATS
- xferP =
- &(afs_stats_cmfullperf.rpc.
- fsXferTimes[AFS_STATS_FS_XFERIDX_FETCHDATA]);
- osi_GetuTime(&xferStartTime);
-
- code =
- afs_CacheFetchProc(tcall, file,
- (afs_size_t) Position, tdc,
- avc, &bytesToXfer,
- &bytesXferred, length);
-
- osi_GetuTime(&xferStopTime);
- (xferP->numXfers)++;
- if (!code) {
- (xferP->numSuccesses)++;
- afs_stats_XferSumBytes
- [AFS_STATS_FS_XFERIDX_FETCHDATA] +=
- bytesXferred;
- (xferP->sumBytes) +=
- (afs_stats_XferSumBytes
- [AFS_STATS_FS_XFERIDX_FETCHDATA] >> 10);
- afs_stats_XferSumBytes
- [AFS_STATS_FS_XFERIDX_FETCHDATA] &= 0x3FF;
- if (bytesXferred < xferP->minBytes)
- xferP->minBytes = bytesXferred;
- if (bytesXferred > xferP->maxBytes)
- xferP->maxBytes = bytesXferred;
-
- /*
- * Tally the size of the object. Note: we tally the actual size,
- * NOT the number of bytes that made it out over the wire.
- */
- if (bytesToXfer <= AFS_STATS_MAXBYTES_BUCKET0)
- (xferP->count[0])++;
- else if (bytesToXfer <=
- AFS_STATS_MAXBYTES_BUCKET1)
- (xferP->count[1])++;
- else if (bytesToXfer <=
- AFS_STATS_MAXBYTES_BUCKET2)
- (xferP->count[2])++;
- else if (bytesToXfer <=
- AFS_STATS_MAXBYTES_BUCKET3)
- (xferP->count[3])++;
- else if (bytesToXfer <=
- AFS_STATS_MAXBYTES_BUCKET4)
- (xferP->count[4])++;
- else if (bytesToXfer <=
- AFS_STATS_MAXBYTES_BUCKET5)
- (xferP->count[5])++;
- else if (bytesToXfer <=
- AFS_STATS_MAXBYTES_BUCKET6)
- (xferP->count[6])++;
- else if (bytesToXfer <=
- AFS_STATS_MAXBYTES_BUCKET7)
- (xferP->count[7])++;
- else
- (xferP->count[8])++;
-
- afs_stats_GetDiff(elapsedTime, xferStartTime,
- xferStopTime);
- afs_stats_AddTo((xferP->sumTime), elapsedTime);
- afs_stats_SquareAddTo((xferP->sqrTime),
- elapsedTime);
- if (afs_stats_TimeLessThan
- (elapsedTime, (xferP->minTime))) {
- afs_stats_TimeAssign((xferP->minTime),
- elapsedTime);
- }
- if (afs_stats_TimeGreaterThan
- (elapsedTime, (xferP->maxTime))) {
- afs_stats_TimeAssign((xferP->maxTime),
- elapsedTime);
- }
- }
-#else
- code =
- afs_CacheFetchProc(tcall, file, Position, tdc,
- avc, 0, 0, length);
-#endif /* AFS_NOSTATS */
- }
- if (code == 0) {
- RX_AFS_GUNLOCK();
- code =
- EndRXAFS_FetchData(tcall, &tsmall->OutStatus,
- &tsmall->CallBack,
- &tsmall->tsync);
- RX_AFS_GLOCK();
- }
- XSTATS_END_TIME;
- RX_AFS_GUNLOCK();
- if (tcall)
- code1 = rx_EndCall(tcall, code);
- RX_AFS_GLOCK();
- } else {
- code = -1;
- }
- if (!code && code1)
- code = code1;
+ code = afs_CacheFetchProc(tc, file, Position, tdc,
+ avc, size, tsmall);
+ } else
+ code = -1;
if (code == 0) {
/* callback could have been broken (or expired) in a race here,
*/
osi_Assert(!setLocks || slowPass);
}
- tdc->f.states &= ~(DRO|DBackup|DRW);
- afs_DCMoveBucket(tdc, 0, 0);
tdc = NULL;
goto done;
}
/* Fix up LRU info */
if (tdc) {
- MObtainWriteLock(&afs_xdcache, 602);
+ ObtainWriteLock(&afs_xdcache, 602);
hset(afs_indexTimes[tdc->index], afs_indexCounter);
hadd32(afs_indexCounter, 1);
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/* return the data */
if (vType(avc) == VDIR)
* holding afs_xdcache. So we enter xdcache, get a reference
* for every dcache entry, and exit xdcache.
*/
- MObtainWriteLock(&afs_xdcache, 283);
+ ObtainWriteLock(&afs_xdcache, 283);
QInit(&DirtyQ);
for (i = 0; i < afs_cacheFiles; i++) {
tdc = afs_indexTable[i];
QAdd(&DirtyQ, &tdc->dirty);
}
}
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
/*
* Now, for each dcache entry we found, check if it's dirty.
/* Now that we have the write lock, double-check */
if (wrLock && (tdc->dflags & DFEntryMod)) {
tdc->dflags &= ~DFEntryMod;
- MObtainWriteLock(&afs_xdcache, 620);
+ ObtainWriteLock(&afs_xdcache, 620);
afs_WriteDCache(tdc, 1);
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
touchedit = 1;
}
if (wrLock)
afs_PutDCache(tdc);
}
- MObtainWriteLock(&afs_xdcache, 617);
+ ObtainWriteLock(&afs_xdcache, 617);
if (!touchedit && (cacheDiskType != AFS_FCACHE_TYPE_MEM)) {
/* Touch the file to make sure that the mtime on the file is kept
* up-to-date to avoid losing cached files on cold starts because
theader.version = AFS_CI_VERSION;
afs_osi_Write(afs_cacheInodep, 0, &theader, sizeof(theader));
}
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
}
/*
tdc->f.fid.Fid.Volume = 0;
tdc->f.chunk = -1;
hones(tdc->f.versionNo);
- tdc->f.inode = aslot;
+ tdc->f.inode.mem = aslot;
tdc->dflags |= DFEntryMod;
tdc->refCount = 1;
tdc->index = aslot;
afs_InitCacheFile(char *afile, ino_t ainode)
{
register afs_int32 code;
-#if defined(AFS_LINUX22_ENV)
- struct dentry *filevp;
-#else
- struct vnode *filevp;
-#endif
afs_int32 index;
int fileIsBad;
struct osi_file *tfile;
struct osi_stat tstat;
register struct dcache *tdc;
-#if defined(LINUX_USE_FH)
- int max_len = sizeof(struct fid);
-#endif
AFS_STATCNT(afs_InitCacheFile);
index = afs_stats_cmperf.cacheNumEntries;
if (index >= afs_cacheFiles)
return EINVAL;
- MObtainWriteLock(&afs_xdcache, 282);
+ ObtainWriteLock(&afs_xdcache, 282);
tdc = afs_GetDSlot(index, NULL);
ReleaseReadLock(&tdc->tlock);
- MReleaseWriteLock(&afs_xdcache);
+ ReleaseWriteLock(&afs_xdcache);
ObtainWriteLock(&tdc->lock, 621);
- MObtainWriteLock(&afs_xdcache, 622);
+ ObtainWriteLock(&afs_xdcache, 622);
if (afile) {
- code = gop_lookupname(afile, AFS_UIOSYS, 0, &filevp);
+ code = afs_LookupInodeByPath(afile, &tdc->f.inode.ufs, NULL);
if (code) {
ReleaseWriteLock(&afs_xdcache);
ReleaseWriteLock(&tdc->lock);
afs_PutDCache(tdc);
return code;
}
- /*
- * We have a VN_HOLD on filevp. Get the useful info out and
- * return. We make use of the fact that the cache is in the
- * UFS file system, and just record the inode number.
- */
-#ifdef AFS_LINUX22_ENV
-#if defined(LINUX_USE_FH)
- tdc->f.fh_type = osi_get_fh(filevp, &tdc->f.fh, &max_len);
+ } else {
+ /* Add any other 'complex' inode types here ... */
+#if !defined(LINUX_USE_FH) && !defined(AFS_CACHE_VNODE_PATH)
+ tdc->f.inode.ufs = ainode;
#else
- tdc->f.inode = VTOI(filevp->d_inode)->i_number;
- dput(filevp);
+ osi_Panic("Can't init cache with inode numbers when complex inodes are "
+ "in use\n");
#endif
-#else
- tdc->f.inode = afs_vnodeToInumber(filevp);
- AFS_RELE(filevp);
-#endif /* AFS_LINUX22_ENV */
- } else {
- tdc->f.inode = ainode;
}
fileIsBad = 0;
if ((tdc->f.states & DWriting) || tdc->f.fid.Fid.Volume == 0)
fileIsBad = 1;
-#if defined(LINUX_USE_FH)
- tfile = osi_UFSOpen_fh(&tdc->f.fh, tdc->f.fh_type);
-#else
- tfile = osi_UFSOpen(tdc->f.inode);
-#endif
+ tfile = osi_UFSOpen(&tdc->f.inode);
code = afs_osi_Stat(tfile, &tstat);
if (code)
osi_Panic("initcachefile stat");
/* ablocks is reported in 1K blocks */
code = afs_InitMemCache(afiles, AFS_FIRSTCSIZE, aflags);
if (code != 0) {
- printf("afsd: memory cache too large for available memory.\n");
- printf("afsd: AFS files cannot be accessed.\n\n");
+ afs_warn("afsd: memory cache too large for available memory.\n");
+ afs_warn("afsd: AFS files cannot be accessed.\n\n");
dcacheDisabled = 1;
afiles = ablocks = 0;
} else
- printf("Memory cache: Allocating %d dcache entries...",
+ afs_warn("Memory cache: Allocating %d dcache entries...",
aDentries);
} else {
cacheDiskType = AFS_FCACHE_TYPE_UFS;
/* Allocate and zero the pointer array to the dcache entries */
afs_indexTable = (struct dcache **)
afs_osi_Alloc(sizeof(struct dcache *) * afiles);
- memset((char *)afs_indexTable, 0, sizeof(struct dcache *) * afiles);
+ memset(afs_indexTable, 0, sizeof(struct dcache *) * afiles);
afs_indexTimes =
(afs_hyper_t *) afs_osi_Alloc(afiles * sizeof(afs_hyper_t));
- memset((char *)afs_indexTimes, 0, afiles * sizeof(afs_hyper_t));
+ memset(afs_indexTimes, 0, afiles * sizeof(afs_hyper_t));
afs_indexUnique =
(afs_int32 *) afs_osi_Alloc(afiles * sizeof(afs_uint32));
- memset((char *)afs_indexUnique, 0, afiles * sizeof(afs_uint32));
+ memset(afs_indexUnique, 0, afiles * sizeof(afs_uint32));
afs_indexFlags = (u_char *) afs_osi_Alloc(afiles * sizeof(u_char));
- memset((char *)afs_indexFlags, 0, afiles * sizeof(char));
+ memset(afs_indexFlags, 0, afiles * sizeof(char));
/* Allocate and thread the struct dcache entries themselves */
tdp = afs_Initial_freeDSList =
(struct dcache *)afs_osi_Alloc(aDentries * sizeof(struct dcache));
- memset((char *)tdp, 0, aDentries * sizeof(struct dcache));
+ memset(tdp, 0, aDentries * sizeof(struct dcache));
#ifdef KERNEL_HAVE_PIN
pin((char *)afs_indexTable, sizeof(struct dcache *) * afiles); /* XXX */
pin((char *)afs_indexTimes, sizeof(afs_hyper_t) * afiles); /* XXX */
{
int i;
+#ifdef AFS_CACHE_VNODE_PATH
+ if (cacheDiskType != AFS_FCACHE_TYPE_MEM) {
+ struct dcache *tdc;
+ for (i = 0; i < afs_cacheFiles; i++) {
+ tdc = afs_indexTable[i];
+ if (tdc) {
+ afs_osi_FreeStr(tdc->f.inode.ufs);
+ }
+ }
+ }
+#endif
+
afs_osi_Free(afs_dvnextTbl, afs_cacheFiles * sizeof(afs_int32));
afs_osi_Free(afs_dcnextTbl, afs_cacheFiles * sizeof(afs_int32));
afs_osi_Free(afs_indexTable, afs_cacheFiles * sizeof(struct dcache *));
struct dcache *
afs_ObtainDCacheForWriting(struct vcache *avc, afs_size_t filePos,
afs_size_t len, struct vrequest *areq,
- int noLock) {
+ int noLock)
+{
struct dcache *tdc = NULL;
afs_size_t offset;
* \note The vcache entry must be write locked.
* \note The dcache entry must be read locked.
*/
-int afs_MakeShadowDir(struct vcache *avc, struct dcache *adc)
+int
+afs_MakeShadowDir(struct vcache *avc, struct dcache *adc)
{
int i, code, ret_code = 0, written, trans_size;
struct dcache *new_dc = NULL;
struct osi_file *tfile_src, *tfile_dst;
struct VenusFid shadow_fid;
char *data;
- int lock_held = 0;
/* Is this a dir? */
if (vType(avc) != VDIR)
/* Alloc a 4k block. */
data = (char *) afs_osi_Alloc(4096);
if (!data) {
- printf("afs_MakeShadowDir: could not alloc data\n");
+ afs_warn("afs_MakeShadowDir: could not alloc data\n");
ret_code = ENOMEM;
goto done;
}
/* Open the files. */
- tfile_src = afs_CFileOpen(adc->f.inode);
- tfile_dst = afs_CFileOpen(new_dc->f.inode);
+ tfile_src = afs_CFileOpen(&adc->f.inode);
+ tfile_dst = afs_CFileOpen(&new_dc->f.inode);
/* And now copy dir dcache data into this dcache,
* 4k at a time.
*
* \note avc must be write locked.
*/
-void afs_DeleteShadowDir(struct vcache *avc)
+void
+afs_DeleteShadowDir(struct vcache *avc)
{
struct dcache *tdc;
struct VenusFid shadow_fid;
ObtainWriteLock(&afs_disconDirtyLock, 708);
QRemove(&avc->shadowq);
ReleaseWriteLock(&afs_disconDirtyLock);
+ afs_PutVCache(avc); /* Because we held it when we added to the queue */
}
/*!
* \param alen The new length of the file
*
*/
-void afs_PopulateDCache(struct vcache *avc, afs_size_t apos, struct vrequest *areq) {
+void
+afs_PopulateDCache(struct vcache *avc, afs_size_t apos, struct vrequest *areq)
+{
struct dcache *tdc;
afs_size_t len, offset;
afs_int32 start, end;