/*
* 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
* pass the elements required to identify a file to the underlying file
* systen. For the usual Vice inode operations, this is no more than the
* usual device and inode numbers. For the user space file system used on NT
- * we also need the volume id to identify the file.
+ * we also need the volume id to identify the file.
*
* An FdHandle_t is an abstraction used to associate file descroptors
* with Inode handles. IH_OPEN is used to get a file descriptor that
* cached by IO_CLOSE. To make sure a file descriptor is really closed call
* IH_REALLYCLOSE.
*
+ * Note that IH_REALLYCLOSE does not guarantee that all file descriptors are
+ * closed (or are marked as needing close) by the time it returns, in the case
+ * of an IH_OPEN being executed in parallel. If a separate thread is running
+ * an IH_OPEN on the same IHandle_t at around the same time, it is possible for
+ * it to open the file, then IH_REALLYCLOSE runs, and then IH_OPEN associates
+ * the file handle with the IHandle_t. For this reason, it is probably an
+ * error if it is ever possible to have an IH_OPEN call run at the same time as
+ * an IH_REALLYCLOSE call on the same IHandle_t. If such functionality is
+ * required, ihandle must be changed to accomodate this.
+ *
* The IHandle_t also provides a place to do other optimizations. In the
* NT user space file system, we keep a separate special file for the
* link counts and using the IHandle_t allows keeping the details of
* FDH_REALLYCLOSE - Close a file descriptor, do not return to the cache
* FDH_SYNC - Unconditionally sync an open file.
* FDH_TRUNC - Truncate a file
+ * FDH_LOCKFILE - Lock a whole file
+ * FDH_UNLOCKFILE - Unlock a whole file
*
* status information:
* FDH_SIZE - returns the size of the file.
* FDH_NLINK - returns the link count of the file.
+ * FDH_ISUNLINKED - returns if the file has been unlinked out from under us
*
* Miscellaneous:
* FDH_FDOPEN - create a descriptor for buffered I/O
#define _IHANDLE_H_
#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#include <pthread.h>
+# include <pthread.h>
extern pthread_once_t ih_glock_once;
extern pthread_mutex_t ih_glock_mutex;
extern void ih_glock_init(void);
-#define IH_LOCK \
- assert(pthread_once(&ih_glock_once, ih_glock_init) == 0 && \
- pthread_mutex_lock(&ih_glock_mutex) == 0)
-#define IH_UNLOCK \
- assert(pthread_mutex_unlock(&ih_glock_mutex) == 0)
+# define IH_LOCK \
+ do { opr_Verify(pthread_once(&ih_glock_once, ih_glock_init) == 0); \
+ opr_mutex_enter(&ih_glock_mutex); \
+ } while (0)
+# define IH_UNLOCK opr_mutex_exit(&ih_glock_mutex)
#else /* AFS_PTHREAD_ENV */
-#define IH_LOCK
-#define IH_UNLOCK
+# define IH_LOCK
+# define IH_UNLOCK
#endif /* AFS_PTHREAD_ENV */
#ifndef DLL_INIT_LIST
/*
* Macro to initialize a doubly linked list, lifted from Encina
*/
-#define DLL_INIT_LIST(head, tail) \
+# define DLL_INIT_LIST(head, tail) \
do { \
(head) = NULL; \
(tail) = NULL; \
/*
* Macro to remove an element from a doubly linked list
*/
-#define DLL_DELETE(ptr,head,tail,next,prev) \
+# define DLL_DELETE(ptr,head,tail,next,prev) \
do { \
if ((ptr)->next) \
(ptr)->next->prev = (ptr)->prev; \
else \
(head) = (ptr)->next; \
(ptr)->next = (ptr)->prev = NULL; \
- assert(!(head) || !((head)->prev)); \
+ opr_Assert(!(head) || !((head)->prev)); \
} while(0)
/*
* Macro to insert an element at the tail of a doubly linked list
*/
-#define DLL_INSERT_TAIL(ptr,head,tail,next,prev) \
+# define DLL_INSERT_TAIL(ptr,head,tail,next,prev) \
do { \
(ptr)->next = NULL; \
(ptr)->prev = (tail); \
(ptr)->prev->next = (ptr); \
else \
(head) = (ptr); \
- assert((head) && ((head)->prev == NULL)); \
+ opr_Assert((head) && ((head)->prev == NULL)); \
} while(0)
#endif /* DLL_INIT_LIST */
#ifdef AFS_NT40_ENV
typedef __int64 Inode;
#else
-#include <afs/afssyscalls.h>
+# include <afs/afssyscalls.h>
#endif
/* The dir package's page hashing function is dependent upon the layout of
*/
#ifdef AFS_NT40_ENV
typedef HANDLE FD_t;
+# define INVALID_FD INVALID_HANDLE_VALUE
#else
typedef int FD_t;
+# define INVALID_FD ((FD_t)-1)
#endif
-#define INVALID_FD ((FD_t)-1)
/* 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 */
#define FD_HANDLE_AVAIL 1 /* handle is not open and available */
#define FD_HANDLE_OPEN 2 /* handle is open and not in use */
#define FD_HANDLE_INUSE 3 /* handle is open and in use */
+#define FD_HANDLE_CLOSING 4 /* handle is open, in use, and has been
+ * IH_REALLYCLOSE'd. It should not be
+ * used for subsequent opens. */
/* buffered file descriptor handle */
#define STREAM_HANDLE_BUFSIZE 2048 /* buffer size for STR_READ/STR_WRITE */
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 */
#define FD_HANDLE_MALLOCSIZE ((size_t)((4096/sizeof(FdHandle_t))))
#define STREAM_HANDLE_MALLOCSIZE 1
+/* Possible values for the vol_io_params.sync_behavior option.
+ * These dictate what actually happens when you call FDH_SYNC or IH_CONDSYNC. */
+#define IH_SYNC_ALWAYS (1) /* This makes FDH_SYNCs do what you'd probably
+ * expect: a synchronous fsync() */
+#define IH_SYNC_ONCLOSE (2) /* This makes FDH_SYNCs just flag the ih as "I
+ * need to sync", and does not perform the actual
+ * fsync() until we IH_REALLYCLOSE. This provides a
+ * little assurance over IH_SYNC_NEVER when a volume
+ * has gone offline, and a few other situations. */
+#define IH_SYNC_NEVER (3) /* This makes FDH_SYNCs do nothing. Faster, but
+ * obviously less durable. The OS may ensure that
+ * our data hits the disk eventually, depending on
+ * the platform and various OS-specific tuning
+ * parameters. */
+
+
+/* READ THIS.
+ *
+ * On modern platforms tuned for I/O intensive workloads, there may be
+ * thousands of file descriptors available (64K on 32-bit Solaris 7,
+ * for example), and threading in Solaris 9 and Linux 2.6 (NPTL) are
+ * tuned for (many) thousands of concurrent threads at peak.
+ *
+ * On these platforms, it makes sense to allow administrators to set
+ * appropriate limits for their hardware. Clients may now set desired
+ * values in the exported vol_io_params, of type ih_init_params.
+ */
+
+typedef struct ih_init_params
+{
+ afs_uint32 fd_handle_setaside; /* for non-cached i/o, trad. was 128 */
+ afs_uint32 fd_initial_cachesize; /* what was 'default' */
+ afs_uint32 fd_max_cachesize; /* max open files if large-cache activated */
+
+ int sync_behavior; /* one of the IH_SYNC_* constants */
+} ih_init_params;
+
/* Number of file descriptors needed for non-cached I/O */
#define FD_HANDLE_SETASIDE 128 /* Match to MAX_FILESERVER_THREAD */
+/* Which systems have 8-bit fileno? On GNU/Linux systems, the
+ * fileno member of FILE is an int. On NetBSD 5, it's a short.
+ * Ditto for OpenBSD 4.5. Through Solaris 10 8/07 it's unsigned char.
+ */
+
/* Don't try to have more than 256 files open at once if you are planning
* to use fopen or fdopen. The FILE structure has an eight bit field for
* the file descriptor. */
*/
#define FD_MAX_CACHESIZE (2000 - FD_HANDLE_SETASIDE)
+/* On modern platforms, this is sized higher than the note implies.
+ * For HP, see http://forums11.itrc.hp.com/service/forums/questionanswer.do?admit=109447626+1242508538748+28353475&threadId=302950
+ * On AIX, it's said to be self-tuning (sar -v)
+ * On Solaris, http://www.princeton.edu/~unix/Solaris/troubleshoot/kerntune.html
+ * says stdio limit (FILE) may exist, but then backtracks and says the 64bit
+ * solaris and POLL (rather than select) io avoid the issue. Solaris Internals
+ * states that Solaris 7 and above deal with up to 64K on 32bit.
+ * However, extended FILE must be enabled to use this. See
+ * enable_extended_FILE_stdio(3C)
+ */
+
/* Inode handle */
typedef struct IHandle_s {
- afs_uint32 ih_vid; /* Parent volume id. */
+ VolumeId ih_vid; /* Parent volume id. */
int ih_dev; /* device id. */
int ih_flags; /* Flags */
int ih_synced; /* should be synced next time */
#define IH_REALLY_CLOSED 1
/* Hash function for inode handles */
-#define I_HANDLE_HASH_SIZE 1024 /* power of 2 */
+#define I_HANDLE_HASH_SIZE 2048 /* power of 2 */
+
/* The casts to int's ensure NT gets the xor operation correct. */
#define IH_HASH(D, V, I) ((int)(((D)^(V)^((int)(I)))&(I_HANDLE_HASH_SIZE-1)))
/* Prototypes for handle support routines. */
#ifdef AFS_NAMEI_ENV
-#ifdef AFS_NT40_ENV
-#include "ntops.h"
-#else
-#include "namei_ops.h"
-#endif
+# ifdef AFS_NT40_ENV
+# include "ntops.h"
+# endif
+# include "namei_ops.h"
+
extern void ih_clear(IHandle_t * h);
extern Inode ih_create(IHandle_t * h, int dev, char *part, Inode nI, int p1,
int p2, int p3, int p4);
-extern FILE *ih_fdopen(FdHandle_t * h, char *fdperms);
+extern FD_t *ih_fdopen(FdHandle_t * h, char *fdperms);
#endif /* AFS_NAMEI_ENV */
/*
* Prototypes for file descriptor cache routines
*/
+extern void ih_PkgDefaults(void);
extern void ih_Initialize(void);
extern void ih_UseLargeCache(void);
+extern int ih_SetSyncBehavior(const char *behavior);
extern IHandle_t *ih_init(int /*@alt Device@ */ dev, int /*@alt VolId@ */ vid,
Inode ino);
extern IHandle_t *ih_copy(IHandle_t * ihP);
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);
extern int ih_release(IHandle_t * ihP);
extern int ih_condsync(IHandle_t * ihP);
+extern FdHandle_t *ih_attachfd(IHandle_t * ihP, FD_t fd);
/* Macros common to user space and inode API's. */
#define IH_INIT(H, D, V, I) ((H) = ih_init((D), (V), (I)))
#define IH_OPEN(H) ih_open(H)
-#define FDH_CLOSE(H) (fd_close(H), (H)=NULL, 0)
+#define FDH_CLOSE(H) (fd_close(H), (H)=NULL)
-#define FDH_REALLYCLOSE(H) (fd_reallyclose(H), (H)=NULL, 0)
+#define FDH_REALLYCLOSE(H) (fd_reallyclose(H), (H)=NULL)
#define FDH_FDOPEN(H, A) stream_fdopen((H)->fd_fd)
#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)
#define STREAM_REALLYCLOSE(H) stream_close(H, 1)
-#define IH_RELEASE(H) (ih_release(H), (H)=NULL, 0)
+#define IH_RELEASE(H) (ih_release(H), (H)=NULL)
#define IH_REALLYCLOSE(H) ih_reallyclose(H)
#define IH_CONDSYNC(H) ih_condsync(H)
-#ifdef AFS_NAMEI_ENV
+#ifdef HAVE_PIO
+# define AFS_IHANDLE_PIO_ENV 1
+# 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 */
+#elif defined(AFS_NT40_ENV)
+# define AFS_IHANDLE_PIO_ENV 1
+# define OS_PREAD(FD, B, S, O) nt_pread(FD, B, S, O)
+# define OS_PWRITE(FD, B, S, O) nt_pwrite(FD, B, S, O)
+#else
+extern ssize_t ih_pread(FD_t fd, void * buf, size_t count, afs_foff_t offset);
+extern ssize_t ih_pwrite(FD_t 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
#ifdef AFS_NT40_ENV
-#define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
- nt_icreate(H, P, P1, P2, P3, P4)
+# define OS_LOCKFILE(FD, O) (!LockFile(FD, (DWORD)((O) & 0xFFFFFFFF), (DWORD)((O) >> 32), 2, 0))
+# define OS_UNLOCKFILE(FD, O) (!UnlockFile(FD, (DWORD)((O) & 0xFFFFFFFF), (DWORD)((O) >> 32), 2, 0))
+# define OS_ERROR(X) nterr_nt2unix(GetLastError(), X)
+# define OS_UNLINK(X) nt_unlink(X)
+/* we can't have a file unlinked out from under us on NT */
+# define OS_ISUNLINKED(X) (0)
+# define OS_DIRSEP "\\"
+# define OS_DIRSEPC '\\'
+#else
+# define OS_LOCKFILE(FD, O) flock(FD, LOCK_EX)
+# define OS_UNLOCKFILE(FD, O) flock(FD, LOCK_UN)
+# define OS_ERROR(X) X
+# define OS_UNLINK(X) unlink(X)
+# define OS_ISUNLINKED(X) ih_isunlinked(X)
+extern int ih_isunlinked(FD_t fd);
+# define OS_DIRSEP "/"
+# define OS_DIRSEPC '/'
+#endif
-#define OS_IOPEN(H) nt_iopen(H)
-#define OS_OPEN(F, M, P) nt_open(F, M, P)
-#define OS_CLOSE(FD) nt_close(FD)
+#if defined(AFS_NT40_ENV) || !defined(AFS_NAMEI_ENV)
+# define IH_CREATE_INIT(H, D, P, N, P1, P2, P3, P4) \
+ ih_icreate_init(H, D, P, N, P1, P2, P3, P4)
+#endif
-#define OS_READ(FD, B, S) nt_read(FD, B, S)
-#define OS_WRITE(FD, B, S) nt_write(FD, B, S)
-#define OS_SEEK(FD, O, F) nt_seek(FD, O, F)
+#ifdef AFS_NAMEI_ENV
-#define OS_SYNC(FD) nt_fsync(FD)
-#define OS_TRUNC(FD, L) nt_ftruncate(FD, L)
-#define OS_SIZE(FD) nt_size(FD)
+# ifdef AFS_NT40_ENV
+# define OS_OPEN(F, M, P) nt_open(F, M, P)
+# define OS_CLOSE(FD) nt_close(FD)
-#define IH_INC(H, I, P) nt_inc(H, I, P)
-#define IH_DEC(H, I, P) nt_dec(H, I, P)
-#define IH_IREAD(H, O, B, S) nt_iread(H, O, B, S)
-#define IH_IWRITE(H, O, B, S) nt_iwrite(H, O, B, S)
+# define OS_READ(FD, B, S) nt_read(FD, B, S)
+# define OS_WRITE(FD, B, S) nt_write(FD, B, S)
+# define OS_SEEK(FD, O, F) nt_seek(FD, O, F)
-#else /* AFS_NT40_ENV */
+# define OS_SYNC(FD) nt_fsync(FD)
+# define OS_TRUNC(FD, L) nt_ftruncate(FD, L)
+
+# else /* AFS_NT40_ENV */
/*@+fcnmacros +macrofcndecl@*/
-#ifdef S_SPLINT_S
+# ifdef S_SPLINT_S
extern Inode IH_CREATE(IHandle_t * H, int /*@alt Device @ */ D,
char *P, Inode N, int /*@alt VolumeId @ */ P1,
int /*@alt VnodeId @ */ P2,
int /*@alt unsigned @ */ P4);
extern FD_t OS_IOPEN(IHandle_t * H);
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 int OS_SYNC(int FD);
-extern afs_sfsize_t OS_SIZE(int FD);
+extern int OS_CLOSE(FD_t FD);
+extern ssize_t OS_READ(FD_t FD, void *B, size_t S);
+extern ssize_t OS_WRITE(FD_t FD, void *B, size_t S);
+extern ssize_t OS_PREAD(FD_t FD, void *B, size_t S, afs_foff_t O);
+extern ssize_t OS_PWRITE(FD_t FD, void *B, size_t S, afs_foff_t O);
+extern int OS_SYNC(FD_t FD);
+extern afs_sfsize_t OS_SIZE(FD_t FD);
extern int IH_INC(IHandle_t * H, Inode I, int /*@alt VolId, VolumeId @ */ P);
extern int IH_DEC(IHandle_t * H, Inode I, int /*@alt VolId, VolumeId @ */ P);
extern afs_sfsize_t IH_IREAD(IHandle_t * H, afs_foff_t O, void *B,
afs_fsize_t S);
extern afs_sfsize_t IH_IWRITE(IHandle_t * H, afs_foff_t O, void *B,
afs_fsize_t S);
-#ifdef O_LARGEFILE
-extern off64_t OS_SEEK(int FD, off64_t O, int F);
-extern int OS_TRUNC(int FD, off64_t L);
-#else /* !O_LARGEFILE */
-extern off_t OS_SEEK(int FD, off_t O, int F);
-extern int OS_TRUNC(int FD, off_t L);
-#endif /* !O_LARGEFILE */
-#endif /*S_SPLINT_S */
-
-#define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
- namei_icreate(H, P, P1, P2, P3, P4)
-
-#define OS_IOPEN(H) namei_iopen(H)
-#ifdef O_LARGEFILE
-#define OS_OPEN(F, M, P) open64(F, M, P)
-#else /* !O_LARGEFILE */
-#define OS_OPEN(F, M, P) open(F, M, P)
-#endif /* !O_LARGEFILE */
-#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 */
-#define OS_SEEK(FD, O, F) lseek(FD, (off_t) (O), F)
-#endif /* !O_LARGEFILE */
-
-#define OS_SYNC(FD) fsync(FD)
-#ifdef O_LARGEFILE
-#define OS_TRUNC(FD, L) ftruncate64(FD, (off64_t) (L))
-#else /* !O_LARGEFILE */
-#define OS_TRUNC(FD, L) ftruncate(FD, (off_t) (L))
-#endif /* !O_LARGEFILE */
-#define OS_SIZE(FD) ih_size(FD)
-extern afs_sfsize_t ih_size(int fd);
+# ifdef O_LARGEFILE
+# define OFFT off64_t
+# else
+# define OFFT off_t
+# endif
+
+extern OFFT OS_SEEK(FD_t FD, OFFT O, int F);
+extern int OS_TRUNC(FD_t FD, OFFT L);
+# endif /*S_SPLINT_S */
+
+# ifdef O_LARGEFILE
+# define OS_OPEN(F, M, P) open64(F, M, P)
+# else /* !O_LARGEFILE */
+# define OS_OPEN(F, M, P) open(F, M, P)
+# endif /* !O_LARGEFILE */
+# 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)
+# define OS_TRUNC(FD, L) ftruncate64(FD, (off64_t) (L))
+# else /* !O_LARGEFILE */
+# define OS_SEEK(FD, O, F) lseek(FD, (off_t) (O), F)
+# define OS_TRUNC(FD, L) ftruncate(FD, (off_t) (L))
+# endif /* !O_LARGEFILE */
+
+# define OS_SYNC(FD) fsync(FD)
+# define IH_CREATE_INIT(H, D, P, N, P1, P2, P3, P4) \
+ namei_icreate_init(H, D, P, P1, P2, P3, P4)
-#define IH_INC(H, I, P) namei_inc(H, I, P)
-#define IH_DEC(H, I, P) namei_dec(H, I, P)
-#define IH_IREAD(H, O, B, S) namei_iread(H, O, B, S)
-#define IH_IWRITE(H, O, B, S) namei_iwrite(H, O, B, S)
/*@=fcnmacros =macrofcndecl@*/
-#endif /* AFS_NT40_ENV */
+# endif /* AFS_NT40_ENV */
+# define IH_INC(H, I, P) namei_inc(H, I, P)
+# define IH_DEC(H, I, P) namei_dec(H, I, P)
+# define IH_IREAD(H, O, B, S) namei_iread(H, O, B, S)
+# define IH_IWRITE(H, O, B, S) namei_iwrite(H, O, B, S)
+# define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
+ namei_icreate(H, P, P1, P2, P3, P4)
+# define OS_IOPEN(H) namei_iopen(H)
+
#else /* AFS_NAMEI_ENV */
extern Inode ih_icreate(IHandle_t * ih, int dev, char *part, Inode nI, int p1,
int p2, int p3, int p4);
-#define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
- ih_icreate(H, D, P, N, P1, P2, P3, P4)
-
-#ifdef AFS_LINUX22_ENV
-#define OS_IOPEN(H) -1
-#else
-#ifdef O_LARGEFILE
-#define OS_IOPEN(H) (IOPEN((H)->ih_dev, (H)->ih_ino, O_RDWR|O_LARGEFILE))
-#else
-#define OS_IOPEN(H) (IOPEN((H)->ih_dev, (H)->ih_ino, O_RDWR))
-#endif
-#endif
-#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 */
-#define OS_SEEK(FD, O, F) lseek(FD, (off_t) (O), F)
-#endif /* !O_LARGEFILE */
-
-#define OS_SYNC(FD) fsync(FD)
-#ifdef O_LARGEFILE
-#define OS_TRUNC(FD, L) ftruncate64(FD, (off64_t) (L))
-#else /* !O_LARGEFILE */
-#define OS_TRUNC(FD, L) ftruncate(FD, (off_t) (L))
-#endif /* !O_LARGEFILE */
-#define OS_SIZE(FD) ih_size(FD)
-extern afs_sfsize_t ih_size(int fd);
-
-#ifdef AFS_LINUX22_ENV
-#define IH_INC(H, I, P) -1
-#define IH_DEC(H, I, P) -1
-#define IH_IREAD(H, O, B, S) -1
-#define IH_IWRITE(H, O, B, S) -1
-#else
-#define IH_INC(H, I, P) IINC((H)->ih_dev, I, P)
-#define IH_DEC(H, I, P) IDEC((H)->ih_dev, I, P)
-#define IH_IREAD(H, O, B, S) inode_read((H)->ih_dev, (H)->ih_ino, (H)->ih_vid,\
- O, B, S)
-#define IH_IWRITE(H, O, B, S) \
- inode_write((H)->ih_dev, (H)->ih_ino, (H)->ih_vid, O, B, S)
-#endif /* AFS_LINUX22_ENV */
-
+# define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
+ ih_icreate(H, D, P, N, P1, P2, P3, P4)
+
+# ifdef AFS_LINUX22_ENV
+# define OS_IOPEN(H) -1
+# else
+# ifdef O_LARGEFILE
+# define OS_IOPEN(H) (IOPEN((H)->ih_dev, (H)->ih_ino, O_RDWR|O_LARGEFILE))
+# else
+# define OS_IOPEN(H) (IOPEN((H)->ih_dev, (H)->ih_ino, O_RDWR))
+# endif
+# endif
+# 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)
+# define OS_TRUNC(FD, L) ftruncate64(FD, (off64_t) (L))
+# else /* !O_LARGEFILE */
+# define OS_SEEK(FD, O, F) lseek(FD, (off_t) (O), F)
+# define OS_TRUNC(FD, L) ftruncate(FD, (off_t) (L))
+# endif /* !O_LARGEFILE */
+
+# define OS_SYNC(FD) fsync(FD)
+
+# ifdef AFS_LINUX22_ENV
+# define IH_INC(H, I, P) -1
+# define IH_DEC(H, I, P) -1
+# define IH_IREAD(H, O, B, S) -1
+# define IH_IWRITE(H, O, B, S) -1
+# else
+# define IH_INC(H, I, P) IINC((H)->ih_dev, I, P)
+# define IH_DEC(H, I, P) IDEC((H)->ih_dev, I, P)
+# define IH_IREAD(H, O, B, S) inode_read((H)->ih_dev, (H)->ih_ino, (H)->ih_vid,\
+ O, B, S)
+# define IH_IWRITE(H, O, B, S) \
+ inode_write((H)->ih_dev, (H)->ih_ino, (H)->ih_vid, O, B, S)
+# endif /* AFS_LINUX22_ENV */
#endif /* AFS_NAMEI_ENV */
+#define OS_SIZE(FD) ih_size(FD)
+extern afs_sfsize_t ih_size(FD_t);
+
#ifndef AFS_NT40_ENV
-#define FDH_READV(H, I, N) readv((H)->fd_fd, I, N)
-#define FDH_WRITEV(H, I, N) writev((H)->fd_fd, I, N)
+# define FDH_READV(H, I, N) readv((H)->fd_fd, I, N)
+# define FDH_WRITEV(H, I, N) writev((H)->fd_fd, I, N)
#endif
+#ifdef HAVE_PIOV
+# ifdef O_LARGEFILE
+# define FDH_PREADV(H, I, N, O) preadv64((H)->fd_fd, I, N, O)
+# define FDH_PWRITEV(H, I, N, O) pwritev64((H)->fd_fd, I, N, O)
+# else /* !O_LARGEFILE */
+# 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 /* !O_LARGEFILE */
+#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)
-#define FDH_SYNC(H) ((H->fd_ih!=NULL) ? ( H->fd_ih->ih_synced = 1) - 1 : 1)
+#define FDH_SYNC(H) ih_fdsync(H)
#define FDH_TRUNC(H, L) OS_TRUNC((H)->fd_fd, L)
#define FDH_SIZE(H) OS_SIZE((H)->fd_fd)
+#define FDH_LOCKFILE(H, O) OS_LOCKFILE((H)->fd_fd, O)
+#define FDH_UNLOCKFILE(H, O) OS_UNLOCKFILE((H)->fd_fd, O)
+#define FDH_ISUNLINKED(H) OS_ISUNLINKED((H)->fd_fd)
+
+extern int ih_fdsync(FdHandle_t *fdP);
+
+#ifdef AFS_NT40_ENV
+# define afs_stat_st __stat64
+# define afs_stat _stat64
+# define afs_fstat _fstat64
+# define afs_fopen fopen
+# define afs_open open
+# define afs_lseek(FD, O, F) _lseeki64(FD, O, F)
+#else /* AFS_NT40_ENV */
+# ifdef O_LARGEFILE
+# define afs_stat_st stat64
+# define afs_stat stat64
+# define afs_fstat fstat64
+# define afs_fopen fopen64
+# define afs_open open64
+# 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_ftruncate ftruncate64
+# define afs_mmap mmap64
+# ifdef AFS_AIX_ENV
+extern void * mmap64(); /* ugly hack since aix build env appears to be somewhat broken */
+# endif
+# else /* !O_LARGEFILE */
+# define afs_stat_st stat
+# define afs_stat stat
+# define afs_fstat fstat
+# define afs_fopen fopen
+# define afs_open open
+# 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_ftruncate ftruncate
+# define afs_mmap mmap
+# endif /* !O_LARGEFILE */
+# if AFS_HAVE_STATVFS64
+# define afs_statvfs statvfs64
+# else
+# if AFS_HAVE_STATFS64
+# define afs_statfs statfs64
+# else
+# if AFS_HAVE_STATVFS
+# define afs_statvfs statvfs
+# else
+# define afs_statfs statfs
+# endif /* !AFS_HAVE_STATVFS */
+# endif /* !AFS_HAVE_STATFS64 */
+# endif /* !AFS_HAVE_STATVFS64 */
+#endif /* !AFS_NT40_ENV */
#endif /* _IHANDLE_H_ */