mirror of
				https://github.com/isar/libmdbx.git
				synced 2025-10-31 03:29:01 +08:00 
			
		
		
		
	mdbx: add an explicit/strict check that the environment is open.
More for https://github.com/erthink/libmdbx/issues/171. Change-Id: Ifbf7f8ba143d19162bd3ed1cf29c21c31b45f0d5
This commit is contained in:
		
							
								
								
									
										96
									
								
								src/core.c
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								src/core.c
									
									
									
									
									
								
							| @@ -6456,9 +6456,6 @@ __cold static int mdbx_env_sync_internal(MDBX_env *env, bool force, | ||||
|   if (unlikely(flags & (MDBX_RDONLY | MDBX_FATAL_ERROR))) | ||||
|     return MDBX_EACCESS; | ||||
|  | ||||
|   if (unlikely(!env->me_map)) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
|   int rc = MDBX_RESULT_TRUE /* means "nothing to sync" */; | ||||
|   bool need_unlock = false; | ||||
|   if (nonblock && atomic_load32(env->me_unsynced_pages, mo_AcquireRelease) == 0) | ||||
| @@ -6551,7 +6548,7 @@ fastpath: | ||||
|   return rc; | ||||
| } | ||||
|  | ||||
| static __inline int check_env(const MDBX_env *env) { | ||||
| static __inline int check_env(const MDBX_env *env, const bool wanna_active) { | ||||
|   if (unlikely(!env)) | ||||
|     return MDBX_EINVAL; | ||||
|  | ||||
| @@ -6568,11 +6565,16 @@ static __inline int check_env(const MDBX_env *env) { | ||||
|   if (unlikely(env->me_flags & MDBX_FATAL_ERROR)) | ||||
|     return MDBX_PANIC; | ||||
|  | ||||
|   if (wanna_active && unlikely((env->me_flags & MDBX_ENV_ACTIVE) == 0)) { | ||||
|     mdbx_assert(env, env->me_map != nullptr); | ||||
|     return MDBX_EPERM; | ||||
|   } | ||||
|  | ||||
|   return MDBX_SUCCESS; | ||||
| } | ||||
|  | ||||
| __cold int mdbx_env_sync_ex(MDBX_env *env, bool force, bool nonblock) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -6838,7 +6840,7 @@ static bind_rslot_result bind_rslot(MDBX_env *env, const uintptr_t tid) { | ||||
| } | ||||
|  | ||||
| __cold int mdbx_thread_register(const MDBX_env *env) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -6868,7 +6870,7 @@ __cold int mdbx_thread_register(const MDBX_env *env) { | ||||
| } | ||||
|  | ||||
| __cold int mdbx_thread_unregister(const MDBX_env *env) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -7201,6 +7203,9 @@ static __always_inline int check_txn(const MDBX_txn *txn, int bad_bits) { | ||||
|   if (unlikely(txn->mt_flags & bad_bits)) | ||||
|     return MDBX_BAD_TXN; | ||||
|  | ||||
|   if (unlikely(!txn->mt_env->me_map)) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
| #if MDBX_TXN_CHECKOWNER | ||||
|   if ((txn->mt_flags & MDBX_NOTLS) == 0 && | ||||
|       unlikely(txn->mt_owner != mdbx_thread_self())) | ||||
| @@ -7220,6 +7225,9 @@ static __always_inline int check_txn_rw(const MDBX_txn *txn, int bad_bits) { | ||||
|   if (unlikely(txn->mt_flags & bad_bits)) | ||||
|     return MDBX_BAD_TXN; | ||||
|  | ||||
|   if (unlikely(!txn->mt_env->me_map)) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
|   if (unlikely(F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY))) | ||||
|     return MDBX_EACCESS; | ||||
|  | ||||
| @@ -7295,7 +7303,7 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags, | ||||
|                (flags & ~MDBX_TXN_RO_BEGIN_FLAGS))) | ||||
|     return MDBX_EINVAL; | ||||
|  | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -7303,9 +7311,6 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags, | ||||
|                ~flags)) /* write txn in RDONLY env */ | ||||
|     return MDBX_EACCESS; | ||||
|  | ||||
|   if (unlikely(!env->me_map)) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
|   flags |= env->me_flags & MDBX_WRITEMAP; | ||||
|  | ||||
|   if (parent) { | ||||
| @@ -10485,7 +10490,7 @@ __cold LIBMDBX_API int | ||||
| mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, | ||||
|                       intptr_t size_upper, intptr_t growth_step, | ||||
|                       intptr_t shrink_threshold, intptr_t pagesize) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -11647,11 +11652,12 @@ static uint32_t merge_sync_flags(const uint32_t a, const uint32_t b) { | ||||
| __cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target_meta) { | ||||
|   if (unlikely(target_meta >= NUM_METAS)) | ||||
|     return MDBX_EINVAL; | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
|   if ((env->me_flags & (MDBX_EXCLUSIVE | MDBX_RDONLY)) != MDBX_EXCLUSIVE) | ||||
|   if (unlikely((env->me_flags & (MDBX_EXCLUSIVE | MDBX_RDONLY)) != | ||||
|                MDBX_EXCLUSIVE)) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
|   MDBX_page *page = | ||||
| @@ -11704,9 +11710,11 @@ __cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname, | ||||
|                                       unsigned target_meta, bool writeable) { | ||||
|   if (unlikely(target_meta >= NUM_METAS)) | ||||
|     return MDBX_EINVAL; | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|   if (unlikely(env->me_map)) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
|   env->me_stuck_meta = (int8_t)target_meta; | ||||
|   return mdbx_env_open( | ||||
| @@ -11901,7 +11909,7 @@ __cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) { | ||||
|  | ||||
| __cold int mdbx_env_open(MDBX_env *env, const char *pathname, | ||||
|                          MDBX_env_flags_t flags, mdbx_mode_t mode) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -11909,7 +11917,7 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname, | ||||
|     return MDBX_EINVAL; | ||||
|  | ||||
|   if (env->me_lazy_fd != INVALID_HANDLE_VALUE || | ||||
|       (env->me_flags & MDBX_ENV_ACTIVE) != 0) | ||||
|       (env->me_flags & MDBX_ENV_ACTIVE) != 0 || env->me_map) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
|   /* pickup previously mdbx_env_set_flags(), | ||||
| @@ -12236,7 +12244,8 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) { | ||||
|     env->me_flags |= MDBX_FATAL_ERROR; | ||||
| #endif /* MDBX_ENV_CHECKPID */ | ||||
|  | ||||
|   if ((env->me_flags & (MDBX_RDONLY | MDBX_FATAL_ERROR)) == 0 && env->me_txn0) { | ||||
|   if (env->me_map && (env->me_flags & (MDBX_RDONLY | MDBX_FATAL_ERROR)) == 0 && | ||||
|       env->me_txn0) { | ||||
|     if (env->me_txn0->mt_owner && env->me_txn0->mt_owner != mdbx_thread_self()) | ||||
|       return MDBX_BUSY; | ||||
|   } else | ||||
| @@ -18084,7 +18093,7 @@ static __cold int mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn, | ||||
|  | ||||
| __cold int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, | ||||
|                             unsigned flags) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -18149,7 +18158,7 @@ __cold int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, | ||||
|  | ||||
| __cold int mdbx_env_copy(MDBX_env *env, const char *dest_path, | ||||
|                          MDBX_copy_flags_t flags) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -18211,11 +18220,13 @@ __cold int mdbx_env_copy(MDBX_env *env, const char *dest_path, | ||||
|  | ||||
| __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags, | ||||
|                               bool onoff) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
|   if (unlikely(flags & ~ENV_CHANGEABLE_FLAGS)) | ||||
|   if (unlikely(flags & | ||||
|                ((env->me_flags & MDBX_ENV_ACTIVE) ? ~ENV_CHANGEABLE_FLAGS | ||||
|                                                   : ~ENV_USABLE_FLAGS))) | ||||
|     return MDBX_EPERM; | ||||
|  | ||||
|   if (unlikely(env->me_flags & MDBX_RDONLY)) | ||||
| @@ -18224,21 +18235,28 @@ __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags, | ||||
|   if (unlikely(env->me_txn0->mt_owner == mdbx_thread_self())) | ||||
|     return MDBX_BUSY; | ||||
|  | ||||
|   rc = mdbx_txn_lock(env, false); | ||||
|   if (unlikely(rc)) | ||||
|     return rc; | ||||
|   const bool lock_needed = (env->me_map && env->me_txn0 && | ||||
|                             env->me_txn0->mt_owner != mdbx_thread_self()); | ||||
|   bool should_unlock = false; | ||||
|   if (lock_needed) { | ||||
|     rc = mdbx_txn_lock(env, false); | ||||
|     if (unlikely(rc)) | ||||
|       return rc; | ||||
|     should_unlock = true; | ||||
|   } | ||||
|  | ||||
|   if (onoff) | ||||
|     env->me_flags = merge_sync_flags(env->me_flags, flags); | ||||
|   else | ||||
|     env->me_flags &= ~flags; | ||||
|  | ||||
|   mdbx_txn_unlock(env); | ||||
|   if (should_unlock) | ||||
|     mdbx_txn_unlock(env); | ||||
|   return MDBX_SUCCESS; | ||||
| } | ||||
|  | ||||
| __cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -18250,7 +18268,7 @@ __cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) { | ||||
| } | ||||
|  | ||||
| __cold int mdbx_env_set_userctx(MDBX_env *env, void *ctx) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -18263,7 +18281,7 @@ void *__cold mdbx_env_get_userctx(const MDBX_env *env) { | ||||
| } | ||||
|  | ||||
| __cold int mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -18277,7 +18295,7 @@ __cold int mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) { | ||||
| } | ||||
|  | ||||
| __cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -18289,7 +18307,7 @@ __cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) { | ||||
| } | ||||
|  | ||||
| __cold int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -18335,7 +18353,7 @@ __cold int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn, | ||||
|       return err; | ||||
|   } | ||||
|   if (env) { | ||||
|     int err = check_env(env); | ||||
|     int err = check_env(env, true); | ||||
|     if (unlikely(err != MDBX_SUCCESS)) | ||||
|       return err; | ||||
|     if (txn && unlikely(txn->mt_env != env)) | ||||
| @@ -18431,7 +18449,7 @@ __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn, | ||||
|       return err; | ||||
|   } | ||||
|   if (env) { | ||||
|     int err = check_env(env); | ||||
|     int err = check_env(env, false); | ||||
|     if (unlikely(err != MDBX_SUCCESS)) | ||||
|       return err; | ||||
|     if (txn && unlikely(txn->mt_env != env)) | ||||
| @@ -18918,7 +18936,7 @@ static int mdbx_dbi_close_locked(MDBX_env *env, MDBX_dbi dbi) { | ||||
| } | ||||
|  | ||||
| int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -19154,7 +19172,7 @@ int mdbx_set_dupsort(MDBX_txn *txn, MDBX_dbi dbi, MDBX_cmp_func *cmp) { | ||||
|  | ||||
| __cold int mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func, | ||||
|                             void *ctx) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -19273,7 +19291,7 @@ __cold int mdbx_reader_check(MDBX_env *env, int *dead) { | ||||
|  *  Otherwise errcode. */ | ||||
| MDBX_INTERNAL_FUNC __cold int | ||||
| mdbx_cleanup_dead_readers(MDBX_env *env, int rdt_locked, int *dead) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, true); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -19503,7 +19521,7 @@ __cold int mdbx_env_set_syncperiod(MDBX_env *env, unsigned seconds_16dot16) { | ||||
| #endif /* LIBMDBX_NO_EXPORTS_LEGACY_API */ | ||||
|  | ||||
| __cold int mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr) { | ||||
|   int rc = check_env(env); | ||||
|   int rc = check_env(env, false); | ||||
|   if (unlikely(rc != MDBX_SUCCESS)) | ||||
|     return rc; | ||||
|  | ||||
| @@ -20909,7 +20927,7 @@ __cold MDBX_cmp_func *mdbx_get_datacmp(unsigned flags) { | ||||
|  | ||||
| __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option, | ||||
|                                const uint64_t value) { | ||||
|   int err = check_env(env); | ||||
|   int err = check_env(env, false); | ||||
|   if (unlikely(err != MDBX_SUCCESS)) | ||||
|     return err; | ||||
|  | ||||
| @@ -21069,7 +21087,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option, | ||||
|  | ||||
| __cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option, | ||||
|                                uint64_t *value) { | ||||
|   int err = check_env(env); | ||||
|   int err = check_env(env, false); | ||||
|   if (unlikely(err != MDBX_SUCCESS)) | ||||
|     return err; | ||||
|   if (unlikely(!value)) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user