[Suspend2][ 4/9] [Suspend2] Add extent to extent chain.

Nigel Cunningham
2006-06-26T16:56:44Z

Add a new extent, possibly merging it with existing extents.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

kernel/power/extent.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/kernel/power/extent.c b/kernel/power/extent.c
index ab19509..31fcb65 100644
--- a/kernel/power/extent.c
+++ b/kernel/power/extent.c
@@ -70,3 +70,74 @@ void suspend_put_extent_chain(struct ext
chain->size = chain->allocs = chain->frees = 0;
}

+/*
+ * suspend_add_to_extent_chain
+ *
+ * Add an extent to an existing chain.
+ */
+int suspend_add_to_extent_chain(struct extent_chain *chain,
+ unsigned long minimum, unsigned long maximum)
+{
+ struct extent *new_extent = NULL, *start_at;
+
+ /* Find the right place in the chain */
+ start_at = (chain->last_touched &&
+ (chain->last_touched->minimum < minimum)) ?
+ chain->last_touched : NULL;
+
+ if (!start_at && chain->first && chain->first->minimum < minimum)
+ start_at = chain->first;
+
+ while (start_at && start_at->next && start_at->next->minimum < minimum)
+ start_at = start_at->next;
+
+ if (start_at && start_at->maximum == (minimum - 1)) {
+ start_at->maximum = maximum;
+
+ /* Merge with the following one? */
+ if (start_at->next &&
+ start_at->maximum + 1 == start_at->next->minimum) {
+ struct extent *to_free = start_at->next;
+ start_at->maximum = start_at->next->maximum;
+ start_at->next = start_at->next->next;
+ chain->frees++;
+ suspend_put_extent(to_free);
+ }
+
+ chain->last_touched = start_at;
+ chain->size+= (maximum - minimum + 1);
+
+ return 0;
+ }
+
+ new_extent = suspend_get_extent();
+ if (!new_extent) {
+ printk("Error unable to append a new extent to the chain.\n");
+ return 2;
+ }
+
+ chain->allocs++;
+ chain->size+= (maximum - minimum + 1);
+ new_extent->minimum = minimum;
+ new_extent->maximum = maximum;
+ new_extent->next = NULL;
+
+ chain->last_touched = new_extent;
+
+ if (start_at) {
+ struct extent *next = start_at->next;
+ start_at->next = new_extent;
+ new_extent->next = next;
+ if (!next)
+ chain->last = new_extent;
+ } else {
+ if (chain->first) {
+ new_extent->next = chain->first;
+ chain->first = new_extent;
+ } else
+ chain->last = chain->first = new_extent;
+ }
+
+ return 0;
+}
+

--
Nigel Cunningham nigel at suspend2 dot net