]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Make osi_fetchstore.c protocol independent
authorHartmut Reuter <reuter@rzg.mpg.de>
Tue, 2 Nov 2010 11:15:42 +0000 (12:15 +0100)
committerDerrick Brashear <shadow@dementia.org>
Wed, 3 Nov 2010 11:47:08 +0000 (04:47 -0700)
For future use of OSD and vicep-access osi_fetchstore.c should not depend on
the rx-fileserver-protocol but call instead the routines pointed to by ops.

Some code beautyfication in afs_fetchstore.c to use nBytes instead of code.

New global variable afs_protocols in afs_fetchstore.c which will be used
in RXOSD/VICEP-ACCESS programs in the future.

Change-Id: Id6b6e6c794b4fb00ad4719670caefd381f98949b
Reviewed-on: http://gerrit.openafs.org/2952
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
src/afs/LINUX/osi_fetchstore.c
src/afs/afs.h
src/afs/afs_fetchstore.c
src/afs/afs_prototypes.h

index 4989a01ed8e157f35e2c5d59ebb12c6e1e9324b2..9bae9969ecbd174e74b1bdd820781e8b70906939 100644 (file)
 #include "afs/sysincludes.h"
 #include "afsincludes.h"
 
+struct rockops {
+    void *rock;
+    struct storeOps *ops;
+};
+
 #if defined(HAVE_LINUX_SPLICE_DIRECT_TO_ACTOR)
 static int
 afs_linux_splice_actor(struct pipe_inode_info *pipe,
                       struct pipe_buffer *buf,
                       struct splice_desc *sd)
 {
-    struct rxfs_storeVariables *svar = sd->u.data;
+    struct rockops *rockops = (struct rockops *) (sd->u.data);
     size_t size;
     int code;
+    afs_uint32 byteswritten = 0;
 
     code = buf->ops->confirm(pipe, buf);
     if (code)
@@ -63,10 +69,10 @@ afs_linux_splice_actor(struct pipe_inode_info *pipe,
 
     size = sd->len;
 
-    /* Eventually, this could be rx_WritePage */
-    code = rx_Write(svar->call, kmap(buf->page), size);
-
-    if (code != size)
+    /* Eventually, this could be rx_WritePage or better rockops->ops->writepage */
+    code = (rockops->ops->write)(rockops->rock, kmap(buf->page), size,
+                                &byteswritten);
+    if (byteswritten != size)
        size = -33; /* Can't get a proper rx error out from here */
 
     kunmap(buf->page);
@@ -83,16 +89,19 @@ afs_linux_ds_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
 /* This is a store proc which uses splice to reduce the number
  * of page copies. */
 afs_int32
-afs_linux_storeproc(struct storeOps *ops, void *rock, struct dcache *tdc,
-                   int *shouldwake, afs_size_t *bytesXferred)
+afs_linux_storeproc(struct vcache *avc, struct storeOps *ops, void *rock,
+                   struct dcache *tdc, int *shouldwake, afs_size_t *bytesXferred)
 {
-    struct rxfs_storeVariables *svar = rock;
     struct file *cacheFp;
+    struct rockops rockops = {
+       .rock = rock,
+       .ops = ops
+    };
     struct splice_desc sd = {
        .len    = 0,
        .total_len = tdc->f.chunkBytes,
        .pos    = 0,
-       .u.data = rock
+       .u.data = &rockops
     };
     int code;
 
@@ -109,7 +118,7 @@ afs_linux_storeproc(struct storeOps *ops, void *rock, struct dcache *tdc,
      * GLOCK in the middle of our actor */
     if (shouldwake && *shouldwake && ((*ops->status)(rock) == 0)) {
        *shouldwake = 0;
-       afs_wakeup(svar->vcache);
+       afs_wakeup(avc);
     }
 
     if (code > 0) {
@@ -126,18 +135,20 @@ static int
 afs_linux_read_actor(read_descriptor_t *desc, struct page *page,
                     unsigned long offset, unsigned long size)
 {
-    struct rxfs_storeVariables *svar = desc->arg.data;
+    struct rockops *rockops = (struct rockops *) desc->arg.data;
     unsigned long count = desc->count;
     int code;
+    afs_uint32 byteswritten = 0;
 
     if (size > count)
        size = count;
 
-    /* Eventually, this could be rx_WritePage */
-    code = rx_Write(svar->call, kmap(page) + offset, size);
+    /* Eventually, this could be rx_WritePage or better rockops->ops->writepage */
+    code = (rockops->ops->write)(rockops->rock, kmap(page) + offset, size,
+                                &byteswritten);
     kunmap(page);
 
-    if (code != size) {
+    if (byteswritten != size) {
         return -33; /* Can't get a proper rx error out from here */
     }
 
@@ -148,19 +159,22 @@ afs_linux_read_actor(read_descriptor_t *desc, struct page *page,
 }
 
 afs_int32
-afs_linux_storeproc(struct storeOps *ops, void *rock, struct dcache *tdc,
-                    int *shouldwake, afs_size_t *bytesXferred)
+afs_linux_storeproc(struct vcache *avc, struct storeOps *ops, void *rock,
+                   struct dcache *tdc, int *shouldwake, afs_size_t *bytesXferred)
 {
-    struct rxfs_storeVariables *svar = rock;
     struct file *cacheFp;
     int code;
     loff_t offset = 0;
+    struct rockops rockops = {
+       .rock = rock,
+       .ops = ops
+    };
 
     /* Open the file, splice its contents */
     AFS_GUNLOCK();
     cacheFp = afs_linux_raw_open(&tdc->f.inode);
     code = cacheFp->f_op->sendfile(cacheFp, &offset, tdc->f.chunkBytes,
-                                  afs_linux_read_actor, rock);
+                                  afs_linux_read_actor, &rockops);
     filp_close(cacheFp, NULL);
     AFS_GLOCK();
 
@@ -170,7 +184,7 @@ afs_linux_storeproc(struct storeOps *ops, void *rock, struct dcache *tdc,
      * GLOCK in the middle of our actor */
     if (shouldwake && *shouldwake && ((*ops->status)(rock) == 0)) {
        *shouldwake = 0;
-       afs_wakeup(svar->vcache);
+       afs_wakeup(avc);
     }
 
     if (code > 0) {
index 6ba746dfe4adc44ac7e53065c0e89eff9b796acc..e755d59087ad4c894d8efdb06a9104e31421af55 100644 (file)
@@ -1387,38 +1387,25 @@ extern struct brequest afs_brs[NBRS];   /* request structures */
 
 struct buf;
 
-struct rxfs_storeVariables {
-    struct rx_call *call;
-    struct vcache *vcache;
-    char *tbuffer;
-    struct iovec *tiov;
-    afs_int32 tnio;
-    afs_int32 hasNo64bit;
-    struct AFSStoreStatus InStatus;
-};
-
 struct storeOps {
-    int (*prepare)(void *rock, afs_uint32 size, afs_uint32 *bytestoxfer);
-    int (*read)(void *rock, struct osi_file *tfile, afs_uint32 offset,
-        afs_uint32 tlen, afs_uint32 *bytesread);
-    int (*write)(void *rock, afs_uint32 tlen, afs_uint32 *byteswritten);
-    int (*status)(void *rock);
-    int (*padd)(void *rock, afs_uint32 tlen);
-    int (*close)(void *rock, struct AFSFetchStatus *OutStatus,
-        afs_int32 *doProcessFS);
-    int (*destroy)(void **rock, afs_int32 error);
-    int (*storeproc)(struct storeOps *, void *, struct dcache *, int *,
-                    afs_size_t *);
+    int (*prepare)(void *, afs_uint32, afs_uint32 *);
+    int (*read)(void *, struct osi_file *, afs_uint32, afs_uint32,
+               afs_uint32 *, char **);
+    int (*write)(void *, char *, afs_uint32, afs_uint32 *);
+    int (*status)(void *);
+    int (*padd)(void *, afs_uint32);
+    int (*close)(void *, struct AFSFetchStatus *, afs_int32 *);
+    int (*destroy)(void **, afs_int32);
+    int (*storeproc)(struct vcache *, struct storeOps *, void *,
+                    struct dcache *, int *, afs_size_t *);
 };
 
 struct fetchOps {
-    int (*more)(void *rock, afs_int32 *length, afs_uint32 *moredata);
-    int (*read)(void *rock, afs_uint32 tlen, afs_uint32 *bytesread);
-    int (*write)(void *rock, struct osi_file *fp, afs_uint32 offset,
-        afs_uint32 tlen, afs_uint32 *byteswritten);
-    int (*close)(void *rock, struct vcache *avc, struct dcache *adc,
-        struct afs_FetchOutput *Outputs);
-    int (*destroy)(void **rock, afs_int32 error);
+    int (*more)(void *, afs_int32 *, afs_uint32 *);
+    int (*read)(void *, afs_uint32, afs_uint32 *);
+    int (*write)(void *, struct osi_file *, afs_uint32, afs_uint32, afs_uint32 *);
+    int (*close)(void *, struct vcache *, struct dcache *, struct afs_FetchOutput *);
+    int (*destroy)(void **, afs_int32);
 };
 
 /* fakestat support: opaque storage for afs_EvalFakeStat to remember
index f34c96eb770e87e5a94f769959aec308256d279c..ea4c686fbd8d2d28cb957e36543301100d6935ab 100644 (file)
@@ -26,6 +26,8 @@
 
 extern int cacheDiskType;
 
+afs_uint32 afs_protocols = 0;
+
 #ifndef AFS_NOSTATS
 void
 FillStoreStats(int code, int idx, osi_timeval_t *xferStartTime,
@@ -78,6 +80,17 @@ FillStoreStats(int code, int idx, osi_timeval_t *xferStartTime,
 
 /* rock and operations for RX_FILESERVER */
 
+struct rxfs_storeVariables {
+    void *ops;
+    struct rx_call *call;
+    struct vcache *vcache;
+    struct osi_file *fP;
+    char *tbuffer;
+    struct iovec *tiov;
+    afs_int32 tnio;
+    afs_int32 hasNo64bit;
+    struct AFSStoreStatus InStatus;
+};
 
 
 afs_int32
@@ -93,8 +106,9 @@ rxfs_storeMemPrepare(void *r, afs_uint32 size, afs_uint32 *tlen)
     afs_int32 code;
     struct rxfs_storeVariables *v = (struct rxfs_storeVariables *) r;
 
+    *tlen = (size > AFS_LRALLOCSIZ ?  AFS_LRALLOCSIZ : size);
     RX_AFS_GUNLOCK();
-    code = rx_WritevAlloc(v->call, v->tiov, &v->tnio, RX_MAXIOVECS, size);
+    code = rx_WritevAlloc(v->call, v->tiov, &v->tnio, RX_MAXIOVECS, *tlen);
     RX_AFS_GLOCK();
     if (code <= 0) {
        code = rx_Error(v->call);
@@ -110,82 +124,99 @@ rxfs_storeMemPrepare(void *r, afs_uint32 size, afs_uint32 *tlen)
 
 afs_int32
 rxfs_storeUfsRead(void *r, struct osi_file *tfile, afs_uint32 offset,
-                 afs_uint32 tlen, afs_uint32 *bytesread)
+                 afs_uint32 tlen, afs_uint32 *bytesread, char **abuf)
 {
-    afs_int32 code;
+    afs_int32 nBytes;
     struct rxfs_storeVariables *v = (struct rxfs_storeVariables *)r;
 
     *bytesread = 0;
-    code = afs_osi_Read(tfile, -1, v->tbuffer, tlen);
-    if (code < 0)
+    *abuf = v->tbuffer;
+    nBytes = afs_osi_Read(tfile, -1, v->tbuffer, tlen);
+    if (nBytes < 0)
        return EIO;
-    *bytesread = code;
-    if (code == tlen)
+    *bytesread = nBytes;
+    if (nBytes == tlen)
         return 0;
 #if defined(KERNEL_HAVE_UERROR)
     if (getuerror())
        return EIO;
 #endif
+    if (nBytes == 0)
+       return EIO;
     return 0;
 }
 
 afs_int32
 rxfs_storeMemRead(void *r, struct osi_file *tfile, afs_uint32 offset,
-                 afs_uint32 tlen, afs_uint32 *bytesread)
+                 afs_uint32 tlen, afs_uint32 *bytesread, char **abuf)
 {
-    afs_int32 code;
+    afs_int32 nBytes;
     struct rxfs_storeVariables *v = (struct rxfs_storeVariables *)r;
     struct memCacheEntry *mceP = (struct memCacheEntry *)tfile;
 
     *bytesread = 0;
-    code = afs_MemReadvBlk(mceP, offset, v->tiov, v->tnio, tlen);
-    if (code != tlen)
+    nBytes = afs_MemReadvBlk(mceP, offset, v->tiov, v->tnio, tlen);
+    if (nBytes != tlen)
        return -33;
-    *bytesread = code;
+    *bytesread = nBytes;
     return 0;
 }
 
 afs_int32
-rxfs_storeMemWrite(void *r, afs_uint32 l, afs_uint32 *byteswritten)
+rxfs_storeMemWrite(void *r, char *abuf, afs_uint32 len,
+                  afs_uint32 *byteswritten)
 {
-    afs_int32 code;
+    afs_int32 nBytes, code;
     struct rxfs_storeVariables *v = (struct rxfs_storeVariables *)r;
 
     RX_AFS_GUNLOCK();
-    code = rx_Writev(v->call, v->tiov, v->tnio, l);
+    nBytes = rx_Writev(v->call, v->tiov, v->tnio, len);
     RX_AFS_GLOCK();
-    if (code != l) {
+    if (nBytes != len) {
        code = rx_Error(v->call);
         return (code ? code : -33);
     }
-    *byteswritten = code;
+    *byteswritten = nBytes;
     return 0;
 }
 
 afs_int32
-rxfs_storeUfsWrite(void *r, afs_uint32 l, afs_uint32 *byteswritten)
+rxfs_storeUfsWrite(void *r, char *abuf, afs_uint32 len,
+                  afs_uint32 *byteswritten)
 {
-    afs_int32 code;
+    afs_int32 nBytes, code;
     struct rxfs_storeVariables *v = (struct rxfs_storeVariables *)r;
 
     RX_AFS_GUNLOCK();
-    code = rx_Write(v->call, v->tbuffer, l);
-       /* 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. */
+    nBytes = rx_Write(v->call, abuf, len);
     RX_AFS_GLOCK();
-    if (code != l) {
+    if (nBytes != len) {
        code = rx_Error(v->call);
         return (code ? code : -33);
     }
-    *byteswritten = code;
+    *byteswritten = nBytes;
     return 0;
 }
 
+afs_int32
+rxfs_storeUfsWriteUnlocked(void *r, char *abuf, afs_uint32 len,
+                  afs_uint32 *byteswritten)
+{
+    afs_int32 nBytes, code;
+    struct rxfs_storeVariables *v = (struct rxfs_storeVariables *)r;
+
+    nBytes = rx_Write(v->call, abuf, len);
+    if (nBytes != len) {
+       code = rx_Error(v->call);
+        return (code ? code : -33);
+    }
+    *byteswritten = nBytes;
+    return 0;
+}
 afs_int32
 rxfs_storePadd(void *rock, afs_uint32 size)
 {
-    afs_int32 code = 0;
+    afs_int32 nBytes;
     afs_uint32 tlen;
     struct rxfs_storeVariables *v = (struct rxfs_storeVariables *)rock;
 
@@ -196,10 +227,10 @@ rxfs_storePadd(void *rock, afs_uint32 size)
     while (size) {
        tlen = (size > AFS_LRALLOCSIZ ? AFS_LRALLOCSIZ : size);
        RX_AFS_GUNLOCK();
-       code = rx_Write(v->call, v->tbuffer, tlen);
+       nBytes = rx_Write(v->call, v->tbuffer, tlen);
        RX_AFS_GLOCK();
 
-       if (code != tlen)
+       if (nBytes != tlen)
            return -33; /* XXX */
        size -= tlen;
     }
@@ -219,7 +250,7 @@ rxfs_storeStatus(void *rock)
 afs_int32
 rxfs_storeClose(void *r, struct AFSFetchStatus *OutStatus, int *doProcessFS)
 {
-    afs_int32 code;
+    afs_int32 code, code2;
     struct AFSVolSync tsync;
     struct rxfs_storeVariables *v = (struct rxfs_storeVariables *)r;
 
@@ -232,7 +263,11 @@ rxfs_storeClose(void *r, struct AFSFetchStatus *OutStatus, int *doProcessFS)
     else
 #endif
        code = EndRXAFS_StoreData(v->call, OutStatus, &tsync);
+    code2 = rx_EndCall(v->call, code);
     RX_AFS_GLOCK();
+    if (!code && code2)
+       code = code2;
+    v->call = NULL;
     if (!code)
        *doProcessFS = 1;       /* Flag to run afs_ProcessFS() later on */
 
@@ -262,16 +297,16 @@ rxfs_storeDestroy(void **r, afs_int32 error)
 }
 
 afs_int32
-afs_GenericStoreProc(struct storeOps *ops, void *rock,
+afs_GenericStoreProc(struct vcache *avc, struct storeOps *ops, void *rock,
                     struct dcache *tdc, int *shouldwake,
                     afs_size_t *bytesXferred)
 {
-    struct rxfs_storeVariables *svar = rock;
     afs_uint32 tlen, bytesread, byteswritten;
     afs_int32 code = 0;
     int offset = 0;
     afs_size_t size;
     struct osi_file *tfile;
+    char *abuf;
 
     size = tdc->f.chunkBytes;
 
@@ -282,12 +317,12 @@ afs_GenericStoreProc(struct storeOps *ops, void *rock,
        if ( code )
            break;
 
-       code = (*ops->read)(rock, tfile, offset, tlen, &bytesread);
+       code = (*ops->read)(rock, tfile, offset, tlen, &bytesread, &abuf);
        if (code)
            break;
 
        tlen = bytesread;
-       code = (*ops->write)(rock, tlen, &byteswritten);
+       code = (*ops->write)(rock, abuf, tlen, &byteswritten);
        if (code)
            break;
 #ifndef AFS_NOSTATS
@@ -302,7 +337,7 @@ afs_GenericStoreProc(struct storeOps *ops, void *rock,
         */
        if (shouldwake && *shouldwake && ((*ops->status)(rock) == 0)) {
            *shouldwake = 0;    /* only do this once */
-           afs_wakeup(svar->vcache);
+           afs_wakeup(avc);
        }
     }
     afs_CFileClose(tfile);
@@ -324,7 +359,11 @@ struct storeOps rxfs_storeUfsOps = {
 #else
     .prepare =         rxfs_storeUfsPrepare,
     .read =    rxfs_storeUfsRead,
+#ifdef AFS_LINUX26_ENV
+    .write =   rxfs_storeUfsWriteUnlocked,
+#else
     .write =   rxfs_storeUfsWrite,
+#endif
     .status =  rxfs_storeStatus,
     .padd =    rxfs_storePadd,
     .close =   rxfs_storeClose,
@@ -413,7 +452,7 @@ rxfs_storeInit(struct vcache *avc, struct afs_conn *tc, afs_size_t base,
        v->tbuffer = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
        if (!v->tbuffer)
            osi_Panic
-            ("rxfs_storeInit: osi_AllocLargeSpace for iovecs returned NULL\n");
+            ("rxfs_storeInit: osi_AllocLargeSpace for tbuffer returned NULL\n");
        *ops = (struct storeOps *) &rxfs_storeUfsOps;
     } else {
        v->tiov = osi_AllocSmallSpace(sizeof(struct iovec) * RX_MAXIOVECS);
@@ -436,6 +475,7 @@ rxfs_storeInit(struct vcache *avc, struct afs_conn *tc, afs_size_t base,
 #endif /* notdef */
     }
 
+    v->ops = (void *)*ops;
     *rock = (void *)v;
     return 0;
 }
@@ -512,7 +552,7 @@ afs_CacheStoreDCaches(struct vcache *avc, struct dcache **dclist,
 #endif /* AFS_NOSTATS */
        bytesXferred = 0;
 
-       code = (*ops->storeproc)(ops, rock, tdc, shouldwake,
+       code = (*ops->storeproc)(avc, ops, rock, tdc, shouldwake,
                                     &bytesXferred);
 
        afs_Trace4(afs_iclSetp, CM_TRACE_STOREPROC, ICL_TYPE_POINTER, avc,
@@ -682,7 +722,7 @@ afs_CacheStoreVCache(struct dcache **dcList, struct vcache *avc,
                dclist[i] = NULL;
            }
 
-           if (doProcessFS) {
+           if (!code && doProcessFS) {
                /* Now copy out return params */
                UpgradeSToWLock(&avc->lock, 28);        /* keep out others for a while */
                afs_ProcessFS(avc, &OutStatus, areq);
@@ -718,8 +758,10 @@ afs_CacheStoreVCache(struct dcache **dcList, struct vcache *avc,
 /* rock and operations for RX_FILESERVER */
 
 struct rxfs_fetchVariables {
+    void *ops;
     struct rx_call *call;
     char *tbuffer;
+    struct osi_file *fP;
     struct iovec *iov;
     afs_int32 nio;
     afs_int32 hasNo64bit;
@@ -748,16 +790,16 @@ rxfs_fetchUfsRead(void *r, afs_uint32 size, afs_uint32 *bytesread)
 afs_int32
 rxfs_fetchMemRead(void *r, afs_uint32 tlen, afs_uint32 *bytesread)
 {
-    afs_int32 code;
+    afs_int32 nBytes;
     struct rxfs_fetchVariables *v = (struct rxfs_fetchVariables *)r;
 
     *bytesread = 0;
     RX_AFS_GUNLOCK();
-    code = rx_Readv(v->call, v->iov, &v->nio, RX_MAXIOVECS, tlen);
+    nBytes = rx_Readv(v->call, v->iov, &v->nio, RX_MAXIOVECS, tlen);
     RX_AFS_GLOCK();
-    if (code <= 0)
+    if (nBytes <= 0)
        return -34;
-    *bytesread = code;
+    *bytesread = nBytes;
     return 0;
 }
 
@@ -766,15 +808,15 @@ afs_int32
 rxfs_fetchMemWrite(void *r, struct osi_file *fP, afs_uint32 offset,
                   afs_uint32 tlen, afs_uint32 *byteswritten)
 {
-    afs_int32 code;
+    afs_int32 nBytes;
     struct rxfs_fetchVariables *v = (struct rxfs_fetchVariables *)r;
     struct memCacheEntry *mceP = (struct memCacheEntry *)fP;
 
-    code = afs_MemWritevBlk(mceP, offset, v->iov, v->nio, tlen);
-    if (code != tlen) {
+    nBytes = afs_MemWritevBlk(mceP, offset, v->iov, v->nio, tlen);
+    if (nBytes != tlen) {
         return EIO;
     }
-    *byteswritten = code;
+    *byteswritten = nBytes;
     return 0;
 }
 
@@ -782,14 +824,14 @@ afs_int32
 rxfs_fetchUfsWrite(void *r, struct osi_file *fP, afs_uint32 offset,
                   afs_uint32 tlen, afs_uint32 *byteswritten)
 {
-    afs_int32 code;
+    afs_int32 nBytes;
     struct rxfs_fetchVariables *v = (struct rxfs_fetchVariables *)r;
 
-    code = afs_osi_Write(fP, -1, v->tbuffer, tlen);
-    if (code != tlen) {
+    nBytes = afs_osi_Write(fP, -1, v->tbuffer, tlen);
+    if (nBytes != tlen) {
         return EIO;
     }
-    *byteswritten = code;
+    *byteswritten = nBytes;
     return 0;
 }
 
@@ -798,7 +840,7 @@ afs_int32
 rxfs_fetchClose(void *r, struct vcache *avc, struct dcache * adc,
                struct afs_FetchOutput *o)
 {
-    afs_int32 code, code1 = 0;
+    afs_int32 code, code2 = 0;
     struct rxfs_fetchVariables *v = (struct rxfs_fetchVariables *)r;
 
     if (!v->call)
@@ -813,10 +855,10 @@ rxfs_fetchClose(void *r, struct vcache *avc, struct dcache * adc,
 #endif
         code = EndRXAFS_FetchData(v->call, &o->OutStatus, &o->CallBack,
                                &o->tsync);
-    code1 = rx_EndCall(v->call, code);
+    code2 = rx_EndCall(v->call, code);
     RX_AFS_GLOCK();
-    if (!code && code1)
-       code = code1;
+    if (!code && code2)
+       code = code2;
 
     v->call = NULL;
 
@@ -848,7 +890,7 @@ rxfs_fetchDestroy(void **r, afs_int32 error)
 afs_int32
 rxfs_fetchMore(void *r, afs_int32 *length, afs_uint32 *moredata)
 {
-    afs_int32 code;
+    afs_int32 nBytes, code;
     struct rxfs_fetchVariables *v = (struct rxfs_fetchVariables *)r;
 
     /*
@@ -862,11 +904,12 @@ rxfs_fetchMore(void *r, afs_int32 *length, afs_uint32 *moredata)
      */
     if (*moredata) {
        RX_AFS_GUNLOCK();
-       code = rx_Read(v->call, (void *)length, sizeof(afs_int32));
+       nBytes = rx_Read(v->call, (void *)length, sizeof(afs_int32));
        RX_AFS_GLOCK();
        *length = ntohl(*length);
-       if (code != sizeof(afs_int32)) {
+       if (nBytes != sizeof(afs_int32)) {
            code = rx_Error(v->call);
+           *length = 0;
            *moredata = 0;
            return (code ? code : -1);  /* try to return code, not -1 */
         }
@@ -906,12 +949,15 @@ rxfs_fetchInit(struct afs_conn *tc, struct vcache *avc, afs_offs_t base,
 #endif
     afs_uint32 length, bytes;
 
+    if (!tc)
+       return -1;
     v = (struct rxfs_fetchVariables *)
            osi_AllocSmallSpace(sizeof(struct rxfs_fetchVariables));
     if (!v)
         osi_Panic("rxfs_fetchInit: osi_AllocSmallSpace returned NULL\n");
     memset(v, 0, sizeof(struct rxfs_fetchVariables));
 
+    v->fP = fP;
     RX_AFS_GUNLOCK();
     v->call = rx_NewCall(tc->id);
     RX_AFS_GLOCK();
@@ -1027,7 +1073,7 @@ rxfs_fetchInit(struct afs_conn *tc, struct vcache *avc, afs_offs_t base,
     if (cacheDiskType == AFS_FCACHE_TYPE_UFS) {
        v->tbuffer = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
        if (!v->tbuffer)
-           osi_Panic("rxfs_fetchInit: osi_AllocLargeSpace for iovecs returned NULL\n");
+           osi_Panic("rxfs_fetchInit: osi_AllocLargeSpace for tbuffer returned NULL\n");
        osi_Assert(WriteLocked(&adc->lock));
        fP->offset = 0;
        *ops = (struct fetchOps *) &rxfs_fetchUfsOps;
@@ -1045,6 +1091,8 @@ rxfs_fetchInit(struct afs_conn *tc, struct vcache *avc, afs_offs_t base,
            osi_Panic("rxfs_fetchInit: osi_AllocSmallSpace for iovecs returned NULL\n");
        *ops = (struct fetchOps *) &rxfs_fetchMemOps;
     }
+
+    v->ops = (void *) *ops;
     *rock = (void *)v;
     return 0;
 }
@@ -1056,6 +1104,7 @@ rxfs_fetchInit(struct afs_conn *tc, struct vcache *avc, afs_offs_t base,
  *
  * \param tc Ptr to the Rx connection structure.
  * \param fP File descriptor for the cache file.
+ * \param areq Ptr to vrequest structure.
  * \param base Base offset to fetch.
  * \param adc Ptr to the dcache entry for the file, write-locked.
  * \param avc Ptr to the vcache entry for the file.
@@ -1093,9 +1142,6 @@ afs_CacheFetchProc(struct afs_conn *tc, struct osi_file *fP, afs_size_t base,
      * avc->lock(W) if !setLocks || slowPass
      * adc->lock(W)
      */
-    code = rxfs_fetchInit(
-               tc, avc, base, size, &length, adc, fP, &ops, &rock);
-
 #ifndef AFS_NOSTATS
     osi_GetuTime(&xferStartTime);
 #endif /* AFS_NOSTATS */
@@ -1104,6 +1150,12 @@ afs_CacheFetchProc(struct afs_conn *tc, struct osi_file *fP, afs_size_t base,
        adc->validPos = base;
     }
 
+#ifdef AFS_64BIT_CLIENT
+restart:
+#endif
+    code = rxfs_fetchInit(
+               tc, avc, base, size, &length, adc, fP, &ops, &rock);
+
     if ( !code ) do {
        if (avc->f.states & CForeign) {
            code = (*ops->more)(rock, &length, &moredata);
@@ -1152,6 +1204,12 @@ afs_CacheFetchProc(struct afs_conn *tc, struct osi_file *fP, afs_size_t base,
        code = (*ops->close)(rock, avc, adc, tsmall);
     if (ops)
        (*ops->destroy)(&rock, code);
+#ifdef AFS_64BIT_CLIENT
+    if (code == RXGEN_OPCODE && !afs_serverHasNo64Bit(tc)) {
+       afs_serverSetNo64Bit(tc);
+       goto restart;
+    }
+#endif /* AFS_64BIT_CLIENT */
 
 #ifndef AFS_NOSTATS
     FillStoreStats(code, AFS_STATS_FS_XFERIDX_FETCHDATA, &xferStartTime,
index 93a2d12a97ea71a98d0ce99c9e425d37c7d20818..38570622bb27fb61dac1c008f407a3ee05296154 100644 (file)
@@ -612,8 +612,8 @@ extern void osi_ReleaseVM(struct vcache *avc, afs_ucred_t *acred);
 
 /* LINUX/osi_fetchstore.c */
 #ifdef AFS_LINUX26_ENV
-extern int afs_linux_storeproc(struct storeOps *, void *, struct dcache *,
-                              int *, afs_size_t *);
+extern int afs_linux_storeproc(struct vcache *, struct storeOps *, void *,
+                              struct dcache *, int *, afs_size_t *);
 #endif
 
 /* ARCH/osi_misc.c */