I prefered to keep it outside and make chunk_new() not have the responsability to dealloc in order to reuse the memory block as much as possible. In general terms I try to keep alloc/dealloc operations to a minimum, you never know when you are going to deal with sub-optimal memory allocation algorithms on one side, on the other, they tend to be big source of contention on multi-threaded applications most times.

you see, chunk_new here is inside a loop:

 /* Insert the file's data chunk by chunk */
  while (data_ptr < end) {
    chunkLen = DEFAULT_CHUNK_SIZE < (unsigned int)(end - data_ptr) ? DEFAULT_CHUNK_SIZE: (unsigned int)(end - data_ptr);
    oChunk = chunk_new(id, chunkNumber, &targetBuf, (void*)data_ptr, chunkLen, flags );
    memAllocated = targetBuf != data_ptr;
    mongo_insert(gfs->client, gfs->chunks_ns, oChunk, NULL);
    chunk_free(oChunk);
    chunkNumber++;
    data_ptr += chunkLen;
  }

  if( memAllocated ) {
    bson_free( targetBuf );
  }

So the target allocated on targetBuf is reused for every call to chunk_new.

Same on function gridfs_store_file():

  do {
    oChunk = chunk_new(id, chunkNumber, &targetBuf, (void*)buffer, (size_t)chunkLen, flags );
    mongo_insert(gfs->client, gfs->chunks_ns, oChunk, NULL);
    chunk_free(oChunk);
    length += chunkLen;
    chunkNumber++;
    chunkLen = fread(buffer, 1, DEFAULT_CHUNK_SIZE, fd);
  } while (chunkLen != 0);

...
if( targetBuf && targetBuf != buffer ) {
    bson_free( targetBuf );
  }

In the case of gridfile_flush_pendingchunk() we are dealing with a single chunk, so chunk_new could have been responsible of disposing the user buffer...

And then again on gridfile_write_buffer()

...
while( bytes_left >= DEFAULT_CHUNK_SIZE ) {
    oChunk = chunk_new(gfile->id, gfile->chunk_num, &targetBuf, (void*)data, DEFAULT_CHUNK_SIZE, gfile->flags );
    memAllocated = targetBuf != data;
...

if( memAllocated ){
    bson_free( targetBuf );
  }

Also, as I mentioned before, I want to refactor the pre/post processing logic to bring it a notch further to a point where this "targetBuffer" is reused thorough the lifecycle of the gridFile by providing a "context" for general use, which the pre/post processing callback writers can leverage to store this buffer or any other info that could make streaming of data more efficient.