--- nono/host/diskimage.h 2026/04/29 17:04:57 1.1 +++ nono/host/diskimage.h 2026/04/29 17:05:11 1.1.1.3 @@ -7,51 +7,93 @@ #pragma once #include "header.h" +#include "autofd.h" +#include +#include + +// ディスクイメージを実際に処理するドライバ +// (DiskImage クラスの下請けになる) +class DiskImageDriver +{ + public: + DiskImageDriver(const std::string& pathname_); + virtual ~DiskImageDriver(); + + virtual bool GetInfo(off_t *size, bool *w_ok) = 0; + virtual bool Open(bool read_only) = 0; + virtual void Close() = 0; + virtual off_t GetSize() const = 0; + virtual bool Read(void *buf, off_t offset, size_t size) = 0; + virtual bool Write(const void *buf, off_t offset, size_t size) = 0; + + protected: + const std::string& pathname; +}; -// ディスクイメージの基本クラス +// ディスクイメージ class DiskImage { - public: - enum class Type { - Raw, // 生イメージ - }; + private: + // Copy-on-Write キャッシュのブロックサイズ + static const uint BLKSIZE = 4096; + + using SectBuf = std::array; public: - DiskImage(Type type_); + DiskImage(); virtual ~DiskImage(); - static DiskImage *Create(const std::string& pathname); + // パス名を指定して、下位ドライバをオープン。 + // コンストラクタ後最初に実行すること。 + bool CreateHandler(const std::string& pathname_); // このディスクイメージのサイズと書き込み可能かどうかを返す。 // Open() 前でも動作する。 - // 成功すれば 0、失敗なら errno をセットして - 1を返す。 - virtual int GetInfo(off_t *size, bool *w_ok) = 0; + // 成功すれば true、失敗なら errno をセットして false を返す。 + bool GetInfo(off_t *size, bool *w_ok); // このディスクイメージを実際のアクセス用にオープンする。 + // read_only == true なら、ディスクイメージを読み込み専用でオープンする。 + // is_cow == true なら、Copy-on-Write モードにする。 // 失敗すれば warn() でエラーメッセージを表示して false を返す。 - virtual bool Open(bool read_only) = 0; - - // このディスクイメージの offset から size バイトを buf に読み出す - virtual bool Read(void *buf, off_t offset, size_t size) = 0; - - // このディスクイメージの offset から size バイトに buf を書き込む - virtual bool Write(const void *buf, off_t offset, size_t size) = 0; + bool Open(bool read_only, bool is_cow); - // このディスクイメージをクローズする - virtual void Close() = 0; + // このディスクイメージをクローズする。 + void Close(); // このディスクイメージのバイト数を返す。 // オープン後のみ使用可能。 - virtual off_t GetSize() const = 0; + off_t GetSize() const; + + // このディスクイメージの offset から size バイトを buf に読み出す。 + bool Read(void *buf, off_t offset, size_t size) const; - // このディスクイメージの種別を返す - Type GetDiskImageType() const { return type; } + // このディスクイメージの offset から size バイトに buf を書き込む。 + bool Write(const void *buf, off_t offset, size_t size); - // このディスクイメージのパス込みのファイル名を返す + // このディスクイメージのパス名を返す。 const std::string& GetPathName() const { return pathname; } - protected: - Type type {}; + // driver があれば true を返す。 + // unique_ptr の (bool) キャストと同じ。 + operator bool() const { return (bool)driver; } + + private: + // map::find は分かりにくいので。C++20 には map::contains() がある + bool map_contains(off_t x) const { + return map.find(x) != map.end(); + } std::string pathname {}; + + std::unique_ptr driver {}; + + // Copy-on-Write モード + bool cow_enable {}; + autofd cowfd {}; + std::string cowname {}; // ファイルパス + // map (連想配列)のキーはオリジナルファイル上のブロック番号(バイト + // オフセットを BLKSIZE で割ったもの)、対応する値は CoW ファイル上の + // バイトオフセット。 + std::map map {}; };