#endif
/* Internal error codes, not exposed outside liblmdb */
+#define MDB_NO_META (MDB_LAST_ERRCODE + 9)
#define MDB_NO_ROOT (MDB_LAST_ERRCODE + 10)
#ifdef _WIN32
#define MDB_OWNERDEAD ((int) WAIT_ABANDONED)
"MDB_TXN_PENDING: Transaction already prepared, must abort or commit",
"MDB_CANT_ROLLBACK: Environment can't rollback last transaction",
"MDB_DBIS_BUSY: Can't drop main DBI while other DBIs are open",
+ "MDB_SHORT_WRITE: Fewer bytes were written than requested",
+ "MDB_ENV_BUSY: Environment is busy, can't use previous snapshot",
+ "MDB_IS_READONLY: Can't write in readonly txn or environment",
+ "MDB_ADDR_BUSY: Requested map address is unavailable",
};
char *
* have used LMDB-specific error codes for everything.
*/
switch(err) {
- case ENOENT: /* 2, FILE_NOT_FOUND */
- case EIO: /* 5, ACCESS_DENIED */
case ENOMEM: /* 12, INVALID_ACCESS */
- case EACCES: /* 13, INVALID_DATA */
- case EBUSY: /* 16, CURRENT_DIRECTORY */
case EINVAL: /* 22, BAD_COMMAND */
- case ENOSPC: /* 28, OUT_OF_PAPER */
return strerror(err);
default:
;
{
int rc = 0;
if (env->me_flags & MDB_RDONLY)
- return EACCES;
+ return MDB_IS_READONLY;
if (force || !(env->me_flags & MDB_NOSYNC)
#ifdef _WIN32 /* Sync is normally achieved in Windows by doing WRITE_THROUGH writes */
&& (env->me_flags & MDB_WRITEMAP)
flags |= env->me_flags & MDB_WRITEMAP;
if (env->me_flags & MDB_RDONLY & ~flags) /* write txn in RDONLY env */
- return EACCES;
+ return MDB_IS_READONLY;
if (parent) {
/* Nested transactions:
goto retry_write;
DPRINTF(("Write error: %s", strerror(rc)));
} else {
- rc = EIO; /* TODO: Use which error code? */
+ rc = MDB_SHORT_WRITE;
DPUTS("short write, filesystem full?");
}
}
p = (MDB_page *)env->me_map;
for (i=0; i<NUM_METAS; i++) {
if (!F_ISSET(p->mp_flags, P_META))
- return ENOENT;
+ return MDB_NO_META;
if (env->me_metas[i]->mm_magic != MDB_MAGIC)
return MDB_INVALID;
if (env->me_metas[i]->mm_version != MDB_DATA_VERSION)
#endif
if (rc != Size) {
if (rc == 0 && off == 0)
- return ENOENT;
+ return MDB_NO_META;
rc = rc < 0 ? (int) ErrCode() : MDB_INVALID;
DPRINTF(("read: %s", mdb_strerror(rc)));
return rc;
if (!F_ISSET(p->mp_flags, P_META)) {
if (env->me_flags & MDB_RAWPART)
- return ENOENT;
+ return MDB_NO_META;
DPRINTF(("page %"Yu" not a meta page", p->mp_pgno));
return MDB_INVALID;
}
else if ((unsigned) len == psize * NUM_METAS)
rc = MDB_SUCCESS;
else
- rc = ENOSPC;
+ rc = MDB_SHORT_WRITE;
free(p);
return rc;
}
rc = pwrite(mfd, ptr, len, off);
#endif
if (rc != len) {
- rc = rc < 0 ? ErrCode() : EIO;
+ rc = rc < 0 ? ErrCode() : MDB_SHORT_WRITE;
#ifndef _WIN32
if (rc == EINTR)
goto retry_write;
* instead unmap existing pages to make room for the new map.
*/
if (addr && env->me_map != addr)
- return EBUSY; /* TODO: Make a new MDB_* error code? */
+ return MDB_ADDR_BUSY;
p = (MDB_page *)env->me_map;
env->me_metas[0] = METADATA(p);
#endif
if ((i = mdb_env_read_header(env, prev, &meta)) != 0) {
- if (i != ENOENT)
+ if (i != MDB_NO_META)
return i;
DPUTS("new mdbenv");
newenv = 1;
rc = MDB_VERSION_MISMATCH;
goto fail;
}
- rc = ErrCode();
- if (rc && rc != EACCES && rc != EAGAIN) {
- goto fail;
- }
#ifdef _WIN32
mdb_env_mname_init(env);
env->me_rmutex = OpenMutexA(SYNCHRONIZE, FALSE, MUTEXNAME(env, 'r'));
if (rc)
goto leave;
if ((flags & MDB_PREVSNAPSHOT) && !excl) {
- rc = EAGAIN;
+ rc = MDB_ENV_BUSY;
goto leave;
}
}
flags &= ~MDB_NOSPILL;
if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))
- return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
+ return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? MDB_IS_READONLY : MDB_BAD_TXN;
if (key->mv_size-1 >= ENV_MAXKEY(env))
return MDB_BAD_VALSIZE;
int rc;
if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))
- return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
+ return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? MDB_IS_READONLY : MDB_BAD_TXN;
if (!(mc->mc_flags & C_INITIALIZED))
return EINVAL;
return EINVAL;
if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))
- return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
+ return (txn->mt_flags & MDB_TXN_RDONLY) ? MDB_IS_READONLY : MDB_BAD_TXN;
if (!F_ISSET(txn->mt_dbs[dbi].md_flags, MDB_DUPSORT)) {
/* must ignore any data */
return EINVAL;
if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))
- return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
+ return (txn->mt_flags & MDB_TXN_RDONLY) ? MDB_IS_READONLY : MDB_BAD_TXN;
MDB_TRACE(("%p, %u, %"Z"u[%s], %"Z"u%s, %u",
txn, dbi, key ? key->mv_size:0, DKEY(key), data->mv_size, mdb_dval(txn, dbi, data, dbuf), flags));
wsize -= len;
continue;
} else {
- rc = EIO;
+ rc = MDB_SHORT_WRITE;
break;
}
}
continue;
} else {
/* Non-blocking or async handles are not supported */
- rc = EIO;
+ rc = MDB_SHORT_WRITE;
break;
}
}
wsize -= len;
continue;
} else {
- rc = EIO;
+ rc = MDB_SHORT_WRITE;
break;
}
}
w3 -= len;
continue;
} else {
- rc = EIO;
+ rc = MDB_SHORT_WRITE;
goto leave;
}
}
if (rc != MDB_NOTFOUND || !(flags & MDB_CREATE))
return rc;
if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY))
- return EACCES;
+ return MDB_IS_READONLY;
}
/* Done here so we cannot fail after creating a new DB */
return EINVAL;
if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY))
- return EACCES;
+ return MDB_IS_READONLY;
if (TXN_DBI_CHANGED(txn, dbi))
return MDB_BAD_DBI;