lkml.org 
[lkml]   [2005]   [Jul]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH] [33/48] Suspend2 2.1.9.8 for 2.6.12: 610-encryption.patch
    Date
    From
    diff -ruNp 610-extent.patch-old/kernel/power/suspend2_core/extent.c 610-extent.patch-new/kernel/power/suspend2_core/extent.c
    --- 610-extent.patch-old/kernel/power/suspend2_core/extent.c 1970-01-01 10:00:00.000000000 +1000
    +++ 610-extent.patch-new/kernel/power/suspend2_core/extent.c 2005-07-04 23:14:19.000000000 +1000
    @@ -0,0 +1,206 @@
    +/*
    + * kernel/power/suspend2_core/extent.c
    + *
    + * Suspend2 routines for manipulating extents.
    + *
    + * (C) 2003-2005 Nigel Cunningham <nigel@suspend2.net>
    + *
    + * Distributed under GPLv2.
    + *
    + * These functions encapsulate the manipulation of extents.
    + * They work like this:
    + *
    + * A lot of the data that suspend saves involves continguous extents of memory
    + * or storage. Let's say that we're storing data on disk in blocks 1-32768 and
    + * 49152-49848 of a swap partition. Rather than recording 1, 2, 3... in arrays
    + * pointing to the locations, we simply use:
    + *
    + * struct extent {
    + * unsigned long min;
    + * unsigned long max;
    + * struct extent * next;
    + * }
    + *
    + * We can then store 1-32768 and 49152-49848 in 2 struct extents, using 24 bytes
    + * instead of something like 133,860. This is of course inefficient where a extent
    + * covers only one or two values, but the benefits gained by the much larger
    + * extents more than outweigh these instances.
    + *
    + * When _all_ the metadata was stored in extents, we used to have fancier code that
    + * stored them in pages and was optimised for our usage. Nowadays they are only
    + * used for storage information. We therefore kmalloc them as required, and
    + * provide a far simpler routine to serialise them in the image header.
    + */
    +
    +#include <linux/module.h>
    +#include <linux/suspend.h>
    +#include "plugins.h"
    +#include "extent.h"
    +#include "ui.h"
    +
    +int extents_allocated = 0, max_extents_used = 0;
    +
    +/* get_extent
    + *
    + * Returns a free extent.
    + * May fail, returning NULL instead.
    + */
    +
    +static struct extent * get_extent(void)
    +{
    + struct extent * result;
    +
    + if (!(result = kmalloc(sizeof(struct extent), GFP_ATOMIC)))
    + return NULL;
    +
    + extents_allocated++;
    + if (extents_allocated > max_extents_used)
    + max_extents_used++;
    + result->minimum = result->maximum = 0;
    + result->next = NULL;
    + return result;
    +}
    +
    +/*
    + * put_extent.
    + *
    + * Frees an extent.
    + *
    + * Assumes unlinking is done by the caller.
    + */
    +void put_extent(struct extent * extent)
    +{
    + if (!extent) {
    + printk("Error! put_extent called with NULL extent.\n");
    + return;
    + }
    + kfree(extent);
    + extents_allocated--;
    +}
    +
    +/*
    + * put_extent_chain.
    + *
    + * Frees a whole chain of extents.
    + */
    +void put_extent_chain(struct extentchain * chain)
    +{
    + struct extent * this;
    +
    + this = chain->first;
    +
    + if (!this)
    + return;
    +
    + while(this) {
    + struct extent * next = this->next;
    + kfree(this);
    + chain->frees++;
    + extents_allocated --;
    + this = next;
    + }
    +
    + BUG_ON(chain->frees != chain->allocs);
    + chain->first = chain->last = NULL;
    + chain->size = chain->allocs = chain->frees = 0;
    +}
    +
    +/*
    + * append_extent_to_extent_chain
    + *
    + * Used where we know a extent is to be added to the end of the list
    + * and does not need merging with the current last extent.
    + */
    +
    +int append_extent_to_extent_chain(struct extentchain * chain,
    + unsigned long minimum, unsigned long maximum)
    +{
    + struct extent * newextent = NULL;
    +
    + newextent = get_extent();
    + if (!newextent) {
    + printk("Error unable to append a new extent to the chain.\n");
    + return 2;
    + }
    +
    + chain->allocs++;
    + chain->size+= (maximum - minimum + 1);
    + newextent->minimum = minimum;
    + newextent->maximum = maximum;
    + newextent->next = NULL;
    +
    + if (chain->last) {
    + chain->last->next = newextent;
    + chain->last = newextent;
    + } else
    + chain->last = chain->first = newextent;
    +
    + /* No need to reset optimisation info since added to end */
    + return 0;
    +}
    +
    +/*
    + * serialise_extent_chain
    + *
    + * Write a chain in the image.
    + */
    +int serialise_extent_chain(struct extentchain * chain)
    +{
    + struct extent * this;
    + int ret, i = 1;
    +
    + if ((ret = active_writer->ops.writer.write_header_chunk((char *) chain,
    + sizeof(struct extentchain) - 2 * sizeof(struct extent *)))) {
    + printk("Write header chunk returned %d - aborting serialising chain.\n",
    + ret);
    + return ret;
    + }
    +
    + this = chain->first;
    + while (this) {
    + if ((ret = active_writer->ops.writer.write_header_chunk((char *) this,
    + 2 * sizeof(unsigned long)))) {
    + printk("Failed to write extent.\n");
    + return ret;
    + }
    + this = this->next;
    + i++;
    + }
    + return ret;
    +}
    +
    +/*
    + * load_extent_chain
    + *
    + * Read back a chain saved in the image.
    + */
    +int load_extent_chain(struct extentchain * chain)
    +{
    + struct extent * this, * last = NULL;
    + int i, ret;
    +
    + if (!(ret = active_writer->ops.writer.read_header_chunk((char *) chain,
    + sizeof(struct extentchain) - 2 * sizeof(struct extent *)))) {
    + printk("Read header chunk returned %d - aborting serialising chain.\n",
    + ret);
    + return ret;
    + }
    +
    + for (i = 0; i < (chain->allocs - chain->frees); i++) {
    + this = kmalloc(sizeof(struct extent), GFP_ATOMIC);
    + BUG_ON(!this); /* Shouldn't run out of memory trying this! */
    + this->next = NULL;
    + if (!(ret = active_writer->ops.writer.read_header_chunk((char *) this,
    + 2 * sizeof(unsigned long)))) {
    + printk("Failed to read extent.\n");
    + return ret;
    + }
    + if (last)
    + last->next = this;
    + else
    + chain->first = this;
    + last = this;
    + }
    + chain->last = last;
    + return ret;
    +}
    diff -ruNp 610-extent.patch-old/kernel/power/suspend2_core/extent.h 610-extent.patch-new/kernel/power/suspend2_core/extent.h
    --- 610-extent.patch-old/kernel/power/suspend2_core/extent.h 1970-01-01 10:00:00.000000000 +1000
    +++ 610-extent.patch-new/kernel/power/suspend2_core/extent.h 2005-07-05 23:48:59.000000000 +1000
    @@ -0,0 +1,84 @@
    +/*
    + * kernel/power/extent.h
    + *
    + * Copyright (C) 2004-2005 Nigel Cunningham <nigel@suspend2.net>
    + *
    + * This file is released under the GPLv2.
    + *
    + * It contains declarations related to extents. Extents are
    + * suspend's method of storing some of the metadata for the image.
    + * See extent.c for more info.
    + *
    + */
    +
    +#ifndef EXTENT_H
    +#define EXTENT_H
    +struct extentchain {
    + int size; /* size of the extent ie sum (max-min+1) */
    + int allocs;
    + int frees;
    + int debug;
    + int timesusedoptimisation;
    + char * name;
    + struct extent * first;
    + struct extent * last;
    +};
    +
    +/*
    + * We rely on extents not fitting evenly into a page.
    + * The last four bytes are used to store the number
    + * of the page, to make saving & reloading pages simpler.
    + */
    +struct extent {
    + unsigned long minimum;
    + unsigned long maximum;
    + struct extent * next;
    +};
    +
    +
    +#define extent_for_each(extentchain, extentpointer, value) \
    +if ((extentchain)->first) \
    + for ((extentpointer) = (extentchain)->first, (value) = \
    + (extentpointer)->minimum; \
    + ((extentpointer) && ((extentpointer)->next || (value) <= \
    + (extentpointer)->maximum)); \
    + (((value) == (extentpointer)->maximum) ? \
    + ((extentpointer) = (extentpointer)->next, (value) = \
    + ((extentpointer) ? (extentpointer)->minimum : 0)) : \
    + (value)++))
    +
    +/*
    + * When using compression and expected_compression > 0,
    + * we allocate fewer swap entries, so GET_EXTENT_NEXT can
    + * validly run out of data to return.
    + */
    +#define GET_EXTENT_NEXT(currentextent, currentval) \
    +{ \
    + if (currentextent) { \
    + if ((currentval) == (currentextent)->maximum) { \
    + if ((currentextent)->next) { \
    + (currentextent) = (currentextent)->next; \
    + (currentval) = (currentextent)->minimum; \
    + } else { \
    + (currentextent) = NULL; \
    + (currentval) = 0; \
    + } \
    + } else \
    + currentval++; \
    + } \
    +}
    +
    +extern int max_extents_used, extents_allocated;
    +void put_extent(struct extent * extent);
    +void put_extent_chain(struct extentchain * chain);
    +int append_extent_to_extent_chain(struct extentchain * chain,
    + unsigned long minimum, unsigned long maximum);
    +int serialise_extent_chain(struct extentchain * chain);
    +int load_extent_chain(struct extentchain * chain);
    +
    +/* swap_entry_to_extent_val & extent_val_to_swap_entry:
    + * We are putting offset in the low bits so consecutive swap entries
    + * make consecutive extent values */
    +#define swap_entry_to_extent_val(swp_entry) (swp_entry.val)
    +#define extent_val_to_swap_entry(val) (swp_entry_t) { (val) }
    +#endif
    -
    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/

    \
     
     \ /
      Last update: 2005-07-06 05:53    [W:0.033 / U:2.048 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site