dm vdo indexer: rename uds.h to indexer.h
authorMike Snitzer <snitzer@kernel.org>
Fri, 9 Feb 2024 18:16:13 +0000 (12:16 -0600)
committerMike Snitzer <snitzer@kernel.org>
Fri, 1 Mar 2024 14:25:49 +0000 (09:25 -0500)
Also remove unnecessary include from funnel-queue.c.

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Matthew Sakai <msakai@redhat.com>
23 files changed:
drivers/md/dm-vdo/chapter-index.c
drivers/md/dm-vdo/config.h
drivers/md/dm-vdo/data-vio.h
drivers/md/dm-vdo/dedupe.c
drivers/md/dm-vdo/dedupe.h
drivers/md/dm-vdo/delta-index.c
drivers/md/dm-vdo/encodings.h
drivers/md/dm-vdo/funnel-queue.c
drivers/md/dm-vdo/funnel-requestqueue.h
drivers/md/dm-vdo/geometry.c
drivers/md/dm-vdo/geometry.h
drivers/md/dm-vdo/hash-utils.h
drivers/md/dm-vdo/index-layout.h
drivers/md/dm-vdo/index-page-map.c
drivers/md/dm-vdo/index-session.h
drivers/md/dm-vdo/indexer.h [new file with mode: 0644]
drivers/md/dm-vdo/sparse-cache.h
drivers/md/dm-vdo/uds-sysfs.c
drivers/md/dm-vdo/uds.h [deleted file]
drivers/md/dm-vdo/vdo.h
drivers/md/dm-vdo/volume-index.c
drivers/md/dm-vdo/volume-index.h
drivers/md/dm-vdo/volume.h

index 363991d56218325487d8db6a84344d92ca40e237..9b9185c2c2374ac2629ffc0481fe8bce2b60ba84 100644 (file)
@@ -7,10 +7,10 @@
 
 #include "errors.h"
 #include "hash-utils.h"
+#include "indexer.h"
 #include "logger.h"
 #include "memory-alloc.h"
 #include "permassert.h"
-#include "uds.h"
 
 int uds_make_open_chapter_index(struct open_chapter_index **chapter_index,
                                const struct index_geometry *geometry, u64 volume_nonce)
index 7d19863800d6b011d292d7f61d90bd1e3f5d9692..08507dc2f7a14723e9b28aa098057332ef878be0 100644 (file)
@@ -7,8 +7,8 @@
 #define UDS_CONFIG_H
 
 #include "geometry.h"
+#include "indexer.h"
 #include "io-factory.h"
-#include "uds.h"
 
 /*
  * The uds_configuration records a variety of parameters used to configure a new UDS index. Some
index 78744d064e9638fd6b61d6cde1fce89d5537d674..e7729623a6bb53a5107f34d8b3798f85e064aa3c 100644 (file)
@@ -10,8 +10,8 @@
 #include <linux/bio.h>
 #include <linux/list.h>
 
+#include "indexer.h"
 #include "permassert.h"
-#include "uds.h"
 
 #include "block-map.h"
 #include "completion.h"
index 2a1902c4423c5a744dbac2ad1b6aca7a481e983f..942a50ef8b0d82cfbefecf3b2807377c81ecefe9 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 
+#include "indexer.h"
 #include "logger.h"
 #include "memory-alloc.h"
 #include "numeric.h"
 #include "permassert.h"
 #include "string-utils.h"
-#include "uds.h"
 
 #include "action-manager.h"
 #include "admin-state.h"
index 773dde5f93654be11330f470b2a28a3c745cabfa..1566fc972ea74cdefaf647c44244ccbdde6bec40 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 
-#include "uds.h"
+#include "indexer.h"
 
 #include "admin-state.h"
 #include "constants.h"
index 6306777bb20288bbef9e2c368fbf08faae4b508c..66f51b5f8fd21d9ddf58b7344d3871654d56736c 100644 (file)
 #include "config.h"
 #include "cpu.h"
 #include "errors.h"
+#include "indexer.h"
 #include "logger.h"
 #include "memory-alloc.h"
 #include "numeric.h"
 #include "permassert.h"
 #include "string-utils.h"
 #include "time-utils.h"
-#include "uds.h"
 
 /*
  * The entries in a delta index could be stored in a single delta list, but to reduce search times
index ba3db9867f4a8e1f1a2a96ce58ab9fd8ed96ded8..18794fd59b0bbb04e2830079c338ce846690e326 100644 (file)
@@ -11,8 +11,8 @@
 #include <linux/limits.h>
 #include <linux/uuid.h>
 
+#include "indexer.h"
 #include "numeric.h"
-#include "uds.h"
 
 #include "constants.h"
 #include "types.h"
index 6940b282086d68c6bf9d817a39af24e78f50a672..d5d96bb38b947d0c306a9a7bb6143ee94cda9c3b 100644 (file)
@@ -8,7 +8,6 @@
 #include "cpu.h"
 #include "memory-alloc.h"
 #include "permassert.h"
-#include "uds.h"
 
 int uds_make_funnel_queue(struct funnel_queue **queue_ptr)
 {
index e74c231fe2690c101f33b347de70e7a7d2c4bba4..9b0f53939b4dd027023a3bd16599eb52764f289b 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef UDS_REQUEST_QUEUE_H
 #define UDS_REQUEST_QUEUE_H
 
-#include "uds.h"
+#include "indexer.h"
 
 /*
  * A simple request queue which will handle new requests in the order in which they are received,
index 0e83bba4184ab2cdffa9a9831cd8a8162d5cbb3e..04c07195a01c68d51b275d5e4512a18d16469210 100644 (file)
 
 #include "delta-index.h"
 #include "errors.h"
+#include "indexer.h"
 #include "logger.h"
 #include "memory-alloc.h"
 #include "permassert.h"
-#include "uds.h"
 
 /*
  * An index volume is divided into a fixed number of fixed-size chapters, each consisting of a
index 9a4a66ac2e467b19c6f6474fbd182d81ffda2f52..a2ecdb238cf2dfd4fcbd1321527db716ab04d951 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef UDS_INDEX_GEOMETRY_H
 #define UDS_INDEX_GEOMETRY_H
 
-#include "uds.h"
+#include "indexer.h"
 
 /*
  * The index_geometry records parameters that define the layout of a UDS index volume, and the size and
index e22be69695beb42df7429917d3ae871f00fdb6f8..e3b865bbe9b2cf98412476bca1f1488e476bb5af 100644 (file)
@@ -7,8 +7,8 @@
 #define UDS_HASH_UTILS_H
 
 #include "geometry.h"
+#include "indexer.h"
 #include "numeric.h"
-#include "uds.h"
 
 /* Utilities for extracting portions of a request name for various uses. */
 
index 84a9eb43a49db668775dbf41f70f19ca78a0b06f..e9ac6f4302d632d09db1b84a75adf517e4ef6b52 100644 (file)
@@ -7,8 +7,8 @@
 #define UDS_INDEX_LAYOUT_H
 
 #include "config.h"
+#include "indexer.h"
 #include "io-factory.h"
-#include "uds.h"
 
 /*
  * The index layout describes the format of the index on the underlying storage, and is responsible
index 8441f86ef3a4e0efa262d6afd4caf3641d2416d2..1bb12066ad1a2321c443a8d426d81d39839974cb 100644 (file)
@@ -7,13 +7,13 @@
 
 #include "errors.h"
 #include "hash-utils.h"
+#include "indexer.h"
 #include "logger.h"
 #include "memory-alloc.h"
 #include "numeric.h"
 #include "permassert.h"
 #include "string-utils.h"
 #include "thread-utils.h"
-#include "uds.h"
 
 /*
  * The index page map is conceptually a two-dimensional array indexed by chapter number and index
index 62a9020dd9fa84bc4065eb3a505660422b127e84..733d10f8a56cd2e6ba6b81cbfc6c453da4bf790b 100644 (file)
@@ -10,8 +10,8 @@
 #include <linux/cache.h>
 
 #include "config.h"
+#include "indexer.h"
 #include "thread-utils.h"
-#include "uds.h"
 
 /*
  * The index session mediates all interactions with a UDS index. Once the index session is created,
diff --git a/drivers/md/dm-vdo/indexer.h b/drivers/md/dm-vdo/indexer.h
new file mode 100644 (file)
index 0000000..59e6a5c
--- /dev/null
@@ -0,0 +1,329 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2023 Red Hat
+ */
+
+#ifndef INDEXER_H
+#define INDEXER_H
+
+#include <linux/types.h>
+
+#include "funnel-queue.h"
+
+/*
+ * UDS public API
+ *
+ * The Universal Deduplication System (UDS) is an efficient name-value store. When used for
+ * deduplicating storage, the names are generally hashes of data blocks and the associated data is
+ * where that block is located on the underlying storage medium. The stored names are expected to
+ * be randomly distributed among the space of possible names. If this assumption is violated, the
+ * UDS index will store fewer names than normal but will otherwise continue to work. The data
+ * associated with each name can be any 16-byte value.
+ *
+ * A client must first create an index session to interact with an index. Once created, the session
+ * can be shared among multiple threads or users. When a session is destroyed, it will also close
+ * and save any associated index.
+ *
+ * To make a request, a client must allocate a uds_request structure and set the required fields
+ * before launching it. UDS will invoke the provided callback to complete the request. After the
+ * callback has been called, the uds_request structure can be freed or reused for a new request.
+ * There are five types of requests:
+ *
+ * A UDS_UPDATE request will associate the provided name with the provided data. Any previous data
+ * associated with that name will be discarded.
+ *
+ * A UDS_QUERY request will return the data associated with the provided name, if any. The entry
+ * for the name will also be marked as most recent, as if the data had been updated.
+ *
+ * A UDS_POST request is a combination of UDS_QUERY and UDS_UPDATE. If there is already data
+ * associated with the provided name, that data is returned. If there is no existing association,
+ * the name is associated with the newly provided data. This request is equivalent to a UDS_QUERY
+ * request followed by a UDS_UPDATE request if no data is found, but it is much more efficient.
+ *
+ * A UDS_QUERY_NO_UPDATE request will return the data associated with the provided name, but will
+ * not change the recency of the entry for the name. This request is primarily useful for testing,
+ * to determine whether an entry exists without changing the internal state of the index.
+ *
+ * A UDS_DELETE request removes any data associated with the provided name. This operation is
+ * generally not necessary, because the index will automatically discard its oldest entries once it
+ * becomes full.
+ */
+
+/* General UDS constants and structures */
+
+enum uds_request_type {
+       /* Create or update the mapping for a name, and make the name most recent. */
+       UDS_UPDATE,
+
+       /* Return any mapped data for a name, and make the name most recent. */
+       UDS_QUERY,
+
+       /*
+        * Return any mapped data for a name, or map the provided data to the name if there is no
+        * current data, and make the name most recent.
+        */
+       UDS_POST,
+
+       /* Return any mapped data for a name without updating its recency. */
+       UDS_QUERY_NO_UPDATE,
+
+       /* Remove any mapping for a name. */
+       UDS_DELETE,
+
+};
+
+enum uds_open_index_type {
+       /* Create a new index. */
+       UDS_CREATE,
+
+       /* Load an existing index and try to recover if necessary. */
+       UDS_LOAD,
+
+       /* Load an existing index, but only if it was saved cleanly. */
+       UDS_NO_REBUILD,
+};
+
+enum {
+       /* The record name size in bytes */
+       UDS_RECORD_NAME_SIZE = 16,
+       /* The maximum record data size in bytes */
+       UDS_RECORD_DATA_SIZE = 16,
+};
+
+/*
+ * A type representing a UDS memory configuration which is either a positive integer number of
+ * gigabytes or one of the six special constants for configurations smaller than one gigabyte.
+ */
+typedef int uds_memory_config_size_t;
+
+enum {
+       /* The maximum configurable amount of memory */
+       UDS_MEMORY_CONFIG_MAX = 1024,
+       /* Flag indicating that the index has one less chapter than usual */
+       UDS_MEMORY_CONFIG_REDUCED = 0x1000,
+       UDS_MEMORY_CONFIG_REDUCED_MAX = 1024 + UDS_MEMORY_CONFIG_REDUCED,
+       /* Special values indicating sizes less than 1 GB */
+       UDS_MEMORY_CONFIG_256MB = -256,
+       UDS_MEMORY_CONFIG_512MB = -512,
+       UDS_MEMORY_CONFIG_768MB = -768,
+       UDS_MEMORY_CONFIG_REDUCED_256MB = -1280,
+       UDS_MEMORY_CONFIG_REDUCED_512MB = -1536,
+       UDS_MEMORY_CONFIG_REDUCED_768MB = -1792,
+};
+
+struct uds_record_name {
+       unsigned char name[UDS_RECORD_NAME_SIZE];
+};
+
+struct uds_record_data {
+       unsigned char data[UDS_RECORD_DATA_SIZE];
+};
+
+struct uds_volume_record {
+       struct uds_record_name name;
+       struct uds_record_data data;
+};
+
+struct uds_parameters {
+       /* The block_device used for storage */
+       struct block_device *bdev;
+       /* The maximum allowable size of the index on storage */
+       size_t size;
+       /* The offset where the index should start */
+       off_t offset;
+       /* The maximum memory allocation, in GB */
+       uds_memory_config_size_t memory_size;
+       /* Whether the index should include sparse chapters */
+       bool sparse;
+       /* A 64-bit nonce to validate the index */
+       u64 nonce;
+       /* The number of threads used to process index requests */
+       unsigned int zone_count;
+       /* The number of threads used to read volume pages */
+       unsigned int read_threads;
+};
+
+/*
+ * These statistics capture characteristics of the current index, including resource usage and
+ * requests processed since the index was opened.
+ */
+struct uds_index_stats {
+       /* The total number of records stored in the index */
+       u64 entries_indexed;
+       /* An estimate of the index's memory usage, in bytes */
+       u64 memory_used;
+       /* The number of collisions recorded in the volume index */
+       u64 collisions;
+       /* The number of entries discarded from the index since startup */
+       u64 entries_discarded;
+       /* The time at which these statistics were fetched */
+       s64 current_time;
+       /* The number of post calls that found an existing entry */
+       u64 posts_found;
+       /* The number of post calls that added an entry */
+       u64 posts_not_found;
+       /*
+        * The number of post calls that found an existing entry that is current enough to only
+        * exist in memory and not have been committed to disk yet
+        */
+       u64 in_memory_posts_found;
+       /*
+        * The number of post calls that found an existing entry in the dense portion of the index
+        */
+       u64 dense_posts_found;
+       /*
+        * The number of post calls that found an existing entry in the sparse portion of the index
+        */
+       u64 sparse_posts_found;
+       /* The number of update calls that updated an existing entry */
+       u64 updates_found;
+       /* The number of update calls that added a new entry */
+       u64 updates_not_found;
+       /* The number of delete requests that deleted an existing entry */
+       u64 deletions_found;
+       /* The number of delete requests that did nothing */
+       u64 deletions_not_found;
+       /* The number of query calls that found existing entry */
+       u64 queries_found;
+       /* The number of query calls that did not find an entry */
+       u64 queries_not_found;
+       /* The total number of requests processed */
+       u64 requests;
+};
+
+enum uds_index_region {
+       /* No location information has been determined */
+       UDS_LOCATION_UNKNOWN = 0,
+       /* The index page entry has been found */
+       UDS_LOCATION_INDEX_PAGE_LOOKUP,
+       /* The record page entry has been found */
+       UDS_LOCATION_RECORD_PAGE_LOOKUP,
+       /* The record is not in the index */
+       UDS_LOCATION_UNAVAILABLE,
+       /* The record was found in the open chapter */
+       UDS_LOCATION_IN_OPEN_CHAPTER,
+       /* The record was found in the dense part of the index */
+       UDS_LOCATION_IN_DENSE,
+       /* The record was found in the sparse part of the index */
+       UDS_LOCATION_IN_SPARSE,
+} __packed;
+
+/* Zone message requests are used to communicate between index zones. */
+enum uds_zone_message_type {
+       /* A standard request with no message */
+       UDS_MESSAGE_NONE = 0,
+       /* Add a chapter to the sparse chapter index cache */
+       UDS_MESSAGE_SPARSE_CACHE_BARRIER,
+       /* Close a chapter to keep the zone from falling behind */
+       UDS_MESSAGE_ANNOUNCE_CHAPTER_CLOSED,
+} __packed;
+
+struct uds_zone_message {
+       /* The type of message, determining how it will be processed */
+       enum uds_zone_message_type type;
+       /* The virtual chapter number to which the message applies */
+       u64 virtual_chapter;
+};
+
+struct uds_index_session;
+struct uds_index;
+struct uds_request;
+
+/* Once this callback has been invoked, the uds_request structure can be reused or freed. */
+typedef void (*uds_request_callback_fn)(struct uds_request *request);
+
+struct uds_request {
+       /* These input fields must be set before launching a request. */
+
+       /* The name of the record to look up or create */
+       struct uds_record_name record_name;
+       /* New data to associate with the record name, if applicable */
+       struct uds_record_data new_metadata;
+       /* A callback to invoke when the request is complete */
+       uds_request_callback_fn callback;
+       /* The index session that will manage this request */
+       struct uds_index_session *session;
+       /* The type of operation to perform, as describe above */
+       enum uds_request_type type;
+
+       /* These output fields are set when a request is complete. */
+
+       /* The existing data associated with the request name, if any */
+       struct uds_record_data old_metadata;
+       /* Either UDS_SUCCESS or an error code for the request */
+       int status;
+       /* True if the record name had an existing entry in the index */
+       bool found;
+
+       /*
+        * The remaining fields are used internally and should not be altered by clients. The index
+        * relies on zone_number being the first field in this section.
+        */
+
+       /* The number of the zone which will process this request*/
+       unsigned int zone_number;
+       /* A link for adding a request to a lock-free queue */
+       struct funnel_queue_entry queue_link;
+       /* A link for adding a request to a standard linked list */
+       struct uds_request *next_request;
+       /* A pointer to the index processing this request */
+       struct uds_index *index;
+       /* Control message for coordinating between zones */
+       struct uds_zone_message zone_message;
+       /* If true, process request immediately by waking the worker thread */
+       bool unbatched;
+       /* If true, continue this request before processing newer requests */
+       bool requeued;
+       /* The virtual chapter containing the record name, if known */
+       u64 virtual_chapter;
+       /* The region of the index containing the record name */
+       enum uds_index_region location;
+};
+
+/* Compute the number of bytes needed to store an index. */
+int __must_check uds_compute_index_size(const struct uds_parameters *parameters,
+                                       u64 *index_size);
+
+/* A session is required for most index operations. */
+int __must_check uds_create_index_session(struct uds_index_session **session);
+
+/* Destroying an index session also closes and saves the associated index. */
+int uds_destroy_index_session(struct uds_index_session *session);
+
+/*
+ * Create or open an index with an existing session. This operation fails if the index session is
+ * suspended, or if there is already an open index.
+ */
+int __must_check uds_open_index(enum uds_open_index_type open_type,
+                               const struct uds_parameters *parameters,
+                               struct uds_index_session *session);
+
+/*
+ * Wait until all callbacks for index operations are complete, and prevent new index operations
+ * from starting. New index operations will fail with EBUSY until the session is resumed. Also
+ * optionally saves the index.
+ */
+int __must_check uds_suspend_index_session(struct uds_index_session *session, bool save);
+
+/*
+ * Allow new index operations for an index, whether it was suspended or not. If the index is
+ * suspended and the supplied block device differs from the current backing store, the index will
+ * start using the new backing store instead.
+ */
+int __must_check uds_resume_index_session(struct uds_index_session *session,
+                                         struct block_device *bdev);
+
+/* Wait until all outstanding index operations are complete. */
+int __must_check uds_flush_index_session(struct uds_index_session *session);
+
+/* Close an index. This operation fails if the index session is suspended. */
+int __must_check uds_close_index(struct uds_index_session *session);
+
+/* Get index statistics since the last time the index was opened. */
+int __must_check uds_get_index_session_stats(struct uds_index_session *session,
+                                            struct uds_index_stats *stats);
+
+/* This function will fail if any required field of the request is not set. */
+int __must_check uds_launch_request(struct uds_request *request);
+
+#endif /* INDEXER_H */
index 90b0be15545396b4f4d2db12aea853590697604b..45e2dcf165b51db17c2934ab2f2b4735c759b074 100644 (file)
@@ -7,7 +7,7 @@
 #define UDS_SPARSE_CACHE_H
 
 #include "geometry.h"
-#include "uds.h"
+#include "indexer.h"
 
 /*
  * The sparse cache is a cache of entire chapter indexes from sparse chapters used for searching
index eee8a5b7d147d6b6dd88e6a8f882b4660376151e..1548092e7de1db60c9493050987db49bf25600a3 100644 (file)
@@ -9,10 +9,10 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
+#include "indexer.h"
 #include "logger.h"
 #include "memory-alloc.h"
 #include "string-utils.h"
-#include "uds.h"
 
 #define UDS_SYSFS_NAME "uds"
 
diff --git a/drivers/md/dm-vdo/uds.h b/drivers/md/dm-vdo/uds.h
deleted file mode 100644 (file)
index 1264362..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright 2023 Red Hat
- */
-
-#ifndef UDS_H
-#define UDS_H
-
-#include <linux/types.h>
-
-#include "funnel-queue.h"
-
-/*
- * UDS public API
- *
- * The Universal Deduplication System (UDS) is an efficient name-value store. When used for
- * deduplicating storage, the names are generally hashes of data blocks and the associated data is
- * where that block is located on the underlying storage medium. The stored names are expected to
- * be randomly distributed among the space of possible names. If this assumption is violated, the
- * UDS index will store fewer names than normal but will otherwise continue to work. The data
- * associated with each name can be any 16-byte value.
- *
- * A client must first create an index session to interact with an index. Once created, the session
- * can be shared among multiple threads or users. When a session is destroyed, it will also close
- * and save any associated index.
- *
- * To make a request, a client must allocate a uds_request structure and set the required fields
- * before launching it. UDS will invoke the provided callback to complete the request. After the
- * callback has been called, the uds_request structure can be freed or reused for a new request.
- * There are five types of requests:
- *
- * A UDS_UPDATE request will associate the provided name with the provided data. Any previous data
- * associated with that name will be discarded.
- *
- * A UDS_QUERY request will return the data associated with the provided name, if any. The entry
- * for the name will also be marked as most recent, as if the data had been updated.
- *
- * A UDS_POST request is a combination of UDS_QUERY and UDS_UPDATE. If there is already data
- * associated with the provided name, that data is returned. If there is no existing association,
- * the name is associated with the newly provided data. This request is equivalent to a UDS_QUERY
- * request followed by a UDS_UPDATE request if no data is found, but it is much more efficient.
- *
- * A UDS_QUERY_NO_UPDATE request will return the data associated with the provided name, but will
- * not change the recency of the entry for the name. This request is primarily useful for testing,
- * to determine whether an entry exists without changing the internal state of the index.
- *
- * A UDS_DELETE request removes any data associated with the provided name. This operation is
- * generally not necessary, because the index will automatically discard its oldest entries once it
- * becomes full.
- */
-
-/* General UDS constants and structures */
-
-enum uds_request_type {
-       /* Create or update the mapping for a name, and make the name most recent. */
-       UDS_UPDATE,
-
-       /* Return any mapped data for a name, and make the name most recent. */
-       UDS_QUERY,
-
-       /*
-        * Return any mapped data for a name, or map the provided data to the name if there is no
-        * current data, and make the name most recent.
-        */
-       UDS_POST,
-
-       /* Return any mapped data for a name without updating its recency. */
-       UDS_QUERY_NO_UPDATE,
-
-       /* Remove any mapping for a name. */
-       UDS_DELETE,
-
-};
-
-enum uds_open_index_type {
-       /* Create a new index. */
-       UDS_CREATE,
-
-       /* Load an existing index and try to recover if necessary. */
-       UDS_LOAD,
-
-       /* Load an existing index, but only if it was saved cleanly. */
-       UDS_NO_REBUILD,
-};
-
-enum {
-       /* The record name size in bytes */
-       UDS_RECORD_NAME_SIZE = 16,
-       /* The maximum record data size in bytes */
-       UDS_RECORD_DATA_SIZE = 16,
-};
-
-/*
- * A type representing a UDS memory configuration which is either a positive integer number of
- * gigabytes or one of the six special constants for configurations smaller than one gigabyte.
- */
-typedef int uds_memory_config_size_t;
-
-enum {
-       /* The maximum configurable amount of memory */
-       UDS_MEMORY_CONFIG_MAX = 1024,
-       /* Flag indicating that the index has one less chapter than usual */
-       UDS_MEMORY_CONFIG_REDUCED = 0x1000,
-       UDS_MEMORY_CONFIG_REDUCED_MAX = 1024 + UDS_MEMORY_CONFIG_REDUCED,
-       /* Special values indicating sizes less than 1 GB */
-       UDS_MEMORY_CONFIG_256MB = -256,
-       UDS_MEMORY_CONFIG_512MB = -512,
-       UDS_MEMORY_CONFIG_768MB = -768,
-       UDS_MEMORY_CONFIG_REDUCED_256MB = -1280,
-       UDS_MEMORY_CONFIG_REDUCED_512MB = -1536,
-       UDS_MEMORY_CONFIG_REDUCED_768MB = -1792,
-};
-
-struct uds_record_name {
-       unsigned char name[UDS_RECORD_NAME_SIZE];
-};
-
-struct uds_record_data {
-       unsigned char data[UDS_RECORD_DATA_SIZE];
-};
-
-struct uds_volume_record {
-       struct uds_record_name name;
-       struct uds_record_data data;
-};
-
-struct uds_parameters {
-       /* The block_device used for storage */
-       struct block_device *bdev;
-       /* The maximum allowable size of the index on storage */
-       size_t size;
-       /* The offset where the index should start */
-       off_t offset;
-       /* The maximum memory allocation, in GB */
-       uds_memory_config_size_t memory_size;
-       /* Whether the index should include sparse chapters */
-       bool sparse;
-       /* A 64-bit nonce to validate the index */
-       u64 nonce;
-       /* The number of threads used to process index requests */
-       unsigned int zone_count;
-       /* The number of threads used to read volume pages */
-       unsigned int read_threads;
-};
-
-/*
- * These statistics capture characteristics of the current index, including resource usage and
- * requests processed since the index was opened.
- */
-struct uds_index_stats {
-       /* The total number of records stored in the index */
-       u64 entries_indexed;
-       /* An estimate of the index's memory usage, in bytes */
-       u64 memory_used;
-       /* The number of collisions recorded in the volume index */
-       u64 collisions;
-       /* The number of entries discarded from the index since startup */
-       u64 entries_discarded;
-       /* The time at which these statistics were fetched */
-       s64 current_time;
-       /* The number of post calls that found an existing entry */
-       u64 posts_found;
-       /* The number of post calls that added an entry */
-       u64 posts_not_found;
-       /*
-        * The number of post calls that found an existing entry that is current enough to only
-        * exist in memory and not have been committed to disk yet
-        */
-       u64 in_memory_posts_found;
-       /*
-        * The number of post calls that found an existing entry in the dense portion of the index
-        */
-       u64 dense_posts_found;
-       /*
-        * The number of post calls that found an existing entry in the sparse portion of the index
-        */
-       u64 sparse_posts_found;
-       /* The number of update calls that updated an existing entry */
-       u64 updates_found;
-       /* The number of update calls that added a new entry */
-       u64 updates_not_found;
-       /* The number of delete requests that deleted an existing entry */
-       u64 deletions_found;
-       /* The number of delete requests that did nothing */
-       u64 deletions_not_found;
-       /* The number of query calls that found existing entry */
-       u64 queries_found;
-       /* The number of query calls that did not find an entry */
-       u64 queries_not_found;
-       /* The total number of requests processed */
-       u64 requests;
-};
-
-enum uds_index_region {
-       /* No location information has been determined */
-       UDS_LOCATION_UNKNOWN = 0,
-       /* The index page entry has been found */
-       UDS_LOCATION_INDEX_PAGE_LOOKUP,
-       /* The record page entry has been found */
-       UDS_LOCATION_RECORD_PAGE_LOOKUP,
-       /* The record is not in the index */
-       UDS_LOCATION_UNAVAILABLE,
-       /* The record was found in the open chapter */
-       UDS_LOCATION_IN_OPEN_CHAPTER,
-       /* The record was found in the dense part of the index */
-       UDS_LOCATION_IN_DENSE,
-       /* The record was found in the sparse part of the index */
-       UDS_LOCATION_IN_SPARSE,
-} __packed;
-
-/* Zone message requests are used to communicate between index zones. */
-enum uds_zone_message_type {
-       /* A standard request with no message */
-       UDS_MESSAGE_NONE = 0,
-       /* Add a chapter to the sparse chapter index cache */
-       UDS_MESSAGE_SPARSE_CACHE_BARRIER,
-       /* Close a chapter to keep the zone from falling behind */
-       UDS_MESSAGE_ANNOUNCE_CHAPTER_CLOSED,
-} __packed;
-
-struct uds_zone_message {
-       /* The type of message, determining how it will be processed */
-       enum uds_zone_message_type type;
-       /* The virtual chapter number to which the message applies */
-       u64 virtual_chapter;
-};
-
-struct uds_index_session;
-struct uds_index;
-struct uds_request;
-
-/* Once this callback has been invoked, the uds_request structure can be reused or freed. */
-typedef void (*uds_request_callback_fn)(struct uds_request *request);
-
-struct uds_request {
-       /* These input fields must be set before launching a request. */
-
-       /* The name of the record to look up or create */
-       struct uds_record_name record_name;
-       /* New data to associate with the record name, if applicable */
-       struct uds_record_data new_metadata;
-       /* A callback to invoke when the request is complete */
-       uds_request_callback_fn callback;
-       /* The index session that will manage this request */
-       struct uds_index_session *session;
-       /* The type of operation to perform, as describe above */
-       enum uds_request_type type;
-
-       /* These output fields are set when a request is complete. */
-
-       /* The existing data associated with the request name, if any */
-       struct uds_record_data old_metadata;
-       /* Either UDS_SUCCESS or an error code for the request */
-       int status;
-       /* True if the record name had an existing entry in the index */
-       bool found;
-
-       /*
-        * The remaining fields are used internally and should not be altered by clients. The index
-        * relies on zone_number being the first field in this section.
-        */
-
-       /* The number of the zone which will process this request*/
-       unsigned int zone_number;
-       /* A link for adding a request to a lock-free queue */
-       struct funnel_queue_entry queue_link;
-       /* A link for adding a request to a standard linked list */
-       struct uds_request *next_request;
-       /* A pointer to the index processing this request */
-       struct uds_index *index;
-       /* Control message for coordinating between zones */
-       struct uds_zone_message zone_message;
-       /* If true, process request immediately by waking the worker thread */
-       bool unbatched;
-       /* If true, continue this request before processing newer requests */
-       bool requeued;
-       /* The virtual chapter containing the record name, if known */
-       u64 virtual_chapter;
-       /* The region of the index containing the record name */
-       enum uds_index_region location;
-};
-
-/* Compute the number of bytes needed to store an index. */
-int __must_check uds_compute_index_size(const struct uds_parameters *parameters,
-                                       u64 *index_size);
-
-/* A session is required for most index operations. */
-int __must_check uds_create_index_session(struct uds_index_session **session);
-
-/* Destroying an index session also closes and saves the associated index. */
-int uds_destroy_index_session(struct uds_index_session *session);
-
-/*
- * Create or open an index with an existing session. This operation fails if the index session is
- * suspended, or if there is already an open index.
- */
-int __must_check uds_open_index(enum uds_open_index_type open_type,
-                               const struct uds_parameters *parameters,
-                               struct uds_index_session *session);
-
-/*
- * Wait until all callbacks for index operations are complete, and prevent new index operations
- * from starting. New index operations will fail with EBUSY until the session is resumed. Also
- * optionally saves the index.
- */
-int __must_check uds_suspend_index_session(struct uds_index_session *session, bool save);
-
-/*
- * Allow new index operations for an index, whether it was suspended or not. If the index is
- * suspended and the supplied block device differs from the current backing store, the index will
- * start using the new backing store instead.
- */
-int __must_check uds_resume_index_session(struct uds_index_session *session,
-                                         struct block_device *bdev);
-
-/* Wait until all outstanding index operations are complete. */
-int __must_check uds_flush_index_session(struct uds_index_session *session);
-
-/* Close an index. This operation fails if the index session is suspended. */
-int __must_check uds_close_index(struct uds_index_session *session);
-
-/* Get index statistics since the last time the index was opened. */
-int __must_check uds_get_index_session_stats(struct uds_index_session *session,
-                                            struct uds_index_stats *stats);
-
-/* This function will fail if any required field of the request is not set. */
-int __must_check uds_launch_request(struct uds_request *request);
-
-#endif /* UDS_H */
index 772317e6db52bd37d33514b5019641a59a6f30db..3938e519ae6a5747b4b052e226f529fb6cfd6a47 100644 (file)
 #include "admin-state.h"
 #include "encodings.h"
 #include "funnel-workqueue.h"
+#include "indexer.h"
 #include "packer.h"
 #include "physical-zone.h"
 #include "statistics.h"
 #include "thread-registry.h"
 #include "types.h"
-#include "uds.h"
 
 enum notifier_state {
        /* Notifications are allowed but not in progress */
index daeafe7691eaee50392857dd1f65266823a43f55..39c4be06780f6afaf4b875651e8e0ba37591c854 100644 (file)
 #include "errors.h"
 #include "geometry.h"
 #include "hash-utils.h"
+#include "indexer.h"
 #include "logger.h"
 #include "memory-alloc.h"
 #include "numeric.h"
 #include "permassert.h"
 #include "thread-utils.h"
-#include "uds.h"
 
 /*
  * The volume index is a combination of two separate subindexes, one containing sparse hook entries
index 2eb2cee7ee5884f2b3079b6965c178f14210daa7..66bf14fddc90642a3731e63f2604305e6d17243b 100644 (file)
@@ -10,8 +10,8 @@
 
 #include "config.h"
 #include "delta-index.h"
+#include "indexer.h"
 #include "thread-utils.h"
-#include "uds.h"
 
 /*
  * The volume index is the primary top-level index for UDS. It contains records which map a record
index 7ef9945d84031f59fd2289bd3825aa997250b536..290de5cbf9ec86a0d7af6ce9dfbe576ccf834026 100644 (file)
 #include "chapter-index.h"
 #include "config.h"
 #include "geometry.h"
+#include "indexer.h"
 #include "index-layout.h"
 #include "index-page-map.h"
 #include "permassert.h"
 #include "radix-sort.h"
 #include "sparse-cache.h"
 #include "thread-utils.h"
-#include "uds.h"
 
 /*
  * The volume manages deduplication records on permanent storage. The term "volume" can also refer