brintos

brintos / linux-shallow public Read only

0
0
Text · 5.3 KiB · 8679a5e Raw
173 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright 2023 Red Hat4 */5 6#ifndef UDS_VOLUME_H7#define UDS_VOLUME_H8 9#include <linux/atomic.h>10#include <linux/cache.h>11#include <linux/dm-bufio.h>12#include <linux/limits.h>13 14#include "permassert.h"15#include "thread-utils.h"16 17#include "chapter-index.h"18#include "config.h"19#include "geometry.h"20#include "indexer.h"21#include "index-layout.h"22#include "index-page-map.h"23#include "radix-sort.h"24#include "sparse-cache.h"25 26/*27 * The volume manages deduplication records on permanent storage. The term "volume" can also refer28 * to the region of permanent storage where the records (and the chapters containing them) are29 * stored. The volume handles all I/O to this region by reading, caching, and writing chapter pages30 * as necessary.31 */32 33enum index_lookup_mode {34	/* Always do lookups in all chapters normally */35	LOOKUP_NORMAL,36	/* Only do a subset of lookups needed when rebuilding an index */37	LOOKUP_FOR_REBUILD,38};39 40struct queued_read {41	bool invalid;42	bool reserved;43	u32 physical_page;44	struct uds_request *first_request;45	struct uds_request *last_request;46};47 48struct __aligned(L1_CACHE_BYTES) search_pending_counter {49	u64 atomic_value;50};51 52struct cached_page {53	/* Whether this page is currently being read asynchronously */54	bool read_pending;55	/* The physical page stored in this cache entry */56	u32 physical_page;57	/* The value of the volume clock when this page was last used */58	s64 last_used;59	/* The cached page buffer */60	struct dm_buffer *buffer;61	/* The chapter index page, meaningless for record pages */62	struct delta_index_page index_page;63};64 65struct page_cache {66	/* The number of zones */67	unsigned int zone_count;68	/* The number of volume pages that can be cached */69	u32 indexable_pages;70	/* The maximum number of simultaneously cached pages */71	u16 cache_slots;72	/* An index for each physical page noting where it is in the cache */73	u16 *index;74	/* The array of cached pages */75	struct cached_page *cache;76	/* A counter for each zone tracking if a search is occurring there */77	struct search_pending_counter *search_pending_counters;78	/* The read queue entries as a circular array */79	struct queued_read *read_queue;80 81	/* All entries above this point are constant after initialization. */82 83	/*84	 * These values are all indexes into the array of read queue entries. New entries in the85	 * read queue are enqueued at read_queue_last. To dequeue entries, a reader thread gets the86	 * lock and then claims the entry pointed to by read_queue_next_read and increments that87	 * value. After the read is completed, the reader thread calls release_read_queue_entry(),88	 * which increments read_queue_first until it points to a pending read, or is equal to89	 * read_queue_next_read. This means that if multiple reads are outstanding,90	 * read_queue_first might not advance until the last of the reads finishes.91	 */92	u16 read_queue_first;93	u16 read_queue_next_read;94	u16 read_queue_last;95 96	atomic64_t clock;97};98 99struct volume {100	struct index_geometry *geometry;101	struct dm_bufio_client *client;102	u64 nonce;103	size_t cache_size;104 105	/* A single page worth of records, for sorting */106	const struct uds_volume_record **record_pointers;107	/* Sorter for sorting records within each page */108	struct radix_sorter *radix_sorter;109 110	struct sparse_cache *sparse_cache;111	struct page_cache page_cache;112	struct index_page_map *index_page_map;113 114	struct mutex read_threads_mutex;115	struct cond_var read_threads_cond;116	struct cond_var read_threads_read_done_cond;117	struct thread **reader_threads;118	unsigned int read_thread_count;119	bool read_threads_exiting;120 121	enum index_lookup_mode lookup_mode;122	unsigned int reserved_buffers;123};124 125int __must_check uds_make_volume(const struct uds_configuration *config,126				 struct index_layout *layout,127				 struct volume **new_volume);128 129void uds_free_volume(struct volume *volume);130 131int __must_check uds_replace_volume_storage(struct volume *volume,132					    struct index_layout *layout,133					    struct block_device *bdev);134 135int __must_check uds_find_volume_chapter_boundaries(struct volume *volume,136						    u64 *lowest_vcn, u64 *highest_vcn,137						    bool *is_empty);138 139int __must_check uds_search_volume_page_cache(struct volume *volume,140					      struct uds_request *request,141					      bool *found);142 143int __must_check uds_search_volume_page_cache_for_rebuild(struct volume *volume,144							  const struct uds_record_name *name,145							  u64 virtual_chapter,146							  bool *found);147 148int __must_check uds_search_cached_record_page(struct volume *volume,149					       struct uds_request *request, u32 chapter,150					       u16 record_page_number, bool *found);151 152void uds_forget_chapter(struct volume *volume, u64 chapter);153 154int __must_check uds_write_chapter(struct volume *volume,155				   struct open_chapter_index *chapter_index,156				   const struct uds_volume_record records[]);157 158void uds_prefetch_volume_chapter(const struct volume *volume, u32 chapter);159 160int __must_check uds_read_chapter_index_from_volume(const struct volume *volume,161						    u64 virtual_chapter,162						    struct dm_buffer *volume_buffers[],163						    struct delta_index_page index_pages[]);164 165int __must_check uds_get_volume_record_page(struct volume *volume, u32 chapter,166					    u32 page_number, u8 **data_ptr);167 168int __must_check uds_get_volume_index_page(struct volume *volume, u32 chapter,169					   u32 page_number,170					   struct delta_index_page **page_ptr);171 172#endif /* UDS_VOLUME_H */173