ihandle: Ensure FDH_REALLYCLOSE really closes
[openafs.git] / src / vol / ihandle.h
index 0786e9f..44b163b 100644 (file)
@@ -55,6 +55,8 @@
  * 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.
 #define _IHANDLE_H_
 
 #ifdef AFS_PTHREAD_ENV
-#include <assert.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)
+    do { osi_Assert(pthread_once(&ih_glock_once, ih_glock_init) == 0); \
+       MUTEX_ENTER(&ih_glock_mutex); \
+    } while (0)
+#define IH_UNLOCK MUTEX_EXIT(&ih_glock_mutex)
 #else /* AFS_PTHREAD_ENV */
 #define IH_LOCK
 #define IH_UNLOCK
@@ -108,7 +109,7 @@ extern void ih_glock_init(void);
        else                                    \
            (head) = (ptr)->next;               \
        (ptr)->next = (ptr)->prev = NULL;       \
-       assert(!(head) || !((head)->prev)); \
+       osi_Assert(!(head) || !((head)->prev)); \
     } while(0)
 
 /*
@@ -123,7 +124,7 @@ extern void ih_glock_init(void);
            (ptr)->prev->next = (ptr);           \
        else                                     \
            (head) = (ptr);                      \
-       assert((head) && ((head)->prev == NULL)); \
+       osi_Assert((head) && ((head)->prev == NULL));   \
     } while(0)
 
 #endif /* DLL_INIT_LIST */
@@ -148,14 +149,17 @@ struct IHandle_s;
  */
 #ifdef AFS_NT40_ENV
 typedef HANDLE FD_t;
+#define INVALID_FD INVALID_HANDLE_VALUE
 #else
 typedef int FD_t;
-#endif
 #define INVALID_FD ((FD_t)-1)
+#endif
 
 /* file descriptor handle */
 typedef struct FdHandle_s {
     int fd_status;             /* status flags */
+    int fd_refcnt;             /* refcnt */
+    int fd_needs_rclose;       /* do we need to fd_reallyclose? */
     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 +180,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 */
@@ -278,13 +283,13 @@ typedef struct IHashBucket_s {
 #ifdef AFS_NAMEI_ENV
 #ifdef AFS_NT40_ENV
 #include "ntops.h"
-#else
-#include "namei_ops.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 */
 
 /*
@@ -306,8 +311,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 +341,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,13 +359,46 @@ extern int ih_condsync(IHandle_t * ihP);
 
 #define IH_CONDSYNC(H) ih_condsync(H)
 
+#ifdef HAVE_PIO
+#ifdef AFS_NT40_ENV
+#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
+#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 */
+#endif /* AFS_NT40_ENV */
+#else /* !HAVE_PIO */
+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 /* !HAVE_PIO */
+#ifdef AFS_NT40_ENV
+#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)
+#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_DIRSEP "/"
+#define OS_DIRSEPC '/'
+#endif
+
+
+
 #ifdef AFS_NAMEI_ENV
 
 #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_IOPEN(H) nt_iopen(H)
 #define OS_OPEN(F, M, P) nt_open(F, M, P)
 #define OS_CLOSE(FD) nt_close(FD)
 
@@ -371,12 +408,6 @@ extern int ih_condsync(IHandle_t * ihP);
 
 #define OS_SYNC(FD) nt_fsync(FD)
 #define OS_TRUNC(FD, L) nt_ftruncate(FD, L)
-#define OS_SIZE(FD) nt_size(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)
 
 #else /* AFS_NT40_ENV */
 
@@ -389,11 +420,13 @@ extern Inode IH_CREATE(IHandle_t * H, int /*@alt Device @ */ D,
                       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,
@@ -401,18 +434,15 @@ extern afs_sfsize_t IH_IREAD(IHandle_t * H, afs_foff_t O, void *B,
 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 OFFT off64_t
+#else
+#define OFFT off_t
+#endif
 
-#define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
-       namei_icreate(H, P, P1, P2, P3, P4)
+extern OFFT OS_SEEK(FD_t FD, OFFT O, int F);
+extern int OS_TRUNC(FD_t FD, OFFT L);
+#endif /*S_SPLINT_S */
 
-#define OS_IOPEN(H) namei_iopen(H)
 #ifdef O_LARGEFILE
 #define OS_OPEN(F, M, P) open64(F, M, P)
 #else /* !O_LARGEFILE */
@@ -424,25 +454,24 @@ extern int OS_TRUNC(int FD, off_t L);
 #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 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);
 
+/*@=fcnmacros =macrofcndecl@*/
+#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)
-/*@=fcnmacros =macrofcndecl@*/
-#endif /* AFS_NT40_ENV */
+#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,
@@ -467,18 +496,13 @@ extern Inode ih_icreate(IHandle_t * ih, int dev, char *part, Inode nI, int p1,
 #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 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
@@ -496,12 +520,26 @@ extern afs_sfsize_t ih_size(int fd);
 
 
 #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)
 #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)
@@ -509,5 +547,58 @@ extern afs_sfsize_t ih_size(int fd);
 #define FDH_SYNC(H) ((H->fd_ih!=NULL) ? ( H->fd_ih->ih_synced = 1) - 1 : 1)
 #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)
+
+#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
+#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_ */