mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:32:44 +00:00 
			
		
		
		
	Kernel: Stop using *LockRefPtr for FileSystem pointers
There was only one permanent storage location for these: as a member in the Mount class. That member is never modified after Mount initialization, so we don't need to worry about races there.
This commit is contained in:
		
							parent
							
								
									3f69ef86c2
								
							
						
					
					
						commit
						673592dea8
					
				
					 23 changed files with 40 additions and 41 deletions
				
			
		|  | @ -13,9 +13,9 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> DevPtsFS::try_create() | ErrorOr<NonnullRefPtr<FileSystem>> DevPtsFS::try_create() | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) DevPtsFS)); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) DevPtsFS)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DevPtsFS::DevPtsFS() = default; | DevPtsFS::DevPtsFS() = default; | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ class DevPtsFS final : public FileSystem { | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     virtual ~DevPtsFS() override; |     virtual ~DevPtsFS() override; | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(); | ||||||
| 
 | 
 | ||||||
|     virtual ErrorOr<void> initialize() override; |     virtual ErrorOr<void> initialize() override; | ||||||
|     virtual StringView class_name() const override { return "DevPtsFS"sv; } |     virtual StringView class_name() const override { return "DevPtsFS"sv; } | ||||||
|  |  | ||||||
|  | @ -13,9 +13,9 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> Ext2FS::try_create(OpenFileDescription& file_description) | ErrorOr<NonnullRefPtr<FileSystem>> Ext2FS::try_create(OpenFileDescription& file_description) | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Ext2FS(file_description))); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Ext2FS(file_description))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Ext2FS::Ext2FS(OpenFileDescription& file_description) | Ext2FS::Ext2FS(OpenFileDescription& file_description) | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ public: | ||||||
|         FileSize64bits = 1 << 1, |         FileSize64bits = 1 << 1, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(OpenFileDescription&); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(OpenFileDescription&); | ||||||
| 
 | 
 | ||||||
|     virtual ~Ext2FS() override; |     virtual ~Ext2FS() override; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,9 +10,9 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> FATFS::try_create(OpenFileDescription& file_description) | ErrorOr<NonnullRefPtr<FileSystem>> FATFS::try_create(OpenFileDescription& file_description) | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) FATFS(file_description))); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) FATFS(file_description))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FATFS::FATFS(OpenFileDescription& file_description) | FATFS::FATFS(OpenFileDescription& file_description) | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ class FATFS final : public BlockBasedFileSystem { | ||||||
|     friend FATInode; |     friend FATInode; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(OpenFileDescription&); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(OpenFileDescription&); | ||||||
| 
 | 
 | ||||||
|     virtual ~FATFS() override = default; |     virtual ~FATFS() override = default; | ||||||
|     virtual StringView class_name() const override { return "FATFS"sv; } |     virtual StringView class_name() const override { return "FATFS"sv; } | ||||||
|  |  | ||||||
|  | @ -16,9 +16,9 @@ constexpr u32 first_data_area_block = 16; | ||||||
| constexpr u32 logical_sector_size = 2048; | constexpr u32 logical_sector_size = 2048; | ||||||
| constexpr u32 max_cached_directory_entries = 128; | constexpr u32 max_cached_directory_entries = 128; | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> ISO9660FS::try_create(OpenFileDescription& description) | ErrorOr<NonnullRefPtr<FileSystem>> ISO9660FS::try_create(OpenFileDescription& description) | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) ISO9660FS(description))); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ISO9660FS(description))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ISO9660FS::ISO9660FS(OpenFileDescription& description) | ISO9660FS::ISO9660FS(OpenFileDescription& description) | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ class ISO9660FS final : public BlockBasedFileSystem { | ||||||
|     friend ISO9660DirectoryIterator; |     friend ISO9660DirectoryIterator; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(OpenFileDescription&); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(OpenFileDescription&); | ||||||
| 
 | 
 | ||||||
|     virtual ~ISO9660FS() override; |     virtual ~ISO9660FS() override; | ||||||
|     virtual StringView class_name() const override { return "ISO9660FS"sv; } |     virtual StringView class_name() const override { return "ISO9660FS"sv; } | ||||||
|  |  | ||||||
|  | @ -11,8 +11,8 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| Mount::Mount(FileSystem& guest_fs, Custody* host_custody, int flags) | Mount::Mount(NonnullRefPtr<FileSystem> guest_fs, Custody* host_custody, int flags) | ||||||
|     : m_guest(guest_fs.root_inode()) |     : m_guest(guest_fs->root_inode()) | ||||||
|     , m_guest_fs(guest_fs) |     , m_guest_fs(guest_fs) | ||||||
|     , m_host_custody(host_custody) |     , m_host_custody(host_custody) | ||||||
|     , m_flags(flags) |     , m_flags(flags) | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ class Mount { | ||||||
|     friend class VirtualFileSystem; |     friend class VirtualFileSystem; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     Mount(FileSystem&, Custody* host_custody, int flags); |     Mount(NonnullRefPtr<FileSystem>, Custody* host_custody, int flags); | ||||||
|     Mount(Inode& source, Custody& host_custody, int flags); |     Mount(Inode& source, Custody& host_custody, int flags); | ||||||
| 
 | 
 | ||||||
|     RefPtr<Inode const> host() const; |     RefPtr<Inode const> host() const; | ||||||
|  | @ -39,7 +39,7 @@ public: | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     NonnullRefPtr<Inode> m_guest; |     NonnullRefPtr<Inode> m_guest; | ||||||
|     NonnullLockRefPtr<FileSystem> m_guest_fs; |     NonnullRefPtr<FileSystem> m_guest_fs; | ||||||
|     SpinlockProtected<RefPtr<Custody>, LockRank::None> m_host_custody; |     SpinlockProtected<RefPtr<Custody>, LockRank::None> m_host_custody; | ||||||
|     int m_flags; |     int m_flags; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,9 +10,9 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> Plan9FS::try_create(OpenFileDescription& file_description) | ErrorOr<NonnullRefPtr<FileSystem>> Plan9FS::try_create(OpenFileDescription& file_description) | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Plan9FS(file_description))); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Plan9FS(file_description))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Plan9FS::Plan9FS(OpenFileDescription& file_description) | Plan9FS::Plan9FS(OpenFileDescription& file_description) | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ class Plan9FS final : public FileBackedFileSystem { | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     virtual ~Plan9FS() override; |     virtual ~Plan9FS() override; | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(OpenFileDescription&); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(OpenFileDescription&); | ||||||
| 
 | 
 | ||||||
|     virtual bool supports_watchers() const override { return false; } |     virtual bool supports_watchers() const override { return false; } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,9 +11,9 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> ProcFS::try_create() | ErrorOr<NonnullRefPtr<FileSystem>> ProcFS::try_create() | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) ProcFS)); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ProcFS)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ProcFS::ProcFS() = default; | ProcFS::ProcFS() = default; | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ class ProcFS final : public FileSystem { | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     virtual ~ProcFS() override; |     virtual ~ProcFS() override; | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(); | ||||||
| 
 | 
 | ||||||
|     virtual ErrorOr<void> initialize() override; |     virtual ErrorOr<void> initialize() override; | ||||||
|     virtual StringView class_name() const override { return "ProcFS"sv; } |     virtual StringView class_name() const override { return "ProcFS"sv; } | ||||||
|  |  | ||||||
|  | @ -10,9 +10,9 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> RAMFS::try_create() | ErrorOr<NonnullRefPtr<FileSystem>> RAMFS::try_create() | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) RAMFS)); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) RAMFS)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RAMFS::RAMFS() = default; | RAMFS::RAMFS() = default; | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ class RAMFS final : public FileSystem { | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     virtual ~RAMFS() override; |     virtual ~RAMFS() override; | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(); | ||||||
|     virtual ErrorOr<void> initialize() override; |     virtual ErrorOr<void> initialize() override; | ||||||
| 
 | 
 | ||||||
|     virtual StringView class_name() const override { return "RAMFS"sv; } |     virtual StringView class_name() const override { return "RAMFS"sv; } | ||||||
|  |  | ||||||
|  | @ -11,9 +11,9 @@ | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileSystem>> SysFS::try_create() | ErrorOr<NonnullRefPtr<FileSystem>> SysFS::try_create() | ||||||
| { | { | ||||||
|     return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) SysFS)); |     return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SysFS)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SysFS::SysFS() = default; | SysFS::SysFS() = default; | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ class SysFS final : public FileSystem { | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     virtual ~SysFS() override; |     virtual ~SysFS() override; | ||||||
|     static ErrorOr<NonnullLockRefPtr<FileSystem>> try_create(); |     static ErrorOr<NonnullRefPtr<FileSystem>> try_create(); | ||||||
| 
 | 
 | ||||||
|     virtual ErrorOr<void> initialize() override; |     virtual ErrorOr<void> initialize() override; | ||||||
|     virtual StringView class_name() const override { return "SysFS"sv; } |     virtual StringView class_name() const override { return "SysFS"sv; } | ||||||
|  |  | ||||||
|  | @ -135,7 +135,7 @@ ErrorOr<void> VirtualFileSystem::remount(Custody& mount_point, int new_flags) | ||||||
| 
 | 
 | ||||||
| void VirtualFileSystem::sync_filesystems() | void VirtualFileSystem::sync_filesystems() | ||||||
| { | { | ||||||
|     Vector<NonnullLockRefPtr<FileSystem>, 32> file_systems; |     Vector<NonnullRefPtr<FileSystem>, 32> file_systems; | ||||||
|     m_file_systems_list.with([&](auto const& list) { |     m_file_systems_list.with([&](auto const& list) { | ||||||
|         for (auto& fs : list) |         for (auto& fs : list) | ||||||
|             file_systems.append(fs); |             file_systems.append(fs); | ||||||
|  | @ -147,7 +147,7 @@ void VirtualFileSystem::sync_filesystems() | ||||||
| 
 | 
 | ||||||
| void VirtualFileSystem::lock_all_filesystems() | void VirtualFileSystem::lock_all_filesystems() | ||||||
| { | { | ||||||
|     Vector<NonnullLockRefPtr<FileSystem>, 32> file_systems; |     Vector<NonnullRefPtr<FileSystem>, 32> file_systems; | ||||||
|     m_file_systems_list.with([&](auto const& list) { |     m_file_systems_list.with([&](auto const& list) { | ||||||
|         for (auto& fs : list) |         for (auto& fs : list) | ||||||
|             file_systems.append(fs); |             file_systems.append(fs); | ||||||
|  | @ -334,9 +334,9 @@ ErrorOr<InodeMetadata> VirtualFileSystem::lookup_metadata(Credentials const& cre | ||||||
|     return custody->inode().metadata(); |     return custody->inode().metadata(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullLockRefPtr<FileBackedFileSystem>> VirtualFileSystem::find_already_existing_or_create_file_backed_file_system(OpenFileDescription& description, Function<ErrorOr<NonnullLockRefPtr<FileSystem>>(OpenFileDescription&)> callback) | ErrorOr<NonnullRefPtr<FileBackedFileSystem>> VirtualFileSystem::find_already_existing_or_create_file_backed_file_system(OpenFileDescription& description, Function<ErrorOr<NonnullRefPtr<FileSystem>>(OpenFileDescription&)> callback) | ||||||
| { | { | ||||||
|     return TRY(m_file_backed_file_systems_list.with([&](auto& list) -> ErrorOr<NonnullLockRefPtr<FileBackedFileSystem>> { |     return TRY(m_file_backed_file_systems_list.with([&](auto& list) -> ErrorOr<NonnullRefPtr<FileBackedFileSystem>> { | ||||||
|         for (auto& node : list) { |         for (auto& node : list) { | ||||||
|             if (&node.file_description() == &description) { |             if (&node.file_description() == &description) { | ||||||
|                 return node; |                 return node; | ||||||
|  |  | ||||||
|  | @ -19,7 +19,6 @@ | ||||||
| #include <Kernel/FileSystem/Mount.h> | #include <Kernel/FileSystem/Mount.h> | ||||||
| #include <Kernel/FileSystem/UnveilNode.h> | #include <Kernel/FileSystem/UnveilNode.h> | ||||||
| #include <Kernel/Forward.h> | #include <Kernel/Forward.h> | ||||||
| #include <Kernel/Library/LockRefPtr.h> |  | ||||||
| #include <Kernel/Locking/SpinlockProtected.h> | #include <Kernel/Locking/SpinlockProtected.h> | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
|  | @ -82,7 +81,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     ErrorOr<void> for_each_mount(Function<ErrorOr<void>(Mount const&)>) const; |     ErrorOr<void> for_each_mount(Function<ErrorOr<void>(Mount const&)>) const; | ||||||
| 
 | 
 | ||||||
|     ErrorOr<NonnullLockRefPtr<FileBackedFileSystem>> find_already_existing_or_create_file_backed_file_system(OpenFileDescription& description, Function<ErrorOr<NonnullLockRefPtr<FileSystem>>(OpenFileDescription&)> callback); |     ErrorOr<NonnullRefPtr<FileBackedFileSystem>> find_already_existing_or_create_file_backed_file_system(OpenFileDescription& description, Function<ErrorOr<NonnullRefPtr<FileSystem>>(OpenFileDescription&)> callback); | ||||||
| 
 | 
 | ||||||
|     InodeIdentifier root_inode_id() const; |     InodeIdentifier root_inode_id() const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -446,7 +446,7 @@ u32 StorageManagement::generate_controller_id() | ||||||
|     return s_controller_id.fetch_add(1); |     return s_controller_id.fetch_add(1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| NonnullLockRefPtr<FileSystem> StorageManagement::root_filesystem() const | NonnullRefPtr<FileSystem> StorageManagement::root_filesystem() const | ||||||
| { | { | ||||||
|     auto boot_device_description = boot_block_device(); |     auto boot_device_description = boot_block_device(); | ||||||
|     if (!boot_device_description) { |     if (!boot_device_description) { | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ public: | ||||||
|     void initialize(StringView boot_argument, bool force_pio, bool nvme_poll); |     void initialize(StringView boot_argument, bool force_pio, bool nvme_poll); | ||||||
|     static StorageManagement& the(); |     static StorageManagement& the(); | ||||||
| 
 | 
 | ||||||
|     NonnullLockRefPtr<FileSystem> root_filesystem() const; |     NonnullRefPtr<FileSystem> root_filesystem() const; | ||||||
| 
 | 
 | ||||||
|     static MajorNumber storage_type_major_number(); |     static MajorNumber storage_type_major_number(); | ||||||
|     static MinorNumber generate_storage_minor_number(); |     static MinorNumber generate_storage_minor_number(); | ||||||
|  |  | ||||||
|  | @ -24,8 +24,8 @@ struct FileSystemInitializer { | ||||||
|     bool requires_open_file_description { false }; |     bool requires_open_file_description { false }; | ||||||
|     bool requires_block_device { false }; |     bool requires_block_device { false }; | ||||||
|     bool requires_seekable_file { false }; |     bool requires_seekable_file { false }; | ||||||
|     ErrorOr<NonnullLockRefPtr<FileSystem>> (*create_with_fd)(OpenFileDescription&) = nullptr; |     ErrorOr<NonnullRefPtr<FileSystem>> (*create_with_fd)(OpenFileDescription&) = nullptr; | ||||||
|     ErrorOr<NonnullLockRefPtr<FileSystem>> (*create)(void) = nullptr; |     ErrorOr<NonnullRefPtr<FileSystem>> (*create)(void) = nullptr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static constexpr FileSystemInitializer s_initializers[] = { | static constexpr FileSystemInitializer s_initializers[] = { | ||||||
|  | @ -39,14 +39,14 @@ static constexpr FileSystemInitializer s_initializers[] = { | ||||||
|     { "fat"sv, "FATFS"sv, true, true, true, FATFS::try_create, {} }, |     { "fat"sv, "FATFS"sv, true, true, true, FATFS::try_create, {} }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static ErrorOr<NonnullLockRefPtr<FileSystem>> find_or_create_filesystem_instance(StringView fs_type, OpenFileDescription* possible_description) | static ErrorOr<NonnullRefPtr<FileSystem>> find_or_create_filesystem_instance(StringView fs_type, OpenFileDescription* possible_description) | ||||||
| { | { | ||||||
|     for (auto& initializer_entry : s_initializers) { |     for (auto& initializer_entry : s_initializers) { | ||||||
|         if (fs_type != initializer_entry.short_name && fs_type != initializer_entry.name) |         if (fs_type != initializer_entry.short_name && fs_type != initializer_entry.name) | ||||||
|             continue; |             continue; | ||||||
|         if (!initializer_entry.requires_open_file_description) { |         if (!initializer_entry.requires_open_file_description) { | ||||||
|             VERIFY(initializer_entry.create); |             VERIFY(initializer_entry.create); | ||||||
|             NonnullLockRefPtr<FileSystem> fs = TRY(initializer_entry.create()); |             NonnullRefPtr<FileSystem> fs = TRY(initializer_entry.create()); | ||||||
|             return fs; |             return fs; | ||||||
|         } |         } | ||||||
|         // Note: If there's an associated file description with the filesystem, we could
 |         // Note: If there's an associated file description with the filesystem, we could
 | ||||||
|  | @ -110,7 +110,7 @@ ErrorOr<FlatPtr> Process::sys$mount(Userspace<Syscall::SC_mount_params const*> u | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     LockRefPtr<FileSystem> fs; |     RefPtr<FileSystem> fs; | ||||||
| 
 | 
 | ||||||
|     if (!description_or_error.is_error()) { |     if (!description_or_error.is_error()) { | ||||||
|         auto description = description_or_error.release_value(); |         auto description = description_or_error.release_value(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling