The copyup should be asynchronous from the read so that the read can still complete. The extra write operation will need to be tracked by the ImageCtx so that all outstanding copy-on-read-triggered copyups are complete before destroying the ImageCtx and potentially crashing when the Objecter is shutdown with requests outstanding.

You could do this with a new member of ImageCtx, xlist<librados::AioCompletion> cor_completions, protected by a mutex, so that when a request completed its callback could remove it from the list, and during shutdown the ImageCtx could wait_for_complete() on any remaining completions.