ITS#8106 retry writes on EINTR

vl32b
Howard Chu 10 years ago
parent ccf4d8b385
commit 4c62fde880
  1. 12
      libraries/liblmdb/mdb.c

@ -3236,6 +3236,7 @@ mdb_page_flush(MDB_txn *txn, int keep)
/* Write up to MDB_COMMIT_PAGES dirty pages at a time. */ /* Write up to MDB_COMMIT_PAGES dirty pages at a time. */
if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) { if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) {
if (n) { if (n) {
retry_write:
/* Write previous page(s) */ /* Write previous page(s) */
#ifdef MDB_USE_PWRITEV #ifdef MDB_USE_PWRITEV
wres = pwritev(env->me_fd, iov, n, wpos); wres = pwritev(env->me_fd, iov, n, wpos);
@ -3243,8 +3244,11 @@ mdb_page_flush(MDB_txn *txn, int keep)
if (n == 1) { if (n == 1) {
wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos); wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos);
} else { } else {
retry_seek:
if (lseek(env->me_fd, wpos, SEEK_SET) == -1) { if (lseek(env->me_fd, wpos, SEEK_SET) == -1) {
rc = ErrCode(); rc = ErrCode();
if (rc == EINTR)
goto retry_seek;
DPRINTF(("lseek: %s", strerror(rc))); DPRINTF(("lseek: %s", strerror(rc)));
return rc; return rc;
} }
@ -3254,6 +3258,8 @@ mdb_page_flush(MDB_txn *txn, int keep)
if (wres != wsize) { if (wres != wsize) {
if (wres < 0) { if (wres < 0) {
rc = ErrCode(); rc = ErrCode();
if (rc == EINTR)
goto retry_write;
DPRINTF(("Write error: %s", strerror(rc))); DPRINTF(("Write error: %s", strerror(rc)));
} else { } else {
rc = EIO; /* TODO: Use which error code? */ rc = EIO; /* TODO: Use which error code? */
@ -3627,7 +3633,8 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
int len; int len;
#define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \ #define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \
len = pwrite(fd, ptr, size, pos); \ len = pwrite(fd, ptr, size, pos); \
rc = (len >= 0); } while(0) if (len == -1 && ErrCode() == EINTR) continue; \
rc = (len >= 0); break; } while(1)
#endif #endif
DPUTS("writing new meta page"); DPUTS("writing new meta page");
@ -3735,6 +3742,7 @@ mdb_env_write_meta(MDB_txn *txn)
/* Write to the SYNC fd */ /* Write to the SYNC fd */
mfd = (flags & (MDB_NOSYNC|MDB_NOMETASYNC)) ? env->me_fd : env->me_mfd; mfd = (flags & (MDB_NOSYNC|MDB_NOMETASYNC)) ? env->me_fd : env->me_mfd;
retry_write:
#ifdef _WIN32 #ifdef _WIN32
{ {
memset(&ov, 0, sizeof(ov)); memset(&ov, 0, sizeof(ov));
@ -3747,6 +3755,8 @@ mdb_env_write_meta(MDB_txn *txn)
#endif #endif
if (rc != len) { if (rc != len) {
rc = rc < 0 ? ErrCode() : EIO; rc = rc < 0 ? ErrCode() : EIO;
if (rc == EINTR)
goto retry_write;
DPUTS("write failed, disk error?"); DPUTS("write failed, disk error?");
/* On a failure, the pagecache still contains the new data. /* On a failure, the pagecache still contains the new data.
* Write some old data back, to prevent it from being used. * Write some old data back, to prevent it from being used.

Loading…
Cancel
Save