]> git.sur5r.net Git - openldap/commitdiff
Merge remote-tracking branch 'origin/mdb.RE/0.9' into OPENLDAP_REL_ENG_2_4
authorQuanah Gibson-Mount <quanah@openldap.org>
Thu, 23 Apr 2015 17:49:56 +0000 (12:49 -0500)
committerQuanah Gibson-Mount <quanah@openldap.org>
Thu, 23 Apr 2015 17:49:56 +0000 (12:49 -0500)
libraries/liblmdb/CHANGES
libraries/liblmdb/mdb.c

index 1d60d7f511537a674030671e40633055fdc2d8c3..da4e5ce5f4f1a1cc3cd38f19576d21eef0220954 100644 (file)
@@ -6,6 +6,8 @@ LMDB 0.9.15 Release Engineering
        Fix compact of empty env (ITS#7956)
        Fix mdb_rebalance collapsing root (ITS#8062)
        Fix mdb_load with large values (ITS#8066)
+       Fix to retry writes on EINTR (ITS#8106)
+       Fix mdb_cursor_del on empty DB (ITS#8109)
        Added workaround for fdatasync bug in ext3fs
        Build
                Don't use -fPIC for static lib
index 944b95f1ccedd1307ed2136f73388729af723917..fe651509f8a1debc766c95fdfeb8a4a48806f677 100644 (file)
@@ -3133,6 +3133,7 @@ mdb_page_flush(MDB_txn *txn, int keep)
                /* Write up to MDB_COMMIT_PAGES dirty pages at a time. */
                if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) {
                        if (n) {
+retry_write:
                                /* Write previous page(s) */
 #ifdef MDB_USE_PWRITEV
                                wres = pwritev(env->me_fd, iov, n, wpos);
@@ -3140,8 +3141,11 @@ mdb_page_flush(MDB_txn *txn, int keep)
                                if (n == 1) {
                                        wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos);
                                } else {
+retry_seek:
                                        if (lseek(env->me_fd, wpos, SEEK_SET) == -1) {
                                                rc = ErrCode();
+                                               if (rc == EINTR)
+                                                       goto retry_seek;
                                                DPRINTF(("lseek: %s", strerror(rc)));
                                                return rc;
                                        }
@@ -3151,6 +3155,8 @@ mdb_page_flush(MDB_txn *txn, int keep)
                                if (wres != wsize) {
                                        if (wres < 0) {
                                                rc = ErrCode();
+                                               if (rc == EINTR)
+                                                       goto retry_write;
                                                DPRINTF(("Write error: %s", strerror(rc)));
                                        } else {
                                                rc = EIO; /* TODO: Use which error code? */
@@ -3520,7 +3526,8 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
        int len;
 #define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \
        len = pwrite(fd, ptr, size, pos);       \
-       rc = (len >= 0); } while(0)
+       if (len == -1 && ErrCode() == EINTR) continue; \
+       rc = (len >= 0); break; } while(1)
 #endif
 
        DPUTS("writing new meta page");
@@ -3625,6 +3632,7 @@ mdb_env_write_meta(MDB_txn *txn)
        /* Write to the SYNC fd */
        mfd = env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC) ?
                env->me_fd : env->me_mfd;
+retry_write:
 #ifdef _WIN32
        {
                memset(&ov, 0, sizeof(ov));
@@ -3637,6 +3645,8 @@ mdb_env_write_meta(MDB_txn *txn)
 #endif
        if (rc != len) {
                rc = rc < 0 ? ErrCode() : EIO;
+               if (rc == EINTR)
+                       goto retry_write;
                DPUTS("write failed, disk error?");
                /* On a failure, the pagecache still contains the new data.
                 * Write some old data back, to prevent it from being used.
@@ -7835,6 +7845,13 @@ mdb_cursor_del0(MDB_cursor *mc)
                MDB_cursor *m2, *m3;
                MDB_dbi dbi = mc->mc_dbi;
 
+               /* DB is totally empty now, just bail out.
+                * Other cursors adjustments were already done
+                * by mdb_rebalance and aren't needed here.
+                */
+               if (!mc->mc_snum)
+                       return rc;
+
                mp = mc->mc_pg[mc->mc_top];
                nkeys = NUMKEYS(mp);