From: Felix Frank Date: Wed, 1 Jul 2009 11:20:14 +0000 (+0200) Subject: Gathered alternative afs_TttCacheFetchProcs and afs_TttCacheStoreProcs X-Git-Tag: openafs-devel-1_5_61~89 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=0b3e7a074789dccf4738364e24f20656d3f06729;hp=07692c44d39e3c11347ce7428730342ea9c6f53c Gathered alternative afs_TttCacheFetchProcs and afs_TttCacheStoreProcs Fetch and Store procs now live in the new source file afs_fetchstore.c Reviewed-on: http://gerrit.openafs.org/106 Reviewed-by: Russ Allbery Verified-by: Russ Allbery --- diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index d99dd44..84e3ab4 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -1469,216 +1469,6 @@ afs_FindDCache(register struct vcache *avc, afs_size_t abyte) /* - * 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. * diff --git a/src/afs/afs_fetchstore.c b/src/afs/afs_fetchstore.c new file mode 100644 index 0000000..50389f1 --- /dev/null +++ b/src/afs/afs_fetchstore.c @@ -0,0 +1,426 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#include +#include "afs/param.h" + +#include "afs/sysincludes.h" /* Standard vendor system headers */ +#ifndef AFS_LINUX22_ENV +#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 "afsincludes.h" /* Afs-based standard headers */ +#include "afs/afs_stats.h" /* statistics */ +#include "afs_prototypes.h" + +/* + * 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. + */ +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. + */ + +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 */ + +int +afs_MemCacheStoreProc(register struct rx_call *acall, + register struct osi_file *fP, + register afs_int32 alen, struct vcache *avc, + int *shouldWake, afs_size_t * abytesToXferP, + afs_size_t * abytesXferredP) +{ + register struct memCacheEntry *mceP = (struct memCacheEntry *)fP; + + 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->f.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); + RX_AFS_GUNLOCK(); + code = rx_WritevAlloc(acall, tiov, &tnio, RX_MAXIOVECS, tlen); + RX_AFS_GLOCK(); + if (code <= 0) { + code = rx_Error(acall); + osi_FreeSmallSpace(tiov); + return code ? code : -33; + } + tlen = code; + code = afs_MemReadvBlk(mceP, offset, tiov, tnio, tlen); + if (code != tlen) { + osi_FreeSmallSpace(tiov); + return -33; + } + RX_AFS_GUNLOCK(); + code = rx_Writev(acall, tiov, tnio, tlen); + RX_AFS_GLOCK(); +#ifndef AFS_NOSTATS + (*abytesXferredP) += code; +#endif /* AFS_NOSTATS */ + if (code != tlen) { + code = rx_Error(acall); + osi_FreeSmallSpace(tiov); + return code ? code : -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; +} + +int +afs_MemCacheFetchProc(register struct rx_call *acall, + register struct osi_file *fP, afs_size_t abase, + struct dcache *adc, struct vcache *avc, + afs_size_t * abytesToXferP, afs_size_t * abytesXferredP, + afs_int32 lengthFound) +{ + register struct memCacheEntry *mceP = (struct memCacheEntry *)fP; + 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"); + } + adc->validPos = abase; + do { + if (moredata) { + RX_AFS_GUNLOCK(); + code = rx_Read(acall, (char *)&length, sizeof(afs_int32)); + length = ntohl(length); + RX_AFS_GLOCK(); + 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->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); + RX_AFS_GUNLOCK(); + code = rx_Readv(acall, tiov, &tnio, RX_MAXIOVECS, tlen); + RX_AFS_GLOCK(); +#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; + 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); + /* max of two sizes */ + osi_FreeSmallSpace(tiov); + return 0; +} + diff --git a/src/afs/afs_memcache.c b/src/afs/afs_memcache.c index cc7bb90..3bbd53e 100644 --- a/src/afs/afs_memcache.c +++ b/src/afs/afs_memcache.c @@ -341,194 +341,6 @@ afs_MemCacheTruncate(register struct osi_file *fP, int size) return 0; } -int -afs_MemCacheStoreProc(register struct rx_call *acall, - register struct osi_file *fP, - register afs_int32 alen, struct vcache *avc, - int *shouldWake, afs_size_t * abytesToXferP, - afs_size_t * abytesXferredP) -{ - register struct memCacheEntry *mceP = (struct memCacheEntry *)fP; - - 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->f.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); - RX_AFS_GUNLOCK(); - code = rx_WritevAlloc(acall, tiov, &tnio, RX_MAXIOVECS, tlen); - RX_AFS_GLOCK(); - if (code <= 0) { - code = rx_Error(acall); - osi_FreeSmallSpace(tiov); - return code ? code : -33; - } - tlen = code; - code = afs_MemReadvBlk(mceP, offset, tiov, tnio, tlen); - if (code != tlen) { - osi_FreeSmallSpace(tiov); - return -33; - } - RX_AFS_GUNLOCK(); - code = rx_Writev(acall, tiov, tnio, tlen); - RX_AFS_GLOCK(); -#ifndef AFS_NOSTATS - (*abytesXferredP) += code; -#endif /* AFS_NOSTATS */ - if (code != tlen) { - code = rx_Error(acall); - osi_FreeSmallSpace(tiov); - return code ? code : -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; -} - -int -afs_MemCacheFetchProc(register struct rx_call *acall, - register struct osi_file *fP, afs_size_t abase, - struct dcache *adc, struct vcache *avc, - afs_size_t * abytesToXferP, afs_size_t * abytesXferredP, - afs_int32 lengthFound) -{ - register struct memCacheEntry *mceP = (struct memCacheEntry *)fP; - 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"); - } - adc->validPos = abase; - do { - if (moredata) { - RX_AFS_GUNLOCK(); - code = rx_Read(acall, (char *)&length, sizeof(afs_int32)); - length = ntohl(length); - RX_AFS_GLOCK(); - 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->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); - RX_AFS_GUNLOCK(); - code = rx_Readv(acall, tiov, &tnio, RX_MAXIOVECS, tlen); - RX_AFS_GLOCK(); -#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; - 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); - /* max of two sizes */ - osi_FreeSmallSpace(tiov); - return 0; -} - void shutdown_memcache(void) diff --git a/src/libafs/Makefile.common.in b/src/libafs/Makefile.common.in index 3321ab4..4ffbb56 100644 --- a/src/libafs/Makefile.common.in +++ b/src/libafs/Makefile.common.in @@ -95,6 +95,7 @@ AFSAOBJS = \ afs_mariner.o \ afs_md5.o \ afs_memcache.o \ + afs_fetchstore.o \ afs_osi.o \ afs_osidnlc.o \ afs_osi_alloc.o \ @@ -355,6 +356,8 @@ afs_pag_call.o: $(TOP_SRC_AFS)/afs_pag_call.c $(CRULE_NOOPT) afs_pag_cred.o: $(TOP_SRC_AFS)/afs_pag_cred.c $(CRULE_NOOPT) +afs_fetchstore.o: $(TOP_SRC_AFS)/afs_fetchstore.c + $(CRULE_NOOPT) afs_stat.o: $(TOP_SRC_AFS)/afs_stat.c $(CRULE_NOOPT) afs_syscall.o: $(TOP_SRC_AFS)/afs_syscall.c diff --git a/src/libuafs/Makefile.common.in b/src/libuafs/Makefile.common.in index e918785..e455766 100644 --- a/src/libuafs/Makefile.common.in +++ b/src/libuafs/Makefile.common.in @@ -104,6 +104,7 @@ UAFSOBJ = \ $(UOBJ)/afs_mariner.o \ $(UOBJ)/afs_memcache.o \ $(UOBJ)/afs_md5.o \ + $(UOBJ)/afs_fetchstore.o \ $(UOBJ)/afs_osidnlc.o \ $(UOBJ)/afs_osi_pag.o \ $(UOBJ)/afs_segments.o \ @@ -232,6 +233,7 @@ AFSWEBOBJ = \ $(WEBOBJ)/afs_mariner.o \ $(WEBOBJ)/afs_memcache.o \ $(WEBOBJ)/afs_md5.o \ + $(WEBOBJ)/afs_fetchstore.o \ $(WEBOBJ)/afs_osidnlc.o \ $(WEBOBJ)/afs_osi_pag.o \ $(WEBOBJ)/afs_segments.o \ @@ -361,6 +363,7 @@ AFSWEBOBJKRB = \ $(WEBOBJ)/afs_mariner.o \ $(WEBOBJ)/afs_memcache.o \ $(WEBOBJ)/afs_md5.o \ + $(WEBOBJ)/afs_fetchstore.o \ $(WEBOBJ)/afs_osidnlc.o \ $(WEBOBJ)/afs_osi_pag.o \ $(WEBOBJ)/afs_segments.o \ @@ -485,6 +488,7 @@ JUAFSOBJ = \ $(JUAFS)/afs_mariner.o \ $(JUAFS)/afs_memcache.o \ $(JUAFS)/afs_md5.o \ + $(JUAFS)/afs_fetchstore.o \ $(JUAFS)/afs_osidnlc.o \ $(JUAFS)/afs_osi_pag.o \ $(JUAFS)/afs_segments.o \ @@ -693,6 +697,8 @@ $(UOBJ)/afs_memcache.o: $(TOP_SRC_AFS)/afs_memcache.c $(CRULE1) $(UOBJ)/afs_md5.o: $(TOP_SRC_AFS)/afs_md5.c $(CRULE1) +$(UOBJ)/afs_fetchstore.o: $(TOP_SRC_AFS)/afs_fetchstore.c + $(CRULE1) $(UOBJ)/afs_stat.o: $(TOP_SRC_AFS)/afs_stat.c $(CRULE1) $(UOBJ)/fcrypt.o: $(TOP_SRC_RXKAD)/domestic/fcrypt.c @@ -956,6 +962,8 @@ $(WEBOBJ)/afs_memcache.o: $(TOP_SRC_AFS)/afs_memcache.c $(CRULE2) $(WEBOBJ)/afs_md5.o: $(TOP_SRC_AFS)/afs_md5.c $(CRULE2) +$(WEBOBJ)/afs_fetchstore.o: $(TOP_SRC_AFS)/afs_fetchstore.c + $(CRULE2) $(WEBOBJ)/afs_stat.o: $(TOP_SRC_AFS)/afs_stat.c $(CRULE2) $(WEBOBJ)/fcrypt.o: $(TOP_SRC_RXKAD)/domestic/fcrypt.c @@ -1223,6 +1231,8 @@ $(JUAFS)/afs_memcache.o: $(TOP_SRC_AFS)/afs_memcache.c $(CRULE1) $(JUAFS)/afs_md5.o: $(TOP_SRC_AFS)/afs_md5.c $(CRULE1) +$(JUAFS)/afs_fetchstore.o: $(TOP_SRC_AFS)/afs_fetchstore.c + $(CRULE1) $(JUAFS)/afs_stat.o: $(TOP_SRC_AFS)/afs_stat.c $(CRULE1) $(JUAFS)/fcrypt.o: $(TOP_SRC_RXKAD)/domestic/fcrypt.c