Kernel: Avoid double-locking devices when trying to acquire them

Previously, you'd occasionally see this sort of construct (simplified):
```
return FooDevice::all_instances().with([&](auto& list) {
    for (auto& device : list) {
        if (/* search condition */)
            continue;
        return do_something_that_reacquires(device.index());
    }
    return ENOENT;
});
```

This would only work if the relevant `all_instances()` used a recursive
spinlock, since reacquiring the device would lock that again.

To get around this, a new helper has been added in `Device` through
which devices can be accessed whilst locking the device list, removing
the need to loop through the device type's `all_instances()`.
This commit is contained in:
implicitfield
2025-05-16 14:12:16 +03:00
committed by Sönke Holz
parent d3a314f5cd
commit 6a4ceb6bf2
12 changed files with 74 additions and 59 deletions

View File

@@ -446,7 +446,10 @@ ErrorOr<NonnullRefPtr<OpenFileDescription>> VirtualFileSystem::open(Process cons
if (custody.mount_flags() & MS_NODEV)
return EACCES;
auto device_type = metadata.is_block_device() ? DeviceNodeType::Block : DeviceNodeType::Character;
auto device = Device::acquire_by_type_and_major_minor_numbers(device_type, metadata.major_device, metadata.minor_device);
RefPtr<Device> device;
Device::run_by_type_and_major_minor_numbers(device_type, metadata.major_device, metadata.minor_device, [&](RefPtr<Device> found_device) {
device = move(found_device);
});
if (device == nullptr) {
return ENODEV;
}