Messages in this thread Patch in this message | | | From | Nigel Cunningham <> | Subject | [Suspend2][ 4/9] [Suspend2] Add extent to extent chain. | Date | Tue, 27 Jun 2006 02:54:18 +1000 |
| |
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 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |