1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #pragma once |
4 | |
5 | #include "ext4.h" |
6 | #include "ext4_blockdev.h" |
7 | #include "ext4_types.h" |
8 | #include "proto/blockdev.pb.h" |
9 | #include "proto/blockdev.services.h" |
10 | #include "proto/filesystem.pb.h" |
11 | #include "proto/filesystem.services.h" |
12 | #include "proto/userfs-manager.services.h" |
13 | |
14 | #include <librpc/macro_magic.h> |
15 | #include <librpc/rpc.h> |
16 | #include <librpc/rpc_client.h> |
17 | #include <librpc/rpc_server++.hpp> |
18 | #include <memory> |
19 | #include <mos/filesystem/fs_types.h> |
20 | #include <mos/proto/fs_server.h> |
21 | #include <pb_decode.h> |
22 | |
23 | using namespace std::string_literals; |
24 | |
25 | extern std::unique_ptr<UserFSManagerStub> userfs_manager; |
26 | extern std::unique_ptr<BlockdevManagerStub> blockdev_manager; |
27 | |
28 | struct ext4_context_state |
29 | { |
30 | mosrpc_blockdev_blockdev blockdev; |
31 | |
32 | uint8_t ext4_buf[512] = { 0 }; |
33 | ext4_blockdev_iface ext4_dev_iface; |
34 | ext4_blockdev ext4_dev; |
35 | ext4_fs *fs; |
36 | ext4_mountpoint *mp; |
37 | }; |
38 | |
39 | class Ext4UserFS : public IUserFSService |
40 | { |
41 | public: |
42 | explicit Ext4UserFS(const std::string &name); |
43 | |
44 | private: |
45 | virtual void on_connect(rpc_context_t *ctx) override; |
46 | |
47 | virtual void on_disconnect(rpc_context_t *ctx) override; |
48 | |
49 | private: |
50 | template<typename T> |
51 | static file_type_t ext4_get_file_type(ext4_sblock *sb, T *dentry_or_inode) |
52 | { |
53 | if constexpr (std::is_same_v<T, ext4_dir_en>) |
54 | { |
55 | const auto type = ext4_dir_en_get_inode_type(sb, dentry_or_inode); |
56 | switch (type) |
57 | { |
58 | case EXT4_DE_FIFO: return FILE_TYPE_NAMED_PIPE; |
59 | case EXT4_DE_CHRDEV: return FILE_TYPE_CHAR_DEVICE; |
60 | case EXT4_DE_DIR: return FILE_TYPE_DIRECTORY; |
61 | case EXT4_DE_BLKDEV: return FILE_TYPE_BLOCK_DEVICE; |
62 | case EXT4_DE_REG_FILE: return FILE_TYPE_REGULAR; |
63 | case EXT4_DE_SYMLINK: return FILE_TYPE_SYMLINK; |
64 | case EXT4_DE_SOCK: return FILE_TYPE_SOCKET; |
65 | case EXT4_DE_UNKNOWN: return FILE_TYPE_UNKNOWN; |
66 | default: return FILE_TYPE_UNKNOWN; |
67 | } |
68 | } |
69 | else if constexpr (std::is_same_v<T, ext4_inode>) |
70 | { |
71 | const auto type = ext4_inode_type(sb, dentry_or_inode); |
72 | switch (type) |
73 | { |
74 | case EXT4_INODE_MODE_FIFO: return FILE_TYPE_NAMED_PIPE; |
75 | case EXT4_INODE_MODE_CHARDEV: return FILE_TYPE_CHAR_DEVICE; |
76 | case EXT4_INODE_MODE_DIRECTORY: return FILE_TYPE_DIRECTORY; |
77 | case EXT4_INODE_MODE_BLOCKDEV: return FILE_TYPE_BLOCK_DEVICE; |
78 | case EXT4_INODE_MODE_FILE: return FILE_TYPE_REGULAR; |
79 | case EXT4_INODE_MODE_SOFTLINK: return FILE_TYPE_SYMLINK; |
80 | case EXT4_INODE_MODE_SOCKET: return FILE_TYPE_SOCKET; |
81 | default: return FILE_TYPE_UNKNOWN; |
82 | } |
83 | } |
84 | else |
85 | { |
86 | static_assert(false, "Invalid type" ); |
87 | } |
88 | }; |
89 | |
90 | static void populate_mosrpc_fs_inode_info(mosrpc_fs_inode_info &info, ext4_sblock *sb, ext4_inode *inode, int ino); |
91 | static void save_inode_info(ext4_sblock *sb, ext4_inode *inode, const mosrpc_fs_inode_info &info); |
92 | |
93 | private: |
94 | virtual rpc_result_code_t mount(rpc_context_t *ctx, mosrpc_fs_mount_request *req, mosrpc_fs_mount_response *resp) override; |
95 | |
96 | virtual rpc_result_code_t readdir(rpc_context_t *ctx, mosrpc_fs_readdir_request *req, mosrpc_fs_readdir_response *resp) override; |
97 | |
98 | virtual rpc_result_code_t lookup(rpc_context_t *ctx, mosrpc_fs_lookup_request *req, mosrpc_fs_lookup_response *resp) override; |
99 | |
100 | virtual rpc_result_code_t readlink(rpc_context_t *ctx, mosrpc_fs_readlink_request *req, mosrpc_fs_readlink_response *resp) override; |
101 | |
102 | virtual rpc_result_code_t get_page(rpc_context_t *ctx, mosrpc_fs_getpage_request *req, mosrpc_fs_getpage_response *resp) override; |
103 | |
104 | virtual rpc_result_code_t create_file(rpc_context_t *ctx, mosrpc_fs_create_file_request *req, mosrpc_fs_create_file_response *resp) override; |
105 | |
106 | virtual rpc_result_code_t put_page(rpc_context_t *ctx, mosrpc_fs_putpage_request *req, mosrpc_fs_putpage_response *resp) override; |
107 | |
108 | virtual rpc_result_code_t sync_inode(rpc_context_t *ctx, mosrpc_fs_sync_inode_request *req, mosrpc_fs_sync_inode_response *resp) override; |
109 | |
110 | virtual rpc_result_code_t unlink(rpc_context_t *ctx, mosrpc_fs_unlink_request *req, mosrpc_fs_unlink_response *resp) override; |
111 | |
112 | virtual rpc_result_code_t make_dir(rpc_context_t *ctx, mosrpc_fs_make_dir_request *req, mosrpc_fs_make_dir_response *resp) override; |
113 | }; |
114 | |