Changeset 905 for trunk/server
- Timestamp:
- May 19, 2016, 2:25:59 PM (9 years ago)
- Location:
- trunk/server/lib/tdb/common
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server/lib/tdb/common/lock.c
r895 r905 33 33 } 34 34 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__ */108 35 static int fcntl_lock(struct tdb_context *tdb, 109 36 int rw, off_t off, off_t len, bool waitflag) … … 192 119 return fcntl(tdb->fd, F_SETLKW, &fl); 193 120 } 194 #endif /* __OS2__ */195 121 196 122 /* list -1 is the alloc list, otherwise a hash chain. */ … … 208 134 note that a len of zero means lock to end of file 209 135 */ 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 #else216 136 int tdb_brlock(struct tdb_context *tdb, 217 137 int rw_type, tdb_off_t offset, size_t len, 218 138 enum tdb_lock_flags flags) 219 #endif220 139 { 221 140 int ret; … … 234 153 } 235 154 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 #endif248 249 155 do { 250 #ifdef __OS2__251 ret = os2_set_file_locks(tdb, os2_flags, start, offset, len);252 #else253 156 ret = fcntl_lock(tdb, rw_type, offset, len, 254 157 flags & TDB_LOCK_WAIT); 255 #endif256 158 /* Check for a sigalarm break. */ 257 159 if (ret == -1 && errno == EINTR && … … 268 170 * locks. */ 269 171 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)); 272 174 } 273 175 return -1; … … 276 178 } 277 179 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 #endif286 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 #else292 180 int tdb_brunlock(struct tdb_context *tdb, 293 181 int rw_type, tdb_off_t offset, size_t len) 294 #endif295 182 { 296 183 int ret; … … 301 188 302 189 do { 303 #ifdef __OS2__304 ret = os2_set_file_locks(tdb, rw_type == F_WRLCK ? OS2_FL_RW : 0,305 start, offset, len);306 #else307 190 ret = fcntl_unlock(tdb, rw_type, offset, len); 308 #endif309 191 } while (ret == -1 && errno == EINTR); 310 192 311 193 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 } 325 199 326 200 /* … … 350 224 struct timeval tv; 351 225 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) { 353 227 tdb->allrecord_lock.ltype = F_WRLCK; 354 228 tdb->allrecord_lock.off = 0; … … 640 514 } 641 515 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 #else652 #define TDB_ADJLOCK_START_DECL653 #define TDB_ADJLOCK_START_REF654 #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 #endif661 662 516 /* We only need to lock individual bytes, but Linux merges consecutive locks 663 517 * so we lock in contiguous ranges. */ 664 518 static int tdb_chainlock_gradual(struct tdb_context *tdb, 665 519 int ltype, enum tdb_lock_flags flags, 666 TDB_ADJLOCK_START_DECLsize_t off, size_t len)520 size_t off, size_t len) 667 521 { 668 522 int ret; … … 671 525 if (len <= 4) { 672 526 /* 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); 674 528 } 675 529 676 530 /* 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); 678 532 if (ret == 0) { 679 533 return 0; … … 681 535 682 536 /* 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); 684 538 if (ret == -1) 685 539 return -1; 686 540 687 ret = TDB_CHAINLOCK_GRADUAL(tdb, ltype, flags, start,541 ret = tdb_chainlock_gradual(tdb, ltype, flags, 688 542 off + len / 2, len - len / 2); 689 543 if (ret == -1) { 690 TDB_ADJUNLOCK(tdb, ltype, start, off, len / 2);544 tdb_brunlock(tdb, ltype, off, len / 2); 691 545 return -1; 692 546 } … … 714 568 * It is (1) which cause the starvation problem, so we're only 715 569 * 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, 717 571 tdb->header.hash_size * 4) == -1) { 718 572 return -1; … … 720 574 721 575 /* Grab individual record locks. */ 722 if ( TDB_ADJLOCK(tdb, ltype, FREELIST_TOP, lock_offset(tdb->header.hash_size), 0,723 576 if (tdb_brlock(tdb, ltype, lock_offset(tdb->header.hash_size), 0, 577 flags) == -1) { 724 578 tdb_brunlock(tdb, ltype, FREELIST_TOP, 725 579 tdb->header.hash_size * 4); -
trunk/server/lib/tdb/common/open.c
r901 r905 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 120 120 } 121 121 122 /* open the database, creating it if necessary 122 /* open the database, creating it if necessary 123 123 124 124 The open_flags and mode are passed straight to the open call on the … … 126 126 is advisory, use zero for a default value. 127 127 128 Return is NULL on error, in which case errno is also set. Don't 128 Return is NULL on error, in which case errno is also set. Don't 129 129 try to call tdb_error or tdb_errname, just do strerror(errno). 130 130 … … 162 162 return check_header_hash(tdb, false, m1, m2); 163 163 } 164 165 #ifdef __OS2__166 static int os2_create_lockfile(struct tdb_context *tdb, const char *name, const char *origin)167 {168 /* name could be null, so handle it */169 if (name == NULL)170 return 0;171 172 char lock_name[_MAX_PATH + 5];173 snprintf(lock_name, sizeof(lock_name), "%s.lock", name);174 /*175 * First try to O_TRUNC it to make sure the file is empty (this176 * will succeed on first open), but ignore the error that will177 * happen if some bytes are already locked.178 */179 tdb->lock_fd = open(lock_name, tdb->open_flags | O_CREAT | O_TRUNC, 0777);180 if (tdb->lock_fd == -1 && errno == EACCES)181 tdb->lock_fd = open(lock_name, tdb->open_flags | O_CREAT, 0777);182 if (tdb->lock_fd == -1) {183 TDB_LOG((tdb, TDB_DEBUG_ERROR, "os2_create_lockfile: cannot create lock file %s, errno=%d\n",184 lock_name, errno));185 return -1;186 }187 188 return 0;189 }190 #endif191 164 192 165 _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, … … 333 306 fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); 334 307 335 #ifdef __OS2__336 if (os2_create_lockfile(tdb, name, "tdb_open_ex") != 0)337 goto fail;338 #endif339 340 308 /* ensure there is only one process initialising at once */ 341 309 if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { … … 505 473 { int save_errno = errno; 506 474 507 #ifdef __OS2__508 close(tdb->lock_fd);509 tdb->lock_fd = -1;510 #endif511 475 if (!tdb) 512 476 return NULL; … … 577 541 } 578 542 579 #ifdef __OS2__580 close(tdb->lock_fd);581 tdb->lock_fd = -1;582 #endif583 584 543 #ifdef TDB_TRACE 585 544 close(tdb->tracefd); … … 649 608 #endif /* fake pread or pwrite */ 650 609 651 #ifdef __OS2__652 close(tdb->lock_fd);653 tdb->lock_fd = -1;654 655 if (os2_create_lockfile(tdb, tdb->name, "tdb_reopen") != 0)656 goto fail;657 #endif658 610 /* We may still think we hold the active lock. */ 659 611 tdb->num_lockrecs = 0; -
trunk/server/lib/tdb/common/tdb_private.h
r895 r905 23 23 License along with this library; if not, see <http://www.gnu.org/licenses/>. 24 24 */ 25 #ifdef __OS2__26 #define INCL_ERRORS27 #define INCL_DOS28 #include <os2.h>29 #endif30 25 31 26 #include "replace.h" … … 180 175 /* If set, don't actually lock at all. */ 181 176 TDB_LOCK_MARK_ONLY = 4, 182 /* If set, upgrade the existiong lock (used only on OS/2). */183 TDB_LOCK_UPGRADE = 8,184 177 }; 185 178 … … 221 214 #endif 222 215 volatile sig_atomic_t *interrupt_sig_ptr; 223 #ifdef __OS2__224 int lock_fd;225 #endif226 216 }; 227 217
Note:
See TracChangeset
for help on using the changeset viewer.