ITS#7364 Limit mdb lock upgrade before sem_unlink.

Do not try shared lock when closing or after error.  Track file lock
state to decide.  Change meaning of *excl to reflect file lock state.
vmware
Hallvard Furuseth 12 years ago
parent c760e536ec
commit fe1b3794de
  1. 17
      libraries/libmdb/mdb.c

@ -2775,6 +2775,9 @@ mdb_env_share_locks(MDB_env *env)
return rc; return rc;
} }
/** Try to get exlusive lock, otherwise shared.
* Maintain *excl = -1: no/unknown lock, 0: shared, 1: exclusive.
*/
static int static int
mdb_env_excl_lock(MDB_env *env, int *excl) mdb_env_excl_lock(MDB_env *env, int *excl)
{ {
@ -2798,7 +2801,11 @@ mdb_env_excl_lock(MDB_env *env, int *excl)
lock_info.l_len = 1; lock_info.l_len = 1;
if (!fcntl(env->me_lfd, F_SETLK, &lock_info)) { if (!fcntl(env->me_lfd, F_SETLK, &lock_info)) {
*excl = 1; *excl = 1;
} else { } else
# ifdef MDB_USE_POSIX_SEM
if (*excl < 0) /* always true when !MDB_USE_POSIX_SEM */
# endif
{
lock_info.l_type = F_RDLCK; lock_info.l_type = F_RDLCK;
while ((rc = fcntl(env->me_lfd, F_SETLKW, &lock_info)) && while ((rc = fcntl(env->me_lfd, F_SETLKW, &lock_info)) &&
(rc = ErrCode()) == EINTR) ; (rc = ErrCode()) == EINTR) ;
@ -2896,7 +2903,7 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
int rc; int rc;
off_t size, rsize; off_t size, rsize;
*excl = 0; *excl = -1;
#ifdef _WIN32 #ifdef _WIN32
if ((env->me_lfd = CreateFile(lpath, GENERIC_READ|GENERIC_WRITE, if ((env->me_lfd = CreateFile(lpath, GENERIC_READ|GENERIC_WRITE,
@ -2934,7 +2941,7 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
size = lseek(env->me_lfd, 0, SEEK_END); size = lseek(env->me_lfd, 0, SEEK_END);
#endif #endif
rsize = (env->me_maxreaders-1) * sizeof(MDB_reader) + sizeof(MDB_txninfo); rsize = (env->me_maxreaders-1) * sizeof(MDB_reader) + sizeof(MDB_txninfo);
if (size < rsize && *excl) { if (size < rsize && *excl > 0) {
#ifdef _WIN32 #ifdef _WIN32
SetFilePointer(env->me_lfd, rsize, NULL, 0); SetFilePointer(env->me_lfd, rsize, NULL, 0);
if (!SetEndOfFile(env->me_lfd)) { if (!SetEndOfFile(env->me_lfd)) {
@ -2978,7 +2985,7 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
env->me_txns = m; env->me_txns = m;
#endif #endif
} }
if (*excl) { if (*excl > 0) {
#ifdef _WIN32 #ifdef _WIN32
BY_HANDLE_FILE_INFORMATION stbuf; BY_HANDLE_FILE_INFORMATION stbuf;
struct { struct {
@ -3205,7 +3212,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mode_t mode)
goto leave; goto leave;
} }
#endif #endif
if (excl) { if (excl > 0) {
rc = mdb_env_share_locks(env); rc = mdb_env_share_locks(env);
if (rc) if (rc)
goto leave; goto leave;

Loading…
Cancel
Save