Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-s3 for openSUSE:Factory checked in at 2026-04-09 16:12:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-s3 (Old) and /work/SRC/openSUSE:Factory/.aws-c-s3.new.21863 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-s3" Thu Apr 9 16:12:04 2026 rev:37 rq:1345503 version:0.12.0 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-s3/aws-c-s3.changes 2026-02-13 16:39:51.427374598 +0100 +++ /work/SRC/openSUSE:Factory/.aws-c-s3.new.21863/aws-c-s3.changes 2026-04-09 16:25:07.071433123 +0200 @@ -1,0 +2,8 @@ +Wed Mar 25 10:35:29 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to version 0.12.0 + * Auto - Update S3 Ruleset & Partition by @aws-crt-bot in (#613) + * Optimize the sizes of buffers requested from mem pool + by @DmitriyMusatkin in (#563) + +------------------------------------------------------------------- Old: ---- v0.11.5.tar.gz New: ---- v0.12.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-s3.spec ++++++ --- /var/tmp/diff_new_pack.vS1Nhy/_old 2026-04-09 16:25:08.535493379 +0200 +++ /var/tmp/diff_new_pack.vS1Nhy/_new 2026-04-09 16:25:08.563494532 +0200 @@ -19,7 +19,7 @@ %define library_version 1.0.0 %define library_soversion 0unstable Name: aws-c-s3 -Version: 0.11.5 +Version: 0.12.0 Release: 0 Summary: AWS Cross-Platform, C99 wrapper for cryptography primitives License: Apache-2.0 ++++++ v0.11.5.tar.gz -> v0.12.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/.github/workflows/ci.yml new/aws-c-s3-0.12.0/.github/workflows/ci.yml --- old/aws-c-s3-0.11.5/.github/workflows/ci.yml 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/.github/workflows/ci.yml 2026-03-23 18:14:51.000000000 +0100 @@ -37,7 +37,7 @@ - manylinux2014-x86 - al2-x64 steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -88,7 +88,7 @@ # our base Linux image to Ubuntu 22. extra-build-flag: --cmake-extra=-DCMAKE_EXE_LINKER_FLAGS="-lresolv" steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -104,7 +104,7 @@ matrix: sanitizers: [",thread", ",address,undefined"] steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -117,7 +117,7 @@ linux-shared-libs: runs-on: ubuntu-24.04 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -130,7 +130,7 @@ byo-crypto: runs-on: ubuntu-24.04 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -143,7 +143,7 @@ windows: runs-on: windows-2025 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -159,7 +159,7 @@ matrix: arch: [x86, x64] steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -171,7 +171,7 @@ windows-shared-libs: runs-on: windows-2025 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -183,7 +183,7 @@ windows-app-verifier: runs-on: windows-2025 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -198,7 +198,7 @@ macos: runs-on: macos-14 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -215,7 +215,7 @@ macos-x64: runs-on: macos-14-large # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -234,7 +234,7 @@ downstream: runs-on: ubuntu-24.04 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -247,7 +247,7 @@ linux-debug: runs-on: ubuntu-24.04 # latest steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/.github/workflows/codecov.yml new/aws-c-s3-0.12.0/.github/workflows/codecov.yml --- old/aws-c-s3-0.11.5/.github/workflows/codecov.yml 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/.github/workflows/codecov.yml 2026-03-23 18:14:51.000000000 +0100 @@ -20,7 +20,7 @@ codecov-linux: runs-on: ubuntu-24.04 steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/include/aws/s3/private/s3_default_buffer_pool.h new/aws-c-s3-0.12.0/include/aws/s3/private/s3_default_buffer_pool.h --- old/aws-c-s3-0.11.5/include/aws/s3/private/s3_default_buffer_pool.h 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/include/aws/s3/private/s3_default_buffer_pool.h 2026-03-23 18:14:51.000000000 +0100 @@ -44,6 +44,9 @@ /* Max size of buffer to be allocated from primary. */ size_t primary_cutoff; + /* Min size of buffer to be allocated from primary. */ + size_t primary_min_cutoff; + /* Overall memory allocated for blocks. */ size_t primary_allocated; /* Number of blocks allocated in primary. */ @@ -91,6 +94,9 @@ /* size at which allocations should go to secondary */ size_t primary_size_cutoff; + /* size below which allocations should go to secondary */ + size_t primary_size_min_cutoff; + /* NOTE: See aws_s3_buffer_pool_usage_stats for descriptions of most fields */ size_t mem_limit; @@ -185,6 +191,18 @@ AWS_S3_API struct aws_s3_default_buffer_pool_usage_stats aws_s3_default_buffer_pool_get_usage( struct aws_s3_buffer_pool *buffer_pool); +enum aws_s3_default_buffer_pool_reserved_from { + AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY = 0, + AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY, + AWS_S3_BUFFER_POOL_RESERVED_FROM_SPECIAL, +}; + +/* + * Helper to determine which area of default buffer pool ticket was reserved from. + */ +AWS_S3_API enum aws_s3_default_buffer_pool_reserved_from aws_s3_default_buffer_pool_get_ticket_reserved_from( + struct aws_s3_default_buffer_ticket *ticket); + /* * Trims all unused mem from the pool. * Warning: fairly slow operation, do not use in critical path. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/include/aws/s3/private/s3_request.h new/aws-c-s3-0.12.0/include/aws/s3/private/s3_request.h --- old/aws-c-s3-0.11.5/include/aws/s3/private/s3_request.h 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/include/aws/s3/private/s3_request.h 2026-03-23 18:14:51.000000000 +0100 @@ -240,10 +240,12 @@ */ struct aws_s3_buffer_ticket *ticket; - /* Beginning range of this part. */ + /* Beginning range of this part. */ uint64_t part_range_start; - /* Last byte of this part.*/ + /* Last byte of this part. + * Note: this is available on both put and get, but in put case it can be optimistic, + * ex for unknown content length we dont know what the end will be until we finish reading data. */ uint64_t part_range_end; /* Part number that this request refers to. If this is not a part, this can be 0. (S3 Part Numbers start at 1.) @@ -364,6 +366,11 @@ uint32_t part_number, uint32_t flags); +/* Gets the size of the part payload. + * Range is inclusive (i.e. 0-0 range has 1 byte size). In case of misconfigured range returns 0. */ +AWS_S3_API +uint64_t aws_s3_request_get_payload_size(struct aws_s3_request *request); + /* Set up the request to be sent. Called each time before the request is sent. Will initially call * aws_s3_request_clean_up_send_data to clear out anything previously existing in send_data. */ AWS_S3_API diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/source/s3_auto_ranged_get.c new/aws-c-s3-0.12.0/source/s3_auto_ranged_get.c --- old/aws-c-s3-0.11.5/source/s3_auto_ranged_get.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/source/s3_auto_ranged_get.c 2026-03-23 18:14:51.000000000 +0100 @@ -265,6 +265,10 @@ 1 /*part_number*/, AWS_S3_REQUEST_FLAG_RECORD_RESPONSE_HEADERS | AWS_S3_REQUEST_FLAG_ALLOCATE_BUFFER_FROM_POOL); + /* Note: our current default logic is to do part 1, discover size and then abort if payload its + * too huge We optimistically reserve part size for it */ + request->part_range_start = 0; + request->part_range_end = meta_request->part_size - 1; ++auto_ranged_get->synced_data.num_parts_requested; break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/source/s3_auto_ranged_put.c new/aws-c-s3-0.12.0/source/s3_auto_ranged_put.c --- old/aws-c-s3-0.11.5/source/s3_auto_ranged_put.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/source/s3_auto_ranged_put.c 2026-03-23 18:14:51.000000000 +0100 @@ -323,6 +323,36 @@ .pause = s_s3_auto_ranged_put_pause, }; +/** + * Helper to initialize the request ranges and content-length + * based on the request->part_number and meta_request->part_size + */ +static int s_compute_request_body_size(const struct aws_s3_meta_request *meta_request, struct aws_s3_request *request) { + AWS_ERROR_PRECONDITION(meta_request); + AWS_ERROR_PRECONDITION(request); + + const struct aws_s3_auto_ranged_put *auto_ranged_put = meta_request->impl; + + size_t request_body_size = meta_request->part_size; + /* Last part--adjust size to match remaining content length. */ + if (auto_ranged_put->has_content_length && + request->part_number == auto_ranged_put->total_num_parts_from_content_length) { + size_t content_remainder = (size_t)(auto_ranged_put->content_length % (uint64_t)meta_request->part_size); + + if (content_remainder > 0) { + request_body_size = content_remainder; + } + } + if (aws_mul_u64_checked(request->part_number - 1, meta_request->part_size, &request->part_range_start)) { + return AWS_OP_ERR; + } + if (aws_add_u64_checked(request->part_range_start, request_body_size - 1, &request->part_range_end)) { + return AWS_OP_ERR; + } + request->content_length = request_body_size; + return AWS_OP_SUCCESS; +} + /* Allocate a new auto-ranged put meta request */ struct aws_s3_meta_request *aws_s3_meta_request_auto_ranged_put_new( struct aws_allocator *allocator, @@ -605,6 +635,8 @@ request->part_number = auto_ranged_put->threaded_update_data.next_part_number; + s_compute_request_body_size(meta_request, request); + /* If request was previously uploaded, we prepare it to ensure checksums still match, * but ultimately it gets marked no-op and we don't send it */ request->was_previously_uploaded = request_previously_uploaded; @@ -761,36 +793,6 @@ return work_remaining; } -/** - * Helper to initialize the request ranges and content-length - * based on the request->part_number and meta_request->part_size - */ -static int s_compute_request_body_size(const struct aws_s3_meta_request *meta_request, struct aws_s3_request *request) { - AWS_ERROR_PRECONDITION(meta_request); - AWS_ERROR_PRECONDITION(request); - - const struct aws_s3_auto_ranged_put *auto_ranged_put = meta_request->impl; - - size_t request_body_size = meta_request->part_size; - /* Last part--adjust size to match remaining content length. */ - if (auto_ranged_put->has_content_length && - request->part_number == auto_ranged_put->total_num_parts_from_content_length) { - size_t content_remainder = (size_t)(auto_ranged_put->content_length % (uint64_t)meta_request->part_size); - - if (content_remainder > 0) { - request_body_size = content_remainder; - } - } - if (aws_mul_u64_checked(request->part_number - 1, meta_request->part_size, &request->part_range_start)) { - return AWS_OP_ERR; - } - if (aws_add_u64_checked(request->part_range_start, request_body_size - 1, &request->part_range_end)) { - return AWS_OP_ERR; - } - request->content_length = request_body_size; - return AWS_OP_SUCCESS; -} - static int s_verify_part_matches_checksum( struct aws_allocator *allocator, struct aws_byte_cursor body_cur, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/source/s3_client.c new/aws-c-s3-0.12.0/source/s3_client.c --- old/aws-c-s3-0.11.5/source/s3_client.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/source/s3_client.c 2026-03-23 18:14:51.000000000 +0100 @@ -11,6 +11,7 @@ #include "aws/s3/private/s3_default_meta_request.h" #include "aws/s3/private/s3_meta_request_impl.h" #include "aws/s3/private/s3_parallel_input_stream.h" +#include "aws/s3/private/s3_request.h" #include "aws/s3/private/s3_request_messages.h" #include "aws/s3/private/s3_util.h" #include "aws/s3/private/s3express_credentials_provider_impl.h" @@ -2059,7 +2060,10 @@ aws_s3_meta_request_prepare_request_callback_fn *callback, void *user_data) { - if (request->ticket == NULL && request->should_allocate_buffer_from_pool) { + size_t request_size = (size_t)aws_s3_request_get_payload_size(request); + AWS_ASSERT(request_size != 0); /* Note: 0 request size is invalid in all cases. */ + + if (request->ticket == NULL && request->should_allocate_buffer_from_pool && request_size > 0) { if (request->send_data.metrics) { struct aws_s3_request_metrics *metric = request->send_data.metrics; @@ -2069,10 +2073,11 @@ struct aws_allocator *allocator = request->allocator; struct aws_s3_meta_request *meta_request = request->meta_request; + struct aws_s3_buffer_pool_reserve_meta meta = { .client = client, .meta_request = meta_request, - .size = request->buffer_size, + .size = request_size, }; struct aws_s3_reserve_memory_payload *payload = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/source/s3_default_buffer_pool.c new/aws-c-s3-0.12.0/source/s3_default_buffer_pool.c --- old/aws-c-s3-0.11.5/source/s3_default_buffer_pool.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/source/s3_default_buffer_pool.c 2026-03-23 18:14:51.000000000 +0100 @@ -51,7 +51,7 @@ size_t chunks_used; bool forced; struct aws_s3_buffer_pool *pool; - bool is_special_block; /* True if this ticket is from a special-sized block */ + enum aws_s3_default_buffer_pool_reserved_from reserved_from; /* which area ticket was reserved from */ }; /* Default size for blocks array. Note: this is just for meta info, blocks @@ -83,6 +83,12 @@ static const size_t s_max_impact_of_forced_buffers_on_memory_limit_as_percentage = 80; /* + * primary min cut off. below this number buffers are not allocated from primary and instead use + * secondary. + */ +static const size_t s_primary_min_cutoff = KB_TO_BYTES(512); + +/* * Sets n bits at position starting with LSB. * Note: n must be at most 8, but in practice will always be at most 4. * position + n should at most be 16 @@ -232,6 +238,20 @@ chunk_size = 0; } + /* + * Determine the min cutoff. At high level this tries to avoid using buffer pool if requests + * are small compared to primary (ex. 512 req buffer compared to 8mb buffer size). + * How that is done is fairly arbitrary. System allocator tends to be a bit better on tiny allocations. + * And we want to avoid wasting mem in that case. + * Note this is not the answer for wasting mem, but it does improve some corner cases. + */ + size_t min_primary_size = 0; + if (4 * chunk_size >= s_primary_min_cutoff) { + min_primary_size = s_primary_min_cutoff; + } else { + min_primary_size = 0; + } + size_t page_size = aws_system_info_page_size(); /* TODO: if people override their allocator, this will not wrap their allocator at all. eg: mem-tracing allocator * will be ignored. */ @@ -248,6 +268,7 @@ * Tries to balance between how many allocations use buffer and buffer space * being wasted. */ buffer_pool->primary_size_cutoff = chunk_size * 4; + buffer_pool->primary_size_min_cutoff = min_primary_size; buffer_pool->mem_limit = adjusted_mem_lim; int mutex_error = aws_mutex_init(&buffer_pool->mutex); @@ -395,16 +416,22 @@ if (ticket->ptr == NULL) { /* Ticket was never used, make sure to clean up reserved count. */ - if (ticket->is_special_block) { - buffer_pool->special_blocks_reserved -= ticket->size; - } else if (ticket->size <= buffer_pool->primary_size_cutoff) { - buffer_pool->primary_reserved -= ticket->size; - } else { - buffer_pool->secondary_reserved -= ticket->size; + switch (ticket->reserved_from) { + case AWS_S3_BUFFER_POOL_RESERVED_FROM_SPECIAL: + buffer_pool->special_blocks_reserved -= ticket->size; + break; + case AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY: + buffer_pool->primary_reserved -= ticket->size; + break; + case AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY: + buffer_pool->secondary_reserved -= ticket->size; + break; + default: + AWS_ASSERT(false); /* someone forgot to update this after adding new member. */ } } else { /* Handle special block returns */ - if (ticket->is_special_block) { + if (ticket->reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_SPECIAL) { struct aws_hash_element *elem = NULL; aws_hash_table_find(&buffer_pool->special_blocks, (void *)ticket->size, &elem); /* TODO: the lifetime between the ticket and the special block, let's assume the block will always be @@ -427,7 +454,7 @@ /* Make sure we do find where the ticket buffer from the list. */ AWS_FATAL_ASSERT(found); buffer_pool->special_blocks_used -= ticket->size; - } else if (ticket->size <= buffer_pool->primary_size_cutoff) { + } else if (ticket->reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY) { size_t chunks_used = ticket->size / buffer_pool->chunk_size; if (ticket->size % buffer_pool->chunk_size != 0) { @@ -455,13 +482,15 @@ if (ticket->forced) { buffer_pool->forced_used -= ticket->size; } - } else { + } else if (ticket->reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY) { aws_mem_release(buffer_pool->base_allocator, ticket->ptr); buffer_pool->secondary_used -= ticket->size; if (ticket->forced) { buffer_pool->forced_used -= ticket->size; } + } else { + AWS_ASSERT(false); /* someone forgot to update this after adding new member. */ } } aws_mem_release(buffer_pool->base_allocator, ticket); @@ -608,11 +637,29 @@ /* Check if this is a special-sized allocation */ if (from_special) { - ticket->is_special_block = true; + ticket->reserved_from = AWS_S3_BUFFER_POOL_RESERVED_FROM_SPECIAL; buffer_pool->special_blocks_reserved += meta.size; } else if (meta.size <= buffer_pool->primary_size_cutoff) { - buffer_pool->primary_reserved += meta.size; + /* This needs to be smarter. Currently if primary req size is below limit, it will allocate full block, + which can be above limit. */ + if (meta.size <= buffer_pool->primary_size_min_cutoff) { + ticket->reserved_from = AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY; + buffer_pool->secondary_reserved += meta.size; + } else { + if ((buffer_pool->primary_used + buffer_pool->primary_reserved + meta.size) > + buffer_pool->primary_allocated && + (overall_taken + buffer_pool->block_size) > buffer_pool->mem_limit) { + /* allocating this from primary would result in exceeding mem limit if new block is created, + so allocate from secondary instead. */ + ticket->reserved_from = AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY; + buffer_pool->secondary_reserved += meta.size; + } else { + ticket->reserved_from = AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY; + buffer_pool->primary_reserved += meta.size; + } + } } else { + ticket->reserved_from = AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY; buffer_pool->secondary_reserved += meta.size; } } @@ -639,6 +686,12 @@ ticket->forced = true; ticket->pool = buffer_pool_wrapper; + if (meta.size <= buffer_pool->primary_size_cutoff && meta.size >= buffer_pool->primary_size_min_cutoff) { + ticket->reserved_from = AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY; + } else { + ticket->reserved_from = AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY; + } + } else { ticket = s_try_reserve_synced(buffer_pool_wrapper, meta); } @@ -684,6 +737,7 @@ if (!s_check_bits(block->alloc_bit_mask, chunk_i, chunks_needed)) { alloc_ptr = block->block_ptr + chunk_i * buffer_pool->chunk_size; block->alloc_bit_mask = s_set_bits(block->alloc_bit_mask, chunk_i, chunks_needed); + AWS_LOGF_INFO(AWS_LS_S3_CLIENT, "Reusing existing primary block %zu", i); goto on_allocated; } } @@ -697,6 +751,12 @@ aws_array_list_push_back(&buffer_pool->blocks, &block); alloc_ptr = block.block_ptr; + AWS_LOGF_INFO( + AWS_LS_S3_CLIENT, + "Allocated primary block: size=%zu, total_allocated=%zu", + buffer_pool->block_size, + buffer_pool->primary_allocated); + buffer_pool->primary_allocated += buffer_pool->block_size; on_allocated: @@ -741,13 +801,10 @@ AWS_PRECONDITION(ticket->ptr == NULL); AWS_LOGF_INFO( - AWS_LS_S3_CLIENT, - "s_acquire_buffer_synced: size=%zu, is_special_block=%d", - ticket->size, - ticket->is_special_block); + AWS_LS_S3_CLIENT, "s_acquire_buffer_synced: size=%zu, reserved_from=%u", ticket->size, ticket->reserved_from); /* Check if this is a special-sized allocation */ - if (ticket->is_special_block) { + if (ticket->reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_SPECIAL) { struct aws_hash_element *elem = NULL; aws_hash_table_find(&buffer_pool->special_blocks, (void *)ticket->size, &elem); AWS_FATAL_ASSERT(elem != NULL); @@ -761,13 +818,13 @@ for (size_t i = 0; i < aws_array_list_length(&special_list->blocks); ++i) { struct s3_buffer_pool_block *block; aws_array_list_get_at_ptr(&special_list->blocks, (void **)&block, i); - AWS_LOGF_INFO(AWS_LS_S3_CLIENT, "Checking block %zu: alloc_bit_mask=%u", i, block->alloc_bit_mask); + AWS_LOGF_INFO(AWS_LS_S3_CLIENT, "Checking special block %zu: alloc_bit_mask=%u", i, block->alloc_bit_mask); /* Try to find if any block in the list is not used. */ if (block->alloc_bit_mask == 0) { block->alloc_bit_mask = UINT16_MAX; ticket->ptr = block->block_ptr; AWS_ASSERT(ticket->size == block->block_size); - AWS_LOGF_INFO(AWS_LS_S3_CLIENT, "Reusing existing block %zu", i); + AWS_LOGF_INFO(AWS_LS_S3_CLIENT, "Reusing existing special block %zu", i); break; } } @@ -788,9 +845,10 @@ } buffer_pool->special_blocks_used += ticket->size; buffer_pool->special_blocks_reserved -= ticket->size; - } else if (ticket->size <= buffer_pool->primary_size_cutoff) { + } else if (ticket->reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY) { ticket->ptr = s_primary_acquire_synced(buffer_pool, ticket); } else { + AWS_ASSERT(ticket->reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY); ticket->ptr = aws_mem_acquire(buffer_pool->base_allocator, ticket->size); buffer_pool->secondary_used += ticket->size; @@ -816,6 +874,7 @@ struct aws_s3_default_buffer_pool_usage_stats ret = (struct aws_s3_default_buffer_pool_usage_stats){ .mem_limit = buffer_pool->mem_limit, .primary_cutoff = buffer_pool->primary_size_cutoff, + .primary_min_cutoff = buffer_pool->primary_size_min_cutoff, .primary_allocated = buffer_pool->primary_allocated, .primary_used = buffer_pool->primary_used, .primary_reserved = buffer_pool->primary_reserved, @@ -916,3 +975,9 @@ /* Return the aligned size */ return chunks_needed * buffer_pool->chunk_size; } + +enum aws_s3_default_buffer_pool_reserved_from aws_s3_default_buffer_pool_get_ticket_reserved_from( + struct aws_s3_default_buffer_ticket *ticket) { + AWS_FATAL_ASSERT(ticket); + return ticket->reserved_from; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/source/s3_endpoint_resolver/aws_s3_endpoint_resolver_partition.c new/aws-c-s3-0.12.0/source/s3_endpoint_resolver/aws_s3_endpoint_resolver_partition.c --- old/aws-c-s3-0.11.5/source/s3_endpoint_resolver/aws_s3_endpoint_resolver_partition.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/source/s3_endpoint_resolver/aws_s3_endpoint_resolver_partition.c 2026-03-23 18:14:51.000000000 +0100 @@ -151,112 +151,114 @@ 'e', 'u', 's', 'c', '\\', '\\', '-', '(', 'd', 'e', ')', '\\', '\\', '-', '\\', '\\', 'w', '+', '\\', '\\', '-', '\\', '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', ':', '{', '"', 'e', 'u', 's', 'c', '-', 'd', 'e', '-', 'e', 'a', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', - 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'E', 'U', ' ', '(', 'G', 'e', 'r', 'm', - 'a', 'n', 'y', ')', '"', '}', '}', '}', ',', '{', '"', 'i', 'd', '"', ':', '"', 'a', 'w', 's', '-', - 'i', 's', 'o', '"', ',', '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', ':', '{', '"', 'd', 'n', 's', - 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'c', '2', 's', '.', 'i', 'c', '.', 'g', 'o', 'v', '"', - ',', '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', - '"', ':', '"', 'a', 'p', 'i', '.', 'a', 'w', 's', '.', 'i', 'c', '.', 'g', 'o', 'v', '"', ',', '"', - 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', 'R', 'e', 'g', 'i', 'o', 'n', - '"', ':', '"', 'u', 's', '-', 'i', 's', 'o', '-', 'e', 'a', 's', 't', '-', '1', '"', ',', '"', 'n', - 'a', 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '"', ',', '"', 's', 'u', 'p', 'p', - 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', '"', ':', 't', 'r', 'u', 'e', ',', - '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', '"', ':', 't', 'r', 'u', 'e', '}', - ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 'R', 'e', 'g', 'e', 'x', '"', ':', '"', '^', 'u', 's', '\\', - '\\', '-', 'i', 's', 'o', '\\', '\\', '-', '\\', '\\', 'w', '+', '\\', '\\', '-', '\\', '\\', 'd', '+', '$', - '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', ':', '{', '"', 'a', 'w', 's', '-', 'i', 's', - 'o', '-', 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', - 'i', 'o', 'n', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', ' ', 'g', 'l', 'o', 'b', 'a', 'l', - ' ', 'r', 'e', 'g', 'i', 'o', 'n', '"', '}', ',', '"', 'u', 's', '-', 'i', 's', 'o', '-', 'e', 'a', - 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', - ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', ' ', 'E', 'a', 's', 't', '"', '}', ',', '"', 'u', 's', '-', - 'i', 's', 'o', '-', 'w', 'e', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', - 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', ' ', 'W', 'E', 'S', 'T', '"', - '}', '}', '}', ',', '{', '"', 'i', 'd', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'b', - '"', ',', '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', ':', '{', '"', 'd', 'n', 's', 'S', 'u', 'f', - 'f', 'i', 'x', '"', ':', '"', 's', 'c', '2', 's', '.', 's', 'g', 'o', 'v', '.', 'g', 'o', 'v', '"', - ',', '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', - '"', ':', '"', 'a', 'p', 'i', '.', 'a', 'w', 's', '.', 's', 'c', 'l', 'o', 'u', 'd', '"', ',', '"', - 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', 'R', 'e', 'g', 'i', 'o', 'n', - '"', ':', '"', 'u', 's', '-', 'i', 's', 'o', 'b', '-', 'e', 'a', 's', 't', '-', '1', '"', ',', '"', - 'n', 'a', 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'b', '"', ',', '"', 's', - 'u', 'p', 'p', 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', '"', ':', 't', 'r', - 'u', 'e', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', '"', ':', 't', 'r', - 'u', 'e', '}', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 'R', 'e', 'g', 'e', 'x', '"', ':', '"', '^', - 'u', 's', '\\', '\\', '-', 'i', 's', 'o', 'b', '\\', '\\', '-', '\\', '\\', 'w', '+', '\\', '\\', '-', '\\', - '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', ':', '{', '"', 'a', 'w', - 's', '-', 'i', 's', 'o', '-', 'b', '-', 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', '{', '"', 'd', 'e', - 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', - 'b', ' ', 'g', 'l', 'o', 'b', 'a', 'l', ' ', 'r', 'e', 'g', 'i', 'o', 'n', '"', '}', ',', '"', 'u', - 's', '-', 'i', 's', 'o', 'b', '-', 'e', 'a', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', - 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', 'B', ' ', 'E', - 'a', 's', 't', ' ', '(', 'O', 'h', 'i', 'o', ')', '"', '}', ',', '"', 'u', 's', '-', 'i', 's', 'o', - 'b', '-', 'w', 'e', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', - 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', 'B', ' ', 'W', 'e', 's', 't', '"', '}', - '}', '}', ',', '{', '"', 'i', 'd', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'e', '"', - ',', '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', ':', '{', '"', 'd', 'n', 's', 'S', 'u', 'f', 'f', - 'i', 'x', '"', ':', '"', 'c', 'l', 'o', 'u', 'd', '.', 'a', 'd', 'c', '-', 'e', '.', 'u', 'k', '"', - ',', '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', - '"', ':', '"', 'a', 'p', 'i', '.', 'c', 'l', 'o', 'u', 'd', '-', 'a', 'w', 's', '.', 'a', 'd', 'c', - '-', 'e', '.', 'u', 'k', '"', ',', '"', 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', - 'a', 'l', 'R', 'e', 'g', 'i', 'o', 'n', '"', ':', '"', 'e', 'u', '-', 'i', 's', 'o', 'e', '-', 'w', - 'e', 's', 't', '-', '1', '"', ',', '"', 'n', 'a', 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'i', - 's', 'o', '-', 'e', '"', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', - 't', 'a', 'c', 'k', '"', ':', 't', 'r', 'u', 'e', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', - 'F', 'I', 'P', 'S', '"', ':', 't', 'r', 'u', 'e', '}', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 'R', - 'e', 'g', 'e', 'x', '"', ':', '"', '^', 'e', 'u', '\\', '\\', '-', 'i', 's', 'o', 'e', '\\', '\\', '-', - '\\', '\\', 'w', '+', '\\', '\\', '-', '\\', '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', - 'n', 's', '"', ':', '{', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'e', '-', 'g', 'l', 'o', 'b', - 'a', 'l', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', - 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'e', ' ', 'g', 'l', 'o', 'b', 'a', 'l', ' ', 'r', 'e', 'g', - 'i', 'o', 'n', '"', '}', ',', '"', 'e', 'u', '-', 'i', 's', 'o', 'e', '-', 'w', 'e', 's', 't', '-', - '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'E', - 'U', ' ', 'I', 'S', 'O', 'E', ' ', 'W', 'e', 's', 't', '"', '}', '}', '}', ',', '{', '"', 'i', 'd', - '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'f', '"', ',', '"', 'o', 'u', 't', 'p', 'u', - 't', 's', '"', ':', '{', '"', 'd', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'c', 's', - 'p', '.', 'h', 'c', 'i', '.', 'i', 'c', '.', 'g', 'o', 'v', '"', ',', '"', 'd', 'u', 'a', 'l', 'S', - 't', 'a', 'c', 'k', 'D', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'a', 'p', 'i', '.', - 'a', 'w', 's', '.', 'h', 'c', 'i', '.', 'i', 'c', '.', 'g', 'o', 'v', '"', ',', '"', 'i', 'm', 'p', - 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', 'R', 'e', 'g', 'i', 'o', 'n', '"', ':', '"', - 'u', 's', '-', 'i', 's', 'o', 'f', '-', 's', 'o', 'u', 't', 'h', '-', '1', '"', ',', '"', 'n', 'a', - 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'f', '"', ',', '"', 's', 'u', 'p', - 'p', 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', '"', ':', 't', 'r', 'u', 'e', - ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', '"', ':', 't', 'r', 'u', 'e', - '}', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 'R', 'e', 'g', 'e', 'x', '"', ':', '"', '^', 'u', 's', - '\\', '\\', '-', 'i', 's', 'o', 'f', '\\', '\\', '-', '\\', '\\', 'w', '+', '\\', '\\', '-', '\\', '\\', 'd', - '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', ':', '{', '"', 'a', 'w', 's', '-', - 'i', 's', 'o', '-', 'f', '-', 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', '{', '"', 'd', 'e', 's', 'c', - 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'f', ' ', + 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'A', 'W', 'S', ' ', 'E', 'u', 'r', 'o', + 'p', 'e', 'a', 'n', ' ', 'S', 'o', 'v', 'e', 'r', 'e', 'i', 'g', 'n', ' ', 'C', 'l', 'o', 'u', 'd', + ' ', '(', 'G', 'e', 'r', 'm', 'a', 'n', 'y', ')', '"', '}', '}', '}', ',', '{', '"', 'i', 'd', '"', + ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '"', ',', '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', + ':', '{', '"', 'd', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'c', '2', 's', '.', 'i', + 'c', '.', 'g', 'o', 'v', '"', ',', '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', + 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'a', 'p', 'i', '.', 'a', 'w', 's', '.', 'i', 'c', '.', + 'g', 'o', 'v', '"', ',', '"', 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', + 'R', 'e', 'g', 'i', 'o', 'n', '"', ':', '"', 'u', 's', '-', 'i', 's', 'o', '-', 'e', 'a', 's', 't', + '-', '1', '"', ',', '"', 'n', 'a', 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '"', + ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', '"', + ':', 't', 'r', 'u', 'e', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', '"', + ':', 't', 'r', 'u', 'e', '}', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 'R', 'e', 'g', 'e', 'x', '"', + ':', '"', '^', 'u', 's', '\\', '\\', '-', 'i', 's', 'o', '\\', '\\', '-', '\\', '\\', 'w', '+', '\\', '\\', + '-', '\\', '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', ':', '{', '"', + 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', '{', '"', 'd', 'e', + 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', ' ', 'g', 'l', 'o', 'b', 'a', 'l', ' ', 'r', 'e', 'g', 'i', 'o', 'n', '"', '}', ',', '"', 'u', 's', '-', - 'i', 's', 'o', 'f', '-', 'e', 'a', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', - 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', 'F', ' ', 'E', 'A', 'S', - 'T', '"', '}', ',', '"', 'u', 's', '-', 'i', 's', 'o', 'f', '-', 's', 'o', 'u', 't', 'h', '-', '1', - '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', - ' ', 'I', 'S', 'O', 'F', ' ', 'S', 'O', 'U', 'T', 'H', '"', '}', '}', '}', ',', '{', '"', 'i', 'd', - '"', ':', '"', 'a', 'w', 's', '-', 'u', 's', '-', 'g', 'o', 'v', '"', ',', '"', 'o', 'u', 't', 'p', - 'u', 't', 's', '"', ':', '{', '"', 'd', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'a', - 'm', 'a', 'z', 'o', 'n', 'a', 'w', 's', '.', 'c', 'o', 'm', '"', ',', '"', 'd', 'u', 'a', 'l', 'S', - 't', 'a', 'c', 'k', 'D', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'a', 'p', 'i', '.', - 'a', 'w', 's', '"', ',', '"', 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', - 'R', 'e', 'g', 'i', 'o', 'n', '"', ':', '"', 'u', 's', '-', 'g', 'o', 'v', '-', 'w', 'e', 's', 't', - '-', '1', '"', ',', '"', 'n', 'a', 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'u', 's', '-', 'g', - 'o', 'v', '"', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', + 'i', 's', 'o', '-', 'e', 'a', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', + 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', ' ', 'E', 'a', 's', 't', '"', + '}', ',', '"', 'u', 's', '-', 'i', 's', 'o', '-', 'w', 'e', 's', 't', '-', '1', '"', ':', '{', '"', + 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', + ' ', 'W', 'E', 'S', 'T', '"', '}', '}', '}', ',', '{', '"', 'i', 'd', '"', ':', '"', 'a', 'w', 's', + '-', 'i', 's', 'o', '-', 'b', '"', ',', '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', ':', '{', '"', + 'd', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 's', 'c', '2', 's', '.', 's', 'g', 'o', + 'v', '.', 'g', 'o', 'v', '"', ',', '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', + 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'a', 'p', 'i', '.', 'a', 'w', 's', '.', 's', 'c', 'l', + 'o', 'u', 'd', '"', ',', '"', 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', + 'R', 'e', 'g', 'i', 'o', 'n', '"', ':', '"', 'u', 's', '-', 'i', 's', 'o', 'b', '-', 'e', 'a', 's', + 't', '-', '1', '"', ',', '"', 'n', 'a', 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', + '-', 'b', '"', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', '"', ':', 't', 'r', 'u', 'e', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', '"', ':', 't', 'r', 'u', 'e', '}', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 'R', 'e', 'g', - 'e', 'x', '"', ':', '"', '^', 'u', 's', '\\', '\\', '-', 'g', 'o', 'v', '\\', '\\', '-', '\\', '\\', 'w', - '+', '\\', '\\', '-', '\\', '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', - ':', '{', '"', 'a', 'w', 's', '-', 'u', 's', '-', 'g', 'o', 'v', '-', 'g', 'l', 'o', 'b', 'a', 'l', + 'e', 'x', '"', ':', '"', '^', 'u', 's', '\\', '\\', '-', 'i', 's', 'o', 'b', '\\', '\\', '-', '\\', '\\', + 'w', '+', '\\', '\\', '-', '\\', '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', + '"', ':', '{', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'b', '-', 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'a', 'w', - 's', '-', 'u', 's', '-', 'g', 'o', 'v', ' ', 'g', 'l', 'o', 'b', 'a', 'l', ' ', 'r', 'e', 'g', 'i', - 'o', 'n', '"', '}', ',', '"', 'u', 's', '-', 'g', 'o', 'v', '-', 'e', 'a', 's', 't', '-', '1', '"', - ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'A', 'W', 'S', - ' ', 'G', 'o', 'v', 'C', 'l', 'o', 'u', 'd', ' ', '(', 'U', 'S', '-', 'E', 'a', 's', 't', ')', '"', - '}', ',', '"', 'u', 's', '-', 'g', 'o', 'v', '-', 'w', 'e', 's', 't', '-', '1', '"', ':', '{', '"', - 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'A', 'W', 'S', ' ', 'G', 'o', - 'v', 'C', 'l', 'o', 'u', 'd', ' ', '(', 'U', 'S', '-', 'W', 'e', 's', 't', ')', '"', '}', '}', '}', - ']', ',', '"', 'v', 'e', 'r', 's', 'i', 'o', 'n', '"', ':', '"', '1', '.', '1', '"', '}'}; + 's', '-', 'i', 's', 'o', '-', 'b', ' ', 'g', 'l', 'o', 'b', 'a', 'l', ' ', 'r', 'e', 'g', 'i', 'o', + 'n', '"', '}', ',', '"', 'u', 's', '-', 'i', 's', 'o', 'b', '-', 'e', 'a', 's', 't', '-', '1', '"', + ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', + 'I', 'S', 'O', 'B', ' ', 'E', 'a', 's', 't', ' ', '(', 'O', 'h', 'i', 'o', ')', '"', '}', ',', '"', + 'u', 's', '-', 'i', 's', 'o', 'b', '-', 'w', 'e', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', + 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', 'B', ' ', + 'W', 'e', 's', 't', '"', '}', '}', '}', ',', '{', '"', 'i', 'd', '"', ':', '"', 'a', 'w', 's', '-', + 'i', 's', 'o', '-', 'e', '"', ',', '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', ':', '{', '"', 'd', + 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'c', 'l', 'o', 'u', 'd', '.', 'a', 'd', 'c', + '-', 'e', '.', 'u', 'k', '"', ',', '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', + 'S', 'u', 'f', 'f', 'i', 'x', '"', ':', '"', 'a', 'p', 'i', '.', 'c', 'l', 'o', 'u', 'd', '-', 'a', + 'w', 's', '.', 'a', 'd', 'c', '-', 'e', '.', 'u', 'k', '"', ',', '"', 'i', 'm', 'p', 'l', 'i', 'c', + 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', 'R', 'e', 'g', 'i', 'o', 'n', '"', ':', '"', 'e', 'u', '-', + 'i', 's', 'o', 'e', '-', 'w', 'e', 's', 't', '-', '1', '"', ',', '"', 'n', 'a', 'm', 'e', '"', ':', + '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'e', '"', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', + 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', '"', ':', 't', 'r', 'u', 'e', ',', '"', 's', 'u', + 'p', 'p', 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', '"', ':', 't', 'r', 'u', 'e', '}', ',', '"', 'r', + 'e', 'g', 'i', 'o', 'n', 'R', 'e', 'g', 'e', 'x', '"', ':', '"', '^', 'e', 'u', '\\', '\\', '-', 'i', + 's', 'o', 'e', '\\', '\\', '-', '\\', '\\', 'w', '+', '\\', '\\', '-', '\\', '\\', 'd', '+', '$', '"', ',', + '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', ':', '{', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', + 'e', '-', 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', + 'i', 'o', 'n', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'e', ' ', 'g', 'l', 'o', 'b', + 'a', 'l', ' ', 'r', 'e', 'g', 'i', 'o', 'n', '"', '}', ',', '"', 'e', 'u', '-', 'i', 's', 'o', 'e', + '-', 'w', 'e', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', + 'o', 'n', '"', ':', '"', 'E', 'U', ' ', 'I', 'S', 'O', 'E', ' ', 'W', 'e', 's', 't', '"', '}', '}', + '}', ',', '{', '"', 'i', 'd', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'f', '"', ',', + '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', ':', '{', '"', 'd', 'n', 's', 'S', 'u', 'f', 'f', 'i', + 'x', '"', ':', '"', 'c', 's', 'p', '.', 'h', 'c', 'i', '.', 'i', 'c', '.', 'g', 'o', 'v', '"', ',', + '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', + ':', '"', 'a', 'p', 'i', '.', 'a', 'w', 's', '.', 'h', 'c', 'i', '.', 'i', 'c', '.', 'g', 'o', 'v', + '"', ',', '"', 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', 'G', 'l', 'o', 'b', 'a', 'l', 'R', 'e', 'g', + 'i', 'o', 'n', '"', ':', '"', 'u', 's', '-', 'i', 's', 'o', 'f', '-', 's', 'o', 'u', 't', 'h', '-', + '1', '"', ',', '"', 'n', 'a', 'm', 'e', '"', ':', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'f', + '"', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'D', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', + '"', ':', 't', 'r', 'u', 'e', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', + '"', ':', 't', 'r', 'u', 'e', '}', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 'R', 'e', 'g', 'e', 'x', + '"', ':', '"', '^', 'u', 's', '\\', '\\', '-', 'i', 's', 'o', 'f', '\\', '\\', '-', '\\', '\\', 'w', '+', + '\\', '\\', '-', '\\', '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', 'g', 'i', 'o', 'n', 's', '"', ':', + '{', '"', 'a', 'w', 's', '-', 'i', 's', 'o', '-', 'f', '-', 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', + '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'a', 'w', 's', '-', + 'i', 's', 'o', '-', 'f', ' ', 'g', 'l', 'o', 'b', 'a', 'l', ' ', 'r', 'e', 'g', 'i', 'o', 'n', '"', + '}', ',', '"', 'u', 's', '-', 'i', 's', 'o', 'f', '-', 'e', 'a', 's', 't', '-', '1', '"', ':', '{', + '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', + 'O', 'F', ' ', 'E', 'A', 'S', 'T', '"', '}', ',', '"', 'u', 's', '-', 'i', 's', 'o', 'f', '-', 's', + 'o', 'u', 't', 'h', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', + 'n', '"', ':', '"', 'U', 'S', ' ', 'I', 'S', 'O', 'F', ' ', 'S', 'O', 'U', 'T', 'H', '"', '}', '}', + '}', ',', '{', '"', 'i', 'd', '"', ':', '"', 'a', 'w', 's', '-', 'u', 's', '-', 'g', 'o', 'v', '"', + ',', '"', 'o', 'u', 't', 'p', 'u', 't', 's', '"', ':', '{', '"', 'd', 'n', 's', 'S', 'u', 'f', 'f', + 'i', 'x', '"', ':', '"', 'a', 'm', 'a', 'z', 'o', 'n', 'a', 'w', 's', '.', 'c', 'o', 'm', '"', ',', + '"', 'd', 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', 'D', 'n', 's', 'S', 'u', 'f', 'f', 'i', 'x', '"', + ':', '"', 'a', 'p', 'i', '.', 'a', 'w', 's', '"', ',', '"', 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't', + 'G', 'l', 'o', 'b', 'a', 'l', 'R', 'e', 'g', 'i', 'o', 'n', '"', ':', '"', 'u', 's', '-', 'g', 'o', + 'v', '-', 'w', 'e', 's', 't', '-', '1', '"', ',', '"', 'n', 'a', 'm', 'e', '"', ':', '"', 'a', 'w', + 's', '-', 'u', 's', '-', 'g', 'o', 'v', '"', ',', '"', 's', 'u', 'p', 'p', 'o', 'r', 't', 's', 'D', + 'u', 'a', 'l', 'S', 't', 'a', 'c', 'k', '"', ':', 't', 'r', 'u', 'e', ',', '"', 's', 'u', 'p', 'p', + 'o', 'r', 't', 's', 'F', 'I', 'P', 'S', '"', ':', 't', 'r', 'u', 'e', '}', ',', '"', 'r', 'e', 'g', + 'i', 'o', 'n', 'R', 'e', 'g', 'e', 'x', '"', ':', '"', '^', 'u', 's', '\\', '\\', '-', 'g', 'o', 'v', + '\\', '\\', '-', '\\', '\\', 'w', '+', '\\', '\\', '-', '\\', '\\', 'd', '+', '$', '"', ',', '"', 'r', 'e', + 'g', 'i', 'o', 'n', 's', '"', ':', '{', '"', 'a', 'w', 's', '-', 'u', 's', '-', 'g', 'o', 'v', '-', + 'g', 'l', 'o', 'b', 'a', 'l', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', + 'n', '"', ':', '"', 'a', 'w', 's', '-', 'u', 's', '-', 'g', 'o', 'v', ' ', 'g', 'l', 'o', 'b', 'a', + 'l', ' ', 'r', 'e', 'g', 'i', 'o', 'n', '"', '}', ',', '"', 'u', 's', '-', 'g', 'o', 'v', '-', 'e', + 'a', 's', 't', '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', + '"', ':', '"', 'A', 'W', 'S', ' ', 'G', 'o', 'v', 'C', 'l', 'o', 'u', 'd', ' ', '(', 'U', 'S', '-', + 'E', 'a', 's', 't', ')', '"', '}', ',', '"', 'u', 's', '-', 'g', 'o', 'v', '-', 'w', 'e', 's', 't', + '-', '1', '"', ':', '{', '"', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', '"', ':', '"', + 'A', 'W', 'S', ' ', 'G', 'o', 'v', 'C', 'l', 'o', 'u', 'd', ' ', '(', 'U', 'S', '-', 'W', 'e', 's', + 't', ')', '"', '}', '}', '}', ']', ',', '"', 'v', 'e', 'r', 's', 'i', 'o', 'n', '"', ':', '"', '1', + '.', '1', '"', '}'}; const struct aws_byte_cursor aws_s3_endpoint_resolver_partitions = { - .len = 4878, + .len = 4904, .ptr = (uint8_t *) s_generated_array }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/source/s3_meta_request.c new/aws-c-s3-0.12.0/source/s3_meta_request.c --- old/aws-c-s3-0.11.5/source/s3_meta_request.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/source/s3_meta_request.c 2026-03-23 18:14:51.000000000 +0100 @@ -1425,8 +1425,17 @@ } if (request->part_range_end != object_range_end) { /* In the case where the object size is less than the range requested. It must be return the - * last part to the end of the object. */ - if (object_size != object_range_end + 1 || request->part_range_end < object_range_end) { + * last part to the end of the object. + * Note: that when get with part 1 is used we dont know how big the buffer will be. We + * optimistically allocate part sized buffer, and see if its enough. If its over, the req will + * get canceled. So in that case skip validation on expected size. + */ + bool is_unknown_len_part_req = + request->request_type == AWS_S3_REQUEST_TYPE_GET_OBJECT && + request->request_tag == AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_GET_OBJECT_WITH_PART_NUMBER_1; + + if (!is_unknown_len_part_req && + (object_size != object_range_end + 1 || request->part_range_end < object_range_end)) { /* Something went wrong if it's matching. Log the error. */ AWS_LOGF_ERROR( AWS_LS_S3_META_REQUEST, @@ -1536,7 +1545,7 @@ if (request->send_data.response_body.capacity == 0) { /* Make sure that request is get, since puts can also have ticket allocated, which is used for request body. */ - if (request->request_type == AWS_S3_REQUEST_TYPE_GET_OBJECT && request->ticket != NULL) { + if (successful_response && request->request_type == AWS_S3_REQUEST_TYPE_GET_OBJECT && request->ticket != NULL) { request->send_data.response_body = aws_s3_buffer_ticket_claim(request->ticket); } else { size_t buffer_size = s_dynamic_body_initial_buf_size; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/source/s3_request.c new/aws-c-s3-0.12.0/source/s3_request.c --- old/aws-c-s3-0.11.5/source/s3_request.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/source/s3_request.c 2026-03-23 18:14:51.000000000 +0100 @@ -55,6 +55,14 @@ return request; } +uint64_t aws_s3_request_get_payload_size(struct aws_s3_request *request) { + uint64_t result = 0; + if (aws_sub_u64_checked(request->part_range_end, request->part_range_start, &result) != AWS_OP_SUCCESS) { + return 0; + } + return result + 1; +} + static void s_populate_metrics_from_message(struct aws_s3_request *request, struct aws_http_message *message) { struct aws_byte_cursor out_path; AWS_ZERO_STRUCT(out_path); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/tests/CMakeLists.txt new/aws-c-s3-0.12.0/tests/CMakeLists.txt --- old/aws-c-s3-0.11.5/tests/CMakeLists.txt 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/tests/CMakeLists.txt 2026-03-23 18:14:51.000000000 +0100 @@ -447,6 +447,7 @@ add_test_case(test_s3_buffer_pool_special_size_with_limits) add_test_case(test_s3_buffer_pool_special_size_mixed) add_test_case(test_s3_buffer_pool_special_size_trim) +add_test_case(test_s3_buffer_pool_reserve_tiny_chunks) add_net_test_case(client_update_upload_part_timeout) add_net_test_case(client_meta_request_override_part_size) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/tests/fuzz/fuzz_buffer_pool_special_size.c new/aws-c-s3-0.12.0/tests/fuzz/fuzz_buffer_pool_special_size.c --- old/aws-c-s3-0.11.5/tests/fuzz/fuzz_buffer_pool_special_size.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/tests/fuzz/fuzz_buffer_pool_special_size.c 2026-03-23 18:14:51.000000000 +0100 @@ -179,17 +179,14 @@ } else if (size_type == 1) { /* Primary storage allocation (below primary_cutoff) */ reservation_size = 1024 + (size_value % (primary_cutoff - 1024)); - is_primary = true; } else { /* Secondary storage allocation (above primary_cutoff, below smallest special size) */ size_t secondary_range = special_sizes[0] - primary_cutoff - 1; if (secondary_range > 0) { reservation_size = primary_cutoff + 1 + (size_value % secondary_range); - is_secondary = true; } else { /* Not enough space for secondary, use primary instead */ reservation_size = 1024 + (size_value % (primary_cutoff - 1024)); - is_primary = true; } } @@ -227,6 +224,25 @@ int error = aws_future_s3_buffer_ticket_get_error(future); AWS_FATAL_ASSERT(error == AWS_OP_SUCCESS); + /* Acquire the ticket */ + struct aws_s3_buffer_ticket *ticket = aws_future_s3_buffer_ticket_get_result_by_move(future); + AWS_FATAL_ASSERT(ticket != NULL); + + enum aws_s3_default_buffer_pool_reserved_from reserved_from = + aws_s3_default_buffer_pool_get_ticket_reserved_from(ticket->impl); + + if (reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_SPECIAL) { + AWS_FATAL_ASSERT(is_special); /* we know in advance all special blocks that must be reserved.*/ + is_special = true; + } else if (reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY) { + is_primary = true; /* for primary and secondary there is a lot more rules so rely on pool for where its + allocated from*/ + } else if (reserved_from == AWS_S3_BUFFER_POOL_RESERVED_FROM_SECONDARY) { + is_secondary = true; + } else { + AWS_FATAL_ASSERT(false); + } + /* Update expected reserved based on type we determined earlier (including accidental special size check) */ if (is_special) { expected_special_reserved += reservation_size; @@ -248,10 +264,6 @@ AWS_FATAL_ASSERT(after_reserve_stats.secondary_reserved == expected_secondary_reserved); } - /* Acquire the ticket */ - struct aws_s3_buffer_ticket *ticket = aws_future_s3_buffer_ticket_get_result_by_move(future); - AWS_FATAL_ASSERT(ticket != NULL); - /* Claim the buffer to verify it works */ struct aws_byte_buf buf = aws_s3_buffer_ticket_claim(ticket); AWS_FATAL_ASSERT(buf.buffer != NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.11.5/tests/s3_default_buffer_pool_tests.c new/aws-c-s3-0.12.0/tests/s3_default_buffer_pool_tests.c --- old/aws-c-s3-0.11.5/tests/s3_default_buffer_pool_tests.c 2026-01-13 22:39:24.000000000 +0100 +++ new/aws-c-s3-0.12.0/tests/s3_default_buffer_pool_tests.c 2026-03-23 18:14:51.000000000 +0100 @@ -139,6 +139,7 @@ struct aws_future_s3_buffer_ticket *future2 = aws_s3_default_buffer_pool_reserve( buffer_pool, (struct aws_s3_buffer_pool_reserve_meta){.size = MB_TO_BYTES(32)}); + ASSERT_NOT_NULL(future2); ASSERT_TRUE(aws_future_s3_buffer_ticket_is_done(future2)); ASSERT_INT_EQUALS(aws_future_s3_buffer_ticket_get_error(future2), AWS_OP_SUCCESS); @@ -147,6 +148,9 @@ struct aws_byte_buf buf2 = aws_s3_buffer_ticket_claim(ticket2); ASSERT_NOT_NULL(buf2.buffer); + struct aws_s3_default_buffer_pool_usage_stats stats = aws_s3_default_buffer_pool_get_usage(buffer_pool); + ASSERT_UINT_EQUALS(0, stats.primary_allocated); + for (size_t i = 0; i < 6; ++i) { aws_s3_buffer_ticket_release(tickets[i]); aws_future_s3_buffer_ticket_release(ticket_futures[i]); @@ -234,11 +238,15 @@ struct aws_s3_buffer_ticket *tickets[112]; struct aws_future_s3_buffer_ticket *ticket_futures[112]; for (size_t i = 0; i < 112; ++i) { + AWS_LOGF_DEBUG(0, "reserving buffer %zu", i + 1); ticket_futures[i] = aws_s3_default_buffer_pool_reserve( buffer_pool, (struct aws_s3_buffer_pool_reserve_meta){.size = MB_TO_BYTES(8)}); ASSERT_TRUE(aws_future_s3_buffer_ticket_is_done(ticket_futures[i])); ASSERT_INT_EQUALS(aws_future_s3_buffer_ticket_get_error(ticket_futures[i]), AWS_OP_SUCCESS); tickets[i] = aws_future_s3_buffer_ticket_get_result_by_move(ticket_futures[i]); + ASSERT_INT_EQUALS( + aws_s3_default_buffer_pool_get_ticket_reserved_from(tickets[i]->impl), + AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY); struct aws_byte_buf buf = aws_s3_buffer_ticket_claim(tickets[i]); ASSERT_NOT_NULL(buf.buffer); } @@ -258,6 +266,9 @@ } ASSERT_NOT_NULL(state.ticket); + ASSERT_INT_EQUALS( + aws_s3_default_buffer_pool_get_ticket_reserved_from(state.ticket->impl), + AWS_S3_BUFFER_POOL_RESERVED_FROM_PRIMARY); aws_s3_buffer_ticket_release(state.ticket); aws_future_s3_buffer_ticket_release(over_future); @@ -635,3 +646,36 @@ AWS_TEST_CASE( test_s3_buffer_pool_forced_buffer_wont_stop_reservations, s_test_s3_buffer_pool_forced_buffer_wont_stop_reservations) + +/* Test small requests reserve expected amount of mem without rounding up to part size. */ +static int s_test_s3_buffer_pool_reserve_tiny_chunks(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + const size_t chunk_size = MB_TO_BYTES(8); + const size_t small_size = KB_TO_BYTES(128); + const size_t mem_limit = GB_TO_BYTES(1); + struct aws_s3_buffer_pool *buffer_pool = aws_s3_default_buffer_pool_new( + allocator, (struct aws_s3_buffer_pool_config){.part_size = chunk_size, .memory_limit = mem_limit}); + + struct aws_s3_buffer_ticket *ticket = NULL; + struct aws_future_s3_buffer_ticket *future = + aws_s3_default_buffer_pool_reserve(buffer_pool, (struct aws_s3_buffer_pool_reserve_meta){.size = small_size}); + ASSERT_TRUE(aws_future_s3_buffer_ticket_is_done(future)); + ASSERT_INT_EQUALS(aws_future_s3_buffer_ticket_get_error(future), AWS_OP_SUCCESS); + ticket = aws_future_s3_buffer_ticket_get_result_by_move(future); + struct aws_byte_buf buf = aws_s3_buffer_ticket_claim(ticket); + ASSERT_UINT_EQUALS(small_size, buf.capacity); + + struct aws_s3_default_buffer_pool_usage_stats stats = aws_s3_default_buffer_pool_get_usage(buffer_pool); + ASSERT_INT_EQUALS(small_size, stats.secondary_used); + + aws_s3_buffer_ticket_release(ticket); + aws_future_s3_buffer_ticket_release(future); + + stats = aws_s3_default_buffer_pool_get_usage(buffer_pool); + ASSERT_INT_EQUALS(0, stats.secondary_used); + + /* Cleanup */ + aws_s3_default_buffer_pool_destroy(buffer_pool); + return 0; +} +AWS_TEST_CASE(test_s3_buffer_pool_reserve_tiny_chunks, s_test_s3_buffer_pool_reserve_tiny_chunks)
