~aleteoryx/muditaos

ref: 79a6264b7c6e92c8cb44f9624c26b119ea661a0f muditaos/module-vfs/include/user/purefs/blkdev/disk_manager.hpp -rw-r--r-- 6.2 KiB
79a6264b — Lucjan Bryndza [EGD-5020] Add autodetect filesystem 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <tuple>
#include <optional>
#include "defs.hpp"
#include "partition.hpp"

namespace cpp_freertos
{
    class MutexRecursive;
}

namespace purefs::blkdev
{
    class disk;

    /** Disk manager is a class for allows to control block devices media
     */
    class disk_manager
    {
      public:
        disk_manager(const disk_manager &) = delete;
        auto operator=(const disk_manager &) -> disk_manager & = delete;
        disk_manager();
        ~disk_manager();
        /** Register a new disc
         * @param[in] disk Block device register
         * @param[in] device_name Disk friendly name
         * @return zero on success othervise error
         */
        auto register_device(std::shared_ptr<disk> disk, std::string_view device_name, unsigned flags = 0) -> int;
        /** Unregister a disc from the manager
         *  param[in] Disc to unregister
         *  @return error code or 0 if success
         */
        auto unregister_device(std::string_view device_name) -> int;
        /** Write a data onto block device or partition
         * @param[in] dfd Disk manager fd
         * @param[in] buf Data buffer to write
         * @param[in] lba First sector
         * @param[in] Count sectors count
         * @return zero on success otherwise error
         */
        auto write(disk_fd dfd, const void *buf, sector_t lba, std::size_t count) -> int;
        auto write(std::string_view device_name, const void *buf, sector_t lba, std::size_t count) -> int;
        /** Read a data from block device or partition
         * @param[in] dfd Disk manager fd
         * @param[in] buf Data buffer for read
         * @param[in] lba First sector
         * @param[in] Count sectors count
         * @return zero on success otherwise error
         */

        auto read(disk_fd dfd, void *buf, sector_t lba, std::size_t count) -> int;
        auto read(std::string_view device_name, void *buf, sector_t lba, std::size_t count) -> int;
        /** Erase selected area on the block device or partition
         * @param[in] dfd Disk manager fd
         * @param[in] lba First sector to erase
         * @param[in] count Sectors count for erase
         * @return zero or success otherwise error
         */

        auto erase(disk_fd dfd, sector_t lba, std::size_t count) -> int;
        auto erase(std::string_view device_name, sector_t lba, std::size_t count) -> int;
        /** Flush buffers and write all data into the physical device
         * param[in] dfd Disc manager fd
         * @return zero or success otherwise error
         */
        auto sync(disk_fd dfd) -> int;
        auto sync(std::string_view device_name) -> int;
        /** Set block device power state
         * @param[in] device_name Device or partition name
         * @param[in] target_state Set the target power state
         * @return zero or success otherwise error
         * @note If the partition is changed whole device state will be suspended
         */
        auto pm_control(disk_fd dfd, pm_state target_state) -> int;
        auto pm_control(std::string_view device_name, pm_state target_state) -> int;
        /** Get block device power state
         * @param[in] dfd Disk device handle
         * @param[out] currrent_state Device current state
         * @return zero or success otherwise error
         * @note If the partition is changed whole device state will be suspended
         */
        auto pm_read(disk_fd dfd, pm_state &current_state) -> int;
        auto pm_read(std::string_view device_name, pm_state &current_state) -> int;
        /** Read the current media status
         * @param[in] dfd Disk manager handle
         * @return Current media status @seee media_status
         */
        [[nodiscard]] auto status(disk_fd dfd) const -> media_status;
        [[nodiscard]] auto status(std::string_view device_name) const -> media_status;
        /** List the partitions on the underlaying device
         * @param[in] dfd Disk manager fd
         * @return Partition list @see partition
         */
        [[nodiscard]] auto partitions(disk_fd dfd) const -> std::vector<partition>;
        [[nodiscard]] auto partitions(std::string_view device_name) const -> std::vector<partition>;

        /** Get the selected partition info
         * @Param[in] Disk manager fd
         * @return Partition info data
         */
        [[nodiscard]] auto partition_info(disk_fd dfd) const -> std::optional<partition>;
        [[nodiscard]] auto partition_info(std::string_view device_name) const -> std::optional<partition>;

        /** Get media device info
         * @param[in] dfd Disk manager handle
         * @param[in] what Information type @see info_type
         * @return Desired data or error if negative
         */
        [[nodiscard]] auto get_info(disk_fd dfd, info_type what) const -> scount_t;
        [[nodiscard]] auto get_info(std::string_view device_name, info_type what) const -> scount_t;

        /** Force reread partition tables
         * @param dfd Disk manager handle
         * @return error code
         */
        auto reread_partitions(disk_fd dfd) -> int;
        auto reread_partitions(std::string_view device_name) -> int;
        /**
         * Return the device object based on friendly name
         * @param device_name  Device name
         * @return device object pointer
         */
        auto device_handle(std::string_view device_name) const -> disk_fd;

        /** Convert disk handle containing partitions to the full disk handle
         * @param disk Disk handle with partitions
         * @return disk handle for whole disc
         */
        static auto disk_handle_from_partition_handle(disk_fd disk) -> disk_fd;

      private:
        static auto parse_device_name(std::string_view device) -> std::tuple<std::string_view, short>;
        static auto part_lba_to_disk_lba(disk_fd disk, sector_t part_lba, size_t count) -> scount_t;

      private:
        std::unordered_map<std::string, std::shared_ptr<disk>> m_dev_map;
        std::unique_ptr<cpp_freertos::MutexRecursive> m_lock;
    };
} // namespace purefs::blkdev