blob: a99aa1df89d6f694154dd527906b098996f11514 [file] [log] [blame]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_BLOCK_DRIVERS_RAMDISK_V2_RAMDISK_H_
#define SRC_DEVICES_BLOCK_DRIVERS_RAMDISK_V2_RAMDISK_H_
#include <fidl/fuchsia.hardware.ramdisk/cpp/wire.h>
#include <lib/driver/component/cpp/driver_base.h>
#include <lib/fzl/owned-vmo-mapper.h>
#include <lib/sync/completion.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>
#include <memory>
#include <mutex>
#include <vector>
#include "src/devices/block/drivers/ramdisk/v2/ramdisk-controller.h"
#include "src/storage/lib/block_server/block_server.h"
namespace ramdisk_v2 {
class Ramdisk : public fidl::WireServer<fuchsia_hardware_ramdisk::Ramdisk>,
public block_server::Interface {
public:
static zx::result<std::unique_ptr<Ramdisk>> Create(
RamdiskController* controller, async_dispatcher_t* dispatcher, zx::vmo vmo,
const block_server::PartitionInfo& partition_info, component::OutgoingDirectory outgoing,
int id, bool publish);
Ramdisk(const Ramdisk&) = delete;
Ramdisk& operator=(const Ramdisk&) = delete;
~Ramdisk();
// FIDL interface Ramdisk
void SetFlags(SetFlagsRequestView request, SetFlagsCompleter::Sync& completer) override;
void Wake(WakeCompleter::Sync& completer) override;
void SleepAfter(SleepAfterRequestView request, SleepAfterCompleter::Sync& completer) override;
void GetBlockCounts(GetBlockCountsCompleter::Sync& completer) override;
private:
Ramdisk(RamdiskController* controller, fzl::OwnedVmoMapper mapping,
const block_server::PartitionInfo& partition_info, component::OutgoingDirectory outgoing)
: controller_(controller),
block_size_(partition_info.block_size),
block_count_(partition_info.block_count),
mapping_(std::move(mapping)),
outgoing_(std::move(outgoing)),
block_server_(partition_info, this) {}
void StartThread(block_server::Thread thread) override;
void OnNewSession(block_server::Session) override;
void OnRequests(cpp20::span<block_server::Request>) override;
// Reads or writes `block_count` blocks (it ignores the count in `request`) at
// `request_block_offset` blocks relative to the request.
zx_status_t ReadWrite(const block_server::Request& request, uint64_t request_block_offset,
uint64_t block_count) TA_EXCL(lock_);
// Returns true if we should fail requests (due to being asleep).
bool ShouldFailRequests() const TA_REQ(lock_);
RamdiskController* controller_;
const uint32_t block_size_;
const uint64_t block_count_;
fzl::OwnedVmoMapper mapping_;
// Guards fields of the ramdisk which may be accessed concurrently.
std::mutex lock_;
std::condition_variable condition_;
fuchsia_hardware_ramdisk::wire::BlockWriteCounts block_counts_ TA_GUARDED(lock_);
std::optional<uint64_t> pre_sleep_write_block_count_ TA_GUARDED(lock_);
std::vector<uint64_t> blocks_written_since_last_barrier_ TA_GUARDED(lock_);
// Flags modified by SetFlags.
fuchsia_hardware_ramdisk::RamdiskFlag flags_ TA_GUARDED(lock_);
component::OutgoingDirectory outgoing_;
block_server::BlockServer block_server_;
};
} // namespace ramdisk_v2
#endif // SRC_DEVICES_BLOCK_DRIVERS_RAMDISK_V2_RAMDISK_H_