I think there's a simpler solution.
1. Add a new special xattr to trigger the functionality (look at
s3qlcp.py and copy_tree() in fs.py)
2. Have fs.py write directly to the destination directory (which should
be outside the S3QL mountpoint)
3. Start a number of async workers (no need for threads) that, in a
loop, download blocks and write them to a given offset in a given fh.
4. Have the main thread recursively traverse the source and issue "copy"
requests to the workers (through a queue)
5. Wait for all workers to finish.
6. Profit.
I wouldn't even bother putting blocks in the cache - just download and
write to the destination on the fly. It may be worth checking if a block
is *already* in the cache and, if so, skip download though.
With this implementation, blocks referenced by multiple files will be
downloaded multiple times. I think this can be improved upon once the
minimum functionality is working.