Struct MetadataCaches

Source
pub(super) struct MetadataCaches<S: Storage> {
    l2: AsyncLruCache<HostCluster, L2Table, L2CacheBackend<S>>,
    rb: AsyncLruCache<HostCluster, RefBlock, RefBlockCacheBackend<S>>,
    direction: RwLock<CacheDependency>,
}
Expand description

Qcow2 metadata caches with flush-ordering coordination.

When allocating clusters, we need to increment the refcounts (from 0 to 1) before writing the L2 pointers. Therefore, before anything is written from the L2 cache to disk, we need to flush the refblock cache.

When freeing clusters, we need to clear the L2 pointers before decrementing the refcounts (to 0). Therefore before anything is written from the refblock cache to disk, we need to flush the L2 cache.

This structure takes care to heed those dependencies (though the general qcow2 code still needs to announce them by calling .l2_depends_on_rb() for allocations and .rb_depends_on_l2() for freeing).

Fields§

§l2: AsyncLruCache<HostCluster, L2Table, L2CacheBackend<S>>

L2 table cache

§rb: AsyncLruCache<HostCluster, RefBlock, RefBlockCacheBackend<S>>

Refblock cache

§direction: RwLock<CacheDependency>

Current dependency direction

Wrapped methods hold a read guard for their entire execution, preventing the direction from changing mid-operation. Direction switch methods take a write guard.

Implementations§

Source§

impl<S: Storage> MetadataCaches<S>

Source

pub fn new( file: &Arc<S>, header: &Arc<Header>, l2_entries: usize, rb_entries: usize, ) -> Self

Create metadata caches for the given file, with the given header.

The L2 cache is going to hold l2_entries tables, the refblock cache will have rb_entries refcount blocks.

Source

pub async fn l2_depends_on_rb(&self) -> Result<()>

Make sure the refblock cache is flushed before the L2 cache.

Use before allocating new clusters.

Source

pub async fn rb_depends_on_l2(&self) -> Result<()>

Make sure the L2 cache is flushed before the refblock cache.

Use before freeing clusters.

Source

pub async fn flush_all(&self) -> Result<()>

Flush both L2 and refblock cache to disk.

Source

pub async fn l2_get_or_insert( &self, cluster_index: HostCluster, ) -> Result<Arc<L2Table>>

Retrieve an L2 table from the cache.

See AsyncLruCache::get_or_insert() for details.

Source

pub async fn l2_insert( &self, cluster_index: HostCluster, table: Arc<L2Table>, ) -> Result<()>

Force-insert an L2 table.

See AsyncLruCache::insert() for details.

Source

pub async unsafe fn invalidate_l2(&self) -> Result<()>

Invalidate the L2 cache.

§Safety

May cause image corruption, you must guarantee the on-disk state is consistent.

Source

pub async fn rb_get_or_insert( &self, cluster_index: HostCluster, ) -> Result<Arc<RefBlock>>

Retrieve a refblock from the cache.

See AsyncLruCache::get_or_insert() for details.

Source

pub async fn rb_insert( &self, cluster_index: HostCluster, rb: Arc<RefBlock>, ) -> Result<()>

Force-insert a refblock.

See AsyncLruCache::insert() for details.

Source

pub async fn flush_rb(&self) -> Result<()>

Flush the refblock cache to disk.

Source

pub async unsafe fn invalidate_rb(&self) -> Result<()>

Invalidate the refblock cache.

§Safety

May cause image corruption, you must guarantee the on-disk state is consistent.

Auto Trait Implementations§

§

impl<S> !Freeze for MetadataCaches<S>

§

impl<S> !RefUnwindSafe for MetadataCaches<S>

§

impl<S> Send for MetadataCaches<S>

§

impl<S> Sync for MetadataCaches<S>

§

impl<S> Unpin for MetadataCaches<S>

§

impl<S> !UnwindSafe for MetadataCaches<S>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more