1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright 2023 Red Hat
9 #include <linux/atomic.h>
10 #include <linux/cache.h>
11 #include <linux/dm-bufio.h>
12 #include <linux/limits.h>
14 #include "permassert.h"
15 #include "thread-utils.h"
17 #include "chapter-index.h"
21 #include "index-layout.h"
22 #include "index-page-map.h"
23 #include "radix-sort.h"
24 #include "sparse-cache.h"
27 * The volume manages deduplication records on permanent storage. The term "volume" can also refer
28 * to the region of permanent storage where the records (and the chapters containing them) are
29 * stored. The volume handles all I/O to this region by reading, caching, and writing chapter pages
33 enum index_lookup_mode
{
34 /* Always do lookups in all chapters normally */
36 /* Only do a subset of lookups needed when rebuilding an index */
44 struct uds_request
*first_request
;
45 struct uds_request
*last_request
;
48 struct __aligned(L1_CACHE_BYTES
) search_pending_counter
{
53 /* Whether this page is currently being read asynchronously */
55 /* The physical page stored in this cache entry */
57 /* The value of the volume clock when this page was 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
;
66 /* The number of zones */
67 unsigned int zone_count
;
68 /* The number of volume pages that can be cached */
70 /* The maximum number of simultaneously cached pages */
72 /* An index for each physical page noting where it is in the cache */
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
;
81 /* All entries above this point are constant after initialization. */
84 * These values are all indexes into the array of read queue entries. New entries in the
85 * read queue are enqueued at read_queue_last. To dequeue entries, a reader thread gets the
86 * lock and then claims the entry pointed to by read_queue_next_read and increments that
87 * 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 to
89 * 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.
93 u16 read_queue_next_read
;
100 struct index_geometry
*geometry
;
101 struct dm_bufio_client
*client
;
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
;
110 struct sparse_cache
*sparse_cache
;
111 struct page_cache page_cache
;
112 struct index_page_map
*index_page_map
;
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
;
121 enum index_lookup_mode lookup_mode
;
122 unsigned int reserved_buffers
;
125 int __must_check
uds_make_volume(const struct uds_configuration
*config
,
126 struct index_layout
*layout
,
127 struct volume
**new_volume
);
129 void uds_free_volume(struct volume
*volume
);
131 int __must_check
uds_replace_volume_storage(struct volume
*volume
,
132 struct index_layout
*layout
,
133 struct block_device
*bdev
);
135 int __must_check
uds_find_volume_chapter_boundaries(struct volume
*volume
,
136 u64
*lowest_vcn
, u64
*highest_vcn
,
139 int __must_check
uds_search_volume_page_cache(struct volume
*volume
,
140 struct uds_request
*request
,
143 int __must_check
uds_search_volume_page_cache_for_rebuild(struct volume
*volume
,
144 const struct uds_record_name
*name
,
148 int __must_check
uds_search_cached_record_page(struct volume
*volume
,
149 struct uds_request
*request
, u32 chapter
,
150 u16 record_page_number
, bool *found
);
152 void uds_forget_chapter(struct volume
*volume
, u64 chapter
);
154 int __must_check
uds_write_chapter(struct volume
*volume
,
155 struct open_chapter_index
*chapter_index
,
156 const struct uds_volume_record records
[]);
158 void uds_prefetch_volume_chapter(const struct volume
*volume
, u32 chapter
);
160 int __must_check
uds_read_chapter_index_from_volume(const struct volume
*volume
,
162 struct dm_buffer
*volume_buffers
[],
163 struct delta_index_page index_pages
[]);
165 int __must_check
uds_get_volume_record_page(struct volume
*volume
, u32 chapter
,
166 u32 page_number
, u8
**data_ptr
);
168 int __must_check
uds_get_volume_index_page(struct volume
*volume
, u32 chapter
,
170 struct delta_index_page
**page_ptr
);
172 #endif /* UDS_VOLUME_H */