*/
#include <afsconfig.h>
-#include "../afs/param.h"
+#include "afs/param.h"
-RCSID("$Header$");
-#include "../afs/sysincludes.h" /* Standard vendor system headers */
+#include "afs/sysincludes.h" /* Standard vendor system headers */
#ifndef AFS_LINUX22_ENV
-#include "../rpc/types.h"
+#include "rpc/types.h"
#endif
-#ifdef AFS_ALPHA_ENV
-#undef kmem_alloc
-#undef kmem_free
-#undef mem_alloc
-#undef mem_free
-#undef register
-#endif /* AFS_ALPHA_ENV */
-#include "../afs/afsincludes.h" /* Afs-based standard headers */
-#include "../afs/afs_stats.h" /* statistics */
+#include "afsincludes.h" /* Afs-based standard headers */
+#include "afs/afs_stats.h" /* statistics */
/* memory cache routines */
-
-struct memCacheEntry {
- int size; /* # of valid bytes in this entry */
- int dataSize; /* size of allocated data area */
- afs_lock_t afs_memLock;
- char *data; /* bytes */
-};
-
static struct memCacheEntry *memCache;
static int memCacheBlkSize = 8192;
static int memMaxBlkNumber = 0;
-static int memAllocMaySleep = 0;
extern int cacheDiskType;
-afs_InitMemCache(size, blkSize, flags)
- int size;
- int blkSize;
- int flags;
- {
- int index;
-
- AFS_STATCNT(afs_InitMemCache);
- if(blkSize)
- memCacheBlkSize = blkSize;
-
- memMaxBlkNumber = size / memCacheBlkSize;
- memCache = (struct memCacheEntry *)
- afs_osi_Alloc(memMaxBlkNumber * sizeof(struct memCacheEntry));
- if (flags & AFSCALL_INIT_MEMCACHE_SLEEP) {
- memAllocMaySleep = 1;
- }
-
- for(index = 0; index < memMaxBlkNumber; index++) {
- char *blk;
- (memCache+index)->size = 0;
- (memCache+index)->dataSize = memCacheBlkSize;
- LOCK_INIT(&((memCache+index)->afs_memLock), "afs_memLock");
- if (memAllocMaySleep) {
- blk = afs_osi_Alloc(memCacheBlkSize);
- } else {
- blk = afs_osi_Alloc_NoSleep(memCacheBlkSize);
- }
- if (blk == NULL)
- goto nomem;
- (memCache+index)->data = blk;
- memset((memCache+index)->data, 0, memCacheBlkSize);
- }
-#if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS)
- afs_InitDualFSCacheOps((struct vnode*)0);
+int
+afs_InitMemCache(int blkCount, int blkSize, int flags)
+{
+ int index;
+
+ AFS_STATCNT(afs_InitMemCache);
+ if (blkSize)
+ memCacheBlkSize = blkSize;
+
+ memMaxBlkNumber = blkCount;
+ memCache = (struct memCacheEntry *)
+ afs_osi_Alloc(memMaxBlkNumber * sizeof(struct memCacheEntry));
+
+ for (index = 0; index < memMaxBlkNumber; index++) {
+ char *blk;
+ (memCache + index)->size = 0;
+ (memCache + index)->dataSize = memCacheBlkSize;
+ LOCK_INIT(&((memCache + index)->afs_memLock), "afs_memLock");
+ blk = afs_osi_Alloc(memCacheBlkSize);
+ if (blk == NULL)
+ goto nomem;
+ (memCache + index)->data = blk;
+ memset((memCache + index)->data, 0, memCacheBlkSize);
+ }
+#if defined(AFS_HAVE_VXFS)
+ afs_InitDualFSCacheOps((struct vnode *)0);
#endif
- return 0;
+ return 0;
-nomem:
- printf("afsd: memCache allocation failure at %d KB.\n",
- (index * memCacheBlkSize) / 1024);
- while(--index >= 0) {
- afs_osi_Free((memCache+index)->data, memCacheBlkSize);
- (memCache+index)->data = NULL;
- }
- return ENOMEM;
+ nomem:
+ printf("afsd: memCache allocation failure at %d KB.\n",
+ (index * memCacheBlkSize) / 1024);
+ while (--index >= 0) {
+ afs_osi_Free((memCache + index)->data, memCacheBlkSize);
+ (memCache + index)->data = NULL;
+ }
+ return ENOMEM;
- }
+}
-afs_MemCacheClose(file)
- char *file;
+int
+afs_MemCacheClose(struct osi_file *file)
{
return 0;
}
-void *afs_MemCacheOpen(ino_t blkno)
- {
- struct memCacheEntry *mep;
-
- if (blkno < 0 || blkno > memMaxBlkNumber) {
- osi_Panic("afs_MemCacheOpen: invalid block #");
- }
- mep = (memCache + blkno);
- afs_Trace4(afs_iclSetp, CM_TRACE_MEMOPEN,
- ICL_TYPE_INT32, blkno,
- ICL_TYPE_POINTER, mep,
- ICL_TYPE_POINTER, mep->data,
- ICL_TYPE_STRING, mep->data);
- return (void *) mep;
- }
+void *
+afs_MemCacheOpen(afs_dcache_id_t *ainode)
+{
+ struct memCacheEntry *mep;
+
+ if (ainode->mem < 0 || ainode->mem > memMaxBlkNumber) {
+ osi_Panic("afs_MemCacheOpen: invalid block #");
+ }
+ mep = (memCache + ainode->mem);
+ afs_Trace3(afs_iclSetp, CM_TRACE_MEMOPEN, ICL_TYPE_INT32, ainode->mem,
+ ICL_TYPE_POINTER, mep, ICL_TYPE_POINTER, mep ? mep->data : 0);
+ return (void *)mep;
+}
/*
* this routine simulates a read in the Memory Cache
*/
-afs_MemReadBlk(mceP, offset, dest, size)
- int offset;
- register struct memCacheEntry *mceP;
- char *dest;
- int size;
- {
- int bytesRead;
-
- MObtainReadLock(&mceP->afs_memLock);
- AFS_STATCNT(afs_MemReadBlk);
- if (offset < 0) {
- MReleaseReadLock(&mceP->afs_memLock);
- return 0;
- }
- /* use min of bytes in buffer or requested size */
- bytesRead = (size < mceP->size - offset) ? size :
- mceP->size - offset;
-
- if(bytesRead > 0) {
- AFS_GUNLOCK();
- memcpy(dest, mceP->data + offset, bytesRead);
- AFS_GLOCK();
- }
- else
- bytesRead = 0;
-
- MReleaseReadLock(&mceP->afs_memLock);
- return bytesRead;
- }
+int
+afs_MemReadBlk(register struct osi_file *fP, int offset, void *dest,
+ int size)
+{
+ register struct memCacheEntry *mceP = (struct memCacheEntry *)fP;
+ int bytesRead;
+
+ ObtainReadLock(&mceP->afs_memLock);
+ AFS_STATCNT(afs_MemReadBlk);
+ if (offset < 0) {
+ ReleaseReadLock(&mceP->afs_memLock);
+ return 0;
+ }
+ /* use min of bytes in buffer or requested size */
+ bytesRead = (size < mceP->size - offset) ? size : mceP->size - offset;
+
+ if (bytesRead > 0) {
+ AFS_GUNLOCK();
+ memcpy(dest, mceP->data + offset, bytesRead);
+ AFS_GLOCK();
+ } else
+ bytesRead = 0;
+
+ ReleaseReadLock(&mceP->afs_memLock);
+ return bytesRead;
+}
/*
* this routine simulates a readv in the Memory Cache
*/
-afs_MemReadvBlk(mceP, offset, iov, nio, size)
- int offset;
- register struct memCacheEntry *mceP;
- struct iovec *iov;
- int nio;
- int size;
- {
- int i;
- int bytesRead;
- int bytesToRead;
-
- MObtainReadLock(&mceP->afs_memLock);
- AFS_STATCNT(afs_MemReadBlk);
- if (offset < 0) {
- MReleaseReadLock(&mceP->afs_memLock);
- return 0;
- }
- /* use min of bytes in buffer or requested size */
- bytesRead = (size < mceP->size - offset) ? size :
- mceP->size - offset;
-
- if(bytesRead > 0) {
- for (i = 0 , size = bytesRead ; i < nio && size > 0 ; i++) {
- bytesToRead = (size < iov[i].iov_len) ? size : iov[i].iov_len;
- AFS_GUNLOCK();
- memcpy(iov[i].iov_base, mceP->data + offset, bytesToRead);
- AFS_GLOCK();
- offset += bytesToRead;
- size -= bytesToRead;
- }
- bytesRead -= size;
- } else
- bytesRead = 0;
-
- MReleaseReadLock(&mceP->afs_memLock);
- return bytesRead;
- }
-
-afs_MemReadUIO(blkno, uioP)
- ino_t blkno;
- struct uio *uioP;
- {
- register struct memCacheEntry *mceP = (struct memCacheEntry *)afs_MemCacheOpen(blkno);
- int length = mceP->size - uioP->uio_offset;
- afs_int32 code;
-
- AFS_STATCNT(afs_MemReadUIO);
- MObtainReadLock(&mceP->afs_memLock);
- length = (length < uioP->uio_resid) ? length : uioP->uio_resid;
- AFS_UIOMOVE(mceP->data + uioP->uio_offset, length, UIO_READ, uioP, code);
- MReleaseReadLock(&mceP->afs_memLock);
- return code;
- }
+int
+afs_MemReadvBlk(register struct memCacheEntry *mceP, int offset,
+ struct iovec *iov, int nio, int size)
+{
+ int i;
+ int bytesRead;
+ int bytesToRead;
+
+ ObtainReadLock(&mceP->afs_memLock);
+ AFS_STATCNT(afs_MemReadBlk);
+ if (offset < 0) {
+ ReleaseReadLock(&mceP->afs_memLock);
+ return 0;
+ }
+ /* use min of bytes in buffer or requested size */
+ bytesRead = (size < mceP->size - offset) ? size : mceP->size - offset;
+
+ if (bytesRead > 0) {
+ for (i = 0, size = bytesRead; i < nio && size > 0; i++) {
+ bytesToRead = (size < iov[i].iov_len) ? size : iov[i].iov_len;
+ AFS_GUNLOCK();
+ memcpy(iov[i].iov_base, mceP->data + offset, bytesToRead);
+ AFS_GLOCK();
+ offset += bytesToRead;
+ size -= bytesToRead;
+ }
+ bytesRead -= size;
+ } else
+ bytesRead = 0;
+
+ ReleaseReadLock(&mceP->afs_memLock);
+ return bytesRead;
+}
-/*XXX: this extends a block arbitrarily to support big directories */
-afs_MemWriteBlk(mceP, offset, src, size)
- register struct memCacheEntry *mceP;
- int offset;
- char *src;
- int size;
- {
- AFS_STATCNT(afs_MemWriteBlk);
- MObtainWriteLock(&mceP->afs_memLock,560);
- if (size + offset > mceP->dataSize) {
- char *oldData = mceP->data;
-
- if (memAllocMaySleep) {
- mceP->data = afs_osi_Alloc(size+offset);
- } else {
- mceP->data = afs_osi_Alloc_NoSleep(size+offset);
- }
- if ( mceP->data == NULL ) /* no available memory */
- {
- mceP->data = oldData; /* revert back change that was made */
- MReleaseWriteLock(&mceP->afs_memLock);
- afs_warn("afs: afs_MemWriteBlk mem alloc failure (%d bytes)\n",
- size+offset);
- return -ENOMEM;
- }
-
- /* may overlap, but this is OK */
- AFS_GUNLOCK();
- memcpy(mceP->data, oldData, mceP->size);
- AFS_GLOCK();
- afs_osi_Free(oldData,mceP->dataSize);
- mceP->dataSize = size+offset;
- }
- AFS_GUNLOCK();
- if (mceP->size < offset)
- memset(mceP->data+mceP->size, 0, offset-mceP->size);
- memcpy(mceP->data + offset, src, size);
- AFS_GLOCK();
- mceP->size = (size+offset < mceP->size) ? mceP->size :
- size + offset;
-
- MReleaseWriteLock(&mceP->afs_memLock);
- return size;
- }
+int
+afs_MemReadUIO(afs_dcache_id_t *ainode, struct uio *uioP)
+{
+ register struct memCacheEntry *mceP =
+ (struct memCacheEntry *)afs_MemCacheOpen(ainode);
+ int length = mceP->size - AFS_UIO_OFFSET(uioP);
+ afs_int32 code;
+
+ AFS_STATCNT(afs_MemReadUIO);
+ ObtainReadLock(&mceP->afs_memLock);
+ length = (length < AFS_UIO_RESID(uioP)) ? length : AFS_UIO_RESID(uioP);
+ AFS_UIOMOVE(mceP->data + AFS_UIO_OFFSET(uioP), length, UIO_READ, uioP, code);
+ ReleaseReadLock(&mceP->afs_memLock);
+ return code;
+}
+
+int
+afs_MemWriteBlk(register struct osi_file *fP, int offset, void *src,
+ int size)
+{
+ register struct memCacheEntry *mceP = (struct memCacheEntry *)fP;
+ struct iovec tiov;
+
+ tiov.iov_base = src;
+ tiov.iov_len = size;
+ return afs_MemWritevBlk(mceP, offset, &tiov, 1, size);
+}
/*XXX: this extends a block arbitrarily to support big directories */
-afs_MemWritevBlk(mceP, offset, iov, nio, size)
- register struct memCacheEntry *mceP;
- int offset;
- struct iovec *iov;
- int nio;
- int size;
- {
- int i;
- int bytesWritten;
- int bytesToWrite;
- AFS_STATCNT(afs_MemWriteBlk);
- MObtainWriteLock(&mceP->afs_memLock,561);
- if (offset + size > mceP->dataSize) {
- char *oldData = mceP->data;
-
- mceP->data = afs_osi_Alloc(size+offset);
-
- /* may overlap, but this is OK */
- AFS_GUNLOCK();
- memcpy(mceP->data, oldData, mceP->size);
- AFS_GLOCK();
- afs_osi_Free(oldData,mceP->dataSize);
- mceP->dataSize = size+offset;
- }
- if (mceP->size < offset)
- memset(mceP->data+mceP->size, 0, offset-mceP->size);
- for (bytesWritten = 0, i = 0 ; i < nio && size > 0 ; i++) {
- bytesToWrite = (size < iov[i].iov_len) ? size : iov[i].iov_len;
- AFS_GUNLOCK();
- memcpy(mceP->data + offset, iov[i].iov_base, bytesToWrite);
- AFS_GLOCK();
- offset += bytesToWrite;
- bytesWritten += bytesToWrite;
- size -= bytesToWrite;
- }
- mceP->size = (offset < mceP->size) ? mceP->size : offset;
-
- MReleaseWriteLock(&mceP->afs_memLock);
- return bytesWritten;
- }
-
-afs_MemWriteUIO(blkno, uioP)
- ino_t blkno;
- struct uio *uioP;
- {
- register struct memCacheEntry *mceP = (struct memCacheEntry *)afs_MemCacheOpen(blkno);
- afs_int32 code;
-
- AFS_STATCNT(afs_MemWriteUIO);
- MObtainWriteLock(&mceP->afs_memLock,312);
- if(uioP->uio_resid + uioP->uio_offset > mceP->dataSize) {
- char *oldData = mceP->data;
-
- mceP->data = afs_osi_Alloc(uioP->uio_resid + uioP->uio_offset);
-
- AFS_GUNLOCK();
- memcpy(mceP->data, oldData, mceP->size);
- AFS_GLOCK();
-
- afs_osi_Free(oldData,mceP->dataSize);
- mceP->dataSize = uioP->uio_resid + uioP->uio_offset;
- }
- if (mceP->size < uioP->uio_offset)
- memset(mceP->data+mceP->size, 0, (int)(uioP->uio_offset-mceP->size));
- AFS_UIOMOVE(mceP->data+uioP->uio_offset, uioP->uio_resid, UIO_WRITE, uioP, code);
- if (uioP->uio_offset > mceP->size)
- mceP->size = uioP->uio_offset;
-
- MReleaseWriteLock(&mceP->afs_memLock);
- return code;
- }
-
-afs_MemCacheTruncate(mceP, size)
- register struct memCacheEntry *mceP;
- int size;
- {
- AFS_STATCNT(afs_MemCacheTruncate);
-
- MObtainWriteLock(&mceP->afs_memLock,313);
- /* old directory entry; g.c. */
- if(size == 0 && mceP->dataSize > memCacheBlkSize) {
- afs_osi_Free(mceP->data, mceP->dataSize);
- mceP->data = afs_osi_Alloc(memCacheBlkSize);
- mceP->dataSize = memCacheBlkSize;
- }
-
- if (size < mceP->size)
- mceP->size = size;
-
- MReleaseWriteLock(&mceP->afs_memLock);
- return 0;
- }
-
-afs_MemCacheStoreProc(acall, mceP, alen, avc, shouldWake, abytesToXferP, abytesXferredP, length)
- register struct memCacheEntry *mceP;
- register struct rx_call *acall;
- register afs_int32 alen;
- struct vcache *avc;
- int *shouldWake;
- afs_size_t *abytesToXferP;
- afs_size_t *abytesXferredP;
- afs_int32 length;
-
- {
-
- register afs_int32 code;
- register int tlen;
- int offset = 0;
- struct iovec *tiov; /* no data copying with iovec */
- int tnio; /* temp for iovec size */
-
- AFS_STATCNT(afs_MemCacheStoreProc);
-#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 */
-
- /*
- * We need to alloc the iovecs on the heap so that they are "pinned" rather than
- * declare them on the stack - defect 11272
- */
- tiov = (struct iovec *) osi_AllocSmallSpace(sizeof(struct iovec)*RX_MAXIOVECS);
- if(!tiov) {
- osi_Panic("afs_MemCacheStoreProc: osi_AllocSmallSpace for iovecs returned NULL\n");
- }
-
-#ifdef notdef
- /* do this at a higher level now -- it's a parameter */
- /* for now, only do 'continue from close' code if file fits in one
- chunk. Could clearly do better: if only one modified chunk
- then can still do this. can do this on *last* modified chunk */
- tlen = avc->m.Length-1; /* byte position of last byte we'll store */
- if (shouldWake) {
- if (AFS_CHUNK(tlen) != 0) *shouldWake = 0;
- else *shouldWake = 1;
- }
-#endif /* notdef */
-
- while (alen > 0) {
- tlen = (alen > AFS_LRALLOCSIZ? AFS_LRALLOCSIZ : alen);
-#ifdef RX_ENABLE_LOCKS
- AFS_GUNLOCK();
-#endif /* RX_ENABLE_LOCKS */
- code = rx_WritevAlloc(acall, tiov, &tnio, RX_MAXIOVECS, tlen);
-#ifdef RX_ENABLE_LOCKS
- AFS_GLOCK();
-#endif /* RX_ENABLE_LOCKS */
- if (code <= 0) {
- osi_FreeSmallSpace(tiov);
- return -33;
- }
- tlen = code;
- code = afs_MemReadvBlk(mceP, offset, tiov, tnio, tlen);
- if (code != tlen) {
- osi_FreeSmallSpace(tiov);
- return -33;
- }
-#ifdef RX_ENABLE_LOCKS
- AFS_GUNLOCK();
-#endif /* RX_ENABLE_LOCKS */
- code = rx_Writev(acall, tiov, tnio, tlen);
-#ifdef RX_ENABLE_LOCKS
- AFS_GLOCK();
-#endif /* RX_ENABLE_LOCKS */
-#ifndef AFS_NOSTATS
- (*abytesXferredP) += code;
-#endif /* AFS_NOSTATS */
- if (code != tlen) {
- osi_FreeSmallSpace(tiov);
- return -33;
- }
- offset += tlen;
- alen -= tlen;
- /* if file has been locked on server, can allow store to continue */
- if (shouldWake && *shouldWake && (rx_GetRemoteStatus(acall) & 1)) {
- *shouldWake = 0; /* only do this once */
- afs_wakeup(avc);
- }
- }
- osi_FreeSmallSpace(tiov);
- return 0;
- }
-
-afs_MemCacheFetchProc(acall, mceP, abase, adc, avc, abytesToXferP, abytesXferredP, lengthFound)
- register struct rx_call *acall;
- afs_size_t abase;
- afs_size_t *abytesToXferP;
- afs_size_t *abytesXferredP;
- struct dcache *adc;
- struct vcache *avc;
- register struct memCacheEntry *mceP;
- afs_int32 lengthFound;
+int
+afs_MemWritevBlk(register struct memCacheEntry *mceP, int offset,
+ struct iovec *iov, int nio, int size)
+{
+ int i;
+ int bytesWritten;
+ int bytesToWrite;
+ AFS_STATCNT(afs_MemWriteBlk);
+ ObtainWriteLock(&mceP->afs_memLock, 561);
+ if (offset + size > mceP->dataSize) {
+ char *oldData = mceP->data;
+
+ mceP->data = afs_osi_Alloc(size + offset);
+ if (mceP->data == NULL) { /* no available memory */
+ mceP->data = oldData; /* revert back change that was made */
+ ReleaseWriteLock(&mceP->afs_memLock);
+ afs_warn("afs: afs_MemWriteBlk mem alloc failure (%d bytes)\n",
+ size + offset);
+ return -ENOMEM;
+ }
+
+ /* may overlap, but this is OK */
+ AFS_GUNLOCK();
+ memcpy(mceP->data, oldData, mceP->size);
+ AFS_GLOCK();
+ afs_osi_Free(oldData, mceP->dataSize);
+ mceP->dataSize = size + offset;
+ }
+ AFS_GUNLOCK();
+ if (mceP->size < offset)
+ memset(mceP->data + mceP->size, 0, offset - mceP->size);
+ for (bytesWritten = 0, i = 0; i < nio && size > 0; i++) {
+ bytesToWrite = (size < iov[i].iov_len) ? size : iov[i].iov_len;
+ memcpy(mceP->data + offset, iov[i].iov_base, bytesToWrite);
+ offset += bytesToWrite;
+ bytesWritten += bytesToWrite;
+ size -= bytesToWrite;
+ }
+ mceP->size = (offset < mceP->size) ? mceP->size : offset;
+ AFS_GLOCK();
+
+ ReleaseWriteLock(&mceP->afs_memLock);
+ return bytesWritten;
+}
+
+int
+afs_MemWriteUIO(afs_dcache_id_t *ainode, struct uio *uioP)
{
- register afs_int32 code;
- afs_int32 length;
- int moredata = 0;
- struct iovec *tiov; /* no data copying with iovec */
- register int tlen, offset=0;
- int tnio; /* temp for iovec size */
-
- AFS_STATCNT(afs_MemCacheFetchProc);
- length = lengthFound;
- afs_Trace4(afs_iclSetp, CM_TRACE_MEMFETCH,
- ICL_TYPE_POINTER, avc,
- ICL_TYPE_POINTER, mceP,
- ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(abase),
- ICL_TYPE_INT32, length);
-#ifndef AFS_NOSTATS
- (*abytesToXferP) = 0;
- (*abytesXferredP) = 0;
-#endif /* AFS_NOSTATS */
- /*
- * We need to alloc the iovecs on the heap so that they are "pinned" rather than
- * declare them on the stack - defect 11272
- */
- tiov = (struct iovec *) osi_AllocSmallSpace(sizeof(struct iovec)*RX_MAXIOVECS);
- if(!tiov) {
- osi_Panic("afs_MemCacheFetchProc: osi_AllocSmallSpace for iovecs returned NULL\n");
- }
- do {
- if (moredata) {
-#ifdef RX_ENABLE_LOCKS
- AFS_GUNLOCK();
-#endif /* RX_ENABLE_LOCKS */
- code = rx_Read(acall, (char *)&length, sizeof(afs_int32));
- length = ntohl(length);
-#ifdef RX_ENABLE_LOCKS
- AFS_GLOCK();
-#endif /* RX_ENABLE_LOCKS */
- if (code != sizeof(afs_int32)) {
- code = rx_Error(acall);
- osi_FreeSmallSpace(tiov);
- 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->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_ENABLE_LOCKS
- AFS_GUNLOCK();
-#endif /* RX_ENABLE_LOCKS */
- code = rx_Readv(acall, tiov, &tnio, RX_MAXIOVECS, tlen);
-#ifdef RX_ENABLE_LOCKS
- AFS_GLOCK();
-#endif /* RX_ENABLE_LOCKS */
-#ifndef AFS_NOSTATS
- (*abytesXferredP) += code;
-#endif /* AFS_NOSTATS */
- if (code <= 0) {
- afs_Trace3(afs_iclSetp, CM_TRACE_FETCH64READ,
- ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, code,
- ICL_TYPE_INT32, length);
- osi_FreeSmallSpace(tiov);
- return -34;
- }
- tlen = code;
- afs_MemWritevBlk(mceP, offset, tiov, tnio, tlen);
- offset += tlen;
- abase += tlen;
- length -= tlen;
- adc->validPos = abase;
- afs_osi_Wakeup(&adc->validPos);
- }
- } while (moredata);
- /* max of two sizes */
- osi_FreeSmallSpace(tiov);
- return 0;
- }
-
-
-void shutdown_memcache()
+ register struct memCacheEntry *mceP =
+ (struct memCacheEntry *)afs_MemCacheOpen(ainode);
+ afs_int32 code;
+
+ AFS_STATCNT(afs_MemWriteUIO);
+ ObtainWriteLock(&mceP->afs_memLock, 312);
+ if (AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP) > mceP->dataSize) {
+ char *oldData = mceP->data;
+
+ mceP->data = afs_osi_Alloc(AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP));
+ if (mceP->data == NULL) { /* no available memory */
+ mceP->data = oldData; /* revert back change that was made */
+ ReleaseWriteLock(&mceP->afs_memLock);
+ afs_warn("afs: afs_MemWriteBlk mem alloc failure (%ld bytes)\n",
+ (long)(AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP)));
+ return -ENOMEM;
+ }
+
+ AFS_GUNLOCK();
+ memcpy(mceP->data, oldData, mceP->size);
+ AFS_GLOCK();
+
+ afs_osi_Free(oldData, mceP->dataSize);
+ mceP->dataSize = AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP);
+ }
+ if (mceP->size < AFS_UIO_OFFSET(uioP))
+ memset(mceP->data + mceP->size, 0,
+ (int)(AFS_UIO_OFFSET(uioP) - mceP->size));
+ AFS_UIOMOVE(mceP->data + AFS_UIO_OFFSET(uioP), AFS_UIO_RESID(uioP), UIO_WRITE,
+ uioP, code);
+ if (AFS_UIO_OFFSET(uioP) > mceP->size)
+ mceP->size = AFS_UIO_OFFSET(uioP);
+
+ ReleaseWriteLock(&mceP->afs_memLock);
+ return code;
+}
+
+int
+afs_MemCacheTruncate(register struct osi_file *fP, int size)
+{
+ register struct memCacheEntry *mceP = (struct memCacheEntry *)fP;
+ AFS_STATCNT(afs_MemCacheTruncate);
+
+ ObtainWriteLock(&mceP->afs_memLock, 313);
+ /* old directory entry; g.c. */
+ if (size == 0 && mceP->dataSize > memCacheBlkSize) {
+ char *oldData = mceP->data;
+ mceP->data = afs_osi_Alloc(memCacheBlkSize);
+ if (mceP->data == NULL) { /* no available memory */
+ mceP->data = oldData;
+ ReleaseWriteLock(&mceP->afs_memLock);
+ afs_warn("afs: afs_MemWriteBlk mem alloc failure (%d bytes)\n",
+ memCacheBlkSize);
+ } else {
+ afs_osi_Free(oldData, mceP->dataSize);
+ mceP->dataSize = memCacheBlkSize;
+ }
+ }
+
+ if (size < mceP->size)
+ mceP->size = size;
+
+ ReleaseWriteLock(&mceP->afs_memLock);
+ return 0;
+}
+
+
+void
+shutdown_memcache(void)
{
register int index;
return;
memCacheBlkSize = 8192;
for (index = 0; index < memMaxBlkNumber; index++) {
- LOCK_INIT(&((memCache+index)->afs_memLock), "afs_memLock");
- afs_osi_Free((memCache+index)->data, (memCache+index)->dataSize);
+ LOCK_INIT(&((memCache + index)->afs_memLock), "afs_memLock");
+ afs_osi_Free((memCache + index)->data, (memCache + index)->dataSize);
}
- afs_osi_Free((char *)memCache, memMaxBlkNumber * sizeof(struct memCacheEntry));
+ afs_osi_Free((char *)memCache,
+ memMaxBlkNumber * sizeof(struct memCacheEntry));
memMaxBlkNumber = 0;
}