~aleteoryx/muditaos

ref: a7484bf9c18c02a560df57215e7af3215dce2e6e muditaos/module-vfs/board/linux/purefs/src/blkdev/disk_image.cpp -rw-r--r-- 3.0 KiB
a7484bf9 — Lucjan Bryndza [EGD-4754] Add automount default filesystems 5 years ago
                                                                                
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <purefs/blkdev/disk_image.hpp>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>

namespace purefs::blkdev
{

    disk_image::disk_image(std::string_view image_filename) : m_image_name(image_filename)
    {}

    auto disk_image::probe(unsigned int flags) -> int
    {
        m_filedes = ::open(m_image_name.c_str(), O_RDWR, O_SYNC);
        if (!m_filedes)
            return m_filedes;
        struct stat fst;
        auto ret = ::fstat(m_filedes, &fst);
        if (ret < 0) {
            return -errno;
        }
        m_sectors = fst.st_size / sector_size;
        return 0;
    }
    auto disk_image::cleanup() -> int
    {
        int ret{-EBADFD};
        if (m_filedes) {
            if (m_filedes) {
                ret = ::close(m_filedes);
                if (ret < 0)
                    ret = -errno;
            }
        }
        return ret;
    }
    auto disk_image::write(const void *buf, sector_t lba, std::size_t count) -> int
    {
        auto offs = ::lseek(m_filedes, off_t(lba) * sector_size, SEEK_SET);
        if (offs < 0) {
            return offs;
        }
        auto to_write = count * sector_size;
        auto buf_b    = reinterpret_cast<const uint8_t *>(buf);
        do {
            auto ret = ::write(m_filedes, buf_b, to_write);
            if (ret < 0) {
                return -errno;
            }
            to_write -= ret;
            buf_b += ret;
        } while (to_write > 0);
        return 0;
    }
    auto disk_image::read(void *buf, sector_t lba, std::size_t count) -> int
    {
        auto offs = ::lseek(m_filedes, off_t(lba) * sector_size, SEEK_SET);
        if (offs < 0) {
            return offs;
        }
        auto to_read = count * sector_size;
        auto buf_b   = reinterpret_cast<uint8_t *>(buf);
        do {
            auto ret = ::read(m_filedes, buf_b, to_read);
            if (ret < 0) {
                return -errno;
            }
            to_read -= ret;
            buf_b += ret;
        } while (to_read > 0);
        return 0;
    }
    auto disk_image::sync() -> int
    {
        int ret{-EBADFD};
        if (m_filedes) {
            ret = fsync(m_filedes);
            if (ret < 0)
                ret = -errno;
        }
        return ret;
    }
    auto disk_image::status() const -> media_status
    {
        struct stat st;
        auto ret = ::stat(m_image_name.c_str(), &st);
        if (!ret)
            return media_status::nomedia;
        else
            return media_status::healthly;
    }
    auto disk_image::get_info(info_type what) const -> scount_t
    {
        switch (what) {
        case info_type::sector_size:
            return sector_size;
        case info_type::sector_count:
            return m_sectors;
        case info_type::erase_block:
            return 0;
        }
        return -1;
    }
} // namespace purefs::blkdev