blob: f500f8eab3de93e6b4ab3bd4ff8681b90f002e19 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <mercury/kernel/storage.hpp>
namespace mercury::kernel::storage {
bd_result block_device::load_cache_block(uint64_t i) {
if (block_cache_i == i)
return bd_result::success;
bd_result result = read_blocks_no_cache(i, 1, block_cache);
if (result != bd_result::success) {
block_cache_i = block_count;
return result;
}
block_cache_i = i;
return bd_result::success;
}
bd_result block_device::read_bytes(
uint64_t start, uint64_t count, void *into
) {
if (start + count > block_size * block_count)
return bd_result::out_of_bounds;
uint8_t *into_u8 = (uint8_t *)into;
if (start % block_size != 0) {
uint64_t prefix_len = block_size - start % block_size;
bd_result result = load_cache_block(start / block_size);
if (result != bd_result::success)
return result;
for (uint64_t i = 0; i < prefix_len; ++i)
into_u8[i] = block_cache[start % block_size + i];
into_u8 += prefix_len;
start += prefix_len;
count -= prefix_len;
}
uint64_t postfix_start = ((start + count) / block_size) * block_size;
if (postfix_start != start) {
bd_result result = read_blocks_no_cache(
start / block_size, (postfix_start - start) / block_size, into_u8);
if (result != bd_result::success)
return result;
count -= postfix_start - start;
into_u8 += postfix_start - start;
start = postfix_start;
}
if (count != 0) {
bd_result result = load_cache_block(start / block_size);
if (result != bd_result::success)
return result;
for (uint64_t i = 0; i < count; ++i)
into_u8[i] = block_cache[i];
}
return bd_result::success;
}
}
|