/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include <afsconfig.h>
#include <afs/param.h>
+#include <roken.h>
#include <stdio.h>
#include <sys/types.h>
#include "nfs.h"
#include "ihandle.h"
#include "viceinode.h"
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include "afs/assert.h"
-#endif /* AFS_PTHREAD_ENV */
+#include "afs/afs_assert.h"
#include <limits.h>
-#ifndef AFS_NT40_ENV
-#ifdef O_LARGEFILE
-#define afs_stat stat64
-#define afs_fstat fstat64
-#else /* !O_LARGEFILE */
-#define afs_stat stat
-#define afs_fstat fstat
-#endif /* !O_LARGEFILE */
-#endif /* AFS_NT40_ENV */
-
#ifdef AFS_PTHREAD_ENV
pthread_once_t ih_glock_once = PTHREAD_ONCE_INIT;
pthread_mutex_t ih_glock_mutex;
void
ih_glock_init(void)
{
- assert(pthread_mutex_init(&ih_glock_mutex, NULL) == 0);
+ MUTEX_INIT(&ih_glock_mutex, "ih glock", MUTEX_DEFAULT, 0);
}
#endif /* AFS_PTHREAD_ENV */
ih_Initialize(void)
{
int i;
- assert(!ih_Inited);
+ osi_Assert(!ih_Inited);
ih_Inited = 1;
DLL_INIT_LIST(ihAvailHead, ihAvailTail);
DLL_INIT_LIST(fdAvailHead, fdAvailTail);
#elif defined(AFS_SUN5_ENV) || defined(AFS_NBSD_ENV)
{
struct rlimit rlim;
- assert(getrlimit(RLIMIT_NOFILE, &rlim) == 0);
+ osi_Assert(getrlimit(RLIMIT_NOFILE, &rlim) == 0);
rlim.rlim_cur = rlim.rlim_max;
- assert(setrlimit(RLIMIT_NOFILE, &rlim) == 0);
+ osi_Assert(setrlimit(RLIMIT_NOFILE, &rlim) == 0);
fdMaxCacheSize = rlim.rlim_cur - vol_io_params.fd_handle_setaside;
#ifdef AFS_NBSD_ENV
/* XXX this is to avoid using up all system fd netbsd is
fdMaxCacheSize /= 4;
#endif
fdMaxCacheSize = MIN(fdMaxCacheSize, vol_io_params.fd_max_cachesize);
- assert(fdMaxCacheSize > 0);
+ osi_Assert(fdMaxCacheSize > 0);
}
#elif defined(AFS_HPUX_ENV)
/* Avoid problems with "UFSOpen: igetinode failed" panics on HPUX 11.0 */
int i;
IHandle_t *ihP;
- assert(ihAvailHead == NULL);
+ osi_Assert(ihAvailHead == NULL);
ihP = (IHandle_t *) malloc(I_HANDLE_MALLOCSIZE * sizeof(IHandle_t));
- assert(ihP != NULL);
+ osi_Assert(ihP != NULL);
for (i = 0; i < I_HANDLE_MALLOCSIZE; i++) {
ihP[i].ih_refcnt = 0;
DLL_INSERT_TAIL(&ihP[i], ihAvailHead, ihAvailTail, ih_next, ih_prev);
iHandleAllocateChunk();
}
ihP = ihAvailHead;
- assert(ihP->ih_refcnt == 0);
+ osi_Assert(ihP->ih_refcnt == 0);
DLL_DELETE(ihP, ihAvailHead, ihAvailTail, ih_next, ih_prev);
ihP->ih_dev = dev;
ihP->ih_vid = vid;
ih_copy(IHandle_t * ihP)
{
IH_LOCK;
- assert(ih_Inited);
- assert(ihP->ih_refcnt > 0);
+ osi_Assert(ih_Inited);
+ osi_Assert(ihP->ih_refcnt > 0);
ihP->ih_refcnt++;
IH_UNLOCK;
return ihP;
int i;
FdHandle_t *fdP;
- assert(fdAvailHead == NULL);
+ osi_Assert(fdAvailHead == NULL);
fdP = (FdHandle_t *) malloc(FD_HANDLE_MALLOCSIZE * sizeof(FdHandle_t));
- assert(fdP != NULL);
+ osi_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;
+ fdP[i].fd_ihnext = NULL;
+ fdP[i].fd_ihprev = NULL;
DLL_INSERT_TAIL(&fdP[i], fdAvailHead, fdAvailTail, fd_next, fd_prev);
}
}
int i;
StreamHandle_t *streamP;
- assert(streamAvailHead == NULL);
+ osi_Assert(streamAvailHead == NULL);
streamP = (StreamHandle_t *)
malloc(STREAM_HANDLE_MALLOCSIZE * sizeof(StreamHandle_t));
- assert(streamP != NULL);
+ osi_Assert(streamP != NULL);
for (i = 0; i < STREAM_HANDLE_MALLOCSIZE; i++) {
streamP[i].str_fd = INVALID_FD;
DLL_INSERT_TAIL(&streamP[i], streamAvailHead, streamAvailTail,
/* 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);
+ osi_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;
}
}
* of open files reaches the size of the cache */
if ((fdInUseCount > fdCacheSize || fd == INVALID_FD) && fdLruHead != NULL) {
fdP = fdLruHead;
- assert(fdP->fd_status == FD_HANDLE_OPEN);
+ osi_Assert(fdP->fd_status == FD_HANDLE_OPEN);
DLL_DELETE(fdP, fdLruHead, fdLruTail, fd_next, fd_prev);
DLL_DELETE(fdP, fdP->fd_ih->ih_fdhead, fdP->fd_ih->ih_fdtail,
fd_ihnext, fd_ihprev);
fdHandleAllocateChunk();
}
fdP = fdAvailHead;
- assert(fdP->fd_status == FD_HANDLE_AVAIL);
+ osi_Assert(fdP->fd_status == FD_HANDLE_AVAIL);
DLL_DELETE(fdP, fdAvailHead, fdAvailTail, fd_next, fd_prev);
closeFd = INVALID_FD;
}
fdP->fd_status = FD_HANDLE_INUSE;
fdP->fd_fd = fd;
fdP->fd_ih = ihP;
+ fdP->fd_refcnt++;
ihP->ih_refcnt++;
return 0;
IH_LOCK;
- assert(ih_Inited);
- assert(fdInUseCount > 0);
- assert(fdP->fd_status == FD_HANDLE_INUSE);
+ osi_Assert(ih_Inited);
+ osi_Assert(fdInUseCount > 0);
+ osi_Assert(fdP->fd_status == FD_HANDLE_INUSE);
ihP = fdP->fd_ih;
return fd_reallyclose(fdP);
}
- /* Put this descriptor back into the cache */
- fdP->fd_status = FD_HANDLE_OPEN;
- DLL_INSERT_TAIL(fdP, fdLruHead, fdLruTail, fd_next, fd_prev);
+ 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.
return 0;
IH_LOCK;
- assert(ih_Inited);
- assert(fdInUseCount > 0);
- assert(fdP->fd_status == FD_HANDLE_INUSE);
+ osi_Assert(ih_Inited);
+ osi_Assert(fdInUseCount > 0);
+ osi_Assert(fdP->fd_status == FD_HANDLE_INUSE);
ihP = fdP->fd_ih;
closeFd = fdP->fd_fd;
+ fdP->fd_refcnt--;
- DLL_DELETE(fdP, ihP->ih_fdhead, ihP->ih_fdtail, fd_ihnext, fd_ihprev);
- DLL_INSERT_TAIL(fdP, fdAvailHead, fdAvailTail, fd_next, fd_prev);
+ 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_ih = NULL;
- fdP->fd_fd = INVALID_FD;
+ 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;
}
- IH_UNLOCK;
- OS_CLOSE(closeFd);
- IH_LOCK;
- fdInUseCount -= 1;
+ 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;
} else if (strcmp(mode, "a+") == 0) {
fd = OS_OPEN(filename, O_RDWR | O_APPEND | O_CREAT, 0);
} else {
- assert(FALSE); /* not implemented */
+ osi_Assert(FALSE); /* not implemented */
}
if (fd == INVALID_FD) {
streamP->str_bufoff = 0;
streamP->str_buflen = 0;
} else {
- assert(streamP->str_direction == STREAM_DIRECTION_READ);
+ osi_Assert(streamP->str_direction == STREAM_DIRECTION_READ);
}
bytesRead = 0;
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;
streamP->str_bufoff = 0;
streamP->str_buflen = STREAM_HANDLE_BUFSIZE;
} else {
- assert(streamP->str_direction == STREAM_DIRECTION_WRITE);
+ osi_Assert(streamP->str_direction == STREAM_DIRECTION_WRITE);
}
nbytes = size * 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;
}
/* 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;
ssize_t rc;
int retval = 0;
- assert(streamP != NULL);
+ osi_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) {
int closeCount, closedAll;
FdHandle_t *fdP, *head, *tail, *next;
- assert(ihP->ih_refcnt > 0);
+ osi_Assert(ihP->ih_refcnt > 0);
closedAll = 1;
DLL_INIT_LIST(head, tail);
*/
for (fdP = ihP->ih_fdhead; fdP != NULL; fdP = next) {
next = fdP->fd_ihnext;
- assert(fdP->fd_ih == ihP);
- assert(fdP->fd_status == FD_HANDLE_OPEN
+ osi_Assert(fdP->fd_ih == ihP);
+ osi_Assert(fdP->fd_status == FD_HANDLE_OPEN
|| fdP->fd_status == FD_HANDLE_INUSE);
if (fdP->fd_status == FD_HANDLE_OPEN) {
DLL_DELETE(fdP, ihP->ih_fdhead, ihP->ih_fdtail, fd_ihnext,
* closed all file descriptors.
*/
if (ihP->ih_refcnt == 1 || closedAll) {
- assert(closedAll);
- assert(!ihP->ih_fdhead);
- assert(!ihP->ih_fdtail);
+ osi_Assert(closedAll);
+ osi_Assert(!ihP->ih_fdhead);
+ osi_Assert(!ihP->ih_fdtail);
}
if (head == NULL) {
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++;
}
IH_LOCK;
- assert(fdInUseCount >= closeCount);
+ osi_Assert(fdInUseCount >= closeCount);
fdInUseCount -= closeCount;
/*
ihP->ih_refcnt++; /* must not disappear over unlock */
if (ihP->ih_synced) {
FdHandle_t *fdP;
+ ihP->ih_synced = 0;
IH_UNLOCK;
-
+
fdP = IH_OPEN(ihP);
- if (fdP) {
+ if (fdP) {
OS_SYNC(fdP->fd_fd);
FDH_CLOSE(fdP);
}
-
+
IH_LOCK;
}
- assert(ihP->ih_refcnt > 0);
- ihP->ih_synced = 0;
+ osi_Assert(ihP->ih_refcnt > 0);
ih_fdclose(ihP);
return 0;
IH_LOCK;
- assert(ihP->ih_refcnt > 0);
+ osi_Assert(ihP->ih_refcnt > 0);
if (ihP->ih_refcnt > 1) {
ihP->ih_refcnt--;
if (ihP)
ihP->ih_refcnt++; /* must not disappear over unlock */
for (; ihP; ihP = ihPnext) {
-
+
if (ihP->ih_synced) {
FdHandle_t *fdP;
IH_UNLOCK;
fdP = IH_OPEN(ihP);
- if (fdP) {
+ if (fdP) {
OS_SYNC(fdP->fd_fd);
FDH_CLOSE(fdP);
}
}
#endif /* AFS_NAMEI_ENV */
-
-#ifndef AFS_NT40_ENV
afs_sfsize_t
-ih_size(int fd)
+ih_size(FD_t fd)
{
- struct afs_stat status;
+#ifdef AFS_NT40_ENV
+ LARGE_INTEGER size;
+ if (!GetFileSizeEx(fd, &size))
+ return -1;
+ return size.QuadPart;
+#else
+ struct afs_stat_st status;
if (afs_fstat(fd, &status) < 0)
return -1;
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 */