ihandle positional read and write
authorMichael Meffie <mmeffie@sinenomine.net>
Mon, 15 Mar 2010 17:42:23 +0000 (12:42 -0500)
committerDerrick Brashear <shadow@dementia.org>
Tue, 31 Aug 2010 17:41:10 +0000 (10:41 -0700)
When available, use POSIX positional read and write
calls in the ihandle package. Originally written
by Derrick Brashear and Andrew Deason.

Change-Id: I29a9d830872cb920e8ed5820e33d3cbcb7247460
Reviewed-on: http://gerrit.openafs.org/1562
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

21 files changed:
acinclude.m4
src/viced/afsfileprocs.c
src/viced/physio.c
src/vol/clone.c
src/vol/ihandle.c
src/vol/ihandle.h
src/vol/listinodes.c
src/vol/namei_ops.c
src/vol/ntops.c
src/vol/physio.c
src/vol/purge.c
src/vol/vnode.c
src/vol/vol-info.c
src/vol/vol-salvage.c
src/vol/volume.c
src/vol/vutil.c
src/volser/dumpstuff.c
src/volser/physio.c
src/volser/vol-dump.c
src/volser/vol_split.c
src/volser/volprocs.c

index ba8f7b6..8782488 100644 (file)
@@ -1258,6 +1258,10 @@ AC_CHECK_FUNCS([ \
        getrlimit \
        issetugid \
        mkstemp \
+       pread \
+       preadv \
+       pwrite \
+       pwritev \
        regcomp \
        regerror \
        regexec \
@@ -1275,6 +1279,23 @@ AC_CHECK_FUNCS([ \
        vsyslog \
 ])
 
+AC_MSG_CHECKING([for positional I/O])
+if test "$ac_cv_func_pread" = "yes" && \
+        test "$ac_cv_func_pwrite" = "yes"; then
+   AC_DEFINE(HAVE_PIO, 1, [define if you have pread() and pwrite()])
+   AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+AC_MSG_CHECKING([for vectored positional I/O])
+if test "$ac_cv_func_preadv" = "yes" && \
+        test "$ac_cv_func_pwritev" = "yes"; then
+   AC_DEFINE(HAVE_PIOV, 1, [define if you have preadv() and pwritev()])
+   AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
 AC_MSG_CHECKING([for POSIX regex library])
 if test "$ac_cv_header_regex_h" = "yes" && \
        test "$ac_cv_func_regcomp" = "yes" && \
index 40dea53..f441be0 100644 (file)
@@ -1114,6 +1114,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
     ssize_t rdlen;
     ssize_t wrlen;
     afs_fsize_t size;
+    afs_foff_t done;
     size_t length;
     char *buff;
     int rc;                    /* return code */
@@ -1175,8 +1176,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
     newFdP = IH_OPEN(newH);
     assert(newFdP != NULL);
 
-    FDH_SEEK(targFdP, off, SEEK_SET);
-    FDH_SEEK(newFdP, off, SEEK_SET);
+    done = off;
     while (size > 0) {
        if (size > COPYBUFFSIZE) {      /* more than a buffer */
            length = COPYBUFFSIZE;
@@ -1185,10 +1185,11 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
            length = size;
            size = 0;
        }
-       rdlen = FDH_READ(targFdP, buff, length);
-       if (rdlen == length)
-           wrlen = FDH_WRITE(newFdP, buff, length);
-       else
+       rdlen = FDH_PREAD(targFdP, buff, length, done);
+       if (rdlen == length) {
+           wrlen = FDH_PWRITE(newFdP, buff, length, done);
+           done += rdlen;
+       } else
            wrlen = 0;
        /*  Callers of this function are not prepared to recover
         *  from error that put the filesystem in an inconsistent
@@ -1272,9 +1273,7 @@ CopyOnWrite2(FdHandle_t *targFdP, FdHandle_t *newFdP, afs_foff_t off,
     ssize_t rdlen;
     ssize_t wrlen;
     int rc = 0;
-
-    FDH_SEEK(targFdP, off, SEEK_SET);
-    FDH_SEEK(newFdP, off, SEEK_SET);
+    afs_foff_t done = off;
 
     if (size > FDH_SIZE(targFdP) - off)
        size = FDH_SIZE(targFdP) - off;
@@ -1287,9 +1286,11 @@ CopyOnWrite2(FdHandle_t *targFdP, FdHandle_t *newFdP, afs_foff_t off,
            length = size;
            size = 0;
        }
-       rdlen = FDH_READ(targFdP, buff, length);
-       if (rdlen == length)
-           wrlen = FDH_WRITE(newFdP, buff, length);
+       rdlen = FDH_PREAD(targFdP, buff, length, done);
+       if (rdlen == length) {
+           wrlen = FDH_PWRITE(newFdP, buff, length, done);
+           done += rdlen;
+       }
        else
            wrlen = 0;
 
@@ -2025,13 +2026,13 @@ SRXAFS_FsCmd(struct rx_call * acall, struct AFSFid * Fid,
     return code;
 }
 
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
 static struct afs_buffer {
     struct afs_buffer *next;
 } *freeBufferList = 0;
 static int afs_buffersAlloced = 0;
 
-static
+static int
 FreeSendBuffer(struct afs_buffer *adata)
 {
     FS_LOCK;
@@ -2045,7 +2046,7 @@ FreeSendBuffer(struct afs_buffer *adata)
 
 /* allocate space for sender */
 static char *
-AllocSendBuffer()
+AllocSendBuffer(void)
 {
     struct afs_buffer *tp;
 
@@ -2067,7 +2068,7 @@ AllocSendBuffer()
     return (char *)tp;
 
 }                              /*AllocSendBuffer */
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
 
 /*
  * This routine returns the status info associated with the targetptr vnode
@@ -4465,9 +4466,9 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
        return EIO;
     }
     len = strlen((char *) LinkContents);
-    code = (len == FDH_WRITE(fdP, (char *) LinkContents, len)) ? 0 : VDISKFULL;
+    code = (len == FDH_PWRITE(fdP, (char *) LinkContents, len, 0)) ? 0 : VDISKFULL;
     if (code)
-       ViceLog(0, ("SAFSS_Symlink FDH_WRITE failed for len=%d, Fid=%u.%d.%d\n", (int)len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
+       ViceLog(0, ("SAFSS_Symlink FDH_PWRITE failed for len=%d, Fid=%u.%d.%d\n", (int)len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
     FDH_CLOSE(fdP);
     /*
      * Set up and return modified status for the parent dir and new symlink
@@ -7029,12 +7030,12 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
     struct timeval StartTime, StopTime;        /* used to calculate file  transfer rates */
     IHandle_t *ihP;
     FdHandle_t *fdP;
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     char *tbuffer;
-#else /* AFS_NT40_ENV */
+#else /* HAVE_PIOV */
     struct iovec tiov[RX_MAXIOVECS];
     int tnio;
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     afs_sfsize_t tlen;
     afs_int32 optSize;
 
@@ -7089,7 +7090,6 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
     if (Pos + Len > tlen) /* get length we should send */
        Len = ((tlen - Pos) < 0) ? 0 : tlen - Pos;
 
-    (void)FDH_SEEK(fdP, Pos, 0);
     {
        afs_int32 high, low;
        SplitOffsetOrSize(Len, high, low);
@@ -7104,9 +7104,9 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
 #if FS_STATS_DETAILED
     (*a_bytesToFetchP) = Len;
 #endif /* FS_STATS_DETAILED */
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     tbuffer = AllocSendBuffer();
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     while (Len > 0) {
        size_t wlen;
        ssize_t nBytes;
@@ -7114,8 +7114,8 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
            wlen = optSize;
        else
            wlen = Len;
-#ifdef AFS_NT40_ENV
-       nBytes = FDH_READ(fdP, tbuffer, wlen);
+#ifndef HAVE_PIOV
+       nBytes = FDH_PREAD(fdP, tbuffer, wlen, Pos);
        if (nBytes != wlen) {
            FDH_CLOSE(fdP);
            FreeSendBuffer((struct afs_buffer *)tbuffer);
@@ -7125,14 +7125,14 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
            return EIO;
        }
        nBytes = rx_Write(Call, tbuffer, wlen);
-#else /* AFS_NT40_ENV */
+#else /* HAVE_PIOV */
        nBytes = rx_WritevAlloc(Call, tiov, &tnio, RX_MAXIOVECS, wlen);
        if (nBytes <= 0) {
            FDH_CLOSE(fdP);
            return EIO;
        }
        wlen = nBytes;
-       nBytes = FDH_READV(fdP, tiov, tnio);
+       nBytes = FDH_PREADV(fdP, tiov, tnio, Pos);
        if (nBytes != wlen) {
            FDH_CLOSE(fdP);
            VTakeOffline(volptr);
@@ -7141,7 +7141,8 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
            return EIO;
        }
        nBytes = rx_Writev(Call, tiov, tnio, wlen);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
+       Pos += wlen;
 #if FS_STATS_DETAILED
        /*
         * Bump the number of bytes actually sent by the number from this
@@ -7151,16 +7152,16 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
 #endif /* FS_STATS_DETAILED */
        if (nBytes != wlen) {
            FDH_CLOSE(fdP);
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
            FreeSendBuffer((struct afs_buffer *)tbuffer);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
            return -31;
        }
        Len -= wlen;
     }
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     FreeSendBuffer((struct afs_buffer *)tbuffer);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     FDH_CLOSE(fdP);
     FT_GetTimeOfDay(&StopTime, 0);
 
@@ -7255,12 +7256,12 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     afs_sfsize_t bytesTransfered;      /* number of bytes actually transfered */
     struct timeval StartTime, StopTime;        /* Used to measure how long the store takes */
     Error errorCode = 0;               /* Returned error code to caller */
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     char *tbuffer;     /* data copying buffer */
-#else /* AFS_NT40_ENV */
+#else /* HAVE_PIOV */
     struct iovec tiov[RX_MAXIOVECS];   /* no data copying with iovec */
     int tnio;                  /* temp for iovec size */
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     afs_sfsize_t tlen;         /* temp for xfr length */
     Inode tinode;              /* inode for I/O */
     afs_int32 optSize;         /* optimal transfer size */
@@ -7416,12 +7417,10 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     /* truncate the file iff it needs it (ftruncate is slow even when its a noop) */
     if (FileLength < DataLength)
        FDH_TRUNC(fdP, FileLength);
-    if (Pos > 0)
-       FDH_SEEK(fdP, Pos, 0);
     bytesTransfered = 0;
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     tbuffer = AllocSendBuffer();
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     /* if length == 0, the loop below isn't going to do anything, including
      * extend the length of the inode, which it must do, since the file system
      * assumes that the inode length == vnode's file length.  So, we extend
@@ -7433,7 +7432,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
        /* Set the file's length; we've already done an lseek to the right
         * spot above.
         */
-       nBytes = FDH_WRITE(fdP, &tlen, 1);
+       nBytes = FDH_PWRITE(fdP, &tlen, 1, Pos);
        if (nBytes != 1) {
            errorCode = -1;
            goto done;
@@ -7455,11 +7454,11 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
                rlen = optSize; /* bound by buffer size */
            else
                rlen = (int)tlen;
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
            errorCode = rx_Read(Call, tbuffer, rlen);
-#else /* AFS_NT40_ENV */
+#else /* HAVE_PIOV */
            errorCode = rx_Readv(Call, tiov, &tnio, RX_MAXIOVECS, rlen);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
            if (errorCode <= 0) {
                errorCode = -32;
                break;
@@ -7468,22 +7467,23 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
            (*a_bytesStoredP) += errorCode;
 #endif /* FS_STATS_DETAILED */
            rlen = errorCode;
-#ifdef AFS_NT40_ENV
-           nBytes = FDH_WRITE(fdP, tbuffer, rlen);
-#else /* AFS_NT40_ENV */
-           nBytes = FDH_WRITEV(fdP, tiov, tnio);
-#endif /* AFS_NT40_ENV */
+#ifndef HAVE_PIOV
+           nBytes = FDH_PWRITE(fdP, tbuffer, rlen, Pos);
+#else /* HAVE_PIOV */
+           nBytes = FDH_PWRITEV(fdP, tiov, tnio, Pos);
+#endif /* HAVE_PIOV */
            if (nBytes != rlen) {
                errorCode = VDISKFULL;
                break;
            }
            bytesTransfered += rlen;
+           Pos += rlen;
        }
     }
   done:
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     FreeSendBuffer((struct afs_buffer *)tbuffer);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     if (sync) {
        FDH_SYNC(fdP);
     }
index 6165dcc..caf5cf2 100644 (file)
@@ -64,17 +64,7 @@ ReallyRead(DirHandle * file, int block, char *data)
                                                       ih_ino), code));
        return code;
     }
-    if (FDH_SEEK(fdP, block * PAGESIZE, SEEK_SET) < 0) {
-       code = errno;
-       ViceLog(0,
-               ("ReallyRead(): lseek failed device %X inode %s errno %d\n",
-                file->dirh_handle->ih_dev, PrintInode(NULL,
-                                                      file->dirh_handle->
-                                                      ih_ino), code));
-       FDH_REALLYCLOSE(fdP);
-       return code;
-    }
-    rdlen = FDH_READ(fdP, data, PAGESIZE);
+    rdlen = FDH_PREAD(fdP, data, PAGESIZE, ((afs_foff_t)block) * PAGESIZE);
     if (rdlen != PAGESIZE) {
        if (rdlen < 0)
            code = errno;
@@ -111,17 +101,7 @@ ReallyWrite(DirHandle * file, int block, char *data)
        lpErrno = errno;
        return 0;
     }
-    if (FDH_SEEK(fdP, block * PAGESIZE, SEEK_SET) < 0) {
-       ViceLog(0,
-               ("ReallyWrite(): lseek failed device %X inode %s errno %d\n",
-                file->dirh_handle->ih_dev, PrintInode(NULL,
-                                                      file->dirh_handle->
-                                                      ih_ino), errno));
-       lpErrno = errno;
-       FDH_REALLYCLOSE(fdP);
-       return 0;
-    }
-    if ((count = FDH_WRITE(fdP, data, PAGESIZE)) != PAGESIZE) {
+    if ((count = FDH_PWRITE(fdP, data, PAGESIZE, ((afs_foff_t)block) * PAGESIZE)) != PAGESIZE) {
        ViceLog(0,
                ("ReallyWrite(): write failed device %X inode %s errno %d\n",
                 file->dirh_handle->ih_dev, PrintInode(stmp,
index e2e5909..c42c8af 100644 (file)
@@ -194,7 +194,7 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
     rwfile = FDH_FDOPEN(rwFd, ReadWriteOriginal ? "r+" : "r");
     if (!rwfile)
        ERROR_EXIT(EIO);
-    STREAM_SEEK(rwfile, vcp->diskSize, 0);     /* Will fail if no vnodes */
+    STREAM_ASEEK(rwfile, vcp->diskSize);       /* Will fail if no vnodes */
 
     /* Open the clone volume's index file and seek to beginning */
     IH_COPY(clHout, clvp->vnodeIndex[class].handle);
@@ -204,7 +204,7 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
     clfileout = FDH_FDOPEN(clFdOut, "a");
     if (!clfileout)
        ERROR_EXIT(EIO);
-    code = STREAM_SEEK(clfileout, vcp->diskSize, 0);
+    code = STREAM_ASEEK(clfileout, vcp->diskSize);
     if (code)
        ERROR_EXIT(EIO);
 
@@ -220,7 +220,7 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
        clfilein = FDH_FDOPEN(clFdIn, "r");
        if (!clfilein)
            ERROR_EXIT(EIO);
-       STREAM_SEEK(clfilein, vcp->diskSize, 0);        /* Will fail if no vnodes */
+       STREAM_ASEEK(clfilein, vcp->diskSize);  /* Will fail if no vnodes */
     }
 
     /* Initialize list of inodes to nuke */
@@ -287,14 +287,14 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
                rwvnode->dataVersion++;
 #endif /* DVINC */
                rwvnode->cloned = 1;
-               code = STREAM_SEEK(rwfile, offset, 0);
+               code = STREAM_ASEEK(rwfile, offset);
                if (code == -1)
                    goto clonefailed;
                code = STREAM_WRITE(rwvnode, vcp->diskSize, 1, rwfile);
                if (code != 1)
                    goto clonefailed;
                dircloned = 1;
-               code = STREAM_SEEK(rwfile, offset + vcp->diskSize, 0);
+               code = STREAM_ASEEK(rwfile, offset + vcp->diskSize);
                if (code == -1)
                    goto clonefailed;
 #ifdef DVINC
@@ -323,7 +323,7 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
            /* And if the directory was marked clone, unmark it */
            if (dircloned) {
                rwvnode->cloned = 0;
-               if (STREAM_SEEK(rwfile, offset, 0) != -1)
+               if (STREAM_ASEEK(rwfile, offset) != -1)
                    (void)STREAM_WRITE(rwvnode, vcp->diskSize, 1, rwfile);
            }
            ERROR_EXIT(EIO);
@@ -341,7 +341,7 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
 
     /* Clean out any junk at end of clone file */
     if (reclone) {
-       STREAM_SEEK(clfilein, offset, 0);
+       STREAM_ASEEK(clfilein, offset);
        while (STREAM_READ(clvnode, vcp->diskSize, 1, clfilein) == 1) {
            if (clvnode->type != vNull && VNDISK_GET_INO(clvnode) != 0) {
                ci_AddItem(&decHead, VNDISK_GET_INO(clvnode));
index 096f34d..2740e2f 100644 (file)
@@ -303,6 +303,7 @@ fdHandleAllocateChunk(void)
     assert(fdP != NULL);
     for (i = 0; i < FD_HANDLE_MALLOCSIZE; i++) {
        fdP[i].fd_status = FD_HANDLE_AVAIL;
+       fdP[i].fd_refcnt = 0;
        fdP[i].fd_ih = NULL;
        fdP[i].fd_fd = INVALID_FD;
        DLL_INSERT_TAIL(&fdP[i], fdAvailHead, fdAvailTail, fd_next, fd_prev);
@@ -344,13 +345,23 @@ ih_open(IHandle_t * ihP)
 
     /* Do we already have an open file handle for this Inode? */
     for (fdP = ihP->ih_fdtail; fdP != NULL; fdP = fdP->fd_ihprev) {
+#ifndef HAVE_PIO
+       /*
+        * If we don't have positional i/o, don't try to share fds, since
+        * we can't do so in a threadsafe way.
+        */
        if (fdP->fd_status != FD_HANDLE_INUSE) {
            assert(fdP->fd_status == FD_HANDLE_OPEN);
+#else /* HAVE_PIO */
+       if (fdP->fd_status != FD_HANDLE_AVAIL) {
+#endif /* HAVE_PIO */
+           fdP->fd_refcnt++;
+           if (fdP->fd_status == FD_HANDLE_OPEN) {
            fdP->fd_status = FD_HANDLE_INUSE;
            DLL_DELETE(fdP, fdLruHead, fdLruTail, fd_next, fd_prev);
+           }
            ihP->ih_refcnt++;
            IH_UNLOCK;
-           (void)FDH_SEEK(fdP, 0, SEEK_SET);
            return fdP;
        }
     }
@@ -403,6 +414,7 @@ ih_open_retry:
     fdP->fd_status = FD_HANDLE_INUSE;
     fdP->fd_fd = fd;
     fdP->fd_ih = ihP;
+    fdP->fd_refcnt++;
 
     ihP->ih_refcnt++;
 
@@ -449,9 +461,12 @@ fd_close(FdHandle_t * fdP)
        return fd_reallyclose(fdP);
     }
 
+    fdP->fd_refcnt--;
+    if (fdP->fd_refcnt == 0) {
     /* Put this descriptor back into the cache */
     fdP->fd_status = FD_HANDLE_OPEN;
     DLL_INSERT_TAIL(fdP, fdLruHead, fdLruTail, fd_next, fd_prev);
+    }
 
     /* If this is not the only reference to the Inode then we can decrement
      * the reference count, otherwise we need to call ih_release.
@@ -487,13 +502,17 @@ fd_reallyclose(FdHandle_t * fdP)
 
     ihP = fdP->fd_ih;
     closeFd = fdP->fd_fd;
+    fdP->fd_refcnt--;
 
+    if (fdP->fd_refcnt == 0) {
     DLL_DELETE(fdP, ihP->ih_fdhead, ihP->ih_fdtail, fd_ihnext, fd_ihprev);
     DLL_INSERT_TAIL(fdP, fdAvailHead, fdAvailTail, fd_next, fd_prev);
 
     fdP->fd_status = FD_HANDLE_AVAIL;
+    fdP->fd_refcnt = 0;
     fdP->fd_ih = NULL;
     fdP->fd_fd = INVALID_FD;
+    }
 
     /* All the file descriptor handles have been closed; reset
      * the IH_REALLY_CLOSED flag indicating that ih_reallyclose
@@ -503,10 +522,12 @@ fd_reallyclose(FdHandle_t * fdP)
        ihP->ih_flags &= ~IH_REALLY_CLOSED;
     }
 
+    if (fdP->fd_refcnt == 0) {
     IH_UNLOCK;
     OS_CLOSE(closeFd);
     IH_LOCK;
     fdInUseCount -= 1;
+    }
 
     /* If this is not the only reference to the Inode then we can decrement
      * the reference count, otherwise we need to call ih_release. */
@@ -537,6 +558,7 @@ stream_fdopen(FD_t fd)
     streamP->str_fd = fd;
     streamP->str_buflen = 0;
     streamP->str_bufoff = 0;
+    streamP->str_fdoff = 0;
     streamP->str_error = 0;
     streamP->str_eof = 0;
     streamP->str_direction = STREAM_DIRECTION_NONE;
@@ -595,8 +617,8 @@ stream_read(void *ptr, afs_fsize_t size, afs_fsize_t nitems,
        if (streamP->str_buflen == 0) {
            streamP->str_bufoff = 0;
            streamP->str_buflen =
-               OS_READ(streamP->str_fd, streamP->str_buffer,
-                       STREAM_HANDLE_BUFSIZE);
+               OS_PREAD(streamP->str_fd, streamP->str_buffer,
+                       STREAM_HANDLE_BUFSIZE, streamP->str_fdoff);
            if (streamP->str_buflen < 0) {
                streamP->str_error = errno;
                streamP->str_buflen = 0;
@@ -606,6 +628,7 @@ stream_read(void *ptr, afs_fsize_t size, afs_fsize_t nitems,
                streamP->str_eof = 1;
                break;
            }
+           streamP->str_fdoff += streamP->str_buflen;
        }
 
        bytesToRead = nbytes;
@@ -646,13 +669,14 @@ stream_write(void *ptr, afs_fsize_t size, afs_fsize_t nitems,
     p = (char *)ptr;
     while (nbytes > 0) {
        if (streamP->str_buflen == 0) {
-           rc = OS_WRITE(streamP->str_fd, streamP->str_buffer,
-                         STREAM_HANDLE_BUFSIZE);
+           rc = OS_PWRITE(streamP->str_fd, streamP->str_buffer,
+                         STREAM_HANDLE_BUFSIZE, streamP->str_fdoff);
            if (rc < 0) {
                streamP->str_error = errno;
                bytesWritten = 0;
                break;
            }
+           streamP->str_fdoff += rc;
            streamP->str_bufoff = 0;
            streamP->str_buflen = STREAM_HANDLE_BUFSIZE;
        }
@@ -674,28 +698,25 @@ stream_write(void *ptr, afs_fsize_t size, afs_fsize_t nitems,
 
 /* fseek for buffered I/O handles */
 int
-stream_seek(StreamHandle_t * streamP, afs_foff_t offset, int whence)
+stream_aseek(StreamHandle_t * streamP, afs_foff_t offset)
 {
     ssize_t rc;
     int retval = 0;
 
     if (streamP->str_direction == STREAM_DIRECTION_WRITE
        && streamP->str_bufoff > 0) {
-       rc = OS_WRITE(streamP->str_fd, streamP->str_buffer,
-                     streamP->str_bufoff);
+       rc = OS_PWRITE(streamP->str_fd, streamP->str_buffer,
+                     streamP->str_bufoff, streamP->str_fdoff);
        if (rc < 0) {
            streamP->str_error = errno;
            retval = -1;
        }
     }
+    streamP->str_fdoff = offset;
     streamP->str_bufoff = 0;
     streamP->str_buflen = 0;
     streamP->str_eof = 0;
     streamP->str_direction = STREAM_DIRECTION_NONE;
-    if (OS_SEEK(streamP->str_fd, offset, whence) < 0) {
-       streamP->str_error = errno;
-       retval = -1;
-    }
     return retval;
 }
 
@@ -708,11 +729,13 @@ stream_flush(StreamHandle_t * streamP)
 
     if (streamP->str_direction == STREAM_DIRECTION_WRITE
        && streamP->str_bufoff > 0) {
-       rc = OS_WRITE(streamP->str_fd, streamP->str_buffer,
-                     streamP->str_bufoff);
+       rc = OS_PWRITE(streamP->str_fd, streamP->str_buffer,
+                     streamP->str_bufoff, streamP->str_fdoff);
        if (rc < 0) {
            streamP->str_error = errno;
            retval = -1;
+       } else {
+           streamP->str_fdoff += rc;
        }
        streamP->str_bufoff = 0;
        streamP->str_buflen = STREAM_HANDLE_BUFSIZE;
@@ -731,10 +754,12 @@ stream_close(StreamHandle_t * streamP, int reallyClose)
     assert(streamP != NULL);
     if (streamP->str_direction == STREAM_DIRECTION_WRITE
        && streamP->str_bufoff > 0) {
-       rc = OS_WRITE(streamP->str_fd, streamP->str_buffer,
-                     streamP->str_bufoff);
+       rc = OS_PWRITE(streamP->str_fd, streamP->str_buffer,
+                     streamP->str_bufoff, streamP->str_fdoff);
        if (rc < 0) {
            retval = -1;
+       } else {
+           streamP->str_fdoff += rc;
        }
     }
     if (reallyClose) {
@@ -811,6 +836,7 @@ ih_fdclose(IHandle_t * ihP)
     for (fdP = head; fdP != NULL; fdP = fdP->fd_next) {
        OS_CLOSE(fdP->fd_fd);
        fdP->fd_status = FD_HANDLE_AVAIL;
+       fdP->fd_refcnt = 0;
        fdP->fd_fd = INVALID_FD;
        fdP->fd_ih = NULL;
        closeCount++;
@@ -1023,3 +1049,25 @@ ih_size(int fd)
     return status.st_size;
 }
 #endif
+
+#ifndef HAVE_PIO
+ssize_t
+ih_pread(int fd, void * buf, size_t count, afs_foff_t offset)
+{
+       afs_foff_t code;
+       code = OS_SEEK(fd, offset, 0);
+       if (code < 0)
+           return code;
+       return OS_READ(fd, buf, count);
+}
+
+ssize_t
+ih_pwrite(int fd, const void * buf, size_t count, afs_foff_t offset)
+{
+       afs_foff_t code;
+       code = OS_SEEK(fd, offset, 0);
+       if (code < 0)
+           return code;
+       return OS_WRITE(fd, buf, count);
+}
+#endif /* !HAVE_PIO */
index 0786e9f..fc19fee 100644 (file)
@@ -156,6 +156,7 @@ typedef int FD_t;
 /* file descriptor handle */
 typedef struct FdHandle_s {
     int fd_status;             /* status flags */
+    int fd_refcnt;             /* refcnt */
     FD_t fd_fd;                        /* file descriptor */
     struct IHandle_s *fd_ih;   /* Pointer to Inode handle */
     struct FdHandle_s *fd_next;        /* LRU/Avail list pointers */
@@ -176,6 +177,7 @@ typedef struct StreamHandle_s {
     int str_direction;         /* current read/write direction */
     afs_sfsize_t str_buflen;   /* bytes remaining in buffer */
     afs_foff_t str_bufoff;     /* current offset into buffer */
+    afs_foff_t str_fdoff;      /* current offset into file */
     int str_error;             /* error code */
     int str_eof;               /* end of file flag */
     struct StreamHandle_s *str_next;   /* Avail list pointers */
@@ -306,8 +308,7 @@ extern afs_sfsize_t stream_read(void *ptr, afs_fsize_t size,
 extern afs_sfsize_t stream_write(void *ptr, afs_fsize_t size,
                                 afs_fsize_t nitems,
                                 StreamHandle_t * streamP);
-extern int stream_seek(StreamHandle_t * streamP, afs_foff_t offset,
-                      int whence);
+extern int stream_aseek(StreamHandle_t * streamP, afs_foff_t offset);
 extern int stream_flush(StreamHandle_t * streamP);
 extern int stream_close(StreamHandle_t * streamP, int reallyClose);
 extern int ih_reallyclose(IHandle_t * ihP);
@@ -337,7 +338,7 @@ extern int ih_condsync(IHandle_t * ihP);
 
 #define STREAM_WRITE(A, B, C, H) stream_write(A, B, C, H)
 
-#define STREAM_SEEK(H, A, B) stream_seek(H, A, B)
+#define STREAM_ASEEK(H, A) stream_aseek(H, A)
 
 #define STREAM_FLUSH(H) stream_flush(H)
 
@@ -355,6 +356,21 @@ extern int ih_condsync(IHandle_t * ihP);
 
 #define IH_CONDSYNC(H) ih_condsync(H)
 
+#ifdef HAVE_PIO
+#ifdef O_LARGEFILE
+#define OS_PREAD(FD, B, S, O) pread64(FD, B, S, O)
+#define OS_PWRITE(FD, B, S, O) pwrite64(FD, B, S, O)
+#else /* !O_LARGEFILE */
+#define OS_PREAD(FD, B, S, O) pread(FD, B, S, O)
+#define OS_PWRITE(FD, B, S, O) pwrite(FD, B, S, O)
+#endif /* !O_LARGEFILE */
+#else /* !HAVE_PIO */
+extern ssize_t ih_pread(int fd, void * buf, size_t count, afs_foff_t offset);
+extern ssize_t ih_pwrite(int fd, const void * buf, size_t count, afs_foff_t offset);
+#define OS_PREAD(FD, B, S, O) ih_pread(FD, B, S, O)
+#define OS_PWRITE(FD, B, S, O) ih_pwrite(FD, B, S, O)
+#endif /* !HAVE_PIO */
+
 #ifdef AFS_NAMEI_ENV
 
 #ifdef AFS_NT40_ENV
@@ -392,6 +408,8 @@ extern int OS_OPEN(const char *F, int M, mode_t P);
 extern int OS_CLOSE(int FD);
 extern ssize_t OS_READ(int FD, void *B, size_t S);
 extern ssize_t OS_WRITE(int FD, void *B, size_t S);
+extern ssize_t OS_PREAD(int FD, void *B, size_t S, afs_foff_t O);
+extern ssize_t OS_PWRITE(int FD, void *B, size_t S, afs_foff_t O);
 extern int OS_SYNC(int FD);
 extern afs_sfsize_t OS_SIZE(int FD);
 extern int IH_INC(IHandle_t * H, Inode I, int /*@alt VolId, VolumeId @ */ P);
@@ -463,8 +481,6 @@ extern Inode ih_icreate(IHandle_t * ih, int dev, char *part, Inode nI, int p1,
 #define OS_OPEN(F, M, P) open(F, M, P)
 #define OS_CLOSE(FD) close(FD)
 
-#define OS_READ(FD, B, S) read(FD, B, S)
-#define OS_WRITE(FD, B, S) write(FD, B, S)
 #ifdef O_LARGEFILE
 #define OS_SEEK(FD, O, F) lseek64(FD, (off64_t) (O), F)
 #else /* !O_LARGEFILE */
@@ -502,6 +518,13 @@ extern afs_sfsize_t ih_size(int fd);
 #define FDH_WRITEV(H, I, N) writev((H)->fd_fd, I, N)
 #endif
 
+#ifdef HAVE_PIOV
+#define FDH_PREADV(H, I, N, O) preadv((H)->fd_fd, I, N, O)
+#define FDH_PWRITEV(H, I, N, O) pwritev((H)->fd_fd, I, N, O)
+#endif
+
+#define FDH_PREAD(H, B, S, O) OS_PREAD((H)->fd_fd, B, S, O)
+#define FDH_PWRITE(H, B, S, O) OS_PWRITE((H)->fd_fd, B, S, O)
 #define FDH_READ(H, B, S) OS_READ((H)->fd_fd, B, S)
 #define FDH_WRITE(H, B, S) OS_WRITE((H)->fd_fd, B, S)
 #define FDH_SEEK(H, O, F) OS_SEEK((H)->fd_fd, O, F)
index 090f954..e3a1ea6 100644 (file)
@@ -1311,12 +1311,12 @@ bread(int fd, char *buf, daddr_t blk, afs_int32 size)
 
 #endif /* AFS_LINUX20_ENV */
 static afs_int32
-convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
+convertVolumeInfo(FdHandle_t *fdhr, FdHandle_t *fdhw, afs_uint32 vid)
 {
     struct VolumeDiskData vd;
     char *p;
 
-    if (read(fdr, &vd, sizeof(struct VolumeDiskData)) !=
+    if (FDH_PREAD(fdhr, &vd, sizeof(struct VolumeDiskData), 0) !=
         sizeof(struct VolumeDiskData)) {
         Log("1 convertiVolumeInfo: read failed for %lu with code %d\n", vid,
             errno);
@@ -1336,7 +1336,7 @@ convertVolumeInfo(int fdr, int fdw, afs_uint32 vid)
         memset(p, 0, 9);
     }
 
-    if (write(fdw, &vd, sizeof(struct VolumeDiskData)) !=
+    if (FDH_PWRITE(fdhw, &vd, sizeof(struct VolumeDiskData), 0) !=
         sizeof(struct VolumeDiskData)) {
         Log("1 convertiVolumeInfo: write failed for %lu with code %d\n", vid,
             errno);
@@ -1400,6 +1400,7 @@ inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     struct VolumeDiskHeader h;
     IHandle_t *ih, *ih2;
     FdHandle_t *fdP, *fdP2;
+    ssize_t offset;
     char wpath[100];
     char tmpDevName[100];
     char buffer[128];
@@ -1480,19 +1481,21 @@ inode_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
            }
 
            if (j == VI_VOLINFO)
-               convertVolumeInfo(fdP->fd_fd, fdP2->fd_fd, ih2->ih_vid);
+               convertVolumeInfo(fdP, fdP2, ih2->ih_vid);
            else {
+               offset = 0;
                while (1) {
-                   len = read(fdP->fd_fd, buffer, sizeof(buffer));
+                   len = FDH_PREAD(fdP, buffer, sizeof(buffer), offset);
                    if (len < 0)
                        return errno;
                    if (len == 0)
                        break;
-                   nBytes = write(fdP2->fd_fd, buffer, len);
+                   nBytes = FDH_PWRITE(fdP2, buffer, len, offset);
                    if (nBytes != len) {
                        code = -1;
                        goto done;
                    }
+                   offset += len;
                }
            }
 
index bd55fc3..93b4f49 100644 (file)
 /*@+fcnmacros +macrofcndecl@*/
 #ifdef O_LARGEFILE
 #ifdef S_SPLINT_S
-extern off64_t afs_lseek(int FD, off64_t O, int F);
 #endif /*S_SPLINT_S */
-#define afs_lseek(FD, O, F)    lseek64(FD, (off64_t)(O), F)
 #define afs_stat               stat64
 #define afs_fstat              fstat64
 #define afs_open               open64
 #define afs_fopen              fopen64
 #else /* !O_LARGEFILE */
 #ifdef S_SPLINT_S
-extern off_t afs_lseek(int FD, off_t O, int F);
 #endif /*S_SPLINT_S */
-#define afs_lseek(FD, O, F)    lseek(FD, (off_t)(O), F)
 #define afs_stat               stat
 #define afs_fstat              fstat
 #define afs_open               open
@@ -111,12 +107,7 @@ namei_iread(IHandle_t * h, afs_foff_t offset, char *buf, afs_fsize_t size)
     if (fdP == NULL)
        return -1;
 
-    if (FDH_SEEK(fdP, offset, SEEK_SET) < 0) {
-       FDH_REALLYCLOSE(fdP);
-       return -1;
-    }
-
-    nBytes = FDH_READ(fdP, buf, size);
+    nBytes = FDH_PREAD(fdP, buf, size, offset);
     FDH_CLOSE(fdP);
     return nBytes;
 }
@@ -131,11 +122,7 @@ namei_iwrite(IHandle_t * h, afs_foff_t offset, char *buf, afs_fsize_t size)
     if (fdP == NULL)
        return -1;
 
-    if (FDH_SEEK(fdP, offset, SEEK_SET) < 0) {
-       FDH_REALLYCLOSE(fdP);
-       return -1;
-    }
-    nBytes = FDH_WRITE(fdP, buf, size);
+    nBytes = FDH_PWRITE(fdP, buf, size, offset);
     FDH_CLOSE(fdP);
     return nBytes;
 }
@@ -825,6 +812,7 @@ namei_copy_on_write(IHandle_t *h)
     namei_t name;
     FdHandle_t *fdP;
     struct afs_stat tstat;
+    afs_foff_t offset;
 
     namei_HandleToName(&name, h);
     if (afs_stat(name.n_path, &tstat) < 0)
@@ -852,14 +840,15 @@ namei_copy_on_write(IHandle_t *h)
            return ENOMEM;
        }
        size = tstat.st_size;
-       FDH_SEEK(fdP, 0, 0);
+       offset = 0;
        while (size) {
            tlen = size > 8192 ? 8192 : size;
-           if (FDH_READ(fdP, buf, tlen) != tlen)
+           if (FDH_PREAD(fdP, buf, tlen, offset) != tlen)
                break;
            if (write(fd, buf, tlen) != tlen)
                break;
            size -= tlen;
+           offset += tlen;
        }
        close(fd);
        FDH_REALLYCLOSE(fdP);
@@ -989,10 +978,7 @@ namei_GetLinkCount2(FdHandle_t * h, Inode ino, int lockit, int fixup, int nowrit
            return -1;
     }
 
-    if (afs_lseek(h->fd_fd, offset, SEEK_SET) == -1)
-       goto bad_getLinkByte;
-
-    rc = read(h->fd_fd, (char *)&row, sizeof(row));
+    rc = FDH_PREAD(h, (char*)&row, sizeof(row), offset);
     if ((rc == 0 || !((row >> index) & NAMEI_TAGMASK)) && fixup && nowrite)
         return 1;
     if (rc == 0 && fixup) {
@@ -1001,7 +987,7 @@ namei_GetLinkCount2(FdHandle_t * h, Inode ino, int lockit, int fixup, int nowrit
           goto bad_getLinkByte;
         FDH_TRUNC(h, offset+sizeof(row));
         row = 1 << index;
-        rc = write(h->fd_fd, (char *)&row, sizeof(row));
+       rc = FDH_PWRITE(h, (char *)&row, sizeof(row), offset);
     }
     if (rc != sizeof(row)) {
        goto bad_getLinkByte;
@@ -1009,9 +995,7 @@ namei_GetLinkCount2(FdHandle_t * h, Inode ino, int lockit, int fixup, int nowrit
 
     if (fixup && !((row >> index) & NAMEI_TAGMASK)) {
         row |= 1<<index;
-        if (afs_lseek(h->fd_fd, offset, SEEK_SET) == -1)
-           goto bad_getLinkByte;
-        rc = write(h->fd_fd, (char *)&row, sizeof(row));
+       rc = FDH_PWRITE(h, (char *)&row, sizeof(row), offset);
         if (rc != sizeof(row))
            goto bad_getLinkByte;
     }
@@ -1053,11 +1037,8 @@ GetFreeTag(IHandle_t * ih, int vno)
     }
 
     offset = (vno << LINKTABLE_SHIFT) + 8;     /* * 2 + sizeof stamp */
-    if (afs_lseek(fdP->fd_fd, offset, SEEK_SET) == -1) {
-       goto badGetFreeTag;
-    }
 
-    nBytes = read(fdP->fd_fd, (char *)&row, sizeof(row));
+    nBytes = FDH_PREAD(fdP, (char *)&row, sizeof(row), offset);
     if (nBytes != sizeof(row)) {
        if (nBytes != 0)
            goto badGetFreeTag;
@@ -1078,10 +1059,7 @@ GetFreeTag(IHandle_t * ih, int vno)
     coldata = 1 << (col * 3);
     row |= coldata;
 
-    if (afs_lseek(fdP->fd_fd, offset, SEEK_SET) == -1) {
-       goto badGetFreeTag;
-    }
-    if (write(fdP->fd_fd, (char *)&row, sizeof(row)) != sizeof(row)) {
+    if (FDH_PWRITE(fdP, (char *)&row, sizeof(row), offset) != sizeof(row)) {
        goto badGetFreeTag;
     }
     FDH_SYNC(fdP);
@@ -1117,13 +1095,8 @@ namei_SetLinkCount(FdHandle_t * fdP, Inode ino, int count, int locked)
            return -1;
        }
     }
-    if (afs_lseek(fdP->fd_fd, offset, SEEK_SET) == -1) {
-       errno = EBADF;
-       goto bad_SetLinkCount;
-    }
 
-
-    nBytes = read(fdP->fd_fd, (char *)&row, sizeof(row));
+    nBytes = FDH_PREAD(fdP, (char *)&row, sizeof(row), offset);
     if (nBytes != sizeof(row)) {
        if (nBytes != 0) {
            errno = EBADF;
@@ -1137,12 +1110,7 @@ namei_SetLinkCount(FdHandle_t * fdP, Inode ino, int count, int locked)
     row &= (unsigned short)~junk;
     row |= (unsigned short)count;
 
-    if (afs_lseek(fdP->fd_fd, offset, SEEK_SET) == -1) {
-       errno = EBADF;
-       goto bad_SetLinkCount;
-    }
-
-    if (write(fdP->fd_fd, (char *)&row, sizeof(short)) != sizeof(short)) {
+    if (FDH_PWRITE(fdP, (char *)&row, sizeof(short), offset) != sizeof(short)) {
        errno = EBADF;
        goto bad_SetLinkCount;
     }
index 6e0c59e..0cd94f4 100644 (file)
@@ -181,12 +181,7 @@ nt_iread(IHandle_t * h, int offset, char *buf, int size)
     if (fdP == NULL)
        return -1;
 
-    if (FDH_SEEK(fdP, offset, SEEK_SET) < 0) {
-       FDH_REALLYCLOSE(fdP);
-       return -1;
-    }
-
-    nBytes = FDH_READ(fdP, buf, size);
+    nBytes = FDH_PREAD(fdP, buf, size, offset);
     FDH_CLOSE(fdP);
     return nBytes;
 }
@@ -201,11 +196,7 @@ nt_iwrite(IHandle_t * h, int offset, char *buf, int size)
     if (fdP == NULL)
        return -1;
 
-    if (FDH_SEEK(fdP, offset, SEEK_SET) < 0) {
-       FDH_REALLYCLOSE(fdP);
-       return -1;
-    }
-    nBytes = FDH_WRITE(fdP, buf, size);
+    nBytes = FDH_PWRITE(fdP, buf, size, offset);
     FDH_CLOSE(fdP);
     return nBytes;
 }
index 9b06ff8..e5ef192 100644 (file)
@@ -55,12 +55,8 @@ ReallyRead(DirHandle * file, int block, char *data)
        code = errno;
        return code;
     }
-    if (FDH_SEEK(fdP, ((afs_foff_t)block) * AFS_PAGESIZE, SEEK_SET) < 0) {
-       code = errno;
-       FDH_REALLYCLOSE(fdP);
-       return code;
-    }
-    nBytes = FDH_READ(fdP, data, (afs_fsize_t) AFS_PAGESIZE);
+    nBytes = FDH_PREAD(fdP, data, (afs_fsize_t) AFS_PAGESIZE,
+                       ((afs_foff_t)block) * AFS_PAGESIZE);
     if (nBytes != AFS_PAGESIZE) {
        if (nBytes < 0)
            code = errno;
@@ -88,12 +84,8 @@ ReallyWrite(DirHandle * file, int block, char *data)
        code = errno;
        return code;
     }
-    if (FDH_SEEK(fdP, ((afs_foff_t)block) * AFS_PAGESIZE, SEEK_SET) < 0) {
-       code = errno;
-       FDH_REALLYCLOSE(fdP);
-       return code;
-    }
-    nBytes = FDH_WRITE(fdP, data, (afs_fsize_t) AFS_PAGESIZE);
+    nBytes = FDH_PWRITE(fdP, data, (afs_fsize_t) AFS_PAGESIZE,
+                        ((afs_foff_t)block) * AFS_PAGESIZE);
     if (nBytes != AFS_PAGESIZE) {
        if (nBytes < 0)
            code = errno;
index 47bce55..1ac4bae 100644 (file)
@@ -127,7 +127,7 @@ ObliterateRegion(Volume * avp, VnodeClass aclass, StreamHandle_t * afile,
      * We remember the inodes in an array, and idec them after zeroing them in the index.
      * The reason for these contortions is to make volume deletion idempotent, even
      * if we crash in the middle of a delete operation. */
-    STREAM_SEEK(afile, offset, 0);
+    STREAM_ASEEK(afile, offset);
     while (1) {
        if (iindex >= MAXOBLITATONCE) {
            break;
@@ -148,7 +148,7 @@ ObliterateRegion(Volume * avp, VnodeClass aclass, StreamHandle_t * afile,
     }
 
     /* next, obliterate the index and fflush (and fsync) it */
-    STREAM_SEEK(afile, *aoffset, 0);   /* seek back to start of vnode index region */
+    STREAM_ASEEK(afile, *aoffset);     /* seek back to start of vnode index region */
     memset(buf, 0, sizeof(buf));       /* zero out our proto-vnode */
     for (i = 0; i < nscanned; i++) {
        if (STREAM_WRITE(buf, vcp->diskSize, 1, afile) != 1)
index 18e2014..a857af8 100644 (file)
@@ -764,13 +764,8 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
                *ec = EIO;
                goto error_encountered;
            }
-           if (FDH_SEEK(fdP, off, SEEK_SET) < 0) {
-               Log("VAllocVnode: can't seek on index file!\n");
-               *ec = EIO;
-               goto error_encountered;
-           }
            if (off + vcp->diskSize <= size) {
-               if (FDH_READ(fdP, &vnp->disk, vcp->diskSize) != vcp->diskSize) {
+             if (FDH_PREAD(fdP, &vnp->disk, vcp->diskSize, off) != vcp->diskSize) {
                    Log("VAllocVnode: can't read index file!\n");
                    *ec = EIO;
                    goto error_encountered;
@@ -789,7 +784,7 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
                    goto error_encountered;
                }
                memset(buf, 0, 16 * 1024);
-               if ((FDH_WRITE(fdP, buf, 16 * 1024)) != 16 * 1024) {
+               if ((FDH_PWRITE(fdP, buf, 16 * 1024, off)) != 16 * 1024) {
                    Log("VAllocVnode: can't grow vnode index: write failed\n");
                    *ec = EIO;
                    free(buf);
@@ -902,12 +897,7 @@ VnLoad(Error * ec, Volume * vp, Vnode * vnp,
            PrintInode(stmp, vp->vnodeIndex[class].handle->ih_ino));
        *ec = VIO;
        goto error_encountered_nolock;
-    } else if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, Vn_id(vnp)), SEEK_SET)
-              < 0) {
-       Log("VnLoad: can't seek on index file vn=%u\n", Vn_id(vnp));
-       *ec = VIO;
-       goto error_encountered_nolock;
-    } else if ((nBytes = FDH_READ(fdP, (char *)&vnp->disk, vcp->diskSize))
+    } else if ((nBytes = FDH_PREAD(fdP, (char *)&vnp->disk, vcp->diskSize, vnodeIndexOffset(vcp, Vn_id(vnp))))
               != vcp->diskSize) {
        /* Don't take volume off line if the inumber is out of range
         * or the inode table is full. */
@@ -1029,14 +1019,7 @@ VnStore(Error * ec, Volume * vp, Vnode * vnp,
        Log("VnStore: can't open index file!\n");
        goto error_encountered;
     }
-    if (FDH_SEEK(fdP, offset, SEEK_SET) < 0) {
-       Log("VnStore: can't seek on index file! fdp=%"AFS_PTR_FMT
-           " offset=%d, errno=%d\n",
-           fdP, (int) offset, errno);
-       goto error_encountered;
-    }
-
-    nBytes = FDH_WRITE(fdP, &vnp->disk, vcp->diskSize);
+    nBytes = FDH_PWRITE(fdP, &vnp->disk, vcp->diskSize, offset);
     if (nBytes != vcp->diskSize) {
        /* Don't force volume offline if the inumber is out of
         * range or the inode table is full.
index f4c4516..31ce4df 100644 (file)
@@ -779,7 +779,7 @@ PrintVnodes(Volume * vp, VnodeClass class)
 
     nVnodes = (size / diskSize) - 1;
     if (nVnodes > 0) {
-       STREAM_SEEK(file, diskSize, 0);
+       STREAM_ASEEK(file, diskSize);
     } else
        nVnodes = 0;
 
@@ -810,7 +810,7 @@ PrintVnodes(Volume * vp, VnodeClass class)
                total = bad = 0;
                while (1) {
                    ssize_t nBytes;
-                   len = FDH_READ(fdP1, buffer, sizeof(buffer));
+                   len = FDH_PREAD(fdP1, buffer, sizeof(buffer), total);
                    if (len < 0) {
                        FDH_REALLYCLOSE(fdP1);
                        IH_RELEASE(ih1);
index 964ae21..5ad2e58 100644 (file)
@@ -1780,7 +1780,7 @@ CreateLinkTable(struct SalvInfo *salvinfo, struct InodeSummary *isp, Inode ino)
     version.magic = LINKTABLEMAGIC;
     version.version = LINKTABLEVERSION;
 
-    if (FDH_WRITE(fdP, (char *)&version, sizeof(version))
+    if (FDH_PWRITE(fdP, (char *)&version, sizeof(version), 0)
        != sizeof(version))
        Abort("Can't truncate link table for volume %u (error = %d)\n",
              isp->RWvolumeId, errno);
@@ -2393,7 +2393,7 @@ SalvageHeader(struct SalvInfo *salvinfo, struct afs_inode_info *sp,
              sp->description, errno);
 
     if (!recreate
-       && (FDH_READ(fdP, (char *)&header, sp->size) != sp->size
+       && (FDH_PREAD(fdP, (char *)&header, sp->size, 0) != sp->size
            || header.fileHeader.magic != sp->stamp.magic)) {
        if (check) {
            Log("Part of the header (%s) is corrupted\n", sp->description);
@@ -2444,14 +2444,9 @@ SalvageHeader(struct SalvInfo *salvinfo, struct afs_inode_info *sp,
            header.volumeInfo.needsCallback = 0;
            gettimeofday(&tp, 0);
            header.volumeInfo.creationDate = tp.tv_sec;
-           if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
-               Abort
-                   ("Unable to seek to beginning of volume header file (%s) (errno = %d)\n",
-                    sp->description, errno);
-           }
            nBytes =
-               FDH_WRITE(fdP, (char *)&header.volumeInfo,
-                         sizeof(header.volumeInfo));
+               FDH_PWRITE(fdP, (char *)&header.volumeInfo,
+                          sizeof(header.volumeInfo), 0);
            if (nBytes != sizeof(header.volumeInfo)) {
                if (nBytes < 0)
                    Abort
@@ -2461,12 +2456,7 @@ SalvageHeader(struct SalvInfo *salvinfo, struct afs_inode_info *sp,
                      sp->description);
            }
        } else {
-           if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
-               Abort
-                   ("Unable to seek to beginning of volume header file (%s) (errno = %d)\n",
-                    sp->description, errno);
-           }
-           nBytes = FDH_WRITE(fdP, (char *)&sp->stamp, sizeof(sp->stamp));
+           nBytes = FDH_PWRITE(fdP, (char *)&sp->stamp, sizeof(sp->stamp), 0);
            if (nBytes != sizeof(sp->stamp)) {
                if (nBytes < 0)
                    Abort
@@ -2558,7 +2548,7 @@ SalvageIndex(struct SalvInfo *salvinfo, Inode ino, VnodeClass class, int RW,
     nVnodes = (size / vcp->diskSize) - 1;
     if (nVnodes > 0) {
        assert((nVnodes + 1) * vcp->diskSize == size);
-       assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+       assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
     } else {
        nVnodes = 0;
     }
@@ -3132,7 +3122,7 @@ JudgeEntry(void *arock, char *name, afs_int32 vnodeNumber,
 
            if (size > 1024)
                size = 1024;
-           nBytes = FDH_READ(fdP, buf, size);
+           nBytes = FDH_PREAD(fdP, buf, size, 0);
            if (nBytes == size) {
                buf[size] = '\0';
                if ( (*buf != '#' && *buf != '%') || buf[strlen(buf)-1] != '.' ) {
@@ -3228,7 +3218,7 @@ DistilVnodeEssence(struct SalvInfo *salvinfo, VolumeId rwVId,
     vip->nVnodes = (size / vcp->diskSize) - 1;
     if (vip->nVnodes > 0) {
        assert((vip->nVnodes + 1) * vcp->diskSize == size);
-       assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+       assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
        assert((vip->vnodes = (struct VnodeEssence *)
                calloc(vip->nVnodes, sizeof(struct VnodeEssence))) != NULL);
        if (class == vLarge) {
@@ -4386,14 +4376,17 @@ CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume)
     IHandle_t *srcH, *destH;
     FdHandle_t *srcFdP, *destFdP;
     ssize_t nBytes = 0;
+    afs_foff_t size = 0;
 
     IH_INIT(srcH, device, rwvolume, inode1);
     srcFdP = IH_OPEN(srcH);
     assert(srcFdP != NULL);
     IH_INIT(destH, device, rwvolume, inode2);
     destFdP = IH_OPEN(destH);
-    while ((nBytes = FDH_READ(srcFdP, buf, sizeof(buf))) > 0)
-       assert(FDH_WRITE(destFdP, buf, nBytes) == nBytes);
+    while ((nBytes = FDH_PREAD(srcFdP, buf, sizeof(buf), size)) > 0) {
+       assert(FDH_PWRITE(destFdP, buf, nBytes, size) == nBytes);
+       size += nBytes;
+    }
     assert(nBytes == 0);
     FDH_REALLYCLOSE(srcFdP);
     FDH_REALLYCLOSE(destFdP);
index aec2bcb..6b7d95a 100644 (file)
@@ -1890,13 +1890,8 @@ ReadHeader(Error * ec, IHandle_t * h, char *to, int size, bit32 magic,
        return;
     }
 
-    if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
-       *ec = VSALVAGE;
-       FDH_REALLYCLOSE(fdP);
-       return;
-    }
     vsn = (struct versionStamp *)to;
-    if (FDH_READ(fdP, to, size) != size || vsn->magic != magic) {
+    if (FDH_PREAD(fdP, to, size, 0) != size || vsn->magic != magic) {
        *ec = VSALVAGE;
        FDH_REALLYCLOSE(fdP);
        return;
@@ -1922,12 +1917,7 @@ WriteVolumeHeader_r(Error * ec, Volume * vp)
        *ec = VSALVAGE;
        return;
     }
-    if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
-       *ec = VSALVAGE;
-       FDH_REALLYCLOSE(fdP);
-       return;
-    }
-    if (FDH_WRITE(fdP, (char *)&V_disk(vp), sizeof(V_disk(vp)))
+    if (FDH_PWRITE(fdP, (char *)&V_disk(vp), sizeof(V_disk(vp)), 0)
        != sizeof(V_disk(vp))) {
        *ec = VSALVAGE;
        FDH_REALLYCLOSE(fdP);
@@ -5786,7 +5776,7 @@ VGetBitmap_r(Error * ec, Volume * vp, VnodeClass class)
     assert(vip->bitmap != NULL);
     vip->bitmapOffset = 0;
 #endif /* BITMAP_LATER */
-    if (STREAM_SEEK(file, vcp->diskSize, 0) != -1) {
+    if (STREAM_ASEEK(file, vcp->diskSize) != -1) {
        int bitNumber = 0;
        for (bitNumber = 0; bitNumber < nVnodes + 100; bitNumber++) {
            if (STREAM_READ(vnode, vcp->diskSize, 1, file) != 1)
index 3d643c6..a927e7c 100644 (file)
@@ -275,13 +275,7 @@ VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId)
                PrintInode(stmp, *(p->inode)), errno);
            goto bad;
        }
-       if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
-           Log("VCreateVolume:  Problem lseek inode %s (err=%d)\n",
-               PrintInode(NULL, *(p->inode)), errno);
-           FDH_REALLYCLOSE(fdP);
-           goto bad;
-       }
-       if (FDH_WRITE(fdP, (char *)&p->stamp, sizeof(p->stamp)) !=
+       if (FDH_PWRITE(fdP, (char *)&p->stamp, sizeof(p->stamp), 0) !=
            sizeof(p->stamp)) {
            Log("VCreateVolume:  Problem writing to  inode %s (err=%d)\n",
                PrintInode(stmp, *(p->inode)), errno);
@@ -300,13 +294,7 @@ VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId)
            PrintInode(stmp, tempHeader.volumeInfo), errno);
        goto bad;
     }
-    if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
-       Log("VCreateVolume:  Problem lseek inode %s (err=%d)\n",
-           PrintInode(NULL, tempHeader.volumeInfo), errno);
-       FDH_REALLYCLOSE(fdP);
-       goto bad;
-    }
-    if (FDH_WRITE(fdP, (char *)&vol, sizeof(vol)) != sizeof(vol)) {
+    if (FDH_PWRITE(fdP, (char *)&vol, sizeof(vol), 0) != sizeof(vol)) {
        Log("VCreateVolume:  Problem writing to  inode %s (err=%d)\n",
            PrintInode(stmp, tempHeader.volumeInfo), errno);
        FDH_REALLYCLOSE(fdP);
index 732a3f6..f8b7fa1 100644 (file)
@@ -711,7 +711,7 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
     afs_sfsize_t nbytes, howBig;
     ssize_t n;
     size_t howMany;
-    afs_foff_t lcode = 0;
+    afs_foff_t howFar = 0;
     byte *p;
     afs_uint32 hi, lo;
     afs_ino_str_t stmp;
@@ -778,8 +778,9 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
        if (nbytes < howMany)
            howMany = nbytes;
 
-       /* Read the data - unless we know we can't */
-       n = (lcode ? 0 : FDH_READ(handleP, p, howMany));
+       /* Read the data */
+       n = FDH_PREAD(handleP, p, howMany, howFar);
+       howFar += n;
 
        /* If read any good data and we null padded previously, log the
         * amount that we had null padded.
@@ -813,17 +814,7 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
            /* Now seek over the data we could not get. An error here means we
             * can't do the next read.
             */
-           lcode = FDH_SEEK(handleP, (size_t)((size - nbytes) + howMany), SEEK_SET);
-           if (lcode != ((size - nbytes) + howMany)) {
-               if (lcode < 0) {
-                   Log("1 Volser: DumpFile: Error seeking in inode %s for vnode %d: %s\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode, afs_error_message(errno));
-               } else {
-                   Log("1 Volser: DumpFile: Error seeking in inode %s for vnode %d\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
-                   lcode = -1;
-               }
-           } else {
-               lcode = 0;
-           }
+           howFar = (size_t)((size - nbytes) + howMany);
        }
 
        /* Now write the data out */
@@ -1006,7 +997,7 @@ DumpVnodeIndex(struct iod *iodp, Volume * vp, VnodeClass class,
     nVnodes = (size / vcp->diskSize) - 1;
     if (nVnodes > 0) {
        assert((nVnodes + 1) * vcp->diskSize == size);
-       assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+       assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;
@@ -1137,7 +1128,7 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
        for (i = 0; i < *sizep; i++) {
            if (Buf[i]) {
                cnt++;
-               STREAM_SEEK(afile, Buf[i], 0);
+               STREAM_ASEEK(afile, Buf[i]);
                code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
                if (code == 1) {
                    if (vnode->type != vNull && VNDISK_GET_INO(vnode)) {
@@ -1151,7 +1142,7 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
                               V_parentId(vp));
                        DOPOLL;
                    }
-                   STREAM_SEEK(afile, Buf[i], 0);
+                   STREAM_ASEEK(afile, Buf[i]);
                    (void)STREAM_WRITE(zero, vcp->diskSize, 1, afile);  /* Zero it out */
                }
                Buf[i] = 0;
@@ -1181,7 +1172,7 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
                return -1;
            }
            memset(Buf, 0, nVnodes * sizeof(afs_int32));
-           STREAM_SEEK(afile, offset = vcp->diskSize, 0);
+           STREAM_ASEEK(afile, offset = vcp->diskSize);
            while (1) {
                code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
                if (code != 1) {
@@ -1477,14 +1468,7 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
                    afs_error_message(errno));
                return VOLSERREAD_DUMPERROR;
            }
-           if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, vnodeNumber), SEEK_SET) <
-               0) {
-               Log("1 Volser: ReadVnodes: Error seeking into vnode index: %s; restore aborted\n",
-                   afs_error_message(errno));
-               FDH_REALLYCLOSE(fdP);
-               return VOLSERREAD_DUMPERROR;
-           }
-           if (FDH_READ(fdP, &oldvnode, sizeof(oldvnode)) ==
+           if (FDH_PREAD(fdP, &oldvnode, sizeof(oldvnode), vnodeIndexOffset(vcp, vnodeNumber)) ==
                sizeof(oldvnode)) {
                if (oldvnode.type != vNull && VNDISK_GET_INO(&oldvnode)) {
                    IH_DEC(V_linkHandle(vp), VNDISK_GET_INO(&oldvnode),
@@ -1492,14 +1476,7 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
                }
            }
            vnode->vnodeMagic = vcp->magic;
-           if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, vnodeNumber), SEEK_SET) <
-               0) {
-               Log("1 Volser: ReadVnodes: Error seeking into vnode index: %s; restore aborted\n",
-                   afs_error_message(errno));
-               FDH_REALLYCLOSE(fdP);
-               return VOLSERREAD_DUMPERROR;
-           }
-           if (FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
+           if (FDH_PWRITE(fdP, vnode, vcp->diskSize, vnodeIndexOffset(vcp, vnodeNumber)) != vcp->diskSize) {
                Log("1 Volser: ReadVnodes: Error writing vnode index: %s; restore aborted\n",
                    afs_error_message(errno));
                FDH_REALLYCLOSE(fdP);
@@ -1571,7 +1548,7 @@ volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
            break;
        }
        if (handleP) {
-           nBytes = FDH_WRITE(handleP, p, size);
+           nBytes = FDH_PWRITE(handleP, p, size, written);
            if (nBytes > 0)
                written += nBytes;
            if (nBytes != size) {
@@ -1894,7 +1871,7 @@ SizeDumpVnodeIndex(struct iod *iodp, Volume * vp, VnodeClass class,
     nVnodes = (size / vcp->diskSize) - 1;
     if (nVnodes > 0) {
        assert((nVnodes + 1) * vcp->diskSize == size);
-       assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+       assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;
index 35be2f1..69e1f91 100644 (file)
@@ -48,12 +48,7 @@ ReallyRead(DirHandle * file, int block, char *data)
        code = errno;
        return code;
     }
-    if (FDH_SEEK(fdP, ((afs_foff_t)block) * AFS_PAGESIZE, SEEK_SET) < 0) {
-       code = errno;
-       FDH_REALLYCLOSE(fdP);
-       return code;
-    }
-    nBytes = FDH_READ(fdP, data, AFS_PAGESIZE);
+    nBytes = FDH_PREAD(fdP, data, AFS_PAGESIZE, ((afs_foff_t)block) * AFS_PAGESIZE);
     if (nBytes != AFS_PAGESIZE) {
        if (nBytes < 0)
            code = errno;
@@ -82,12 +77,7 @@ ReallyWrite(DirHandle * file, int block, char *data)
        code = errno;
        return code;
     }
-    if (FDH_SEEK(fdP, ((afs_foff_t)block) * AFS_PAGESIZE, SEEK_SET) < 0) {
-       code = errno;
-       FDH_REALLYCLOSE(fdP);
-       return code;
-    }
-    nBytes = FDH_WRITE(fdP, data, AFS_PAGESIZE);
+    nBytes = FDH_PWRITE(fdP, data, AFS_PAGESIZE, ((afs_foff_t)block) * AFS_PAGESIZE);
     if (nBytes != AFS_PAGESIZE) {
        if (nBytes < 0)
            code = errno;
index cb862f9..d3eca97 100644 (file)
@@ -563,6 +563,7 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
     afs_sfsize_t nbytes, howBig;
     ssize_t n;
     size_t howMany;
+    afs_foff_t howFar = 0;
     byte *p;
     afs_uint32 hi, lo;
     afs_ino_str_t stmp;
@@ -628,7 +629,8 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
            howMany = nbytes;
 
        /* Read the data - unless we know we can't */
-       n = (failed_seek ? 0 : FDH_READ(handleP, p, howMany));
+       n = (failed_seek ? 0 : FDH_PREAD(handleP, p, howMany, howFar));
+       howFar += n;
 
        /* If read any good data and we null padded previously, log the
         * amount that we had null padded.
@@ -669,22 +671,7 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
            /* Now seek over the data we could not get. An error here means we
             * can't do the next read.
             */
-           failed_seek = FDH_SEEK(handleP, ((size - nbytes) + howMany), SEEK_SET);
-           if (failed_seek != ((size - nbytes) + howMany)) {
-               if (failed_seek < 0) {
-                   fprintf(stderr,
-                           "Error %d seeking in inode %s for vnode %d\n",
-                           errno, PrintInode(NULL, handleP->fd_ih->ih_ino),
-                           vnode);
-               } else {
-                   fprintf(stderr,
-                           "Error seeking in inode %s for vnode %d\n",
-                           PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
-                   failed_seek = -1;
-               }
-           } else {
-               failed_seek = 0;
-           }
+           howFar = ((size - nbytes) + howMany);
        }
 
        /* Now write the data out */
@@ -795,7 +782,7 @@ DumpVnodeIndex(int dumpfd, Volume * vp, VnodeClass class, afs_int32 fromtime,
     nVnodes = (size / vcp->diskSize) - 1;
 
     if (nVnodes > 0) {
-       STREAM_SEEK(file, vcp->diskSize, 0);
+       STREAM_ASEEK(file, vcp->diskSize);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;
index 20e7baf..eb5b084 100644 (file)
@@ -127,7 +127,7 @@ ExtractVnodes(struct Msg *m, Volume *vol, afs_int32 class,
        return EIO;
        goto Bad_Extract;
     }
-    code = STREAM_SEEK(stream, vcp->diskSize, 0);
+    code = STREAM_ASEEK(stream, vcp->diskSize);
     if (code)
        goto Bad_Extract;
 
@@ -152,7 +152,7 @@ ExtractVnodes(struct Msg *m, Volume *vol, afs_int32 class,
     if (class == vLarge) {
        if (*parent) {
            offset = (*parent + 1 - class) << (vcp->logSize -1);
-            code = STREAM_SEEK(stream, offset, 0);
+            code = STREAM_ASEEK(stream, offset);
            if (STREAM_READ(vnode, vcp->diskSize, 1, stream) == 1)
                memcpy(parentvd, vnode, vcp->diskSize);
            else
@@ -256,6 +256,7 @@ copyDir(struct Msg *m, IHandle_t *inh, IHandle_t *outh)
     FdHandle_t *infdP, *outfdP;
     char *tbuf;
     afs_sfsize_t size;
+    afs_foff_t offset;
 
     infdP = IH_OPEN(inh);
     if (!infdP) {
@@ -277,13 +278,12 @@ copyDir(struct Msg *m, IHandle_t *inh, IHandle_t *outh)
        return EIO;
     }
     tbuf = malloc(2048);
-    FDH_SEEK(infdP, 0, 0);
-    FDH_SEEK(outfdP, 0, 0);
+    offset = 0;
     size = FDH_SIZE(infdP);
     while (size) {
        size_t tlen;
         tlen = size > 2048 ? 2048 : size;
-        if (FDH_READ(infdP, tbuf, tlen) != tlen) {
+        if (FDH_PREAD(infdP, tbuf, tlen, offset) != tlen) {
                    sprintf(m->line, "Couldn't read directory %u.%u.%u\n",
                    infdP->fd_ih->ih_vid,
                    (afs_uint32)(infdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
@@ -294,7 +294,7 @@ copyDir(struct Msg *m, IHandle_t *inh, IHandle_t *outh)
            free(tbuf);
            return EIO;
        }
-       if (FDH_WRITE(outfdP, tbuf, tlen) != tlen) {
+       if (FDH_PWRITE(outfdP, tbuf, tlen, offset) != tlen) {
            sprintf(m->line, "Couldn't write directory %u.%u.%u\n",
                    outfdP->fd_ih->ih_vid,
                    (afs_uint32)(outfdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
@@ -306,6 +306,7 @@ copyDir(struct Msg *m, IHandle_t *inh, IHandle_t *outh)
            return EIO;
        }
        size -= tlen;
+       offset += tlen;
     }
     free(tbuf);
     FDH_CLOSE(outfdP);
@@ -351,8 +352,7 @@ afs_int32 copyVnodes(struct Msg *m, Volume *vol, Volume *newvol,
        if (e->flag) {
            afs_uint64 size;
            offset = (e->vN + 1 - class) << (vcp->logSize -1);
-           if (FDH_SEEK(fdP, offset, 0) != offset
-            || FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
+           if (FDH_PREAD(fdP, vnode, vcp->diskSize, offset) != vcp->diskSize) {
                Log("Couldn't read in %s Index of volume %u at offset %"
                    AFS_UINT64_FMT "\n", class ? "small":"large",
                    V_id(vol), offset);
@@ -384,8 +384,7 @@ afs_int32 copyVnodes(struct Msg *m, Volume *vol, Volume *newvol,
                /* Now update the vnode and write it back to disk */
                VNDISK_SET_INO(vnode, newino);
                vnode->cloned = 0;
-               if (FDH_SEEK(fdP, offset, 0) != offset
-                || FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
+               if (FDH_PWRITE(fdP, vnode, vcp->diskSize, offset) != vcp->diskSize) {
                    Log("Couldn't write in %s Index of volume %u at offset %"
                        AFS_UINT64_FMT "\n", class ? "small":"large",
                        V_id(vol), offset);
@@ -432,8 +431,7 @@ afs_int32 copyVnodes(struct Msg *m, Volume *vol, Volume *newvol,
                if (e->flag & CHANGEPARENT)
                    vnode->parent = 1; /* in new root-directory */
                vnode->cloned = 0;
-               if (FDH_SEEK(newfdP, offset, 0) != offset
-                || FDH_WRITE(newfdP, vnode, vcp->diskSize) != vcp->diskSize) {
+               if (FDH_PWRITE(newfdP, vnode, vcp->diskSize, offset) != vcp->diskSize) {
                    Log("Couldn't write in %s Index of volume %u to offset %"
                        AFS_UINT64_FMT "\n", class ? "small":"large",
                        V_id(newvol), offset);
@@ -453,16 +451,14 @@ afs_int32 copyVnodes(struct Msg *m, Volume *vol, Volume *newvol,
        afs_uint64 newoffset;
 
        newoffset = vcp->diskSize;
-       if (FDH_SEEK(newfdP, newoffset, 0) != newoffset
-        || FDH_READ(newfdP, vnode2, vcp->diskSize) != vcp->diskSize) {
+       if (FDH_PREAD(newfdP, vnode2, vcp->diskSize, newoffset) != vcp->diskSize) {
            Log("splitvolume: couldn't read in large Index of new volume %u at offset %u\n",
                    V_id(newvol), vcp->diskSize);
            code = EIO;
            goto Bad_Copy;
        }
        offset = (where + 1 - class) << (vcp->logSize -1);
-       if (FDH_SEEK(fdP, offset, 0) != offset
-        || FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
+       if (FDH_PREAD(fdP, vnode, vcp->diskSize, offset) != vcp->diskSize) {
            Log("Couldn't read in large Index of old volume %u at offset %"
                AFS_UINT64_FMT "\n", V_id(vol), offset);
            code = EIO;
@@ -487,8 +483,7 @@ afs_int32 copyVnodes(struct Msg *m, Volume *vol, Volume *newvol,
        vnode->cloned = 0;
        vnode->parent = vnode2->parent;
        vnode->serverModifyTime = vnode2->serverModifyTime;
-       if (FDH_SEEK(newfdP, newoffset, 0) != newoffset
-         || FDH_WRITE(newfdP, vnode, vcp->diskSize) != vcp->diskSize) {
+       if (FDH_PWRITE(newfdP, vnode, vcp->diskSize, newoffset) != vcp->diskSize) {
            Log("splitvolume: couldn't write in large Index of %u at offset %u\n",
                    V_id(newvol), vcp->diskSize);
            code = EIO;
@@ -539,6 +534,7 @@ createMountpoint(Volume *vol, Volume *newvol, struct VnodeDiskObject *parent,
     struct timeval now;
     afs_uint32 newvN;
     char symlink[32];
+    ssize_t rc;
 
     FT_GetTimeOfDay(&now, 0);
     fdP = IH_OPEN(vol->vnodeIndex[vSmall].handle);
@@ -547,13 +543,18 @@ createMountpoint(Volume *vol, Volume *newvol, struct VnodeDiskObject *parent,
        return EIO;
     }
     offset = vcp->diskSize;
-    if (FDH_SEEK(fdP, offset, 0) != offset) {
-       Log("split volume: error seeking in small vnode index of %u\n", V_id(vol));
-       return EIO;
-    }
     while (1) {
-       if (FDH_READ(fdP, &vnode, vcp->diskSize) != vcp->diskSize)
-           break;
+       rc = FDH_PREAD(fdP, &vnode, vcp->diskSize, offset);
+       if (rc != vcp->diskSize) {
+           if (rc < 0) {
+               Log("split volume: error reading small vnode index of %u\n", V_id(vol));
+               return EIO;
+            }
+            if (rc == 0)
+                break;
+            if (rc < vcp->diskSize)
+                break;
+       }
        if (vnode.type == vNull)
            break;
        offset += vcp->diskSize;
@@ -587,10 +588,9 @@ createMountpoint(Volume *vol, Volume *newvol, struct VnodeDiskObject *parent,
                V_id(vol), newvN, vnode.uniquifier);
        return EIO;
     }
-    FDH_SEEK(fdP2, 0, 0);
     sprintf(symlink, "#%s", V_name(newvol));
     size = strlen(symlink) + 1;
-    if (FDH_WRITE(fdP2, symlink, size) != size) {
+    if (FDH_PWRITE(fdP2, symlink, size, 0) != size) {
        Log("split volume: couldn't write mountpoint %u.%u.%u\n",
                V_id(vol), newvN, vnode.uniquifier);
        return EIO;
@@ -602,8 +602,7 @@ createMountpoint(Volume *vol, Volume *newvol, struct VnodeDiskObject *parent,
 #ifndef AFS_RXOSD_SUPPORT
     vnode.vnodeMagic = SMALLVNODEMAGIC;
 #endif
-    if (FDH_SEEK(fdP, offset, 0) != offset
-      || FDH_WRITE(fdP, &vnode, vcp->diskSize) != vcp->diskSize) {
+    if (FDH_PWRITE(fdP, &vnode, vcp->diskSize, offset) != vcp->diskSize) {
        Log("split volume: couldn't write vnode for mountpoint %u.%u.%u\n",
                V_id(vol), newvN, vnode.uniquifier);
        return EIO;
@@ -635,8 +634,7 @@ createMountpoint(Volume *vol, Volume *newvol, struct VnodeDiskObject *parent,
     fdP = IH_OPEN(vol->vnodeIndex[class].handle);
     offset = (vN + 1 - class) << (vcp->logSize -1);
     parent->dataVersion++;
-    if (FDH_SEEK(fdP, offset, 0) != offset
-      || FDH_WRITE(fdP, parent, vcp->diskSize) != vcp->diskSize) {
+    if (FDH_PWRITE(fdP, parent, vcp->diskSize, offset) != vcp->diskSize) {
        Log("split volume: couldn't write vnode for parent directory %u.%u.%u\n",
                V_id(vol), vN, parent->uniquifier);
        return EIO;
@@ -674,14 +672,7 @@ deleteVnodes(Volume *vol, afs_int32 class,
        if (e->flag & NEEDED) {
            afs_uint64 size;
            offset = (e->vN + 1 - class) << (vcp->logSize -1);
-           if (FDH_SEEK(fdP, offset, 0) != offset) {
-               Log("Couldn't seek in %s Index of volume %u to offset %"
-                   AFS_UINT64_FMT "\n", class ? "small":"large", V_id(vol),
-                   offset);
-               code = EIO;
-               goto Bad_Delete;
-           }
-           if (FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
+           if (FDH_PREAD(fdP, vnode, vcp->diskSize, offset) != vcp->diskSize) {
                Log("Couldn't read in %s Index of volume %u at offset %"
                    AFS_UINT64_FMT "\n", class ? "small":"large", V_id(vol),
                    offset);
@@ -702,8 +693,7 @@ deleteVnodes(Volume *vol, afs_int32 class,
            }
            memset(vnode, 0, vcp->diskSize);
            vnode->type = vNull;
-           if (FDH_SEEK(fdP, offset, 0) != offset
-             || FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
+           if (FDH_PWRITE(fdP, vnode, vcp->diskSize, offset) != vcp->diskSize) {
                   Log("Couldn't write in %s Index of volume %u to offset %"
                       AFS_UINT64_FMT "\n", class ? "small":"large",
                       V_id(vol), offset);
index a371da5..59e8490 100644 (file)
@@ -337,7 +337,6 @@ ViceCreateRoot(Volume *vp)
     FdHandle_t *fdP;
     afs_fsize_t length;
     ssize_t nBytes;
-    afs_foff_t off;
 
     vnode = (struct VnodeDiskObject *)malloc(SIZEOF_LARGEDISKVNODE);
     if (!vnode)
@@ -397,9 +396,7 @@ ViceCreateRoot(Volume *vp)
            vp->vnodeIndex[vLarge].handle->ih_ino);
     fdP = IH_OPEN(h);
     assert(fdP != NULL);
-    off = FDH_SEEK(fdP, vnodeIndexOffset(vcp, 1), SEEK_SET);
-    assert(off >= 0);
-    nBytes = FDH_WRITE(fdP, vnode, SIZEOF_LARGEDISKVNODE);
+    nBytes = FDH_PWRITE(fdP, vnode, SIZEOF_LARGEDISKVNODE, vnodeIndexOffset(vcp, 1));
     assert(nBytes == SIZEOF_LARGEDISKVNODE);
     FDH_REALLYCLOSE(fdP);
     IH_RELEASE(h);