@@ -27,37 +27,33 @@ UNMAP_AFTER_INIT FUSEDevice::~FUSEDevice() = default;
2727
2828ErrorOr<void > FUSEDevice::initialize_instance (OpenFileDescription const & description)
2929{
30- return m_instances. with ([&]( auto & instances) -> ErrorOr< void > {
31- VERIFY (!instances. contains (&description));
32- TRY (instances. try_set (&description, {} ));
33- return {} ;
34- }) ;
30+ SpinlockLocker locker (m_lock);
31+
32+ VERIFY (!m_instances. contains (&description));
33+ TRY (m_instances. try_set (&description, {})) ;
34+ return {} ;
3535}
3636
3737bool FUSEDevice::can_read (OpenFileDescription const & description, u64 ) const
3838{
39- bool drop = m_closing_instances.with ([&](auto & closing_instances) {
40- auto iterator = closing_instances.find (&description);
41- return iterator != closing_instances.end ();
42- });
39+ SpinlockLocker locker (m_lock);
4340
44- if (drop)
41+ auto iterator = m_closing_instances.find (&description);
42+ if (iterator != m_closing_instances.end ())
4543 return true ;
4644
47- return m_instances.with ([&](auto & instances) {
48- auto instance_iterator = instances.find (&description);
49- if (instance_iterator == instances.end ()) {
50- VERIFY (instances.is_empty ());
51- return false ;
52- }
53-
54- auto const & requests_for_instance = (*instance_iterator).value ;
55- for (auto const & request : requests_for_instance.in_reverse ()) {
56- if (request.buffer_ready )
57- return true ;
58- }
45+ auto instance_iterator = m_instances.find (&description);
46+ if (instance_iterator == m_instances.end ()) {
47+ VERIFY (m_instances.is_empty ());
5948 return false ;
60- });
49+ }
50+
51+ auto const & requests_for_instance = (*instance_iterator).value ;
52+ for (auto const & request : requests_for_instance.in_reverse ()) {
53+ if (request.buffer_ready )
54+ return true ;
55+ }
56+ return false ;
6157}
6258
6359bool FUSEDevice::can_write (OpenFileDescription const &, u64 ) const
@@ -67,120 +63,116 @@ bool FUSEDevice::can_write(OpenFileDescription const&, u64) const
6763
6864ErrorOr<size_t > FUSEDevice::read (OpenFileDescription& description, u64 , UserOrKernelBuffer& buffer, size_t size)
6965{
70- TRY (m_closing_instances.with ([&](auto & closing_instances) -> ErrorOr<void > {
71- bool removed = closing_instances.remove_first_matching ([&](auto const * closing_description) { return closing_description == &description; });
72- if (removed)
73- return Error::from_errno (ENODEV);
66+ SpinlockLocker locker (m_lock);
7467
75- return {};
76- }));
68+ bool removed = m_closing_instances.remove_first_matching ([&](auto const * closing_description) { return closing_description == &description; });
69+ if (removed)
70+ return Error::from_errno (ENODEV);
7771
7872 if (size < 0x21000 )
7973 return Error::from_errno (EIO);
8074
81- return m_instances.with ([&](auto & instances) -> ErrorOr<size_t > {
82- auto instance_iterator = instances.find (&description);
83- if (instance_iterator == instances.end ())
84- return Error::from_errno (ENODEV);
75+ auto instance_iterator = m_instances.find (&description);
76+ if (instance_iterator == m_instances.end ())
77+ return Error::from_errno (ENODEV);
8578
86- auto & requests_for_instance = (*instance_iterator).value ;
79+ auto & requests_for_instance = (*instance_iterator).value ;
8780
88- for (auto & request : requests_for_instance.in_reverse ()) {
89- if (!request.buffer_ready )
90- continue ;
81+ for (auto & request : requests_for_instance.in_reverse ()) {
82+ if (!request.buffer_ready )
83+ continue ;
9184
92- TRY (buffer.write (request.pending_request ->bytes ()));
93- request.buffer_ready = false ;
94- return request.pending_request ->size ();
95- }
85+ TRY (buffer.write (request.pending_request ->bytes ()));
86+ request.buffer_ready = false ;
87+ return request.pending_request ->size ();
88+ }
9689
97- return Error::from_errno (ENOENT);
98- });
90+ return Error::from_errno (ENOENT);
9991}
10092
10193ErrorOr<size_t > FUSEDevice::write (OpenFileDescription& description, u64 , UserOrKernelBuffer const & buffer, size_t size)
10294{
103- return m_instances.with ([&](auto & instances) -> ErrorOr<size_t > {
104- auto instance_iterator = instances.find (&description);
95+ SpinlockLocker locker (m_lock);
10596
106- if (instance_iterator == instances.end ())
107- return Error::from_errno (ENODEV);
97+ auto instance_iterator = m_instances.find (&description);
98+ if (instance_iterator == m_instances.end ())
99+ return Error::from_errno (ENODEV);
108100
109- auto & requests_for_instance = (*instance_iterator).value ;
110- auto & instance = requests_for_instance.last ();
101+ auto & requests_for_instance = (*instance_iterator).value ;
102+ auto & instance = requests_for_instance.last ();
111103
112- if (instance.expecting_header ) {
113- memset (instance.response ->data (), 0 , instance.response ->size ());
104+ if (instance.expecting_header ) {
105+ memset (instance.response ->data (), 0 , instance.response ->size ());
114106
115- fuse_out_header header;
116- TRY (buffer.read (&header, 0 , sizeof (fuse_out_header)));
107+ fuse_out_header header;
108+ TRY (buffer.read (&header, 0 , sizeof (fuse_out_header)));
117109
118- dbgln_if (FUSE_DEBUG, " header: length: {}, error: {}, unique: {}" , header.len , header.error , header.unique );
119- memcpy (instance.response ->data (), &header, sizeof (fuse_out_header));
110+ dbgln_if (FUSE_DEBUG, " header: length: {}, error: {}, unique: {}" , header.len , header.error , header.unique );
111+ memcpy (instance.response ->data (), &header, sizeof (fuse_out_header));
120112
121- if (header.len > sizeof (fuse_out_header))
122- instance.expecting_header = false ;
123- else
124- instance.response_ready = true ;
125- } else {
126- fuse_out_header* existing_header = bit_cast<fuse_out_header*>(instance.response ->data ());
113+ if (header.len > sizeof (fuse_out_header))
114+ instance.expecting_header = false ;
115+ else
116+ instance.response_ready = true ;
117+ } else {
118+ fuse_out_header* existing_header = bit_cast<fuse_out_header*>(instance.response ->data ());
127119
128- instance.expecting_header = true ;
129- if (existing_header->len > instance.response ->size ())
130- return Error::from_errno (EINVAL);
120+ instance.expecting_header = true ;
121+ if (existing_header->len > instance.response ->size ())
122+ return Error::from_errno (EINVAL);
131123
132- instance.response_ready = true ;
133- u64 length = existing_header->len - sizeof (fuse_out_header);
134- dbgln_if (FUSE_DEBUG, " request: response length: {}" , length);
135- TRY (buffer.read (instance.response ->data () + sizeof (fuse_out_header), 0 , length));
136- }
124+ instance.response_ready = true ;
125+ u64 length = existing_header->len - sizeof (fuse_out_header);
126+ dbgln_if (FUSE_DEBUG, " request: response length: {}" , length);
127+ TRY (buffer.read (instance.response ->data () + sizeof (fuse_out_header), 0 , length));
128+ }
137129
138- return size;
139- });
130+ return size;
140131}
141132
142133ErrorOr<NonnullOwnPtr<KBuffer>> FUSEDevice::send_request_and_wait_for_a_reply (OpenFileDescription const & description, Bytes bytes)
143134{
144- return m_instances.with ([&](auto & instances) -> ErrorOr<NonnullOwnPtr<KBuffer>> {
145- auto instance_iterator = instances.find (&description);
146- VERIFY (instance_iterator != instances.end ());
147- auto & requests_for_instance = (*instance_iterator).value ;
148-
149- TRY (requests_for_instance.try_append ({
150- &description,
151- TRY (KBuffer::try_create_with_size (" FUSE: Pending request buffer" sv, 0x21000 )),
152- TRY (KBuffer::try_create_with_size (" FUSE: Response buffer" sv, 0x21000 )),
153- }));
154-
155- size_t instance_index = requests_for_instance.size () - 1 ;
156- auto & instance = requests_for_instance.last ();
157- VERIFY (bytes.size () <= 0x21000 );
158-
159- memset (instance.pending_request ->data (), 0 , instance.pending_request ->size ());
160- memcpy (instance.pending_request ->data (), bytes.data (), bytes.size ());
161- instance.buffer_ready = true ;
162- evaluate_block_conditions ();
135+ SpinlockLocker locker (m_lock);
136+
137+ auto instance_iterator = m_instances.find (&description);
138+ VERIFY (instance_iterator != m_instances.end ());
139+ auto & requests_for_instance = (*instance_iterator).value ;
163140
164- while (!instance.response_ready )
165- (void )Thread::current ()->sleep (Duration::from_microseconds (100 ));
141+ TRY (requests_for_instance.try_append ({
142+ &description,
143+ TRY (KBuffer::try_create_with_size (" FUSE: Pending request buffer" sv, 0x21000 )),
144+ TRY (KBuffer::try_create_with_size (" FUSE: Response buffer" sv, 0x21000 )),
145+ }));
146+
147+ size_t instance_index = requests_for_instance.size () - 1 ;
148+ auto & instance = requests_for_instance.last ();
149+ VERIFY (bytes.size () <= 0x21000 );
150+
151+ memset (instance.pending_request ->data (), 0 , instance.pending_request ->size ());
152+ memcpy (instance.pending_request ->data (), bytes.data (), bytes.size ());
153+ instance.buffer_ready = true ;
154+
155+ while (!instance.response_ready ) {
156+ locker.unlock ();
157+ evaluate_block_conditions ();
158+ Scheduler::yield ();
159+ locker.lock ();
160+ }
166161
167- auto result = KBuffer::try_create_with_bytes (" FUSEDevice: Response" sv, instance.response ->bytes ());
168- requests_for_instance.remove (instance_index);
162+ auto result = KBuffer::try_create_with_bytes (" FUSEDevice: Response" sv, instance.response ->bytes ());
163+ requests_for_instance.remove (instance_index);
169164
170- return result;
171- });
165+ return result;
172166}
173167
174168void FUSEDevice::shutdown_for_description (OpenFileDescription const & description)
175169{
176- m_instances.with ([&](auto & instances) {
177- VERIFY (instances.remove (&description));
178- });
170+ SpinlockLocker locker (m_lock);
179171
180- m_closing_instances.with ([&](auto & closing_instances) {
181- closing_instances.append (&description);
182- });
172+ VERIFY (m_instances.remove (&description));
173+ m_closing_instances.append (&description);
183174
175+ locker.unlock ();
184176 evaluate_block_conditions ();
185177}
186178
0 commit comments