Commit 0eee67fa authored by Yoni Fogel's avatar Yoni Fogel

[t:2216] Merge/windows port of #2216

git-svn-id: file:///svn/toku/tokudb@18191 c7de825b-a66e-492c-adef-691d508d4ae1
parent 78e65416
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <windows.h> #include <windows.h>
#include <toku_atomic.h> #include <toku_atomic.h>
#include <toku_time.h> #include <toku_time.h>
#include <fcntl.h>
int64_t int64_t
pread(int fildes, void *buf, size_t nbyte, int64_t offset) { pread(int fildes, void *buf, size_t nbyte, int64_t offset) {
...@@ -189,6 +190,25 @@ toku_os_full_write (int fd, const void *org_buf, size_t len) { ...@@ -189,6 +190,25 @@ toku_os_full_write (int fd, const void *org_buf, size_t len) {
assert(len == 0); assert(len == 0);
} }
int
toku_os_write (int fd, const void *org_buf, size_t len) {
const uint8_t *buf = org_buf;
while (len > 0) {
ssize_t r;
if (t_write) {
r = t_write(fd, buf, len);
} else {
r = write(fd, buf, len);
}
if (r < 0)
return errno;
len -= r;
buf += r;
}
return 0;
}
// t_fsync exists for testing purposes only // t_fsync exists for testing purposes only
static int (*t_fsync)(int) = 0; static int (*t_fsync)(int) = 0;
static uint64_t toku_fsync_count; static uint64_t toku_fsync_count;
...@@ -266,3 +286,38 @@ toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time) { ...@@ -266,3 +286,38 @@ toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time) {
*fsync_time = toku_fsync_time; *fsync_time = toku_fsync_time;
} }
static toku_pthread_mutex_t mkstemp_lock;
int
toku_mkstemp_init(void) {
int r = 0;
r = toku_pthread_mutex_init(&mkstemp_lock, NULL); assert(r == 0);
return r;
}
int
toku_mkstemp_destroy(void) {
int r = 0;
r = toku_pthread_mutex_destroy(&mkstemp_lock); assert(r == 0);
return r;
}
int mkstemp (char * template) {
int fd;
int r_mutex;
r_mutex = toku_pthread_mutex_lock(&mkstemp_lock);
assert(r_mutex == 0);
errno_t err = _mktemp_s(template, strlen(template)+1);
if (err!=0) {
fd = -1;
errno = err;
goto cleanup;
}
assert(err==0);
fd = open(template, _O_BINARY|_O_CREAT|_O_SHORT_LIVED|_O_EXCL|_O_RDWR, _S_IREAD|_S_IWRITE);
cleanup:
r_mutex = toku_pthread_mutex_unlock(&mkstemp_lock);
assert(r_mutex == 0);
return fd;
}
...@@ -15,6 +15,8 @@ extern "C" { ...@@ -15,6 +15,8 @@ extern "C" {
int fsync(int fildes); int fsync(int fildes);
int toku_fsync_init(void); int toku_fsync_init(void);
int toku_fsync_destroy(void); int toku_fsync_destroy(void);
int toku_mkstemp_init(void);
int toku_mkstemp_destroy(void);
int gettimeofday(struct timeval *tv, struct timezone *tz); int gettimeofday(struct timeval *tv, struct timezone *tz);
...@@ -76,6 +78,8 @@ int snprintf(char *str, size_t size, const char *format, ...); ...@@ -76,6 +78,8 @@ int snprintf(char *str, size_t size, const char *format, ...);
int usleep(unsigned int useconds); int usleep(unsigned int useconds);
int mkstemp(char * ttemplate);
#if defined(__cplusplus) #if defined(__cplusplus)
}; };
#endif #endif
......
...@@ -21,12 +21,14 @@ all: $(BINS) ...@@ -21,12 +21,14 @@ all: $(BINS)
.PHONY: check .PHONY: check
check: $(BINS) $(RUNTARGETS); check: $(BINS) $(RUNTARGETS);
test-pwrite4g.tdbrun: TEST_EXTRA_ARGS=.
test-pwrite4g.tdbrun: VERBVERBOSE=
%.tdbrun: %$(BINSUF) $(PTHREAD_LOCAL) %.tdbrun: %$(BINSUF) $(PTHREAD_LOCAL)
mkdir -p dir.$* mkdir -p dir.$*
ifeq ($(VGRIND),) ifeq ($(VGRIND),)
cd dir.$* && ../$< $(VERBVERBOSE) $(SUMMARIZE_CMD) cd dir.$* && ../$< $(TEST_EXTRA_ARGS) $(VERBVERBOSE) $(SUMMARIZE_CMD)
else else
cd dir.$* && .$(VGRIND) --log-file=$<.valgrind ../$< $(VERBVERBOSE); \ cd dir.$* && .$(VGRIND) --log-file=$<.valgrind ../$< $(TEST_EXTRA_ARGS) $(VERBVERBOSE); \
if [ $$? = 0 ] ; then \ if [ $$? = 0 ] ; then \
grep "LEAK SUMMARY" dir.$*/$<.valgrind >/dev/null 2>&1; \ grep "LEAK SUMMARY" dir.$*/$<.valgrind >/dev/null 2>&1; \
if [ $$? = 0 ] ; then cat dir.$*/$<.valgrind; test 0 = 1; fi \ if [ $$? = 0 ] ; then cat dir.$*/$<.valgrind; test 0 = 1; fi \
......
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <test.h>
#include "toku_os.h" #include "toku_os.h"
#include <dirent.h> #include <dirent.h>
...@@ -33,7 +33,7 @@ static int walk(const char *dirname) { ...@@ -33,7 +33,7 @@ static int walk(const char *dirname) {
return otherfound; return otherfound;
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
int found; int found;
int fd; int fd;
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <test.h>
#include "toku_os.h" #include "toku_os.h"
int verbose=0; int verbose=0;
enum {NUM_IDS=4};
struct fileid old_ids[NUM_IDS];
BOOL valid[NUM_IDS];
//TODO: Test that different files are different, //TODO: Test that different files are different,
// other stuff // other stuff
static void test_handles(const char *fname) { static void test_handles(const char *fname, unsigned which) {
unlink(fname); unlink(fname);
int fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO); int fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO);
assert(fd!=-1); assert(fd!=-1);
...@@ -18,17 +20,34 @@ static void test_handles(const char *fname) { ...@@ -18,17 +20,34 @@ static void test_handles(const char *fname) {
struct fileid id_base; struct fileid id_base;
struct fileid id; struct fileid id;
int r = toku_os_get_unique_file_id(fd, &id_base); int r = toku_os_get_unique_file_id(fd, &id_base);
assert(r==0); CKERR(r);
assert(which < NUM_IDS);
for (i = 0; i < NUM_IDS; i++) {
if (valid[i]) {
if (which==i) {
//Assert same
assert(memcmp(&id_base, &old_ids[i], sizeof(id_base))==0);
}
else {
//Assert different
assert(memcmp(&id_base, &old_ids[i], sizeof(id_base))!=0);
}
}
}
memcpy(&old_ids[which], &id_base, sizeof(id_base));
valid[which] = TRUE;
if (verbose) printf("[%s] : r=[%d] errno=[%d] id=[0x%"PRIx32"/0x%"PRIx64"]\n", fname, r, errno, id_base.st_dev, id_base.st_ino);
for (i=0; i < 1<<16; i++) { for (i=0; i < 1<<16; i++) {
r = toku_os_get_unique_file_id(fd, &id); r = toku_os_get_unique_file_id(fd, &id);
assert(r==0); CKERR(r);
assert(memcmp(&id, &id_base, sizeof(id))==0); assert(memcmp(&id, &id_base, sizeof(id))==0);
} }
r = close(fd); r = close(fd);
assert(r==0); CKERR(r);
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
...@@ -37,7 +56,13 @@ int test_main(int argc, char *argv[]) { ...@@ -37,7 +56,13 @@ int test_main(int argc, char *argv[]) {
verbose++; verbose++;
} }
test_handles("junk"); test_handles("junk1", 0);
test_handles("junk2", 1);
test_handles("junk3", 2);
test_handles("NUL", 3);
test_handles(".\\NUL", 3);
test_handles("\\NUL", 3);
test_handles("C:\\NUL", 3);
return 0; return 0;
} }
...@@ -27,7 +27,7 @@ static int ftruncate(int fd, uint64_t offset) { ...@@ -27,7 +27,7 @@ static int ftruncate(int fd, uint64_t offset) {
} }
#endif #endif
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int r; int r;
int fd; int fd;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <toku_assert.h> #include <toku_assert.h>
#include <toku_time.h> #include <toku_time.h>
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int r; int r;
struct timeval tv; struct timeval tv;
struct timezone tz; struct timezone tz;
......
#define _GNU_SOURCE #define _GNU_SOURCE
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include <unistd.h> #include <unistd.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <test.h>
#include <toku_os.h> #include <toku_os.h>
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
uint64_t maxdata; uint64_t maxdata;
int r = toku_os_get_max_process_data_size(&maxdata); int r = toku_os_get_max_process_data_size(&maxdata);
assert(r == 0); assert(r == 0);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
int fd = open(argv[i], O_RDONLY); int fd = open(argv[i], O_RDONLY);
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#define TESTFILE "test-open-unlink-file" #define TESTFILE "test-open-unlink-file"
#define NEWNAME TESTFILE ".junk" #define NEWNAME TESTFILE ".junk"
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int r; int r;
int fd; int fd;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
const char TESTFILE[] = "test-open-unlink-file"; const char TESTFILE[] = "test-open-unlink-file";
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int r; int r;
int fd; int fd;
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <test.h>
#include "toku_os.h" #include "toku_os.h"
int verbose; int verbose;
...@@ -24,7 +24,7 @@ static void test_pread_empty(const char *fname) { ...@@ -24,7 +24,7 @@ static void test_pread_empty(const char *fname) {
printf("close %s %"PRIu64"\n", fname, r); printf("close %s %"PRIu64"\n", fname, r);
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
......
...@@ -68,7 +68,7 @@ static void *reader(void *arg) { ...@@ -68,7 +68,7 @@ static void *reader(void *arg) {
return arg; return arg;
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
void *ret; void *ret;
toku_pthread_t t[2]; toku_pthread_t t[2];
......
...@@ -20,7 +20,7 @@ static void *myfunc2(void *arg) { ...@@ -20,7 +20,7 @@ static void *myfunc2(void *arg) {
return arg; return arg;
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
#define N 10 #define N 10
toku_pthread_t t[N]; toku_pthread_t t[N];
int i; int i;
......
...@@ -12,7 +12,7 @@ static void *mythreadfunc(void *arg) { ...@@ -12,7 +12,7 @@ static void *mythreadfunc(void *arg) {
return arg; return arg;
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
#define N 1000000 #define N 1000000
int i; int i;
......
#include <toku_assert.h>
#include <test.h> #include <test.h>
#include <toku_assert.h>
#include <toku_pthread.h> #include <toku_pthread.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
int test_main(int argc __attribute__((__unused__)), char *const argv[] __attribute__((__unused__))) { int test_main(int argc, char *const argv[]) {
int r; int r;
toku_pthread_rwlock_t rwlock; toku_pthread_rwlock_t rwlock;
......
#include <toku_assert.h>
#include <test.h> #include <test.h>
#include <toku_assert.h>
#include <toku_pthread.h> #include <toku_pthread.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
...@@ -15,7 +15,7 @@ static void *f(void *arg) { ...@@ -15,7 +15,7 @@ static void *f(void *arg) {
return arg; return arg;
} }
int test_main(int argc __attribute__((__unused__)), char *const argv[] __attribute__((__unused__))) { int test_main(int argc, char *const argv[]) {
int r; int r;
toku_pthread_rwlock_t rwlock; toku_pthread_rwlock_t rwlock;
toku_pthread_t tid; toku_pthread_t tid;
......
/* Verify that toku_os_full_pwrite does the right thing when writing beyond 4GB. */ /* Verify that toku_os_full_pwrite does the right thing when writing beyond 4GB. */
#include <test.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <test.h> #include <string.h>
#include <stdio.h>
static int iszero(char *cp, size_t n) { static int iszero(char *cp, size_t n) {
size_t i; size_t i;
...@@ -12,8 +13,12 @@ static int iszero(char *cp, size_t n) { ...@@ -12,8 +13,12 @@ static int iszero(char *cp, size_t n) {
return 1; return 1;
} }
int test_main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) { int test_main(int argc, char *const argv[]) {
char fname[] = "pwrite4g.data"; assert(argc==2); // first arg is the directory to put the data file into.
char short_fname[] = "pwrite4g.data";
int fname_len = strlen(short_fname) + strlen(argv[1]) + 5;
char fname[fname_len];
snprintf(fname, fname_len, "%s/%s", argv[1], short_fname);
int r; int r;
unlink(fname); unlink(fname);
int fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO); int fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO);
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include <test.h>
#include <toku_os.h> #include <toku_os.h>
static void do_mallocs(void) { static void do_mallocs(void) {
...@@ -16,7 +16,7 @@ static void do_mallocs(void) { ...@@ -16,7 +16,7 @@ static void do_mallocs(void) {
} }
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int64_t rss; int64_t rss;
toku_os_get_max_rss(&rss); toku_os_get_max_rss(&rss);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
int verbose; int verbose;
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
......
/* -*- mode: C; c-basic-offset: 4 -*- */ /* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <toku_portability.h> #include <toku_portability.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <toku_os.h> #include <toku_os.h>
#include <test.h>
static void static void
check_snprintf(int i) { check_snprintf(int i) {
...@@ -37,7 +37,7 @@ check_snprintf(int i) { ...@@ -37,7 +37,7 @@ check_snprintf(int i) {
} }
int test_main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) { int test_main(int argc, char *const argv[]) {
int i; int i;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
check_snprintf(i); check_snprintf(i);
......
...@@ -15,7 +15,7 @@ void test_stat(char *dirname, int result, int ex_errno) { ...@@ -15,7 +15,7 @@ void test_stat(char *dirname, int result, int ex_errno) {
if (r!=0) assert(errno == ex_errno); if (r!=0) assert(errno == ex_errno);
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int r; int r;
test_stat(".", 0, 0); test_stat(".", 0, 0);
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <test.h>
#include "toku_os.h" #include "toku_os.h"
int verbose; int verbose;
...@@ -17,7 +17,7 @@ void testit(int64_t i, int base) { ...@@ -17,7 +17,7 @@ void testit(int64_t i, int base) {
assert(i == o); assert(i == o);
} }
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
int64_t n; int64_t n;
int64_t o; int64_t o;
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <test.h>
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int r; int r;
int fd; int fd;
struct fileid fid; struct fileid fid;
......
#include <test.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <toku_assert.h> #include <toku_assert.h>
...@@ -5,7 +6,7 @@ ...@@ -5,7 +6,7 @@
#include <windows.h> #include <windows.h>
#include <winsock.h> #include <winsock.h>
int usleep(SOCKET s, unsigned int useconds) { int usleep_socket(SOCKET s, unsigned int useconds) {
fd_set dummy; fd_set dummy;
struct timeval tv; struct timeval tv;
FD_ZERO(&dummy); FD_ZERO(&dummy);
...@@ -15,10 +16,9 @@ int usleep(SOCKET s, unsigned int useconds) { ...@@ -15,10 +16,9 @@ int usleep(SOCKET s, unsigned int useconds) {
return select(0, 0, 0, &dummy, &tv); return select(0, 0, 0, &dummy, &tv);
} }
#include <test.h>
int verbose; int verbose;
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
int n = 1; int n = 1;
WSADATA wsadata; WSADATA wsadata;
...@@ -39,7 +39,7 @@ int test_main(int argc, char *argv[]) { ...@@ -39,7 +39,7 @@ int test_main(int argc, char *argv[]) {
if (verbose) { if (verbose) {
printf("usleep %d\n", i); fflush(stdout); printf("usleep %d\n", i); fflush(stdout);
} }
usleep(s, n); usleep_socket(s, n);
} }
return 0; return 0;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
int verbose; int verbose;
int test_main(int argc, char *argv[]) { int test_main(int argc, char *const argv[]) {
int i; int i;
int n = 1; int n = 1;
......
#include <toku_portability.h> #include <toku_portability.h>
#include <toku_assert.h> #include <toku_assert.h>
#define CKERR(r) do { if (r!=0) fprintf(stderr, "%s:%d error %d %s\n", __FILE__, __LINE__, r, strerror(r)); assert(r==0); } while (0)
#define CKERR2(r,r2) do { if (r!=r2) fprintf(stderr, "%s:%d error %d %s, expected %d\n", __FILE__, __LINE__, r, strerror(r), r2); assert(r==r2); } while (0)
#define CKERR2s(r,r2,r3) do { if (r!=r2 && r!=r3) fprintf(stderr, "%s:%d error %d %s, expected %d or %d\n", __FILE__, __LINE__, r, strerror(r), r2,r3); assert(r==r2||r==r3); } while (0)
#define DEBUG_LINE do { \
fprintf(stderr, "%s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
fflush(stderr); \
} while (0)
int test_main(int argc, char *const argv[]); int test_main(int argc, char *const argv[]);
int int
......
...@@ -48,6 +48,8 @@ toku_portability_init(void) { ...@@ -48,6 +48,8 @@ toku_portability_init(void) {
r = toku_pthread_win32_init(); r = toku_pthread_win32_init();
if (r==0) if (r==0)
r = toku_fsync_init(); r = toku_fsync_init();
if (r==0)
r = toku_mkstemp_init();
if (r==0) if (r==0)
_fmode = _O_BINARY; //Default open file is BINARY _fmode = _O_BINARY; //Default open file is BINARY
return r; return r;
...@@ -56,6 +58,8 @@ toku_portability_init(void) { ...@@ -56,6 +58,8 @@ toku_portability_init(void) {
int int
toku_portability_destroy(void) { toku_portability_destroy(void) {
int r = 0; int r = 0;
if (r==0)
r = toku_mkstemp_destroy();
if (r==0) if (r==0)
r = toku_fsync_destroy(); r = toku_fsync_destroy();
if (r==0) if (r==0)
...@@ -115,6 +119,7 @@ toku_os_get_unique_file_id(int fildes, struct fileid *id) { ...@@ -115,6 +119,7 @@ toku_os_get_unique_file_id(int fildes, struct fileid *id) {
HANDLE filehandle; HANDLE filehandle;
memset(id, 0, sizeof(*id)); memset(id, 0, sizeof(*id));
memset(&info, 0, sizeof(info));
filehandle = (HANDLE)_get_osfhandle(fildes); filehandle = (HANDLE)_get_osfhandle(fildes);
if (filehandle==INVALID_HANDLE_VALUE) { if (filehandle==INVALID_HANDLE_VALUE) {
r = errno; assert(r!=0); r = errno; assert(r!=0);
...@@ -123,15 +128,28 @@ toku_os_get_unique_file_id(int fildes, struct fileid *id) { ...@@ -123,15 +128,28 @@ toku_os_get_unique_file_id(int fildes, struct fileid *id) {
r = GetFileInformationByHandle(filehandle, &info); r = GetFileInformationByHandle(filehandle, &info);
if (r==0) { //0 is error here. if (r==0) { //0 is error here.
r = GetLastError(); assert(r!=0); r = GetLastError(); assert(r!=0);
if (r==ERROR_INVALID_FUNCTION && info.dwVolumeSerialNumber == 0 &&
info.nFileIndexHigh == 0 && info.nFileIndexLow == 0) {
//"NUL" will return this.
//TODO: Remove this hack somehow
r = 0;
goto continue_dev_null;
}
goto cleanup; goto cleanup;
} }
//Make sure only "NUL" returns all zeros.
assert(info.dwVolumeSerialNumber!=0 || info.nFileIndexHigh!=0 || info.nFileIndexLow!=0);
continue_dev_null: //Skip zeros check (its allowed here).
id->st_dev = info.dwVolumeSerialNumber; id->st_dev = info.dwVolumeSerialNumber;
id->st_ino = info.nFileIndexHigh; id->st_ino = info.nFileIndexHigh;
id->st_ino <<= 32; id->st_ino <<= 32;
id->st_ino |= info.nFileIndexLow; id->st_ino |= info.nFileIndexLow;
r = 0; r = 0;
cleanup: cleanup:
if (r!=0) errno = r; if (r!=0) {
errno = r;
r = -1;
}
return r; return r;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment