|
|
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.