Changeset 342 for branches/samba-3.3.x/source/locking/brlock.c
- Timestamp:
- Oct 30, 2009, 9:39:05 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.3.x/source/locking/brlock.c
r224 r342 372 372 ****************************************************************************/ 373 373 374 static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, /* Output array. */ 375 const struct lock_struct *ex, /* existing lock. */ 376 const struct lock_struct *plock, /* proposed lock. */ 377 bool *lock_was_added) 374 static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, /* Output array. */ 375 struct lock_struct *ex, /* existing lock. */ 376 struct lock_struct *plock) /* proposed lock. */ 378 377 { 379 378 bool lock_types_differ = (ex->lock_type != plock->lock_type); … … 392 391 393 392 /********************************************* 394 395 396 397 398 399 393 +---------+ 394 | ex | 395 +---------+ 396 +-------+ 397 | plock | 398 +-------+ 400 399 OR.... 401 402 403 400 +---------+ 401 | ex | 402 +---------+ 404 403 **********************************************/ 405 404 406 405 if ( (ex->start > (plock->start + plock->size)) || 407 (plock->start > (ex->start + ex->size))) { 406 (plock->start > (ex->start + ex->size))) { 407 408 408 /* No overlap with this lock - copy existing. */ 409 409 410 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); 410 411 return 1; … … 418 419 | plock | -> replace with plock. 419 420 +---------------------------+ 421 OR 422 +---------------+ 423 | ex | 424 +---------------+ 425 +---------------------------+ 426 | plock | -> replace with plock. 427 +---------------------------+ 428 420 429 **********************************************/ 421 430 422 431 if ( (ex->start >= plock->start) && 423 (ex->start + ex->size <= plock->start + plock->size) ) { 424 memcpy(&lck_arr[0], plock, sizeof(struct lock_struct)); 425 *lock_was_added = True; 426 return 1; 432 (ex->start + ex->size <= plock->start + plock->size) ) { 433 434 /* Replace - discard existing lock. */ 435 436 return 0; 427 437 } 428 438 429 439 /********************************************* 440 Adjacent after. 441 +-------+ 442 | ex | 443 +-------+ 444 +---------------+ 445 | plock | 446 +---------------+ 447 448 BECOMES.... 449 +---------------+-------+ 450 | plock | ex | - different lock types. 451 +---------------+-------+ 452 OR.... (merge) 453 +-----------------------+ 454 | plock | - same lock type. 455 +-----------------------+ 456 **********************************************/ 457 458 if (plock->start + plock->size == ex->start) { 459 460 /* If the lock types are the same, we merge, if different, we 461 add the remainder of the old lock. */ 462 463 if (lock_types_differ) { 464 /* Add existing. */ 465 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); 466 return 1; 467 } else { 468 /* Merge - adjust incoming lock as we may have more 469 * merging to come. */ 470 plock->size += ex->size; 471 return 0; 472 } 473 } 474 475 /********************************************* 476 Adjacent before. 477 +-------+ 478 | ex | 479 +-------+ 480 +---------------+ 481 | plock | 482 +---------------+ 483 BECOMES.... 484 +-------+---------------+ 485 | ex | plock | - different lock types 486 +-------+---------------+ 487 488 OR.... (merge) 489 +-----------------------+ 490 | plock | - same lock type. 491 +-----------------------+ 492 493 **********************************************/ 494 495 if (ex->start + ex->size == plock->start) { 496 497 /* If the lock types are the same, we merge, if different, we 498 add the existing lock. */ 499 500 if (lock_types_differ) { 501 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); 502 return 1; 503 } else { 504 /* Merge - adjust incoming lock as we may have more 505 * merging to come. */ 506 plock->start = ex->start; 507 plock->size += ex->size; 508 return 0; 509 } 510 } 511 512 /********************************************* 513 Overlap after. 430 514 +-----------------------+ 431 515 | ex | … … 434 518 | plock | 435 519 +---------------+ 436 OR ....437 +-------+438 | ex|439 +-------+520 OR 521 +----------------+ 522 | ex | 523 +----------------+ 440 524 +---------------+ 441 525 | plock | … … 448 532 OR.... (merge) 449 533 +-----------------------+ 450 | ex| - same lock type.534 | plock | - same lock type. 451 535 +-----------------------+ 452 536 **********************************************/ 453 537 454 538 if ( (ex->start >= plock->start) && 455 (ex->start <= plock->start + plock->size) && 456 (ex->start + ex->size > plock->start + plock->size) ) { 457 458 *lock_was_added = True; 539 (ex->start <= plock->start + plock->size) && 540 (ex->start + ex->size > plock->start + plock->size) ) { 459 541 460 542 /* If the lock types are the same, we merge, if different, we 461 add the new lock before the old. */543 add the remainder of the old lock. */ 462 544 463 545 if (lock_types_differ) { 464 /* Add new. */ 465 memcpy(&lck_arr[0], plock, sizeof(struct lock_struct)); 466 memcpy(&lck_arr[1], ex, sizeof(struct lock_struct)); 546 /* Add remaining existing. */ 547 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); 467 548 /* Adjust existing start and size. */ 468 lck_arr[ 1].start = plock->start + plock->size;469 lck_arr[ 1].size = (ex->start + ex->size) - (plock->start + plock->size);470 return 2;549 lck_arr[0].start = plock->start + plock->size; 550 lck_arr[0].size = (ex->start + ex->size) - (plock->start + plock->size); 551 return 1; 471 552 } else { 472 /* Merge. */ 473 memcpy(&lck_arr[0], plock, sizeof(struct lock_struct)); 474 /* Set new start and size. */ 475 lck_arr[0].start = plock->start; 476 lck_arr[0].size = (ex->start + ex->size) - plock->start; 477 return 1; 553 /* Merge - adjust incoming lock as we may have more 554 * merging to come. */ 555 plock->size += (ex->start + ex->size) - (plock->start + plock->size); 556 return 0; 478 557 } 479 558 } 480 559 481 560 /********************************************* 482 +-----------------------+ 483 | ex | 484 +-----------------------+ 485 +---------------+ 486 | plock | 487 +---------------+ 488 OR.... 489 +-------+ 490 | ex | 491 +-------+ 492 +---------------+ 493 | plock | 494 +---------------+ 561 Overlap before. 562 +-----------------------+ 563 | ex | 564 +-----------------------+ 565 +---------------+ 566 | plock | 567 +---------------+ 568 OR 569 +-------------+ 570 | ex | 571 +-------------+ 572 +---------------+ 573 | plock | 574 +---------------+ 575 495 576 BECOMES.... 496 +-------+---------------+497 | ex | plock | - different lock types498 +-------+---------------+577 +-------+---------------+ 578 | ex | plock | - different lock types 579 +-------+---------------+ 499 580 500 581 OR.... (merge) 501 +-----------------------+502 | ex| - same lock type.503 +-----------------------+582 +-----------------------+ 583 | plock | - same lock type. 584 +-----------------------+ 504 585 505 586 **********************************************/ … … 509 590 (ex->start + ex->size <= plock->start + plock->size) ) { 510 591 511 *lock_was_added = True;512 513 592 /* If the lock types are the same, we merge, if different, we 514 add the new lock after the old. */593 add the truncated old lock. */ 515 594 516 595 if (lock_types_differ) { 517 596 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); 518 memcpy(&lck_arr[1], plock, sizeof(struct lock_struct));519 597 /* Adjust existing size. */ 520 598 lck_arr[0].size = plock->start - ex->start; 521 return 2;599 return 1; 522 600 } else { 523 /* Merge . */524 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct));525 /* Adjust existing size. */526 lck_arr[0].size = (plock->start + plock->size) -ex->start;527 return 1;601 /* Merge - adjust incoming lock as we may have more 602 * merging to come. MUST ADJUST plock SIZE FIRST ! */ 603 plock->size += (plock->start - ex->start); 604 plock->start = ex->start; 605 return 0; 528 606 } 529 607 } 530 608 531 609 /********************************************* 610 Complete overlap. 532 611 +---------------------------+ 533 612 | ex | … … 542 621 OR 543 622 +---------------------------+ 544 | ex| - same lock type.623 | plock | - same lock type. 545 624 +---------------------------+ 546 625 **********************************************/ 547 626 548 627 if ( (ex->start < plock->start) && (ex->start + ex->size > plock->start + plock->size) ) { 549 *lock_was_added = True;550 628 551 629 if (lock_types_differ) { … … 554 632 555 633 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); 556 memcpy(&lck_arr[1], plock, sizeof(struct lock_struct)); 557 memcpy(&lck_arr[2], ex, sizeof(struct lock_struct)); 634 memcpy(&lck_arr[1], ex, sizeof(struct lock_struct)); 558 635 559 636 /* Adjust first existing size. */ … … 561 638 562 639 /* Adjust second existing start and size. */ 563 lck_arr[ 2].start = plock->start + plock->size;564 lck_arr[ 2].size = (ex->start + ex->size) - (plock->start + plock->size);565 return 3;640 lck_arr[1].start = plock->start + plock->size; 641 lck_arr[1].size = (ex->start + ex->size) - (plock->start + plock->size); 642 return 2; 566 643 } else { 567 /* Just eat plock. */ 568 memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); 569 return 1; 644 /* Just eat the existing locks, merge them into plock. */ 645 plock->start = ex->start; 646 plock->size = ex->size; 647 return 0; 570 648 } 571 649 } … … 591 669 struct lock_struct *locks = br_lck->lock_data; 592 670 struct lock_struct *tp; 593 bool lock_was_added = False;594 671 bool signal_pending_read = False; 595 672 … … 613 690 return NT_STATUS_NO_MEMORY; 614 691 } 615 692 616 693 count = 0; 694 617 695 for (i=0; i < br_lck->num_locks; i++) { 618 696 struct lock_struct *curr_lock = &locks[i]; … … 649 727 650 728 /* Work out overlaps. */ 651 count += brlock_posix_split_merge(&tp[count], curr_lock, plock, &lock_was_added); 652 } 653 } 654 655 if (!lock_was_added) { 656 memcpy(&tp[count], plock, sizeof(struct lock_struct)); 657 count++; 658 } 729 count += brlock_posix_split_merge(&tp[count], curr_lock, plock); 730 } 731 } 732 733 /* Try and add the lock in order, sorted by lock start. */ 734 for (i=0; i < count; i++) { 735 struct lock_struct *curr_lock = &tp[i]; 736 737 if (curr_lock->start <= plock->start) { 738 continue; 739 } 740 } 741 742 if (i < count) { 743 memmove(&tp[i+1], &tp[i], 744 (count - i)*sizeof(struct lock_struct)); 745 } 746 memcpy(&tp[i], plock, sizeof(struct lock_struct)); 747 count++; 659 748 660 749 /* We can get the POSIX lock, now see if it needs to … … 688 777 } 689 778 690 /* Realloc so we don't leak entries per lock call. */ 691 tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks)); 692 if (!tp) { 693 return NT_STATUS_NO_MEMORY; 694 } 779 /* If we didn't use all the allocated size, 780 * Realloc so we don't leak entries per lock call. */ 781 if (count < br_lck->num_locks + 2) { 782 tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks)); 783 if (!tp) { 784 return NT_STATUS_NO_MEMORY; 785 } 786 } 787 695 788 br_lck->num_locks = count; 696 789 SAFE_FREE(br_lck->lock_data); … … 891 984 static bool brl_unlock_posix(struct messaging_context *msg_ctx, 892 985 struct byte_range_lock *br_lck, 893 conststruct lock_struct *plock)986 struct lock_struct *plock) 894 987 { 895 988 unsigned int i, j, count; … … 923 1016 for (i = 0; i < br_lck->num_locks; i++) { 924 1017 struct lock_struct *lock = &locks[i]; 925 struct lock_struct tmp_lock[3];926 bool lock_was_added = False;927 1018 unsigned int tmp_count; 928 1019 … … 935 1026 } 936 1027 937 /* Work out overlaps. */ 938 tmp_count = brlock_posix_split_merge(&tmp_lock[0], &locks[i], plock, &lock_was_added); 939 940 if (tmp_count == 1) { 941 /* Ether the locks didn't overlap, or the unlock completely 942 overlapped this lock. If it didn't overlap, then there's 943 no change in the locks. */ 944 if (tmp_lock[0].lock_type != UNLOCK_LOCK) { 945 SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); 946 /* No change in this lock. */ 947 memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); 948 count++; 949 } else { 950 SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK); 951 overlap_found = True; 1028 if (lock->lock_flav == WINDOWS_LOCK) { 1029 /* Do any Windows flavour locks conflict ? */ 1030 if (brl_conflict(lock, plock)) { 1031 SAFE_FREE(tp); 1032 return false; 952 1033 } 953 continue; 954 } else if (tmp_count == 2) { 955 /* The unlock overlapped an existing lock. Copy the truncated 956 lock into the lock array. */ 957 if (tmp_lock[0].lock_type != UNLOCK_LOCK) { 958 SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); 959 SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK); 960 memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); 961 if (tmp_lock[0].size != locks[i].size) { 962 overlap_found = True; 963 } 964 } else { 965 SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK); 966 SMB_ASSERT(tmp_lock[1].lock_type == locks[i].lock_type); 967 memcpy(&tp[count], &tmp_lock[1], sizeof(struct lock_struct)); 968 if (tmp_lock[1].start != locks[i].start) { 969 overlap_found = True; 970 } 971 } 1034 /* Just copy the Windows lock into the new array. */ 1035 memcpy(&tp[count], lock, sizeof(struct lock_struct)); 972 1036 count++; 973 1037 continue; 974 } else { 975 /* tmp_count == 3 - (we split a lock range in two). */ 976 SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); 977 SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK); 978 SMB_ASSERT(tmp_lock[2].lock_type == locks[i].lock_type); 979 980 memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); 981 count++; 982 memcpy(&tp[count], &tmp_lock[2], sizeof(struct lock_struct)); 983 count++; 984 overlap_found = True; 1038 } 1039 1040 /* Work out overlaps. */ 1041 tmp_count = brlock_posix_split_merge(&tp[count], lock, plock); 1042 1043 if (tmp_count == 0) { 1044 /* plock overlapped the existing lock completely, 1045 or replaced it. Don't copy the existing lock. */ 1046 overlap_found = true; 1047 } else if (tmp_count == 1) { 1048 /* Either no overlap, (simple copy of existing lock) or 1049 * an overlap of an existing lock. */ 1050 /* If the lock changed size, we had an overlap. */ 1051 if (tp[count].size != lock->size) { 1052 overlap_found = true; 1053 } 1054 count += tmp_count; 1055 } else if (tmp_count == 2) { 1056 /* We split a lock range in two. */ 1057 overlap_found = true; 1058 count += tmp_count; 1059 985 1060 /* Optimisation... */ 986 1061 /* We know we're finished here as we can't overlap any 987 1062 more POSIX locks. Copy the rest of the lock array. */ 1063 988 1064 if (i < br_lck->num_locks - 1) { 989 memcpy(&tp[count], &locks[i+1], 1065 memcpy(&tp[count], &locks[i+1], 990 1066 sizeof(*locks)*((br_lck->num_locks-1) - i)); 991 1067 count += ((br_lck->num_locks-1) - i); … … 993 1069 break; 994 1070 } 1071 995 1072 } 996 1073
Note:
See TracChangeset
for help on using the changeset viewer.