libafs: Tidy up iovec allocation and trimming
authorSimon Wilkinson <sxw@your-file-system.com>
Sun, 17 Apr 2011 19:52:50 +0000 (20:52 +0100)
committerDerrick Brashear <shadow@dementia.org>
Sun, 5 Jun 2011 14:38:47 +0000 (07:38 -0700)
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 <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/afs/DARWIN/osi_machdep.h
src/afs/DARWIN/osi_misc.c
src/afs/VNOPS/afs_vnop_read.c
src/afs/VNOPS/afs_vnop_write.c
src/afs/afs_osi_uio.c
src/afs/afs_prototypes.h

index 5a615cb..e186d3a 100644 (file)
@@ -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 */
index 56f1181..c602fb1 100644 (file)
@@ -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;
index d4244a4..1028e37 100644 (file)
@@ -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();
index 58f09d5..26150ad 100644 (file)
@@ -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
index f0703ef..5d4f3aa 100644 (file)
@@ -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 */
index 2f37d5a..7a18f27 100644 (file)
@@ -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 */