|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2024 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // ディスクイメージドライバ (QCOW2 形式) ! 9: // ! 10: ! 11: #pragma once ! 12: ! 13: #include "diskdriver.h" ! 14: #include "autofd.h" ! 15: #include "vectorbool64.h" ! 16: #include <vector> ! 17: ! 18: // ディスクイメージ (QCOW2 形式) ! 19: class DiskDriverQcow2 : public DiskImageDriver ! 20: { ! 21: using inherited = DiskImageDriver; ! 22: public: ! 23: DiskDriverQcow2(const std::string& objname_, const std::string& pathname_); ! 24: ~DiskDriverQcow2() override; ! 25: ! 26: bool Match() override; ! 27: bool Attach(std::string& errmsg) override; ! 28: bool Open(bool read_only) override; ! 29: void Close() override; ! 30: bool Read(void *buf, off_t offset, size_t size) override; ! 31: bool Write(const void *buf, off_t offset, size_t size) override; ! 32: ! 33: private: ! 34: int HasCompressed(); ! 35: bool ReadTable(std::vector<uint64>& buf, uint64 offset); ! 36: off_t AllocCluster(const void *buf); ! 37: bool WriteEntry(uint64 baseoff, uint64 index, uint64 data); ! 38: bool ReadRefcount(); ! 39: uint64 AllocRefcount(); ! 40: bool FindCluster(uint64 *); ! 41: ! 42: static bool is_mem_zero(const void *, size_t); ! 43: static const char *CryptMethodToStr(uint32); ! 44: static const char *CompressionTypeToStr(uint32); ! 45: ! 46: autofd fd {}; ! 47: ! 48: uint32 version {}; ! 49: uint32 L1_size {}; ! 50: uint64 L1_table_offset {}; ! 51: uint32 cluster_bits {}; ! 52: uint64 L2_entries {}; ! 53: uint64 refcount_table_offset {}; ! 54: uint32 refcount_table_clusters {}; ! 55: ! 56: // クラスタのバイトサイズ。 ! 57: uint64 cluster_size {}; ! 58: // 下位側を取り出すためのマスク。64KB/クラスタなら 0xffff になる。 ! 59: uint64 cluster_mask {}; ! 60: ! 61: // L1/L2 インデックスを分けるためのビット数とマスク。 ! 62: uint32 L2_entries_bits {}; ! 63: uint64 L2_entries_mask {}; ! 64: ! 65: uint compress_offset_bits {}; ! 66: uint64 compress_sector_mask {}; ! 67: ! 68: // L1 テーブルは常にメモリに全コピーを持つ。 ! 69: std::vector<uint64> L1_table {}; ! 70: // L2 テーブルは現在参照中の1つのキャッシュを持つ。 ! 71: std::vector<uint64> L2_table {}; ! 72: ! 73: // 現在 L2_table[] でキャッシュしている箇所の L1 index。 ! 74: // L1_table[0] の L2 をキャッシュしていれば $0。 ! 75: // (uint64)-1 ならキャッシュなし。 ! 76: uint64 cached_L1_index {}; ! 77: ! 78: // データクラスタのキャッシュ。 ! 79: std::vector<uint8> data_cluster {}; ! 80: ! 81: // 現在 data_cluster[] でキャッシュしている箇所のデータクラスタ番号。 ! 82: // ゲストイメージの先頭クラスタなら $0。 ! 83: // (uint64)-1 ならキャッシュなし。 ! 84: uint64 cached_data_index {}; ! 85: ! 86: // refblock (2段目) の1クラスタ内の要素数。標準では 32768。 ! 87: uint32 refblock_capacity {}; ! 88: // refblock_capacity のビット数。標準では 15 になる。 ! 89: uint32 refblock_bits {}; ! 90: // refblock (2段目) の下位を取り出すマスク。標準では 0x7fff になる。 ! 91: uint64 refblock_mask {}; ! 92: ! 93: // refcount はイメージ上は 1,2,4,8,16,32,64 ビットの可能性がある ! 94: // (ただし通常は 16 ビットしかないと思われる)。 ! 95: // オンメモリでは bool で扱い、空き(refcount==0)なら true に反転して ! 96: // 保持する (count trailing zero で空きを探すため)。 ! 97: // 読み込みはオープン時に行い、書き込みはライトスルーキャッシュ方式。 ! 98: VectorBool64 freemap {}; ! 99: ! 100: std::vector<uint64> refcount_block_offset {}; ! 101: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.