From a41dee091610d3acff04e73e21eb1ecbae0980b5 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Sun, 17 Apr 2011 20:52:50 +0100 Subject: [PATCH] libafs: Tidy up iovec allocation and trimming Tidy up the way that we perform iovec allocation and trimming by making the rest of the world look a little bit more like Darwin. This relies upon a struct uio, followed by 16 iovecs, being able to fit into a SmallSpace sized block. On the majority of 32 bit systems, such a block is 256 bytes long (on AIX and HPUX it is 152 bytes). With a 32bit size_t, an iovec is 8 bytes, so 16 of them is 128 bytes, and a struct uio is 24 bytes, giving a grand total of 152. Change-Id: I5243f034bcb4e1f5fa319c4f522229bd96eaae3d Reviewed-on: http://gerrit.openafs.org/4749 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/afs/DARWIN/osi_machdep.h | 6 ++-- src/afs/DARWIN/osi_misc.c | 6 ++-- src/afs/VNOPS/afs_vnop_read.c | 50 ++++++---------------------------- src/afs/VNOPS/afs_vnop_write.c | 30 ++++---------------- src/afs/afs_osi_uio.c | 31 +++++++++++++++++++++ src/afs/afs_prototypes.h | 5 ++++ 6 files changed, 56 insertions(+), 72 deletions(-) diff --git a/src/afs/DARWIN/osi_machdep.h b/src/afs/DARWIN/osi_machdep.h index 5a615cbc4..e186d3a6d 100644 --- a/src/afs/DARWIN/osi_machdep.h +++ b/src/afs/DARWIN/osi_machdep.h @@ -225,9 +225,9 @@ extern int igetinode(mount_t vfsp, dev_t dev , ino_t inode, vnode_t *vpp, #define osi_curcred() &afs_osi_cred #ifdef AFS_DARWIN80_ENV -uio_t afsio_darwin_partialcopy(uio_t auio, int size); - -#define uprintf printf +# define afsio_free(X) uio_free(X) +# define afsio_setoffset(X, Y) uio_setoffset(X, Y) +# define uprintf printf #endif /* Vnode related macros */ diff --git a/src/afs/DARWIN/osi_misc.c b/src/afs/DARWIN/osi_misc.c index 56f118198..c602fb10c 100644 --- a/src/afs/DARWIN/osi_misc.c +++ b/src/afs/DARWIN/osi_misc.c @@ -184,10 +184,10 @@ afs_suser(void *credp) } #ifdef AFS_DARWIN80_ENV -uio_t -afsio_darwin_partialcopy(uio_t auio, int size) +struct uio * +afsio_partialcopy(struct uio *auio, size_t size) { - uio_t res; + struct uio *res; int i; user_addr_t iovaddr; user_size_t iovsize; diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index d4244a49a..1028e379f 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -52,13 +52,7 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, afs_int32 trimlen; struct dcache *tdc = 0; afs_int32 error, trybusy = 1; -#ifdef AFS_DARWIN80_ENV - uio_t tuiop = NULL; -#else - struct uio tuio; - struct uio *tuiop = &tuio; - struct iovec *tvec = NULL; -#endif + struct uio *tuiop = NULL; afs_int32 code; struct vrequest treq; @@ -94,9 +88,6 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, } #endif -#ifndef AFS_DARWIN80_ENV - tvec = 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, @@ -121,14 +112,8 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, 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 + tuiop = afsio_partialcopy(auio, trimlen); AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, tuiop, code); } @@ -329,14 +314,8 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, 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 + tuiop = afsio_partialcopy(auio, trimlen); AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, tuiop, code); if (code) { error = code; @@ -346,16 +325,9 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, /* get the data from the cache */ /* mung uio structure to be right for this transfer */ -#ifdef AFS_DARWIN80_ENV - trimlen = len; - tuiop = afsio_darwin_partialcopy(auio, trimlen); - uio_setoffset(tuiop, offset); -#else - afsio_copy(auio, &tuio, tvec); trimlen = len; - afsio_trim(&tuio, trimlen); - tuio.afsio_offset = offset; -#endif + tuiop = afsio_partialcopy(auio, trimlen); + AFS_UIO_SETOFFSET(tuiop, offset); code = (*(afs_cacheType->vreadUIO))(&tdc->f.inode, tuiop); @@ -374,12 +346,10 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, if (len <= 0) break; /* surprise eof */ -#ifdef AFS_DARWIN80_ENV if (tuiop) { - uio_free(tuiop); - tuiop = 0; + afsio_free(tuiop); + tuiop = NULL; } -#endif } /* the whole while loop */ /* @@ -408,12 +378,8 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, code = afs_CheckCode(error, &treq, 10); -#ifdef AFS_DARWIN80_ENV if (tuiop) - uio_free(tuiop); -#else - osi_FreeSmallSpace(tvec); -#endif + afsio_free(tuiop); out: AFS_DISCON_UNLOCK(); diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index 58f09d5a1..26150ada0 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -218,13 +218,7 @@ afs_write(struct vcache *avc, struct uio *auio, int aio, #if defined(AFS_FBSD_ENV) || defined(AFS_DFBSD_ENV) struct vnode *vp = AFSTOV(avc); #endif -#ifdef AFS_DARWIN80_ENV - uio_t tuiop = NULL; -#else - struct uio tuio; - struct uio *tuiop = &tuio; - struct iovec *tvec; /* again, should have define */ -#endif + struct uio *tuiop = NULL; afs_int32 code; struct vrequest treq; @@ -307,9 +301,7 @@ afs_write(struct vcache *avc, struct uio *auio, int aio, afs_FakeOpen(avc); #endif avc->f.states |= CDirty; -#ifndef AFS_DARWIN80_ENV - tvec = osi_AllocSmallSpace(sizeof(struct iovec)); -#endif + while (totalLength > 0) { tdc = afs_ObtainDCacheForWriting(avc, filePos, totalLength, &treq, noLock); @@ -326,17 +318,10 @@ afs_write(struct vcache *avc, struct uio *auio, int aio, len = max - offset; } -#ifdef AFS_DARWIN80_ENV if (tuiop) - uio_free(tuiop); - trimlen = len; - tuiop = afsio_darwin_partialcopy(auio, trimlen); -#else - /* mung uio structure to be right for this transfer */ - afsio_copy(auio, &tuio, tvec); + afsio_free(tuiop); trimlen = len; - afsio_trim(&tuio, trimlen); -#endif + tuiop = afsio_partialcopy(auio, trimlen); AFS_UIO_SETOFFSET(tuiop, offset); code = (*(afs_cacheType->vwriteUIO))(avc, &tdc->f.inode, tuiop); @@ -413,11 +398,8 @@ afs_write(struct vcache *avc, struct uio *auio, int aio, avc->vc_error = error; if (!noLock) ReleaseWriteLock(&avc->lock); -#ifdef AFS_DARWIN80_ENV - uio_free(tuiop); -#else - osi_FreeSmallSpace(tvec); -#endif + afsio_free(tuiop); + #ifndef AFS_VM_RDWR_ENV /* * If write is implemented via VM, afs_fsync() is called from the high-level diff --git a/src/afs/afs_osi_uio.c b/src/afs/afs_osi_uio.c index f0703ef5a..5d4f3aab5 100644 --- a/src/afs/afs_osi_uio.c +++ b/src/afs/afs_osi_uio.c @@ -75,6 +75,37 @@ afsio_trim(struct uio *auio, afs_int32 asize) } return 0; } + +/* Allocate space for, then partially copy, over an existing iovec up to the + * length given in len. + * + * This requires that SmallSpace can alloc space big enough to hold a struct + * UIO, plus 16 iovecs + */ + +struct uio * +afsio_partialcopy(struct uio *auio, size_t len) { + char *space; + struct uio *newuio; + struct iovec *newvec; + + /* Allocate a block that can contain both the UIO and the iovec */ + space = osi_AllocSmallSpace(sizeof(struct uio) + + sizeof(struct iovec) * AFS_MAXIOVCNT); + + newuio = (struct uio *) space; + newvec = (struct iovec *) (space + sizeof(struct uio)); + + afsio_copy(auio, newuio, newvec); + afsio_trim(newuio, len); + + return newuio; +} + +void +afsio_free(struct uio *uio) { + osi_FreeSmallSpace(uio); +} #endif /* skip asize bytes in the current uio structure */ diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 2f37d5a64..7a18f27e7 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -603,9 +603,14 @@ extern void afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p); extern afs_int32 PagInCred(afs_ucred_t *cred); /* afs_osi_uio.c */ +#if !defined(AFS_DARWIN80_ENV) extern int afsio_copy(struct uio *ainuio, struct uio *aoutuio, struct iovec *aoutvec); extern int afsio_trim(struct uio *auio, afs_int32 asize); +extern void afsio_free(struct uio *auio); +#endif + +extern struct uio* afsio_partialcopy(struct uio *auio, size_t size); extern int afsio_skip(struct uio *auio, afs_int32 asize); /* afs_osi_vm.c */ -- 2.39.5