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);
/* 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;
}
}
fdP->fd_status = FD_HANDLE_INUSE;
fdP->fd_fd = fd;
fdP->fd_ih = ihP;
+ fdP->fd_refcnt++;
ihP->ih_refcnt++;
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.
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
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. */
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;
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;
streamP->str_eof = 1;
break;
}
+ streamP->str_fdoff += streamP->str_buflen;
}
bytesToRead = nbytes;
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;
}
/* 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;
}
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;
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) {
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++;
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 */