206 lines
5.8 KiB
Diff
206 lines
5.8 KiB
Diff
|
From 7955002f1292f0c0d02076440b441ab7ebaf650d Mon Sep 17 00:00:00 2001
|
||
|
From: Tao Liu <ltao@redhat.com>
|
||
|
Date: Tue, 10 Jan 2023 14:56:29 +0800
|
||
|
Subject: [PATCH 67/89] Add do_maple_tree() for maple tree operations
|
||
|
|
||
|
do_maple_tree() is similar to do_radix_tree() and do_xarray(), which
|
||
|
takes the same do_maple_tree_traverse entry as tree command.
|
||
|
|
||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||
|
---
|
||
|
defs.h | 6 +++
|
||
|
maple_tree.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
2 files changed, 151 insertions(+)
|
||
|
|
||
|
diff --git a/defs.h b/defs.h
|
||
|
index cc9af21a6b64..b2389cd82fae 100644
|
||
|
--- a/defs.h
|
||
|
+++ b/defs.h
|
||
|
@@ -5750,6 +5750,12 @@ int cleanup_memory_driver(void);
|
||
|
|
||
|
void maple_init(void);
|
||
|
int do_mptree(struct tree_data *);
|
||
|
+ulong do_maple_tree(ulong, int, struct list_pair *);
|
||
|
+#define MAPLE_TREE_COUNT (1)
|
||
|
+#define MAPLE_TREE_SEARCH (2)
|
||
|
+#define MAPLE_TREE_DUMP (3)
|
||
|
+#define MAPLE_TREE_GATHER (4)
|
||
|
+#define MAPLE_TREE_DUMP_CB (5)
|
||
|
|
||
|
/*
|
||
|
* help.c
|
||
|
diff --git a/maple_tree.c b/maple_tree.c
|
||
|
index 471136f3eb1d..807c17f7dfa0 100644
|
||
|
--- a/maple_tree.c
|
||
|
+++ b/maple_tree.c
|
||
|
@@ -40,6 +40,12 @@ static inline bool ma_is_leaf(const enum maple_type type)
|
||
|
|
||
|
/*************** For cmd_tree ********************/
|
||
|
|
||
|
+struct do_maple_tree_info {
|
||
|
+ ulong maxcount;
|
||
|
+ ulong count;
|
||
|
+ void *data;
|
||
|
+};
|
||
|
+
|
||
|
struct maple_tree_ops {
|
||
|
void (*entry)(ulong node, ulong slot, const char *path,
|
||
|
ulong index, void *private);
|
||
|
@@ -281,6 +287,9 @@ static void do_mt_entry(ulong entry, ulong min, ulong max, uint depth,
|
||
|
static struct req_entry **e = NULL;
|
||
|
struct tree_data *td = ops->is_td ? (struct tree_data *)ops->private : NULL;
|
||
|
|
||
|
+ if (ops->entry)
|
||
|
+ ops->entry(entry, entry, path, max, ops->private);
|
||
|
+
|
||
|
if (!td)
|
||
|
return;
|
||
|
|
||
|
@@ -424,6 +433,142 @@ int do_mptree(struct tree_data *td)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+/************* For do_maple_tree *****************/
|
||
|
+static void do_maple_tree_count(ulong node, ulong slot, const char *path,
|
||
|
+ ulong index, void *private)
|
||
|
+{
|
||
|
+ struct do_maple_tree_info *info = private;
|
||
|
+ info->count++;
|
||
|
+}
|
||
|
+
|
||
|
+static void do_maple_tree_search(ulong node, ulong slot, const char *path,
|
||
|
+ ulong index, void *private)
|
||
|
+{
|
||
|
+ struct do_maple_tree_info *info = private;
|
||
|
+ struct list_pair *lp = info->data;
|
||
|
+
|
||
|
+ if (lp->index == index) {
|
||
|
+ lp->value = (void *)slot;
|
||
|
+ info->count = 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void do_maple_tree_dump(ulong node, ulong slot, const char *path,
|
||
|
+ ulong index, void *private)
|
||
|
+{
|
||
|
+ struct do_maple_tree_info *info = private;
|
||
|
+ fprintf(fp, "[%lu] %lx\n", index, slot);
|
||
|
+ info->count++;
|
||
|
+}
|
||
|
+
|
||
|
+static void do_maple_tree_gather(ulong node, ulong slot, const char *path,
|
||
|
+ ulong index, void *private)
|
||
|
+{
|
||
|
+ struct do_maple_tree_info *info = private;
|
||
|
+ struct list_pair *lp = info->data;
|
||
|
+
|
||
|
+ if (info->maxcount) {
|
||
|
+ lp[info->count].index = index;
|
||
|
+ lp[info->count].value = (void *)slot;
|
||
|
+
|
||
|
+ info->count++;
|
||
|
+ info->maxcount--;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void do_maple_tree_dump_cb(ulong node, ulong slot, const char *path,
|
||
|
+ ulong index, void *private)
|
||
|
+{
|
||
|
+ struct do_maple_tree_info *info = private;
|
||
|
+ struct list_pair *lp = info->data;
|
||
|
+ int (*cb)(ulong) = lp->value;
|
||
|
+
|
||
|
+ /* Caller defined operation */
|
||
|
+ if (!cb(slot)) {
|
||
|
+ error(FATAL, "do_maple_tree: callback "
|
||
|
+ "operation failed: entry: %ld item: %lx\n",
|
||
|
+ info->count, slot);
|
||
|
+ }
|
||
|
+ info->count++;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * do_maple_tree argument usage:
|
||
|
+ *
|
||
|
+ * root: Address of a maple_tree_root structure
|
||
|
+ *
|
||
|
+ * flag: MAPLE_TREE_COUNT - Return the number of entries in the tree.
|
||
|
+ * MAPLE_TREE_SEARCH - Search for an entry at lp->index; if found,
|
||
|
+ * store the entry in lp->value and return a count of 1; otherwise
|
||
|
+ * return a count of 0.
|
||
|
+ * MAPLE_TREE_DUMP - Dump all existing index/value pairs.
|
||
|
+ * MAPLE_TREE_GATHER - Store all existing index/value pairs in the
|
||
|
+ * passed-in array of list_pair structs starting at lp,
|
||
|
+ * returning the count of entries stored; the caller can/should
|
||
|
+ * limit the number of returned entries by putting the array size
|
||
|
+ * (max count) in the lp->index field of the first structure
|
||
|
+ * in the passed-in array.
|
||
|
+ * MAPLE_TREE_DUMP_CB - Similar with MAPLE_TREE_DUMP, but for each
|
||
|
+ * maple tree entry, a user defined callback at lp->value will
|
||
|
+ * be invoked.
|
||
|
+ *
|
||
|
+ * lp: Unused by MAPLE_TREE_COUNT and MAPLE_TREE_DUMP.
|
||
|
+ * A pointer to a list_pair structure for MAPLE_TREE_SEARCH.
|
||
|
+ * A pointer to an array of list_pair structures for
|
||
|
+ * MAPLE_TREE_GATHER; the dimension (max count) of the array may
|
||
|
+ * be stored in the index field of the first structure to avoid
|
||
|
+ * any chance of an overrun.
|
||
|
+ * For MAPLE_TREE_DUMP_CB, the lp->value must be initialized as a
|
||
|
+ * callback function. The callback prototype must be: int (*)(ulong);
|
||
|
+ */
|
||
|
+ulong
|
||
|
+do_maple_tree(ulong root, int flag, struct list_pair *lp)
|
||
|
+{
|
||
|
+ struct do_maple_tree_info info = {
|
||
|
+ .count = 0,
|
||
|
+ .data = lp,
|
||
|
+ };
|
||
|
+ struct maple_tree_ops ops = {
|
||
|
+ .private = &info,
|
||
|
+ .is_td = false,
|
||
|
+ };
|
||
|
+
|
||
|
+ switch (flag)
|
||
|
+ {
|
||
|
+ case MAPLE_TREE_COUNT:
|
||
|
+ ops.entry = do_maple_tree_count;
|
||
|
+ break;
|
||
|
+
|
||
|
+ case MAPLE_TREE_SEARCH:
|
||
|
+ ops.entry = do_maple_tree_search;
|
||
|
+ break;
|
||
|
+
|
||
|
+ case MAPLE_TREE_DUMP:
|
||
|
+ ops.entry = do_maple_tree_dump;
|
||
|
+ break;
|
||
|
+
|
||
|
+ case MAPLE_TREE_GATHER:
|
||
|
+ if (!(info.maxcount = lp->index))
|
||
|
+ info.maxcount = (ulong)(-1); /* caller beware */
|
||
|
+
|
||
|
+ ops.entry = do_maple_tree_gather;
|
||
|
+ break;
|
||
|
+
|
||
|
+ case MAPLE_TREE_DUMP_CB:
|
||
|
+ if (lp->value == NULL) {
|
||
|
+ error(FATAL, "do_maple_tree: need set callback function");
|
||
|
+ }
|
||
|
+ ops.entry = do_maple_tree_dump_cb;
|
||
|
+ break;
|
||
|
+
|
||
|
+ default:
|
||
|
+ error(FATAL, "do_maple_tree: invalid flag: %lx\n", flag);
|
||
|
+ }
|
||
|
+
|
||
|
+ do_maple_tree_traverse(root, true, &ops);
|
||
|
+ return info.count;
|
||
|
+}
|
||
|
+
|
||
|
/***********************************************/
|
||
|
void maple_init(void)
|
||
|
{
|
||
|
--
|
||
|
2.37.1
|
||
|
|