Skip to content

virtio-devices, block: generalize disk locking - #191

Open
Coffeeri wants to merge 3 commits into
cyberus-technology:gardenlinuxfrom
Coffeeri:generalize-lock
Open

virtio-devices, block: generalize disk locking#191
Coffeeri wants to merge 3 commits into
cyberus-technology:gardenlinuxfrom
Coffeeri:generalize-lock

Conversation

@Coffeeri

Copy link
Copy Markdown

These changes support blockdev-mirror.

Blockdev-Mirroring keeps both the source and destination disk open. The existing locking helpers always operated on Block::disk_image, so they could not be reused for the destination.
This PR generalizes lock granularity and acquisition to accept an explicit disk backend and path, while keeping the existing source-disk wrapper.

It also fixes stale QEMU-compatible locks after a successful downgrade. Read-only sources use a write lock for the destination while mirroring, then downgrade it to a read lock after completion. Previously, the write marker remained locked after the successful downgrade, preventing another reader from acquiring the image. The unused lock bytes are now released.

Calculate advisory lock granularity for an explicitly supplied disk
backend and path instead of always using Block::disk_image. This lets
mirror destinations reuse the configured locking policy.

On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
Extract advisory lock acquisition into a helper that accepts a disk
backend, path, requested mode, and current mode. Keep try_lock_image as
the source-disk wrapper.

This enables the generalized use of `try_lock_disk_image` for other disk
images within the same Block device, which occurs whenever we mirror a
disk image.

On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
@Coffeeri
Coffeeri requested a review from arctic-alpaca August 12, 2026 13:47
Downgrading a QEMU-compatible lock from write to read leaves the write
marker byte locked. try_acquire_lock_qemu() only releases unneeded bytes
when rolling back after a failed acquisition, so a successful downgrade
keeps the write marker in place.

This blocks mirroring of read-only disks. The destination acquires a
write lock while data is copied and must downgrade to the source's
read-only lock when the mirror completes. The stale write marker
prevents another reader from locking the image.

Release the bytes that the new lock type does not need once the conflict
checks succeed, and add a test that downgrades a write lock to a read
lock and verifies that another reader can still acquire the image.

On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
@arctic-alpaca

Copy link
Copy Markdown

I'm not sure breaking open the API is a maintenance-friendly way to achieve the goal. On the other hand, we need to rethink parts of the disk locking anyway to address https://github.com/cobaltcore-dev/cobaltcore/issues/628. To unblock the blockdev-mirror, I think it's fair to continue with the PR on the premise that we will have to refactor disk locking anyway and can take the blockdev-mirror use case into account.

Comment on lines +1016 to +1017
/// Acquires an advisory lock for an arbitrary disk backend.
fn try_lock_disk_image(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should retain the notion of trying to acquire the lock, since locking can fail.

Comment on lines +982 to +987
/// Returns the configured advisory lock granularity for `disk_image`.
fn lock_granularity(
&self,
disk_image: &dyn AsyncFullDiskFile,
disk_path: &Path,
) -> LockGranularity {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should include, that the lock granularity is influenced by the choice made in block.

Comment thread block/src/fcntl.rs
return Err(error);
}

self.release_unneeded_locks_qemu(file, lock_type)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment why we're doing this, similar to the commit message?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants