Ignore:
Timestamp:
May 19, 2016, 2:25:59 PM (9 years ago)
Author:
dmik
Message:

tdb: Revert open/lock code to vendor.

This effectively reverts r895, r896 and many earlier commits that would
all attempt to solve the issues with file advisory locking provided by
fcntl() and used to serialize access to TDB files in Samba. All these
issues are to be solved by a proper fcntl() lock implementation provided
now by the new libcx library (https://github.com/bitwiseworks/libcx).

With the current version of libcx tdbtorture works flawlessly for
-n > 1 (it may run out of memory returning ENOLCK but that's a separate
issue that will be solved soon).

File:
1 edited

Legend:

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

    r895 r905  
    3333}
    3434
    35 #ifdef __OS2__
    36 enum os2_fl {
    37     OS2_FL_LOCK = 0x1,
    38     OS2_FL_RW = 0x2,
    39     OS2_FL_WAIT = 0x4,
    40     OS2_FL_UPGRADE = 0x8,
    41 };
    42 
    43 static int os2_set_file_locks(struct tdb_context *tdb, enum os2_fl flags,
    44                               off_t start, off_t offset, off_t len)
    45 {
    46     FILELOCKL locks[2] = {0};
    47     ULONG fl;
    48     BOOL dowait;
    49     APIRET arc;
    50 
    51     if ((!(flags & OS2_FL_UPGRADE) && (start > offset || start < 0)) ||
    52         offset < 0 || offset + len < 0) {
    53         errno = EINVAL;
    54         return -1;
    55     }
    56 
    57     fl = (flags & OS2_FL_RW) ? 0 : 1; /* excluive when rw, shared otherwise */
    58 
    59     if (flags & OS2_FL_UPGRADE) {
    60         locks[0].lOffset = offset;
    61         locks[0].lRange = len == 0 ? OFF_MAX : len;
    62         locks[1] = locks[0];
    63         fl |= 2; /* atomic */
    64     } else {
    65         if (start != offset) {
    66             locks[0].lOffset = start;
    67             locks[0].lRange = offset - start;
    68             fl |= 2; /* atomic */
    69         }
    70         locks[1].lOffset = start;
    71         locks[1].lRange = len == 0 ? OFF_MAX : (locks[0].lRange + len);
    72     }
    73 
    74     dowait = (flags & (OS2_FL_LOCK | OS2_FL_UPGRADE)) && (flags & OS2_FL_WAIT);
    75 
    76     TDB_LOG((tdb, TDB_DEBUG_TRACE, "os2_file_locks: fd=%d lock_fd=%d flags=%x start=%lld offset=%lld len=%lld pid=%d\n",
    77              tdb->fd, tdb->lock_fd, flags, start, offset, len, getpid()));
    78 
    79     arc = DosSetFileLocksL(tdb->lock_fd,
    80                            &locks[(flags & OS2_FL_LOCK) ? 0 : 1],
    81                            &locks[(flags & OS2_FL_LOCK) ? 1 : 0],
    82                            dowait ? SEM_INDEFINITE_WAIT : SEM_IMMEDIATE_RETURN,
    83                            fl);
    84 
    85     TDB_LOG((tdb, TDB_DEBUG_TRACE, "os2_file_locks: arc=%d pid=%d\n", arc, getpid()));
    86 
    87     if (arc) {
    88         switch (arc) {
    89             case ERROR_LOCK_VIOLATION:
    90                 errno = EACCES;
    91                 break;
    92             case ERROR_INTERRUPT:
    93                 errno = EINTR;
    94                 break;
    95             case ERROR_TIMEOUT:
    96                 errno = EDEADLK;
    97                 break;
    98             default:
    99                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "os2_file_locks failed, lock_fd=%d flags=%x start=%d off=%d len=%d (arc=%d)\n",
    100                          tdb->lock_fd, flags, start, offset, len, arc));
    101         }
    102         return -1;
    103     }
    104 
    105     return 0;
    106 }
    107 #else /* __OS2__ */
    10835static int fcntl_lock(struct tdb_context *tdb,
    10936                      int rw, off_t off, off_t len, bool waitflag)
     
    192119        return fcntl(tdb->fd, F_SETLKW, &fl);
    193120}
    194 #endif /* __OS2__ */
    195121
    196122/* list -1 is the alloc list, otherwise a hash chain. */
     
    208134   note that a len of zero means lock to end of file
    209135*/
    210 #ifdef __OS2__
    211 static int tdb_brlock_ex(struct tdb_context *tdb,
    212                          int rw_type, tdb_off_t start,
    213                          tdb_off_t offset, size_t len,
    214                          enum tdb_lock_flags flags)
    215 #else
    216136int tdb_brlock(struct tdb_context *tdb,
    217137               int rw_type, tdb_off_t offset, size_t len,
    218138               enum tdb_lock_flags flags)
    219 #endif
    220139{
    221140        int ret;
     
    234153        }
    235154
    236 #ifdef __OS2__
    237         int os2_flags = OS2_FL_LOCK;
    238         if (rw_type == F_WRLCK) {
    239             os2_flags |= OS2_FL_RW;
    240         }
    241         if (flags & TDB_LOCK_WAIT) {
    242             os2_flags |= OS2_FL_WAIT;
    243         }
    244         if (flags & TDB_LOCK_UPGRADE) {
    245             os2_flags |= OS2_FL_UPGRADE;
    246         }
    247 #endif
    248 
    249155        do {
    250 #ifdef __OS2__
    251                 ret = os2_set_file_locks(tdb, os2_flags, start, offset, len);
    252 #else
    253156                ret = fcntl_lock(tdb, rw_type, offset, len,
    254157                                 flags & TDB_LOCK_WAIT);
    255 #endif
    256158                /* Check for a sigalarm break. */
    257159                if (ret == -1 && errno == EINTR &&
     
    268170                 * locks. */
    269171                if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) {
    270                         TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d flags=%d len=%d (errno=%d)\n",
    271                                  tdb->fd, offset, rw_type, flags, (int)len, errno));
     172                        TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d flags=%d len=%d\n",
     173                                 tdb->fd, offset, rw_type, flags, (int)len));
    272174                }
    273175                return -1;
     
    276178}
    277179
    278 #ifdef __OS2__
    279 int tdb_brlock(struct tdb_context *tdb,
    280                int rw_type, tdb_off_t offset, size_t len,
    281                enum tdb_lock_flags flags)
    282 {
    283     return tdb_brlock_ex(tdb, rw_type, offset, offset, len, flags);
    284 }
    285 #endif
    286 
    287 #ifdef __OS2__
    288 static int tdb_brunlock_ex(struct tdb_context *tdb,
    289                            int rw_type, tdb_off_t start,
    290                            tdb_off_t offset, size_t len)
    291 #else
    292180int tdb_brunlock(struct tdb_context *tdb,
    293181                 int rw_type, tdb_off_t offset, size_t len)
    294 #endif
    295182{
    296183        int ret;
     
    301188
    302189        do {
    303 #ifdef __OS2__
    304                 ret = os2_set_file_locks(tdb, rw_type == F_WRLCK ? OS2_FL_RW : 0,
    305                                          start, offset, len);
    306 #else
    307190                ret = fcntl_unlock(tdb, rw_type, offset, len);
    308 #endif
    309191        } while (ret == -1 && errno == EINTR);
    310192
    311193        if (ret == -1) {
    312                 TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %d rw_type=%d len=%d (errno=%d)\n",
    313                          tdb->fd, offset, rw_type, (int)len, errno));
    314         }
    315         return ret;
    316 }
    317 
    318 #ifdef __OS2__
    319 int tdb_brunlock(struct tdb_context *tdb,
    320                  int rw_type, tdb_off_t offset, size_t len)
    321 {
    322         return tdb_brunlock_ex(tdb, rw_type, offset, offset, len);
    323 }
    324 #endif
     194                TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %d rw_type=%d len=%d\n",
     195                         tdb->fd, offset, rw_type, (int)len));
     196        }
     197        return ret;
     198}
    325199
    326200/*
     
    350224                struct timeval tv;
    351225                if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0,
    352                                TDB_LOCK_WAIT|TDB_LOCK_PROBE|TDB_LOCK_UPGRADE) == 0) {
     226                               TDB_LOCK_WAIT|TDB_LOCK_PROBE) == 0) {
    353227                        tdb->allrecord_lock.ltype = F_WRLCK;
    354228                        tdb->allrecord_lock.off = 0;
     
    640514}
    641515
    642 #ifdef __OS2__
    643 #define TDB_ADJLOCK_START_DECL size_t start,
    644 #define TDB_ADJLOCK_START start,
    645 #define TDB_ADJLOCK(tdb, rw_type, start, offset, len, flags) \
    646         tdb_brlock_ex(tdb, rw_type, start, offset, len, flags)
    647 #define TDB_ADJUNLOCK(tdb, rw_type, start, offset, len) \
    648         tdb_brunlock_ex(tdb, rw_type, start, offset, len)
    649 #define TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start, offset, len) \
    650         tdb_chainlock_gradual(tdb, ltype, flags, start, offset, len)
    651 #else
    652 #define TDB_ADJLOCK_START_DECL
    653 #define TDB_ADJLOCK_START_REF
    654 #define TDB_ADJLOCK(tdb, rw_type, start, offset, len, flags) \
    655         tdb_brlock(tdb, rw_type, offset, len, flags)
    656 #define TDB_ADJUNLOCK(tdb, rw_type, start, offset, len) \
    657         tdb_brunlock(tdb, rw_type, offset, len)
    658 #define TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start, offset, len) \
    659         tdb_chainlock_gradual(tdb, ltype, flags, offset, len)
    660 #endif
    661 
    662516/* We only need to lock individual bytes, but Linux merges consecutive locks
    663517 * so we lock in contiguous ranges. */
    664518static int tdb_chainlock_gradual(struct tdb_context *tdb,
    665519                                 int ltype, enum tdb_lock_flags flags,
    666                                  TDB_ADJLOCK_START_DECL size_t off, size_t len)
     520                                 size_t off, size_t len)
    667521{
    668522        int ret;
     
    671525        if (len <= 4) {
    672526                /* Single record.  Just do blocking lock. */
    673                 return TDB_ADJLOCK(tdb, ltype, start, off, len, flags);
     527                return tdb_brlock(tdb, ltype, off, len, flags);
    674528        }
    675529
    676530        /* First we try non-blocking. */
    677         ret = TDB_ADJLOCK(tdb, ltype, start, off, len, nb_flags);
     531        ret = tdb_brlock(tdb, ltype, off, len, nb_flags);
    678532        if (ret == 0) {
    679533                return 0;
     
    681535
    682536        /* Try locking first half, then second. */
    683         ret = TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start, off, len / 2);
     537        ret = tdb_chainlock_gradual(tdb, ltype, flags, off, len / 2);
    684538        if (ret == -1)
    685539                return -1;
    686540
    687         ret = TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start,
     541        ret = tdb_chainlock_gradual(tdb, ltype, flags,
    688542                                    off + len / 2, len - len / 2);
    689543        if (ret == -1) {
    690                 TDB_ADJUNLOCK(tdb, ltype, start, off, len / 2);
     544                tdb_brunlock(tdb, ltype, off, len / 2);
    691545                return -1;
    692546        }
     
    714568         * It is (1) which cause the starvation problem, so we're only
    715569         * gradual for that. */
    716         if (TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, FREELIST_TOP, FREELIST_TOP,
     570        if (tdb_chainlock_gradual(tdb, ltype, flags, FREELIST_TOP,
    717571                                  tdb->header.hash_size * 4) == -1) {
    718572                return -1;
     
    720574
    721575        /* Grab individual record locks. */
    722         if (TDB_ADJLOCK(tdb, ltype, FREELIST_TOP, lock_offset(tdb->header.hash_size), 0,
    723                         flags) == -1) {
     576        if (tdb_brlock(tdb, ltype, lock_offset(tdb->header.hash_size), 0,
     577                       flags) == -1) {
    724578                tdb_brunlock(tdb, ltype, FREELIST_TOP,
    725579                             tdb->header.hash_size * 4);
Note: See TracChangeset for help on using the changeset viewer.