FileSystem.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Atomic.h>
  8. #include <Kernel/FileSystem/FileBackedFileSystem.h>
  9. #include <Kernel/FileSystem/Inode.h>
  10. #include <Kernel/FileSystem/Plan9FS/Definitions.h>
  11. #include <Kernel/FileSystem/Plan9FS/Message.h>
  12. #include <Kernel/Library/KBufferBuilder.h>
  13. namespace Kernel {
  14. class Plan9FSInode;
  15. class Plan9FS final : public FileBackedFileSystem {
  16. friend class Plan9FSInode;
  17. public:
  18. virtual ~Plan9FS() override;
  19. static ErrorOr<NonnullRefPtr<FileSystem>> try_create(OpenFileDescription&, ReadonlyBytes);
  20. virtual bool supports_watchers() const override { return false; }
  21. virtual Inode& root_inode() override;
  22. u16 allocate_tag() { return m_next_tag++; }
  23. u32 allocate_fid() { return m_next_fid++; }
  24. enum class ProtocolVersion {
  25. v9P2000,
  26. v9P2000u,
  27. v9P2000L
  28. };
  29. private:
  30. Plan9FS(OpenFileDescription&);
  31. virtual ErrorOr<void> prepare_to_clear_last_mount(Inode&) override;
  32. virtual bool is_initialized_while_locked() override;
  33. virtual ErrorOr<void> initialize_while_locked() override;
  34. class Blocker;
  35. class Plan9FSBlockerSet final : public Thread::BlockerSet {
  36. public:
  37. Plan9FSBlockerSet(Plan9FS& fs)
  38. : m_fs(fs)
  39. {
  40. }
  41. void unblock_completed(u16);
  42. void unblock_all();
  43. void try_unblock(Blocker&);
  44. protected:
  45. virtual bool should_add_blocker(Thread::Blocker&, void*) override;
  46. private:
  47. Plan9FS& m_fs;
  48. mutable Spinlock<LockRank::None> m_lock {};
  49. };
  50. struct ReceiveCompletion final : public AtomicRefCounted<ReceiveCompletion> {
  51. mutable Spinlock<LockRank::None> lock {};
  52. bool completed { false };
  53. u16 const tag;
  54. OwnPtr<Plan9FSMessage> message;
  55. ErrorOr<void> result;
  56. ReceiveCompletion(u16 tag);
  57. ~ReceiveCompletion();
  58. };
  59. class Blocker final : public Thread::Blocker {
  60. public:
  61. Blocker(Plan9FS& fs, Plan9FSMessage& message, NonnullLockRefPtr<ReceiveCompletion> completion)
  62. : m_fs(fs)
  63. , m_message(message)
  64. , m_completion(move(completion))
  65. {
  66. }
  67. virtual bool setup_blocker() override;
  68. virtual StringView state_string() const override { return "Waiting"sv; }
  69. virtual Type blocker_type() const override { return Type::Plan9FS; }
  70. virtual void will_unblock_immediately_without_blocking(UnblockImmediatelyReason) override;
  71. NonnullLockRefPtr<ReceiveCompletion> const& completion() const { return m_completion; }
  72. u16 tag() const { return m_completion->tag; }
  73. bool is_completed() const;
  74. bool unblock()
  75. {
  76. unblock_from_blocker();
  77. return true;
  78. }
  79. bool unblock(u16 tag);
  80. private:
  81. Plan9FS& m_fs;
  82. Plan9FSMessage& m_message;
  83. NonnullLockRefPtr<ReceiveCompletion> m_completion;
  84. bool m_did_unblock { false };
  85. };
  86. friend class Blocker;
  87. virtual StringView class_name() const override { return "Plan9FS"sv; }
  88. bool is_complete(ReceiveCompletion const&);
  89. ErrorOr<void> post_message(Plan9FSMessage&, LockRefPtr<ReceiveCompletion>);
  90. ErrorOr<void> do_read(u8* buffer, size_t);
  91. ErrorOr<void> read_and_dispatch_one_message();
  92. ErrorOr<void> post_message_and_wait_for_a_reply(Plan9FSMessage&);
  93. ErrorOr<void> post_message_and_explicitly_ignore_reply(Plan9FSMessage&);
  94. ProtocolVersion parse_protocol_version(StringView) const;
  95. size_t adjust_buffer_size(size_t size) const;
  96. void thread_main();
  97. void ensure_thread();
  98. RefPtr<Plan9FSInode> m_root_inode;
  99. Atomic<u16> m_next_tag { (u16)-1 };
  100. Atomic<u32> m_next_fid { 1 };
  101. ProtocolVersion m_remote_protocol_version { ProtocolVersion::v9P2000 };
  102. size_t m_max_message_size { 4 * KiB };
  103. Mutex m_send_lock { "Plan9FS send"sv };
  104. Plan9FSBlockerSet m_completion_blocker;
  105. HashMap<u16, NonnullLockRefPtr<ReceiveCompletion>> m_completions;
  106. Spinlock<LockRank::None> m_thread_lock {};
  107. RefPtr<Thread> m_thread;
  108. Atomic<bool> m_thread_running { false };
  109. };
  110. }