In class IDiskRemote, all metadata file system operations use os file system api directly.
There is little extendiability if we want store the metadata of HDFS or S3 into distributed file system.
So I suggest change this way by using DiskPtr and will propose a pull request.

In addition, metadata of HDFS or S3 only store local FS which is not sharable.

LOG_INFO(log, "Starting to restore disk {}. Revision: {}, Source bucket: {}, Source path: {}",
                 name, information.revision, information.source_bucket, information.source_path);
        if (readSchemaVersion(information.source_bucket, information.source_path) < RESTORABLE_SCHEMA_VERSION)
            throw Exception("Source bucket doesn't have restorable schema.", ErrorCodes::BAD_ARGUMENTS);
        LOG_INFO(log, "Removing old metadata...");
        bool cleanup_s3 = information.source_bucket != bucket || information.source_path != remote_fs_root_path;
        for (const auto & root : data_roots)
            if (exists(root))
                removeSharedRecursive(root + '/', !cleanup_s3);
        restoreFiles(information);
        restoreFileOperations(information);
        fs::path restore_file = fs::path(metadata_path) / RESTORE_FILE_NAME;
        fs::remove(restore_file);
        saveSchemaVersion(RESTORABLE_SCHEMA_VERSION);
        LOG_INFO(log, "Restore disk {} finished", name);
    }
    catch (const Exception &)
    {
        tryLogCurrentException(log, fmt::format("Failed to restore disk {}", name));
        throw;
    }
}
void DiskS3::restoreFiles(const RestoreInformation & restore_information)
{
    LOG_INFO(log, "Starting restore files for disk {}", name);
    std::vector<std::future<void>> results;
    auto restore_files = [this, &restore_information, &results](auto list_result)
    {
        std::vector<String> keys;
        for (const auto & row : list_result.GetContents())