Ignore:
Timestamp:
Oct 30, 2009, 9:39:05 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update 3.3 to 3.3.9

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.3.x/source/locking/brlock.c

    r224 r342  
    372372****************************************************************************/
    373373
    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)
     374static 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. */
    378377{
    379378        bool lock_types_differ = (ex->lock_type != plock->lock_type);
     
    392391
    393392/*********************************************
    394                                              +---------+
    395                                              | ex      |
    396                                              +---------+
    397                               +-------+
    398                               | plock |
    399                               +-------+
     393                                        +---------+
     394                                        | ex      |
     395                                        +---------+
     396                         +-------+
     397                         | plock |
     398                         +-------+
    400399OR....
    401              +---------+
    402              |  ex     |
    403              +---------+
     400        +---------+
     401        |  ex     |
     402        +---------+
    404403**********************************************/
    405404
    406405        if ( (ex->start > (plock->start + plock->size)) ||
    407                         (plock->start > (ex->start + ex->size))) {
     406                (plock->start > (ex->start + ex->size))) {
     407
    408408                /* No overlap with this lock - copy existing. */
     409
    409410                memcpy(&lck_arr[0], ex, sizeof(struct lock_struct));
    410411                return 1;
     
    418419        |       plock               | -> replace with plock.
    419420        +---------------------------+
     421OR
     422             +---------------+
     423             |       ex      |
     424             +---------------+
     425        +---------------------------+
     426        |       plock               | -> replace with plock.
     427        +---------------------------+
     428
    420429**********************************************/
    421430
    422431        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;
    427437        }
    428438
    429439/*********************************************
     440Adjacent after.
     441                        +-------+
     442                        |  ex   |
     443                        +-------+
     444        +---------------+
     445        |   plock       |
     446        +---------------+
     447
     448BECOMES....
     449        +---------------+-------+
     450        |   plock       | ex    | - different lock types.
     451        +---------------+-------+
     452OR.... (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/*********************************************
     476Adjacent before.
     477        +-------+
     478        |  ex   |
     479        +-------+
     480                +---------------+
     481                |   plock       |
     482                +---------------+
     483BECOMES....
     484        +-------+---------------+
     485        | ex    |   plock       | - different lock types
     486        +-------+---------------+
     487
     488OR.... (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/*********************************************
     513Overlap after.
    430514        +-----------------------+
    431515        |          ex           |
     
    434518        |   plock       |
    435519        +---------------+
    436 OR....
    437                         +-------+
    438                         |  ex   |
    439                         +-------+
     520OR
     521               +----------------+
     522               |       ex       |
     523               +----------------+
    440524        +---------------+
    441525        |   plock       |
     
    448532OR.... (merge)
    449533        +-----------------------+
    450         |   ex                  | - same lock type.
     534        |   plock               | - same lock type.
    451535        +-----------------------+
    452536**********************************************/
    453537
    454538        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) ) {
    459541
    460542                /* 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. */
    462544
    463545                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));
    467548                        /* 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;
    471552                } 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;
    478557                }
    479558        }
    480559
    481560/*********************************************
    482    +-----------------------+
    483    |  ex                   |
    484    +-----------------------+
    485            +---------------+
    486            |   plock       |
    487            +---------------+
    488 OR....
    489    +-------+       
    490    |  ex   |
    491    +-------+
    492            +---------------+
    493            |   plock       |
    494            +---------------+
     561Overlap before.
     562        +-----------------------+
     563        |  ex                   |
     564        +-----------------------+
     565                +---------------+
     566                |   plock       |
     567                +---------------+
     568OR
     569        +-------------+
     570        |  ex         |
     571        +-------------+
     572                +---------------+
     573                |   plock       |
     574                +---------------+
     575
    495576BECOMES....
    496    +-------+---------------+
    497    | ex    |   plock       | - different lock types
    498    +-------+---------------+
     577        +-------+---------------+
     578        | ex    |   plock       | - different lock types
     579        +-------+---------------+
    499580
    500581OR.... (merge)
    501    +-----------------------+
    502    | ex                    | - same lock type.
    503    +-----------------------+
     582        +-----------------------+
     583        |      plock            | - same lock type.
     584        +-----------------------+
    504585
    505586**********************************************/
     
    509590                        (ex->start + ex->size <= plock->start + plock->size) ) {
    510591
    511                 *lock_was_added = True;
    512 
    513592                /* 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. */
    515594
    516595                if (lock_types_differ) {
    517596                        memcpy(&lck_arr[0], ex, sizeof(struct lock_struct));
    518                         memcpy(&lck_arr[1], plock, sizeof(struct lock_struct));
    519597                        /* Adjust existing size. */
    520598                        lck_arr[0].size = plock->start - ex->start;
    521                         return 2;
     599                        return 1;
    522600                } 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;
    528606                }
    529607        }
    530608
    531609/*********************************************
     610Complete overlap.
    532611        +---------------------------+
    533612        |        ex                 |
     
    542621OR
    543622        +---------------------------+
    544         |        ex                 | - same lock type.
     623        |        plock              | - same lock type.
    545624        +---------------------------+
    546625**********************************************/
    547626
    548627        if ( (ex->start < plock->start) && (ex->start + ex->size > plock->start + plock->size) ) {
    549                 *lock_was_added = True;
    550628
    551629                if (lock_types_differ) {
     
    554632
    555633                        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));
    558635
    559636                        /* Adjust first existing size. */
     
    561638
    562639                        /* 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;
    566643                } 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;
    570648                }
    571649        }
     
    591669        struct lock_struct *locks = br_lck->lock_data;
    592670        struct lock_struct *tp;
    593         bool lock_was_added = False;
    594671        bool signal_pending_read = False;
    595672
     
    613690                return NT_STATUS_NO_MEMORY;
    614691        }
    615        
     692
    616693        count = 0;
     694
    617695        for (i=0; i < br_lck->num_locks; i++) {
    618696                struct lock_struct *curr_lock = &locks[i];
     
    649727
    650728                        /* 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++;
    659748
    660749        /* We can get the POSIX lock, now see if it needs to
     
    688777        }
    689778
    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
    695788        br_lck->num_locks = count;
    696789        SAFE_FREE(br_lck->lock_data);
     
    891984static bool brl_unlock_posix(struct messaging_context *msg_ctx,
    892985                             struct byte_range_lock *br_lck,
    893                              const struct lock_struct *plock)
     986                             struct lock_struct *plock)
    894987{
    895988        unsigned int i, j, count;
     
    9231016        for (i = 0; i < br_lck->num_locks; i++) {
    9241017                struct lock_struct *lock = &locks[i];
    925                 struct lock_struct tmp_lock[3];
    926                 bool lock_was_added = False;
    9271018                unsigned int tmp_count;
    9281019
     
    9351026                }
    9361027
    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;
    9521033                        }
    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));
    9721036                        count++;
    9731037                        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
    9851060                        /* Optimisation... */
    9861061                        /* We know we're finished here as we can't overlap any
    9871062                           more POSIX locks. Copy the rest of the lock array. */
     1063
    9881064                        if (i < br_lck->num_locks - 1) {
    989                                 memcpy(&tp[count], &locks[i+1], 
     1065                                memcpy(&tp[count], &locks[i+1],
    9901066                                        sizeof(*locks)*((br_lck->num_locks-1) - i));
    9911067                                count += ((br_lck->num_locks-1) - i);
     
    9931069                        break;
    9941070                }
     1071
    9951072        }
    9961073
Note: See TracChangeset for help on using the changeset viewer.