Ignore:
Timestamp:
Jun 7, 2010, 9:08:40 AM (15 years ago)
Author:
Silvan Scherrer
Message:

Samba Server 3.5: changes from 3.3

Location:
trunk/server/lib/tdb/common
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/lib/tdb/common/io.c

    r414 r456  
    9090                return -1;
    9191
     92#ifdef __OS2__
     93        // YD we must upgrade read locks to write locks (exclusive), otherwise
     94        // the owner (us) is not allowed to write to the file (different from unix)
     95        TDB_LOG((tdb, TDB_DEBUG_TRACE,"unlocking at %d len=%d before writing.\n", off, len));
     96        tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, 1);
     97        // if a wider previous lock is in effect, we cannot write lock our segment
     98        // (e.g. a lock_upgrade locks all the file), so we hope the previous lock
     99        // is a write lock: do not wait for lock.
     100        tdb_brlock( tdb, off, F_WRLCK, F_SETLK, 0, len);
     101#endif
     102
    92103        if (tdb->map_ptr) {
    93104                memcpy(off + (char *)tdb->map_ptr, buf, len);
     
    115126                                 "write %d bytes at %d in two attempts\n",
    116127                                 len, off));
    117                         return -1;
    118                 }
    119         }
     128
     129#ifdef __OS2__ // remove our lock
     130                        tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, len);
     131#endif
     132                        return -1;
     133                }
     134        }
     135
     136#ifdef __OS2__ // remove our lock
     137        tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, len);
     138#endif
     139
    120140        return 0;
    121141}
  • trunk/server/lib/tdb/common/lock.c

    r414 r456  
    3030#define TDB_MARK_LOCK 0x80000000
    3131
     32#ifdef __OS2__
     33
     34static char* lock_type( int lck)
     35{
     36        static char buffer[16];
     37        switch(lck) {
     38        case F_GETLK: return "F_GETLK";
     39        case F_SETLK: return "F_SETLK";
     40        case F_SETLKW: return "F_SETLKW";
     41        default:
     42                sprintf( buffer, "unknown %d", lck);
     43        }
     44        return buffer;
     45}
     46
     47static char* read_type( int rw)
     48{
     49        static char buffer[16];
     50        switch(rw) {
     51        case F_RDLCK: return "F_RDLCK";
     52        case F_UNLCK: return "F_UNLCK";
     53        case F_WRLCK: return "F_WRLCK";
     54        default:
     55                sprintf( buffer, "unknown %d", rw);
     56        }
     57        return buffer;
     58}
     59
     60static int _mutex_brlock(struct tdb_context *tdb, tdb_off_t offset,
     61               int rw_type, int lck_type, int probe, size_t len)
     62{
     63        HMTX    hSem;
     64        ULONG   ulTimeout;
     65        APIRET  rc;
     66       
     67        switch( offset) {
     68        case GLOBAL_LOCK:
     69                hSem = tdb->hGlobalLock;
     70                break;
     71        case ACTIVE_LOCK:
     72                hSem = tdb->hActiveLock;
     73                break;
     74        case TRANSACTION_LOCK:
     75                hSem = tdb->hTransactionLock;
     76                break;
     77        default:
     78                TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown offset %d\n", offset));
     79                exit(1);
     80        }
     81        if (hSem == 0) {
     82                TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown sem handle offset %d\n", offset));
     83                exit(1);
     84        }
     85
     86        TDB_LOG((tdb, TDB_DEBUG_TRACE,"_mutex_brlock handle %d, offset %d\n", hSem, offset));
     87
     88        if (lck_type == F_SETLKW)
     89                ulTimeout = SEM_INDEFINITE_WAIT;
     90        else
     91                ulTimeout = SEM_IMMEDIATE_RETURN;
     92
     93        switch (rw_type) {
     94        case F_UNLCK:
     95                rc = DosReleaseMutexSem( hSem);
     96                break;
     97        case F_RDLCK:
     98        case F_WRLCK:
     99                rc = DosRequestMutexSem( hSem, ulTimeout);
     100                break;
     101        default:
     102                TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown rw_type request %d\n", rw_type));
     103                exit(1);
     104                        break;
     105        }
     106
     107        if (rc == NO_ERROR
     108                || rc == ERROR_SEM_OWNER_DIED
     109                || rc == ERROR_NOT_OWNER)
     110                return 0;
     111
     112        errno = EINVAL;
     113        TDB_LOG(( tdb, TDB_DEBUG_ERROR, "_mutex_brlock pid %X, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d, rc=%d\n",
     114                 getpid(), tdb->fd, offset, rw_type, lck_type, (int)len, rc));
     115        tdb->ecode = TDB_ERR_LOCK;
     116        return -1;
     117}
     118#endif
     119
    32120void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
    33121{
     
    46134               int rw_type, int lck_type, int probe, size_t len)
    47135{
     136
     137#ifdef __OS2__
     138        APIRET      rc;
     139        ULONG       fAccess = 0;
     140        int         fLock = 0;
     141        ULONG       ulTimeout;
     142        off_t       cbFile;
     143        off_t       offStart;
     144        off_t       cbRange;
     145
     146        TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_brlock pid %X, fd %d, lck_type %s, rw_type %s, offset %d, len %d\n",
     147                getpid(), tdb->fd, lock_type(lck_type), read_type(rw_type), offset, len));
     148       
     149        switch( offset) {
     150        case GLOBAL_LOCK:
     151        case ACTIVE_LOCK:
     152        case TRANSACTION_LOCK:
     153                return _mutex_brlock( tdb, offset, rw_type,  lck_type,  probe, len);
     154        }
     155
     156        if (tdb->flags & TDB_NOLOCK) {
     157                return 0;
     158        }
     159
     160        if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) {
     161                tdb->ecode = TDB_ERR_RDONLY;
     162                return -1;
     163        }
     164
     165        /* flags and order */
     166        fAccess = 0; /* exclusive */
     167        switch (rw_type)
     168        {
     169                case F_UNLCK:
     170                        fLock = 0;
     171                        break;
     172                case F_RDLCK:
     173                        fAccess = 1; /* read-only */
     174                case F_WRLCK:
     175                        fLock = 1;
     176                        break;
     177                default:
     178                        break;
     179        }
     180       
     181        if (lck_type == F_SETLKW)
     182                ulTimeout = SEM_INDEFINITE_WAIT;
     183        else
     184                ulTimeout = SEM_IMMEDIATE_RETURN;
     185       
     186        FILELOCK   aflock[2];
     187        bzero(&aflock[(fLock + 1) & 1], sizeof(aflock[0]));
     188        aflock[fLock].lOffset = offset;
     189        aflock[fLock].lRange  = len ? len : LONG_MAX;
     190        rc = DosSetFileLocks(tdb->fd, &aflock[0], &aflock[1], SEM_IMMEDIATE_RETURN, fAccess);
     191
     192        if (rc != NO_ERROR && lck_type == F_SETLKW) {
     193                int     count = 20;
     194                do {
     195                        rc = DosSetFileLocks(tdb->fd, &aflock[0], &aflock[1], 100, fAccess);
     196                        count--;
     197                } while( count>0 && rc !=NO_ERROR);
     198
     199        }
     200        if (rc != NO_ERROR) {
     201                errno  = EINVAL;
     202                /* Generic lock error. errno set by fcntl.
     203                 * EAGAIN is an expected return from non-blocking
     204                 * locks. */
     205                if (!probe && lck_type != F_SETLK) {
     206                        /* Ensure error code is set for log fun to examine. */
     207                        tdb->ecode = TDB_ERR_LOCK;
     208                        TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
     209                                 tdb->fd, offset, rw_type, lck_type, (int)len));
     210                }
     211
     212                TDB_LOG(( tdb, TDB_DEBUG_TRACE, "tdb_brlock pid %X, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
     213                         getpid(), tdb->fd, offset, rw_type, lck_type, (int)len));
     214                tdb->ecode = TDB_ERR_LOCK;
     215                return -1;
     216        }
     217
     218        TDB_LOG(( tdb, TDB_DEBUG_TRACE, "tdb_brlock pid %X, fd %d, lck_type %s, rw_type %s, offset %d, len %d DONE\n",
     219                getpid(), tdb->fd, lock_type(lck_type), read_type(rw_type), offset, len));
     220
     221#else
     222
    48223        struct flock fl;
    49224        int ret;
     
    87262        }
    88263        return 0;
     264#endif
    89265}
    90266
     
    101277        while (count--) {
    102278                struct timeval tv;
     279
     280#ifdef __OS2__
     281                // YD we cannot upgrade without an unlock first...
     282                tdb_brlock(tdb, offset, F_UNLCK, F_SETLKW, 1, len);
     283#endif
     284
    103285                if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) {
    104286                        return 0;
  • trunk/server/lib/tdb/common/open.c

    r414 r456  
    2727
    2828#include "tdb_private.h"
     29
     30#ifdef __OS2__
     31// nmbd.c sets it to 1
     32int global_Sem32Add = 0;
     33#endif
    2934
    3035/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
     
    179184        tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash;
    180185
     186#ifdef __OS2__
     187        if (os2_crtsem(tdb, name, "tdb_open_ex") != 0) {
     188                goto fail;
     189        }
     190#endif
     191
    181192        /* cache the page size */
    182193        tdb->page_size = getpagesize();
     
    250261        /* we need to zero database if we are the only one with it open */
    251262        if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
    252             (!tdb->read_only) &&
    253             (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) {
     263            (!tdb->read_only)
     264#ifndef __OS2__
     265            && (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))
     266#endif
     267            ) {
    254268                open_flags |= O_CREAT;
    255269                if (ftruncate(tdb->fd, 0) == -1) {
     
    314328        tdb_mmap(tdb);
    315329        if (locked) {
     330#ifndef __OS2__
    316331                if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) {
    317332                        TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
     
    321336                }
    322337
     338#endif
    323339        }
    324340
     
    327343           users know we're using it. */
    328344
     345#ifndef __OS2__
    329346        if (tdb_flags & TDB_CLEAR_IF_FIRST) {
    330347                /* leave this lock in place to indicate it's in use */
     
    332349                        goto fail;
    333350        }
     351#endif
    334352
    335353        /* if needed, run recovery */
     
    337355                goto fail;
    338356        }
     357
     358#ifdef __OS2__
     359        // YD internal databases do not get global lock!
     360        if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1)
     361                goto fail;
     362#endif
    339363
    340364#ifdef TDB_TRACE
     
    358382         * do with disk files, and resume here by releasing their
    359383         * global lock and hooking into the active list. */
     384#ifndef __OS2__
    360385        if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1)
    361386                goto fail;
     387#endif
    362388        tdb->next = tdbs;
    363         tdbs = tdb;
     389                tdbs = tdb;
    364390        return tdb;
    365391
     
    380406        }
    381407        SAFE_FREE(tdb->name);
     408#ifdef __OS2__
     409        DosCloseMutexSem( tdb->hGlobalLock);
     410        tdb->hGlobalLock = 0;
     411        DosCloseMutexSem( tdb->hActiveLock);
     412        tdb->hActiveLock = 0;
     413        DosCloseMutexSem( tdb->hTransactionLock);
     414        tdb->hTransactionLock = 0;
     415#endif
    382416        if (tdb->fd != -1)
    383417                if (close(tdb->fd) != 0)
     
    420454        }
    421455        SAFE_FREE(tdb->name);
     456#ifdef __OS2__
     457        // YD internal databases do not have a global lock
     458        if (!(tdb->flags & TDB_INTERNAL))
     459                tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLK, 0, 1);
     460#endif
    422461        if (tdb->fd != -1) {
    423462                ret = close(tdb->fd);
     
    425464        }
    426465        SAFE_FREE(tdb->lockrecs);
     466#ifdef __OS2__
     467        DosCloseMutexSem( tdb->hGlobalLock);
     468        tdb->hGlobalLock = 0;
     469        DosCloseMutexSem( tdb->hActiveLock);
     470        tdb->hActiveLock = 0;
     471        DosCloseMutexSem( tdb->hTransactionLock);
     472        tdb->hTransactionLock = 0;
     473#endif
    427474
    428475        /* Remove from contexts list */
     
    465512                return 0; /* Nothing to do. */
    466513        }
     514
     515#ifdef __OS2__
     516        DosCloseMutexSem( tdb->hGlobalLock);
     517        tdb->hGlobalLock = 0;
     518        DosCloseMutexSem( tdb->hActiveLock);
     519        tdb->hActiveLock = 0;
     520        DosCloseMutexSem( tdb->hTransactionLock);
     521        tdb->hTransactionLock = 0;
     522
     523        if (os2_crtsem(tdb, tdb->name, "tdb_reopen") != 0) {
     524                goto fail;
     525        }
     526#endif
    467527
    468528        if (tdb->num_locks != 0 || tdb->global_lock.count) {
     
    551611        return 0;
    552612}
     613
     614#ifdef __OS2__
     615int os2_crtsem(struct tdb_context *tdb, const char *name, const char *caller)
     616{
     617        if (!(tdb->flags & TDB_INTERNAL))
     618        {
     619                char    szSem[_MAX_PATH];
     620                char    drive[_MAX_DRIVE], dir[_MAX_DIR];
     621                char    fname[_MAX_FNAME], ext[_MAX_EXT];
     622                APIRET  rc;
     623                // extract path info
     624                _splitpath( name, drive, dir, fname, ext);
     625                sprintf( szSem, "\\SEM32\\TDB_GL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
     626                rc = DosCreateMutexSem( szSem, &tdb->hGlobalLock, 0, FALSE);
     627                if (rc == ERROR_DUPLICATE_NAME)
     628                        rc = DosOpenMutexSem( szSem, &tdb->hGlobalLock);
     629                if (rc != NO_ERROR) {
     630                                TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
     631                        errno = EINVAL;
     632                        return -1;
     633                }
     634                TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d global handle %d\n", caller, getpid(), tdb->hGlobalLock));
     635
     636                sprintf( szSem, "\\SEM32\\TDB_AL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
     637                rc = DosCreateMutexSem( szSem, &tdb->hActiveLock, 0, FALSE);
     638                if (rc == ERROR_DUPLICATE_NAME)
     639                        rc = DosOpenMutexSem( szSem, &tdb->hActiveLock);
     640                if (rc != NO_ERROR) {
     641                        TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
     642                        errno = EINVAL;
     643                        return -1;
     644                }
     645                TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d active handle %d\n", caller, getpid(), tdb->hActiveLock));
     646
     647                sprintf( szSem, "\\SEM32\\TDB_TL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
     648                rc = DosCreateMutexSem( szSem, &tdb->hTransactionLock, 0, FALSE);
     649                if (rc == ERROR_DUPLICATE_NAME)
     650                        rc = DosOpenMutexSem( szSem, &tdb->hTransactionLock);
     651                if (rc != NO_ERROR) {
     652                        TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
     653                        errno = EINVAL;
     654                        return -1;
     655                }
     656                TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d transaction handle %d\n", caller, getpid(), tdb->hTransactionLock));
     657        }
     658        return 0;
     659}
     660#endif
     661               
  • trunk/server/lib/tdb/common/tdb_private.h

    r414 r456  
    2323   License along with this library; if not, see <http://www.gnu.org/licenses/>.
    2424*/
     25
     26#ifdef __OS2__
     27#define INCL_ERRORS
     28#define INCL_DOS
     29#include <os2.h>
     30#endif
    2531
    2632#include "replace.h"
     
    204210#endif
    205211        volatile sig_atomic_t *interrupt_sig_ptr;
     212#ifdef __OS2__
     213        HMTX    hGlobalLock;
     214        HMTX    hActiveLock;
     215        HMTX    hTransactionLock;
     216#endif
    206217};
    207218
  • trunk/server/lib/tdb/common/transaction.c

    r414 r456  
    495495        /* get a read lock from the freelist to the end of file. This
    496496           is upgraded to a write lock during the commit */
     497#ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough.
    497498        if (tdb_brlock(tdb, FREELIST_TOP, F_RDLCK, F_SETLKW, 0, 0) == -1) {
    498499                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n"));
     
    500501                goto fail;
    501502        }
     503#endif
    502504
    503505        /* setup a copy of the hash table heads so the hash scan in
     
    531533       
    532534fail:
     535#ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough.
    533536        tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
     537#endif
    534538        tdb_transaction_unlock(tdb);
    535539        SAFE_FREE(tdb->transaction->blocks);
     
    632636        tdb->methods = tdb->transaction->io_methods;
    633637
     638#ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough
    634639        tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
     640#endif
    635641        tdb_transaction_unlock(tdb);
    636642        SAFE_FREE(tdb->transaction->hash_heads);
     
    940946
    941947        /* upgrade the main transaction lock region to a write lock */
     948#ifndef __OS2__ // YD the global lock is an exclusive lock for us, it is enough
    942949        if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) {
    943950                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to upgrade hash locks\n"));
     
    946953                return -1;
    947954        }
     955#endif
    948956
    949957        /* get the global lock - this prevents new users attaching to the database
Note: See TracChangeset for help on using the changeset viewer.