From: Simon Wilkinson Date: Tue, 12 Apr 2011 18:41:30 +0000 (+0100) Subject: libafs: Remove afs_read duplication X-Git-Tag: upstream/1.8.0_pre1^2~3868 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=fd620283a926386d4a90e602a1a47ee622b6a483;p=packages%2Fo%2Fopenafs.git libafs: Remove afs_read duplication The disk cache and memcache afs_read functions are effectively duplicates of each other. Abstract out the common code into a generic afs_read() function, and put the cache type specific code into UFSReadUIO (there is already a MemReadUIO which contains the code necessary for the memcache). Change-Id: Ic66242fa4695a146ac874a82bd48a7c1f1f412a6 Reviewed-on: http://gerrit.openafs.org/4463 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index acd02bfbd..dfdf34347 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -42,9 +42,8 @@ void afs_PrefetchChunk(struct vcache *avc, struct dcache *adc, afs_ucred_t *acred, struct vrequest *areq); int -afs_MemRead(struct vcache *avc, struct uio *auio, - afs_ucred_t *acred, daddr_t albn, struct buf **abpp, - int noLock) +afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, + daddr_t albn, struct buf **abpp, int noLock) { afs_size_t totalLength; afs_size_t transferLength; @@ -58,23 +57,30 @@ afs_MemRead(struct vcache *avc, struct uio *auio, #else struct uio tuio; struct uio *tuiop = &tuio; - struct iovec *tvec; + struct iovec *tvec = NULL; #endif afs_int32 code; struct vrequest treq; - AFS_STATCNT(afs_MemRead); + AFS_STATCNT(afs_read); + if (avc->vc_error) return EIO; + AFS_DISCON_LOCK(); + /* check that we have the latest status info in the vnode cache */ if ((code = afs_InitReq(&treq, acred))) - return code; + goto out; + if (!noLock) { + if (!avc) + osi_Panic("null avc in afs_GenericRead"); + code = afs_VerifyVCache(avc, &treq); if (code) { code = afs_CheckCode(code, &treq, 8); /* failed to get it */ - return code; + goto out; } } #ifndef AFS_VM_RDWR_ENV @@ -82,13 +88,14 @@ afs_MemRead(struct vcache *avc, struct uio *auio, if (!afs_AccessOK (avc, PRSFS_READ, &treq, CHECK_MODE_BITS | CMB_ALLOW_EXEC_AS_READ)) { - return afs_CheckCode(EACCES, &treq, 9); + code = afs_CheckCode(EACCES, &treq, 9); + goto out; } } #endif #ifndef AFS_DARWIN80_ENV - tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec)); + tvec = osi_AllocSmallSpace(sizeof(struct iovec)); #endif totalLength = AFS_UIO_RESID(auio); filePos = AFS_UIO_OFFSET(auio); @@ -138,7 +145,7 @@ afs_MemRead(struct vcache *avc, struct uio *auio, if (tdc) { ObtainReadLock(&tdc->lock); offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk); - len = tdc->f.chunkBytes - offset; + len = tdc->validPos - filePos; } } else { /* a tricky question: does the presence of the DFFetching flag @@ -176,6 +183,11 @@ afs_MemRead(struct vcache *avc, struct uio *auio, afs_PutDCache(tdc); /* before reusing tdc */ } tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 2); + if (!tdc) { + error = ENETDOWN; + break; + } + ObtainReadLock(&tdc->lock); /* now, first try to start transfer, if we'll need the data. If * data already coming, we don't need to do this, obviously. Type @@ -196,8 +208,9 @@ afs_MemRead(struct vcache *avc, struct uio *auio, tdc->mflags |= DFFetchReq; bp = afs_BQueue(BOP_FETCH, avc, B_DONTWAIT, 0, acred, (afs_size_t) filePos, (afs_size_t) 0, - tdc, (void *)0, (void *)0); + tdc, NULL, NULL); if (!bp) { + /* Bkg table full; retry deadlocks */ tdc->mflags &= ~DFFetchReq; trybusy = 0; /* Avoid bkg daemon since they're too busy */ ReleaseWriteLock(&tdc->mflock); @@ -330,7 +343,7 @@ afs_MemRead(struct vcache *avc, struct uio *auio, break; } } else { - /* get the data from the mem cache */ + /* get the data from the cache */ /* mung uio structure to be right for this transfer */ #ifdef AFS_DARWIN80_ENV @@ -344,7 +357,7 @@ afs_MemRead(struct vcache *avc, struct uio *auio, tuio.afsio_offset = offset; #endif - code = afs_MemReadUIO(&tdc->f.inode, tuiop); + code = (*(afs_cacheType->vreadUIO))(&tdc->f.inode, tuiop); if (code) { error = code; @@ -381,28 +394,30 @@ afs_MemRead(struct vcache *avc, struct uio *auio, */ if (tdc) { ReleaseReadLock(&tdc->lock); +#if !defined(AFS_VM_RDWR_ENV) /* try to queue prefetch, if needed */ - if (!noLock && -#ifndef AFS_VM_RDWR_ENV - afs_preCache -#else - 1 -#endif - ) { - afs_PrefetchChunk(avc, tdc, acred, &treq); + if (!noLock) { + if (!(tdc->mflags &DFNextStarted)) + afs_PrefetchChunk(avc, tdc, acred, &treq); } +#endif afs_PutDCache(tdc); } if (!noLock) ReleaseReadLock(&avc->lock); + + code = afs_CheckCode(error, &treq, 10); + #ifdef AFS_DARWIN80_ENV if (tuiop) uio_free(tuiop); #else osi_FreeSmallSpace(tvec); #endif - error = afs_CheckCode(error, &treq, 10); - return error; + +out: + AFS_DISCON_UNLOCK(); + return code; } /* called with the dcache entry triggering the fetch, the vcache entry involved, @@ -486,330 +501,29 @@ afs_PrefetchChunk(struct vcache *avc, struct dcache *adc, } int -afs_UFSRead(struct vcache *avc, struct uio *auio, - afs_ucred_t *acred, daddr_t albn, struct buf **abpp, - int noLock) +afs_UFSReadUIO(afs_dcache_id_t *cacheId, struct uio *tuiop) { - afs_size_t totalLength; - afs_size_t transferLength; - afs_size_t filePos; - afs_size_t offset, len, tlen; - afs_int32 trimlen; - struct dcache *tdc = 0; - afs_int32 error; -#ifdef AFS_DARWIN80_ENV - uio_t tuiop=NULL; -#else - struct uio tuio; - struct uio *tuiop = &tuio; - struct iovec *tvec; -#endif + int code; struct osi_file *tfile; - afs_int32 code; - int trybusy = 1; - struct vrequest treq; - - AFS_STATCNT(afs_UFSRead); - if (avc && avc->vc_error) - return EIO; - - AFS_DISCON_LOCK(); - - /* check that we have the latest status info in the vnode cache */ - if ((code = afs_InitReq(&treq, acred))) - return code; - if (!noLock) { - if (!avc) - osi_Panic("null avc in afs_UFSRead"); - else { - code = afs_VerifyVCache(avc, &treq); - if (code) { - code = afs_CheckCode(code, &treq, 11); /* failed to get it */ - AFS_DISCON_UNLOCK(); - return code; - } - } - } -#ifndef AFS_VM_RDWR_ENV - if (AFS_NFSXLATORREQ(acred)) { - if (!afs_AccessOK - (avc, PRSFS_READ, &treq, - CHECK_MODE_BITS | CMB_ALLOW_EXEC_AS_READ)) { - AFS_DISCON_UNLOCK(); - return afs_CheckCode(EACCES, &treq, 12); - } - } -#endif - -#ifndef AFS_DARWIN80_ENV - tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec)); -#endif - totalLength = AFS_UIO_RESID(auio); - filePos = AFS_UIO_OFFSET(auio); - afs_Trace4(afs_iclSetp, CM_TRACE_READ, ICL_TYPE_POINTER, avc, - ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(filePos), ICL_TYPE_INT32, - totalLength, ICL_TYPE_OFFSET, - ICL_HANDLE_OFFSET(avc->f.m.Length)); - error = 0; - transferLength = 0; - if (!noLock) - ObtainReadLock(&avc->lock); -#if defined(AFS_TEXT_ENV) && !defined(AFS_VM_RDWR_ENV) - if (avc->flushDV.high == AFS_MAXDV && avc->flushDV.low == AFS_MAXDV) { - hset(avc->flushDV, avc->f.m.DataVersion); - } -#endif - - if (filePos >= avc->f.m.Length) { - if (len > AFS_ZEROS) - len = sizeof(afs_zeros); /* and in 0 buffer */ - len = 0; -#ifdef AFS_DARWIN80_ENV - trimlen = len; - tuiop = afsio_darwin_partialcopy(auio, trimlen); -#else - afsio_copy(auio, &tuio, tvec); - trimlen = len; - afsio_trim(&tuio, trimlen); -#endif - AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, tuiop, code); - } - - while (avc->f.m.Length > 0 && totalLength > 0) { - /* read all of the cached info */ - if (filePos >= avc->f.m.Length) - break; /* all done */ - if (noLock) { - if (tdc) { - ReleaseReadLock(&tdc->lock); - afs_PutDCache(tdc); - } - tdc = afs_FindDCache(avc, filePos); - if (tdc) { - ObtainReadLock(&tdc->lock); - offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk); - len = tdc->validPos - filePos; - } - } else { - /* a tricky question: does the presence of the DFFetching flag - * mean that we're fetching the latest version of the file? No. - * The server could update the file as soon as the fetch responsible - * for the setting of the DFFetching flag completes. - * - * However, the presence of the DFFetching flag (visible under - * a dcache read lock since it is set and cleared only under a - * dcache write lock) means that we're fetching as good a version - * as was known to this client at the time of the last call to - * afs_VerifyVCache, since the latter updates the stat cache's - * m.DataVersion field under a vcache write lock, and from the - * time that the DFFetching flag goes on in afs_GetDCache (before - * the fetch starts), to the time it goes off (after the fetch - * completes), afs_GetDCache keeps at least a read lock on the - * vcache entry. - * - * This means that if the DFFetching flag is set, we can use that - * data for any reads that must come from the current version of - * the file (current == m.DataVersion). - * - * Another way of looking at this same point is this: if we're - * fetching some data and then try do an afs_VerifyVCache, the - * VerifyVCache operation will not complete until after the - * DFFetching flag is turned off and the dcache entry's f.versionNo - * field is updated. - * - * Note, by the way, that if DFFetching is set, - * m.DataVersion > f.versionNo (the latter is not updated until - * after the fetch completes). - */ - if (tdc) { - ReleaseReadLock(&tdc->lock); - afs_PutDCache(tdc); /* before reusing tdc */ - } - tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 2); - if (!tdc) { - error = ENETDOWN; - break; - } - - ObtainReadLock(&tdc->lock); - /* now, first try to start transfer, if we'll need the data. If - * data already coming, we don't need to do this, obviously. Type - * 2 requests never return a null dcache entry, btw. */ - if (!(tdc->dflags & DFFetching) - && !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { - /* have cache entry, it is not coming in now, and we'll need new data */ - tagain: - if (trybusy && !afs_BBusy()) { - struct brequest *bp; - /* daemon is not busy */ - ObtainSharedLock(&tdc->mflock, 667); - if (!(tdc->mflags & DFFetchReq)) { - UpgradeSToWLock(&tdc->mflock, 668); - tdc->mflags |= DFFetchReq; - bp = afs_BQueue(BOP_FETCH, avc, B_DONTWAIT, 0, acred, - (afs_size_t) filePos, (afs_size_t) 0, - tdc, (void *)0, (void *)0); - if (!bp) { - /* Bkg table full; retry deadlocks */ - tdc->mflags &= ~DFFetchReq; - trybusy = 0; /* Avoid bkg daemon since they're too busy */ - ReleaseWriteLock(&tdc->mflock); - goto tagain; - } - ConvertWToSLock(&tdc->mflock); - } - code = 0; - ConvertSToRLock(&tdc->mflock); - while (!code && tdc->mflags & DFFetchReq) { - afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, - ICL_TYPE_STRING, __FILE__, ICL_TYPE_INT32, - __LINE__, ICL_TYPE_POINTER, tdc, - ICL_TYPE_INT32, tdc->dflags); - /* don't need waiting flag on this one */ - ReleaseReadLock(&tdc->mflock); - ReleaseReadLock(&tdc->lock); - ReleaseReadLock(&avc->lock); - code = afs_osi_SleepSig(&tdc->validPos); - ObtainReadLock(&avc->lock); - ObtainReadLock(&tdc->lock); - ObtainReadLock(&tdc->mflock); - } - ReleaseReadLock(&tdc->mflock); - if (code) { - error = code; - break; - } - } - } - /* now data may have started flowing in (if DFFetching is on). If - * data is now streaming in, then wait for some interesting stuff. - */ - code = 0; - while (!code && (tdc->dflags & DFFetching) - && tdc->validPos <= filePos) { - /* too early: wait for DFFetching flag to vanish, - * or data to appear */ - afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING, - __FILE__, ICL_TYPE_INT32, __LINE__, - ICL_TYPE_POINTER, tdc, ICL_TYPE_INT32, - tdc->dflags); - ReleaseReadLock(&tdc->lock); - ReleaseReadLock(&avc->lock); - code = afs_osi_SleepSig(&tdc->validPos); - ObtainReadLock(&avc->lock); - ObtainReadLock(&tdc->lock); - } - if (code) { - error = code; - break; - } - /* fetching flag gone, data is here, or we never tried - * (BBusy for instance) */ - if (tdc->dflags & DFFetching) { - /* still fetching, some new data is here: - * compute length and offset */ - offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk); - len = tdc->validPos - filePos; - } else { - /* no longer fetching, verify data version (avoid new - * GetDCache call) */ - if (hsame(avc->f.m.DataVersion, tdc->f.versionNo) - && ((len = tdc->validPos - filePos) > 0)) { - offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk); - } else { - /* don't have current data, so get it below */ - afs_Trace3(afs_iclSetp, CM_TRACE_VERSIONNO, - ICL_TYPE_INT64, ICL_HANDLE_OFFSET(filePos), - ICL_TYPE_HYPER, &avc->f.m.DataVersion, - ICL_TYPE_HYPER, &tdc->f.versionNo); - ReleaseReadLock(&tdc->lock); - afs_PutDCache(tdc); - tdc = NULL; - } - } - if (!tdc) { - /* If we get, it was not possible to start the - * background daemon. With flag == 1 afs_GetDCache - * does the FetchData rpc synchronously. - */ - ReleaseReadLock(&avc->lock); - tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 1); - ObtainReadLock(&avc->lock); - if (tdc) - ObtainReadLock(&tdc->lock); - } - } - - if (!tdc) { - error = EIO; - break; - } - len = tdc->validPos - filePos; - afs_Trace3(afs_iclSetp, CM_TRACE_VNODEREAD, ICL_TYPE_POINTER, tdc, - ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(offset), - ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(len)); - if (len > totalLength) - len = totalLength; /* will read len bytes */ - if (len <= 0) { /* shouldn't get here if DFFetching is on */ - afs_Trace4(afs_iclSetp, CM_TRACE_VNODEREAD2, ICL_TYPE_POINTER, - tdc, ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(tdc->validPos), - ICL_TYPE_INT32, tdc->f.chunkBytes, ICL_TYPE_INT32, - tdc->dflags); - /* read past the end of a chunk, may not be at next chunk yet, and yet - * also not at eof, so may have to supply fake zeros */ - len = AFS_CHUNKTOSIZE(tdc->f.chunk) - offset; /* bytes left in chunk addr space */ - if (len > totalLength) - len = totalLength; /* and still within xfr request */ - tlen = avc->f.m.Length - offset; /* and still within file */ - if (len > tlen) - len = tlen; - if (len > AFS_ZEROS) - len = sizeof(afs_zeros); /* and in 0 buffer */ -#ifdef AFS_DARWIN80_ENV - trimlen = len; - tuiop = afsio_darwin_partialcopy(auio, trimlen); -#else - afsio_copy(auio, &tuio, tvec); - trimlen = len; - afsio_trim(&tuio, trimlen); -#endif - AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, tuiop, code); - if (code) { - error = code; - break; - } - } else { - /* get the data from the file */ - tfile = (struct osi_file *)osi_UFSOpen(&tdc->f.inode); -#ifdef AFS_DARWIN80_ENV - trimlen = len; - tuiop = afsio_darwin_partialcopy(auio, trimlen); - uio_setoffset(tuiop, offset); -#else - /* mung uio structure to be right for this transfer */ - afsio_copy(auio, &tuio, tvec); - trimlen = len; - afsio_trim(&tuio, trimlen); - tuio.afsio_offset = offset; -#endif + tfile = (struct osi_file *) osi_UFSOpen(cacheId); #if defined(AFS_AIX41_ENV) - AFS_GUNLOCK(); - code = - VNOP_RDWR(tfile->vnode, UIO_READ, FREAD, &tuio, NULL, NULL, - NULL, afs_osi_credp); - AFS_GLOCK(); + AFS_GUNLOCK(); + code = + VNOP_RDWR(tfile->vnode, UIO_READ, FREAD, tuiop, NULL, NULL, + NULL, afs_osi_credp); + AFS_GLOCK(); #elif defined(AFS_AIX32_ENV) - code = - VNOP_RDWR(tfile->vnode, UIO_READ, FREAD, &tuio, NULL, NULL); - /* Flush all JFS pages now for big performance gain in big file cases - * If we do something like this, must check to be sure that AFS file - * isn't mmapped... see afs_gn_map() for why. - */ -/* - if (tfile->vnode->v_gnode && tfile->vnode->v_gnode->gn_seg) { - many different ways to do similar things: + code = + VNOP_RDWR(tfile->vnode, UIO_READ, FREAD, tuiop, NULL, NULL); + /* Flush all JFS pages now for big performance gain in big file cases + * If we do something like this, must check to be sure that AFS file + * isn't mmapped... see afs_gn_map() for why. + */ + /* + if (tfile->vnode->v_gnode && tfile->vnode->v_gnode->gn_seg) { + any different ways to do similar things: so far, the best performing one is #2, but #1 might match it if we straighten out the confusion regarding which pages to flush. It really does matter. @@ -828,127 +542,77 @@ afs_UFSRead(struct vcache *avc, struct uio *auio, } */ #elif defined(AFS_AIX_ENV) - code = - VNOP_RDWR(tfile->vnode, UIO_READ, FREAD, (off_t) & offset, - &tuio, NULL, NULL, -1); + code = + VNOP_RDWR(tfile->vnode, UIO_READ, FREAD, (off_t) & offset, + tuiop, NULL, NULL, -1); #elif defined(AFS_SUN5_ENV) - AFS_GUNLOCK(); + AFS_GUNLOCK(); #ifdef AFS_SUN510_ENV - { - caller_context_t ct; - - VOP_RWLOCK(tfile->vnode, 0, &ct); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp, &ct); - VOP_RWUNLOCK(tfile->vnode, 0, &ct); - } + { + caller_context_t ct; + VOP_RWLOCK(tfile->vnode, 0, &ct); + code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp, &ct); + VOP_RWUNLOCK(tfile->vnode, 0, &ct); + } #else - VOP_RWLOCK(tfile->vnode, 0); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); - VOP_RWUNLOCK(tfile->vnode, 0); + VOP_RWLOCK(tfile->vnode, 0); + code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); + VOP_RWUNLOCK(tfile->vnode, 0); #endif - AFS_GLOCK(); + AFS_GLOCK(); #elif defined(AFS_SGI_ENV) - AFS_GUNLOCK(); - AFS_VOP_RWLOCK(tfile->vnode, VRWLOCK_READ); - AFS_VOP_READ(tfile->vnode, &tuio, IO_ISLOCKED, afs_osi_credp, - code); - AFS_VOP_RWUNLOCK(tfile->vnode, VRWLOCK_READ); - AFS_GLOCK(); + AFS_GUNLOCK(); + AFS_VOP_RWLOCK(tfile->vnode, VRWLOCK_READ); + AFS_VOP_READ(tfile->vnode, tuiop, IO_ISLOCKED, afs_osi_credp, + code); + AFS_VOP_RWUNLOCK(tfile->vnode, VRWLOCK_READ); + AFS_GLOCK(); #elif defined(AFS_HPUX100_ENV) - AFS_GUNLOCK(); - code = VOP_RDWR(tfile->vnode, &tuio, UIO_READ, 0, afs_osi_credp); - AFS_GLOCK(); + AFS_GUNLOCK(); + code = VOP_RDWR(tfile->vnode, tuiop, UIO_READ, 0, afs_osi_credp); + AFS_GLOCK(); #elif defined(AFS_LINUX20_ENV) - AFS_GUNLOCK(); - code = osi_rdwr(tfile, &tuio, UIO_READ); - AFS_GLOCK(); + AFS_GUNLOCK(); + code = osi_rdwr(tfile, tuiop, UIO_READ); + AFS_GLOCK(); #elif defined(AFS_DARWIN80_ENV) - AFS_GUNLOCK(); - code = VNOP_READ(tfile->vnode, tuiop, 0, afs_osi_ctxtp); - AFS_GLOCK(); + AFS_GUNLOCK(); + code = VNOP_READ(tfile->vnode, tuiop, 0, afs_osi_ctxtp); + AFS_GLOCK(); #elif defined(AFS_DARWIN_ENV) - AFS_GUNLOCK(); - VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, current_proc()); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); - VOP_UNLOCK(tfile->vnode, 0, current_proc()); - AFS_GLOCK(); + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, current_proc()); + code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); + VOP_UNLOCK(tfile->vnode, 0, current_proc()); + AFS_GLOCK(); #elif defined(AFS_FBSD80_ENV) - AFS_GUNLOCK(); - VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); - VOP_UNLOCK(tfile->vnode, 0); - AFS_GLOCK(); + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); + code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); + VOP_UNLOCK(tfile->vnode, 0); + AFS_GLOCK(); #elif defined(AFS_FBSD_ENV) - AFS_GUNLOCK(); - VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curthread); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); - VOP_UNLOCK(tfile->vnode, 0, curthread); - AFS_GLOCK(); + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curthread); + code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); + VOP_UNLOCK(tfile->vnode, 0, curthread); + AFS_GLOCK(); #elif defined(AFS_NBSD_ENV) - AFS_GUNLOCK(); - VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); - VOP_UNLOCK(tfile->vnode, 0); - AFS_GLOCK(); - + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); + code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); + VOP_UNLOCK(tfile->vnode, 0); + AFS_GLOCK(); #elif defined(AFS_XBSD_ENV) - AFS_GUNLOCK(); - VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curproc); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); - VOP_UNLOCK(tfile->vnode, 0, curproc); - AFS_GLOCK(); + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curproc); + code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); + VOP_UNLOCK(tfile->vnode, 0, curproc); + AFS_GLOCK(); #else - code = VOP_RDWR(tfile->vnode, &tuio, UIO_READ, 0, afs_osi_credp); -#endif - osi_UFSClose(tfile); - - if (code) { - error = code; - break; - } - } - /* otherwise we've read some, fixup length, etc and continue with next seg */ - len = len - AFS_UIO_RESID(tuiop); /* compute amount really transferred */ - trimlen = len; - afsio_skip(auio, trimlen); /* update input uio structure */ - totalLength -= len; - transferLength += len; - filePos += len; - if (len <= 0) - break; /* surprise eof */ -#ifdef AFS_DARWIN80_ENV - if (tuiop) { - uio_free(tuiop); - tuiop = 0; - } -#endif - } - - /* if we make it here with tdc non-zero, then it is the last chunk we - * dealt with, and we have to release it when we're done. We hold on - * to it in case we need to do a prefetch, obviously. - */ - if (tdc) { - ReleaseReadLock(&tdc->lock); -#if !defined(AFS_VM_RDWR_ENV) - /* try to queue prefetch, if needed */ - if (!noLock) { - if (!(tdc->mflags & DFNextStarted)) - afs_PrefetchChunk(avc, tdc, acred, &treq); - } + code = VOP_RDWR(tfile->vnode, tuiop, UIO_READ, 0, afs_osi_credp); #endif - afs_PutDCache(tdc); - } - if (!noLock) - ReleaseReadLock(&avc->lock); + osi_UFSClose(tfile); -#ifdef AFS_DARWIN80_ENV - if (tuiop) - uio_free(tuiop); -#else - osi_FreeSmallSpace(tvec); -#endif - AFS_DISCON_UNLOCK(); - error = afs_CheckCode(error, &treq, 13); - return error; + return code; } diff --git a/src/afs/afs.h b/src/afs/afs.h index 496b8eaaf..1c75991d7 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -1348,8 +1348,6 @@ extern struct brequest afs_brs[NBRS]; /* request structures */ #define AFS_VLPORT ((unsigned short) htons(7003)) #define AFS_RXOSDPORT ((unsigned short) htons(7011)) -#define afs_read(avc, uio, acred, albn, abpp, nolock) \ - (*(afs_cacheType->vread))(avc, uio, acred, albn, abpp, nolock) #define afs_write(avc, uio, aio, acred, nolock) \ (*(afs_cacheType->vwrite))(avc, uio, aio, acred, nolock) diff --git a/src/afs/afs_chunkops.h b/src/afs/afs_chunkops.h index d3a509081..e99b9d7ed 100644 --- a/src/afs/afs_chunkops.h +++ b/src/afs/afs_chunkops.h @@ -58,9 +58,7 @@ struct afs_cacheOps { int (*fwrite) (struct osi_file * fp, afs_int32 offset, void *buf, afs_int32 len); int (*close) (struct osi_file * fp); - int (*vread) (struct vcache * avc, struct uio * auio, - afs_ucred_t * acred, daddr_t albn, struct buf ** abpp, - int noLock); + int (*vreadUIO) (afs_dcache_id_t *, struct uio *); int (*vwrite) (struct vcache * avc, struct uio * auio, int aio, afs_ucred_t * acred, int noLock); struct dcache *(*GetDSlot) (afs_int32 aslot, diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 91c4ae015..4cdf962ac 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -106,7 +106,7 @@ struct afs_cacheOps afs_UfsCacheOps = { afs_osi_Read, afs_osi_Write, osi_UFSClose, - afs_UFSRead, + afs_UFSReadUIO, afs_UFSWrite, afs_UFSGetDSlot, afs_UFSGetVolSlot, @@ -117,7 +117,7 @@ struct afs_cacheOps afs_UfsCacheOps = { .fread = afs_osi_Read, .fwrite = afs_osi_Write, .close = osi_UFSClose, - .vread = afs_UFSRead, + .vreadUIO = afs_UFSReadUIO, .vwrite = afs_UFSWrite, .GetDSlot = afs_UFSGetDSlot, .GetVolSlot = afs_UFSGetVolSlot, @@ -132,7 +132,7 @@ struct afs_cacheOps afs_MemCacheOps = { afs_MemReadBlk, afs_MemWriteBlk, afs_MemCacheClose, - afs_MemRead, + afs_MemReadUIO, afs_MemWrite, afs_MemGetDSlot, afs_MemGetVolSlot, @@ -143,7 +143,7 @@ struct afs_cacheOps afs_MemCacheOps = { .fread = afs_MemReadBlk, .fwrite = afs_MemWriteBlk, .close = afs_MemCacheClose, - .vread = afs_MemRead, + .vreadUIO = afs_MemReadUIO, .vwrite = afs_MemWrite, .GetDSlot = afs_MemGetDSlot, .GetVolSlot = afs_MemGetVolSlot, diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 570a02129..9a340a572 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -1242,12 +1242,12 @@ extern int afs_open(struct vcache **avcp, afs_int32 aflags, /* VNOPS/afs_vnop_read.c */ -extern int afs_MemRead(struct vcache *avc, struct uio *auio, - afs_ucred_t *acred, daddr_t albn, - struct buf **abpp, int noLock); -extern int afs_UFSRead(struct vcache *avc, struct uio *auio, - afs_ucred_t *acred, daddr_t albn, - struct buf **abpp, int noLock); +extern int afs_read(struct vcache *avc, struct uio *auio, + afs_ucred_t *acred, daddr_t albn, + struct buf **abpp, int noLock); + +extern int afs_UFSReadUIO(afs_dcache_id_t *cacheId, struct uio *tuiop); + extern void afs_PrefetchChunk(struct vcache *avc, struct dcache *adc, afs_ucred_t *acred, struct vrequest *areq);