]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
ITS#7682 F_NOCACHE: Allow error, skip any O_DIRECT
[openldap] / libraries / liblmdb / mdb.c
index fe58cab5032146de9c740519e5b5f11ff935c44e..057595848607fa41587e24bf5dd1989d2c97f75c 100644 (file)
@@ -258,6 +258,10 @@ typedef SSIZE_T    ssize_t;
 #  define MDB_USE_ROBUST       0
 # else
 #  define MDB_USE_ROBUST       1
+# endif
+#endif /* !MDB_USE_ROBUST */
+
+#if defined(MDB_USE_POSIX_MUTEX) && (MDB_USE_ROBUST)
 /* glibc < 2.12 only provided _np API */
 #  if (defined(__GLIBC__) && GLIBC_VER < 0x02000c) || \
        (defined(PTHREAD_MUTEX_ROBUST_NP) && !defined(PTHREAD_MUTEX_ROBUST))
@@ -265,10 +269,9 @@ typedef SSIZE_T    ssize_t;
 #   define pthread_mutexattr_setrobust(attr, flag)     pthread_mutexattr_setrobust_np(attr, flag)
 #   define pthread_mutex_consistent(mutex)     pthread_mutex_consistent_np(mutex)
 #  endif
-# endif
-#endif /* MDB_USE_ROBUST */
+#endif /* MDB_USE_POSIX_MUTEX && MDB_USE_ROBUST */
 
-#if defined(MDB_OWNERDEAD) && MDB_USE_ROBUST
+#if defined(MDB_OWNERDEAD) && (MDB_USE_ROBUST)
 #define MDB_ROBUST_SUPPORTED   1
 #endif
 
@@ -768,9 +771,23 @@ typedef struct MDB_txninfo {
          + (((MDB_PIDLOCK) != 0) << 16)))
 /** @} */
 
-/** Common header for all page types.
- * Overflow records occupy a number of contiguous pages with no
- * headers on any page after the first.
+/** Common header for all page types. The page type depends on #mp_flags.
+ *
+ * #P_BRANCH and #P_LEAF pages have unsorted '#MDB_node's at the end, with
+ * sorted #mp_ptrs[] entries referring to them. Exception: #P_LEAF2 pages
+ * omit mp_ptrs and pack sorted #MDB_DUPFIXED values after the page header.
+ *
+ * #P_OVERFLOW records occupy one or more contiguous pages where only the
+ * first has a page header. They hold the real data of #F_BIGDATA nodes.
+ *
+ * #P_SUBP sub-pages are small leaf "pages" with duplicate data.
+ * A node with flag #F_DUPDATA but not #F_SUBDATA contains a sub-page.
+ * (Duplicate data can also go in sub-databases, which use normal pages.)
+ *
+ * #P_META pages contain #MDB_meta, the start point of an LMDB snapshot.
+ *
+ * Each non-metapage up to #MDB_meta.%mm_last_pg is reachable exactly once
+ * in the snapshot: Either used by a database or listed in a freeDB record.
  */
 typedef struct MDB_page {
 #define        mp_pgno mp_p.p_pgno
@@ -779,7 +796,7 @@ typedef struct MDB_page {
                pgno_t          p_pgno; /**< page number */
                struct MDB_page *p_next; /**< for in-memory list of freed pages */
        } mp_p;
-       uint16_t        mp_pad;
+       uint16_t        mp_pad;                 /**< key size if this is a LEAF2 page */
 /**    @defgroup mdb_page      Page Flags
  *     @ingroup internal
  *     Flags for the page headers.
@@ -846,7 +863,9 @@ typedef struct MDB_page {
        /** The number of overflow pages needed to store the given size. */
 #define OVPAGES(size, psize)   ((PAGEHDRSZ-1 + (size)) / (psize) + 1)
 
-       /** Link in #MDB_txn.%mt_loose_pgs list */
+       /** Link in #MDB_txn.%mt_loose_pgs list.
+        *  Kept outside the page header, which is needed when reusing the page.
+        */
 #define NEXT_LOOSE_PAGE(p)             (*(MDB_page **)((p) + 2))
 
        /** Header for a single key/data pair within a page.
@@ -1583,7 +1602,7 @@ mdb_page_list(MDB_page *mp)
                        pgno, ((MDB_meta *)METADATA(mp))->mm_txnid);
                return;
        default:
-               fprintf(stderr, "Bad page %"Z"u flags 0x%u\n", pgno, mp->mp_flags);
+               fprintf(stderr, "Bad page %"Z"u flags 0x%X\n", pgno, mp->mp_flags);
                return;
        }
 
@@ -1699,7 +1718,7 @@ static void mdb_audit(MDB_txn *txn)
                }
        }
        if (freecount + count + NUM_METAS != txn->mt_next_pgno) {
-               fprintf(stderr, "audit: %lu freecount: %lu count: %lu total: %lu next_pgno: %lu\n",
+               fprintf(stderr, "audit: %"Z"u freecount: %"Z"u count: %"Z"u total: %"Z"u next_pgno: %"Z"u\n",
                        txn->mt_txnid, freecount, count+NUM_METAS,
                        freecount+count+NUM_METAS, txn->mt_next_pgno);
        }
@@ -5909,6 +5928,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data,
                                                }
                                        }
                                        rc = 0;
+                                       mc->mc_flags &= ~C_EOF;
                                        goto set2;
                                }
                        }
@@ -9374,17 +9394,12 @@ mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
        }
 
        if (env->me_psize >= env->me_os_psize) {
-#ifdef O_DIRECT
+#ifdef F_NOCACHE       /* __APPLE__ */
+       (void) fcntl(newfd, F_NOCACHE, 1);
+#elif defined O_DIRECT
        /* Set O_DIRECT if the file system supports it */
        if ((rc = fcntl(newfd, F_GETFL)) != -1)
                (void) fcntl(newfd, F_SETFL, rc | O_DIRECT);
-#endif
-#ifdef F_NOCACHE       /* __APPLE__ */
-       rc = fcntl(newfd, F_NOCACHE, 1);
-       if (rc) {
-               rc = ErrCode();
-               goto leave;
-       }
 #endif
        }