Struct Allocator

Source
pub(super) struct Allocator<S: Storage> {
    file: Arc<S>,
    reftable: RefTable,
    first_free_cluster: HostCluster,
    header: Arc<Header>,
    rb_cache: AsyncLruCache<HostCluster, RefBlock, RefBlockCacheBackend<S>>,
}
Expand description

Central facility for cluster allocation.

Fields§

§file: Arc<S>

Qcow2 metadata file.

§reftable: RefTable

Qcow2 refcount table.

§first_free_cluster: HostCluster

The first free cluster index in the qcow2 file, to speed up allocation.

§header: Arc<Header>

Qcow2 image header.

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

Refblock cache.

Implementations§

Source§

impl<S: Storage> Allocator<S>

Source

pub async fn new(image: Arc<S>, header: Arc<Header>) -> Result<Self>

Create a new allocator for the given image file.

Source

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

Flush the refcount block cache.

Source

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

Invaidate the refcount block cache.

§Safety

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

Source

async fn allocate_clusters( &mut self, count: ClusterCount, end_cluster: Option<HostCluster>, ) -> Result<HostCluster>

Allocate clusters in the image file.

end_cluster should only be used when allocating refblocks. When reaching this cluster index, abort trying to allocate. (This is used for allocating refblocks, to prevent infinite recursion and speed things up.)

Source

async fn allocate_clusters_at( &mut self, index: HostCluster, count: ClusterCount, ) -> Result<ClusterCount>

Allocate the given clusters in the image file.

Allocate up to count unallocated clusters starting from index. When encountering an already allocated cluster (or any other error), stop, and free the clusters that were just newly allocated.

Returns the number of clusters that could be allocated (starting from index), which may be 0 if index has already been allocated. Note again that in case this is less than count, those clusters will have been freed again already, so this is just a hint to callers that the cluster at index + count is already allocated.

Source

async fn allocate_cluster_at(&mut self, index: HostCluster) -> Result<bool>

Allocate the given cluster in the image file.

Return Ok(true) if allocation was successful, or Ok(false) if the cluster was already allocated before.

Source

async fn get_rb(&mut self, rt_index: usize) -> Result<Option<Arc<RefBlock>>>

Get the refblock referenced by the given reftable index, if any.

If there is no refblock for the given reftable index, return Ok(None).

Source

async fn ensure_rb(&mut self, rt_index: usize) -> Result<Arc<RefBlock>>

Get a refblock for the given reftable index.

If there already is a refblock at that index, return it. Otherwise, create one and hook it up.

Source

async fn grow_reftable(&mut self, at_least_index: usize) -> Result<()>

Create a new refcount table covering at least at_least_index.

Create a new reftable of the required size, copy all existing refblock references into it, ensure it is refcounted itself (also creating new refblocks if necessary), and have the image header reference the new refcount table.

Source

async fn free_clusters(&mut self, start: HostCluster, count: ClusterCount)

Free clusters (i.e. decrement their refcount).

Best-effort operation. On error, the given clusters may be leaked, but no errors are ever returned (because there is no good way to handle such errors anyway).

Auto Trait Implementations§

§

impl<S> !Freeze for Allocator<S>

§

impl<S> !RefUnwindSafe for Allocator<S>

§

impl<S> Send for Allocator<S>

§

impl<S> Sync for Allocator<S>

§

impl<S> Unpin for Allocator<S>

§

impl<S> !UnwindSafe for Allocator<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