windows: native versions of ih_pread and ih_pwrite
authorRod Widdowson <rdw@steadingsoftware.com>
Wed, 27 Oct 2010 22:20:30 +0000 (00:20 +0200)
committerDerrick Brashear <shadow@dementia.org>
Fri, 29 Oct 2010 16:45:51 +0000 (09:45 -0700)
Separate the windows code out in ihandle.c to reduce dependency on ntops.

As an aid to future threading issues, pass the offset in an OVERLAP
rather than doing a separate SetFilePointerEx.

Change-Id: I225387a574b1301516a9313838bbcb86e9e14b8d
Reviewed-on: http://gerrit.openafs.org/3176
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/config/afsconfig-windows.h
src/vol/ihandle.h
src/vol/ntops.c
src/vol/ntops.h

index 6088655..d23a8c0 100644 (file)
@@ -33,6 +33,7 @@
 /* Define as the return type of signal handlers (int or void).  */
 #undef RETSIGTYPE
 
+
 /* The size of `long', as computed by sizeof. */
 #define SIZEOF_LONG 4
 
 /* define if struct ufsvfs has vfs_dqrwlock */
 #undef HAVE_VFS_DQRWLOCK
 
+/* define if you have pread() and pwrite() */
+#define HAVE_PIO 1
+
 #undef PACKAGE
 #undef VERSION
 
index 6df2dff..c36acd7 100644 (file)
@@ -356,6 +356,10 @@ 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)
@@ -363,6 +367,7 @@ extern int ih_condsync(IHandle_t * ihP);
 #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(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);
index a36b4ea..835bc51 100644 (file)
@@ -157,6 +157,31 @@ nt_write(FD_t fd, char *buf, size_t size)
 }
 
 int
+nt_pwrite(FD_t fd, const void * buf, size_t count, afs_foff_t offset)
+{
+    /*
+     * same comment as read
+     */
+
+    DWORD nbytes;
+    BOOL code;
+    OVERLAPPED overlap = {0};
+    LARGE_INTEGER liOffset;
+
+    liOffset.QuadPart = offset;
+    overlap.Offset = liOffset.LowPart;
+    overlap.OffsetHigh = liOffset.HighPart;
+
+    code = WriteFile((HANDLE) fd, (void *)buf, (DWORD) count, &nbytes, &overlap);
+
+    if (!code) {
+       errno = nterr_nt2unix(GetLastError(), EBADF);
+       return -1;
+    }
+    return (ssize_t)nbytes;
+}
+
+int
 nt_read(FD_t fd, char *buf, size_t size)
 {
     BOOL code;
@@ -172,6 +197,33 @@ nt_read(FD_t fd, char *buf, size_t size)
 }
 
 int
+nt_pread(FD_t fd, void * buf, size_t count, afs_foff_t offset)
+{
+    /*
+     * This really ought to call NtReadFile
+     */
+    DWORD nbytes;
+    BOOL code;
+    OVERLAPPED overlap = {0};
+    LARGE_INTEGER liOffset;
+    /*
+     * Cast through a LARGE_INTEGER - make no assumption about
+     * byte ordering and leave that to the compiler..
+     */
+    liOffset.QuadPart = offset;
+    overlap.Offset = liOffset.LowPart;
+    overlap.OffsetHigh = liOffset.HighPart;
+
+    code = ReadFile((HANDLE) fd, (void *)buf, (DWORD) count, &nbytes, &overlap);
+
+    if (!code) {
+       errno = nterr_nt2unix(GetLastError(), EBADF);
+       return -1;
+    }
+    return (ssize_t)nbytes;
+}
+
+int
 nt_iread(IHandle_t * h, int offset, char *buf, int size)
 {
     int nBytes;
index 8ffa469..a01c4d9 100644 (file)
@@ -25,6 +25,8 @@ extern FD_t nt_open(char *name, int flags, int mode);
 extern int nt_close(FD_t fd);
 extern int nt_write(FD_t fd, char *buf, size_t size);
 extern int nt_read(FD_t fd, char *buf, size_t size);
+extern int nt_pread(FD_t fd, void * buf, size_t count, afs_foff_t offset);
+extern int nt_pwrite(FD_t fd, const void * buf, size_t count, afs_foff_t offset);
 extern int nt_size(FD_t fd);
 extern int nt_getFileCreationTime(FD_t fd, FILETIME * ftime);
 extern int nt_setFileCreationTime(FD_t fd, FILETIME * ftime);