]> git.pld-linux.org Git - packages/kernel.git/commitdiff
- update patches for 2.6.32; they apply when using --without grsecurity
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Fri, 4 Dec 2009 19:21:52 +0000 (19:21 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    kernel-hostap.patch -> 1.3
    kernel-imq.patch -> 1.5
    kernel-owner-xid.patch -> 1.4
    kernel-reiser4.patch -> 1.7
    kernel-small_fixes.patch -> 1.7
    kernel-tuxonice.patch -> 1.9
    kernel-vserver-2.3.patch -> 1.26
    kernel-warnings.patch -> 1.4
    kernel-wrr.patch -> 1.7
    kernel-xfs-recover-quota.patch -> 1.2
    kernel.spec -> 1.729

kernel-hostap.patch
kernel-imq.patch
kernel-owner-xid.patch
kernel-reiser4.patch
kernel-small_fixes.patch
kernel-tuxonice.patch
kernel-vserver-2.3.patch
kernel-warnings.patch
kernel-wrr.patch
kernel-xfs-recover-quota.patch [deleted file]
kernel.spec

index e1447fc1a0f9b896d1e5dcdf7a68fed921b4b1a8..1afcbf2184d4314a7861836a2ecf1f51965f082d 100644 (file)
@@ -19,17 +19,6 @@ diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_80211_tx.c linux
        iface->stats.tx_packets++;
        iface->stats.tx_bytes += skb->len;
  
-@@ -404,8 +408,6 @@
-       }
-       if (skb->len < 24) {
--              printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
--                     "(len=%d)\n", dev->name, skb->len);
-               ret = 0;
-               iface->stats.tx_dropped++;
-               goto fail;
-Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_cs.c.orig
-Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_cs.c.rej
 diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_hw.c linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_hw.c
 --- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_hw.c        2006-09-21 01:26:27.000000000 -0400
 +++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_hw.c  2006-09-21 01:30:18.000000000 -0400
index 2bc3b8293abf709370304cb8ef9b5309a8bc510b..c8a1a46f0a63d664b2181d2681c9e4b3f64edd5e 100644 (file)
@@ -822,7 +822,7 @@ diff -uNr --exclude='*~' linux-2.6.29.1/include/linux/skbuff.h linux-2.6.29.1-im
 @@ -332,6 +341,9 @@
        __u8                    requeue:1;
  #endif
-       /* 0/13/14 bit hole */
+       /* 0/14 bit hole */
 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
 +      __u8                    imq_flags:IMQ_F_BITS;
 +#endif
index 047497034bb086ffc2c9eb126bb61095bb72a70f..0030bbbb60e0fc799234909e3706c40a328deb77 100644 (file)
@@ -18,101 +18,9 @@ diff -upr linux-2.6.25/include/linux/netfilter/xt_owner.h linux-2.6.25-owner-xid
  };
  
  #endif /* _XT_OWNER_MATCH_H */
-Only in linux-2.6.25-owner-xid/include/linux/netfilter: xt_owner.h~
-diff -upr linux-2.6.25/include/linux/netfilter_ipv4/ipt_owner.h linux-2.6.25-owner-xid/include/linux/netfilter_ipv4/ipt_owner.h
---- linux-2.6.25/include/linux/netfilter_ipv4/ipt_owner.h      2008-05-20 17:15:02.411418369 +0000
-+++ linux-2.6.25-owner-xid/include/linux/netfilter_ipv4/ipt_owner.h    2008-05-20 17:16:22.905886167 +0000
-@@ -1,12 +1,16 @@
- #ifndef _IPT_OWNER_H
- #define _IPT_OWNER_H
-+#include <linux/types.h>
-+
- /* match and invert flags */
- #define IPT_OWNER_UID 0x01
- #define IPT_OWNER_GID 0x02
- #define IPT_OWNER_PID 0x04
- #define IPT_OWNER_SID 0x08
- #define IPT_OWNER_COMM        0x10
-+#define IPT_OWNER_NID 0x20
-+#define IPT_OWNER_XID 0x40
- struct ipt_owner_info {
-     uid_t uid;
-@@ -15,6 +19,8 @@ struct ipt_owner_info {
-     pid_t sid;
-     char comm[16];
-     u_int8_t match, invert;   /* flags */
-+    u_int32_t nid;
-+    u_int32_t xid;
- };
- #endif /*_IPT_OWNER_H*/
-diff -upr linux-2.6.25/include/linux/netfilter_ipv6/ip6t_owner.h linux-2.6.25-owner-xid/include/linux/netfilter_ipv6/ip6t_owner.h
---- linux-2.6.25/include/linux/netfilter_ipv6/ip6t_owner.h     2008-05-20 17:15:02.411418369 +0000
-+++ linux-2.6.25-owner-xid/include/linux/netfilter_ipv6/ip6t_owner.h   2008-05-20 17:16:22.905886167 +0000
-@@ -1,11 +1,15 @@
- #ifndef _IP6T_OWNER_H
- #define _IP6T_OWNER_H
-+#include <linux/types.h>
-+
- /* match and invert flags */
- #define IP6T_OWNER_UID        0x01
- #define IP6T_OWNER_GID        0x02
- #define IP6T_OWNER_PID        0x04
- #define IP6T_OWNER_SID        0x08
-+#define IP6T_OWNER_NID        0x20
-+#define IP6T_OWNER_XID        0x40
- struct ip6t_owner_info {
-     uid_t uid;
-@@ -13,6 +17,8 @@ struct ip6t_owner_info {
-     pid_t pid;
-     pid_t sid;
-     u_int8_t match, invert;   /* flags */
-+    u_int32_t nid;
-+    u_int32_t xid;
- };
- #endif /*_IPT_OWNER_H*/
 diff -upr linux-2.6.25/net/netfilter/xt_owner.c linux-2.6.25-owner-xid/net/netfilter/xt_owner.c
 --- linux-2.6.25/net/netfilter/xt_owner.c      2008-05-20 17:15:02.411418369 +0000
 +++ linux-2.6.25-owner-xid/net/netfilter/xt_owner.c    2008-05-20 17:48:15.774419069 +0000
-@@ -46,6 +46,16 @@ owner_mt_v0(const struct sk_buff *skb, c
-                   !!(info->invert & IPT_OWNER_GID))
-                       return false;
-+      if (info->match & IPT_OWNER_NID)
-+              if ((skb->sk->sk_nid != info->nid) ^
-+                  !!(info->invert & IPT_OWNER_NID))
-+                      return 0;
-+
-+      if (info->match & IPT_OWNER_XID)
-+              if ((skb->sk->sk_xid != info->xid) ^
-+                  !!(info->invert & IPT_OWNER_XID))
-+                      return 0;
-+
-       return true;
- }
-@@ -75,6 +85,16 @@ owner_mt6_v0(const struct sk_buff *skb, 
-                   !!(info->invert & IP6T_OWNER_GID))
-                       return false;
-+      if (info->match & IP6T_OWNER_NID)
-+              if ((skb->sk->sk_nid != info->nid) ^
-+                  !!(info->invert & IP6T_OWNER_NID))
-+                      return 0;
-+
-+      if (info->match & IP6T_OWNER_XID)
-+              if ((skb->sk->sk_xid != info->xid) ^
-+                  !!(info->invert & IP6T_OWNER_XID))
-+                      return 0;
-+
-       return true;
- }
 @@ -113,6 +133,16 @@ owner_mt(const struct sk_buff *skb, cons
                    !(info->invert & XT_OWNER_GID))
                        return false;
@@ -130,4 +38,3 @@ diff -upr linux-2.6.25/net/netfilter/xt_owner.c linux-2.6.25-owner-xid/net/netfi
        return true;
  }
  
-Only in linux-2.6.25-owner-xid/net/netfilter: xt_owner.c~
index fd76bddbddec7c460d1fe0c2224aee672fa86e7c..6a31448650f01c1522763fa6b5e597d16fe809cd 100644 (file)
@@ -113,21 +113,6 @@ diff -urN linux-2.6.28.orig/Documentation/filesystems/reiser4.txt linux-2.6.28/D
 +dont_load_bitmap
 +      Don't load all bitmap blocks at mount time, it is useful for
 +      machines with tiny RAM and large disks.
-diff -urN linux-2.6.28.orig/fs/fs-writeback.c linux-2.6.28/fs/fs-writeback.c
---- linux-2.6.28.orig/fs/fs-writeback.c        2008-12-26 14:35:40.000000000 +0300
-+++ linux-2.6.28/fs/fs-writeback.c     2008-12-26 15:03:53.000000000 +0300
-@@ -531,7 +531,10 @@
- static void sync_sb_inodes(struct super_block *sb,
-                               struct writeback_control *wbc)
- {
--      generic_sync_sb_inodes(sb, wbc);
-+       if (sb->s_op->sync_inodes)
-+               sb->s_op->sync_inodes(sb, wbc);
-+       else
-+               generic_sync_sb_inodes(sb, wbc);
- }
- /*
 diff -urN linux-2.6.28.orig/fs/Kconfig linux-2.6.28/fs/Kconfig
 --- linux-2.6.28.orig/fs/Kconfig       2008-12-26 14:35:40.000000000 +0300
 +++ linux-2.6.28/fs/Kconfig    2008-12-26 15:03:53.000000000 +0300
index 5742932eda799dc9ba8ac5abdac50369268f2e6a..ca6ce13c5963272236f42807d9423ba12360539a 100644 (file)
  /* Enforce in-order execution of data I/O.
   * No distinction between read/write on PPC; use eieio for all three.
   */
---- linux-2.6.20/drivers/media/common/ir-keymaps.c.orig        2007-02-04 19:44:54.000000000 +0100
-+++ linux-2.6.20/drivers/media/common/ir-keymaps.c     2007-02-17 22:22:39.327414970 +0100
-@@ -151,10 +151,6 @@
- IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
--      [ 0x1e ] = KEY_POWER,       // power
--      [ 0x07 ] = KEY_MEDIA,       // source
--      [ 0x1c ] = KEY_SEARCH,      // scan
--
- /* FIXME: duplicate keycodes?
-  *
-  * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
-@@ -175,14 +171,10 @@
-  */
-       [ 0x03 ] = KEY_TUNER,       // TV/FM
-+      [ 0x07 ] = KEY_SEARCH,      // scan
-+      [ 0x1c ] = KEY_ZOOM,        // zoom
--      [ 0x00 ] = KEY_RECORD,
--      [ 0x08 ] = KEY_STOP,
--      [ 0x11 ] = KEY_PLAY,
--
--      [ 0x1a ] = KEY_PLAYPAUSE,   // freeze
--      [ 0x19 ] = KEY_ZOOM,        // zoom
--      [ 0x0f ] = KEY_TEXT,        // min
-+      [ 0x1e ] = KEY_POWER,       // power
-       [ 0x01 ] = KEY_1,
-       [ 0x0b ] = KEY_2,
-@@ -195,20 +187,22 @@
-       [ 0x12 ] = KEY_9,
-       [ 0x02 ] = KEY_0,
-       [ 0x10 ] = KEY_LAST,        // +100
--      [ 0x13 ] = KEY_LIST,        // recall
-+      [ 0x13 ] = KEY_LIST,        // loop
--      [ 0x1f ] = KEY_CHANNELUP,   // chn down
--      [ 0x17 ] = KEY_CHANNELDOWN, // chn up
--      [ 0x16 ] = KEY_VOLUMEUP,    // vol down
--      [ 0x14 ] = KEY_VOLUMEDOWN,  // vol up
-+      [ 0x1f ] = KEY_VOLUMEUP,    // vol down
-+      [ 0x17 ] = KEY_VOLUMEDOWN,  // vol up
-+      [ 0x16 ] = KEY_CHANNELUP,   // chn down
-+      [ 0x14 ] = KEY_CHANNELDOWN, // chn up
--      [ 0x04 ] = KEY_KPMINUS,     // <<<
-+      [ 0x00 ] = KEY_MEDIA,       // source
-+      [ 0x18 ] = KEY_MUTE,        // mute/unmute
-+
-+      [ 0x04 ] = KEY_KPMINUS,     // -
-       [ 0x0e ] = KEY_SETUP,       // function
--      [ 0x0c ] = KEY_KPPLUS,      // >>>
-+      [ 0x0c ] = KEY_KPPLUS,      // +
--      [ 0x0d ] = KEY_GOTO,        // mts
--      [ 0x1d ] = KEY_REFRESH,     // reset
--      [ 0x18 ] = KEY_MUTE         // mute/unmute
-+      [ 0x0d ] = KEY_REFRESH,     // reset
-+      [ 0x0f ] = KEY_PLAYPAUSE    // freeze
- };
- EXPORT_SYMBOL_GPL(ir_codes_pixelview);
 --- linux-2.6.27/arch/powerpc/include/asm/suspend.h    2007-07-09 01:32:17.000000000 +0200
 +++ linux-2.6.27/arch/powerpc/include/asm/suspend.h    2007-08-28 23:26:16.629658848 +0200
 @@ -6,4 +6,7 @@
  
  void restore_processor_state(void)
  {
---- linux-2.6.31/scripts/Makefile.lib~ 2009-09-15 23:40:30.552124999 +0200
-+++ linux-2.6.31/scripts/Makefile.lib  2009-09-15 23:46:05.155641644 +0200
-@@ -208,7 +208,7 @@
- # Bzip2 and LZMA do not include size in file... so we have to fake that;
- # append the size as a 32-bit littleendian number as gzip does.
--size_append = echo -ne $(shell                                                \
-+size_append = /bin/echo -ne $(shell                                           \
- dec_size=0;                                                           \
- for F in $1; do                                                               \
-       fsize=$$(stat -c "%s" $$F);                                     \
+
index 12c36ed1364fd15c6ad886d72fc2ee6624f85f4e..a98ec81b8220c04b3e4d6567d65a67ec9ee7a4fd 100644 (file)
@@ -1436,10 +1436,10 @@ index 0000000..3bf0575
 +   testing. His efforts have contributed as much to TuxOnIce as any of the
 +   names above.
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 8dca9d8..14c7e10 100644
+index 4f96ac8..21b92f2 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -5038,6 +5038,13 @@ S:      Maintained
+@@ -5259,6 +5259,13 @@ S:      Maintained
  F:    drivers/tc/
  F:    include/linux/tc.h
  
@@ -1454,7 +1454,7 @@ index 8dca9d8..14c7e10 100644
  M:    Dario Ballabio <ballabio_dario@emc.com>
  L:    linux-scsi@vger.kernel.org
 diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
-index 5422169..33be4fa 100644
+index cb96cb2..2be8da2 100644
 --- a/arch/powerpc/mm/pgtable_32.c
 +++ b/arch/powerpc/mm/pgtable_32.c
 @@ -396,6 +396,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
@@ -1466,10 +1466,10 @@ index 5422169..33be4fa 100644
  
  static int fixmaps;
 diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
-index a06e8d1..9a1fe4b 100644
+index f930787..869133f 100644
 --- a/arch/x86/kernel/reboot.c
 +++ b/arch/x86/kernel/reboot.c
-@@ -677,6 +677,7 @@ void machine_restart(char *cmd)
+@@ -693,6 +693,7 @@ void machine_restart(char *cmd)
  {
        machine_ops.restart(cmd);
  }
@@ -1478,10 +1478,10 @@ index a06e8d1..9a1fe4b 100644
  void machine_halt(void)
  {
 diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
-index 7e600c1..418725a 100644
+index dd38bfb..26b3bbf 100644
 --- a/arch/x86/mm/pageattr.c
 +++ b/arch/x86/mm/pageattr.c
-@@ -1284,6 +1284,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
+@@ -1274,6 +1274,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
         */
        __flush_tlb_all();
  }
@@ -1489,7 +1489,7 @@ index 7e600c1..418725a 100644
  
  #ifdef CONFIG_HIBERNATION
  
-@@ -1298,7 +1299,7 @@ bool kernel_page_present(struct page *page)
+@@ -1288,7 +1289,7 @@ bool kernel_page_present(struct page *page)
        pte = lookup_address((unsigned long)page_address(page), &level);
        return (pte_val(*pte) & _PAGE_PRESENT);
  }
@@ -1499,7 +1499,7 @@ index 7e600c1..418725a 100644
  
  #endif /* CONFIG_DEBUG_PAGEALLOC */
 diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
-index b3d20b9..cb13f39 100644
+index 8aa85f1..b22c157 100644
 --- a/arch/x86/power/cpu.c
 +++ b/arch/x86/power/cpu.c
 @@ -111,9 +111,7 @@ void save_processor_state(void)
@@ -1557,28 +1557,481 @@ index 65fdc86..e5c31f6 100644
        return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL;
  }
 +EXPORT_SYMBOL_GPL(arch_hibernation_header_restore);
+diff --git a/block/Makefile b/block/Makefile
+index ba74ca6..aa30a88 100644
+--- a/block/Makefile
++++ b/block/Makefile
+@@ -5,7 +5,7 @@
+ obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
+                       blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \
+                       blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
+-                      blk-iopoll.o ioctl.o genhd.o scsi_ioctl.o
++                      blk-iopoll.o ioctl.o genhd.o scsi_ioctl.o uuid.o
+ obj-$(CONFIG_BLK_DEV_BSG)     += bsg.o
+ obj-$(CONFIG_IOSCHED_NOOP)    += noop-iosched.o
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 71da511..e338e9d 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -37,6 +37,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap);
+ EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
+ EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
++int trap_non_toi_io;
++EXPORT_SYMBOL_GPL(trap_non_toi_io);
++
+ static int __make_request(struct request_queue *q, struct bio *bio);
+ /*
+@@ -1555,6 +1558,9 @@ void submit_bio(int rw, struct bio *bio)
+       bio->bi_rw |= rw;
++      if (unlikely(trap_non_toi_io))
++              BUG_ON(!bio_rw_flagged(bio, BIO_RW_TUXONICE));
++
+       /*
+        * If it's a regular read/write or a barrier with data attached,
+        * go through the normal accounting stuff before submission.
+diff --git a/block/genhd.c b/block/genhd.c
+index 517e433..9a5fa6f 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -18,6 +18,8 @@
+ #include <linux/buffer_head.h>
+ #include <linux/mutex.h>
+ #include <linux/idr.h>
++#include <linux/ctype.h>
++#include <linux/uuid.h>
+ #include "blk.h"
+@@ -1274,3 +1276,30 @@ int invalidate_partition(struct gendisk *disk, int partno)
+ }
+ EXPORT_SYMBOL(invalidate_partition);
++
++dev_t blk_lookup_uuid(const char *uuid)
++{
++      dev_t devt = MKDEV(0, 0);
++      struct class_dev_iter iter;
++      struct device *dev;
++
++      class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
++      while (!devt && (dev = class_dev_iter_next(&iter))) {
++              struct gendisk *disk = dev_to_disk(dev);
++              struct disk_part_iter piter;
++              struct hd_struct *part;
++
++              disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
++
++              while ((part = disk_part_iter_next(&piter))) {
++                      if (part_matches_uuid(part, uuid)) {
++                              devt = part_devt(part);
++                              break;
++                      }
++              }
++              disk_part_iter_exit(&piter);
++      }
++      class_dev_iter_exit(&iter);
++      return devt;
++}
++EXPORT_SYMBOL_GPL(blk_lookup_uuid);
+diff --git a/block/uuid.c b/block/uuid.c
+new file mode 100644
+index 0000000..fefc3ed
+--- /dev/null
++++ b/block/uuid.c
+@@ -0,0 +1,366 @@
++#include <linux/blkdev.h>
++#include <linux/ctype.h>
++
++#if 0
++#define PRINTK(fmt, args...) printk(KERN_DEBUG fmt, ## args)
++#define PRINT_HEX_DUMP(v1, v2, v3, v4, v5, v6, v7, v8) \
++      print_hex_dump(v1, v2, v3, v4, v5, v6, v7, v8)
++#else
++#define PRINTK(fmt, args...)
++#define PRINT_HEX_DUMP(v1, v2, v3, v4, v5, v6, v7, v8)
++#endif
++
++/*
++ * Simple UUID translation
++ */
++
++struct uuid_info {
++      const char *name;
++      long bkoff;
++      unsigned sboff;
++      unsigned sig_len;
++      const char *magic;
++      int uuid_offset;
++};
++
++/*
++ * Based on libuuid's blkid_magic array. Note that I don't
++ * have uuid offsets for all of these yet - mssing ones are 0x0.
++ * Further information welcome.
++ *
++ * Rearranged by sector of fs signature for optimisation.
++ */
++static struct uuid_info uuid_list[] = {
++  { "oracleasm", 0,   32,  8, "ORCLDISK",             0x0 },
++  { "ntfs",    0,      3,  8, "NTFS    ",             0x0 },
++  { "vfat",      0,   0x52,  5, "MSWIN",                0x0 },
++  { "vfat",      0,   0x52,  8, "FAT32   ",             0x0 },
++  { "vfat",      0,   0x36,  5, "MSDOS",                0x0 },
++  { "vfat",      0,   0x36,  8, "FAT16   ",             0x0 },
++  { "vfat",      0,   0x36,  8, "FAT12   ",             0x0 },
++  { "vfat",      0,      0,  1, "\353",                 0x0 },
++  { "vfat",      0,      0,  1, "\351",                 0x0 },
++  { "vfat",      0,  0x1fe,  2, "\125\252",             0x0 },
++  { "xfs",     0,      0,  4, "XFSB",                 0x14 },
++  { "romfs",   0,      0,  8, "-rom1fs-",             0x0 },
++  { "bfs",     0,      0,  4, "\316\372\173\033",     0 },
++  { "cramfs",  0,      0,  4, "E=\315\050",           0x0 },
++  { "qnx4",    0,      4,  6, "QNX4FS",               0 },
++  { "crypt_LUKS", 0,   0,  6, "LUKS\xba\xbe",         0x0 },
++  { "squashfs",        0,      0,  4, "sqsh",                 0 },
++  { "squashfs",        0,      0,  4, "hsqs",                 0 },
++  { "ocfs",    0,      8,  9, "OracleCFS",            0x0 },
++  { "lvm2pv",  0,  0x018,  8, "LVM2 001",             0x0 },
++  { "sysv",    0,  0x3f8,  4, "\020~\030\375",        0 },
++  { "jbd",     1,   0x38,  2, "\123\357",             0x0 },
++  { "ext4dev",         1,   0x38,  2, "\123\357",             0x468 },
++  { "ext4",    1,   0x38,  2, "\123\357",             0x468 },
++  { "ext3",    1,   0x38,  2, "\123\357",             0x468 },
++  { "ext2",    1,   0x38,  2, "\123\357",             0x468 },
++  { "minix",     1,   0x10,  2, "\177\023",             0 },
++  { "minix",     1,   0x10,  2, "\217\023",             0 },
++  { "minix",   1,   0x10,  2, "\150\044",             0 },
++  { "minix",   1,   0x10,  2, "\170\044",             0 },
++  { "lvm2pv",  1,  0x018,  8, "LVM2 001",             0x0 },
++  { "vxfs",    1,      0,  4, "\365\374\001\245",     0 },
++  { "hfsplus",         1,      0,  2, "BD",                   0x0 },
++  { "hfsplus",         1,      0,  2, "H+",                   0x0 },
++  { "hfsplus",         1,      0,  2, "HX",                   0x0 },
++  { "hfs",     1,      0,  2, "BD",                   0x0 },
++  { "ocfs2",   1,      0,  6, "OCFSV2",               0x0 },
++  { "lvm2pv",  0,  0x218,  8, "LVM2 001",             0x0 },
++  { "lvm2pv",  1,  0x218,  8, "LVM2 001",             0x0 },
++  { "ocfs2",   2,      0,  6, "OCFSV2",               0x0 },
++  { "swap",    0,  0xff6, 10, "SWAP-SPACE",           0x40c },
++  { "swap",    0,  0xff6, 10, "SWAPSPACE2",           0x40c },
++  { "swsuspend", 0,  0xff6,  9, "S1SUSPEND",          0x40c },
++  { "swsuspend", 0,  0xff6,  9, "S2SUSPEND",          0x40c },
++  { "swsuspend", 0,  0xff6,  9, "ULSUSPEND",          0x40c },
++  { "ocfs2",   4,      0,  6, "OCFSV2",               0x0 },
++  { "ocfs2",   8,      0,  6, "OCFSV2",               0x0 },
++  { "hpfs",    8,      0,  4, "I\350\225\371",        0 },
++  { "reiserfs",        8,   0x34,  8, "ReIsErFs",             0x10054 },
++  { "reiserfs",        8,     20,  8, "ReIsErFs",             0x10054 },
++  { "zfs",       8,    0,  8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", 0x0 },
++  { "zfs",       8,    0,  8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", 0x0 },
++  { "ufs",     8,  0x55c,  4, "T\031\001\000",        0 },
++  { "swap",    0, 0x1ff6, 10, "SWAP-SPACE",           0x40c },
++  { "swap",    0, 0x1ff6, 10, "SWAPSPACE2",           0x40c },
++  { "swsuspend", 0, 0x1ff6,  9, "S1SUSPEND",          0x40c },
++  { "swsuspend", 0, 0x1ff6,  9, "S2SUSPEND",          0x40c },
++  { "swsuspend", 0, 0x1ff6,  9, "ULSUSPEND",          0x40c },
++  { "reiserfs", 64,   0x34,  9, "ReIsEr2Fs",          0x10054 },
++  { "reiserfs", 64,   0x34,  9, "ReIsEr3Fs",          0x10054 },
++  { "reiserfs", 64,   0x34,  8, "ReIsErFs",           0x10054 },
++  { "reiser4",  64,    0,  7, "ReIsEr4",              0x100544 },
++  { "gfs2",     64,      0,  4, "\x01\x16\x19\x70",     0x0 },
++  { "gfs",      64,      0,  4, "\x01\x16\x19\x70",     0x0 },
++  { "btrfs",  64,   0x40,  8, "_BHRfS_M",             0x0 },
++  { "swap",    0, 0x3ff6, 10, "SWAP-SPACE",           0x40c },
++  { "swap",    0, 0x3ff6, 10, "SWAPSPACE2",           0x40c },
++  { "swsuspend", 0, 0x3ff6,  9, "S1SUSPEND",          0x40c },
++  { "swsuspend", 0, 0x3ff6,  9, "S2SUSPEND",          0x40c },
++  { "swsuspend", 0, 0x3ff6,  9, "ULSUSPEND",          0x40c },
++  { "udf",    32,      1,  5, "BEA01",                0x0 },
++  { "udf",    32,      1,  5, "BOOT2",                0x0 },
++  { "udf",    32,      1,  5, "CD001",                0x0 },
++  { "udf",    32,      1,  5, "CDW02",                0x0 },
++  { "udf",    32,      1,  5, "NSR02",                0x0 },
++  { "udf",    32,      1,  5, "NSR03",                0x0 },
++  { "udf",    32,      1,  5, "TEA01",                0x0 },
++  { "iso9660",        32,      1,  5, "CD001",                0x0 },
++  { "iso9660",        32,      9,  5, "CDROM",                0x0 },
++  { "jfs",    32,      0,  4, "JFS1",                 0x88 },
++  { "swap",    0, 0x7ff6, 10, "SWAP-SPACE",           0x40c },
++  { "swap",    0, 0x7ff6, 10, "SWAPSPACE2",           0x40c },
++  { "swsuspend", 0, 0x7ff6,  9, "S1SUSPEND",          0x40c },
++  { "swsuspend", 0, 0x7ff6,  9, "S2SUSPEND",          0x40c },
++  { "swsuspend", 0, 0x7ff6,  9, "ULSUSPEND",          0x40c },
++  { "swap",    0, 0xfff6, 10, "SWAP-SPACE",           0x40c },
++  { "swap",    0, 0xfff6, 10, "SWAPSPACE2",           0x40c },
++  { "swsuspend", 0, 0xfff6,  9, "S1SUSPEND",          0x40c },
++  { "swsuspend", 0, 0xfff6,  9, "S2SUSPEND",          0x40c },
++  { "swsuspend", 0, 0xfff6,  9, "ULSUSPEND",          0x40c },
++  { "zfs",     264,    0,  8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", 0x0 },
++  { "zfs",     264,    0,  8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", 0x0 },
++  { NULL,        0,      0,  0, NULL,                 0x0 }
++};
++
++static void uuid_end_bio(struct bio *bio, int err)
++{
++      struct page *page = bio->bi_io_vec[0].bv_page;
++
++      BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
++
++      unlock_page(page);
++      bio_put(bio);
++}
++
++
++/**
++ * submit - submit BIO request
++ * @writing: READ or WRITE.
++ * @dev: The block device we're using.
++ * @first_block: The first sector we're using.
++ * @page: The page being used for I/O.
++ * @free_group: If writing, the group that was used in allocating the page
++ *    and which will be used in freeing the page from the completion
++ *    routine.
++ *
++ * Based on Patrick Mochell's pmdisk code from long ago: "Straight from the
++ * textbook - allocate and initialize the bio. If we're writing, make sure
++ * the page is marked as dirty. Then submit it and carry on."
++ *
++ * If we're just testing the speed of our own code, we fake having done all
++ * the hard work and all toi_end_bio immediately.
++ **/
++static struct page *read_bdev_sector(struct block_device *dev,
++              sector_t first_block)
++{
++      struct bio *bio = NULL;
++      struct page *page = alloc_page(GFP_KERNEL);
++
++      if (!page)
++              return NULL;
++
++      lock_page(page);
++
++      bio = bio_alloc(GFP_KERNEL, 1);
++      bio->bi_bdev = dev;
++      bio->bi_sector = first_block;
++      bio->bi_end_io = uuid_end_bio;
++
++      if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
++              printk(KERN_DEBUG "ERROR: adding page to bio at %lld\n",
++                              (unsigned long long) first_block);
++              bio_put(bio);
++              __free_page(page);
++              printk(KERN_DEBUG "read_bdev_sector freed page %p (in error "
++                              "path).\n", page);
++              return ERR_PTR(-EFAULT);
++      }
++
++      submit_bio(READ | (1 << BIO_RW_SYNCIO) |
++                      (1 << BIO_RW_UNPLUG), bio);
++
++      wait_on_page_bit(page, PG_locked);
++      return page;
++}
++
++
++int part_matches_uuid(struct hd_struct *part, const char *uuid)
++{
++      struct block_device *bdev;
++      unsigned char *data = NULL;
++      struct page *data_page = NULL;
++
++      int dev_offset, pg_num, pg_off;
++      int uuid_pg_num, uuid_pg_off, i;
++      unsigned char *uuid_data = NULL;
++      struct page *uuid_data_page = NULL;
++
++      int last_pg_num = 0, last_uuid_pg_num = 0;
++      int result = 0;
++      char buf[50];
++
++      bdev = bdget(part_devt(part));
++
++      PRINTK("blkdev_get %p.\n", part);
++
++      if (blkdev_get(bdev, FMODE_READ)) {
++              PRINTK("blkdev_get failed.\n");
++              return 0;
++      }
++
++      if (!bdev->bd_disk) {
++              bdevname(bdev, buf);
++              PRINTK("bdev %s has no bd_disk.\n", buf);
++              goto out;
++      }
++
++      if (!bdev->bd_disk->queue) {
++              bdevname(bdev, buf);
++              PRINTK("bdev %s has no queue.\n", buf);
++              goto out;
++      }
++
++      PRINT_HEX_DUMP(KERN_EMERG, "part_matches_uuid looking for ",
++                      DUMP_PREFIX_NONE, 16, 1, uuid, 16, 0);
++
++      for (i = 0; uuid_list[i].name; i++) {
++              struct uuid_info *dat = &uuid_list[i];
++              dev_offset = (dat->bkoff << 10) + dat->sboff;
++              pg_num = dev_offset >> 12;
++              pg_off = dev_offset & 0xfff;
++              uuid_pg_num = dat->uuid_offset >> 12;
++              uuid_pg_off = dat->uuid_offset & 0xfff;
++
++              if ((((pg_num + 1) << 3) - 1) > part->nr_sects >> 1)
++                      continue;
++
++              if (!i || pg_num != last_pg_num) {
++                      if (data_page)
++                              __free_page(data_page);
++                      data_page = read_bdev_sector(bdev, pg_num);
++                      data = page_address(data_page);
++              }
++
++              last_pg_num = pg_num;
++
++              if (strncmp(&data[pg_off], dat->magic, dat->sig_len))
++                      continue;
++
++              /* Does the UUID match? */
++              if (uuid_pg_num > part->nr_sects >> 3)
++                      continue;
++
++              if (!uuid_data || uuid_pg_num != last_uuid_pg_num) {
++                      if (uuid_data_page)
++                              __free_page(uuid_data_page);
++                      uuid_data_page = read_bdev_sector(bdev, uuid_pg_num);
++                      uuid_data = page_address(uuid_data_page);
++              }
++
++              last_uuid_pg_num = uuid_pg_num;
++
++              PRINT_HEX_DUMP(KERN_EMERG, "part_matches_uuid considering ",
++                              DUMP_PREFIX_NONE, 16, 1,
++                              &uuid_data[uuid_pg_off], 16, 0);
++
++              if (!memcmp(&uuid_data[uuid_pg_off], uuid, 16)) {
++                      PRINTK("We have a match.\n");
++                      result = 1;
++                      break;
++              }
++      }
++
++      if (data_page)
++              __free_page(data_page);
++
++      if (uuid_data_page)
++              __free_page(uuid_data_page);
++
++out:
++      blkdev_put(bdev, FMODE_READ);
++      return result;
++}
++
++int uuid_from_block_dev(struct block_device *bdev, char *uuid)
++{
++      unsigned char *data = NULL;
++      struct page *data_page = NULL;
++
++      int dev_offset, pg_num, pg_off;
++      int uuid_pg_num, uuid_pg_off, i;
++      unsigned char *uuid_data = NULL;
++      struct page *uuid_data_page = NULL;
++
++      int last_pg_num = 0, last_uuid_pg_num = 0;
++      int result = 1;
++      char buf[50];
++
++      bdevname(bdev, buf);
++
++      PRINTK(KERN_EMERG "uuid_from_block_dev looking for partition type "
++                      "of %s.\n", buf);
++
++      for (i = 0; uuid_list[i].name; i++) {
++              struct uuid_info *dat = &uuid_list[i];
++              dev_offset = (dat->bkoff << 10) + dat->sboff;
++              pg_num = dev_offset >> 12;
++              pg_off = dev_offset & 0xfff;
++              uuid_pg_num = dat->uuid_offset >> 12;
++              uuid_pg_off = dat->uuid_offset & 0xfff;
++
++              if ((((pg_num + 1) << 3) - 1) > bdev->bd_part->nr_sects >> 1)
++                      continue;
++
++              if (!i || pg_num != last_pg_num) {
++                      if (data_page)
++                              __free_page(data_page);
++                      data_page = read_bdev_sector(bdev, pg_num);
++                      data = page_address(data_page);
++              }
++
++              last_pg_num = pg_num;
++
++              if (strncmp(&data[pg_off], dat->magic, dat->sig_len))
++                      continue;
++
++              /* UUID can't be off the end of the disk */
++              if (uuid_pg_num > bdev->bd_part->nr_sects >> 3)
++                      continue;
++
++              PRINTK("This partition looks like %s.\n", dat->name);
++
++              if (!uuid_data || uuid_pg_num != last_uuid_pg_num) {
++                      if (uuid_data_page)
++                              __free_page(uuid_data_page);
++                      uuid_data_page = read_bdev_sector(bdev, uuid_pg_num);
++                      uuid_data = page_address(uuid_data_page);
++              }
++
++              last_uuid_pg_num = uuid_pg_num;
++
++              if (!uuid_pg_off) {
++                      PRINTK("Don't know uuid offset for %s. Continuing the "
++                                      "search.\n", dat->name);
++              } else {
++                      memcpy(uuid, &uuid_data[uuid_pg_off], 16);
++                      PRINT_HEX_DUMP(KERN_EMERG, "uuid_from_block_dev "
++                                      "returning ", DUMP_PREFIX_NONE, 16, 1,
++                                      uuid, 16, 0);
++                      result = 0;
++                      break;
++              }
++      }
++
++      if (data_page)
++              __free_page(data_page);
++
++      if (uuid_data_page)
++              __free_page(uuid_data_page);
++
++      return result;
++}
++EXPORT_SYMBOL_GPL(uuid_from_block_dev);
 diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 58a3e57..4b0c6cf 100644
+index 8aa2443..1e61592 100644
 --- a/drivers/base/power/main.c
 +++ b/drivers/base/power/main.c
-@@ -55,6 +55,7 @@ void device_pm_lock(void)
+@@ -66,6 +66,7 @@ void device_pm_lock(void)
  {
        mutex_lock(&dpm_list_mtx);
  }
 +EXPORT_SYMBOL_GPL(device_pm_lock);
  
  /**
-  *    device_pm_unlock - unlock the list of active devices used by the PM core
-@@ -63,6 +64,7 @@ void device_pm_unlock(void)
+  * device_pm_unlock - Unlock the list of active devices used by the PM core.
+@@ -74,6 +75,7 @@ void device_pm_unlock(void)
  {
        mutex_unlock(&dpm_list_mtx);
  }
 +EXPORT_SYMBOL_GPL(device_pm_unlock);
  
  /**
-  *    device_pm_add - add a device to the list of active devices
+  * device_pm_add - Add a device to the PM core's list of active devices.
 diff --git a/drivers/char/vt.c b/drivers/char/vt.c
-index 404f4c1..0988ad0 100644
+index 0c80c68..af032c1 100644
 --- a/drivers/char/vt.c
 +++ b/drivers/char/vt.c
 @@ -188,6 +188,7 @@ int fg_console;
@@ -1590,7 +2043,7 @@ index 404f4c1..0988ad0 100644
  /*
   * For each existing display, we have a pointer to console currently visible
 diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
-index ffe8f43..5e7dca6 100644
+index e9dbb48..db9bf9b 100644
 --- a/drivers/gpu/drm/drm_gem.c
 +++ b/drivers/gpu/drm/drm_gem.c
 @@ -138,7 +138,8 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
@@ -1604,10 +2057,10 @@ index ffe8f43..5e7dca6 100644
                goto free;
  
 diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 9dd8720..88dc120 100644
+index b182f86..f9d7053 100644
 --- a/drivers/md/md.c
 +++ b/drivers/md/md.c
-@@ -6245,6 +6245,9 @@ void md_do_sync(mddev_t *mddev)
+@@ -6279,6 +6279,9 @@ void md_do_sync(mddev_t *mddev)
                mddev->curr_resync = 2;
  
        try_again:
@@ -1617,7 +2070,7 @@ index 9dd8720..88dc120 100644
                if (kthread_should_stop()) {
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
                        goto skip;
-@@ -6266,6 +6269,10 @@ void md_do_sync(mddev_t *mddev)
+@@ -6300,6 +6303,10 @@ void md_do_sync(mddev_t *mddev)
                                         * time 'round when curr_resync == 2
                                         */
                                        continue;
@@ -1628,7 +2081,7 @@ index 9dd8720..88dc120 100644
                                /* We need to wait 'interruptible' so as not to
                                 * contribute to the load average, and not to
                                 * be caught by 'softlockup'
-@@ -6278,6 +6285,7 @@ void md_do_sync(mddev_t *mddev)
+@@ -6312,6 +6319,7 @@ void md_do_sync(mddev_t *mddev)
                                               " share one or more physical units)\n",
                                               desc, mdname(mddev), mdname(mddev2));
                                        mddev_put(mddev2);
@@ -1636,7 +2089,7 @@ index 9dd8720..88dc120 100644
                                        if (signal_pending(current))
                                                flush_signals(current);
                                        schedule();
-@@ -6384,6 +6392,9 @@ void md_do_sync(mddev_t *mddev)
+@@ -6418,6 +6426,9 @@ void md_do_sync(mddev_t *mddev)
                                                 || kthread_should_stop());
                }
  
@@ -1646,7 +2099,7 @@ index 9dd8720..88dc120 100644
                if (kthread_should_stop())
                        goto interrupted;
  
-@@ -6428,6 +6439,9 @@ void md_do_sync(mddev_t *mddev)
+@@ -6462,6 +6473,9 @@ void md_do_sync(mddev_t *mddev)
                        last_mark = next;
                }
  
@@ -1657,10 +2110,10 @@ index 9dd8720..88dc120 100644
                if (kthread_should_stop())
                        goto interrupted;
 diff --git a/fs/block_dev.c b/fs/block_dev.c
-index 94dfda2..8c1b98e 100644
+index 8bed055..3a49424 100644
 --- a/fs/block_dev.c
 +++ b/fs/block_dev.c
-@@ -327,6 +327,93 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
+@@ -334,6 +334,93 @@ out_unlock:
  }
  EXPORT_SYMBOL(thaw_bdev);
  
@@ -1755,7 +2208,7 @@ index 94dfda2..8c1b98e 100644
  {
        return block_write_full_page(page, blkdev_get_block, wbc);
 diff --git a/fs/drop_caches.c b/fs/drop_caches.c
-index a2edb79..1d0444e 100644
+index 31f4b0e..ff7df7a 100644
 --- a/fs/drop_caches.c
 +++ b/fs/drop_caches.c
 @@ -8,6 +8,7 @@
@@ -1782,12 +2235,12 @@ index a2edb79..1d0444e 100644
 +EXPORT_SYMBOL_GPL(drop_pagecache);
  
  int drop_caches_sysctl_handler(ctl_table *table, int write,
-       struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+       void __user *buffer, size_t *length, loff_t *ppos)
 diff --git a/fs/fuse/control.c b/fs/fuse/control.c
-index 99c99df..cadffd8 100644
+index 3773fd6..6272b60 100644
 --- a/fs/fuse/control.c
 +++ b/fs/fuse/control.c
-@@ -209,6 +209,7 @@ static void fuse_ctl_kill_sb(struct super_block *sb)
+@@ -341,6 +341,7 @@ static void fuse_ctl_kill_sb(struct super_block *sb)
  static struct file_system_type fuse_ctl_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "fusectl",
@@ -1796,7 +2249,7 @@ index 99c99df..cadffd8 100644
        .kill_sb        = fuse_ctl_kill_sb,
  };
 diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
-index 6484eb7..5251799 100644
+index 51d9e33..12ad477 100644
 --- a/fs/fuse/dev.c
 +++ b/fs/fuse/dev.c
 @@ -7,6 +7,7 @@
@@ -1835,7 +2288,7 @@ index 6484eb7..5251799 100644
        if (nbytes < sizeof(struct fuse_out_header))
                return -EINVAL;
 diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
-index e703654..bfb0500 100644
+index 4787ae6..797b7dd 100644
 --- a/fs/fuse/dir.c
 +++ b/fs/fuse/dir.c
 @@ -7,12 +7,14 @@
@@ -1881,7 +2334,7 @@ index e703654..bfb0500 100644
        err = -EIO;
        if (inode && get_node_id(inode) == FUSE_ROOT_ID)
                goto out_iput;
-@@ -389,6 +398,8 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
+@@ -392,6 +401,8 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        if (IS_ERR(forget_req))
                return PTR_ERR(forget_req);
  
@@ -1890,7 +2343,7 @@ index e703654..bfb0500 100644
        req = fuse_get_req(fc);
        err = PTR_ERR(req);
        if (IS_ERR(req))
-@@ -482,6 +493,8 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
+@@ -485,6 +496,8 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        int err;
        struct fuse_req *forget_req;
  
@@ -1899,7 +2352,7 @@ index e703654..bfb0500 100644
        forget_req = fuse_get_req(fc);
        if (IS_ERR(forget_req)) {
                fuse_put_request(fc, req);
-@@ -584,7 +597,11 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
+@@ -587,7 +600,11 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
  {
        struct fuse_mkdir_in inarg;
        struct fuse_conn *fc = get_fuse_conn(dir);
@@ -1912,7 +2365,7 @@ index e703654..bfb0500 100644
        if (IS_ERR(req))
                return PTR_ERR(req);
  
-@@ -608,7 +625,11 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
+@@ -611,7 +628,11 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
  {
        struct fuse_conn *fc = get_fuse_conn(dir);
        unsigned len = strlen(link) + 1;
@@ -1925,7 +2378,7 @@ index e703654..bfb0500 100644
        if (IS_ERR(req))
                return PTR_ERR(req);
  
-@@ -625,7 +646,11 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
+@@ -628,7 +649,11 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
  {
        int err;
        struct fuse_conn *fc = get_fuse_conn(dir);
@@ -1938,7 +2391,7 @@ index e703654..bfb0500 100644
        if (IS_ERR(req))
                return PTR_ERR(req);
  
-@@ -658,7 +683,11 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
+@@ -661,7 +686,11 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
  {
        int err;
        struct fuse_conn *fc = get_fuse_conn(dir);
@@ -1952,7 +2405,7 @@ index e703654..bfb0500 100644
                return PTR_ERR(req);
  
 diff --git a/fs/fuse/file.c b/fs/fuse/file.c
-index cbc4640..b99aa5c 100644
+index c18913a..0f7d313 100644
 --- a/fs/fuse/file.c
 +++ b/fs/fuse/file.c
 @@ -7,11 +7,13 @@
@@ -2051,7 +2504,7 @@ index cbc4640..b99aa5c 100644
        req = fuse_get_req(fc);
        if (IS_ERR(req))
                return PTR_ERR(req);
-@@ -1408,6 +1429,8 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)
+@@ -1409,6 +1430,8 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)
        struct fuse_lk_out outarg;
        int err;
  
@@ -2060,7 +2513,7 @@ index cbc4640..b99aa5c 100644
        req = fuse_get_req(fc);
        if (IS_ERR(req))
                return PTR_ERR(req);
-@@ -1443,6 +1466,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
+@@ -1444,6 +1467,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
        if (fl->fl_flags & FL_CLOSE)
                return 0;
  
@@ -2069,7 +2522,7 @@ index cbc4640..b99aa5c 100644
        req = fuse_get_req(fc);
        if (IS_ERR(req))
                return PTR_ERR(req);
-@@ -1509,6 +1534,8 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
+@@ -1510,6 +1535,8 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
        if (!inode->i_sb->s_bdev || fc->no_bmap)
                return 0;
  
@@ -2098,10 +2551,10 @@ index 0000000..170e49a
 +      } \
 +} while (0)
 diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
-index f91ccc4..8de2966 100644
+index 1a822ce..9b69d61 100644
 --- a/fs/fuse/inode.c
 +++ b/fs/fuse/inode.c
-@@ -991,7 +991,7 @@ static void fuse_kill_sb_anon(struct super_block *sb)
+@@ -1062,7 +1062,7 @@ static void fuse_kill_sb_anon(struct super_block *sb)
  static struct file_system_type fuse_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "fuse",
@@ -2110,7 +2563,7 @@ index f91ccc4..8de2966 100644
        .get_sb         = fuse_get_sb,
        .kill_sb        = fuse_kill_sb_anon,
  };
-@@ -1023,7 +1023,7 @@ static struct file_system_type fuseblk_fs_type = {
+@@ -1094,7 +1094,7 @@ static struct file_system_type fuseblk_fs_type = {
        .name           = "fuseblk",
        .get_sb         = fuse_get_sb_blk,
        .kill_sb        = fuse_kill_sb_blk,
@@ -2120,10 +2573,10 @@ index f91ccc4..8de2966 100644
  
  static inline int register_fuseblk(void)
 diff --git a/fs/namei.c b/fs/namei.c
-index 1f13751..96fcd99 100644
+index d11f404..c665cb7 100644
 --- a/fs/namei.c
 +++ b/fs/namei.c
-@@ -2271,6 +2271,8 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
+@@ -2273,6 +2273,8 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
        if (!dir->i_op->unlink)
                return -EPERM;
  
@@ -2133,7 +2586,7 @@ index 1f13751..96fcd99 100644
  
        mutex_lock(&dentry->d_inode->i_mutex);
 diff --git a/fs/super.c b/fs/super.c
-index 2761d3e..6892dab 100644
+index 19eb70b..96cf7e6 100644
 --- a/fs/super.c
 +++ b/fs/super.c
 @@ -42,6 +42,8 @@
@@ -2146,10 +2599,10 @@ index 2761d3e..6892dab 100644
  
  /**
 diff --git a/include/linux/Kbuild b/include/linux/Kbuild
-index 334a359..c53ebd5 100644
+index 1feed71..23f2385 100644
 --- a/include/linux/Kbuild
 +++ b/include/linux/Kbuild
-@@ -211,6 +211,7 @@ unifdef-y += filter.h
+@@ -212,6 +212,7 @@ unifdef-y += filter.h
  unifdef-y += flat.h
  unifdef-y += futex.h
  unifdef-y += fs.h
@@ -2157,35 +2610,47 @@ index 334a359..c53ebd5 100644
  unifdef-y += gameport.h
  unifdef-y += generic_serial.h
  unifdef-y += hayesesp.h
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index 5be93f1..b9ce6fe 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -175,8 +175,11 @@ enum bio_rw_flags {
+       BIO_RW_META,
+       BIO_RW_DISCARD,
+       BIO_RW_NOIDLE,
++      BIO_RW_TUXONICE,
+ };
++extern int trap_non_toi_io;
++
+ /*
+  * First four bits must match between bio->bi_rw and rq->cmd_flags, make
+  * that explicit here.
 diff --git a/include/linux/freezer.h b/include/linux/freezer.h
-index 5a361f8..c775cd1 100644
+index 5a361f8..a66f2a9 100644
 --- a/include/linux/freezer.h
 +++ b/include/linux/freezer.h
-@@ -121,6 +121,23 @@ static inline void set_freezable(void)
+@@ -121,6 +121,19 @@ static inline void set_freezable(void)
        current->flags &= ~PF_NOFREEZE;
  }
  
++extern int freezer_state;
 +#define FREEZER_OFF 0
 +#define FREEZER_FILESYSTEMS_FROZEN 1
 +#define FREEZER_USERSPACE_FROZEN 2
 +#define FREEZER_FULLY_ON 3
-+#ifdef CONFIG_PM_SLEEP
-+extern int freezer_state;
 +
 +static inline int freezer_is_on(void)
 +{
 +      return freezer_state == FREEZER_FULLY_ON;
 +}
-+#else
-+static inline int freezer_is_on(void) { return 0; }
-+#endif
 +
 +extern void thaw_kernel_threads(void);
 +
  /*
   * Tell the freezer that the current task should be frozen by it and that it
   * should send a fake signal to the task to freeze it.
-@@ -172,6 +189,8 @@ static inline int freeze_processes(void) { BUG(); return 0; }
+@@ -172,6 +185,8 @@ static inline int freeze_processes(void) { BUG(); return 0; }
  static inline void thaw_processes(void) {}
  
  static inline int try_to_freeze(void) { return 0; }
@@ -2195,7 +2660,7 @@ index 5a361f8..c775cd1 100644
  static inline void freezer_do_not_count(void) {}
  static inline void freezer_count(void) {}
 diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 73e9b64..78b2ef3 100644
+index 2620a8c..bd1c328 100644
 --- a/include/linux/fs.h
 +++ b/include/linux/fs.h
 @@ -172,6 +172,7 @@ struct inodes_stat_t {
@@ -2223,7 +2688,7 @@ index 73e9b64..78b2ef3 100644
  
  /*
   * Note that nosuid etc flags are inode-specific: setting some file-system
-@@ -373,6 +377,7 @@ struct inodes_stat_t {
+@@ -377,6 +381,7 @@ struct inodes_stat_t {
  #include <linux/capability.h>
  #include <linux/semaphore.h>
  #include <linux/fiemap.h>
@@ -2231,7 +2696,7 @@ index 73e9b64..78b2ef3 100644
  
  #include <asm/atomic.h>
  #include <asm/byteorder.h>
-@@ -1392,8 +1397,11 @@ enum {
+@@ -1393,8 +1398,11 @@ enum {
        SB_FREEZE_TRANS = 2,
  };
  
@@ -2245,7 +2710,7 @@ index 73e9b64..78b2ef3 100644
  
  #define get_fs_excl() atomic_inc(&current->fs_excl)
  #define put_fs_excl() atomic_dec(&current->fs_excl)
-@@ -1957,6 +1965,13 @@ extern struct super_block *freeze_bdev(struct block_device *);
+@@ -1955,6 +1963,13 @@ extern struct super_block *freeze_bdev(struct block_device *);
  extern void emergency_thaw_all(void);
  extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
  extern int fsync_bdev(struct block_device *);
@@ -2260,18 +2725,18 @@ index 73e9b64..78b2ef3 100644
  static inline void bd_forget(struct inode *inode) {}
  static inline int sync_blockdev(struct block_device *bdev) { return 0; }
 diff --git a/include/linux/mm.h b/include/linux/mm.h
-index 9a72cc7..ec0431d 100644
+index 24c3956..e935946 100644
 --- a/include/linux/mm.h
 +++ b/include/linux/mm.h
-@@ -103,6 +103,7 @@ extern unsigned int kobjsize(const void *objp);
- #define VM_MIXEDMAP   0x10000000      /* Can contain "struct page" and pure PFN pages */
- #define VM_SAO                0x20000000      /* Strong Access Ordering (powerpc) */
- #define VM_PFN_AT_MMAP        0x40000000      /* PFNMAP vma that is fully mapped at mmap time */
-+#define VM_ATOMIC_COPY        0x80000000      /* TuxOnIce should atomically copy */
+@@ -97,6 +97,7 @@ extern unsigned int kobjsize(const void *objp);
+ #define VM_HUGETLB    0x00400000      /* Huge TLB Page VM */
+ #define VM_NONLINEAR  0x00800000      /* Is non-linear (remap_file_pages) */
+ #define VM_MAPPED_COPY        0x01000000      /* T if mapped copy of data (nommu mmap) */
++#define VM_ATOMIC_COPY        0x01000000      /* TuxOnIce should atomically copy (mmu) */
+ #define VM_INSERTPAGE 0x02000000      /* The vma has had "vm_insert_page()" done on it */
+ #define VM_ALWAYSDUMP 0x04000000      /* Always include in core dumps */
  
- #ifndef VM_STACK_DEFAULT_FLAGS                /* arch can override this */
- #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
-@@ -1278,6 +1279,7 @@ int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *,
+@@ -1290,6 +1291,7 @@ int drop_caches_sysctl_handler(struct ctl_table *, int,
                                        void __user *, size_t *, loff_t *);
  unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
                        unsigned long lru_pages);
@@ -2280,7 +2745,7 @@ index 9a72cc7..ec0431d 100644
  #ifndef CONFIG_MMU
  #define randomize_va_space 0
 diff --git a/include/linux/netlink.h b/include/linux/netlink.h
-index 5ba398e..f220828 100644
+index ab5d312..aee7b0f 100644
 --- a/include/linux/netlink.h
 +++ b/include/linux/netlink.h
 @@ -24,6 +24,8 @@
@@ -2293,12 +2758,12 @@ index 5ba398e..f220828 100644
  #define MAX_LINKS 32          
  
 diff --git a/include/linux/suspend.h b/include/linux/suspend.h
-index cd15df6..df6b587 100644
+index 5e781d8..a1c07f3 100644
 --- a/include/linux/suspend.h
 +++ b/include/linux/suspend.h
-@@ -312,4 +312,70 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e)
- extern struct mutex pm_mutex;
+@@ -329,4 +329,70 @@ static inline void unlock_system_sleep(void)
+ }
+ #endif
  
 +enum {
 +      TOI_CAN_HIBERNATE,
@@ -2368,10 +2833,10 @@ index cd15df6..df6b587 100644
 +#endif
  #endif /* _LINUX_SUSPEND_H */
 diff --git a/include/linux/swap.h b/include/linux/swap.h
-index 7c15334..779dcb1 100644
+index 4ec9001..12da629 100644
 --- a/include/linux/swap.h
 +++ b/include/linux/swap.h
-@@ -169,6 +169,7 @@ struct swap_list_t {
+@@ -191,6 +191,7 @@ struct swap_list_t {
  extern unsigned long totalram_pages;
  extern unsigned long totalreserve_pages;
  extern unsigned int nr_free_buffer_pages(void);
@@ -2379,8 +2844,22 @@ index 7c15334..779dcb1 100644
  extern unsigned int nr_free_pagecache_pages(void);
  
  /* Definition of global_page_state not available yet */
+diff --git a/include/linux/uuid.h b/include/linux/uuid.h
+new file mode 100644
+index 0000000..a3f6a99
+--- /dev/null
++++ b/include/linux/uuid.h
+@@ -0,0 +1,8 @@
++#include <linux/device.h>
++
++struct hd_struct;
++struct block_device;
++
++int part_matches_uuid(struct hd_struct *part, const char *uuid);
++dev_t blk_lookup_uuid(const char *uuid);
++int uuid_from_block_dev(struct block_device *bdev, char *uuid);
 diff --git a/init/do_mounts.c b/init/do_mounts.c
-index 093f659..cf1ef2b 100644
+index bb008d0..5273dc9 100644
 --- a/init/do_mounts.c
 +++ b/init/do_mounts.c
 @@ -143,6 +143,7 @@ fail:
@@ -2399,7 +2878,7 @@ index 093f659..cf1ef2b 100644
 +
        mount_root();
  out:
-       sys_mount(".", "/", NULL, MS_MOVE, NULL);
+       devtmpfs_mount("dev");
 diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
 index 614241b..f3ea292 100644
 --- a/init/do_mounts_initrd.c
@@ -2425,10 +2904,10 @@ index 614241b..f3ea292 100644
        sys_fchdir(old_fd);
        sys_mount("/", ".", NULL, MS_MOVE, NULL);
 diff --git a/init/main.c b/init/main.c
-index 11f4f14..cb63e56 100644
+index 4051d75..650828d 100644
 --- a/init/main.c
 +++ b/init/main.c
-@@ -115,6 +115,7 @@ extern void softirq_init(void);
+@@ -116,6 +116,7 @@ extern void softirq_init(void);
  char __initdata boot_command_line[COMMAND_LINE_SIZE];
  /* Untouched saved command line (eg. for /proc) */
  char *saved_command_line;
@@ -2437,18 +2916,18 @@ index 11f4f14..cb63e56 100644
  static char *static_command_line;
  
 diff --git a/kernel/cpu.c b/kernel/cpu.c
-index 8ce1004..853cf28 100644
+index 6ba0f1e..a633bac 100644
 --- a/kernel/cpu.c
 +++ b/kernel/cpu.c
-@@ -412,6 +412,7 @@ int disable_nonboot_cpus(void)
+@@ -413,6 +413,7 @@ int disable_nonboot_cpus(void)
        stop_machine_destroy();
        return error;
  }
 +EXPORT_SYMBOL_GPL(disable_nonboot_cpus);
  
- void __ref enable_nonboot_cpus(void)
+ void __weak arch_enable_nonboot_cpus_begin(void)
  {
-@@ -436,6 +437,7 @@ void __ref enable_nonboot_cpus(void)
+@@ -451,6 +452,7 @@ void __ref enable_nonboot_cpus(void)
  out:
        cpu_maps_update_done();
  }
@@ -2457,10 +2936,10 @@ index 8ce1004..853cf28 100644
  static int alloc_frozen_cpus(void)
  {
 diff --git a/kernel/fork.c b/kernel/fork.c
-index e6c04d4..9f36327 100644
+index 166b8c4..8033d91 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -83,6 +83,7 @@ int max_threads;             /* tunable limit on nr_threads */
+@@ -85,6 +85,7 @@ int max_threads;             /* tunable limit on nr_threads */
  DEFINE_PER_CPU(unsigned long, process_counts) = 0;
  
  __cacheline_aligned DEFINE_RWLOCK(tasklist_lock);  /* outer */
@@ -2469,10 +2948,10 @@ index e6c04d4..9f36327 100644
  int nr_processes(void)
  {
 diff --git a/kernel/kmod.c b/kernel/kmod.c
-index 385c31a..1ad9a46 100644
+index 9fcb53a..624929f 100644
 --- a/kernel/kmod.c
 +++ b/kernel/kmod.c
-@@ -318,6 +318,7 @@ int usermodehelper_disable(void)
+@@ -326,6 +326,7 @@ int usermodehelper_disable(void)
        usermodehelper_disabled = 0;
        return -EAGAIN;
  }
@@ -2480,7 +2959,7 @@ index 385c31a..1ad9a46 100644
  
  /**
   * usermodehelper_enable - allow new helpers to be started again
-@@ -326,6 +327,7 @@ void usermodehelper_enable(void)
+@@ -334,6 +335,7 @@ void usermodehelper_enable(void)
  {
        usermodehelper_disabled = 0;
  }
@@ -2489,7 +2968,7 @@ index 385c31a..1ad9a46 100644
  static void helper_lock(void)
  {
 diff --git a/kernel/pid.c b/kernel/pid.c
-index 31310b5..f64b509 100644
+index d3f722d..291a7c3 100644
 --- a/kernel/pid.c
 +++ b/kernel/pid.c
 @@ -382,6 +382,7 @@ struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
@@ -2501,7 +2980,7 @@ index 31310b5..f64b509 100644
  struct task_struct *find_task_by_vpid(pid_t vnr)
  {
 diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
-index 72067cb..82cd2a1 100644
+index 91e09d3..21f1af0 100644
 --- a/kernel/power/Kconfig
 +++ b/kernel/power/Kconfig
 @@ -38,6 +38,13 @@ config CAN_PM_TRACE
@@ -2757,22 +3236,26 @@ index 72067cb..82cd2a1 100644
        tristate "Advanced Power Management Emulation"
        depends on PM && SYS_SUPPORTS_APM_EMULATION
 diff --git a/kernel/power/Makefile b/kernel/power/Makefile
-index c3b81c3..b5a36bc 100644
+index c3b81c3..982a589 100644
 --- a/kernel/power/Makefile
 +++ b/kernel/power/Makefile
-@@ -3,6 +3,28 @@ ifeq ($(CONFIG_PM_DEBUG),y)
+@@ -3,6 +3,35 @@ ifeq ($(CONFIG_PM_DEBUG),y)
  EXTRA_CFLAGS  +=      -DDEBUG
  endif
  
-+tuxonice_core-y := tuxonice_modules.o tuxonice_sysfs.o tuxonice_highlevel.o \
-+              tuxonice_io.o tuxonice_pagedir.o tuxonice_prepare_image.o \
-+              tuxonice_extent.o tuxonice_pageflags.o tuxonice_ui.o \
-+              tuxonice_power_off.o tuxonice_atomic_copy.o
++tuxonice_core-y := tuxonice_modules.o
 +
 +obj-$(CONFIG_TOI)             += tuxonice_builtin.o
 +
 +tuxonice_core-$(CONFIG_PM_DEBUG)      += tuxonice_alloc.o
 +
++# Compile these in after allocation debugging, if used.
++
++tuxonice_core-y += tuxonice_sysfs.o tuxonice_highlevel.o \
++              tuxonice_io.o tuxonice_pagedir.o tuxonice_prepare_image.o \
++              tuxonice_extent.o tuxonice_pageflags.o tuxonice_ui.o \
++              tuxonice_power_off.o tuxonice_atomic_copy.o
++
 +tuxonice_core-$(CONFIG_TOI_CHECKSUM)  += tuxonice_checksum.o
 +
 +tuxonice_core-$(CONFIG_NET)   += tuxonice_storage.o tuxonice_netlink.o
@@ -2780,8 +3263,11 @@ index c3b81c3..b5a36bc 100644
 +obj-$(CONFIG_TOI_CORE)                += tuxonice_core.o
 +obj-$(CONFIG_TOI_CRYPTO)      += tuxonice_compress.o
 +
-+obj-$(CONFIG_TOI_SWAP)                += tuxonice_block_io.o tuxonice_swap.o
-+obj-$(CONFIG_TOI_FILE)                += tuxonice_block_io.o tuxonice_file.o
++tuxonice_bio-y := tuxonice_bio_core.o tuxonice_bio_chains.o \
++              tuxonice_bio_signature.o
++
++obj-$(CONFIG_TOI_SWAP)                += tuxonice_bio.o tuxonice_swap.o
++obj-$(CONFIG_TOI_FILE)                += tuxonice_bio.o tuxonice_file.o
 +obj-$(CONFIG_TOI_CLUSTER)     += tuxonice_cluster.o
 +
 +obj-$(CONFIG_TOI_USERUI)      += tuxonice_userui.o
@@ -2789,8 +3275,26 @@ index c3b81c3..b5a36bc 100644
  obj-$(CONFIG_PM)              += main.o
  obj-$(CONFIG_PM_SLEEP)                += console.o
  obj-$(CONFIG_FREEZER)         += process.o
+diff --git a/kernel/power/console.c b/kernel/power/console.c
+index 5187136..f4f8761 100644
+--- a/kernel/power/console.c
++++ b/kernel/power/console.c
+@@ -25,6 +25,7 @@ int pm_prepare_console(void)
+       kmsg_redirect = SUSPEND_CONSOLE;
+       return 0;
+ }
++EXPORT_SYMBOL_GPL(pm_prepare_console);
+ void pm_restore_console(void)
+ {
+@@ -33,4 +34,5 @@ void pm_restore_console(void)
+               kmsg_redirect = orig_kmsg;
+       }
+ }
++EXPORT_SYMBOL_GPL(pm_restore_console);
+ #endif
 diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
-index 81d2e74..3fc04ad 100644
+index 04a9e90..c35feb0 100644
 --- a/kernel/power/hibernate.c
 +++ b/kernel/power/hibernate.c
 @@ -25,11 +25,12 @@
@@ -2915,7 +3419,7 @@ index 81d2e74..3fc04ad 100644
  
  /**
   *    create_image - freeze devices that need to be frozen with interrupts
-@@ -491,6 +500,7 @@ int hibernation_platform_enter(void)
+@@ -495,6 +504,7 @@ int hibernation_platform_enter(void)
  
        return error;
  }
@@ -2923,7 +3427,7 @@ index 81d2e74..3fc04ad 100644
  
  /**
   *    power_down - Shut the machine down for hibernation.
-@@ -542,6 +552,9 @@ int hibernate(void)
+@@ -546,6 +556,9 @@ int hibernate(void)
  {
        int error;
  
@@ -2933,7 +3437,7 @@ index 81d2e74..3fc04ad 100644
        mutex_lock(&pm_mutex);
        /* The snapshot device should not be opened while we're running */
        if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
-@@ -619,11 +632,19 @@ int hibernate(void)
+@@ -626,11 +639,19 @@ int hibernate(void)
   *
   */
  
@@ -2954,7 +3458,7 @@ index 81d2e74..3fc04ad 100644
        /*
         * If the user said "noresume".. bail out early.
         */
-@@ -947,6 +968,7 @@ static int __init resume_offset_setup(char *str)
+@@ -959,6 +980,7 @@ static int __init resume_offset_setup(char *str)
  static int __init noresume_setup(char *str)
  {
        noresume = 1;
@@ -2963,10 +3467,10 @@ index 81d2e74..3fc04ad 100644
  }
  
 diff --git a/kernel/power/main.c b/kernel/power/main.c
-index f710e36..8f1b120 100644
+index 347d2cc..10e587f 100644
 --- a/kernel/power/main.c
 +++ b/kernel/power/main.c
-@@ -15,6 +15,7 @@
+@@ -16,6 +16,7 @@
  #include "power.h"
  
  DEFINE_MUTEX(pm_mutex);
@@ -2974,7 +3478,7 @@ index f710e36..8f1b120 100644
  
  unsigned int pm_flags;
  EXPORT_SYMBOL(pm_flags);
-@@ -23,7 +24,8 @@ EXPORT_SYMBOL(pm_flags);
+@@ -24,7 +25,8 @@ EXPORT_SYMBOL(pm_flags);
  
  /* Routines for PM-transition notifications */
  
@@ -2984,7 +3488,7 @@ index f710e36..8f1b120 100644
  
  int register_pm_notifier(struct notifier_block *nb)
  {
-@@ -42,6 +44,7 @@ int pm_notifier_call_chain(unsigned long val)
+@@ -43,6 +45,7 @@ int pm_notifier_call_chain(unsigned long val)
        return (blocking_notifier_call_chain(&pm_chain_head, val, NULL)
                        == NOTIFY_BAD) ? -EINVAL : 0;
  }
@@ -2992,7 +3496,7 @@ index f710e36..8f1b120 100644
  
  #ifdef CONFIG_PM_DEBUG
  int pm_test_level = TEST_NONE;
-@@ -109,6 +112,7 @@ power_attr(pm_test);
+@@ -110,6 +113,7 @@ power_attr(pm_test);
  #endif /* CONFIG_PM_SLEEP */
  
  struct kobject *power_kobj;
@@ -3001,7 +3505,7 @@ index f710e36..8f1b120 100644
  /**
   *    state - control system power state.
 diff --git a/kernel/power/power.h b/kernel/power/power.h
-index 26d5a26..71469b4 100644
+index 46c5a26..d8c8f32 100644
 --- a/kernel/power/power.h
 +++ b/kernel/power/power.h
 @@ -31,8 +31,12 @@ static inline char *check_image_kernel(struct swsusp_info *info)
@@ -3072,7 +3576,7 @@ index 26d5a26..71469b4 100644
 +
 +#define BM_END_OF_MAP (~0UL)
 +
-+#define BM_BITS_PER_BLOCK     (PAGE_SIZE << 3)
++#define BM_BITS_PER_BLOCK     (PAGE_SIZE * BITS_PER_BYTE)
 +
 +struct bm_block {
 +      struct list_head hook;          /* hook into a list of bitmap blocks */
@@ -3122,10 +3626,10 @@ index 26d5a26..71469b4 100644
 +      (int rw, struct toi_module_ops *owner, char *buffer, int buffer_size));
 +#endif
 diff --git a/kernel/power/process.c b/kernel/power/process.c
-index da2072d..9b31b2b 100644
+index cc2e553..5e1a845 100644
 --- a/kernel/power/process.c
 +++ b/kernel/power/process.c
-@@ -13,6 +13,13 @@
+@@ -14,6 +14,13 @@
  #include <linux/module.h>
  #include <linux/syscalls.h>
  #include <linux/freezer.h>
@@ -3139,7 +3643,7 @@ index da2072d..9b31b2b 100644
  
  /* 
   * Timeout for stopping processes
-@@ -86,7 +93,8 @@ static int try_to_freeze_tasks(bool sig_only)
+@@ -87,7 +94,8 @@ static int try_to_freeze_tasks(bool sig_only)
                do_each_thread(g, p) {
                        task_lock(p);
                        if (freezing(p) && !freezer_should_skip(p))
@@ -3149,7 +3653,7 @@ index da2072d..9b31b2b 100644
                        cancel_freezing(p);
                        task_unlock(p);
                } while_each_thread(g, p);
-@@ -106,17 +114,26 @@ int freeze_processes(void)
+@@ -107,17 +115,26 @@ int freeze_processes(void)
  {
        int error;
  
@@ -3178,7 +3682,7 @@ index da2072d..9b31b2b 100644
  
        oom_killer_disable();
   Exit:
-@@ -125,6 +142,7 @@ int freeze_processes(void)
+@@ -126,6 +143,7 @@ int freeze_processes(void)
  
        return error;
  }
@@ -3186,7 +3690,7 @@ index da2072d..9b31b2b 100644
  
  static void thaw_tasks(bool nosig_only)
  {
-@@ -148,12 +166,39 @@ static void thaw_tasks(bool nosig_only)
+@@ -149,12 +167,39 @@ static void thaw_tasks(bool nosig_only)
  
  void thaw_processes(void)
  {
@@ -3228,7 +3732,7 @@ index da2072d..9b31b2b 100644
 + */
 +EXPORT_SYMBOL_GPL(thaw_kernel_threads);
 diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
-index 523a451..ecad28d 100644
+index 36cb168..7f6da8f 100644
 --- a/kernel/power/snapshot.c
 +++ b/kernel/power/snapshot.c
 @@ -34,6 +34,8 @@
@@ -3267,7 +3771,7 @@ index 523a451..ecad28d 100644
  
 -#define BM_END_OF_MAP (~0UL)
 -
--#define BM_BITS_PER_BLOCK     (PAGE_SIZE << 3)
+-#define BM_BITS_PER_BLOCK     (PAGE_SIZE * BITS_PER_BYTE)
 -
 -struct bm_block {
 -      struct list_head hook;  /* hook into a list of bitmap blocks */
@@ -3631,7 +4135,7 @@ index 523a451..ecad28d 100644
  
  /**
   *    count_data_pages - compute the total number of saveable non-highmem
-@@ -1286,6 +1407,9 @@ asmlinkage int swsusp_save(void)
+@@ -1500,6 +1621,9 @@ asmlinkage int swsusp_save(void)
  {
        unsigned int nr_pages, nr_highmem;
  
@@ -3641,7 +4145,7 @@ index 523a451..ecad28d 100644
        printk(KERN_INFO "PM: Creating hibernation image: \n");
  
        drain_local_pages(NULL);
-@@ -1326,14 +1450,14 @@ asmlinkage int swsusp_save(void)
+@@ -1540,14 +1664,14 @@ asmlinkage int swsusp_save(void)
  }
  
  #ifndef CONFIG_ARCH_HIBERNATION_HEADER
@@ -3658,7 +4162,7 @@ index 523a451..ecad28d 100644
  {
        if (info->version_code != LINUX_VERSION_CODE)
                return "kernel version";
-@@ -1347,6 +1471,7 @@ static char *check_image_kernel(struct swsusp_info *info)
+@@ -1561,6 +1685,7 @@ static char *check_image_kernel(struct swsusp_info *info)
                return "machine";
        return NULL;
  }
@@ -3666,7 +4170,7 @@ index 523a451..ecad28d 100644
  #endif /* CONFIG_ARCH_HIBERNATION_HEADER */
  
  unsigned long snapshot_get_image_size(void)
-@@ -1354,7 +1479,7 @@ unsigned long snapshot_get_image_size(void)
+@@ -1568,7 +1693,7 @@ unsigned long snapshot_get_image_size(void)
        return nr_copy_pages + nr_meta_pages + 1;
  }
  
@@ -3675,7 +4179,7 @@ index 523a451..ecad28d 100644
  {
        memset(info, 0, sizeof(struct swsusp_info));
        info->num_physpages = num_physpages;
-@@ -1364,6 +1489,7 @@ static int init_header(struct swsusp_info *info)
+@@ -1578,6 +1703,7 @@ static int init_header(struct swsusp_info *info)
        info->size <<= PAGE_SHIFT;
        return init_header_complete(info);
  }
@@ -3697,10 +4201,10 @@ index 6f10dfc..cecd9a8 100644
   *    suspend_finish - Do final work before exiting suspend sequence.
 diff --git a/kernel/power/tuxonice.h b/kernel/power/tuxonice.h
 new file mode 100644
-index 0000000..4ed1cd4
+index 0000000..2ab1c23
 --- /dev/null
 +++ b/kernel/power/tuxonice.h
-@@ -0,0 +1,213 @@
+@@ -0,0 +1,214 @@
 +/*
 + * kernel/power/tuxonice.h
 + *
@@ -3724,7 +4228,7 @@ index 0000000..4ed1cd4
 +#include "tuxonice_pageflags.h"
 +#include "power.h"
 +
-+#define TOI_CORE_VERSION "3.0.1"
++#define TOI_CORE_VERSION "3.0.99.32"
 +
 +#define MY_BOOT_KERNEL_DATA_VERSION 1
 +
@@ -3912,14 +4416,15 @@ index 0000000..4ed1cd4
 +extern int toi_launch_userspace_program(char *command, int channel_no,
 +              enum umh_wait wait, int debug);
 +
-+extern char *tuxonice_signature;
++extern char tuxonice_signature[9];
++extern int freezer_sync;
 +#endif
 diff --git a/kernel/power/tuxonice_alloc.c b/kernel/power/tuxonice_alloc.c
 new file mode 100644
-index 0000000..0089ab8
+index 0000000..225a067
 --- /dev/null
 +++ b/kernel/power/tuxonice_alloc.c
-@@ -0,0 +1,288 @@
+@@ -0,0 +1,313 @@
 +/*
 + * kernel/power/tuxonice_alloc.c
 + *
@@ -3937,13 +4442,14 @@ index 0000000..0089ab8
 +#include "tuxonice_sysfs.h"
 +#include "tuxonice.h"
 +
-+#define TOI_ALLOC_PATHS 39
++#define TOI_ALLOC_PATHS 40
 +
 +static DEFINE_MUTEX(toi_alloc_mutex);
 +
 +static struct toi_module_ops toi_alloc_ops;
 +
 +static int toi_fail_num;
++static int trace_allocs;
 +static atomic_t toi_alloc_count[TOI_ALLOC_PATHS],
 +              toi_free_count[TOI_ALLOC_PATHS],
 +              toi_test_count[TOI_ALLOC_PATHS],
@@ -3990,7 +4496,8 @@ index 0000000..0089ab8
 +      "swap mark resume attempted buffer", /* 35 */
 +      "cluster member",
 +      "boot kernel data buffer",
-+      "setting swap signature"
++      "setting swap signature",
++      "block i/o bdev struct"
 +};
 +
 +#define MIGHT_FAIL(FAIL_NUM, FAIL_VAL) \
@@ -4015,7 +4522,7 @@ index 0000000..0089ab8
 +      if (unlikely(test_action_state(TOI_GET_MAX_MEM_ALLOCD))) {
 +              mutex_lock(&toi_alloc_mutex);
 +              toi_cur_allocd[fail_num]++;
-+              cur_allocd+= size;
++              cur_allocd += size;
 +              if (unlikely(cur_allocd > max_allocd)) {
 +                      int i;
 +
@@ -4031,9 +4538,12 @@ index 0000000..0089ab8
 +{
 +      BUG_ON(fail_num >= TOI_ALLOC_PATHS);
 +      atomic_inc(&toi_free_count[fail_num]);
++      if (unlikely(atomic_read(&toi_free_count[fail_num]) >
++                              atomic_read(&toi_alloc_count[fail_num])))
++              dump_stack();
 +      if (unlikely(test_action_state(TOI_GET_MAX_MEM_ALLOCD))) {
 +              mutex_lock(&toi_alloc_mutex);
-+              cur_allocd-= size;
++              cur_allocd -= size;
 +              toi_cur_allocd[fail_num]--;
 +              mutex_unlock(&toi_alloc_mutex);
 +      }
@@ -4048,6 +4558,8 @@ index 0000000..0089ab8
 +      result = kzalloc(size, flags);
 +      if (toi_alloc_ops.enabled)
 +              alloc_update_stats(fail_num, result, size);
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      return result;
 +}
 +EXPORT_SYMBOL_GPL(toi_kzalloc);
@@ -4063,6 +4575,8 @@ index 0000000..0089ab8
 +      if (toi_alloc_ops.enabled)
 +              alloc_update_stats(fail_num, (void *) result,
 +                              PAGE_SIZE << order);
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      return result;
 +}
 +EXPORT_SYMBOL_GPL(toi_get_free_pages);
@@ -4076,6 +4590,8 @@ index 0000000..0089ab8
 +      result = alloc_page(mask);
 +      if (toi_alloc_ops.enabled)
 +              alloc_update_stats(fail_num, (void *) result, PAGE_SIZE);
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      return result;
 +}
 +EXPORT_SYMBOL_GPL(toi_alloc_page);
@@ -4084,11 +4600,15 @@ index 0000000..0089ab8
 +{
 +      unsigned long result;
 +
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      if (toi_alloc_ops.enabled)
 +              MIGHT_FAIL(fail_num, 0);
 +      result = get_zeroed_page(mask);
 +      if (toi_alloc_ops.enabled)
 +              alloc_update_stats(fail_num, (void *) result, PAGE_SIZE);
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      return result;
 +}
 +EXPORT_SYMBOL_GPL(toi_get_zeroed_page);
@@ -4098,6 +4618,8 @@ index 0000000..0089ab8
 +      if (arg && toi_alloc_ops.enabled)
 +              free_update_stats(fail_num, size);
 +
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      kfree(arg);
 +}
 +EXPORT_SYMBOL_GPL(toi_kfree);
@@ -4107,6 +4629,8 @@ index 0000000..0089ab8
 +      if (virt && toi_alloc_ops.enabled)
 +              free_update_stats(fail_num, PAGE_SIZE);
 +
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      free_page(virt);
 +}
 +EXPORT_SYMBOL_GPL(toi_free_page);
@@ -4116,6 +4640,8 @@ index 0000000..0089ab8
 +      if (page && toi_alloc_ops.enabled)
 +              free_update_stats(fail_num, PAGE_SIZE);
 +
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      __free_page(page);
 +}
 +EXPORT_SYMBOL_GPL(toi__free_page);
@@ -4125,6 +4651,8 @@ index 0000000..0089ab8
 +      if (page && toi_alloc_ops.enabled)
 +              free_update_stats(fail_num, PAGE_SIZE << order);
 +
++      if (fail_num == trace_allocs)
++              dump_stack();
 +      __free_pages(page, order);
 +}
 +
@@ -4140,7 +4668,7 @@ index 0000000..0089ab8
 +                  atomic_read(&toi_free_count[i])) {
 +                      if (!header_done) {
 +                              printk(KERN_INFO "Idx  Allocs   Frees   Tests "
-+                                      "  Fails Max     Description\n");
++                                      "  Fails     Max Description\n");
 +                              header_done = 1;
 +                      }
 +
@@ -4159,24 +4687,27 @@ index 0000000..0089ab8
 +{
 +      int i;
 +
-+      if (starting_cycle && toi_alloc_ops.enabled) {
-+              for (i = 0; i < TOI_ALLOC_PATHS; i++) {
-+                      atomic_set(&toi_alloc_count[i], 0);
-+                      atomic_set(&toi_free_count[i], 0);
-+                      atomic_set(&toi_test_count[i], 0);
-+                      atomic_set(&toi_fail_count[i], 0);
-+                      toi_cur_allocd[i] = 0;
-+                      toi_max_allocd[i] = 0;
-+              };
-+              max_allocd = 0;
-+              cur_allocd = 0;
-+      }
++      if (!starting_cycle)
++              return 0;
++
++      for (i = 0; i < TOI_ALLOC_PATHS; i++) {
++              atomic_set(&toi_alloc_count[i], 0);
++              atomic_set(&toi_free_count[i], 0);
++              atomic_set(&toi_test_count[i], 0);
++              atomic_set(&toi_fail_count[i], 0);
++              toi_cur_allocd[i] = 0;
++              toi_max_allocd[i] = 0;
++      };
 +
++      max_allocd = 0;
++      cur_allocd = 0;
 +      return 0;
 +}
 +
 +static struct toi_sysfs_data sysfs_params[] = {
 +      SYSFS_INT("failure_test", SYSFS_RW, &toi_fail_num, 0, 99, 0, NULL),
++      SYSFS_INT("trace", SYSFS_RW, &trace_allocs, 0, TOI_ALLOC_PATHS, 0,
++                      NULL),
 +      SYSFS_BIT("find_max_mem_allocated", SYSFS_RW, &toi_bkd.toi_action,
 +                      TOI_GET_MAX_MEM_ALLOCD, 0),
 +      SYSFS_INT("enabled", SYSFS_RW, &toi_alloc_ops.enabled, 0, 1, 0,
@@ -4199,7 +4730,6 @@ index 0000000..0089ab8
 +int toi_alloc_init(void)
 +{
 +      int result = toi_register_module(&toi_alloc_ops);
-+      toi_alloc_ops.enabled = 0;
 +      return result;
 +}
 +
@@ -4713,609 +5243,844 @@ index 0000000..a428f4c
 +
 +int toi_go_atomic(pm_message_t state, int toi_time);
 +void toi_end_atomic(int stage, int toi_time, int error);
-diff --git a/kernel/power/tuxonice_block_io.c b/kernel/power/tuxonice_block_io.c
+diff --git a/kernel/power/tuxonice_bio.h b/kernel/power/tuxonice_bio.h
 new file mode 100644
-index 0000000..aa7a9cd
+index 0000000..9b770d6
 --- /dev/null
-+++ b/kernel/power/tuxonice_block_io.c
-@@ -0,0 +1,1343 @@
++++ b/kernel/power/tuxonice_bio.h
+@@ -0,0 +1,76 @@
 +/*
-+ * kernel/power/tuxonice_block_io.c
++ * kernel/power/tuxonice_bio.h
 + *
 + * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
++ * Copyright (C) 2006 Red Hat, inc.
 + *
 + * Distributed under GPLv2.
 + *
-+ * This file contains block io functions for TuxOnIce. These are
-+ * used by the swapwriter and it is planned that they will also
-+ * be used by the NFSwriter.
-+ *
++ * This file contains declarations for functions exported from
++ * tuxonice_bio.c, which contains low level io functions.
 + */
 +
-+#include <linux/blkdev.h>
-+#include <linux/syscalls.h>
-+#include <linux/suspend.h>
++#include <linux/buffer_head.h>
++#include "tuxonice_extent.h"
 +
-+#include "tuxonice.h"
-+#include "tuxonice_sysfs.h"
-+#include "tuxonice_modules.h"
-+#include "tuxonice_prepare_image.h"
-+#include "tuxonice_block_io.h"
-+#include "tuxonice_ui.h"
-+#include "tuxonice_alloc.h"
-+#include "tuxonice_io.h"
++void toi_put_extent_chain(struct hibernate_extent_chain *chain);
++int toi_add_to_extent_chain(struct hibernate_extent_chain *chain,
++              unsigned long start, unsigned long end);
 +
-+#define MEMORY_ONLY 1
-+#define THROTTLE_WAIT 2
++struct hibernate_extent_saved_state {
++      int extent_num;
++      struct hibernate_extent *extent_ptr;
++      unsigned long offset;
++};
 +
-+/* #define MEASURE_MUTEX_CONTENTION */
-+#ifndef MEASURE_MUTEX_CONTENTION
-+#define my_mutex_lock(index, the_lock) mutex_lock(the_lock)
-+#define my_mutex_unlock(index, the_lock) mutex_unlock(the_lock)
-+#else
-+unsigned long mutex_times[2][2][NR_CPUS];
-+#define my_mutex_lock(index, the_lock) do { \
-+      int have_mutex; \
-+      have_mutex = mutex_trylock(the_lock); \
-+      if (!have_mutex) { \
-+              mutex_lock(the_lock); \
-+              mutex_times[index][0][smp_processor_id()]++; \
-+      } else { \
-+              mutex_times[index][1][smp_processor_id()]++; \
-+      }
++struct toi_bdev_info {
++      struct toi_bdev_info *next;
++      struct hibernate_extent_chain blocks;
++      struct block_device *bdev;
++      struct toi_module_ops *allocator;
++      int allocator_index;
++      struct hibernate_extent_chain allocations;
 +
-+#define my_mutex_unlock(index, the_lock) \
-+      mutex_unlock(the_lock); \
-+} while (0)
-+#endif
++      /* Saved in header */
++      char uuid[17];
++      dev_t dev_t;
++      int prio;
++      int bmap_shift;
++      int blocks_per_page;
++      struct hibernate_extent_saved_state saved_state[4];
++};
 +
-+static int target_outstanding_io = 1024;
-+static int max_outstanding_writes, max_outstanding_reads;
++struct toi_extent_iterate_state {
++      struct toi_bdev_info *current_chain;
++      int num_chains;
++      int saved_chain_number[4];
++      struct toi_bdev_info *saved_chain_ptr[4];
++};
 +
-+static struct page *bio_queue_head, *bio_queue_tail;
-+static atomic_t toi_bio_queue_size;
-+static DEFINE_SPINLOCK(bio_queue_lock);
++/*
++ * Our exported interface so the swapwriter and filewriter don't
++ * need these functions duplicated.
++ */
++struct toi_bio_ops {
++      int (*bdev_page_io) (int rw, struct block_device *bdev, long pos,
++                      struct page *page);
++      int (*register_storage)(struct toi_bdev_info *new);
++      void (*free_storage)(void);
++};
 +
-+static int free_mem_throttle, throughput_throttle;
-+static int more_readahead = 1;
-+static struct page *readahead_list_head, *readahead_list_tail;
++struct toi_allocator_ops {
++      unsigned long (*toi_swap_storage_available) (void);
++};
 +
-+static struct page *waiting_on;
++extern struct toi_bio_ops toi_bio_ops;
 +
-+static atomic_t toi_io_in_progress, toi_io_done;
-+static DECLARE_WAIT_QUEUE_HEAD(num_in_progress_wait);
++extern char *toi_writer_buffer;
++extern int toi_writer_buffer_posn;
++
++struct toi_bio_allocator_ops {
++      int (*register_storage) (void);
++      unsigned long (*storage_available)(void);
++      int (*allocate_storage) (struct toi_bdev_info *, unsigned long);
++      int (*bmap) (struct toi_bdev_info *);
++      void (*free_storage) (struct toi_bdev_info *);
++};
+diff --git a/kernel/power/tuxonice_bio_chains.c b/kernel/power/tuxonice_bio_chains.c
+new file mode 100644
+index 0000000..daddd65
+--- /dev/null
++++ b/kernel/power/tuxonice_bio_chains.c
+@@ -0,0 +1,961 @@
++/*
++ * kernel/power/tuxonice_bio_devinfo.c
++ *
++ * Copyright (C) 2009 Nigel Cunningham (nigel at tuxonice net)
++ *
++ * Distributed under GPLv2.
++ *
++ */
 +
-+static int extra_page_forward;
++#include <linux/mm_types.h>
++#include "tuxonice_bio.h"
++#include "tuxonice_bio_internal.h"
++#include "tuxonice_alloc.h"
++#include "tuxonice_ui.h"
++#include "tuxonice.h"
++#include "tuxonice_io.h"
 +
-+static int current_stream;
-+/* 0 = Header, 1 = Pageset1, 2 = Pageset2, 3 = End of PS1 */
-+struct hibernate_extent_iterate_saved_state toi_writer_posn_save[4];
-+EXPORT_SYMBOL_GPL(toi_writer_posn_save);
++static struct toi_bdev_info *prio_chain_head;
++static int num_chains;
 +
 +/* Pointer to current entry being loaded/saved. */
 +struct toi_extent_iterate_state toi_writer_posn;
-+EXPORT_SYMBOL_GPL(toi_writer_posn);
 +
-+/* Not static, so that the allocators can setup and complete
-+ * writing the header */
-+char *toi_writer_buffer;
-+EXPORT_SYMBOL_GPL(toi_writer_buffer);
++#define metadata_size (sizeof(struct toi_bdev_info) - \
++              offsetof(struct toi_bdev_info, uuid))
 +
-+int toi_writer_buffer_posn;
-+EXPORT_SYMBOL_GPL(toi_writer_buffer_posn);
++/*
++ * After section 0 (header) comes 2 => next_section[0] = 2
++ */
++static int next_section[3] = { 2, 3, 1 };
++
++/**
++ * dump_block_chains - print the contents of the bdev info array.
++ **/
++void dump_block_chains(void)
++{
++      int i = 0;
++      int j;
++      struct toi_bdev_info *cur_chain = prio_chain_head;
 +
-+static struct toi_bdev_info *toi_devinfo;
++      while (cur_chain) {
++              struct hibernate_extent *this = cur_chain->blocks.first;
 +
-+static DEFINE_MUTEX(toi_bio_mutex);
-+static DEFINE_MUTEX(toi_bio_readahead_mutex);
++              printk(KERN_DEBUG "Chain %d (prio %d):", i, cur_chain->prio);
 +
-+static struct task_struct *toi_queue_flusher;
-+static int toi_bio_queue_flush_pages(int dedicated_thread);
++              while (this) {
++                      printk(KERN_CONT " [%lu-%lu]%s", this->start,
++                                      this->end, this->next ? "," : "");
++                      this = this->next;
++              }
 +
-+#define TOTAL_OUTSTANDING_IO (atomic_read(&toi_io_in_progress) + \
-+             atomic_read(&toi_bio_queue_size))
++              printk("\n");
++              cur_chain = cur_chain->next;
++      }
++
++      printk(KERN_DEBUG "Saved states:\n");
++      for (i = 0; i < 4; i++) {
++              printk(KERN_DEBUG "Slot %d: Chain %d.\n",
++                      i, toi_writer_posn.saved_chain_number[i]);
++
++              cur_chain = prio_chain_head;
++              j = 0;
++              while (cur_chain) {
++                      printk(KERN_DEBUG " Chain %d: Extent %d. Offset %lu.\n",
++                                      j, cur_chain->saved_state[i].extent_num,
++                                      cur_chain->saved_state[i].offset);
++                      cur_chain = cur_chain->next;
++                      j++;
++              }
++              printk(KERN_CONT "\n");
++      }
++}
 +
 +/**
-+ * set_free_mem_throttle - set the point where we pause to avoid oom.
 + *
-+ * Initially, this value is zero, but when we first fail to allocate memory,
-+ * we set it (plus a buffer) and thereafter throttle i/o once that limit is
-+ * reached.
 + **/
-+static void set_free_mem_throttle(void)
++static void toi_extent_chain_next(void)
 +{
-+      int new_throttle = nr_unallocated_buffer_pages() + 256;
++      struct toi_bdev_info *this = toi_writer_posn.current_chain;
 +
-+      if (new_throttle > free_mem_throttle)
-+              free_mem_throttle = new_throttle;
-+}
++      if (!this->blocks.current_extent)
++              return;
 +
-+#define NUM_REASONS 7
-+static atomic_t reasons[NUM_REASONS];
-+static char *reason_name[NUM_REASONS] = {
-+      "readahead not ready",
-+      "bio allocation",
-+      "synchronous I/O",
-+      "toi_bio_get_new_page",
-+      "memory low",
-+      "readahead buffer allocation",
-+      "throughput_throttle",
-+};
++      if (this->blocks.current_offset == this->blocks.current_extent->end) {
++              if (this->blocks.current_extent->next) {
++                      this->blocks.current_extent =
++                              this->blocks.current_extent->next;
++                      this->blocks.current_offset =
++                              this->blocks.current_extent->start;
++              } else {
++                      this->blocks.current_extent = NULL;
++                      this->blocks.current_offset = 0;
++              }
++      } else
++              this->blocks.current_offset++;
++}
 +
 +/**
-+ * do_bio_wait - wait for some TuxOnIce I/O to complete
-+ * @reason: The array index of the reason we're waiting.
-+ *
-+ * Wait for a particular page of I/O if we're after a particular page.
-+ * If we're not after a particular page, wait instead for all in flight
-+ * I/O to be completed or for us to have enough free memory to be able
-+ * to submit more I/O.
 + *
-+ * If we wait, we also update our statistics regarding why we waited.
-+ **/
-+static void do_bio_wait(int reason)
++ */
++
++static struct toi_bdev_info *__find_next_chain_same_prio(void)
 +{
-+      struct page *was_waiting_on = waiting_on;
++      struct toi_bdev_info *start_chain = toi_writer_posn.current_chain;
++      struct toi_bdev_info *this = start_chain;
++      int orig_prio = this->prio;
 +
-+      /* On SMP, waiting_on can be reset, so we make a copy */
-+      if (was_waiting_on) {
-+              if (PageLocked(was_waiting_on)) {
-+                      wait_on_page_bit(was_waiting_on, PG_locked);
-+                      atomic_inc(&reasons[reason]);
-+              }
-+      } else {
-+              atomic_inc(&reasons[reason]);
++      do {
++              this = this->next;
 +
-+              wait_event(num_in_progress_wait,
-+                      !atomic_read(&toi_io_in_progress) ||
-+                      nr_unallocated_buffer_pages() > free_mem_throttle);
-+      }
++              if (!this)
++                      this = prio_chain_head;
++
++              /* Back on original chain? Use it again. */
++              if (this == start_chain)
++                      return start_chain;
++
++      } while (!this->blocks.current_extent || this->prio != orig_prio);
++
++      return this;
 +}
 +
-+/**
-+ * throttle_if_needed - wait for I/O completion if throttle points are reached
-+ * @flags: What to check and how to act.
-+ *
-+ * Check whether we need to wait for some I/O to complete. We always check
-+ * whether we have enough memory available, but may also (depending upon
-+ * @reason) check if the throughput throttle limit has been reached.
-+ **/
-+static int throttle_if_needed(int flags)
++static void find_next_chain(void)
 +{
-+      int free_pages = nr_unallocated_buffer_pages();
++      struct toi_bdev_info *this;
 +
-+      /* Getting low on memory and I/O is in progress? */
-+      while (unlikely(free_pages < free_mem_throttle) &&
-+                      atomic_read(&toi_io_in_progress)) {
-+              if (!(flags & THROTTLE_WAIT))
-+                      return -ENOMEM;
-+              do_bio_wait(4);
-+              free_pages = nr_unallocated_buffer_pages();
-+      }
++      this = __find_next_chain_same_prio();
 +
-+      while (!(flags & MEMORY_ONLY) && throughput_throttle &&
-+              TOTAL_OUTSTANDING_IO >= throughput_throttle) {
-+              int result = toi_bio_queue_flush_pages(0);
-+              if (result)
-+                      return result;
-+              atomic_inc(&reasons[6]);
-+              wait_event(num_in_progress_wait,
-+                      !atomic_read(&toi_io_in_progress) ||
-+                      TOTAL_OUTSTANDING_IO < throughput_throttle);
-+      }
++      /*
++       * If we didn't get another chain of the same priority that we
++       * can use, look for the next priority.
++       */
++      while (this && !this->blocks.current_extent)
++              this = this->next;
 +
-+      return 0;
++      toi_writer_posn.current_chain = this;
 +}
 +
 +/**
-+ * update_throughput_throttle - update the raw throughput throttle
-+ * @jif_index: The number of times this function has been called.
-+ *
-+ * This function is called twice per second by the core, and used to limit the
-+ * amount of I/O we submit at once, spreading out our waiting through the
-+ * whole job and letting userui get an opportunity to do its work.
++ * toi_extent_state_next - go to the next extent
++ * @blocks: The number of values to progress.
++ * @stripe_mode: Whether to spread usage across all chains.
 + *
-+ * We don't start limiting I/O until 1/2s has gone so that we get a
-+ * decent sample for our initial limit, and keep updating it because
-+ * throughput may vary (on rotating media, eg) with our block number.
++ * Given a state, progress to the next valid entry. We may begin in an
++ * invalid state, as we do when invoked after extent_state_goto_start below.
 + *
-+ * We throttle to 1/10s worth of I/O.
++ * When using compression and expected_compression > 0, we let the image size
++ * be larger than storage, so we can validly run out of data to return.
 + **/
-+static void update_throughput_throttle(int jif_index)
++static unsigned long toi_extent_state_next(int blocks, int current_stream)
 +{
-+      int done = atomic_read(&toi_io_done);
-+      throughput_throttle = done / jif_index / 5;
++      int i;
++
++      if (!toi_writer_posn.current_chain)
++              return -ENODATA;
++
++      /* Assume chains always have lengths that are multiples of @blocks */
++      for (i = 0; i < blocks; i++)
++              toi_extent_chain_next();
++
++      /* The header stream is not striped */
++      if (current_stream ||
++          !toi_writer_posn.current_chain->blocks.current_extent)
++              find_next_chain();
++
++      return  toi_writer_posn.current_chain ? 0 : -ENODATA;
++}
++
++static void toi_insert_chain_in_prio_list(struct toi_bdev_info *this)
++{
++      struct toi_bdev_info **prev_ptr;
++      struct toi_bdev_info *cur;
++
++      /* Loop through the existing chain, finding where to insert it */
++      prev_ptr = &prio_chain_head;
++      cur = prio_chain_head;
++
++      while (cur && cur->prio >= this->prio) {
++              prev_ptr = &cur->next;
++              cur = cur->next;
++      }
++
++      this->next = *prev_ptr;
++      *prev_ptr = this;
++
++      this = prio_chain_head;
++      while (this)
++              this = this->next;
++      num_chains++;
 +}
 +
 +/**
-+ * toi_finish_all_io - wait for all outstanding i/o to complete
-+ *
-+ * Flush any queued but unsubmitted I/O and wait for it all to complete.
++ * toi_extent_state_goto_start - reinitialize an extent chain iterator
++ * @state:    Iterator to reinitialize
 + **/
-+static int toi_finish_all_io(void)
++void toi_extent_state_goto_start(void)
 +{
-+      int result = toi_bio_queue_flush_pages(0);
-+      wait_event(num_in_progress_wait, !TOTAL_OUTSTANDING_IO);
-+      return result;
++      struct toi_bdev_info *this = prio_chain_head;
++
++      while (this) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0,
++                      "Setting current extent to %p.", this->blocks.first);
++              this->blocks.current_extent = this->blocks.first;
++              if (this->blocks.current_extent) {
++                      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                                      "Setting current offset to %lu.",
++                                      this->blocks.current_extent->start);
++                      this->blocks.current_offset =
++                              this->blocks.current_extent->start;
++              }
++
++              this = this->next;
++      }
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Setting current chain to %p.",
++                      prio_chain_head);
++      toi_writer_posn.current_chain = prio_chain_head;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Leaving extent state goto start.");
 +}
 +
 +/**
-+ * toi_end_bio - bio completion function.
-+ * @bio: bio that has completed.
-+ * @err: Error value. Yes, like end_swap_bio_read, we ignore it.
++ * toi_extent_state_save - save state of the iterator
++ * @state:            Current state of the chain
++ * @saved_state:      Iterator to populate
 + *
-+ * Function called by the block driver from interrupt context when I/O is
-+ * completed. If we were writing the page, we want to free it and will have
-+ * set bio->bi_private to the parameter we should use in telling the page
-+ * allocation accounting code what the page was allocated for. If we're
-+ * reading the page, it will be in the singly linked list made from
-+ * page->private pointers.
++ * Given a state and a struct hibernate_extent_state_store, save the current
++ * position in a format that can be used with relocated chains (at
++ * resume time).
 + **/
-+static void toi_end_bio(struct bio *bio, int err)
++void toi_extent_state_save(int slot)
 +{
-+      struct page *page = bio->bi_io_vec[0].bv_page;
++      struct toi_bdev_info *cur_chain = prio_chain_head;
++      struct hibernate_extent *extent;
++      struct hibernate_extent_saved_state *chain_state;
++      int i = 0;
 +
-+      BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_extent_state_save, slot %d.",
++                      slot);
 +
-+      unlock_page(page);
-+      bio_put(bio);
++      if (!toi_writer_posn.current_chain) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "No current chain => "
++                              "chain_num = -1.");
++              toi_writer_posn.saved_chain_number[slot] = -1;
++              return;
++      }
 +
-+      if (waiting_on == page)
-+              waiting_on = NULL;
++      while (cur_chain) {
++              i++;
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Saving chain %d (%p) "
++                              "state, slot %d.", i, cur_chain, slot);
 +
-+      put_page(page);
++              chain_state = &cur_chain->saved_state[slot];
 +
-+      if (bio->bi_private)
-+              toi__free_page((int) ((unsigned long) bio->bi_private) , page);
++              chain_state->offset = cur_chain->blocks.current_offset;
 +
-+      bio_put(bio);
++              if (toi_writer_posn.current_chain == cur_chain) {
++                      toi_writer_posn.saved_chain_number[slot] = i;
++                      toi_message(TOI_IO, TOI_VERBOSE, 0, "This is the chain "
++                                      "we were on => chain_num is %d.", i);
++              }
 +
-+      atomic_dec(&toi_io_in_progress);
-+      atomic_inc(&toi_io_done);
++              if (!cur_chain->blocks.current_extent) {
++                      chain_state->extent_num = 0;
++                      toi_message(TOI_IO, TOI_VERBOSE, 0, "No current extent "
++                                      "for this chain => extent_num %d is 0.",
++                                      i);
++                      cur_chain = cur_chain->next;
++                      continue;
++              }
 +
-+      wake_up(&num_in_progress_wait);
++              extent = cur_chain->blocks.first;
++              chain_state->extent_num = 1;
++
++              while (extent != cur_chain->blocks.current_extent) {
++                      chain_state->extent_num++;
++                      extent = extent->next;
++              }
++
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "extent num %d is %d.", i,
++                              chain_state->extent_num);
++
++              cur_chain = cur_chain->next;
++      }
++      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                      "Completed saving extent state slot %d.", slot);
 +}
 +
 +/**
-+ * submit - submit BIO request
-+ * @writing: READ or WRITE.
-+ * @dev: The block device we're using.
-+ * @first_block: The first sector we're using.
-+ * @page: The page being used for I/O.
-+ * @free_group: If writing, the group that was used in allocating the page
-+ *    and which will be used in freeing the page from the completion
-+ *    routine.
-+ *
-+ * Based on Patrick Mochell's pmdisk code from long ago: "Straight from the
-+ * textbook - allocate and initialize the bio. If we're writing, make sure
-+ * the page is marked as dirty. Then submit it and carry on."
-+ *
-+ * If we're just testing the speed of our own code, we fake having done all
-+ * the hard work and all toi_end_bio immediately.
++ * toi_extent_state_restore - restore the position saved by extent_state_save
++ * @state:            State to populate
++ * @saved_state:      Iterator saved to restore
 + **/
-+static int submit(int writing, struct block_device *dev, sector_t first_block,
-+              struct page *page, int free_group)
++void toi_extent_state_restore(int slot)
 +{
-+      struct bio *bio = NULL;
-+      int cur_outstanding_io, result;
++      int i = 0;
++      struct toi_bdev_info *cur_chain = prio_chain_head;
++      struct hibernate_extent_saved_state *chain_state;
 +
-+      /*
-+       * Shouldn't throttle if reading - can deadlock in the single
-+       * threaded case as pages are only freed when we use the
-+       * readahead.
-+       */
-+      if (writing) {
-+              result = throttle_if_needed(MEMORY_ONLY | THROTTLE_WAIT);
-+              if (result)
-+                      return result;
-+      }
++      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                      "toi_extent_state_restore - slot %d.", slot);
 +
-+      while (!bio) {
-+              bio = bio_alloc(TOI_ATOMIC_GFP, 1);
-+              if (!bio) {
-+                      set_free_mem_throttle();
-+                      do_bio_wait(1);
-+              }
++      if (toi_writer_posn.saved_chain_number[slot] == -1) {
++              toi_writer_posn.current_chain = NULL;
++              return;
 +      }
 +
-+      bio->bi_bdev = dev;
-+      bio->bi_sector = first_block;
-+      bio->bi_private = (void *) ((unsigned long) free_group);
-+      bio->bi_end_io = toi_end_bio;
++      while (cur_chain) {
++              int posn;
++              int j;
++              i++;
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Restoring chain %d (%p) "
++                              "state, slot %d.", i, cur_chain, slot);
 +
-+      if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
-+              printk(KERN_DEBUG "ERROR: adding page to bio at %lld\n",
-+                              (unsigned long long) first_block);
-+              bio_put(bio);
-+              return -EFAULT;
-+      }
++              chain_state = &cur_chain->saved_state[slot];
 +
-+      bio_get(bio);
++              posn = chain_state->extent_num;
 +
-+      cur_outstanding_io = atomic_add_return(1, &toi_io_in_progress);
-+      if (writing) {
-+              if (cur_outstanding_io > max_outstanding_writes)
-+                      max_outstanding_writes = cur_outstanding_io;
-+      } else {
-+              if (cur_outstanding_io > max_outstanding_reads)
-+                      max_outstanding_reads = cur_outstanding_io;
-+      }
++              cur_chain->blocks.current_extent = cur_chain->blocks.first;
++              cur_chain->blocks.current_offset = chain_state->offset;
 +
++              if (i == toi_writer_posn.saved_chain_number[slot]) {
++                      toi_writer_posn.current_chain = cur_chain;
++                      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                                      "Found current chain.");
++              }
 +
-+      if (unlikely(test_action_state(TOI_TEST_FILTER_SPEED))) {
-+              /* Fake having done the hard work */
-+              set_bit(BIO_UPTODATE, &bio->bi_flags);
-+              toi_end_bio(bio, 0);
-+      } else
-+              submit_bio(writing | (1 << BIO_RW_SYNCIO) |
-+                              (1 << BIO_RW_UNPLUG), bio);
++              for (j = 0; j < 4; j++)
++                      if (i == toi_writer_posn.saved_chain_number[j]) {
++                              toi_writer_posn.saved_chain_ptr[j] = cur_chain;
++                              toi_message(TOI_IO, TOI_VERBOSE, 0,
++                                      "Found saved chain ptr %d (%p) (offset"
++                                      " %d).", j, cur_chain,
++                                      cur_chain->saved_state[j].offset);
++                      }
 +
-+      return 0;
++              if (posn) {
++                      while (--posn)
++                              cur_chain->blocks.current_extent =
++                                      cur_chain->blocks.current_extent->next;
++              } else
++                      cur_chain->blocks.current_extent = NULL;
++
++              cur_chain = cur_chain->next;
++      }
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Done.");
++      if (test_action_state(TOI_LOGALL))
++              dump_block_chains();
 +}
 +
-+/**
-+ * toi_do_io: Prepare to do some i/o on a page and submit or batch it.
-+ *
-+ * @writing: Whether reading or writing.
-+ * @bdev: The block device which we're using.
-+ * @block0: The first sector we're reading or writing.
-+ * @page: The page on which I/O is being done.
-+ * @readahead_index: If doing readahead, the index (reset this flag when done).
-+ * @syncio: Whether the i/o is being done synchronously.
-+ *
-+ * Prepare and start a read or write operation.
++/*
++ * Storage needed
 + *
-+ * Note that we always work with our own page. If writing, we might be given a
-+ * compression buffer that will immediately be used to start compressing the
-+ * next page. For reading, we do readahead and therefore don't know the final
-+ * address where the data needs to go.
-+ **/
-+static int toi_do_io(int writing, struct block_device *bdev, long block0,
-+      struct page *page, int is_readahead, int syncio, int free_group)
++ * Returns amount of space in the image header required
++ * for the chain data. This ignores the links between
++ * pages, which we factor in when allocating the space.
++ */
++int toi_bio_devinfo_storage_needed(void)
 +{
-+      page->private = 0;
-+
-+      /* Do here so we don't race against toi_bio_get_next_page_read */
-+      lock_page(page);
-+
-+      if (is_readahead) {
-+              if (readahead_list_head)
-+                      readahead_list_tail->private = (unsigned long) page;
-+              else
-+                      readahead_list_head = page;
-+
-+              readahead_list_tail = page;
-+      }
-+
-+      /* Done before submitting to avoid races. */
-+      if (syncio)
-+              waiting_on = page;
++      int result = sizeof(num_chains);
++      struct toi_bdev_info *chain = prio_chain_head;
 +
-+      /* Submit the page */
-+      get_page(page);
++      while (chain) {
++              result += metadata_size;
 +
-+      if (submit(writing, bdev, block0, page, free_group))
-+              return -EFAULT;
++              /* Chain size */
++              result += sizeof(int);
 +
-+      if (syncio)
-+              do_bio_wait(2);
++              /* Extents */
++              result += (2 * sizeof(unsigned long) *
++                      chain->blocks.num_extents);
 +
-+      return 0;
-+}
++              chain = chain->next;
++      }
 +
-+/**
-+ * toi_bdev_page_io - simpler interface to do directly i/o on a single page
-+ * @writing: Whether reading or writing.
-+ * @bdev: Block device on which we're operating.
-+ * @pos: Sector at which page to read or write starts.
-+ * @page: Page to be read/written.
-+ *
-+ * A simple interface to submit a page of I/O and wait for its completion.
-+ * The caller must free the page used.
-+ **/
-+static int toi_bdev_page_io(int writing, struct block_device *bdev,
-+              long pos, struct page *page)
-+{
-+      return toi_do_io(writing, bdev, pos, page, 0, 1, 0);
++      result += 4 * sizeof(int);
++      return result;
 +}
 +
 +/**
-+ * toi_bio_memory_needed - report the amount of memory needed for block i/o
-+ *
-+ * We want to have at least enough memory so as to have target_outstanding_io
-+ * or more transactions on the fly at once. If we can do more, fine.
++ * toi_serialise_extent_chain - write a chain in the image
++ * @chain:    Chain to write.
 + **/
-+static int toi_bio_memory_needed(void)
++static int toi_serialise_extent_chain(struct toi_bdev_info *chain)
 +{
-+      return target_outstanding_io * (PAGE_SIZE + sizeof(struct request) +
-+                              sizeof(struct bio));
-+}
++      struct hibernate_extent *this;
++      int ret;
++      int i = 1;
 +
-+/**
-+ * toi_bio_print_debug_stats - put out debugging info in the buffer provided
-+ * @buffer: A buffer of size @size into which text should be placed.
-+ * @size: The size of @buffer.
-+ *
-+ * Fill a buffer with debugging info. This is used for both our debug_info sysfs
-+ * entry and for recording the same info in dmesg.
-+ **/
-+static int toi_bio_print_debug_stats(char *buffer, int size)
-+{
-+      int len = scnprintf(buffer, size, "- Max outstanding reads %d. Max "
-+                      "writes %d.\n", max_outstanding_reads,
-+                      max_outstanding_writes);
++      if (test_action_state(TOI_LOGALL))
++              dump_block_chains();
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Serialising chain (dev_t %lx).",
++                      chain->dev_t);
++      /* Device info -  dev_t, prio, bmap_shift, blocks per page, positions */
++      ret = toiActiveAllocator->rw_header_chunk(WRITE, &toi_blockwriter_ops,
++                      (char *) &chain->uuid, metadata_size);
++      if (ret)
++              return ret;
 +
-+      len += scnprintf(buffer + len, size - len,
-+              "  Memory_needed: %d x (%lu + %u + %u) = %d bytes.\n",
-+              target_outstanding_io,
-+              PAGE_SIZE, (unsigned int) sizeof(struct request),
-+              (unsigned int) sizeof(struct bio), toi_bio_memory_needed());
++      /* Num extents */
++      ret = toiActiveAllocator->rw_header_chunk(WRITE, &toi_blockwriter_ops,
++                      (char *) &chain->blocks.num_extents, sizeof(int));
++      if (ret)
++              return ret;
 +
-+#ifdef MEASURE_MUTEX_CONTENTION
-+      {
-+      int i;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "%d extents.",
++                      chain->blocks.num_extents);
 +
-+      len += scnprintf(buffer + len, size - len,
-+              "  Mutex contention while reading:\n  Contended      Free\n");
++      this = chain->blocks.first;
++      while (this) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Extent %d.", i);
++              ret = toiActiveAllocator->rw_header_chunk(WRITE,
++                              &toi_blockwriter_ops,
++                              (char *) this, 2 * sizeof(this->start));
++              if (ret)
++                      return ret;
++              this = this->next;
++              i++;
++      }
 +
-+      for_each_online_cpu(i)
-+              len += scnprintf(buffer + len, size - len,
-+              "  %9lu %9lu\n",
-+              mutex_times[0][0][i], mutex_times[0][1][i]);
++      return ret;
++}
 +
-+      len += scnprintf(buffer + len, size - len,
-+              "  Mutex contention while writing:\n  Contended      Free\n");
++int toi_serialise_extent_chains(void)
++{
++      struct toi_bdev_info *this = prio_chain_head;
++      int result;
 +
-+      for_each_online_cpu(i)
-+              len += scnprintf(buffer + len, size - len,
-+              "  %9lu %9lu\n",
-+              mutex_times[1][0][i], mutex_times[1][1][i]);
++      /* Write the number of chains */
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Write number of chains (%d)",
++                      num_chains);
++      result = toiActiveAllocator->rw_header_chunk(WRITE,
++                      &toi_blockwriter_ops, (char *) &num_chains,
++                      sizeof(int));
++      if (result)
++              return result;
 +
++      /* Then the chains themselves */
++      while (this) {
++              result = toi_serialise_extent_chain(this);
++              if (result)
++                      return result;
++              this = this->next;
 +      }
-+#endif
 +
-+      return len + scnprintf(buffer + len, size - len,
-+              "  Free mem throttle point reached %d.\n", free_mem_throttle);
++      /*
++       * Finally, the chain we should be on at the start of each
++       * section.
++       */
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Saved chain numbers.");
++      result = toiActiveAllocator->rw_header_chunk(WRITE,
++                      &toi_blockwriter_ops,
++                      (char *) &toi_writer_posn.saved_chain_number[0],
++                      4 * sizeof(int));
++
++      return result;
 +}
 +
-+/**
-+ * toi_set_devinfo - set the bdev info used for i/o
-+ * @info: Pointer to an array of struct toi_bdev_info - the list of
-+ * bdevs and blocks on them in which the image is stored.
-+ *
-+ * Set the list of bdevs and blocks in which the image will be stored.
-+ * Think of them (all together) as one long tape on which the data will be
-+ * stored.
-+ **/
-+static void toi_set_devinfo(struct toi_bdev_info *info)
++int toi_register_storage_chain(struct toi_bdev_info *new)
 +{
-+      toi_devinfo = info;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Inserting chain %p into list.",
++                      new);
++      toi_insert_chain_in_prio_list(new);
++      return 0;
 +}
 +
-+/**
-+ * dump_block_chains - print the contents of the bdev info array.
-+ **/
-+static void dump_block_chains(void)
++static void free_bdev_info(struct toi_bdev_info *chain)
 +{
-+      int i;
-+
-+      for (i = 0; i < toi_writer_posn.num_chains; i++) {
-+              struct hibernate_extent *this;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Free chain %p.", chain);
 +
-+              this = (toi_writer_posn.chains + i)->first;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, " - Block extents.");
++      toi_put_extent_chain(&chain->blocks);
 +
-+              if (!this)
-+                      continue;
++      /*
++       * The allocator may need to do more than just free the chains
++       * (swap_free, for example).
++       */
++      toi_message(TOI_IO, TOI_VERBOSE, 0, " - Allocator extents.");
++      chain->allocator->bio_allocator_ops->free_storage(chain);
 +
-+              printk(KERN_DEBUG "Chain %d:", i);
++      /*
++       * Dropping out of reading atomic copy? Need to undo
++       * toi_open_by_devnum.
++       */
++      toi_message(TOI_IO, TOI_VERBOSE, 0, " - Bdev.");
++      if (chain->bdev && !IS_ERR(chain->bdev) &&
++                      chain->bdev != resume_block_device &&
++                      chain->bdev != header_block_device &&
++                      test_toi_state(TOI_TRYING_TO_RESUME))
++              toi_close_bdev(chain->bdev);
 +
-+              while (this) {
-+                      printk(" [%lu-%lu]%s", this->start,
-+                                      this->end, this->next ? "," : "");
-+                      this = this->next;
-+              }
++      /* Poison */
++      toi_message(TOI_IO, TOI_VERBOSE, 0, " - Struct.");
++      toi_kfree(39, chain, sizeof(*chain));
 +
-+              printk("\n");
-+      }
++      if (prio_chain_head == chain)
++              prio_chain_head = NULL;
 +
-+      for (i = 0; i < 4; i++)
-+              printk(KERN_DEBUG "Posn %d: Chain %d, extent %d, offset %lu.\n",
-+                              i, toi_writer_posn_save[i].chain_num,
-+                              toi_writer_posn_save[i].extent_num,
-+                              toi_writer_posn_save[i].offset);
++      num_chains--;
 +}
 +
-+static int total_header_bytes;
-+static int unowned;
-+
-+static int debug_broken_header(void)
++void free_all_bdev_info(void)
 +{
-+      printk(KERN_DEBUG "Image header too big for size allocated!\n");
-+      print_toi_header_storage_for_modules();
-+      printk(KERN_DEBUG "Page flags : %d.\n", toi_pageflags_space_needed());
-+      printk(KERN_DEBUG "toi_header : %ld.\n", sizeof(struct toi_header));
-+      printk(KERN_DEBUG "Total unowned : %d.\n", unowned);
-+      printk(KERN_DEBUG "Total used : %d (%ld pages).\n", total_header_bytes,
-+                      DIV_ROUND_UP(total_header_bytes, PAGE_SIZE));
-+      printk(KERN_DEBUG "Space needed now : %ld.\n",
-+                      get_header_storage_needed());
-+      dump_block_chains();
-+      abort_hibernate(TOI_HEADER_TOO_BIG, "Header reservation too small.");
-+      return -EIO;
++      struct toi_bdev_info *this = prio_chain_head;
++
++      while (this) {
++              struct toi_bdev_info *next = this->next;
++              free_bdev_info(this);
++              this = next;
++      }
++
++      memset((char *) &toi_writer_posn, 0, sizeof(toi_writer_posn));
++      prio_chain_head = NULL;
 +}
 +
 +/**
-+ * go_next_page - skip blocks to the start of the next page
-+ * @writing: Whether we're reading or writing the image.
++ * toi_load_extent_chain - read back a chain saved in the image
++ * @chain:    Chain to load
 + *
-+ * Go forward one page, or two if extra_page_forward is set. It only gets
-+ * set at the start of reading the image header, to skip the first page
-+ * of the header, which is read without using the extent chains.
++ * The linked list of extents is reconstructed from the disk. chain will point
++ * to the first entry.
 + **/
-+static int go_next_page(int writing, int section_barrier)
++int toi_load_extent_chain(int index)
 +{
-+      int i, chain_num = toi_writer_posn.current_chain,
-+        max = (chain_num == -1) ? 1 : toi_devinfo[chain_num].blocks_per_page,
-+        compare_to = 0, compare_chain, compare_offset;
-+
-+      /* Have we already used the last page of the stream? */
-+      switch (current_stream) {
-+      case 0:
-+              compare_to = 2;
-+              break;
-+      case 1:
-+              compare_to = 3;
-+              break;
-+      case 2:
-+              compare_to = 1;
-+              break;
-+      }
++      struct toi_bdev_info *chain = toi_kzalloc(39,
++                      sizeof(struct toi_bdev_info), GFP_ATOMIC);
++      struct hibernate_extent *this, *last = NULL;
++      int i, ret;
 +
-+      compare_chain = toi_writer_posn_save[compare_to].chain_num;
-+      compare_offset = toi_writer_posn_save[compare_to].offset;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Loading extent chain %d.", index);
++      /* Get dev_t, prio, bmap_shift, blocks per page, positions */
++      ret = toiActiveAllocator->rw_header_chunk_noreadahead(READ, NULL,
++                      (char *) &chain->uuid, metadata_size);
 +
-+      if (section_barrier && chain_num == compare_chain &&
-+          toi_writer_posn.current_offset == compare_offset) {
-+              if (writing) {
-+                      if (!current_stream)
-+                              return debug_broken_header();
++      if (ret) {
++              printk(KERN_ERR "Failed to read the size of extent chain.\n");
++              toi_kfree(39, chain, sizeof(*chain));
++              return 1;
++      }
++
++      ret = toiActiveAllocator->rw_header_chunk_noreadahead(READ, NULL,
++                      (char *) &chain->blocks.num_extents, sizeof(int));
++      if (ret) {
++              printk(KERN_ERR "Failed to read the size of extent chain.\n");
++              toi_kfree(39, chain, sizeof(*chain));
++              return 1;
++      }
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "%d extents.",
++                      chain->blocks.num_extents);
++
++      for (i = 0; i < chain->blocks.num_extents; i++) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Extent %d.", i + 1);
++
++              this = toi_kzalloc(2, sizeof(struct hibernate_extent),
++                              TOI_ATOMIC_GFP);
++              if (!this) {
++                      printk(KERN_INFO "Failed to allocate a new extent.\n");
++                      free_bdev_info(chain);
++                      return -ENOMEM;
++              }
++              this->next = NULL;
++              /* Get the next page */
++              ret = toiActiveAllocator->rw_header_chunk_noreadahead(READ,
++                              NULL, (char *) this, 2 * sizeof(this->start));
++              if (ret) {
++                      printk(KERN_INFO "Failed to read an extent.\n");
++                      toi_kfree(2, this, sizeof(struct hibernate_extent));
++                      free_bdev_info(chain);
++                      return 1;
++              }
++
++              if (last)
++                      last->next = this;
++              else {
++                      char b1[32], b2[32], b3[32];
++                      /*
++                       * Open the bdev
++                       */
++                      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                              "Chain dev_t is %s. Resume dev t is %s. Header"
++                              " bdev_t is %s.\n",
++                              format_dev_t(b1, chain->dev_t),
++                              format_dev_t(b2, resume_dev_t),
++                              format_dev_t(b3, toi_sig_data->header_dev_t));
++
++                      if (chain->dev_t == resume_dev_t)
++                              chain->bdev = resume_block_device;
++                      else if (chain->dev_t == toi_sig_data->header_dev_t)
++                              chain->bdev = header_block_device;
++                      else {
++                              chain->bdev = toi_open_bdev(chain->uuid,
++                                              chain->dev_t, 1);
++                              if (IS_ERR(chain->bdev)) {
++                                      free_bdev_info(chain);
++                                      return -ENODEV;
++                              }
++                      }
++
++                      toi_message(TOI_IO, TOI_VERBOSE, 0, "Chain bmap shift "
++                                      "is %d and blocks per page is %d.",
++                                      chain->bmap_shift,
++                                      chain->blocks_per_page);
++
++                      chain->blocks.first = this;
++
++                      /*
++                       * Couldn't do this earlier, but can't do
++                       * goto_start now - we may have already used blocks
++                       * in the first chain.
++                       */
++                      chain->blocks.current_extent = this;
++                      chain->blocks.current_offset = this->start;
++
++                      /*
++                       * Can't wait until we've read the whole chain
++                       * before we insert it in the list. We might need
++                       * this chain to read the next page in the header
++                       */
++                      toi_insert_chain_in_prio_list(chain);
++                      if (!index) {
++                              toi_writer_posn.current_chain = prio_chain_head;
++                              go_next_page(0, 0);
++                      }
++              }
++              last = this;
++      }
++
++      /*
++       * Shouldn't get empty chains, but it's not impossible. Link them in so
++       * they get freed properly later.
++       */
++      if (!chain->blocks.num_extents)
++              toi_insert_chain_in_prio_list(chain);
++
++      if (!chain->blocks.current_extent) {
++              chain->blocks.current_extent = chain->blocks.first;
++              if (chain->blocks.current_extent)
++                      chain->blocks.current_offset =
++                              chain->blocks.current_extent->start;
++      }
++      return 0;
++}
++
++int toi_load_extent_chains(void)
++{
++      int result;
++      int to_load;
++      int i;
++
++      result = toiActiveAllocator->rw_header_chunk_noreadahead(READ, NULL,
++                      (char *) &to_load,
++                      sizeof(int));
++      if (result)
++              return result;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "%d chains to read.", to_load);
++
++      for (i = 0; i < to_load; i++) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, " >> Loading chain %d/%d.",
++                              i, to_load);
++              result = toi_load_extent_chain(i);
++              if (result)
++                      return result;
++      }
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Save chain numbers.");
++      result = toiActiveAllocator->rw_header_chunk_noreadahead(READ,
++                      &toi_blockwriter_ops,
++                      (char *) &toi_writer_posn.saved_chain_number[0],
++                      4 * sizeof(int));
++
++      return result;
++}
++
++static int toi_end_of_stream(int writing, int section_barrier)
++{
++      struct toi_bdev_info *cur_chain = toi_writer_posn.current_chain;
++      int compare_to = next_section[current_stream];
++      struct toi_bdev_info *compare_chain =
++              toi_writer_posn.saved_chain_ptr[compare_to];
++      int compare_offset = compare_chain ?
++              compare_chain->saved_state[compare_to].offset : 0;
++
++      if (!section_barrier)
++              return 0;
++
++      if (!cur_chain)
++              return 1;
++
++      if (cur_chain == compare_chain &&
++          cur_chain->blocks.current_offset == compare_offset) {
++              if (writing) {
++                      if (!current_stream) {
++                              debug_broken_header();
++                              return 1;
++                      }
 +              } else {
 +                      more_readahead = 0;
-+                      return -ENODATA;
++                      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                                      "Reached the end of stream %d "
++                                      "(not an error).", current_stream);
++                      return 1;
 +              }
 +      }
 +
-+      /* Nope. Go foward a page - or maybe two */
-+      for (i = 0; i < max; i++)
-+              toi_extent_state_next(&toi_writer_posn);
++      return 0;
++}
++
++/**
++ * go_next_page - skip blocks to the start of the next page
++ * @writing: Whether we're reading or writing the image.
++ *
++ * Go forward one page.
++ **/
++int go_next_page(int writing, int section_barrier)
++{
++      struct toi_bdev_info *cur_chain = toi_writer_posn.current_chain;
++      int max = cur_chain ? cur_chain->blocks_per_page : 1;
 +
-+      if (toi_extent_state_eof(&toi_writer_posn)) {
++      /* Nope. Go foward a page - or maybe two. Don't stripe the header,
++       * so that bad fragmentation doesn't put the extent data containing
++       * the location of the second page out of the first header page.
++       */
++      if (toi_extent_state_next(max, current_stream)) {
 +              /* Don't complain if readahead falls off the end */
 +              if (writing && section_barrier) {
-+                      printk(KERN_DEBUG "Extent state eof. "
-+                              "Expected compression ratio too optimistic?\n");
-+                      dump_block_chains();
++                      toi_message(TOI_IO, TOI_VERBOSE, 0, "Extent state eof. "
++                              "Expected compression ratio too optimistic?");
++                      if (test_action_state(TOI_LOGALL))
++                              dump_block_chains();
 +              }
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Ran out of extents to "
++                              "read/write. (Not necessarily a fatal error.");
 +              return -ENODATA;
 +      }
 +
-+      if (extra_page_forward) {
-+              extra_page_forward = 0;
-+              return go_next_page(writing, section_barrier);
-+      }
-+
 +      return 0;
 +}
 +
-+/**
-+ * set_extra_page_forward - make us skip an extra page on next go_next_page
-+ *
-+ * Used in reading header, to jump to 2nd page after getting 1st page
-+ * direct from image header.
-+ **/
-+static void set_extra_page_forward(void)
++int devices_of_same_priority(struct toi_bdev_info *this)
 +{
-+      extra_page_forward = 1;
++      struct toi_bdev_info *check = prio_chain_head;
++      int i = 0;
++
++      while (check) {
++              if (check->prio == this->prio)
++                      i++;
++              check = check->next;
++      }
++
++      return i;
 +}
 +
 +/**
@@ -5329,4758 +6094,5357 @@ index 0000000..aa7a9cd
 + * Pass the group used in allocating the page as well, as it should
 + * be freed on completion of the bio if we're writing the page.
 + **/
-+static int toi_bio_rw_page(int writing, struct page *page,
++int toi_bio_rw_page(int writing, struct page *page,
 +              int is_readahead, int free_group)
 +{
-+      struct toi_bdev_info *dev_info;
-+      int result = go_next_page(writing, 1);
++      int result = toi_end_of_stream(writing, 1);
++      struct toi_bdev_info *dev_info = toi_writer_posn.current_chain;
 +
-+      if (result)
-+              return result;
++      if (result) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Seeking to read/write "
++                              "another page when stream has ended.");
++              return -ENODATA;
++      }
 +
-+      dev_info = &toi_devinfo[toi_writer_posn.current_chain];
++      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                      "%sing device %lx, sector %d << %d.",
++                      writing ? "Writ" : "Read",
++                      dev_info->bdev, dev_info->blocks.current_offset,
++                      dev_info->bmap_shift);
 +
-+      return toi_do_io(writing, dev_info->bdev,
-+              toi_writer_posn.current_offset <<
-+                      dev_info->bmap_shift,
++      result = toi_do_io(writing, dev_info->bdev,
++              dev_info->blocks.current_offset << dev_info->bmap_shift,
 +              page, is_readahead, 0, free_group);
-+}
-+
-+/**
-+ * toi_rw_init - prepare to read or write a stream in the image
-+ * @writing: Whether reading or writing.
-+ * @stream number: Section of the image being processed.
-+ *
-+ * Prepare to read or write a section ('stream') in the image.
-+ **/
-+static int toi_rw_init(int writing, int stream_number)
-+{
-+      if (stream_number)
-+              toi_extent_state_restore(&toi_writer_posn,
-+                              &toi_writer_posn_save[stream_number]);
-+      else
-+              toi_extent_state_goto_start(&toi_writer_posn);
-+
-+      atomic_set(&toi_io_done, 0);
-+      toi_writer_buffer = (char *) toi_get_zeroed_page(11, TOI_ATOMIC_GFP);
-+      toi_writer_buffer_posn = writing ? 0 : PAGE_SIZE;
-+
-+      current_stream = stream_number;
 +
-+      more_readahead = 1;
++      /* Ignore the result here - will check end of stream if come in again */
++      go_next_page(writing, 1);
 +
-+      return toi_writer_buffer ? 0 : -ENOMEM;
++      if (result)
++              printk(KERN_ERR "toi_do_io returned %d.\n", result);
++      return result;
 +}
 +
-+/**
-+ * toi_read_header_init - prepare to read the image header
-+ *
-+ * Reset readahead indices prior to starting to read a section of the image.
-+ **/
-+static void toi_read_header_init(void)
++dev_t get_header_dev_t(void)
 +{
-+      toi_writer_buffer = (char *) toi_get_zeroed_page(11, TOI_ATOMIC_GFP);
-+      more_readahead = 1;
++      return prio_chain_head->dev_t;
 +}
 +
-+/**
-+ * toi_bio_queue_write - queue a page for writing
-+ * @full_buffer: Pointer to a page to be queued
-+ *
-+ * Add a page to the queue to be submitted. If we're the queue flusher,
-+ * we'll do this once we've dropped toi_bio_mutex, so other threads can
-+ * continue to submit I/O while we're on the slow path doing the actual
-+ * submission.
-+ **/
-+static void toi_bio_queue_write(char **full_buffer)
++struct block_device *get_header_bdev(void)
 +{
-+      struct page *page = virt_to_page(*full_buffer);
-+      unsigned long flags;
-+
-+      page->private = 0;
++      return prio_chain_head->bdev;
++}
 +
-+      spin_lock_irqsave(&bio_queue_lock, flags);
-+      if (!bio_queue_head)
-+              bio_queue_head = page;
-+      else
-+              bio_queue_tail->private = (unsigned long) page;
++unsigned long get_headerblock(void)
++{
++      return prio_chain_head->blocks.first->start <<
++              prio_chain_head->bmap_shift;
++}
 +
-+      bio_queue_tail = page;
-+      atomic_inc(&toi_bio_queue_size);
++int get_main_pool_phys_params(void)
++{
++      struct toi_bdev_info *this = prio_chain_head;
++      int result;
 +
-+      spin_unlock_irqrestore(&bio_queue_lock, flags);
-+      wake_up(&toi_io_queue_flusher);
++      while (this) {
++              result = this->allocator->bio_allocator_ops->bmap(this);
++              if (result)
++                      return result;
++              this = this->next;
++      }
 +
-+      *full_buffer = NULL;
++      return 0;
 +}
 +
-+/**
-+ * toi_rw_cleanup - Cleanup after i/o.
-+ * @writing: Whether we were reading or writing.
-+ *
-+ * Flush all I/O and clean everything up after reading or writing a
-+ * section of the image.
-+ **/
-+static int toi_rw_cleanup(int writing)
++static int apply_header_reservation(void)
 +{
-+      int i, result;
-+
-+      if (writing) {
-+              int result;
-+
-+              if (toi_writer_buffer_posn && !test_result_state(TOI_ABORTED))
-+                      toi_bio_queue_write(&toi_writer_buffer);
++      int i;
 +
-+              result = toi_bio_queue_flush_pages(0);
++      if (!header_pages_reserved) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0,
++                              "No header pages reserved at the moment.");
++              return 0;
++      }
 +
-+              if (result)
-+                      return result;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Applying header reservation.");
 +
-+              if (current_stream == 2)
-+                      toi_extent_state_save(&toi_writer_posn,
-+                                      &toi_writer_posn_save[1]);
-+              else if (current_stream == 1)
-+                      toi_extent_state_save(&toi_writer_posn,
-+                                      &toi_writer_posn_save[3]);
-+      }
++      /* Apply header space reservation */
++      toi_extent_state_goto_start();
 +
-+      result = toi_finish_all_io();
++      for (i = 0; i < header_pages_reserved; i++)
++              if (go_next_page(1, 0))
++                      return -ENODATA;
 +
-+      while (readahead_list_head) {
-+              void *next = (void *) readahead_list_head->private;
-+              toi__free_page(12, readahead_list_head);
-+              readahead_list_head = next;
-+      }
++      /* The end of header pages will be the start of pageset 2 */
++      toi_extent_state_save(2);
 +
-+      readahead_list_tail = NULL;
++      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                      "Finished applying header reservation.");
++      return 0;
++}
 +
-+      if (!current_stream)
-+              return result;
++static int toi_bio_register_storage(void)
++{
++      int result = 0;
++      struct toi_module_ops *this_module;
 +
-+      for (i = 0; i < NUM_REASONS; i++) {
-+              if (!atomic_read(&reasons[i]))
++      list_for_each_entry(this_module, &toi_modules, module_list) {
++              if (!this_module->enabled ||
++                  this_module->type != BIO_ALLOCATOR_MODULE)
 +                      continue;
-+              printk(KERN_DEBUG "Waited for i/o due to %s %d times.\n",
-+                              reason_name[i], atomic_read(&reasons[i]));
-+              atomic_set(&reasons[i], 0);
++              toi_message(TOI_IO, TOI_VERBOSE, 0,
++                              "Registering storage from %s.",
++                              this_module->name);
++              result = this_module->bio_allocator_ops->register_storage();
++              if (result)
++                      break;
 +      }
 +
-+      current_stream = 0;
 +      return result;
 +}
 +
-+/**
-+ * toi_start_one_readahead - start one page of readahead
-+ * @dedicated_thread: Is this a thread dedicated to doing readahead?
-+ *
-+ * Start one new page of readahead. If this is being called by a thread
-+ * whose only just is to submit readahead, don't quit because we failed
-+ * to allocate a page.
-+ **/
-+static int toi_start_one_readahead(int dedicated_thread)
++int toi_bio_allocate_storage(unsigned long request)
 +{
-+      char *buffer = NULL;
-+      int oom = 0, result;
++      struct toi_bdev_info *chain = prio_chain_head;
++      unsigned long to_get = request;
++      unsigned long extra_pages, needed;
++      int no_free = 0;
 +
-+      result = throttle_if_needed(dedicated_thread ? THROTTLE_WAIT : 0);
-+      if (result)
-+              return result;
++      if (!chain) {
++              int result = toi_bio_register_storage();
++              if (result)
++                      return 0;
++              chain = prio_chain_head;
++      }
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_bio_allocate_storage: "
++                      "Request is %lu pages.", request);
++      extra_pages = DIV_ROUND_UP(request * (sizeof(unsigned long)
++                             + sizeof(int)), PAGE_SIZE);
++      needed = request + extra_pages + header_pages_reserved;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Adding %lu extra pages and %lu "
++                      "for header => %lu.",
++                      extra_pages, header_pages_reserved, needed);
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Already allocated %lu pages.",
++                      raw_pages_allocd);
 +
-+      mutex_lock(&toi_bio_readahead_mutex);
++      to_get = needed > raw_pages_allocd ? needed - raw_pages_allocd : 0;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Need to get %lu pages.", to_get);
 +
-+      while (!buffer) {
-+              buffer = (char *) toi_get_zeroed_page(12,
-+                              TOI_ATOMIC_GFP);
-+              if (!buffer) {
-+                      if (oom && !dedicated_thread) {
-+                              mutex_unlock(&toi_bio_readahead_mutex);
-+                              return -ENOMEM;
-+                      }
++      if (!to_get)
++              return apply_header_reservation();
 +
-+                      oom = 1;
-+                      set_free_mem_throttle();
-+                      do_bio_wait(5);
-+              }
-+      }
++      while (to_get && chain) {
++              int divisor = devices_of_same_priority(chain) - no_free;
++              int i;
++              unsigned long portion = DIV_ROUND_UP(to_get, divisor);
++              unsigned long got = 0;
++              unsigned long got_this_round = 0;
++              struct toi_bdev_info *top = chain;
 +
-+      result = toi_bio_rw_page(READ, virt_to_page(buffer), 1, 0);
-+      mutex_unlock(&toi_bio_readahead_mutex);
-+      return result;
-+}
++              toi_message(TOI_IO, TOI_VERBOSE, 0,
++                              " Start of loop. To get is %lu. Divisor is %d.",
++                              to_get, divisor);
++              no_free = 0;
 +
-+/**
-+ * toi_start_new_readahead - start new readahead
-+ * @dedicated_thread: Are we dedicated to this task?
++              /*
++               * We're aiming to spread the allocated storage as evenly
++               * as possible, but we also want to get all the storage we
++               * can off this priority.
++               */
++              for (i = 0; i < divisor; i++) {
++                      struct toi_bio_allocator_ops *ops =
++                              chain->allocator->bio_allocator_ops;
++                      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                                      " Asking for %lu pages from chain %p.",
++                                      portion, chain);
++                      got = ops->allocate_storage(chain, portion);
++                      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                                      " Got %lu pages from allocator %p.",
++                                      got, chain);
++                      if (!got)
++                              no_free++;
++                      got_this_round += got;
++                      chain = chain->next;
++              }
++              toi_message(TOI_IO, TOI_VERBOSE, 0, " Loop finished. Got a "
++                              "total of %lu pages from %d allocators.",
++                              got_this_round, divisor - no_free);
++
++              raw_pages_allocd += got_this_round;
++              to_get = needed > raw_pages_allocd ? needed - raw_pages_allocd :
++                      0;
++
++              /*
++               * If we got anything from chains of this priority and we
++               * still have storage to allocate, go over this priority
++               * again.
++               */
++              if (got_this_round && to_get)
++                      chain = top;
++              else
++                      no_free = 0;
++      }
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Finished allocating. Calling "
++                      "get_main_pool_phys_params");
++      /* Now let swap allocator bmap the pages */
++      get_main_pool_phys_params();
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Done. Reserving header.");
++      return apply_header_reservation();
++}
+diff --git a/kernel/power/tuxonice_bio_core.c b/kernel/power/tuxonice_bio_core.c
+new file mode 100644
+index 0000000..188931a
+--- /dev/null
++++ b/kernel/power/tuxonice_bio_core.c
+@@ -0,0 +1,1791 @@
++/*
++ * kernel/power/tuxonice_bio.c
 + *
-+ * Start readahead of image pages.
++ * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
 + *
-+ * We can be called as a thread dedicated to this task (may be helpful on
-+ * systems with lots of CPUs), in which case we don't exit until there's no
-+ * more readahead.
++ * Distributed under GPLv2.
 + *
-+ * If this is not called by a dedicated thread, we top up our queue until
-+ * there's no more readahead to submit, we've submitted the number given
-+ * in target_outstanding_io or the number in progress exceeds the target
-+ * outstanding I/O value.
++ * This file contains block io functions for TuxOnIce. These are
++ * used by the swapwriter and it is planned that they will also
++ * be used by the NFSwriter.
 + *
-+ * No mutex needed because this is only ever called by the first cpu.
-+ **/
-+static int toi_start_new_readahead(int dedicated_thread)
-+{
-+      int last_result, num_submitted = 0;
++ */
 +
-+      /* Start a new readahead? */
-+      if (!more_readahead)
-+              return 0;
++#include <linux/blkdev.h>
++#include <linux/syscalls.h>
++#include <linux/suspend.h>
++#include <linux/ctype.h>
++#include <linux/uuid.h>
++#include <scsi/scsi_scan.h>
 +
-+      do {
-+              last_result = toi_start_one_readahead(dedicated_thread);
++#include "tuxonice.h"
++#include "tuxonice_sysfs.h"
++#include "tuxonice_modules.h"
++#include "tuxonice_prepare_image.h"
++#include "tuxonice_bio.h"
++#include "tuxonice_ui.h"
++#include "tuxonice_alloc.h"
++#include "tuxonice_io.h"
++#include "tuxonice_builtin.h"
++#include "tuxonice_bio_internal.h"
 +
-+              if (last_result) {
-+                      if (last_result == -ENOMEM || last_result == -ENODATA)
-+                              return 0;
++#define MEMORY_ONLY 1
++#define THROTTLE_WAIT 2
 +
-+                      printk(KERN_DEBUG
-+                              "Begin read chunk returned %d.\n",
-+                              last_result);
-+              } else
-+                      num_submitted++;
++/* #define MEASURE_MUTEX_CONTENTION */
++#ifndef MEASURE_MUTEX_CONTENTION
++#define my_mutex_lock(index, the_lock) mutex_lock(the_lock)
++#define my_mutex_unlock(index, the_lock) mutex_unlock(the_lock)
++#else
++unsigned long mutex_times[2][2][NR_CPUS];
++#define my_mutex_lock(index, the_lock) do { \
++      int have_mutex; \
++      have_mutex = mutex_trylock(the_lock); \
++      if (!have_mutex) { \
++              mutex_lock(the_lock); \
++              mutex_times[index][0][smp_processor_id()]++; \
++      } else { \
++              mutex_times[index][1][smp_processor_id()]++; \
++      }
 +
-+      } while (more_readahead && !last_result &&
-+               (dedicated_thread ||
-+                (num_submitted < target_outstanding_io &&
-+                 atomic_read(&toi_io_in_progress) < target_outstanding_io)));
++#define my_mutex_unlock(index, the_lock) \
++      mutex_unlock(the_lock); \
++} while (0)
++#endif
 +
-+      return last_result;
-+}
++static int page_idx, reset_idx;
++
++static int target_outstanding_io = 1024;
++static int max_outstanding_writes, max_outstanding_reads;
++
++static struct page *bio_queue_head, *bio_queue_tail;
++static atomic_t toi_bio_queue_size;
++static DEFINE_SPINLOCK(bio_queue_lock);
++
++static int free_mem_throttle, throughput_throttle;
++int more_readahead = 1;
++static struct page *readahead_list_head, *readahead_list_tail;
++
++static struct page *waiting_on;
++
++static atomic_t toi_io_in_progress, toi_io_done;
++static DECLARE_WAIT_QUEUE_HEAD(num_in_progress_wait);
++
++int current_stream;
++/* Not static, so that the allocators can setup and complete
++ * writing the header */
++char *toi_writer_buffer;
++int toi_writer_buffer_posn;
++
++static DEFINE_MUTEX(toi_bio_mutex);
++static DEFINE_MUTEX(toi_bio_readahead_mutex);
++
++static struct task_struct *toi_queue_flusher;
++static int toi_bio_queue_flush_pages(int dedicated_thread);
++
++struct toi_module_ops toi_blockwriter_ops;
++
++#define TOTAL_OUTSTANDING_IO (atomic_read(&toi_io_in_progress) + \
++             atomic_read(&toi_bio_queue_size))
++
++unsigned long raw_pages_allocd, header_pages_reserved;
 +
 +/**
-+ * bio_io_flusher - start the dedicated I/O flushing routine
-+ * @writing: Whether we're writing the image.
++ * set_free_mem_throttle - set the point where we pause to avoid oom.
++ *
++ * Initially, this value is zero, but when we first fail to allocate memory,
++ * we set it (plus a buffer) and thereafter throttle i/o once that limit is
++ * reached.
 + **/
-+static int bio_io_flusher(int writing)
++static void set_free_mem_throttle(void)
 +{
++      int new_throttle = nr_unallocated_buffer_pages() + 256;
 +
-+      if (writing)
-+              return toi_bio_queue_flush_pages(1);
-+      else
-+              return toi_start_new_readahead(1);
++      if (new_throttle > free_mem_throttle)
++              free_mem_throttle = new_throttle;
 +}
 +
++#define NUM_REASONS 7
++static atomic_t reasons[NUM_REASONS];
++static char *reason_name[NUM_REASONS] = {
++      "readahead not ready",
++      "bio allocation",
++      "synchronous I/O",
++      "toi_bio_get_new_page",
++      "memory low",
++      "readahead buffer allocation",
++      "throughput_throttle",
++};
++
++/* User Specified Parameters. */
++unsigned long resume_firstblock;
++dev_t resume_dev_t;
++struct block_device *resume_block_device;
++static atomic_t resume_bdev_open_count;
++
++struct block_device *header_block_device;
++
 +/**
-+ * toi_bio_get_next_page_read - read a disk page, perhaps with readahead
-+ * @no_readahead: Whether we can use readahead
++ * toi_close_bdev: Close a swap bdev.
 + *
-+ * Read a page from disk, submitting readahead and cleaning up finished i/o
-+ * while we wait for the page we're after.
-+ **/
-+static int toi_bio_get_next_page_read(int no_readahead)
++ * int: The swap entry number to close.
++ */
++void toi_close_bdev(struct block_device *bdev)
 +{
-+      unsigned long *virt;
-+      struct page *next;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, ">>> TuxOnIce closing bdev %p.",
++                      bdev);
++      blkdev_put(bdev, FMODE_READ | FMODE_NDELAY);
++}
 +
-+      /*
-+       * When reading the second page of the header, we have to
-+       * delay submitting the read until after we've gotten the
-+       * extents out of the first page.
-+       */
-+      if (unlikely(no_readahead && toi_start_one_readahead(0))) {
-+              printk(KERN_DEBUG "No readahead and toi_start_one_readahead "
-+                              "returned non-zero.\n");
-+              return -EIO;
++/**
++ * toi_open_bdev: Open a bdev at resume time.
++ *
++ * index: The swap index. May be MAX_SWAPFILES for the resume_dev_t
++ * (the user can have resume= pointing at a swap partition/file that isn't
++ * swapon'd when they hibernate. MAX_SWAPFILES+1 for the first page of the
++ * header. It will be from a swap partition that was enabled when we hibernated,
++ * but we don't know it's real index until we read that first page.
++ * dev_t: The device major/minor.
++ * display_errs: Whether to try to do this quietly.
++ *
++ * We stored a dev_t in the image header. Open the matching device without
++ * requiring /dev/<whatever> in most cases and record the details needed
++ * to close it later and avoid duplicating work.
++ */
++struct block_device *toi_open_bdev(char *uuid, dev_t default_device,
++              int display_errs)
++{
++      struct block_device *bdev;
++      dev_t device = default_device;
++      char buf[32];
++
++      if (uuid) {
++              device = blk_lookup_uuid(uuid);
++              if (!device) {
++                      device = default_device;
++                      printk(KERN_DEBUG "Unable to resolve uuid. Falling back"
++                                      " to dev_t.\n");
++              } else
++                      printk(KERN_DEBUG "Resolved uuid to device %s.\n",
++                                      format_dev_t(buf, device));
 +      }
 +
-+      if (unlikely(!readahead_list_head)) {
-+              /* 
-+               * If the last page finishes exactly on the page
-+               * boundary, we will be called one extra time and
-+               * have no data to return. In this case, we should
-+               * not BUG(), like we used to!
-+               */
-+              if (!more_readahead)
-+                      return -ENODATA;
-+              if (unlikely(toi_start_one_readahead(0))) {
-+                      printk(KERN_DEBUG "No readahead and "
-+                       "toi_start_one_readahead returned non-zero.\n");
-+                      return -EIO;
-+              }
++      if (!device) {
++              printk(KERN_ERR "TuxOnIce attempting to open a "
++                              "blank dev_t!\n");
++              dump_stack();
++              return NULL;
 +      }
++      bdev = toi_open_by_devnum(device, FMODE_READ | FMODE_NDELAY);
 +
-+      if (PageLocked(readahead_list_head)) {
-+              waiting_on = readahead_list_head;
-+              do_bio_wait(0);
++      if (IS_ERR(bdev) || !bdev) {
++              if (display_errs)
++                      toi_early_boot_message(1, TOI_CONTINUE_REQ,
++                              "Failed to get access to block device "
++                              "\"%x\" (error %d).\n Maybe you need "
++                              "to run mknod and/or lvmsetup in an "
++                              "initrd/ramfs?", device, bdev);
++              return ERR_PTR(-EINVAL);
 +      }
++      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                      "TuxOnIce got bdev %p for dev_t %x.",
++                      bdev, device);
 +
-+      virt = page_address(readahead_list_head);
-+      memcpy(toi_writer_buffer, virt, PAGE_SIZE);
++      return bdev;
++}
 +
-+      next = (struct page *) readahead_list_head->private;
-+      toi__free_page(12, readahead_list_head);
-+      readahead_list_head = next;
-+      return 0;
++static void toi_bio_reserve_header_space(unsigned long request)
++{
++      header_pages_reserved = request;
 +}
 +
 +/**
-+ * toi_bio_queue_flush_pages - flush the queue of pages queued for writing
-+ * @dedicated_thread: Whether we're a dedicated thread
-+ *
-+ * Flush the queue of pages ready to be written to disk.
-+ *
-+ * If we're a dedicated thread, stay in here until told to leave,
-+ * sleeping in wait_event.
++ * do_bio_wait - wait for some TuxOnIce I/O to complete
++ * @reason: The array index of the reason we're waiting.
 + *
-+ * The first thread is normally the only one to come in here. Another
-+ * thread can enter this routine too, though, via throttle_if_needed.
-+ * Since that's the case, we must be careful to only have one thread
-+ * doing this work at a time. Otherwise we have a race and could save
-+ * pages out of order.
++ * Wait for a particular page of I/O if we're after a particular page.
++ * If we're not after a particular page, wait instead for all in flight
++ * I/O to be completed or for us to have enough free memory to be able
++ * to submit more I/O.
 + *
-+ * If an error occurs, free all remaining pages without submitting them
-+ * for I/O.
++ * If we wait, we also update our statistics regarding why we waited.
 + **/
-+
-+int toi_bio_queue_flush_pages(int dedicated_thread)
++static void do_bio_wait(int reason)
 +{
-+      unsigned long flags;
-+      int result = 0;
-+      static int busy;
-+
-+      if (busy)
-+              return 0;
++      struct page *was_waiting_on = waiting_on;
 +
-+      busy = 1;
-+
-+top:
-+      spin_lock_irqsave(&bio_queue_lock, flags);
-+      while (bio_queue_head) {
-+              struct page *page = bio_queue_head;
-+              bio_queue_head = (struct page *) page->private;
-+              if (bio_queue_tail == page)
-+                      bio_queue_tail = NULL;
-+              atomic_dec(&toi_bio_queue_size);
-+              spin_unlock_irqrestore(&bio_queue_lock, flags);
-+              if (!result)
-+                      result = toi_bio_rw_page(WRITE, page, 0, 11);
-+              if (result)
-+                      toi__free_page(11 , page);
-+              spin_lock_irqsave(&bio_queue_lock, flags);
-+      }
-+      spin_unlock_irqrestore(&bio_queue_lock, flags);
++      /* On SMP, waiting_on can be reset, so we make a copy */
++      if (was_waiting_on) {
++              if (PageLocked(was_waiting_on)) {
++                      wait_on_page_bit(was_waiting_on, PG_locked);
++                      atomic_inc(&reasons[reason]);
++              }
++      } else {
++              atomic_inc(&reasons[reason]);
 +
-+      if (dedicated_thread) {
-+              wait_event(toi_io_queue_flusher, bio_queue_head ||
-+                              toi_bio_queue_flusher_should_finish);
-+              if (likely(!toi_bio_queue_flusher_should_finish))
-+                      goto top;
-+              toi_bio_queue_flusher_should_finish = 0;
++              wait_event(num_in_progress_wait,
++                      !atomic_read(&toi_io_in_progress) ||
++                      nr_unallocated_buffer_pages() > free_mem_throttle);
 +      }
-+
-+      busy = 0;
-+      return result;
 +}
 +
 +/**
-+ * toi_bio_get_new_page - get a new page for I/O
-+ * @full_buffer: Pointer to a page to allocate.
++ * throttle_if_needed - wait for I/O completion if throttle points are reached
++ * @flags: What to check and how to act.
++ *
++ * Check whether we need to wait for some I/O to complete. We always check
++ * whether we have enough memory available, but may also (depending upon
++ * @reason) check if the throughput throttle limit has been reached.
 + **/
-+static int toi_bio_get_new_page(char **full_buffer)
++static int throttle_if_needed(int flags)
 +{
-+      int result = throttle_if_needed(THROTTLE_WAIT);
-+      if (result)
-+              return result;
++      int free_pages = nr_unallocated_buffer_pages();
 +
-+      while (!*full_buffer) {
-+              *full_buffer = (char *) toi_get_zeroed_page(11, TOI_ATOMIC_GFP);
-+              if (!*full_buffer) {
-+                      set_free_mem_throttle();
-+                      do_bio_wait(3);
-+              }
++      /* Getting low on memory and I/O is in progress? */
++      while (unlikely(free_pages < free_mem_throttle) &&
++                      atomic_read(&toi_io_in_progress)) {
++              if (!(flags & THROTTLE_WAIT))
++                      return -ENOMEM;
++              do_bio_wait(4);
++              free_pages = nr_unallocated_buffer_pages();
++      }
++
++      while (!(flags & MEMORY_ONLY) && throughput_throttle &&
++              TOTAL_OUTSTANDING_IO >= throughput_throttle) {
++              int result = toi_bio_queue_flush_pages(0);
++              if (result)
++                      return result;
++              atomic_inc(&reasons[6]);
++              wait_event(num_in_progress_wait,
++                      !atomic_read(&toi_io_in_progress) ||
++                      TOTAL_OUTSTANDING_IO < throughput_throttle);
 +      }
 +
 +      return 0;
 +}
 +
 +/**
-+ * toi_rw_buffer - combine smaller buffers into PAGE_SIZE I/O
-+ * @writing:          Bool - whether writing (or reading).
-+ * @buffer:           The start of the buffer to write or fill.
-+ * @buffer_size:      The size of the buffer to write or fill.
-+ * @no_readahead:     Don't try to start readhead (when getting extents).
++ * update_throughput_throttle - update the raw throughput throttle
++ * @jif_index: The number of times this function has been called.
++ *
++ * This function is called twice per second by the core, and used to limit the
++ * amount of I/O we submit at once, spreading out our waiting through the
++ * whole job and letting userui get an opportunity to do its work.
++ *
++ * We don't start limiting I/O until 1/2s has gone so that we get a
++ * decent sample for our initial limit, and keep updating it because
++ * throughput may vary (on rotating media, eg) with our block number.
++ *
++ * We throttle to 1/10s worth of I/O.
 + **/
-+static int toi_rw_buffer(int writing, char *buffer, int buffer_size,
-+              int no_readahead)
++static void update_throughput_throttle(int jif_index)
 +{
-+      int bytes_left = buffer_size, result = 0;
-+
-+      while (bytes_left) {
-+              char *source_start = buffer + buffer_size - bytes_left;
-+              char *dest_start = toi_writer_buffer + toi_writer_buffer_posn;
-+              int capacity = PAGE_SIZE - toi_writer_buffer_posn;
-+              char *to = writing ? dest_start : source_start;
-+              char *from = writing ? source_start : dest_start;
-+
-+              if (bytes_left <= capacity) {
-+                      memcpy(to, from, bytes_left);
-+                      toi_writer_buffer_posn += bytes_left;
-+                      return 0;
-+              }
-+
-+              /* Complete this page and start a new one */
-+              memcpy(to, from, capacity);
-+              bytes_left -= capacity;
-+
-+              if (!writing) {
-+                      /*
-+                       * Perform actual I/O:
-+                       * read readahead_list_head into toi_writer_buffer
-+                       */
-+                      int result = toi_bio_get_next_page_read(no_readahead);
-+                      if (result)
-+                              return result;
-+              } else {
-+                      toi_bio_queue_write(&toi_writer_buffer);
-+                      result = toi_bio_get_new_page(&toi_writer_buffer);
-+                      if (result)
-+                              return result;
-+              }
-+
-+              toi_writer_buffer_posn = 0;
-+              toi_cond_pause(0, NULL);
-+      }
-+
-+      return 0;
++      int done = atomic_read(&toi_io_done);
++      throughput_throttle = done / jif_index / 5;
 +}
 +
 +/**
-+ * toi_bio_read_page - read a page of the image
-+ * @pfn:              The pfn where the data belongs.
-+ * @buffer_page:      The page containing the (possibly compressed) data.
-+ * @buf_size:         The number of bytes on @buffer_page used (PAGE_SIZE).
++ * toi_finish_all_io - wait for all outstanding i/o to complete
 + *
-+ * Read a (possibly compressed) page from the image, into buffer_page,
-+ * returning its pfn and the buffer size.
++ * Flush any queued but unsubmitted I/O and wait for it all to complete.
 + **/
-+static int toi_bio_read_page(unsigned long *pfn, struct page *buffer_page,
-+              unsigned int *buf_size)
++static int toi_finish_all_io(void)
 +{
-+      int result = 0;
-+      char *buffer_virt = kmap(buffer_page);
-+
-+      /*
-+       * Only call start_new_readahead if we don't have a dedicated thread
-+       * and we're the queue flusher.
-+       */
-+      if (current == toi_queue_flusher && more_readahead) {
-+              int result2 = toi_start_new_readahead(0);
-+              if (result2) {
-+                      printk(KERN_DEBUG "Queue flusher and "
-+                       "toi_start_one_readahead returned non-zero.\n");
-+                      result = -EIO;
-+                      goto out;
-+              }
-+      }
-+
-+      my_mutex_lock(0, &toi_bio_mutex);
-+
-+      /*
-+       * Structure in the image:
-+       *      [destination pfn|page size|page data]
-+       * buf_size is PAGE_SIZE
-+       */
-+      if (toi_rw_buffer(READ, (char *) pfn, sizeof(unsigned long), 0) ||
-+          toi_rw_buffer(READ, (char *) buf_size, sizeof(int), 0) ||
-+          toi_rw_buffer(READ, buffer_virt, *buf_size, 0)) {
-+              abort_hibernate(TOI_FAILED_IO, "Read of data failed.");
-+              result = 1;
-+      }
-+
-+      my_mutex_unlock(0, &toi_bio_mutex);
-+out:
-+      kunmap(buffer_page);
++      int result = toi_bio_queue_flush_pages(0);
++      wait_event(num_in_progress_wait, !TOTAL_OUTSTANDING_IO);
 +      return result;
 +}
 +
 +/**
-+ * toi_bio_write_page - write a page of the image
-+ * @pfn:              The pfn where the data belongs.
-+ * @buffer_page:      The page containing the (possibly compressed) data.
-+ * @buf_size: The number of bytes on @buffer_page used.
++ * toi_end_bio - bio completion function.
++ * @bio: bio that has completed.
++ * @err: Error value. Yes, like end_swap_bio_read, we ignore it.
 + *
-+ * Write a (possibly compressed) page to the image from the buffer, together
-+ * with it's index and buffer size.
++ * Function called by the block driver from interrupt context when I/O is
++ * completed. If we were writing the page, we want to free it and will have
++ * set bio->bi_private to the parameter we should use in telling the page
++ * allocation accounting code what the page was allocated for. If we're
++ * reading the page, it will be in the singly linked list made from
++ * page->private pointers.
 + **/
-+static int toi_bio_write_page(unsigned long pfn, struct page *buffer_page,
-+              unsigned int buf_size)
++static void toi_end_bio(struct bio *bio, int err)
 +{
-+      char *buffer_virt;
-+      int result = 0, result2 = 0;
++      struct page *page = bio->bi_io_vec[0].bv_page;
 +
-+      if (unlikely(test_action_state(TOI_TEST_FILTER_SPEED)))
-+              return 0;
++      BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
 +
-+      my_mutex_lock(1, &toi_bio_mutex);
++      unlock_page(page);
++      bio_put(bio);
 +
-+      if (test_result_state(TOI_ABORTED)) {
-+              my_mutex_unlock(1, &toi_bio_mutex);
-+              return -EIO;
-+      }
++      if (waiting_on == page)
++              waiting_on = NULL;
 +
-+      buffer_virt = kmap(buffer_page);
++      put_page(page);
 +
-+      /*
-+       * Structure in the image:
-+       *      [destination pfn|page size|page data]
-+       * buf_size is PAGE_SIZE
-+       */
-+      if (toi_rw_buffer(WRITE, (char *) &pfn, sizeof(unsigned long), 0) ||
-+          toi_rw_buffer(WRITE, (char *) &buf_size, sizeof(int), 0) ||
-+          toi_rw_buffer(WRITE, buffer_virt, buf_size, 0)) {
-+              printk(KERN_DEBUG "toi_rw_buffer returned non-zero to "
-+                              "toi_bio_write_page.\n");
-+              result = -EIO;
-+      }
++      if (bio->bi_private)
++              toi__free_page((int) ((unsigned long) bio->bi_private) , page);
 +
-+      kunmap(buffer_page);
-+      my_mutex_unlock(1, &toi_bio_mutex);
++      bio_put(bio);
 +
-+      if (current == toi_queue_flusher)
-+              result2 = toi_bio_queue_flush_pages(0);
++      atomic_dec(&toi_io_in_progress);
++      atomic_inc(&toi_io_done);
 +
-+      return result ? result : result2;
++      wake_up(&num_in_progress_wait);
 +}
 +
 +/**
-+ * _toi_rw_header_chunk - read or write a portion of the image header
-+ * @writing:          Whether reading or writing.
-+ * @owner:            The module for which we're writing.
-+ *                    Used for confirming that modules
-+ *                    don't use more header space than they asked for.
-+ * @buffer:           Address of the data to write.
-+ * @buffer_size:      Size of the data buffer.
-+ * @no_readahead:     Don't try to start readhead (when getting extents).
++ * submit - submit BIO request
++ * @writing: READ or WRITE.
++ * @dev: The block device we're using.
++ * @first_block: The first sector we're using.
++ * @page: The page being used for I/O.
++ * @free_group: If writing, the group that was used in allocating the page
++ *    and which will be used in freeing the page from the completion
++ *    routine.
 + *
-+ * Perform PAGE_SIZE I/O. Start readahead if needed.
-+ **/
-+static int _toi_rw_header_chunk(int writing, struct toi_module_ops *owner,
-+              char *buffer, int buffer_size, int no_readahead)
++ * Based on Patrick Mochell's pmdisk code from long ago: "Straight from the
++ * textbook - allocate and initialize the bio. If we're writing, make sure
++ * the page is marked as dirty. Then submit it and carry on."
++ *
++ * If we're just testing the speed of our own code, we fake having done all
++ * the hard work and all toi_end_bio immediately.
++ **/
++static int submit(int writing, struct block_device *dev, sector_t first_block,
++              struct page *page, int free_group)
 +{
-+      int result = 0;
++      struct bio *bio = NULL;
++      int cur_outstanding_io, result;
 +
-+      if (owner) {
-+              owner->header_used += buffer_size;
-+              toi_message(TOI_HEADER, TOI_LOW, 1,
-+                      "Header: %s : %d bytes (%d/%d).\n",
-+                      owner->name,
-+                      buffer_size, owner->header_used,
-+                      owner->header_requested);
-+              if (owner->header_used > owner->header_requested) {
-+                      printk(KERN_EMERG "TuxOnIce module %s is using more "
-+                              "header space (%u) than it requested (%u).\n",
-+                              owner->name,
-+                              owner->header_used,
-+                              owner->header_requested);
-+                      return buffer_size;
++      /*
++       * Shouldn't throttle if reading - can deadlock in the single
++       * threaded case as pages are only freed when we use the
++       * readahead.
++       */
++      if (writing) {
++              result = throttle_if_needed(MEMORY_ONLY | THROTTLE_WAIT);
++              if (result)
++                      return result;
++      }
++
++      while (!bio) {
++              bio = bio_alloc(TOI_ATOMIC_GFP, 1);
++              if (!bio) {
++                      set_free_mem_throttle();
++                      do_bio_wait(1);
 +              }
-+      } else {
-+              unowned += buffer_size;
-+              toi_message(TOI_HEADER, TOI_LOW, 1,
-+                      "Header: (No owner): %d bytes (%d total so far)\n",
-+                      buffer_size, unowned);
 +      }
 +
-+      if (!writing && !no_readahead && more_readahead)
-+              result = toi_start_new_readahead(0);
++      bio->bi_bdev = dev;
++      bio->bi_sector = first_block;
++      bio->bi_private = (void *) ((unsigned long) free_group);
++      bio->bi_end_io = toi_end_bio;
 +
-+      if (!result)
-+              result = toi_rw_buffer(writing, buffer, buffer_size,
-+                              no_readahead);
++      if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
++              printk(KERN_DEBUG "ERROR: adding page to bio at %lld\n",
++                              (unsigned long long) first_block);
++              bio_put(bio);
++              return -EFAULT;
++      }
 +
-+      total_header_bytes += buffer_size;
-+      return result;
-+}
++      bio_get(bio);
 +
-+static int toi_rw_header_chunk(int writing, struct toi_module_ops *owner,
-+              char *buffer, int size)
-+{
-+      return _toi_rw_header_chunk(writing, owner, buffer, size, 0);
-+}
++      cur_outstanding_io = atomic_add_return(1, &toi_io_in_progress);
++      if (writing) {
++              if (cur_outstanding_io > max_outstanding_writes)
++                      max_outstanding_writes = cur_outstanding_io;
++      } else {
++              if (cur_outstanding_io > max_outstanding_reads)
++                      max_outstanding_reads = cur_outstanding_io;
++      }
 +
-+static int toi_rw_header_chunk_noreadahead(int writing,
-+              struct toi_module_ops *owner, char *buffer, int size)
-+{
-+      return _toi_rw_header_chunk(writing, owner, buffer, size, 1);
++
++      if (unlikely(test_action_state(TOI_TEST_BIO))) {
++              /* Fake having done the hard work */
++              set_bit(BIO_UPTODATE, &bio->bi_flags);
++              toi_end_bio(bio, 0);
++      } else
++              submit_bio(writing | (1 << BIO_RW_SYNCIO) |
++                              (1 << BIO_RW_TUXONICE) |
++                              (1 << BIO_RW_UNPLUG), bio);
++
++      return 0;
 +}
 +
 +/**
-+ * write_header_chunk_finish - flush any buffered header data
++ * toi_do_io: Prepare to do some i/o on a page and submit or batch it.
++ *
++ * @writing: Whether reading or writing.
++ * @bdev: The block device which we're using.
++ * @block0: The first sector we're reading or writing.
++ * @page: The page on which I/O is being done.
++ * @readahead_index: If doing readahead, the index (reset this flag when done).
++ * @syncio: Whether the i/o is being done synchronously.
++ *
++ * Prepare and start a read or write operation.
++ *
++ * Note that we always work with our own page. If writing, we might be given a
++ * compression buffer that will immediately be used to start compressing the
++ * next page. For reading, we do readahead and therefore don't know the final
++ * address where the data needs to go.
 + **/
-+static int write_header_chunk_finish(void)
++int toi_do_io(int writing, struct block_device *bdev, long block0,
++      struct page *page, int is_readahead, int syncio, int free_group)
 +{
-+      int result = 0;
++      page->private = 0;
 +
-+      if (toi_writer_buffer_posn)
-+              toi_bio_queue_write(&toi_writer_buffer);
++      /* Do here so we don't race against toi_bio_get_next_page_read */
++      lock_page(page);
 +
-+      result = toi_finish_all_io();
++      if (is_readahead) {
++              if (readahead_list_head)
++                      readahead_list_tail->private = (unsigned long) page;
++              else
++                      readahead_list_head = page;
 +
-+      unowned = 0;
-+      total_header_bytes = 0;
-+      return result;
-+}
++              readahead_list_tail = page;
++      }
 +
-+/**
-+ * toi_bio_storage_needed - get the amount of storage needed for my fns
-+ **/
-+static int toi_bio_storage_needed(void)
-+{
-+      return sizeof(int);
++      /* Done before submitting to avoid races. */
++      if (syncio)
++              waiting_on = page;
++
++      /* Submit the page */
++      get_page(page);
++
++      if (submit(writing, bdev, block0, page, free_group))
++              return -EFAULT;
++
++      if (syncio)
++              do_bio_wait(2);
++
++      return 0;
 +}
 +
 +/**
-+ * toi_bio_save_config_info - save block I/O config to image header
-+ * @buf:      PAGE_SIZE'd buffer into which data should be saved.
++ * toi_bdev_page_io - simpler interface to do directly i/o on a single page
++ * @writing: Whether reading or writing.
++ * @bdev: Block device on which we're operating.
++ * @pos: Sector at which page to read or write starts.
++ * @page: Page to be read/written.
++ *
++ * A simple interface to submit a page of I/O and wait for its completion.
++ * The caller must free the page used.
 + **/
-+static int toi_bio_save_config_info(char *buf)
++static int toi_bdev_page_io(int writing, struct block_device *bdev,
++              long pos, struct page *page)
 +{
-+      int *ints = (int *) buf;
-+      ints[0] = target_outstanding_io;
-+      return sizeof(int);
++      return toi_do_io(writing, bdev, pos, page, 0, 1, 0);
 +}
 +
 +/**
-+ * toi_bio_load_config_info - restore block I/O config
-+ * @buf:      Data to be reloaded.
-+ * @size:     Size of the buffer saved.
++ * toi_bio_memory_needed - report the amount of memory needed for block i/o
++ *
++ * We want to have at least enough memory so as to have target_outstanding_io
++ * or more transactions on the fly at once. If we can do more, fine.
 + **/
-+static void toi_bio_load_config_info(char *buf, int size)
++static int toi_bio_memory_needed(void)
 +{
-+      int *ints = (int *) buf;
-+      target_outstanding_io  = ints[0];
++      return target_outstanding_io * (PAGE_SIZE + sizeof(struct request) +
++                              sizeof(struct bio));
 +}
 +
 +/**
-+ * toi_bio_initialise - initialise bio code at start of some action
-+ * @starting_cycle:   Whether starting a hibernation cycle, or just reading or
-+ *                    writing a sysfs value.
++ * toi_bio_print_debug_stats - put out debugging info in the buffer provided
++ * @buffer: A buffer of size @size into which text should be placed.
++ * @size: The size of @buffer.
++ *
++ * Fill a buffer with debugging info. This is used for both our debug_info sysfs
++ * entry and for recording the same info in dmesg.
 + **/
-+static int toi_bio_initialise(int starting_cycle)
++static int toi_bio_print_debug_stats(char *buffer, int size)
 +{
-+      if (starting_cycle) {
-+              max_outstanding_writes = 0;
-+              max_outstanding_reads = 0;
-+              toi_queue_flusher = current;
-+#ifdef MEASURE_MUTEX_CONTENTION
-+              {
-+              int i, j, k;
++      int len = 0;
 +
-+              for (i = 0; i < 2; i++)
-+                      for (j = 0; j < 2; j++)
-+                              for_each_online_cpu(k)
-+                                      mutex_times[i][j][k] = 0;
-+              }
-+#endif
++      if (toiActiveAllocator != &toi_blockwriter_ops) {
++              len = scnprintf(buffer, size,
++                              "- Block I/O inactive.\n");
++              return len;
 +      }
 +
-+      return 0;
-+}
++      len = scnprintf(buffer, size, "- Block I/O active.\n");
 +
-+/**
-+ * toi_bio_cleanup - cleanup after some action
-+ * @finishing_cycle:  Whether completing a cycle.
-+ **/
-+static void toi_bio_cleanup(int finishing_cycle)
-+{
-+      if (toi_writer_buffer) {
-+              toi_free_page(11, (unsigned long) toi_writer_buffer);
-+              toi_writer_buffer = NULL;
-+      }
-+}
++      len += scnprintf(buffer + len, size - len,
++                      "- Max outstanding reads %d. Max writes %d.\n",
++                      max_outstanding_reads, max_outstanding_writes);
 +
-+struct toi_bio_ops toi_bio_ops = {
-+      .bdev_page_io = toi_bdev_page_io,
-+      .finish_all_io = toi_finish_all_io,
-+      .update_throughput_throttle = update_throughput_throttle,
-+      .forward_one_page = go_next_page,
-+      .set_extra_page_forward = set_extra_page_forward,
-+      .set_devinfo = toi_set_devinfo,
-+      .read_page = toi_bio_read_page,
-+      .write_page = toi_bio_write_page,
-+      .rw_init = toi_rw_init,
-+      .rw_cleanup = toi_rw_cleanup,
-+      .read_header_init = toi_read_header_init,
-+      .rw_header_chunk = toi_rw_header_chunk,
-+      .rw_header_chunk_noreadahead = toi_rw_header_chunk_noreadahead,
-+      .write_header_chunk_finish = write_header_chunk_finish,
-+      .io_flusher = bio_io_flusher,
-+};
-+EXPORT_SYMBOL_GPL(toi_bio_ops);
++      len += scnprintf(buffer + len, size - len,
++              "  Memory_needed: %d x (%lu + %u + %u) = %d bytes.\n",
++              target_outstanding_io,
++              PAGE_SIZE, (unsigned int) sizeof(struct request),
++              (unsigned int) sizeof(struct bio), toi_bio_memory_needed());
 +
-+static struct toi_sysfs_data sysfs_params[] = {
-+      SYSFS_INT("target_outstanding_io", SYSFS_RW, &target_outstanding_io,
-+                      0, 16384, 0, NULL),
-+};
++#ifdef MEASURE_MUTEX_CONTENTION
++      {
++      int i;
 +
-+static struct toi_module_ops toi_blockwriter_ops = {
-+      .name                                   = "lowlevel i/o",
-+      .type                                   = MISC_HIDDEN_MODULE,
-+      .directory                              = "block_io",
-+      .module                                 = THIS_MODULE,
-+      .print_debug_info                       = toi_bio_print_debug_stats,
-+      .memory_needed                          = toi_bio_memory_needed,
-+      .storage_needed                         = toi_bio_storage_needed,
-+      .save_config_info                       = toi_bio_save_config_info,
-+      .load_config_info                       = toi_bio_load_config_info,
-+      .initialise                             = toi_bio_initialise,
-+      .cleanup                                = toi_bio_cleanup,
++      len += scnprintf(buffer + len, size - len,
++              "  Mutex contention while reading:\n  Contended      Free\n");
 +
-+      .sysfs_data             = sysfs_params,
-+      .num_sysfs_entries      = sizeof(sysfs_params) /
-+              sizeof(struct toi_sysfs_data),
-+};
++      for_each_online_cpu(i)
++              len += scnprintf(buffer + len, size - len,
++              "  %9lu %9lu\n",
++              mutex_times[0][0][i], mutex_times[0][1][i]);
 +
-+/**
-+ * toi_block_io_load - load time routine for block I/O module
-+ *
-+ * Register block i/o ops and sysfs entries.
-+ **/
-+static __init int toi_block_io_load(void)
-+{
-+      return toi_register_module(&toi_blockwriter_ops);
-+}
++      len += scnprintf(buffer + len, size - len,
++              "  Mutex contention while writing:\n  Contended      Free\n");
 +
-+#ifdef MODULE
-+static __exit void toi_block_io_unload(void)
-+{
-+      toi_unregister_module(&toi_blockwriter_ops);
-+}
++      for_each_online_cpu(i)
++              len += scnprintf(buffer + len, size - len,
++              "  %9lu %9lu\n",
++              mutex_times[1][0][i], mutex_times[1][1][i]);
 +
-+module_init(toi_block_io_load);
-+module_exit(toi_block_io_unload);
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Nigel Cunningham");
-+MODULE_DESCRIPTION("TuxOnIce block io functions");
-+#else
-+late_initcall(toi_block_io_load);
++      }
 +#endif
-diff --git a/kernel/power/tuxonice_block_io.h b/kernel/power/tuxonice_block_io.h
-new file mode 100644
-index 0000000..b18298c
---- /dev/null
-+++ b/kernel/power/tuxonice_block_io.h
-@@ -0,0 +1,59 @@
-+/*
-+ * kernel/power/tuxonice_block_io.h
-+ *
-+ * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
-+ * Copyright (C) 2006 Red Hat, inc.
-+ *
-+ * Distributed under GPLv2.
-+ *
-+ * This file contains declarations for functions exported from
-+ * tuxonice_block_io.c, which contains low level io functions.
-+ */
-+
-+#include <linux/buffer_head.h>
-+#include "tuxonice_extent.h"
 +
-+struct toi_bdev_info {
-+      struct block_device *bdev;
-+      dev_t dev_t;
-+      int bmap_shift;
-+      int blocks_per_page;
-+      int ignored;
-+};
++      return len + scnprintf(buffer + len, size - len,
++              "  Free mem throttle point reached %d.\n", free_mem_throttle);
++}
 +
-+/*
-+ * Our exported interface so the swapwriter and filewriter don't
-+ * need these functions duplicated.
-+ */
-+struct toi_bio_ops {
-+      int (*bdev_page_io) (int rw, struct block_device *bdev, long pos,
-+                      struct page *page);
-+      void (*check_io_stats) (void);
-+      void (*reset_io_stats) (void);
-+      void (*update_throughput_throttle) (int jif_index);
-+      int (*finish_all_io) (void);
-+      int (*forward_one_page) (int writing, int section_barrier);
-+      void (*set_extra_page_forward) (void);
-+      void (*set_devinfo) (struct toi_bdev_info *info);
-+      int (*read_page) (unsigned long *index, struct page *buffer_page,
-+                      unsigned int *buf_size);
-+      int (*write_page) (unsigned long index, struct page *buffer_page,
-+                      unsigned int buf_size);
-+      void (*read_header_init) (void);
-+      int (*rw_header_chunk) (int rw, struct toi_module_ops *owner,
-+                      char *buffer, int buffer_size);
-+      int (*rw_header_chunk_noreadahead) (int rw,
-+                      struct toi_module_ops *owner,
-+                      char *buffer, int buffer_size);
-+      int (*write_header_chunk_finish) (void);
-+      int (*rw_init) (int rw, int stream_number);
-+      int (*rw_cleanup) (int rw);
-+      int (*io_flusher) (int rw);
-+};
++static int total_header_bytes;
++static int unowned;
 +
-+extern struct toi_bio_ops toi_bio_ops;
++void debug_broken_header(void)
++{
++      printk(KERN_DEBUG "Image header too big for size allocated!\n");
++      print_toi_header_storage_for_modules();
++      printk(KERN_DEBUG "Page flags : %d.\n", toi_pageflags_space_needed());
++      printk(KERN_DEBUG "toi_header : %ld.\n", sizeof(struct toi_header));
++      printk(KERN_DEBUG "Total unowned : %d.\n", unowned);
++      printk(KERN_DEBUG "Total used : %d (%ld pages).\n", total_header_bytes,
++                      DIV_ROUND_UP(total_header_bytes, PAGE_SIZE));
++      printk(KERN_DEBUG "Space needed now : %ld.\n",
++                      get_header_storage_needed());
++      dump_block_chains();
++      abort_hibernate(TOI_HEADER_TOO_BIG, "Header reservation too small.");
++}
 +
-+extern char *toi_writer_buffer;
-+extern int toi_writer_buffer_posn;
-+extern struct hibernate_extent_iterate_saved_state toi_writer_posn_save[4];
-+extern struct toi_extent_iterate_state toi_writer_posn;
-diff --git a/kernel/power/tuxonice_builtin.c b/kernel/power/tuxonice_builtin.c
-new file mode 100644
-index 0000000..2e3be44
---- /dev/null
-+++ b/kernel/power/tuxonice_builtin.c
-@@ -0,0 +1,324 @@
-+/*
-+ * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
++/**
++ * toi_rw_init - prepare to read or write a stream in the image
++ * @writing: Whether reading or writing.
++ * @stream number: Section of the image being processed.
 + *
-+ * This file is released under the GPLv2.
-+ */
-+#include <linux/resume-trace.h>
-+#include <linux/kernel.h>
-+#include <linux/swap.h>
-+#include <linux/syscalls.h>
-+#include <linux/bio.h>
-+#include <linux/root_dev.h>
-+#include <linux/freezer.h>
-+#include <linux/reboot.h>
-+#include <linux/writeback.h>
-+#include <linux/tty.h>
-+#include <linux/crypto.h>
-+#include <linux/cpu.h>
-+#include <linux/ctype.h>
-+#include "tuxonice_io.h"
-+#include "tuxonice.h"
-+#include "tuxonice_extent.h"
-+#include "tuxonice_netlink.h"
-+#include "tuxonice_prepare_image.h"
-+#include "tuxonice_ui.h"
-+#include "tuxonice_sysfs.h"
-+#include "tuxonice_pagedir.h"
-+#include "tuxonice_modules.h"
-+#include "tuxonice_builtin.h"
-+#include "tuxonice_power_off.h"
++ * Prepare to read or write a section ('stream') in the image.
++ **/
++static int toi_rw_init(int writing, int stream_number)
++{
++      if (stream_number)
++              toi_extent_state_restore(stream_number);
++      else
++              toi_extent_state_goto_start();
 +
-+/*
-+ * Highmem related functions (x86 only).
-+ */
++      if (writing) {
++              reset_idx = 0;
++              if (!current_stream)
++                      page_idx = 0;
++      } else {
++              reset_idx = 1;
++      }
 +
-+#ifdef CONFIG_HIGHMEM
++      atomic_set(&toi_io_done, 0);
++      if (!toi_writer_buffer)
++              toi_writer_buffer = (char *) toi_get_zeroed_page(11,
++                              TOI_ATOMIC_GFP);
++      toi_writer_buffer_posn = writing ? 0 : PAGE_SIZE;
++
++      current_stream = stream_number;
++
++      more_readahead = 1;
++
++      return toi_writer_buffer ? 0 : -ENOMEM;
++}
 +
 +/**
-+ * copyback_high: Restore highmem pages.
++ * toi_bio_queue_write - queue a page for writing
++ * @full_buffer: Pointer to a page to be queued
 + *
-+ * Highmem data and pbe lists are/can be stored in highmem.
-+ * The format is slightly different to the lowmem pbe lists
-+ * used for the assembly code: the last pbe in each page is
-+ * a struct page * instead of struct pbe *, pointing to the
-+ * next page where pbes are stored (or NULL if happens to be
-+ * the end of the list). Since we don't want to generate
-+ * unnecessary deltas against swsusp code, we use a cast
-+ * instead of a union.
++ * Add a page to the queue to be submitted. If we're the queue flusher,
++ * we'll do this once we've dropped toi_bio_mutex, so other threads can
++ * continue to submit I/O while we're on the slow path doing the actual
++ * submission.
 + **/
-+
-+static void copyback_high(void)
++static void toi_bio_queue_write(char **full_buffer)
 +{
-+      struct page *pbe_page = (struct page *) restore_highmem_pblist;
-+      struct pbe *this_pbe, *first_pbe;
-+      unsigned long *origpage, *copypage;
-+      int pbe_index = 1;
-+
-+      if (!pbe_page)
-+              return;
++      struct page *page = virt_to_page(*full_buffer);
++      unsigned long flags;
 +
-+      this_pbe = (struct pbe *) kmap_atomic(pbe_page, KM_BOUNCE_READ);
-+      first_pbe = this_pbe;
++      *full_buffer = NULL;
++      page->private = 0;
 +
-+      while (this_pbe) {
-+              int loop = (PAGE_SIZE / sizeof(unsigned long)) - 1;
++      spin_lock_irqsave(&bio_queue_lock, flags);
++      if (!bio_queue_head)
++              bio_queue_head = page;
++      else
++              bio_queue_tail->private = (unsigned long) page;
 +
-+              origpage = kmap_atomic((struct page *) this_pbe->orig_address,
-+                      KM_BIO_DST_IRQ);
-+              copypage = kmap_atomic((struct page *) this_pbe->address,
-+                      KM_BIO_SRC_IRQ);
++      bio_queue_tail = page;
++      atomic_inc(&toi_bio_queue_size);
 +
-+              while (loop >= 0) {
-+                      *(origpage + loop) = *(copypage + loop);
-+                      loop--;
-+              }
++      spin_unlock_irqrestore(&bio_queue_lock, flags);
++      wake_up(&toi_io_queue_flusher);
++}
 +
-+              kunmap_atomic(origpage, KM_BIO_DST_IRQ);
-+              kunmap_atomic(copypage, KM_BIO_SRC_IRQ);
++/**
++ * toi_rw_cleanup - Cleanup after i/o.
++ * @writing: Whether we were reading or writing.
++ *
++ * Flush all I/O and clean everything up after reading or writing a
++ * section of the image.
++ **/
++static int toi_rw_cleanup(int writing)
++{
++      int i, result;
 +
-+              if (!this_pbe->next)
-+                      break;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_rw_cleanup.");
++      if (writing) {
++              int result;
 +
-+              if (pbe_index < PBES_PER_PAGE) {
-+                      this_pbe++;
-+                      pbe_index++;
-+              } else {
-+                      pbe_page = (struct page *) this_pbe->next;
-+                      kunmap_atomic(first_pbe, KM_BOUNCE_READ);
-+                      if (!pbe_page)
-+                              return;
-+                      this_pbe = (struct pbe *) kmap_atomic(pbe_page,
-+                                      KM_BOUNCE_READ);
-+                      first_pbe = this_pbe;
-+                      pbe_index = 1;
-+              }
-+      }
-+      kunmap_atomic(first_pbe, KM_BOUNCE_READ);
-+}
++              if (toi_writer_buffer_posn && !test_result_state(TOI_ABORTED))
++                      toi_bio_queue_write(&toi_writer_buffer);
 +
-+#else /* CONFIG_HIGHMEM */
-+static void copyback_high(void) { }
-+#endif
++              result = toi_bio_queue_flush_pages(0);
 +
-+char toi_wait_for_keypress_dev_console(int timeout)
-+{
-+      int fd, this_timeout = 255;
-+      char key = '\0';
-+      struct termios t, t_backup;
++              if (result)
++                      return result;
 +
-+      /* We should be guaranteed /dev/console exists after populate_rootfs()
-+       * in init/main.c.
-+       */
-+      fd = sys_open("/dev/console", O_RDONLY, 0);
-+      if (fd < 0) {
-+              printk(KERN_INFO "Couldn't open /dev/console.\n");
-+              return key;
++              if (current_stream == 2)
++                      toi_extent_state_save(1);
++              else if (current_stream == 1)
++                      toi_extent_state_save(3);
 +      }
 +
-+      if (sys_ioctl(fd, TCGETS, (long)&t) < 0)
-+              goto out_close;
-+
-+      memcpy(&t_backup, &t, sizeof(t));
-+
-+      t.c_lflag &= ~(ISIG|ICANON|ECHO);
-+      t.c_cc[VMIN] = 0;
++      result = toi_finish_all_io();
 +
-+new_timeout:
-+      if (timeout > 0) {
-+              this_timeout = timeout < 26 ? timeout : 25;
-+              timeout -= this_timeout;
-+              this_timeout *= 10;
++      while (readahead_list_head) {
++              void *next = (void *) readahead_list_head->private;
++              toi__free_page(12, readahead_list_head);
++              readahead_list_head = next;
 +      }
 +
-+      t.c_cc[VTIME] = this_timeout;
++      readahead_list_tail = NULL;
 +
-+      if (sys_ioctl(fd, TCSETS, (long)&t) < 0)
-+              goto out_restore;
++      if (!current_stream)
++              return result;
 +
-+      while (1) {
-+              if (sys_read(fd, &key, 1) <= 0) {
-+                      if (timeout)
-+                              goto new_timeout;
-+                      key = '\0';
-+                      break;
-+              }
-+              key = tolower(key);
-+              if (test_toi_state(TOI_SANITY_CHECK_PROMPT)) {
-+                      if (key == 'c') {
-+                              set_toi_state(TOI_CONTINUE_REQ);
-+                              break;
-+                      } else if (key == ' ')
-+                              break;
-+              } else
-+                      break;
++      for (i = 0; i < NUM_REASONS; i++) {
++              if (!atomic_read(&reasons[i]))
++                      continue;
++              printk(KERN_DEBUG "Waited for i/o due to %s %d times.\n",
++                              reason_name[i], atomic_read(&reasons[i]));
++              atomic_set(&reasons[i], 0);
 +      }
 +
-+out_restore:
-+      sys_ioctl(fd, TCSETS, (long)&t_backup);
-+out_close:
-+      sys_close(fd);
-+
-+      return key;
++      current_stream = 0;
++      return result;
 +}
-+EXPORT_SYMBOL_GPL(toi_wait_for_keypress_dev_console);
-+
-+struct toi_boot_kernel_data toi_bkd __nosavedata
-+              __attribute__((aligned(PAGE_SIZE))) = {
-+      MY_BOOT_KERNEL_DATA_VERSION,
-+      0,
-+#ifdef CONFIG_TOI_REPLACE_SWSUSP
-+      (1 << TOI_REPLACE_SWSUSP) |
-+#endif
-+      (1 << TOI_NO_FLUSHER_THREAD) |
-+      (1 << TOI_PAGESET2_FULL) | (1 << TOI_LATE_CPU_HOTPLUG),
-+};
-+EXPORT_SYMBOL_GPL(toi_bkd);
 +
-+struct block_device *toi_open_by_devnum(dev_t dev, fmode_t mode)
++/**
++ * toi_start_one_readahead - start one page of readahead
++ * @dedicated_thread: Is this a thread dedicated to doing readahead?
++ *
++ * Start one new page of readahead. If this is being called by a thread
++ * whose only just is to submit readahead, don't quit because we failed
++ * to allocate a page.
++ **/
++static int toi_start_one_readahead(int dedicated_thread)
 +{
-+      struct block_device *bdev = bdget(dev);
-+      int err = -ENOMEM;
-+      if (bdev)
-+              err = blkdev_get(bdev, mode);
-+      return err ? ERR_PTR(err) : bdev;
-+}
-+EXPORT_SYMBOL_GPL(toi_open_by_devnum);
++      char *buffer = NULL;
++      int oom = 0, result;
 +
-+int toi_wait = CONFIG_TOI_DEFAULT_WAIT;
-+EXPORT_SYMBOL_GPL(toi_wait);
++      result = throttle_if_needed(dedicated_thread ? THROTTLE_WAIT : 0);
++      if (result) {
++              printk(KERN_ERR "throttle_if_needed returned %d.\n", result);
++              return result;
++      }
 +
-+struct toi_core_fns *toi_core_fns;
-+EXPORT_SYMBOL_GPL(toi_core_fns);
++      mutex_lock(&toi_bio_readahead_mutex);
 +
-+unsigned long toi_result;
-+EXPORT_SYMBOL_GPL(toi_result);
++      while (!buffer) {
++              buffer = (char *) toi_get_zeroed_page(12,
++                              TOI_ATOMIC_GFP);
++              if (!buffer) {
++                      if (oom && !dedicated_thread) {
++                              mutex_unlock(&toi_bio_readahead_mutex);
++                              printk(KERN_ERR
++                                      "oom and not dedicated thread.\n");
++                              return -ENOMEM;
++                      }
 +
-+struct pagedir pagedir1 = {1};
-+EXPORT_SYMBOL_GPL(pagedir1);
++                      oom = 1;
++                      set_free_mem_throttle();
++                      do_bio_wait(5);
++              }
++      }
 +
-+unsigned long toi_get_nonconflicting_page(void)
-+{
-+      return toi_core_fns->get_nonconflicting_page();
++      result = toi_bio_rw_page(READ, virt_to_page(buffer), 1, 0);
++      if (result == -ENODATA)
++              toi__free_page(12, virt_to_page(buffer));
++      mutex_unlock(&toi_bio_readahead_mutex);
++      if (result)
++              printk(KERN_DEBUG "toi_bio_rw_page returned %d.\n", result);
++      return result;
 +}
 +
-+int toi_post_context_save(void)
++/**
++ * toi_start_new_readahead - start new readahead
++ * @dedicated_thread: Are we dedicated to this task?
++ *
++ * Start readahead of image pages.
++ *
++ * We can be called as a thread dedicated to this task (may be helpful on
++ * systems with lots of CPUs), in which case we don't exit until there's no
++ * more readahead.
++ *
++ * If this is not called by a dedicated thread, we top up our queue until
++ * there's no more readahead to submit, we've submitted the number given
++ * in target_outstanding_io or the number in progress exceeds the target
++ * outstanding I/O value.
++ *
++ * No mutex needed because this is only ever called by the first cpu.
++ **/
++static int toi_start_new_readahead(int dedicated_thread)
 +{
-+      return toi_core_fns->post_context_save();
-+}
++      int last_result, num_submitted = 0;
 +
-+int try_tuxonice_hibernate(void)
-+{
-+      if (!toi_core_fns)
-+              return -ENODEV;
++      /* Start a new readahead? */
++      if (!more_readahead)
++              return 0;
 +
-+      return toi_core_fns->try_hibernate();
-+}
++      do {
++              last_result = toi_start_one_readahead(dedicated_thread);
 +
-+static int num_resume_calls;
-+#ifdef CONFIG_TOI_IGNORE_LATE_INITCALL
-+static int ignore_late_initcall = 1;
-+#else
-+static int ignore_late_initcall;
-+#endif
++              if (last_result) {
++                      if (last_result == -ENOMEM || last_result == -ENODATA)
++                              return 0;
 +
-+int toi_translate_err_default = TOI_CONTINUE_REQ;
-+EXPORT_SYMBOL_GPL(toi_translate_err_default);
++                      printk(KERN_DEBUG
++                              "Begin read chunk returned %d.\n",
++                              last_result);
++              } else
++                      num_submitted++;
 +
-+void try_tuxonice_resume(void)
-+{
-+      /* Don't let it wrap around eventually */
-+      if (num_resume_calls < 2)
-+              num_resume_calls++;
++      } while (more_readahead && !last_result &&
++               (dedicated_thread ||
++                (num_submitted < target_outstanding_io &&
++                 atomic_read(&toi_io_in_progress) < target_outstanding_io)));
 +
-+      if (num_resume_calls == 1 && ignore_late_initcall) {
-+              printk(KERN_INFO "TuxOnIce: Ignoring late initcall, as requested.\n");
-+              return;
-+      }
++      return last_result;
++}
 +
-+      if (toi_core_fns)
-+              toi_core_fns->try_resume();
++/**
++ * bio_io_flusher - start the dedicated I/O flushing routine
++ * @writing: Whether we're writing the image.
++ **/
++static int bio_io_flusher(int writing)
++{
++
++      if (writing)
++              return toi_bio_queue_flush_pages(1);
 +      else
-+              printk(KERN_INFO "TuxOnIce core not loaded yet.\n");
++              return toi_start_new_readahead(1);
 +}
 +
-+int toi_lowlevel_builtin(void)
++/**
++ * toi_bio_get_next_page_read - read a disk page, perhaps with readahead
++ * @no_readahead: Whether we can use readahead
++ *
++ * Read a page from disk, submitting readahead and cleaning up finished i/o
++ * while we wait for the page we're after.
++ **/
++static int toi_bio_get_next_page_read(int no_readahead)
 +{
-+      int error = 0;
++      unsigned long *virt;
++      struct page *next;
 +
-+      save_processor_state();
-+      error = swsusp_arch_suspend();
-+      if (error)
-+              printk(KERN_ERR "Error %d hibernating\n", error);
++      /*
++       * When reading the second page of the header, we have to
++       * delay submitting the read until after we've gotten the
++       * extents out of the first page.
++       */
++      if (unlikely(no_readahead && toi_start_one_readahead(0))) {
++              printk(KERN_EMERG "No readahead and toi_start_one_readahead "
++                              "returned non-zero.\n");
++              return -EIO;
++      }
 +
-+      /* Restore control flow appears here */
-+      if (!toi_in_hibernate) {
-+              copyback_high();
-+              set_toi_state(TOI_NOW_RESUMING);
++      if (unlikely(!readahead_list_head)) {
++              /*
++               * If the last page finishes exactly on the page
++               * boundary, we will be called one extra time and
++               * have no data to return. In this case, we should
++               * not BUG(), like we used to!
++               */
++              if (!more_readahead) {
++                      printk(KERN_EMERG "No more readahead.\n");
++                      return -ENODATA;
++              }
++              if (unlikely(toi_start_one_readahead(0))) {
++                      printk(KERN_EMERG "No readahead and "
++                       "toi_start_one_readahead returned non-zero.\n");
++                      return -EIO;
++              }
 +      }
 +
-+      restore_processor_state();
++      if (PageLocked(readahead_list_head)) {
++              waiting_on = readahead_list_head;
++              do_bio_wait(0);
++      }
 +
-+      return error;
++      virt = page_address(readahead_list_head);
++      memcpy(toi_writer_buffer, virt, PAGE_SIZE);
++
++      next = (struct page *) readahead_list_head->private;
++      toi__free_page(12, readahead_list_head);
++      readahead_list_head = next;
++      return 0;
 +}
-+EXPORT_SYMBOL_GPL(toi_lowlevel_builtin);
 +
-+unsigned long toi_compress_bytes_in;
-+EXPORT_SYMBOL_GPL(toi_compress_bytes_in);
++/**
++ * toi_bio_queue_flush_pages - flush the queue of pages queued for writing
++ * @dedicated_thread: Whether we're a dedicated thread
++ *
++ * Flush the queue of pages ready to be written to disk.
++ *
++ * If we're a dedicated thread, stay in here until told to leave,
++ * sleeping in wait_event.
++ *
++ * The first thread is normally the only one to come in here. Another
++ * thread can enter this routine too, though, via throttle_if_needed.
++ * Since that's the case, we must be careful to only have one thread
++ * doing this work at a time. Otherwise we have a race and could save
++ * pages out of order.
++ *
++ * If an error occurs, free all remaining pages without submitting them
++ * for I/O.
++ **/
 +
-+unsigned long toi_compress_bytes_out;
-+EXPORT_SYMBOL_GPL(toi_compress_bytes_out);
++int toi_bio_queue_flush_pages(int dedicated_thread)
++{
++      unsigned long flags;
++      int result = 0;
++      static DEFINE_MUTEX(busy);
 +
-+unsigned long toi_state = ((1 << TOI_BOOT_TIME) |
-+              (1 << TOI_IGNORE_LOGLEVEL) |
-+              (1 << TOI_IO_STOPPED));
-+EXPORT_SYMBOL_GPL(toi_state);
++      if (!mutex_trylock(&busy))
++              return 0;
 +
-+/* The number of hibernates we have started (some may have been cancelled) */
-+unsigned int nr_hibernates;
-+EXPORT_SYMBOL_GPL(nr_hibernates);
-+
-+int toi_running;
-+EXPORT_SYMBOL_GPL(toi_running);
++top:
++      spin_lock_irqsave(&bio_queue_lock, flags);
++      while (bio_queue_head) {
++              struct page *page = bio_queue_head;
++              bio_queue_head = (struct page *) page->private;
++              if (bio_queue_tail == page)
++                      bio_queue_tail = NULL;
++              atomic_dec(&toi_bio_queue_size);
++              spin_unlock_irqrestore(&bio_queue_lock, flags);
++              result = toi_bio_rw_page(WRITE, page, 0, 11);
++              /*
++               * If writing the page failed, don't drop out.
++               * Flush the rest of the queue too.
++               */
++              if (result)
++                      toi__free_page(11 , page);
++              spin_lock_irqsave(&bio_queue_lock, flags);
++      }
++      spin_unlock_irqrestore(&bio_queue_lock, flags);
 +
-+__nosavedata int toi_in_hibernate;
-+EXPORT_SYMBOL_GPL(toi_in_hibernate);
++      if (dedicated_thread) {
++              wait_event(toi_io_queue_flusher, bio_queue_head ||
++                              toi_bio_queue_flusher_should_finish);
++              if (likely(!toi_bio_queue_flusher_should_finish))
++                      goto top;
++              toi_bio_queue_flusher_should_finish = 0;
++      }
 +
-+__nosavedata struct pbe *restore_highmem_pblist;
-+EXPORT_SYMBOL_GPL(restore_highmem_pblist);
++      mutex_unlock(&busy);
++      return result;
++}
 +
-+static int __init toi_wait_setup(char *str)
++/**
++ * toi_bio_get_new_page - get a new page for I/O
++ * @full_buffer: Pointer to a page to allocate.
++ **/
++static int toi_bio_get_new_page(char **full_buffer)
 +{
-+      int value;
++      int result = throttle_if_needed(THROTTLE_WAIT);
++      if (result)
++              return result;
 +
-+      if (sscanf(str, "=%d", &value)) {
-+              if (value < -1 || value > 255)
-+                      printk(KERN_INFO "TuxOnIce_wait outside range -1 to "
-+                                      "255.\n");
-+              else
-+                      toi_wait = value;
++      while (!*full_buffer) {
++              *full_buffer = (char *) toi_get_zeroed_page(11, TOI_ATOMIC_GFP);
++              if (!*full_buffer) {
++                      set_free_mem_throttle();
++                      do_bio_wait(3);
++              }
 +      }
 +
-+      return 1;
++      return 0;
 +}
 +
-+__setup("toi_wait", toi_wait_setup);
-+
-+static int __init toi_translate_retry_setup(char *str)
++/**
++ * toi_rw_buffer - combine smaller buffers into PAGE_SIZE I/O
++ * @writing:          Bool - whether writing (or reading).
++ * @buffer:           The start of the buffer to write or fill.
++ * @buffer_size:      The size of the buffer to write or fill.
++ * @no_readahead:     Don't try to start readhead (when getting extents).
++ **/
++static int toi_rw_buffer(int writing, char *buffer, int buffer_size,
++              int no_readahead)
 +{
-+      toi_translate_err_default = 0;
-+      return 1;
-+}
++      int bytes_left = buffer_size, result = 0;
 +
-+__setup("toi_translate_retry", toi_translate_retry_setup);
++      while (bytes_left) {
++              char *source_start = buffer + buffer_size - bytes_left;
++              char *dest_start = toi_writer_buffer + toi_writer_buffer_posn;
++              int capacity = PAGE_SIZE - toi_writer_buffer_posn;
++              char *to = writing ? dest_start : source_start;
++              char *from = writing ? source_start : dest_start;
 +
-+static int __init toi_ignore_late_initcall_setup(char *str)
-+{
-+      int value;
++              if (bytes_left <= capacity) {
++                      memcpy(to, from, bytes_left);
++                      toi_writer_buffer_posn += bytes_left;
++                      return 0;
++              }
 +
-+      if (sscanf(str, "=%d", &value))
-+              ignore_late_initcall = value;
++              /* Complete this page and start a new one */
++              memcpy(to, from, capacity);
++              bytes_left -= capacity;
 +
-+      return 1;
++              if (!writing) {
++                      /*
++                       * Perform actual I/O:
++                       * read readahead_list_head into toi_writer_buffer
++                       */
++                      int result = toi_bio_get_next_page_read(no_readahead);
++                      if (result) {
++                              printk("toi_bio_get_next_page_read "
++                                              "returned %d.\n", result);
++                              return result;
++                      }
++              } else {
++                      toi_bio_queue_write(&toi_writer_buffer);
++                      result = toi_bio_get_new_page(&toi_writer_buffer);
++                      if (result) {
++                              printk(KERN_ERR "toi_bio_get_new_page returned "
++                                              "%d.\n", result);
++                              return result;
++                      }
++              }
++
++              toi_writer_buffer_posn = 0;
++              toi_cond_pause(0, NULL);
++      }
++
++      return 0;
 +}
 +
-+__setup("toi_initramfs_resume_only", toi_ignore_late_initcall_setup);
-diff --git a/kernel/power/tuxonice_builtin.h b/kernel/power/tuxonice_builtin.h
-new file mode 100644
-index 0000000..82d926f
---- /dev/null
-+++ b/kernel/power/tuxonice_builtin.h
-@@ -0,0 +1,28 @@
-+/*
-+ * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
++/**
++ * toi_bio_read_page - read a page of the image
++ * @pfn:              The pfn where the data belongs.
++ * @buffer_page:      The page containing the (possibly compressed) data.
++ * @buf_size:         The number of bytes on @buffer_page used (PAGE_SIZE).
 + *
-+ * This file is released under the GPLv2.
-+ */
-+#include <asm/setup.h>
++ * Read a (possibly compressed) page from the image, into buffer_page,
++ * returning its pfn and the buffer size.
++ **/
++static int toi_bio_read_page(unsigned long *pfn, struct page *buffer_page,
++              unsigned int *buf_size)
++{
++      int result = 0;
++      int this_idx;
++      char *buffer_virt = kmap(buffer_page);
 +
-+extern struct toi_core_fns *toi_core_fns;
-+extern unsigned long toi_compress_bytes_in, toi_compress_bytes_out;
-+extern unsigned int nr_hibernates;
-+extern int toi_in_hibernate;
++      /*
++       * Only call start_new_readahead if we don't have a dedicated thread
++       * and we're the queue flusher.
++       */
++      if (current == toi_queue_flusher && more_readahead) {
++              int result2 = toi_start_new_readahead(0);
++              if (result2) {
++                      printk(KERN_DEBUG "Queue flusher and "
++                       "toi_start_one_readahead returned non-zero.\n");
++                      result = -EIO;
++                      goto out;
++              }
++      }
 +
-+extern __nosavedata struct pbe *restore_highmem_pblist;
++      my_mutex_lock(0, &toi_bio_mutex);
 +
-+int toi_lowlevel_builtin(void);
++      /*
++       * Structure in the image:
++       *      [destination pfn|page size|page data]
++       * buf_size is PAGE_SIZE
++       */
++      if (toi_rw_buffer(READ, (char *) &this_idx, sizeof(int), 0) ||
++          toi_rw_buffer(READ, (char *) pfn, sizeof(unsigned long), 0) ||
++          toi_rw_buffer(READ, (char *) buf_size, sizeof(int), 0) ||
++          toi_rw_buffer(READ, buffer_virt, *buf_size, 0)) {
++              abort_hibernate(TOI_FAILED_IO, "Read of data failed.");
++              result = 1;
++      }
 +
-+#ifdef CONFIG_HIGHMEM
-+extern __nosavedata struct zone_data *toi_nosave_zone_list;
-+extern __nosavedata unsigned long toi_nosave_max_pfn;
-+#endif
++      if (reset_idx) {
++              page_idx = this_idx;
++              reset_idx = 0;
++      } else {
++              page_idx++;
++              if (page_idx != this_idx)
++                      printk(KERN_ERR "Got page index %d, expected %d.\n",
++                                      this_idx, page_idx);
++      }
 +
-+extern unsigned long toi_get_nonconflicting_page(void);
-+extern int toi_post_context_save(void);
++      my_mutex_unlock(0, &toi_bio_mutex);
++out:
++      kunmap(buffer_page);
++      return result;
++}
 +
-+extern char toi_wait_for_keypress_dev_console(int timeout);
-+extern struct block_device *toi_open_by_devnum(dev_t dev, fmode_t mode);
-+extern int toi_wait;
-+extern int toi_translate_err_default;
-diff --git a/kernel/power/tuxonice_checksum.c b/kernel/power/tuxonice_checksum.c
-new file mode 100644
-index 0000000..b0adc17
---- /dev/null
-+++ b/kernel/power/tuxonice_checksum.c
-@@ -0,0 +1,375 @@
-+/*
-+ * kernel/power/tuxonice_checksum.c
-+ *
-+ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
-+ * Copyright (C) 2006 Red Hat, inc.
-+ *
-+ * This file is released under the GPLv2.
++/**
++ * toi_bio_write_page - write a page of the image
++ * @pfn:              The pfn where the data belongs.
++ * @buffer_page:      The page containing the (possibly compressed) data.
++ * @buf_size: The number of bytes on @buffer_page used.
 + *
-+ * This file contains data checksum routines for TuxOnIce,
-+ * using cryptoapi. They are used to locate any modifications
-+ * made to pageset 2 while we're saving it.
-+ */
++ * Write a (possibly compressed) page to the image from the buffer, together
++ * with it's index and buffer size.
++ **/
++static int toi_bio_write_page(unsigned long pfn, struct page *buffer_page,
++              unsigned int buf_size)
++{
++      char *buffer_virt;
++      int result = 0, result2 = 0;
 +
-+#include <linux/suspend.h>
-+#include <linux/highmem.h>
-+#include <linux/vmalloc.h>
-+#include <linux/crypto.h>
-+#include <linux/scatterlist.h>
++      if (unlikely(test_action_state(TOI_TEST_FILTER_SPEED)))
++              return 0;
 +
-+#include "tuxonice.h"
-+#include "tuxonice_modules.h"
-+#include "tuxonice_sysfs.h"
-+#include "tuxonice_io.h"
-+#include "tuxonice_pageflags.h"
-+#include "tuxonice_checksum.h"
-+#include "tuxonice_pagedir.h"
-+#include "tuxonice_alloc.h"
++      my_mutex_lock(1, &toi_bio_mutex);
 +
-+static struct toi_module_ops toi_checksum_ops;
++      if (test_result_state(TOI_ABORTED)) {
++              my_mutex_unlock(1, &toi_bio_mutex);
++              return -EIO;
++      }
 +
-+/* Constant at the mo, but I might allow tuning later */
-+static char toi_checksum_name[32] = "md4";
-+/* Bytes per checksum */
-+#define CHECKSUM_SIZE (16)
++      buffer_virt = kmap(buffer_page);
++      page_idx++;
 +
-+#define CHECKSUMS_PER_PAGE ((PAGE_SIZE - sizeof(void *)) / CHECKSUM_SIZE)
++      /*
++       * Structure in the image:
++       *      [destination pfn|page size|page data]
++       * buf_size is PAGE_SIZE
++       */
++      if (toi_rw_buffer(WRITE, (char *) &page_idx, sizeof(int), 0) ||
++          toi_rw_buffer(WRITE, (char *) &pfn, sizeof(unsigned long), 0) ||
++          toi_rw_buffer(WRITE, (char *) &buf_size, sizeof(int), 0) ||
++          toi_rw_buffer(WRITE, buffer_virt, buf_size, 0)) {
++              printk(KERN_DEBUG "toi_rw_buffer returned non-zero to "
++                              "toi_bio_write_page.\n");
++              result = -EIO;
++      }
 +
-+struct cpu_context {
-+      struct crypto_hash *transform;
-+      struct hash_desc desc;
-+      struct scatterlist sg[2];
-+      char *buf;
-+};
-+
-+static DEFINE_PER_CPU(struct cpu_context, contexts);
-+static int pages_allocated;
-+static unsigned long page_list;
-+
-+static int toi_num_resaved;
++      kunmap(buffer_page);
++      my_mutex_unlock(1, &toi_bio_mutex);
 +
-+static unsigned long this_checksum, next_page;
-+static int checksum_index;
++      if (current == toi_queue_flusher)
++              result2 = toi_bio_queue_flush_pages(0);
 +
-+static inline int checksum_pages_needed(void)
-+{
-+      return DIV_ROUND_UP(pagedir2.size, CHECKSUMS_PER_PAGE);
++      return result ? result : result2;
 +}
 +
-+/* ---- Local buffer management ---- */
-+
-+/*
-+ * toi_checksum_cleanup
++/**
++ * _toi_rw_header_chunk - read or write a portion of the image header
++ * @writing:          Whether reading or writing.
++ * @owner:            The module for which we're writing.
++ *                    Used for confirming that modules
++ *                    don't use more header space than they asked for.
++ * @buffer:           Address of the data to write.
++ * @buffer_size:      Size of the data buffer.
++ * @no_readahead:     Don't try to start readhead (when getting extents).
 + *
-+ * Frees memory allocated for our labours.
-+ */
-+static void toi_checksum_cleanup(int ending_cycle)
++ * Perform PAGE_SIZE I/O. Start readahead if needed.
++ **/
++static int _toi_rw_header_chunk(int writing, struct toi_module_ops *owner,
++              char *buffer, int buffer_size, int no_readahead)
 +{
-+      int cpu;
-+
-+      if (ending_cycle) {
-+              for_each_online_cpu(cpu) {
-+                      struct cpu_context *this = &per_cpu(contexts, cpu);
-+                      if (this->transform) {
-+                              crypto_free_hash(this->transform);
-+                              this->transform = NULL;
-+                              this->desc.tfm = NULL;
-+                      }
++      int result = 0;
 +
-+                      if (this->buf) {
-+                              toi_free_page(27, (unsigned long) this->buf);
-+                              this->buf = NULL;
-+                      }
++      if (owner) {
++              owner->header_used += buffer_size;
++              toi_message(TOI_HEADER, TOI_LOW, 1,
++                      "Header: %s : %d bytes (%d/%d) from offset %d.",
++                      owner->name,
++                      buffer_size, owner->header_used,
++                      owner->header_requested,
++                      toi_writer_buffer_posn);
++              if (owner->header_used > owner->header_requested && writing) {
++                      printk(KERN_EMERG "TuxOnIce module %s is using more "
++                              "header space (%u) than it requested (%u).\n",
++                              owner->name,
++                              owner->header_used,
++                              owner->header_requested);
++                      return buffer_size;
 +              }
++      } else {
++              unowned += buffer_size;
++              toi_message(TOI_HEADER, TOI_LOW, 1,
++                      "Header: (No owner): %d bytes (%d total so far) from "
++                      "offset %d.", buffer_size, unowned,
++                      toi_writer_buffer_posn);
 +      }
-+}
-+
-+/*
-+ * toi_crypto_initialise
-+ *
-+ * Prepare to do some work by allocating buffers and transforms.
-+ * Returns: Int: Zero. Even if we can't set up checksum, we still
-+ * seek to hibernate.
-+ */
-+static int toi_checksum_initialise(int starting_cycle)
-+{
-+      int cpu;
-+
-+      if (!(starting_cycle & SYSFS_HIBERNATE) || !toi_checksum_ops.enabled)
-+              return 0;
 +
-+      if (!*toi_checksum_name) {
-+              printk(KERN_INFO "TuxOnIce: No checksum algorithm name set.\n");
-+              return 1;
++      if (!writing && !no_readahead && more_readahead) {
++              result = toi_start_new_readahead(0);
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Start new readahead "
++                              "returned %d.", result);
 +      }
 +
-+      for_each_online_cpu(cpu) {
-+              struct cpu_context *this = &per_cpu(contexts, cpu);
-+              struct page *page;
-+
-+              this->transform = crypto_alloc_hash(toi_checksum_name, 0, 0);
-+              if (IS_ERR(this->transform)) {
-+                      printk(KERN_INFO "TuxOnIce: Failed to initialise the "
-+                              "%s checksum algorithm: %ld.\n",
-+                              toi_checksum_name, (long) this->transform);
-+                      this->transform = NULL;
-+                      return 1;
-+              }
-+
-+              this->desc.tfm = this->transform;
-+              this->desc.flags = 0;
-+
-+              page = toi_alloc_page(27, GFP_KERNEL);
-+              if (!page)
-+                      return 1;
-+              this->buf = page_address(page);
-+              sg_init_one(&this->sg[0], this->buf, PAGE_SIZE);
++      if (!result) {
++              result = toi_rw_buffer(writing, buffer, buffer_size,
++                              no_readahead);
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "rw_buffer returned "
++                              "%d.", result);
 +      }
-+      return 0;
-+}
 +
-+/*
-+ * toi_checksum_print_debug_stats
-+ * @buffer: Pointer to a buffer into which the debug info will be printed.
-+ * @size: Size of the buffer.
-+ *
-+ * Print information to be recorded for debugging purposes into a buffer.
-+ * Returns: Number of characters written to the buffer.
-+ */
++      total_header_bytes += buffer_size;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "_toi_rw_header_chunk returning "
++                      "%d.", result);
++      return result;
++}
 +
-+static int toi_checksum_print_debug_stats(char *buffer, int size)
++static int toi_rw_header_chunk(int writing, struct toi_module_ops *owner,
++              char *buffer, int size)
 +{
-+      int len;
-+
-+      if (!toi_checksum_ops.enabled)
-+              return scnprintf(buffer, size,
-+                      "- Checksumming disabled.\n");
-+
-+      len = scnprintf(buffer, size, "- Checksum method is '%s'.\n",
-+                      toi_checksum_name);
-+      len += scnprintf(buffer + len, size - len,
-+              "  %d pages resaved in atomic copy.\n", toi_num_resaved);
-+      return len;
++      return _toi_rw_header_chunk(writing, owner, buffer, size, 1);
 +}
 +
-+static int toi_checksum_memory_needed(void)
++static int toi_rw_header_chunk_noreadahead(int writing,
++              struct toi_module_ops *owner, char *buffer, int size)
 +{
-+      return toi_checksum_ops.enabled ?
-+              checksum_pages_needed() << PAGE_SHIFT : 0;
++      return _toi_rw_header_chunk(writing, owner, buffer, size, 1);
 +}
 +
-+static int toi_checksum_storage_needed(void)
++/**
++ * toi_bio_storage_needed - get the amount of storage needed for my fns
++ **/
++static int toi_bio_storage_needed(void)
 +{
-+      if (toi_checksum_ops.enabled)
-+              return strlen(toi_checksum_name) + sizeof(int) + 1;
-+      else
-+              return 0;
++      return sizeof(int) + PAGE_SIZE + toi_bio_devinfo_storage_needed();
 +}
 +
-+/*
-+ * toi_checksum_save_config_info
-+ * @buffer: Pointer to a buffer of size PAGE_SIZE.
-+ *
-+ * Save informaton needed when reloading the image at resume time.
-+ * Returns: Number of bytes used for saving our data.
-+ */
-+static int toi_checksum_save_config_info(char *buffer)
++/**
++ * toi_bio_save_config_info - save block I/O config to image header
++ * @buf:      PAGE_SIZE'd buffer into which data should be saved.
++ **/
++static int toi_bio_save_config_info(char *buf)
 +{
-+      int namelen = strlen(toi_checksum_name) + 1;
-+      int total_len;
-+
-+      *((unsigned int *) buffer) = namelen;
-+      strncpy(buffer + sizeof(unsigned int), toi_checksum_name, namelen);
-+      total_len = sizeof(unsigned int) + namelen;
-+      return total_len;
++      int *ints = (int *) buf;
++      ints[0] = target_outstanding_io;
++      return sizeof(int);
 +}
 +
-+/* toi_checksum_load_config_info
-+ * @buffer: Pointer to the start of the data.
-+ * @size: Number of bytes that were saved.
-+ *
-+ * Description:       Reload information needed for dechecksuming the image at
-+ * resume time.
-+ */
-+static void toi_checksum_load_config_info(char *buffer, int size)
++/**
++ * toi_bio_load_config_info - restore block I/O config
++ * @buf:      Data to be reloaded.
++ * @size:     Size of the buffer saved.
++ **/
++static void toi_bio_load_config_info(char *buf, int size)
 +{
-+      int namelen;
-+
-+      namelen = *((unsigned int *) (buffer));
-+      strncpy(toi_checksum_name, buffer + sizeof(unsigned int),
-+                      namelen);
-+      return;
++      int *ints = (int *) buf;
++      target_outstanding_io  = ints[0];
 +}
 +
-+/*
-+ * Free Checksum Memory
-+ */
-+
-+void free_checksum_pages(void)
++static void close_resume_dev_t(int force)
 +{
-+      while (pages_allocated) {
-+              unsigned long next = *((unsigned long *) page_list);
-+              ClearPageNosave(virt_to_page(page_list));
-+              toi_free_page(15, (unsigned long) page_list);
-+              page_list = next;
-+              pages_allocated--;
++      if ((force || atomic_dec_and_test(&resume_bdev_open_count)) &&
++                      resume_block_device) {
++              toi_close_bdev(resume_block_device);
++              resume_block_device = NULL;
 +      }
 +}
 +
-+/*
-+ * Allocate Checksum Memory
-+ */
-+
-+int allocate_checksum_pages(void)
++static int open_resume_dev_t(int force, int quiet)
 +{
-+      int pages_needed = checksum_pages_needed();
++      if (force)
++              close_resume_dev_t(1);
++      else
++              atomic_inc(&resume_bdev_open_count);
 +
-+      if (!toi_checksum_ops.enabled)
++      if (resume_block_device)
 +              return 0;
 +
-+      while (pages_allocated < pages_needed) {
-+              unsigned long *new_page =
-+                (unsigned long *) toi_get_zeroed_page(15, TOI_ATOMIC_GFP);
-+              if (!new_page) {
-+                      printk(KERN_ERR "Unable to allocate checksum pages.\n");
-+                      return -ENOMEM;
-+              }
-+              SetPageNosave(virt_to_page(new_page));
-+              (*new_page) = page_list;
-+              page_list = (unsigned long) new_page;
-+              pages_allocated++;
++      resume_block_device = toi_open_bdev(NULL, resume_dev_t, 0);
++      if (IS_ERR(resume_block_device)) {
++              if (!quiet)
++                      toi_early_boot_message(1, TOI_CONTINUE_REQ,
++                              "Failed to open device %x, where"
++                              " the header should be found.",
++                              resume_dev_t);
++              return 1;
 +      }
 +
-+      next_page = (unsigned long) page_list;
-+      checksum_index = 0;
-+
 +      return 0;
 +}
 +
-+char *tuxonice_get_next_checksum(void)
++/**
++ * toi_bio_initialise - initialise bio code at start of some action
++ * @starting_cycle:   Whether starting a hibernation cycle, or just reading or
++ *                    writing a sysfs value.
++ **/
++static int toi_bio_initialise(int starting_cycle)
 +{
-+      if (!toi_checksum_ops.enabled)
-+              return NULL;
++      int result;
 +
-+      if (checksum_index % CHECKSUMS_PER_PAGE)
-+              this_checksum += CHECKSUM_SIZE;
-+      else {
-+              this_checksum = next_page + sizeof(void *);
-+              next_page = *((unsigned long *) next_page);
-+      }
++      if (!starting_cycle || !resume_dev_t)
++              return 0;
 +
-+      checksum_index++;
-+      return (char *) this_checksum;
++      max_outstanding_writes = 0;
++      max_outstanding_reads = 0;
++      current_stream = 0;
++      toi_queue_flusher = current;
++#ifdef MEASURE_MUTEX_CONTENTION
++      {
++              int i, j, k;
++
++              for (i = 0; i < 2; i++)
++                      for (j = 0; j < 2; j++)
++                              for_each_online_cpu(k)
++                                      mutex_times[i][j][k] = 0;
++      }
++#endif
++      result = open_resume_dev_t(0, 1);
++
++      if (result)
++              return result;
++
++      return get_signature_page();
 +}
 +
-+int tuxonice_calc_checksum(struct page *page, char *checksum_locn)
++static unsigned long raw_to_real(unsigned long raw)
 +{
-+      char *pa;
-+      int result, cpu = smp_processor_id();
-+      struct cpu_context *ctx = &per_cpu(contexts, cpu);
++      unsigned long result;
 +
-+      if (!toi_checksum_ops.enabled)
-+              return 0;
++      result = raw - (raw * (sizeof(unsigned long) + sizeof(int)) +
++              (PAGE_SIZE + sizeof(unsigned long) + sizeof(int) + 1)) /
++              (PAGE_SIZE + sizeof(unsigned long) + sizeof(int));
 +
-+      pa = kmap(page);
-+      memcpy(ctx->buf, pa, PAGE_SIZE);
-+      kunmap(page);
-+      result = crypto_hash_digest(&ctx->desc, ctx->sg, PAGE_SIZE,
-+                                              checksum_locn);
-+      return result;
++      return result < 0 ? 0 : result;
++}
++
++static unsigned long toi_bio_storage_available(void)
++{
++      unsigned long sum = 0;
++      struct toi_module_ops *this_module;
++
++      list_for_each_entry(this_module, &toi_modules, module_list) {
++              if (!this_module->enabled ||
++                  this_module->type != BIO_ALLOCATOR_MODULE)
++                      continue;
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Seeking storage "
++                              "available from %s.", this_module->name);
++              sum += this_module->bio_allocator_ops->storage_available();
++      }
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Total storage available is %lu "
++                      "pages.", sum);
++      return raw_to_real(sum - header_pages_reserved);
++
++}
++
++static unsigned long toi_bio_storage_allocated(void)
++{
++      return raw_pages_allocd > header_pages_reserved ?
++              raw_to_real(raw_pages_allocd - header_pages_reserved) : 0;
 +}
++
 +/*
-+ * Calculate checksums
++ * If we have read part of the image, we might have filled  memory with
++ * data that should be zeroed out.
 + */
-+
-+void check_checksums(void)
++static void toi_bio_noresume_reset(void)
 +{
-+      int pfn, index = 0, cpu = smp_processor_id();
-+      char current_checksum[CHECKSUM_SIZE];
-+      struct cpu_context *ctx = &per_cpu(contexts, cpu);
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_bio_noresume_reset.");
++      toi_rw_cleanup(READ);
++      free_all_bdev_info();
++}
 +
-+      if (!toi_checksum_ops.enabled)
++/**
++ * toi_bio_cleanup - cleanup after some action
++ * @finishing_cycle:  Whether completing a cycle.
++ **/
++static void toi_bio_cleanup(int finishing_cycle)
++{
++      if (!finishing_cycle)
 +              return;
 +
-+      next_page = (unsigned long) page_list;
++      if (toi_writer_buffer) {
++              toi_free_page(11, (unsigned long) toi_writer_buffer);
++              toi_writer_buffer = NULL;
++      }
 +
-+      toi_num_resaved = 0;
-+      this_checksum = 0;
++      forget_signature_page();
 +
-+      memory_bm_position_reset(pageset2_map);
-+      for (pfn = memory_bm_next_pfn(pageset2_map); pfn != BM_END_OF_MAP;
-+                      pfn = memory_bm_next_pfn(pageset2_map)) {
-+              int ret;
-+              char *pa;
-+              struct page *page = pfn_to_page(pfn);
++      if (header_block_device && toi_sig_data &&
++                      toi_sig_data->header_dev_t != resume_dev_t)
++              toi_close_bdev(header_block_device);
 +
-+              if (index % CHECKSUMS_PER_PAGE) {
-+                      this_checksum += CHECKSUM_SIZE;
-+              } else {
-+                      this_checksum = next_page + sizeof(void *);
-+                      next_page = *((unsigned long *) next_page);
-+              }
++      header_block_device = NULL;
++}
 +
-+              /* Done when IRQs disabled so must be atomic */
-+              pa = kmap_atomic(page, KM_USER1);
-+              memcpy(ctx->buf, pa, PAGE_SIZE);
-+              kunmap_atomic(pa, KM_USER1);
-+              ret = crypto_hash_digest(&ctx->desc, ctx->sg, PAGE_SIZE,
-+                                                      current_checksum);
++static int toi_bio_write_header_init(void)
++{
++      int result;
 +
-+              if (ret) {
-+                      printk(KERN_INFO "Digest failed. Returned %d.\n", ret);
-+                      return;
-+              }
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_bio_write_header_init");
++      toi_rw_init(WRITE, 0);
++      toi_writer_buffer_posn = 0;
 +
-+              if (memcmp(current_checksum, (char *) this_checksum,
-+                                                      CHECKSUM_SIZE)) {
-+                      SetPageResave(pfn_to_page(pfn));
-+                      toi_num_resaved++;
-+                      if (test_action_state(TOI_ABORT_ON_RESAVE_NEEDED))
-+                              set_abort_result(TOI_RESAVE_NEEDED);
-+              }
++      /* Info needed to bootstrap goes at the start of the header.
++       * First we save the positions and devinfo, including the number
++       * of header pages. Then we save the structs containing data needed
++       * for reading the header pages back.
++       * Note that even if header pages take more than one page, when we
++       * read back the info, we will have restored the location of the
++       * next header page by the time we go to use it.
++       */
 +
-+              index++;
-+      }
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "serialise extent chains.");
++      result = toi_serialise_extent_chains();
++
++      if (result)
++              return result;
++
++      /*
++       * Signature page hasn't been modified at this point. Write it in
++       * the header so we can restore it later.
++       */
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "serialise signature page.");
++      return toi_rw_header_chunk_noreadahead(WRITE, &toi_blockwriter_ops,
++                      (char *) toi_cur_sig_page,
++                      PAGE_SIZE);
 +}
 +
-+static struct toi_sysfs_data sysfs_params[] = {
-+      SYSFS_INT("enabled", SYSFS_RW, &toi_checksum_ops.enabled, 0, 1, 0,
-+                      NULL),
-+      SYSFS_BIT("abort_if_resave_needed", SYSFS_RW, &toi_bkd.toi_action,
-+                      TOI_ABORT_ON_RESAVE_NEEDED, 0)
-+};
++static int toi_bio_write_header_cleanup(void)
++{
++      int result = 0;
++
++      if (toi_writer_buffer_posn)
++              toi_bio_queue_write(&toi_writer_buffer);
++
++      result = toi_finish_all_io();
++
++      unowned = 0;
++      total_header_bytes = 0;
++
++      /* Set signature to save we have an image */
++      if (!result)
++              result = toi_bio_mark_have_image();
++
++      return result;
++}
 +
 +/*
-+ * Ops structure.
++ * toi_bio_read_header_init()
++ *
++ * Description:
++ * 1. Attempt to read the device specified with resume=.
++ * 2. Check the contents of the swap header for our signature.
++ * 3. Warn, ignore, reset and/or continue as appropriate.
++ * 4. If continuing, read the toi_swap configuration section
++ *    of the header and set up block device info so we can read
++ *    the rest of the header & image.
++ *
++ * Returns:
++ * May not return if user choose to reboot at a warning.
++ * -EINVAL if cannot resume at this time. Booting should continue
++ * normally.
 + */
-+static struct toi_module_ops toi_checksum_ops = {
-+      .type                   = MISC_MODULE,
-+      .name                   = "checksumming",
-+      .directory              = "checksum",
-+      .module                 = THIS_MODULE,
-+      .initialise             = toi_checksum_initialise,
-+      .cleanup                = toi_checksum_cleanup,
-+      .print_debug_info       = toi_checksum_print_debug_stats,
-+      .save_config_info       = toi_checksum_save_config_info,
-+      .load_config_info       = toi_checksum_load_config_info,
-+      .memory_needed          = toi_checksum_memory_needed,
-+      .storage_needed         = toi_checksum_storage_needed,
-+
-+      .sysfs_data             = sysfs_params,
-+      .num_sysfs_entries      = sizeof(sysfs_params) /
-+              sizeof(struct toi_sysfs_data),
-+};
 +
-+/* ---- Registration ---- */
-+int toi_checksum_init(void)
++static int toi_bio_read_header_init(void)
 +{
-+      int result = toi_register_module(&toi_checksum_ops);
-+      return result;
++      int result = 0;
++      char buf[32];
++
++      toi_writer_buffer_posn = 0;
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_bio_read_header_init");
++
++      if (!toi_sig_data) {
++              printk(KERN_INFO "toi_bio_read_header_init called when we "
++                              "haven't verified there is an image!\n");
++              return -EINVAL;
++      }
++
++      /*
++       * If the header is not on the resume_swap_dev_t, get the resume device
++       * first.
++       */
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Header dev_t is %lx.",
++                      toi_sig_data->header_dev_t);
++      if (toi_sig_data->have_uuid) {
++              dev_t device;
++              device = blk_lookup_uuid(toi_sig_data->header_uuid);
++              if (device) {
++                      printk("Using dev_t %s, returned by blk_lookup_uuid.\n",
++                                      format_dev_t(buf, device));
++                      toi_sig_data->header_dev_t = device;
++              }
++      }
++      if (toi_sig_data->header_dev_t != resume_dev_t) {
++              header_block_device = toi_open_bdev(NULL,
++                              toi_sig_data->header_dev_t, 1);
++
++              if (IS_ERR(header_block_device))
++                      return PTR_ERR(header_block_device);
++      } else
++              header_block_device = resume_block_device;
++
++      if (!toi_writer_buffer)
++              toi_writer_buffer = (char *) toi_get_zeroed_page(11,
++                              TOI_ATOMIC_GFP);
++      more_readahead = 1;
++
++      /*
++       * Read toi_swap configuration.
++       * Headerblock size taken into account already.
++       */
++      result = toi_bio_ops.bdev_page_io(READ, header_block_device,
++                      toi_sig_data->first_header_block,
++                      virt_to_page((unsigned long) toi_writer_buffer));
++      if (result)
++              return result;
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "load extent chains.");
++      result = toi_load_extent_chains();
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "load original signature page.");
++      toi_orig_sig_page = (char *) toi_get_zeroed_page(38, TOI_ATOMIC_GFP);
++      if (!toi_orig_sig_page) {
++              printk(KERN_ERR "Failed to allocate memory for the current"
++                      " image signature.\n");
++              return -ENOMEM;
++      }
++
++      return toi_rw_header_chunk_noreadahead(READ, &toi_blockwriter_ops,
++                      (char *) toi_orig_sig_page,
++                      PAGE_SIZE);
 +}
 +
-+void toi_checksum_exit(void)
++static int toi_bio_read_header_cleanup(void)
 +{
-+      toi_unregister_module(&toi_checksum_ops);
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_bio_read_header_cleanup.");
++      return toi_rw_cleanup(READ);
 +}
-diff --git a/kernel/power/tuxonice_checksum.h b/kernel/power/tuxonice_checksum.h
-new file mode 100644
-index 0000000..84a9174
---- /dev/null
-+++ b/kernel/power/tuxonice_checksum.h
-@@ -0,0 +1,32 @@
++
++/* Works only for digits and letters, but small and fast */
++#define TOLOWER(x) ((x) | 0x20)
++
 +/*
-+ * kernel/power/tuxonice_checksum.h
-+ *
-+ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
-+ * Copyright (C) 2006 Red Hat, inc.
-+ *
-+ * This file is released under the GPLv2.
-+ *
-+ * This file contains data checksum routines for TuxOnIce,
-+ * using cryptoapi. They are used to locate any modifications
-+ * made to pageset 2 while we're saving it.
++ * UUID must be 32 chars long. It may have dashes, but nothing
++ * else.
 + */
++char *uuid_from_commandline(char *commandline)
++{
++      int low = 0;
++      char *result = NULL, *output, *ptr;
 +
-+#if defined(CONFIG_TOI_CHECKSUM)
-+extern int toi_checksum_init(void);
-+extern void toi_checksum_exit(void);
-+void check_checksums(void);
-+int allocate_checksum_pages(void);
-+void free_checksum_pages(void);
-+char *tuxonice_get_next_checksum(void);
-+int tuxonice_calc_checksum(struct page *page, char *checksum_locn);
-+#else
-+static inline int toi_checksum_init(void) { return 0; }
-+static inline void toi_checksum_exit(void) { }
-+static inline void check_checksums(void) { };
-+static inline int allocate_checksum_pages(void) { return 0; };
-+static inline void free_checksum_pages(void) { };
-+static inline char *tuxonice_get_next_checksum(void) { return NULL; };
-+static inline int tuxonice_calc_checksum(struct page *page, char *checksum_locn)
-+      { return 0; }
-+#endif
++      if (strncmp(commandline, "UUID=", 5))
++              return NULL;
 +
-diff --git a/kernel/power/tuxonice_cluster.c b/kernel/power/tuxonice_cluster.c
-new file mode 100644
-index 0000000..671006d
---- /dev/null
-+++ b/kernel/power/tuxonice_cluster.c
-@@ -0,0 +1,1069 @@
-+/*
-+ * kernel/power/tuxonice_cluster.c
-+ *
-+ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
-+ *
-+ * This file is released under the GPLv2.
-+ *
-+ * This file contains routines for cluster hibernation support.
-+ *
-+ * Based on ip autoconfiguration code in net/ipv4/ipconfig.c.
-+ *
-+ * How does it work?
-+ *
-+ * There is no 'master' node that tells everyone else what to do. All nodes
-+ * send messages to the broadcast address/port, maintain a list of peers
-+ * and figure out when to progress to the next step in hibernating or resuming.
-+ * This makes us more fault tolerant when it comes to nodes coming and going
-+ * (which may be more of an issue if we're hibernating when power supplies
-+ * are being unreliable).
-+ *
-+ * At boot time, we start a ktuxonice thread that handles communication with
-+ * other nodes. This node maintains a state machine that controls our progress
-+ * through hibernating and resuming, keeping us in step with other nodes. Nodes
-+ * are identified by their hw address.
-+ *
-+ * On startup, the node sends CLUSTER_PING on the configured interface's
-+ * broadcast address, port $toi_cluster_port (see below) and begins to listen
-+ * for other broadcast messages. CLUSTER_PING messages are repeated at
-+ * intervals of 5 minutes, with a random offset to spread traffic out.
-+ *
-+ * A hibernation cycle is initiated from any node via
-+ *
-+ * echo > /sys/power/tuxonice/do_hibernate
-+ *
-+ * and (possibily) the hibernate script. At each step of the process, the node
-+ * completes its work, and waits for all other nodes to signal completion of
-+ * their work (or timeout) before progressing to the next step.
-+ *
-+ * Request/state  Action before reply Possible reply  Next state
-+ * HIBERNATE    capable, pre-script   HIBERNATE|ACK   NODE_PREP
-+ *                                    HIBERNATE|NACK  INIT_0
-+ *
-+ * PREP                 prepare_image         PREP|ACK        IMAGE_WRITE
-+ *                                    PREP|NACK       INIT_0
-+ *                                    ABORT           RUNNING
-+ *
-+ * IO           write image           IO|ACK          power off
-+ *                                    ABORT           POST_RESUME
-+ *
-+ * (Boot time)          check for image       IMAGE|ACK       RESUME_PREP
-+ *                                    (Note 1)
-+ *                                    IMAGE|NACK      (Note 2)
-+ *
-+ * PREP                 prepare read image    PREP|ACK        IMAGE_READ
-+ *                                    PREP|NACK       (As NACK_IMAGE)
-+ *
-+ * IO           read image            IO|ACK          POST_RESUME
++      result = kzalloc(17, GFP_KERNEL);
++      if (!result) {
++              printk("Failed to kzalloc UUID text memory.\n");
++              return NULL;
++      }
++
++      ptr = commandline + 5;
++      output = result;
++
++      while (*ptr && (output - result) < 16) {
++              if (isxdigit(*ptr)) {
++                      int value = isdigit(*ptr) ? *ptr - '0' :
++                              TOLOWER(*ptr) - 'a' + 10;
++                      if (low) {
++                              *output += value;
++                              output++;
++                      } else {
++                              *output = value << 4;
++                      }
++                      low = !low;
++              } else if (*ptr != '-')
++                      break;
++              ptr++;
++      }
++
++      if ((output - result) < 16 || *ptr) {
++              printk(KERN_DEBUG "Found resume=UUID=, but the value looks "
++                              "invalid.\n");
++              kfree(result);
++              result = NULL;
++      }
++
++      return result;
++}
++
++/**
++ * try_to_open_resume_device: Try to parse and open resume=
 + *
-+ * POST_RESUME          thaw, post-script                     RUNNING
++ * Any "swap:" has been stripped away and we just have the path to deal with.
++ * We attempt to do name_to_dev_t, open and stat the file. Having opened the
++ * file, get the struct block_device * to match.
++ */
++static int try_to_open_resume_device(char *commandline, int quiet)
++{
++      struct kstat stat;
++      int error = 0;
++      char *uuid = uuid_from_commandline(commandline);
++
++      resume_dev_t = MKDEV(0, 0);
++
++      if (uuid) {
++              resume_dev_t = blk_lookup_uuid(uuid);
++              kfree(uuid);
++      }
++
++      if (!resume_dev_t)
++              resume_dev_t = name_to_dev_t(commandline);
++
++      if (!resume_dev_t) {
++              wait_for_device_probe();
++              scsi_complete_async_scans();
++              resume_dev_t = name_to_dev_t(commandline);
++      }
++
++      if (!resume_dev_t) {
++              struct file *file = filp_open(commandline,
++                              O_RDONLY|O_LARGEFILE, 0);
++
++              if (!IS_ERR(file) && file) {
++                      vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
++                      filp_close(file, NULL);
++              } else
++                      error = vfs_stat(commandline, &stat);
++              if (!error)
++                      resume_dev_t = stat.rdev;
++      }
++
++      if (!resume_dev_t) {
++              if (quiet)
++                      return 1;
++
++              if (test_toi_state(TOI_TRYING_TO_RESUME))
++                      toi_early_boot_message(1, toi_translate_err_default,
++                        "Failed to translate \"%s\" into a device id.\n",
++                        commandline);
++              else
++                      printk("TuxOnIce: Can't translate \"%s\" into a device "
++                                      "id yet.\n", commandline);
++              return 1;
++      }
++
++      return open_resume_dev_t(1, quiet);
++}
++
++/*
++ * Parse Image Location
 + *
-+ * INIT_0       init 0
++ * Attempt to parse a resume= parameter.
++ * Swap Writer accepts:
++ * resume=[swap:|file:]DEVNAME[:FIRSTBLOCK][@BLOCKSIZE]
 + *
-+ * Other messages:
++ * Where:
++ * DEVNAME is convertable to a dev_t by name_to_dev_t
++ * FIRSTBLOCK is the location of the first block in the swap file
++ * (specifying for a swap partition is nonsensical but not prohibited).
++ * Data is validated by attempting to read a swap header from the
++ * location given. Failure will result in toi_swap refusing to
++ * save an image, and a reboot with correct parameters will be
++ * necessary.
++ */
++static int toi_bio_parse_sig_location(char *commandline,
++              int only_allocator, int quiet)
++{
++      char *thischar, *devstart, *colon = NULL;
++      int signature_found, result = -EINVAL, temp_result = 0;
++
++      if (strncmp(commandline, "swap:", 5) &&
++          strncmp(commandline, "file:", 5)) {
++              /*
++               * Failing swap:, we'll take a simple
++               * resume=/dev/hda2, but fall through to
++               * other allocators if /dev/ or UUID= isn't matched.
++               */
++              if (strncmp(commandline, "/dev/", 5) &&
++                  strncmp(commandline, "UUID=", 5))
++                      return 1;
++      } else
++              commandline += 5;
++
++      devstart = commandline;
++      thischar = commandline;
++      while ((*thischar != ':') && (*thischar != '@') &&
++              ((thischar - commandline) < 250) && (*thischar))
++              thischar++;
++
++      if (*thischar == ':') {
++              colon = thischar;
++              *colon = 0;
++              thischar++;
++      }
++
++      while ((thischar - commandline) < 250 && *thischar)
++              thischar++;
++
++      if (colon) {
++              unsigned long block;
++              temp_result = strict_strtoul(colon + 1, 0, &block);
++              if (!temp_result)
++                      resume_firstblock = (int) block;
++      } else
++              resume_firstblock = 0;
++
++      clear_toi_state(TOI_CAN_HIBERNATE);
++      clear_toi_state(TOI_CAN_RESUME);
++
++      if (!temp_result)
++              temp_result = try_to_open_resume_device(devstart, quiet);
++
++      if (colon)
++              *colon = ':';
++
++      if (temp_result)
++              return -EINVAL;
++
++      signature_found = toi_bio_image_exists(quiet);
++
++      if (signature_found != -1) {
++              result = 0;
++              /*
++               * TODO: If only file storage, CAN_HIBERNATE should only be
++               * set if file allocator's target is valid.
++               */
++              set_toi_state(TOI_CAN_HIBERNATE);
++              set_toi_state(TOI_CAN_RESUME);
++      } else
++              if (!quiet)
++                      printk(KERN_ERR "TuxOnIce: Block I/O: No "
++                              "signature found at %s.\n", devstart);
++
++      close_resume_dev_t(0);
++      return result;
++}
++
++static void toi_bio_release_storage(void)
++{
++      header_pages_reserved = 0;
++      raw_pages_allocd = 0;
++
++      free_all_bdev_info();
++}
++
++/* toi_swap_remove_image
 + *
-+ * - PING: Request for all other live nodes to send a PONG. Used at startup to
-+ *   announce presence, when a node is suspected dead and periodically, in case
-+ *   segments of the network are [un]plugged.
++ */
++static int toi_bio_remove_image(void)
++{
++      int result;
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_bio_remove_image.");
++
++      result = toi_bio_restore_original_signature();
++
++      /*
++       * We don't do a sanity check here: we want to restore the swap
++       * whatever version of kernel made the hibernate image.
++       *
++       * We need to write swap, but swap may not be enabled so
++       * we write the device directly
++       *
++       * If we don't have an current_signature_page, we didn't
++       * read an image header, so don't change anything.
++       */
++
++      toi_bio_release_storage();
++
++      return result;
++}
++
++struct toi_bio_ops toi_bio_ops = {
++      .bdev_page_io = toi_bdev_page_io,
++      .register_storage = toi_register_storage_chain,
++      .free_storage = toi_bio_release_storage,
++};
++EXPORT_SYMBOL_GPL(toi_bio_ops);
++
++static struct toi_sysfs_data sysfs_params[] = {
++      SYSFS_INT("target_outstanding_io", SYSFS_RW, &target_outstanding_io,
++                      0, 16384, 0, NULL),
++};
++
++struct toi_module_ops toi_blockwriter_ops = {
++      .type                           = WRITER_MODULE,
++      .name                           = "block i/o",
++      .directory                      = "block_io",
++      .module                         = THIS_MODULE,
++      .memory_needed                  = toi_bio_memory_needed,
++      .print_debug_info               = toi_bio_print_debug_stats,
++      .storage_needed                 = toi_bio_storage_needed,
++      .save_config_info               = toi_bio_save_config_info,
++      .load_config_info               = toi_bio_load_config_info,
++      .initialise                     = toi_bio_initialise,
++      .cleanup                        = toi_bio_cleanup,
++
++      .rw_init                        = toi_rw_init,
++      .rw_cleanup                     = toi_rw_cleanup,
++      .read_page                      = toi_bio_read_page,
++      .write_page                     = toi_bio_write_page,
++      .rw_header_chunk                = toi_rw_header_chunk,
++      .rw_header_chunk_noreadahead    = toi_rw_header_chunk_noreadahead,
++      .io_flusher                     = bio_io_flusher,
++      .update_throughput_throttle     = update_throughput_throttle,
++      .finish_all_io                  = toi_finish_all_io,
++
++      .noresume_reset                 = toi_bio_noresume_reset,
++      .storage_available              = toi_bio_storage_available,
++      .storage_allocated              = toi_bio_storage_allocated,
++      .reserve_header_space           = toi_bio_reserve_header_space,
++      .allocate_storage               = toi_bio_allocate_storage,
++      .image_exists                   = toi_bio_image_exists,
++      .mark_resume_attempted          = toi_bio_mark_resume_attempted,
++      .write_header_init              = toi_bio_write_header_init,
++      .write_header_cleanup           = toi_bio_write_header_cleanup,
++      .read_header_init               = toi_bio_read_header_init,
++      .read_header_cleanup            = toi_bio_read_header_cleanup,
++      .remove_image                   = toi_bio_remove_image,
++      .parse_sig_location             = toi_bio_parse_sig_location,
++
++      .sysfs_data                     = sysfs_params,
++      .num_sysfs_entries              = sizeof(sysfs_params) /
++              sizeof(struct toi_sysfs_data),
++};
++
++/**
++ * toi_block_io_load - load time routine for block I/O module
 + *
-+ * - PONG: Response to a PING.
++ * Register block i/o ops and sysfs entries.
++ **/
++static __init int toi_block_io_load(void)
++{
++      return toi_register_module(&toi_blockwriter_ops);
++}
++
++#ifdef MODULE
++static __exit void toi_block_io_unload(void)
++{
++      toi_unregister_module(&toi_blockwriter_ops);
++}
++
++module_init(toi_block_io_load);
++module_exit(toi_block_io_unload);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Nigel Cunningham");
++MODULE_DESCRIPTION("TuxOnIce block io functions");
++#else
++late_initcall(toi_block_io_load);
++#endif
+diff --git a/kernel/power/tuxonice_bio_internal.h b/kernel/power/tuxonice_bio_internal.h
+new file mode 100644
+index 0000000..a141faa
+--- /dev/null
++++ b/kernel/power/tuxonice_bio_internal.h
+@@ -0,0 +1,64 @@
++/* Extent chains */
++void toi_extent_state_goto_start(void);
++void toi_extent_state_save(int slot);
++int go_next_page(int writing, int section_barrier);
++void toi_extent_state_restore(int slot);
++void free_all_bdev_info(void);
++int devices_of_same_priority(struct toi_bdev_info *this);
++int toi_register_storage_chain(struct toi_bdev_info *new);
++int toi_serialise_extent_chains(void);
++int toi_load_extent_chains(void);
++int toi_bio_rw_page(int writing, struct page *page, int is_readahead,
++              int free_group);
++int toi_bio_restore_original_signature(void);
++int toi_bio_devinfo_storage_needed(void);
++unsigned long get_headerblock(void);
++dev_t get_header_dev_t(void);
++struct block_device *get_header_bdev(void);
++int toi_bio_allocate_storage(unsigned long request);
++
++/* Signature functions */
++#define HaveImage "HaveImage"
++#define NoImage "TuxOnIce"
++#define sig_size (sizeof(HaveImage))
++
++struct sig_data {
++      char sig[sig_size];
++      int have_image;
++      int resumed_before;
++
++      char have_uuid;
++      char header_uuid[17];
++      dev_t header_dev_t;
++      unsigned long first_header_block;
++};
++
++void forget_signature_page(void);
++int toi_check_for_signature(void);
++int toi_bio_image_exists(int quiet);
++int get_signature_page(void);
++int toi_bio_mark_resume_attempted(int);
++extern char *toi_cur_sig_page;
++extern char *toi_orig_sig_page;
++int toi_bio_mark_have_image(void);
++extern struct sig_data *toi_sig_data;
++extern dev_t resume_dev_t;
++extern struct block_device *resume_block_device;
++extern struct block_device *header_block_device;
++extern unsigned long resume_firstblock;
++
++struct block_device *open_bdev(dev_t device, int display_errs);
++extern int current_stream;
++extern int more_readahead;
++int toi_do_io(int writing, struct block_device *bdev, long block0,
++      struct page *page, int is_readahead, int syncio, int free_group);
++int get_main_pool_phys_params(void);
++
++void toi_close_bdev(struct block_device *bdev);
++struct block_device *toi_open_bdev(char *uuid, dev_t default_device,
++              int display_errs);
++
++extern struct toi_module_ops toi_blockwriter_ops;
++void dump_block_chains(void);
++void debug_broken_header(void);
++extern unsigned long raw_pages_allocd, header_pages_reserved;
+diff --git a/kernel/power/tuxonice_bio_signature.c b/kernel/power/tuxonice_bio_signature.c
+new file mode 100644
+index 0000000..7954027
+--- /dev/null
++++ b/kernel/power/tuxonice_bio_signature.c
+@@ -0,0 +1,281 @@
++/*
++ * kernel/power/tuxonice_bio_signature.c
 + *
-+ * - ABORT: Request to cancel writing an image.
++ * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
 + *
-+ * - BYE: Notification that this node is shutting down.
++ * Distributed under GPLv2.
 + *
-+ * Note 1: Repeated at 3s intervals until we continue to boot/resume, so that
-+ * nodes which are slower to start up can get state synchronised. If a node
-+ * starting up sees other nodes sending RESUME_PREP or IMAGE_READ, it may send
-+ * ACK_IMAGE and they will wait for it to catch up. If it sees ACK_READ, it
-+ * must invalidate its image (if any) and boot normally.
++ */
++
++#include <linux/uuid.h>
++
++#include "tuxonice.h"
++#include "tuxonice_sysfs.h"
++#include "tuxonice_modules.h"
++#include "tuxonice_prepare_image.h"
++#include "tuxonice_bio.h"
++#include "tuxonice_ui.h"
++#include "tuxonice_alloc.h"
++#include "tuxonice_io.h"
++#include "tuxonice_builtin.h"
++#include "tuxonice_bio_internal.h"
++
++struct sig_data *toi_sig_data;
++
++/* Struct of swap header pages */
++
++union diskpage {
++      union swap_header swh;  /* swh.magic is the only member used */
++      struct sig_data sig_data;
++};
++
++union p_diskpage {
++      union diskpage *pointer;
++      char *ptr;
++      unsigned long address;
++};
++
++char *toi_cur_sig_page;
++char *toi_orig_sig_page;
++int have_image;
++
++int get_signature_page(void)
++{
++      if (!toi_cur_sig_page) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0,
++                              "Allocating current signature page.");
++              toi_cur_sig_page = (char *) toi_get_zeroed_page(38,
++                      TOI_ATOMIC_GFP);
++              if (!toi_cur_sig_page) {
++                      printk(KERN_ERR "Failed to allocate memory for the "
++                              "current image signature.\n");
++                      return -ENOMEM;
++              }
++
++              toi_sig_data = (struct sig_data *) toi_cur_sig_page;
++      }
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Reading signature from dev %lx,"
++                      " sector %d.",
++                      resume_block_device->bd_dev, resume_firstblock);
++
++      return toi_bio_ops.bdev_page_io(READ, resume_block_device,
++              resume_firstblock, virt_to_page(toi_cur_sig_page));
++}
++
++void forget_signature_page(void)
++{
++      if (toi_cur_sig_page) {
++              toi_sig_data = NULL;
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Freeing toi_cur_sig_page"
++                              " (%p).", toi_cur_sig_page);
++              toi_free_page(38, (unsigned long) toi_cur_sig_page);
++              toi_cur_sig_page = NULL;
++      }
++
++      if (toi_orig_sig_page) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Freeing toi_orig_sig_page"
++                              " (%p).", toi_orig_sig_page);
++              toi_free_page(38, (unsigned long) toi_orig_sig_page);
++              toi_orig_sig_page = NULL;
++      }
++}
++
++int toi_bio_mark_resume_attempted(int flag)
++{
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Make resume attempted = %d.",
++                      flag);
++      toi_sig_data->resumed_before = flag;
++      return toi_bio_ops.bdev_page_io(WRITE, resume_block_device,
++              resume_firstblock, virt_to_page(toi_cur_sig_page));
++}
++
++int toi_bio_mark_have_image(void)
++{
++      int result;
++      char buf[32];
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Recording that an image exists.");
++      memcpy(toi_sig_data->sig, tuxonice_signature,
++                      sizeof(tuxonice_signature));
++      toi_sig_data->have_image = 1;
++      toi_sig_data->resumed_before = 0;
++      toi_sig_data->header_dev_t = get_header_dev_t();
++      toi_sig_data->have_uuid = 0;
++
++      result = uuid_from_block_dev(get_header_bdev(),
++                      toi_sig_data->header_uuid);
++      if (!result) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Got uuid for dev_t %s.",
++                              format_dev_t(buf, get_header_dev_t()));
++              toi_sig_data->have_uuid = 1;
++      } else
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Could not get uuid for "
++                              "dev_t %s.",
++                              format_dev_t(buf, get_header_dev_t()));
++
++      toi_sig_data->first_header_block = get_headerblock();
++      have_image = 1;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "header dev_t is %x. First block "
++                      "is %d.", toi_sig_data->header_dev_t,
++                      toi_sig_data->first_header_block);
++
++      return toi_bio_ops.bdev_page_io(WRITE, resume_block_device,
++              resume_firstblock, virt_to_page(toi_cur_sig_page));
++}
++
++/*
++ * toi_bio_restore_original_signature - restore the original signature
 + *
-+ * Note 2: May occur when one node lost power or powered off while others
-+ * hibernated. This node waits for others to complete resuming (ACK_READ)
-+ * before completing its boot, so that it appears as a fail node restarting.
++ * At boot time (aborting pre atomic-restore), toi_orig_sig_page gets used.
++ * It will have the original signature page contents, stored in the image
++ * header. Post atomic-restore, we use :toi_cur_sig_page, which will contain
++ * the contents that were loaded when we started the cycle.
++ */
++int toi_bio_restore_original_signature(void)
++{
++      char *use = toi_orig_sig_page ? toi_orig_sig_page : toi_cur_sig_page;
++
++      if (!use) {
++              printk("toi_bio_restore_original_signature: No signature "
++                              "page loaded.\n");
++              return 0;
++      }
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Recording that no image exists.");
++      have_image = 0;
++      toi_sig_data->have_image = 0;
++      return toi_bio_ops.bdev_page_io(WRITE, resume_block_device,
++              resume_firstblock, virt_to_page(use));
++}
++
++/*
++ * check_for_signature - See whether we have an image.
 + *
-+ * If any node has an image, then it also has a list of nodes that hibernated
-+ * in synchronisation with it. The node will wait for other nodes to appear
-+ * or timeout before beginning its restoration.
++ * Returns 0 if no image, 1 if there is one, -1 if indeterminate.
++ */
++int toi_check_for_signature(void)
++{
++      union p_diskpage swap_header_page;
++      int type;
++      const char *normal_sigs[] = {"SWAP-SPACE", "SWAPSPACE2" };
++      const char *swsusp_sigs[] = {"S1SUSP", "S2SUSP", "S1SUSPEND" };
++      char *swap_header;
++
++      if (!toi_cur_sig_page) {
++              int result = get_signature_page();
++
++              if (result)
++                      return result;
++      }
++
++      /*
++       * Start by looking for the binary header.
++       */
++      if (!memcmp(tuxonice_signature, toi_cur_sig_page,
++                              sizeof(tuxonice_signature))) {
++              have_image = toi_sig_data->have_image;
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Have binary signature. "
++                              "Have image is %d.", have_image);
++              if (have_image)
++                      toi_message(TOI_IO, TOI_VERBOSE, 0, "header dev_t is "
++                                      "%x. First block is %d.",
++                                      toi_sig_data->header_dev_t,
++                                      toi_sig_data->first_header_block);
++              return toi_sig_data->have_image;
++      }
++
++      /*
++       * Failing that, try old file allocator headers.
++       */
++
++      if (!memcmp(HaveImage, toi_cur_sig_page, strlen(HaveImage))) {
++              have_image = 1;
++              return 1;
++      }
++
++      have_image = 0;
++
++      if (!memcmp(NoImage, toi_cur_sig_page, strlen(NoImage)))
++              return 0;
++
++      /*
++       * Nope? How about swap?
++       */
++      swap_header_page = (union p_diskpage) toi_cur_sig_page;
++      swap_header = swap_header_page.pointer->swh.magic.magic;
++
++      /* Normal swapspace? */
++      for (type = 0; type < 2; type++)
++              if (!memcmp(normal_sigs[type], swap_header,
++                                      strlen(normal_sigs[type])))
++                      return 0;
++
++      /* Swsusp or uswsusp? */
++      for (type = 0; type < 3; type++)
++              if (!memcmp(swsusp_sigs[type], swap_header,
++                                      strlen(swsusp_sigs[type])))
++                      return 2;
++
++      return -1;
++}
++
++/*
++ * Image_exists
 + *
-+ * If a node has no image, it needs to wait, in case other nodes which do have
-+ * an image are going to resume, but are taking longer to announce their
-+ * presence. For this reason, the user can specify a timeout value and a number
-+ * of nodes detected before we just continue. (We might want to assume in a
-+ * cluster of, say, 15 nodes, if 8 others have booted without finding an image,
-+ * the remaining nodes will too. This might help in situations where some nodes
-+ * are much slower to boot, or more subject to hardware failures or such like).
++ * Returns -1 if don't know, otherwise 0 (no) or 1 (yes).
 + */
++int toi_bio_image_exists(int quiet)
++{
++      int result;
++      char *orig_sig_page = toi_cur_sig_page;
++      char *msg = NULL;
 +
-+#include <linux/suspend.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/if.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/ip.h>
-+#include <linux/udp.h>
-+#include <linux/in.h>
-+#include <linux/if_arp.h>
-+#include <linux/kthread.h>
-+#include <linux/wait.h>
-+#include <linux/netdevice.h>
-+#include <net/ip.h>
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_bio_image_exists.");
++
++      if (!resume_dev_t) {
++              if (!quiet)
++                      printk(KERN_INFO "Not even trying to read header "
++                              "because resume_dev_t is not set.\n");
++              return -1;
++      }
++
++      if (!resume_block_device) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Opening resume_dev_t %lx.",
++                              resume_dev_t);
++              resume_block_device = toi_open_bdev(NULL, resume_dev_t, 1);
++              if (IS_ERR(resume_block_device)) {
++                      if (!quiet)
++                              printk(KERN_INFO "Failed to open resume dev_t"
++                                              " (%x).\n", resume_dev_t);
++                      return -1;
++              }
++      }
++
++      result = toi_check_for_signature();
++
++      clear_toi_state(TOI_RESUMED_BEFORE);
++      if (toi_sig_data->resumed_before)
++              set_toi_state(TOI_RESUMED_BEFORE);
++
++      if (quiet || result == -ENOMEM)
++              goto out;
++
++      if (result == -1)
++              msg = "TuxOnIce: Unable to find a signature."
++                              " Could you have moved a swap file?\n";
++      else if (!result)
++              msg = "TuxOnIce: No image found.\n";
++      else if (result == 1)
++              msg = "TuxOnIce: Image found.\n";
++      else if (result == 2)
++              msg = "TuxOnIce: uswsusp or swsusp image found.\n";
 +
++      printk(KERN_INFO "%s", msg);
++
++out:
++      if (!orig_sig_page)
++              forget_signature_page();
++
++      return result;
++}
+diff --git a/kernel/power/tuxonice_builtin.c b/kernel/power/tuxonice_builtin.c
+new file mode 100644
+index 0000000..b75663d
+--- /dev/null
++++ b/kernel/power/tuxonice_builtin.c
+@@ -0,0 +1,349 @@
++/*
++ * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
++ *
++ * This file is released under the GPLv2.
++ */
++#include <linux/resume-trace.h>
++#include <linux/kernel.h>
++#include <linux/swap.h>
++#include <linux/syscalls.h>
++#include <linux/bio.h>
++#include <linux/root_dev.h>
++#include <linux/freezer.h>
++#include <linux/reboot.h>
++#include <linux/writeback.h>
++#include <linux/tty.h>
++#include <linux/crypto.h>
++#include <linux/cpu.h>
++#include <linux/ctype.h>
++#include "tuxonice_io.h"
 +#include "tuxonice.h"
-+#include "tuxonice_modules.h"
++#include "tuxonice_extent.h"
++#include "tuxonice_netlink.h"
++#include "tuxonice_prepare_image.h"
++#include "tuxonice_ui.h"
 +#include "tuxonice_sysfs.h"
-+#include "tuxonice_alloc.h"
-+#include "tuxonice_io.h"
-+
-+#if 1
-+#define PRINTK(a, b...) do { printk(a, ##b); } while (0)
-+#else
-+#define PRINTK(a, b...) do { } while (0)
-+#endif
++#include "tuxonice_pagedir.h"
++#include "tuxonice_modules.h"
++#include "tuxonice_builtin.h"
++#include "tuxonice_power_off.h"
 +
-+static int loopback_mode;
-+static int num_local_nodes = 1;
-+#define MAX_LOCAL_NODES 8
-+#define SADDR (loopback_mode ? b->sid : h->saddr)
++/*
++ * Highmem related functions (x86 only).
++ */
 +
-+#define MYNAME "TuxOnIce Clustering"
++#ifdef CONFIG_HIGHMEM
 +
-+enum cluster_message {
-+      MSG_ACK = 1,
-+      MSG_NACK = 2,
-+      MSG_PING = 4,
-+      MSG_ABORT = 8,
-+      MSG_BYE = 16,
-+      MSG_HIBERNATE = 32,
-+      MSG_IMAGE = 64,
-+      MSG_IO = 128,
-+      MSG_RUNNING = 256
-+};
++/**
++ * copyback_high: Restore highmem pages.
++ *
++ * Highmem data and pbe lists are/can be stored in highmem.
++ * The format is slightly different to the lowmem pbe lists
++ * used for the assembly code: the last pbe in each page is
++ * a struct page * instead of struct pbe *, pointing to the
++ * next page where pbes are stored (or NULL if happens to be
++ * the end of the list). Since we don't want to generate
++ * unnecessary deltas against swsusp code, we use a cast
++ * instead of a union.
++ **/
 +
-+static char *str_message(int message)
++static void copyback_high(void)
 +{
-+      switch (message) {
-+      case 4:
-+              return "Ping";
-+      case 8:
-+              return "Abort";
-+      case 9:
-+              return "Abort acked";
-+      case 10:
-+              return "Abort nacked";
-+      case 16:
-+              return "Bye";
-+      case 17:
-+              return "Bye acked";
-+      case 18:
-+              return "Bye nacked";
-+      case 32:
-+              return "Hibernate request";
-+      case 33:
-+              return "Hibernate ack";
-+      case 34:
-+              return "Hibernate nack";
-+      case 64:
-+              return "Image exists?";
-+      case 65:
-+              return "Image does exist";
-+      case 66:
-+              return "No image here";
-+      case 128:
-+              return "I/O";
-+      case 129:
-+              return "I/O okay";
-+      case 130:
-+              return "I/O failed";
-+      case 256:
-+              return "Running";
-+      default:
-+              printk(KERN_ERR "Unrecognised message %d.\n", message);
-+              return "Unrecognised message (see dmesg)";
++      struct page *pbe_page = (struct page *) restore_highmem_pblist;
++      struct pbe *this_pbe, *first_pbe;
++      unsigned long *origpage, *copypage;
++      int pbe_index = 1;
++
++      if (!pbe_page)
++              return;
++
++      this_pbe = (struct pbe *) kmap_atomic(pbe_page, KM_BOUNCE_READ);
++      first_pbe = this_pbe;
++
++      while (this_pbe) {
++              int loop = (PAGE_SIZE / sizeof(unsigned long)) - 1;
++
++              origpage = kmap_atomic((struct page *) this_pbe->orig_address,
++                      KM_BIO_DST_IRQ);
++              copypage = kmap_atomic((struct page *) this_pbe->address,
++                      KM_BIO_SRC_IRQ);
++
++              while (loop >= 0) {
++                      *(origpage + loop) = *(copypage + loop);
++                      loop--;
++              }
++
++              kunmap_atomic(origpage, KM_BIO_DST_IRQ);
++              kunmap_atomic(copypage, KM_BIO_SRC_IRQ);
++
++              if (!this_pbe->next)
++                      break;
++
++              if (pbe_index < PBES_PER_PAGE) {
++                      this_pbe++;
++                      pbe_index++;
++              } else {
++                      pbe_page = (struct page *) this_pbe->next;
++                      kunmap_atomic(first_pbe, KM_BOUNCE_READ);
++                      if (!pbe_page)
++                              return;
++                      this_pbe = (struct pbe *) kmap_atomic(pbe_page,
++                                      KM_BOUNCE_READ);
++                      first_pbe = this_pbe;
++                      pbe_index = 1;
++              }
 +      }
++      kunmap_atomic(first_pbe, KM_BOUNCE_READ);
 +}
 +
-+#define MSG_ACK_MASK (MSG_ACK | MSG_NACK)
-+#define MSG_STATE_MASK (~MSG_ACK_MASK)
++#else /* CONFIG_HIGHMEM */
++static void copyback_high(void) { }
++#endif
 +
-+struct node_info {
-+      struct list_head member_list;
-+      wait_queue_head_t member_events;
-+      spinlock_t member_list_lock;
-+      spinlock_t receive_lock;
-+      int peer_count, ignored_peer_count;
-+      struct toi_sysfs_data sysfs_data;
-+      enum cluster_message current_message;
-+};
++char toi_wait_for_keypress_dev_console(int timeout)
++{
++      int fd, this_timeout = 255;
++      char key = '\0';
++      struct termios t, t_backup;
++
++      /* We should be guaranteed /dev/console exists after populate_rootfs()
++       * in init/main.c.
++       */
++      fd = sys_open("/dev/console", O_RDONLY, 0);
++      if (fd < 0) {
++              printk(KERN_INFO "Couldn't open /dev/console.\n");
++              return key;
++      }
++
++      if (sys_ioctl(fd, TCGETS, (long)&t) < 0)
++              goto out_close;
++
++      memcpy(&t_backup, &t, sizeof(t));
++
++      t.c_lflag &= ~(ISIG|ICANON|ECHO);
++      t.c_cc[VMIN] = 0;
++
++new_timeout:
++      if (timeout > 0) {
++              this_timeout = timeout < 26 ? timeout : 25;
++              timeout -= this_timeout;
++              this_timeout *= 10;
++      }
++
++      t.c_cc[VTIME] = this_timeout;
++
++      if (sys_ioctl(fd, TCSETS, (long)&t) < 0)
++              goto out_restore;
++
++      while (1) {
++              if (sys_read(fd, &key, 1) <= 0) {
++                      if (timeout)
++                              goto new_timeout;
++                      key = '\0';
++                      break;
++              }
++              key = tolower(key);
++              if (test_toi_state(TOI_SANITY_CHECK_PROMPT)) {
++                      if (key == 'c') {
++                              set_toi_state(TOI_CONTINUE_REQ);
++                              break;
++                      } else if (key == ' ')
++                              break;
++              } else
++                      break;
++      }
 +
-+struct node_info node_array[MAX_LOCAL_NODES];
++out_restore:
++      sys_ioctl(fd, TCSETS, (long)&t_backup);
++out_close:
++      sys_close(fd);
 +
-+struct cluster_member {
-+      __be32 addr;
-+      enum cluster_message message;
-+      struct list_head list;
-+      int ignore;
++      return key;
++}
++EXPORT_SYMBOL_GPL(toi_wait_for_keypress_dev_console);
++
++struct toi_boot_kernel_data toi_bkd __nosavedata
++              __attribute__((aligned(PAGE_SIZE))) = {
++      MY_BOOT_KERNEL_DATA_VERSION,
++      0,
++#ifdef CONFIG_TOI_REPLACE_SWSUSP
++      (1 << TOI_REPLACE_SWSUSP) |
++#endif
++      (1 << TOI_NO_FLUSHER_THREAD) |
++      (1 << TOI_PAGESET2_FULL) | (1 << TOI_LATE_CPU_HOTPLUG),
 +};
++EXPORT_SYMBOL_GPL(toi_bkd);
 +
-+#define toi_cluster_port_send 3501
-+#define toi_cluster_port_recv 3502
++struct block_device *toi_open_by_devnum(dev_t dev, fmode_t mode)
++{
++      struct block_device *bdev = bdget(dev);
++      int err = -ENOMEM;
++      if (bdev)
++              err = blkdev_get(bdev, mode);
++      return err ? ERR_PTR(err) : bdev;
++}
++EXPORT_SYMBOL_GPL(toi_open_by_devnum);
 +
-+static struct net_device *net_dev;
-+static struct toi_module_ops toi_cluster_ops;
++int toi_wait = CONFIG_TOI_DEFAULT_WAIT;
++EXPORT_SYMBOL_GPL(toi_wait);
 +
-+static int toi_recv(struct sk_buff *skb, struct net_device *dev,
-+              struct packet_type *pt, struct net_device *orig_dev);
++struct toi_core_fns *toi_core_fns;
++EXPORT_SYMBOL_GPL(toi_core_fns);
 +
-+static struct packet_type toi_cluster_packet_type = {
-+      .type = __constant_htons(ETH_P_IP),
-+      .func = toi_recv,
-+};
++unsigned long toi_result;
++EXPORT_SYMBOL_GPL(toi_result);
 +
-+struct toi_pkt {              /* BOOTP packet format */
-+      struct iphdr iph;       /* IP header */
-+      struct udphdr udph;     /* UDP header */
-+      u8 htype;               /* HW address type */
-+      u8 hlen;                /* HW address length */
-+      __be32 xid;             /* Transaction ID */
-+      __be16 secs;            /* Seconds since we started */
-+      __be16 flags;           /* Just what it says */
-+      u8 hw_addr[16];         /* Sender's HW address */
-+      u16 message;            /* Message */
-+      unsigned long sid;      /* Source ID for loopback testing */
-+};
++struct pagedir pagedir1 = {1};
++EXPORT_SYMBOL_GPL(pagedir1);
 +
-+static char toi_cluster_iface[IFNAMSIZ] = CONFIG_TOI_DEFAULT_CLUSTER_INTERFACE;
++unsigned long toi_get_nonconflicting_page(void)
++{
++      return toi_core_fns->get_nonconflicting_page();
++}
 +
-+static int added_pack;
++int toi_post_context_save(void)
++{
++      return toi_core_fns->post_context_save();
++}
 +
-+static int others_have_image;
++int try_tuxonice_hibernate(void)
++{
++      if (!toi_core_fns)
++              return -ENODEV;
 +
-+/* Key used to allow multiple clusters on the same lan */
-+static char toi_cluster_key[32] = CONFIG_TOI_DEFAULT_CLUSTER_KEY;
-+static char pre_hibernate_script[255] =
-+      CONFIG_TOI_DEFAULT_CLUSTER_PRE_HIBERNATE;
-+static char post_hibernate_script[255] =
-+      CONFIG_TOI_DEFAULT_CLUSTER_POST_HIBERNATE;
++      return toi_core_fns->try_hibernate();
++}
 +
-+/*                    List of cluster members                 */
-+static unsigned long continue_delay = 5 * HZ;
-+static unsigned long cluster_message_timeout = 3 * HZ;
++static int num_resume_calls;
++#ifdef CONFIG_TOI_IGNORE_LATE_INITCALL
++static int ignore_late_initcall = 1;
++#else
++static int ignore_late_initcall;
++#endif
 +
-+/*            === Membership list ===         */
++int toi_translate_err_default = TOI_CONTINUE_REQ;
++EXPORT_SYMBOL_GPL(toi_translate_err_default);
 +
-+static void print_member_info(int index)
++void try_tuxonice_resume(void)
 +{
-+      struct cluster_member *this;
++      /* Don't let it wrap around eventually */
++      if (num_resume_calls < 2)
++              num_resume_calls++;
 +
-+      printk(KERN_INFO "==> Dumping node %d.\n", index);
++      if (num_resume_calls == 1 && ignore_late_initcall) {
++              printk(KERN_INFO "TuxOnIce: Ignoring late initcall, as requested.\n");
++              return;
++      }
 +
-+      list_for_each_entry(this, &node_array[index].member_list, list)
-+              printk(KERN_INFO "%d.%d.%d.%d last message %s. %s\n",
-+                              NIPQUAD(this->addr),
-+                              str_message(this->message),
-+                              this->ignore ? "(Ignored)" : "");
-+      printk(KERN_INFO "== Done ==\n");
++      if (toi_core_fns)
++              toi_core_fns->try_resume();
++      else
++              printk(KERN_INFO "TuxOnIce core not loaded yet.\n");
 +}
 +
-+static struct cluster_member *__find_member(int index, __be32 addr)
++int toi_lowlevel_builtin(void)
 +{
-+      struct cluster_member *this;
++      int error = 0;
 +
-+      list_for_each_entry(this, &node_array[index].member_list, list) {
-+              if (this->addr != addr)
-+                      continue;
++      save_processor_state();
++      error = swsusp_arch_suspend();
++      if (error)
++              printk(KERN_ERR "Error %d hibernating\n", error);
 +
-+              return this;
++      /* Restore control flow appears here */
++      if (!toi_in_hibernate) {
++              copyback_high();
++              set_toi_state(TOI_NOW_RESUMING);
 +      }
 +
-+      return NULL;
++      restore_processor_state();
++
++      return error;
 +}
++EXPORT_SYMBOL_GPL(toi_lowlevel_builtin);
 +
-+static void set_ignore(int index, __be32 addr, struct cluster_member *this)
-+{
-+      if (this->ignore) {
-+              PRINTK("Node %d already ignoring %d.%d.%d.%d.\n",
-+                              index, NIPQUAD(addr));
-+              return;
-+      }
++unsigned long toi_compress_bytes_in;
++EXPORT_SYMBOL_GPL(toi_compress_bytes_in);
 +
-+      PRINTK("Node %d sees node %d.%d.%d.%d now being ignored.\n",
-+                              index, NIPQUAD(addr));
-+      this->ignore = 1;
-+      node_array[index].ignored_peer_count++;
-+}
++unsigned long toi_compress_bytes_out;
++EXPORT_SYMBOL_GPL(toi_compress_bytes_out);
 +
-+static int __add_update_member(int index, __be32 addr, int message)
-+{
-+      struct cluster_member *this;
++unsigned long toi_state = ((1 << TOI_BOOT_TIME) |
++              (1 << TOI_IGNORE_LOGLEVEL) |
++              (1 << TOI_IO_STOPPED));
++EXPORT_SYMBOL_GPL(toi_state);
 +
-+      this = __find_member(index, addr);
-+      if (this) {
-+              if (this->message != message) {
-+                      this->message = message;
-+                      if ((message & MSG_NACK) &&
-+                          (message & (MSG_HIBERNATE | MSG_IMAGE | MSG_IO)))
-+                              set_ignore(index, addr, this);
-+                      PRINTK("Node %d sees node %d.%d.%d.%d now sending "
-+                                      "%s.\n", index, NIPQUAD(addr),
-+                                      str_message(message));
-+                      wake_up(&node_array[index].member_events);
-+              }
-+              return 0;
-+      }
++/* The number of hibernates we have started (some may have been cancelled) */
++unsigned int nr_hibernates;
++EXPORT_SYMBOL_GPL(nr_hibernates);
 +
-+      this = (struct cluster_member *) toi_kzalloc(36,
-+                      sizeof(struct cluster_member), GFP_KERNEL);
++int toi_running;
++EXPORT_SYMBOL_GPL(toi_running);
 +
-+      if (!this)
-+              return -1;
++__nosavedata int toi_in_hibernate;
++EXPORT_SYMBOL_GPL(toi_in_hibernate);
 +
-+      this->addr = addr;
-+      this->message = message;
-+      this->ignore = 0;
-+      INIT_LIST_HEAD(&this->list);
++__nosavedata struct pbe *restore_highmem_pblist;
++EXPORT_SYMBOL_GPL(restore_highmem_pblist);
 +
-+      node_array[index].peer_count++;
++static int __init toi_wait_setup(char *str)
++{
++      int value;
 +
-+      PRINTK("Node %d sees node %d.%d.%d.%d sending %s.\n", index,
-+                      NIPQUAD(addr), str_message(message));
++      if (sscanf(str, "=%d", &value)) {
++              if (value < -1 || value > 255)
++                      printk(KERN_INFO "TuxOnIce_wait outside range -1 to "
++                                      "255.\n");
++              else
++                      toi_wait = value;
++      }
 +
-+      if ((message & MSG_NACK) &&
-+          (message & (MSG_HIBERNATE | MSG_IMAGE | MSG_IO)))
-+              set_ignore(index, addr, this);
-+      list_add_tail(&this->list, &node_array[index].member_list);
 +      return 1;
 +}
 +
-+static int add_update_member(int index, __be32 addr, int message)
-+{
-+      int result;
-+      unsigned long flags;
-+      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
-+      result = __add_update_member(index, addr, message);
-+      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
++__setup("toi_wait", toi_wait_setup);
 +
-+      print_member_info(index);
++static int __init toi_translate_retry_setup(char *str)
++{
++      toi_translate_err_default = 0;
++      return 1;
++}
 +
-+      wake_up(&node_array[index].member_events);
++__setup("toi_translate_retry", toi_translate_retry_setup);
 +
-+      return result;
++static int __init toi_debug_setup(char *str)
++{
++      toi_bkd.toi_action |= (1 << TOI_LOGALL) | (1 << TOI_PAUSE);
++      toi_bkd.toi_debug_state = 255;
++      toi_bkd.toi_default_console_level = 7;
++      return 1;
 +}
 +
-+static void del_member(int index, __be32 addr)
++__setup("toi_debug_setup", toi_debug_setup);
++
++static int __init toi_ignore_late_initcall_setup(char *str)
 +{
-+      struct cluster_member *this;
-+      unsigned long flags;
++      int value;
 +
-+      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
-+      this = __find_member(index, addr);
++      if (sscanf(str, "=%d", &value))
++              ignore_late_initcall = value;
 +
-+      if (this) {
-+              list_del_init(&this->list);
-+              toi_kfree(36, this, sizeof(*this));
-+              node_array[index].peer_count--;
-+      }
++      return 1;
++}
++
++__setup("toi_initramfs_resume_only", toi_ignore_late_initcall_setup);
 +
-+      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
-+}
++int toi_force_no_multithreaded;
++EXPORT_SYMBOL_GPL(toi_force_no_multithreaded);
 +
-+/*            === Message transmission ===    */
++static int __init toi_force_no_multithreaded_setup(char *str)
++{
++      int value;
 +
-+static void toi_send_if(int message, unsigned long my_id);
++      if (sscanf(str, "=%d", &value))
++              toi_force_no_multithreaded = value;
++
++      return 1;
++}
 +
++__setup("toi_no_multithreaded", toi_force_no_multithreaded_setup);
+diff --git a/kernel/power/tuxonice_builtin.h b/kernel/power/tuxonice_builtin.h
+new file mode 100644
+index 0000000..9972bb4
+--- /dev/null
++++ b/kernel/power/tuxonice_builtin.h
+@@ -0,0 +1,29 @@
 +/*
-+ *  Process received TOI packet.
++ * Copyright (C) 2004-2008 Nigel Cunningham (nigel at tuxonice net)
++ *
++ * This file is released under the GPLv2.
 + */
-+static int toi_recv(struct sk_buff *skb, struct net_device *dev,
-+              struct packet_type *pt, struct net_device *orig_dev)
-+{
-+      struct toi_pkt *b;
-+      struct iphdr *h;
-+      int len, result, index;
-+      unsigned long addr, message, ack;
++#include <asm/setup.h>
 +
-+      /* Perform verifications before taking the lock.  */
-+      if (skb->pkt_type == PACKET_OTHERHOST)
-+              goto drop;
++extern struct toi_core_fns *toi_core_fns;
++extern unsigned long toi_compress_bytes_in, toi_compress_bytes_out;
++extern unsigned int nr_hibernates;
++extern int toi_in_hibernate;
 +
-+      if (dev != net_dev)
-+              goto drop;
++extern __nosavedata struct pbe *restore_highmem_pblist;
 +
-+      skb = skb_share_check(skb, GFP_ATOMIC);
-+      if (!skb)
-+              return NET_RX_DROP;
++int toi_lowlevel_builtin(void);
 +
-+      if (!pskb_may_pull(skb,
-+                         sizeof(struct iphdr) +
-+                         sizeof(struct udphdr)))
-+              goto drop;
++#ifdef CONFIG_HIGHMEM
++extern __nosavedata struct zone_data *toi_nosave_zone_list;
++extern __nosavedata unsigned long toi_nosave_max_pfn;
++#endif
 +
-+      b = (struct toi_pkt *)skb_network_header(skb);
-+      h = &b->iph;
++extern unsigned long toi_get_nonconflicting_page(void);
++extern int toi_post_context_save(void);
 +
-+      if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)
-+              goto drop;
++extern char toi_wait_for_keypress_dev_console(int timeout);
++extern struct block_device *toi_open_by_devnum(dev_t dev, fmode_t mode);
++extern int toi_wait;
++extern int toi_translate_err_default;
++extern int toi_force_no_multithreaded;
+diff --git a/kernel/power/tuxonice_checksum.c b/kernel/power/tuxonice_checksum.c
+new file mode 100644
+index 0000000..b8c2c00
+--- /dev/null
++++ b/kernel/power/tuxonice_checksum.c
+@@ -0,0 +1,378 @@
++/*
++ * kernel/power/tuxonice_checksum.c
++ *
++ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
++ * Copyright (C) 2006 Red Hat, inc.
++ *
++ * This file is released under the GPLv2.
++ *
++ * This file contains data checksum routines for TuxOnIce,
++ * using cryptoapi. They are used to locate any modifications
++ * made to pageset 2 while we're saving it.
++ */
 +
-+      /* Fragments are not supported */
-+      if (h->frag_off & htons(IP_OFFSET | IP_MF)) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR "TuxOnIce: Ignoring fragmented "
-+                             "cluster message.\n");
-+              goto drop;
-+      }
++#include <linux/suspend.h>
++#include <linux/highmem.h>
++#include <linux/vmalloc.h>
++#include <linux/crypto.h>
++#include <linux/scatterlist.h>
 +
-+      if (skb->len < ntohs(h->tot_len))
-+              goto drop;
++#include "tuxonice.h"
++#include "tuxonice_modules.h"
++#include "tuxonice_sysfs.h"
++#include "tuxonice_io.h"
++#include "tuxonice_pageflags.h"
++#include "tuxonice_checksum.h"
++#include "tuxonice_pagedir.h"
++#include "tuxonice_alloc.h"
 +
-+      if (ip_fast_csum((char *) h, h->ihl))
-+              goto drop;
++static struct toi_module_ops toi_checksum_ops;
 +
-+      if (b->udph.source != htons(toi_cluster_port_send) ||
-+          b->udph.dest != htons(toi_cluster_port_recv))
-+              goto drop;
++/* Constant at the mo, but I might allow tuning later */
++static char toi_checksum_name[32] = "md4";
++/* Bytes per checksum */
++#define CHECKSUM_SIZE (16)
 +
-+      if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
-+              goto drop;
++#define CHECKSUMS_PER_PAGE ((PAGE_SIZE - sizeof(void *)) / CHECKSUM_SIZE)
 +
-+      len = ntohs(b->udph.len) - sizeof(struct udphdr);
++struct cpu_context {
++      struct crypto_hash *transform;
++      struct hash_desc desc;
++      struct scatterlist sg[2];
++      char *buf;
++};
 +
-+      /* Ok the front looks good, make sure we can get at the rest.  */
-+      if (!pskb_may_pull(skb, skb->len))
-+              goto drop;
++static DEFINE_PER_CPU(struct cpu_context, contexts);
++static int pages_allocated;
++static unsigned long page_list;
 +
-+      b = (struct toi_pkt *)skb_network_header(skb);
-+      h = &b->iph;
++static int toi_num_resaved;
 +
-+      addr = SADDR;
-+      PRINTK(">>> Message %s received from " NIPQUAD_FMT ".\n",
-+                      str_message(b->message), NIPQUAD(addr));
++static unsigned long this_checksum, next_page;
++static int checksum_index;
 +
-+      message = b->message & MSG_STATE_MASK;
-+      ack = b->message & MSG_ACK_MASK;
++static inline int checksum_pages_needed(void)
++{
++      return DIV_ROUND_UP(pagedir2.size, CHECKSUMS_PER_PAGE);
++}
 +
-+      for (index = 0; index < num_local_nodes; index++) {
-+              int new_message = node_array[index].current_message,
-+                  old_message = new_message;
++/* ---- Local buffer management ---- */
 +
-+              if (index == SADDR || !old_message) {
-+                      PRINTK("Ignoring node %d (offline or self).\n", index);
-+                      continue;
-+              }
++/*
++ * toi_checksum_cleanup
++ *
++ * Frees memory allocated for our labours.
++ */
++static void toi_checksum_cleanup(int ending_cycle)
++{
++      int cpu;
 +
-+              /* One message at a time, please. */
-+              spin_lock(&node_array[index].receive_lock);
++      if (ending_cycle) {
++              for_each_online_cpu(cpu) {
++                      struct cpu_context *this = &per_cpu(contexts, cpu);
++                      if (this->transform) {
++                              crypto_free_hash(this->transform);
++                              this->transform = NULL;
++                              this->desc.tfm = NULL;
++                      }
 +
-+              result = add_update_member(index, SADDR, b->message);
-+              if (result == -1) {
-+                      printk(KERN_INFO "Failed to add new cluster member "
-+                                      NIPQUAD_FMT ".\n",
-+                                      NIPQUAD(addr));
-+                      goto drop_unlock;
++                      if (this->buf) {
++                              toi_free_page(27, (unsigned long) this->buf);
++                              this->buf = NULL;
++                      }
 +              }
++      }
++}
 +
-+              switch (b->message & MSG_STATE_MASK) {
-+              case MSG_PING:
-+                      break;
-+              case MSG_ABORT:
-+                      break;
-+              case MSG_BYE:
-+                      break;
-+              case MSG_HIBERNATE:
-+                      /* Can I hibernate? */
-+                      new_message = MSG_HIBERNATE |
-+                              ((index & 1) ? MSG_NACK : MSG_ACK);
-+                      break;
-+              case MSG_IMAGE:
-+                      /* Can I resume? */
-+                      new_message = MSG_IMAGE |
-+                              ((index & 1) ? MSG_NACK : MSG_ACK);
-+                      if (new_message != old_message)
-+                              printk(KERN_ERR "Setting whether I can resume "
-+                                              "to %d.\n", new_message);
-+                      break;
-+              case MSG_IO:
-+                      new_message = MSG_IO | MSG_ACK;
-+                      break;
-+              case MSG_RUNNING:
-+                      break;
-+              default:
-+                      if (net_ratelimit())
-+                              printk(KERN_ERR "Unrecognised TuxOnIce cluster"
-+                                      " message %d from " NIPQUAD_FMT ".\n",
-+                                      b->message, NIPQUAD(addr));
-+              };
++/*
++ * toi_crypto_initialise
++ *
++ * Prepare to do some work by allocating buffers and transforms.
++ * Returns: Int: Zero. Even if we can't set up checksum, we still
++ * seek to hibernate.
++ */
++static int toi_checksum_initialise(int starting_cycle)
++{
++      int cpu;
 +
-+              if (old_message != new_message) {
-+                      node_array[index].current_message = new_message;
-+                      printk(KERN_INFO ">>> Sending new message for node "
-+                                      "%d.\n", index);
-+                      toi_send_if(new_message, index);
-+              } else if (!ack) {
-+                      printk(KERN_INFO ">>> Resending message for node %d.\n",
-+                                      index);
-+                      toi_send_if(new_message, index);
++      if (!(starting_cycle & SYSFS_HIBERNATE) || !toi_checksum_ops.enabled)
++              return 0;
++
++      if (!*toi_checksum_name) {
++              printk(KERN_INFO "TuxOnIce: No checksum algorithm name set.\n");
++              return 1;
++      }
++
++      for_each_online_cpu(cpu) {
++              struct cpu_context *this = &per_cpu(contexts, cpu);
++              struct page *page;
++
++              this->transform = crypto_alloc_hash(toi_checksum_name, 0, 0);
++              if (IS_ERR(this->transform)) {
++                      printk(KERN_INFO "TuxOnIce: Failed to initialise the "
++                              "%s checksum algorithm: %ld.\n",
++                              toi_checksum_name, (long) this->transform);
++                      this->transform = NULL;
++                      return 1;
 +              }
-+drop_unlock:
-+              spin_unlock(&node_array[index].receive_lock);
-+      };
 +
-+drop:
-+      /* Throw the packet out. */
-+      kfree_skb(skb);
++              this->desc.tfm = this->transform;
++              this->desc.flags = 0;
 +
++              page = toi_alloc_page(27, GFP_KERNEL);
++              if (!page)
++                      return 1;
++              this->buf = page_address(page);
++              sg_init_one(&this->sg[0], this->buf, PAGE_SIZE);
++      }
 +      return 0;
 +}
 +
 +/*
-+ *  Send cluster message to single interface.
++ * toi_checksum_print_debug_stats
++ * @buffer: Pointer to a buffer into which the debug info will be printed.
++ * @size: Size of the buffer.
++ *
++ * Print information to be recorded for debugging purposes into a buffer.
++ * Returns: Number of characters written to the buffer.
 + */
-+static void toi_send_if(int message, unsigned long my_id)
-+{
-+      struct sk_buff *skb;
-+      struct toi_pkt *b;
-+      int hh_len = LL_RESERVED_SPACE(net_dev);
-+      struct iphdr *h;
-+
-+      /* Allocate packet */
-+      skb = alloc_skb(sizeof(struct toi_pkt) + hh_len + 15, GFP_KERNEL);
-+      if (!skb)
-+              return;
-+      skb_reserve(skb, hh_len);
-+      b = (struct toi_pkt *) skb_put(skb, sizeof(struct toi_pkt));
-+      memset(b, 0, sizeof(struct toi_pkt));
 +
-+      /* Construct IP header */
-+      skb_reset_network_header(skb);
-+      h = ip_hdr(skb);
-+      h->version = 4;
-+      h->ihl = 5;
-+      h->tot_len = htons(sizeof(struct toi_pkt));
-+      h->frag_off = htons(IP_DF);
-+      h->ttl = 64;
-+      h->protocol = IPPROTO_UDP;
-+      h->daddr = htonl(INADDR_BROADCAST);
-+      h->check = ip_fast_csum((unsigned char *) h, h->ihl);
++static int toi_checksum_print_debug_stats(char *buffer, int size)
++{
++      int len;
 +
-+      /* Construct UDP header */
-+      b->udph.source = htons(toi_cluster_port_send);
-+      b->udph.dest = htons(toi_cluster_port_recv);
-+      b->udph.len = htons(sizeof(struct toi_pkt) - sizeof(struct iphdr));
-+      /* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
++      if (!toi_checksum_ops.enabled)
++              return scnprintf(buffer, size,
++                      "- Checksumming disabled.\n");
 +
-+      /* Construct message */
-+      b->message = message;
-+      b->sid = my_id;
-+      b->htype = net_dev->type; /* can cause undefined behavior */
-+      b->hlen = net_dev->addr_len;
-+      memcpy(b->hw_addr, net_dev->dev_addr, net_dev->addr_len);
-+      b->secs = htons(3); /* 3 seconds */
++      len = scnprintf(buffer, size, "- Checksum method is '%s'.\n",
++                      toi_checksum_name);
++      len += scnprintf(buffer + len, size - len,
++              "  %d pages resaved in atomic copy.\n", toi_num_resaved);
++      return len;
++}
 +
-+      /* Chain packet down the line... */
-+      skb->dev = net_dev;
-+      skb->protocol = htons(ETH_P_IP);
-+      if ((dev_hard_header(skb, net_dev, ntohs(skb->protocol),
-+                   net_dev->broadcast, net_dev->dev_addr, skb->len) < 0) ||
-+                      dev_queue_xmit(skb) < 0)
-+              printk(KERN_INFO "E");
++static int toi_checksum_memory_needed(void)
++{
++      return toi_checksum_ops.enabled ?
++              checksum_pages_needed() << PAGE_SHIFT : 0;
 +}
 +
-+/*    =========================================               */
++static int toi_checksum_storage_needed(void)
++{
++      if (toi_checksum_ops.enabled)
++              return strlen(toi_checksum_name) + sizeof(int) + 1;
++      else
++              return 0;
++}
 +
-+/*                    kTOICluster                     */
++/*
++ * toi_checksum_save_config_info
++ * @buffer: Pointer to a buffer of size PAGE_SIZE.
++ *
++ * Save informaton needed when reloading the image at resume time.
++ * Returns: Number of bytes used for saving our data.
++ */
++static int toi_checksum_save_config_info(char *buffer)
++{
++      int namelen = strlen(toi_checksum_name) + 1;
++      int total_len;
 +
-+static atomic_t num_cluster_threads;
-+static DECLARE_WAIT_QUEUE_HEAD(clusterd_events);
++      *((unsigned int *) buffer) = namelen;
++      strncpy(buffer + sizeof(unsigned int), toi_checksum_name, namelen);
++      total_len = sizeof(unsigned int) + namelen;
++      return total_len;
++}
 +
-+static int kTOICluster(void *data)
++/* toi_checksum_load_config_info
++ * @buffer: Pointer to the start of the data.
++ * @size: Number of bytes that were saved.
++ *
++ * Description:       Reload information needed for dechecksuming the image at
++ * resume time.
++ */
++static void toi_checksum_load_config_info(char *buffer, int size)
 +{
-+      unsigned long my_id;
-+
-+      my_id = atomic_add_return(1, &num_cluster_threads) - 1;
-+      node_array[my_id].current_message = (unsigned long) data;
++      int namelen;
 +
-+      PRINTK("kTOICluster daemon %lu starting.\n", my_id);
++      namelen = *((unsigned int *) (buffer));
++      strncpy(toi_checksum_name, buffer + sizeof(unsigned int),
++                      namelen);
++      return;
++}
 +
-+      current->flags |= PF_NOFREEZE;
++/*
++ * Free Checksum Memory
++ */
 +
-+      while (node_array[my_id].current_message) {
-+              toi_send_if(node_array[my_id].current_message, my_id);
-+              sleep_on_timeout(&clusterd_events,
-+                              cluster_message_timeout);
-+              PRINTK("Link state %lu is %d.\n", my_id,
-+                              node_array[my_id].current_message);
++void free_checksum_pages(void)
++{
++      while (pages_allocated) {
++              unsigned long next = *((unsigned long *) page_list);
++              ClearPageNosave(virt_to_page(page_list));
++              toi_free_page(15, (unsigned long) page_list);
++              page_list = next;
++              pages_allocated--;
 +      }
-+
-+      toi_send_if(MSG_BYE, my_id);
-+      atomic_dec(&num_cluster_threads);
-+      wake_up(&clusterd_events);
-+
-+      PRINTK("kTOICluster daemon %lu exiting.\n", my_id);
-+      __set_current_state(TASK_RUNNING);
-+      return 0;
 +}
 +
-+static void kill_clusterd(void)
++/*
++ * Allocate Checksum Memory
++ */
++
++int allocate_checksum_pages(void)
 +{
-+      int i;
++      int pages_needed = checksum_pages_needed();
 +
-+      for (i = 0; i < num_local_nodes; i++) {
-+              if (node_array[i].current_message) {
-+                      PRINTK("Seeking to kill clusterd %d.\n", i);
-+                      node_array[i].current_message = 0;
++      if (!toi_checksum_ops.enabled)
++              return 0;
++
++      while (pages_allocated < pages_needed) {
++              unsigned long *new_page =
++                (unsigned long *) toi_get_zeroed_page(15, TOI_ATOMIC_GFP);
++              if (!new_page) {
++                      printk(KERN_ERR "Unable to allocate checksum pages.\n");
++                      return -ENOMEM;
 +              }
++              SetPageNosave(virt_to_page(new_page));
++              (*new_page) = page_list;
++              page_list = (unsigned long) new_page;
++              pages_allocated++;
 +      }
-+      wait_event(clusterd_events,
-+                      !atomic_read(&num_cluster_threads));
-+      PRINTK("All cluster daemons have exited.\n");
-+}
-+
-+static int peers_not_in_message(int index, int message, int precise)
-+{
-+      struct cluster_member *this;
-+      unsigned long flags;
-+      int result = 0;
 +
-+      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
-+      list_for_each_entry(this, &node_array[index].member_list, list) {
-+              if (this->ignore)
-+                      continue;
++      next_page = (unsigned long) page_list;
++      checksum_index = 0;
 +
-+              PRINTK("Peer %d.%d.%d.%d sending %s. "
-+                      "Seeking %s.\n",
-+                      NIPQUAD(this->addr),
-+                      str_message(this->message), str_message(message));
-+              if ((precise ? this->message :
-+                                      this->message & MSG_STATE_MASK) !=
-+                                      message)
-+                      result++;
-+      }
-+      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
-+      PRINTK("%d peers in sought message.\n", result);
-+      return result;
++      return 0;
 +}
 +
-+static void reset_ignored(int index)
++char *tuxonice_get_next_checksum(void)
 +{
-+      struct cluster_member *this;
-+      unsigned long flags;
++      if (!toi_checksum_ops.enabled)
++              return NULL;
 +
-+      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
-+      list_for_each_entry(this, &node_array[index].member_list, list)
-+              this->ignore = 0;
-+      node_array[index].ignored_peer_count = 0;
-+      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
-+}
++      if (checksum_index % CHECKSUMS_PER_PAGE)
++              this_checksum += CHECKSUM_SIZE;
++      else {
++              this_checksum = next_page + sizeof(void *);
++              next_page = *((unsigned long *) next_page);
++      }
 +
-+static int peers_in_message(int index, int message, int precise)
-+{
-+      return node_array[index].peer_count -
-+              node_array[index].ignored_peer_count -
-+              peers_not_in_message(index, message, precise);
++      checksum_index++;
++      return (char *) this_checksum;
 +}
 +
-+static int time_to_continue(int index, unsigned long start, int message)
++int tuxonice_calc_checksum(struct page *page, char *checksum_locn)
 +{
-+      int first = peers_not_in_message(index, message, 0);
-+      int second = peers_in_message(index, message, 1);
-+
-+      PRINTK("First part returns %d, second returns %d.\n", first, second);
-+
-+      if (!first && !second) {
-+              PRINTK("All peers answered message %d.\n",
-+                      message);
-+              return 1;
-+      }
++      char *pa;
++      int result, cpu = smp_processor_id();
++      struct cpu_context *ctx = &per_cpu(contexts, cpu);
 +
-+      if (time_after(jiffies, start + continue_delay)) {
-+              PRINTK("Timeout reached.\n");
-+              return 1;
-+      }
++      if (!toi_checksum_ops.enabled)
++              return 0;
 +
-+      PRINTK("Not time to continue yet (%lu < %lu).\n", jiffies,
-+                      start + continue_delay);
-+      return 0;
++      pa = kmap(page);
++      memcpy(ctx->buf, pa, PAGE_SIZE);
++      kunmap(page);
++      result = crypto_hash_digest(&ctx->desc, ctx->sg, PAGE_SIZE,
++                                              checksum_locn);
++      if (result)
++              printk(KERN_ERR "TuxOnIce checksumming: crypto_hash_digest "
++                              "returned %d.\n", result);
++      return result;
 +}
++/*
++ * Calculate checksums
++ */
 +
-+void toi_initiate_cluster_hibernate(void)
++void check_checksums(void)
 +{
-+      int result;
-+      unsigned long start;
++      int pfn, index = 0, cpu = smp_processor_id();
++      char current_checksum[CHECKSUM_SIZE];
++      struct cpu_context *ctx = &per_cpu(contexts, cpu);
 +
-+      result = do_toi_step(STEP_HIBERNATE_PREPARE_IMAGE);
-+      if (result)
++      if (!toi_checksum_ops.enabled)
 +              return;
 +
-+      toi_send_if(MSG_HIBERNATE, 0);
++      next_page = (unsigned long) page_list;
 +
-+      start = jiffies;
-+      wait_event(node_array[0].member_events,
-+                      time_to_continue(0, start, MSG_HIBERNATE));
++      toi_num_resaved = 0;
++      this_checksum = 0;
 +
-+      if (test_action_state(TOI_FREEZER_TEST)) {
-+              toi_send_if(MSG_ABORT, 0);
++      memory_bm_position_reset(pageset2_map);
++      for (pfn = memory_bm_next_pfn(pageset2_map); pfn != BM_END_OF_MAP;
++                      pfn = memory_bm_next_pfn(pageset2_map)) {
++              int ret;
++              char *pa;
++              struct page *page = pfn_to_page(pfn);
 +
-+              start = jiffies;
-+              wait_event(node_array[0].member_events,
-+                      time_to_continue(0, start, MSG_RUNNING));
++              if (index % CHECKSUMS_PER_PAGE) {
++                      this_checksum += CHECKSUM_SIZE;
++              } else {
++                      this_checksum = next_page + sizeof(void *);
++                      next_page = *((unsigned long *) next_page);
++              }
 +
-+              do_toi_step(STEP_QUIET_CLEANUP);
-+              return;
-+      }
++              /* Done when IRQs disabled so must be atomic */
++              pa = kmap_atomic(page, KM_USER1);
++              memcpy(ctx->buf, pa, PAGE_SIZE);
++              kunmap_atomic(pa, KM_USER1);
++              ret = crypto_hash_digest(&ctx->desc, ctx->sg, PAGE_SIZE,
++                                                      current_checksum);
 +
-+      toi_send_if(MSG_IO, 0);
++              if (ret) {
++                      printk(KERN_INFO "Digest failed. Returned %d.\n", ret);
++                      return;
++              }
 +
-+      result = do_toi_step(STEP_HIBERNATE_SAVE_IMAGE);
-+      if (result)
-+              return;
++              if (memcmp(current_checksum, (char *) this_checksum,
++                                                      CHECKSUM_SIZE)) {
++                      SetPageResave(pfn_to_page(pfn));
++                      toi_num_resaved++;
++                      if (test_action_state(TOI_ABORT_ON_RESAVE_NEEDED))
++                              set_abort_result(TOI_RESAVE_NEEDED);
++              }
 +
-+      /* This code runs at resume time too! */
-+      if (toi_in_hibernate)
-+              result = do_toi_step(STEP_HIBERNATE_POWERDOWN);
++              index++;
++      }
 +}
-+EXPORT_SYMBOL_GPL(toi_initiate_cluster_hibernate);
 +
-+/* toi_cluster_print_debug_stats
-+ *
-+ * Description:       Print information to be recorded for debugging purposes into a
-+ *            buffer.
-+ * Arguments: buffer: Pointer to a buffer into which the debug info will be
-+ *                    printed.
-+ *            size:   Size of the buffer.
-+ * Returns:   Number of characters written to the buffer.
++static struct toi_sysfs_data sysfs_params[] = {
++      SYSFS_INT("enabled", SYSFS_RW, &toi_checksum_ops.enabled, 0, 1, 0,
++                      NULL),
++      SYSFS_BIT("abort_if_resave_needed", SYSFS_RW, &toi_bkd.toi_action,
++                      TOI_ABORT_ON_RESAVE_NEEDED, 0)
++};
++
++/*
++ * Ops structure.
 + */
-+static int toi_cluster_print_debug_stats(char *buffer, int size)
-+{
-+      int len;
++static struct toi_module_ops toi_checksum_ops = {
++      .type                   = MISC_MODULE,
++      .name                   = "checksumming",
++      .directory              = "checksum",
++      .module                 = THIS_MODULE,
++      .initialise             = toi_checksum_initialise,
++      .cleanup                = toi_checksum_cleanup,
++      .print_debug_info       = toi_checksum_print_debug_stats,
++      .save_config_info       = toi_checksum_save_config_info,
++      .load_config_info       = toi_checksum_load_config_info,
++      .memory_needed          = toi_checksum_memory_needed,
++      .storage_needed         = toi_checksum_storage_needed,
 +
-+      if (strlen(toi_cluster_iface))
-+              len = scnprintf(buffer, size,
-+                              "- Cluster interface is '%s'.\n",
-+                              toi_cluster_iface);
-+      else
-+              len = scnprintf(buffer, size,
-+                              "- Cluster support is disabled.\n");
-+      return len;
-+}
++      .sysfs_data             = sysfs_params,
++      .num_sysfs_entries      = sizeof(sysfs_params) /
++              sizeof(struct toi_sysfs_data),
++};
 +
-+/* cluster_memory_needed
-+ *
-+ * Description:       Tell the caller how much memory we need to operate during
-+ *            hibernate/resume.
-+ * Returns:   Unsigned long. Maximum number of bytes of memory required for
-+ *            operation.
-+ */
-+static int toi_cluster_memory_needed(void)
++/* ---- Registration ---- */
++int toi_checksum_init(void)
 +{
-+      return 0;
++      int result = toi_register_module(&toi_checksum_ops);
++      return result;
 +}
 +
-+static int toi_cluster_storage_needed(void)
++void toi_checksum_exit(void)
 +{
-+      return 1 + strlen(toi_cluster_iface);
++      toi_unregister_module(&toi_checksum_ops);
 +}
-+
-+/* toi_cluster_save_config_info
+diff --git a/kernel/power/tuxonice_checksum.h b/kernel/power/tuxonice_checksum.h
+new file mode 100644
+index 0000000..84a9174
+--- /dev/null
++++ b/kernel/power/tuxonice_checksum.h
+@@ -0,0 +1,32 @@
++/*
++ * kernel/power/tuxonice_checksum.h
 + *
-+ * Description:       Save informaton needed when reloading the image at resume time.
-+ * Arguments: Buffer:         Pointer to a buffer of size PAGE_SIZE.
-+ * Returns:   Number of bytes used for saving our data.
++ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
++ * Copyright (C) 2006 Red Hat, inc.
++ *
++ * This file is released under the GPLv2.
++ *
++ * This file contains data checksum routines for TuxOnIce,
++ * using cryptoapi. They are used to locate any modifications
++ * made to pageset 2 while we're saving it.
 + */
-+static int toi_cluster_save_config_info(char *buffer)
-+{
-+      strcpy(buffer, toi_cluster_iface);
-+      return strlen(toi_cluster_iface + 1);
-+}
 +
-+/* toi_cluster_load_config_info
++#if defined(CONFIG_TOI_CHECKSUM)
++extern int toi_checksum_init(void);
++extern void toi_checksum_exit(void);
++void check_checksums(void);
++int allocate_checksum_pages(void);
++void free_checksum_pages(void);
++char *tuxonice_get_next_checksum(void);
++int tuxonice_calc_checksum(struct page *page, char *checksum_locn);
++#else
++static inline int toi_checksum_init(void) { return 0; }
++static inline void toi_checksum_exit(void) { }
++static inline void check_checksums(void) { };
++static inline int allocate_checksum_pages(void) { return 0; };
++static inline void free_checksum_pages(void) { };
++static inline char *tuxonice_get_next_checksum(void) { return NULL; };
++static inline int tuxonice_calc_checksum(struct page *page, char *checksum_locn)
++      { return 0; }
++#endif
++
+diff --git a/kernel/power/tuxonice_cluster.c b/kernel/power/tuxonice_cluster.c
+new file mode 100644
+index 0000000..671006d
+--- /dev/null
++++ b/kernel/power/tuxonice_cluster.c
+@@ -0,0 +1,1069 @@
++/*
++ * kernel/power/tuxonice_cluster.c
++ *
++ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
++ *
++ * This file is released under the GPLv2.
++ *
++ * This file contains routines for cluster hibernation support.
++ *
++ * Based on ip autoconfiguration code in net/ipv4/ipconfig.c.
++ *
++ * How does it work?
++ *
++ * There is no 'master' node that tells everyone else what to do. All nodes
++ * send messages to the broadcast address/port, maintain a list of peers
++ * and figure out when to progress to the next step in hibernating or resuming.
++ * This makes us more fault tolerant when it comes to nodes coming and going
++ * (which may be more of an issue if we're hibernating when power supplies
++ * are being unreliable).
++ *
++ * At boot time, we start a ktuxonice thread that handles communication with
++ * other nodes. This node maintains a state machine that controls our progress
++ * through hibernating and resuming, keeping us in step with other nodes. Nodes
++ * are identified by their hw address.
++ *
++ * On startup, the node sends CLUSTER_PING on the configured interface's
++ * broadcast address, port $toi_cluster_port (see below) and begins to listen
++ * for other broadcast messages. CLUSTER_PING messages are repeated at
++ * intervals of 5 minutes, with a random offset to spread traffic out.
++ *
++ * A hibernation cycle is initiated from any node via
++ *
++ * echo > /sys/power/tuxonice/do_hibernate
++ *
++ * and (possibily) the hibernate script. At each step of the process, the node
++ * completes its work, and waits for all other nodes to signal completion of
++ * their work (or timeout) before progressing to the next step.
++ *
++ * Request/state  Action before reply Possible reply  Next state
++ * HIBERNATE    capable, pre-script   HIBERNATE|ACK   NODE_PREP
++ *                                    HIBERNATE|NACK  INIT_0
++ *
++ * PREP                 prepare_image         PREP|ACK        IMAGE_WRITE
++ *                                    PREP|NACK       INIT_0
++ *                                    ABORT           RUNNING
++ *
++ * IO           write image           IO|ACK          power off
++ *                                    ABORT           POST_RESUME
++ *
++ * (Boot time)          check for image       IMAGE|ACK       RESUME_PREP
++ *                                    (Note 1)
++ *                                    IMAGE|NACK      (Note 2)
++ *
++ * PREP                 prepare read image    PREP|ACK        IMAGE_READ
++ *                                    PREP|NACK       (As NACK_IMAGE)
++ *
++ * IO           read image            IO|ACK          POST_RESUME
++ *
++ * POST_RESUME          thaw, post-script                     RUNNING
++ *
++ * INIT_0       init 0
++ *
++ * Other messages:
++ *
++ * - PING: Request for all other live nodes to send a PONG. Used at startup to
++ *   announce presence, when a node is suspected dead and periodically, in case
++ *   segments of the network are [un]plugged.
++ *
++ * - PONG: Response to a PING.
++ *
++ * - ABORT: Request to cancel writing an image.
++ *
++ * - BYE: Notification that this node is shutting down.
++ *
++ * Note 1: Repeated at 3s intervals until we continue to boot/resume, so that
++ * nodes which are slower to start up can get state synchronised. If a node
++ * starting up sees other nodes sending RESUME_PREP or IMAGE_READ, it may send
++ * ACK_IMAGE and they will wait for it to catch up. If it sees ACK_READ, it
++ * must invalidate its image (if any) and boot normally.
++ *
++ * Note 2: May occur when one node lost power or powered off while others
++ * hibernated. This node waits for others to complete resuming (ACK_READ)
++ * before completing its boot, so that it appears as a fail node restarting.
 + *
-+ * Description:       Reload information needed for declustering the image at
-+ *            resume time.
-+ * Arguments: Buffer:         Pointer to the start of the data.
-+ *            Size:           Number of bytes that were saved.
++ * If any node has an image, then it also has a list of nodes that hibernated
++ * in synchronisation with it. The node will wait for other nodes to appear
++ * or timeout before beginning its restoration.
++ *
++ * If a node has no image, it needs to wait, in case other nodes which do have
++ * an image are going to resume, but are taking longer to announce their
++ * presence. For this reason, the user can specify a timeout value and a number
++ * of nodes detected before we just continue. (We might want to assume in a
++ * cluster of, say, 15 nodes, if 8 others have booted without finding an image,
++ * the remaining nodes will too. This might help in situations where some nodes
++ * are much slower to boot, or more subject to hardware failures or such like).
 + */
-+static void toi_cluster_load_config_info(char *buffer, int size)
-+{
-+      strncpy(toi_cluster_iface, buffer, size);
-+      return;
-+}
-+
-+static void cluster_startup(void)
-+{
-+      int have_image = do_check_can_resume(), i;
-+      unsigned long start = jiffies, initial_message;
-+      struct task_struct *p;
-+
-+      initial_message = MSG_IMAGE;
-+
-+      have_image = 1;
-+
-+      for (i = 0; i < num_local_nodes; i++) {
-+              PRINTK("Starting ktoiclusterd %d.\n", i);
-+              p = kthread_create(kTOICluster, (void *) initial_message,
-+                              "ktoiclusterd/%d", i);
-+              if (IS_ERR(p)) {
-+                      printk(KERN_ERR "Failed to start ktoiclusterd.\n");
-+                      return;
-+              }
-+
-+              wake_up_process(p);
-+      }
 +
-+      /* Wait for delay or someone else sending first message */
-+      wait_event(node_array[0].member_events, time_to_continue(0, start,
-+                              MSG_IMAGE));
++#include <linux/suspend.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/if.h>
++#include <linux/rtnetlink.h>
++#include <linux/ip.h>
++#include <linux/udp.h>
++#include <linux/in.h>
++#include <linux/if_arp.h>
++#include <linux/kthread.h>
++#include <linux/wait.h>
++#include <linux/netdevice.h>
++#include <net/ip.h>
 +
-+      others_have_image = peers_in_message(0, MSG_IMAGE | MSG_ACK, 1);
++#include "tuxonice.h"
++#include "tuxonice_modules.h"
++#include "tuxonice_sysfs.h"
++#include "tuxonice_alloc.h"
++#include "tuxonice_io.h"
 +
-+      printk(KERN_INFO "Continuing. I %shave an image. Peers with image:"
-+              " %d.\n", have_image ? "" : "don't ", others_have_image);
++#if 1
++#define PRINTK(a, b...) do { printk(a, ##b); } while (0)
++#else
++#define PRINTK(a, b...) do { } while (0)
++#endif
 +
-+      if (have_image) {
-+              int result;
++static int loopback_mode;
++static int num_local_nodes = 1;
++#define MAX_LOCAL_NODES 8
++#define SADDR (loopback_mode ? b->sid : h->saddr)
 +
-+              /* Start to resume */
-+              printk(KERN_INFO "  === Starting to resume ===  \n");
-+              node_array[0].current_message = MSG_IO;
-+              toi_send_if(MSG_IO, 0);
++#define MYNAME "TuxOnIce Clustering"
 +
-+              /* result = do_toi_step(STEP_RESUME_LOAD_PS1); */
-+              result = 0;
++enum cluster_message {
++      MSG_ACK = 1,
++      MSG_NACK = 2,
++      MSG_PING = 4,
++      MSG_ABORT = 8,
++      MSG_BYE = 16,
++      MSG_HIBERNATE = 32,
++      MSG_IMAGE = 64,
++      MSG_IO = 128,
++      MSG_RUNNING = 256
++};
 +
-+              if (!result) {
-+                      /*
-+                       * Atomic restore - we'll come back in the hibernation
-+                       * path.
-+                       */
++static char *str_message(int message)
++{
++      switch (message) {
++      case 4:
++              return "Ping";
++      case 8:
++              return "Abort";
++      case 9:
++              return "Abort acked";
++      case 10:
++              return "Abort nacked";
++      case 16:
++              return "Bye";
++      case 17:
++              return "Bye acked";
++      case 18:
++              return "Bye nacked";
++      case 32:
++              return "Hibernate request";
++      case 33:
++              return "Hibernate ack";
++      case 34:
++              return "Hibernate nack";
++      case 64:
++              return "Image exists?";
++      case 65:
++              return "Image does exist";
++      case 66:
++              return "No image here";
++      case 128:
++              return "I/O";
++      case 129:
++              return "I/O okay";
++      case 130:
++              return "I/O failed";
++      case 256:
++              return "Running";
++      default:
++              printk(KERN_ERR "Unrecognised message %d.\n", message);
++              return "Unrecognised message (see dmesg)";
++      }
++}
 +
-+                      /* result = do_toi_step(STEP_RESUME_DO_RESTORE); */
-+                      result = 0;
++#define MSG_ACK_MASK (MSG_ACK | MSG_NACK)
++#define MSG_STATE_MASK (~MSG_ACK_MASK)
 +
-+                      /* do_toi_step(STEP_QUIET_CLEANUP); */
-+              }
++struct node_info {
++      struct list_head member_list;
++      wait_queue_head_t member_events;
++      spinlock_t member_list_lock;
++      spinlock_t receive_lock;
++      int peer_count, ignored_peer_count;
++      struct toi_sysfs_data sysfs_data;
++      enum cluster_message current_message;
++};
 +
-+              node_array[0].current_message |= MSG_NACK;
++struct node_info node_array[MAX_LOCAL_NODES];
 +
-+              /* For debugging - disable for real life? */
-+              wait_event(node_array[0].member_events,
-+                              time_to_continue(0, start, MSG_IO));
-+      }
++struct cluster_member {
++      __be32 addr;
++      enum cluster_message message;
++      struct list_head list;
++      int ignore;
++};
 +
-+      if (others_have_image) {
-+              /* Wait for them to resume */
-+              printk(KERN_INFO "Waiting for other nodes to resume.\n");
-+              start = jiffies;
-+              wait_event(node_array[0].member_events,
-+                              time_to_continue(0, start, MSG_RUNNING));
-+              if (peers_not_in_message(0, MSG_RUNNING, 0))
-+                      printk(KERN_INFO "Timed out while waiting for other "
-+                                      "nodes to resume.\n");
-+      }
++#define toi_cluster_port_send 3501
++#define toi_cluster_port_recv 3502
 +
-+      /* Find out whether an image exists here. Send ACK_IMAGE or NACK_IMAGE
-+       * as appropriate.
-+       *
-+       * If we don't have an image:
-+       * - Wait until someone else says they have one, or conditions are met
-+       *   for continuing to boot (n machines or t seconds).
-+       * - If anyone has an image, wait for them to resume before continuing
-+       *   to boot.
-+       *
-+       * If we have an image:
-+       * - Wait until conditions are met before continuing to resume (n
-+       *   machines or t seconds). Send RESUME_PREP and freeze processes.
-+       *   NACK_PREP if freezing fails (shouldn't) and follow logic for
-+       *   us having no image above. On success, wait for [N]ACK_PREP from
-+       *   other machines. Read image (including atomic restore) until done.
-+       *   Wait for ACK_READ from others (should never fail). Thaw processes
-+       *   and do post-resume. (The section after the atomic restore is done
-+       *   via the code for hibernating).
-+       */
++static struct net_device *net_dev;
++static struct toi_module_ops toi_cluster_ops;
 +
-+      node_array[0].current_message = MSG_RUNNING;
-+}
++static int toi_recv(struct sk_buff *skb, struct net_device *dev,
++              struct packet_type *pt, struct net_device *orig_dev);
 +
-+/* toi_cluster_open_iface
-+ *
-+ * Description:       Prepare to use an interface.
-+ */
++static struct packet_type toi_cluster_packet_type = {
++      .type = __constant_htons(ETH_P_IP),
++      .func = toi_recv,
++};
 +
-+static int toi_cluster_open_iface(void)
-+{
-+      struct net_device *dev;
++struct toi_pkt {              /* BOOTP packet format */
++      struct iphdr iph;       /* IP header */
++      struct udphdr udph;     /* UDP header */
++      u8 htype;               /* HW address type */
++      u8 hlen;                /* HW address length */
++      __be32 xid;             /* Transaction ID */
++      __be16 secs;            /* Seconds since we started */
++      __be16 flags;           /* Just what it says */
++      u8 hw_addr[16];         /* Sender's HW address */
++      u16 message;            /* Message */
++      unsigned long sid;      /* Source ID for loopback testing */
++};
 +
-+      rtnl_lock();
++static char toi_cluster_iface[IFNAMSIZ] = CONFIG_TOI_DEFAULT_CLUSTER_INTERFACE;
 +
-+      for_each_netdev(&init_net, dev) {
-+              if (/* dev == &init_net.loopback_dev || */
-+                  strcmp(dev->name, toi_cluster_iface))
-+                      continue;
++static int added_pack;
 +
-+              net_dev = dev;
-+              break;
-+      }
++static int others_have_image;
 +
-+      rtnl_unlock();
++/* Key used to allow multiple clusters on the same lan */
++static char toi_cluster_key[32] = CONFIG_TOI_DEFAULT_CLUSTER_KEY;
++static char pre_hibernate_script[255] =
++      CONFIG_TOI_DEFAULT_CLUSTER_PRE_HIBERNATE;
++static char post_hibernate_script[255] =
++      CONFIG_TOI_DEFAULT_CLUSTER_POST_HIBERNATE;
 +
-+      if (!net_dev) {
-+              printk(KERN_ERR MYNAME ": Device %s not found.\n",
-+                              toi_cluster_iface);
-+              return -ENODEV;
-+      }
++/*                    List of cluster members                 */
++static unsigned long continue_delay = 5 * HZ;
++static unsigned long cluster_message_timeout = 3 * HZ;
 +
-+      dev_add_pack(&toi_cluster_packet_type);
-+      added_pack = 1;
++/*            === Membership list ===         */
 +
-+      loopback_mode = (net_dev == init_net.loopback_dev);
-+      num_local_nodes = loopback_mode ? 8 : 1;
++static void print_member_info(int index)
++{
++      struct cluster_member *this;
 +
-+      PRINTK("Loopback mode is %s. Number of local nodes is %d.\n",
-+                      loopback_mode ? "on" : "off", num_local_nodes);
++      printk(KERN_INFO "==> Dumping node %d.\n", index);
 +
-+      cluster_startup();
-+      return 0;
++      list_for_each_entry(this, &node_array[index].member_list, list)
++              printk(KERN_INFO "%d.%d.%d.%d last message %s. %s\n",
++                              NIPQUAD(this->addr),
++                              str_message(this->message),
++                              this->ignore ? "(Ignored)" : "");
++      printk(KERN_INFO "== Done ==\n");
 +}
 +
-+/* toi_cluster_close_iface
-+ *
-+ * Description: Stop using an interface.
-+ */
-+
-+static int toi_cluster_close_iface(void)
++static struct cluster_member *__find_member(int index, __be32 addr)
 +{
-+      kill_clusterd();
-+      if (added_pack) {
-+              dev_remove_pack(&toi_cluster_packet_type);
-+              added_pack = 0;
++      struct cluster_member *this;
++
++      list_for_each_entry(this, &node_array[index].member_list, list) {
++              if (this->addr != addr)
++                      continue;
++
++              return this;
 +      }
-+      return 0;
++
++      return NULL;
 +}
 +
-+static void write_side_effect(void)
++static void set_ignore(int index, __be32 addr, struct cluster_member *this)
 +{
-+      if (toi_cluster_ops.enabled) {
-+              toi_cluster_open_iface();
-+              set_toi_state(TOI_CLUSTER_MODE);
-+      } else {
-+              toi_cluster_close_iface();
-+              clear_toi_state(TOI_CLUSTER_MODE);
++      if (this->ignore) {
++              PRINTK("Node %d already ignoring %d.%d.%d.%d.\n",
++                              index, NIPQUAD(addr));
++              return;
 +      }
-+}
 +
-+static void node_write_side_effect(void)
-+{
++      PRINTK("Node %d sees node %d.%d.%d.%d now being ignored.\n",
++                              index, NIPQUAD(addr));
++      this->ignore = 1;
++      node_array[index].ignored_peer_count++;
 +}
 +
-+/*
-+ * data for our sysfs entries.
-+ */
-+static struct toi_sysfs_data sysfs_params[] = {
-+      SYSFS_STRING("interface", SYSFS_RW, toi_cluster_iface, IFNAMSIZ, 0,
-+                      NULL),
-+      SYSFS_INT("enabled", SYSFS_RW, &toi_cluster_ops.enabled, 0, 1, 0,
-+                      write_side_effect),
-+      SYSFS_STRING("cluster_name", SYSFS_RW, toi_cluster_key, 32, 0, NULL),
-+      SYSFS_STRING("pre-hibernate-script", SYSFS_RW, pre_hibernate_script,
-+                      256, 0, NULL),
-+      SYSFS_STRING("post-hibernate-script", SYSFS_RW, post_hibernate_script,
-+                      256, 0, STRING),
-+      SYSFS_UL("continue_delay", SYSFS_RW, &continue_delay, HZ / 2, 60 * HZ,
-+                      0)
-+};
++static int __add_update_member(int index, __be32 addr, int message)
++{
++      struct cluster_member *this;
 +
-+/*
-+ * Ops structure.
-+ */
++      this = __find_member(index, addr);
++      if (this) {
++              if (this->message != message) {
++                      this->message = message;
++                      if ((message & MSG_NACK) &&
++                          (message & (MSG_HIBERNATE | MSG_IMAGE | MSG_IO)))
++                              set_ignore(index, addr, this);
++                      PRINTK("Node %d sees node %d.%d.%d.%d now sending "
++                                      "%s.\n", index, NIPQUAD(addr),
++                                      str_message(message));
++                      wake_up(&node_array[index].member_events);
++              }
++              return 0;
++      }
 +
-+static struct toi_module_ops toi_cluster_ops = {
-+      .type                   = FILTER_MODULE,
-+      .name                   = "Cluster",
-+      .directory              = "cluster",
-+      .module                 = THIS_MODULE,
-+      .memory_needed          = toi_cluster_memory_needed,
-+      .print_debug_info       = toi_cluster_print_debug_stats,
-+      .save_config_info       = toi_cluster_save_config_info,
-+      .load_config_info       = toi_cluster_load_config_info,
-+      .storage_needed         = toi_cluster_storage_needed,
++      this = (struct cluster_member *) toi_kzalloc(36,
++                      sizeof(struct cluster_member), GFP_KERNEL);
 +
-+      .sysfs_data             = sysfs_params,
-+      .num_sysfs_entries      = sizeof(sysfs_params) /
-+              sizeof(struct toi_sysfs_data),
-+};
++      if (!this)
++              return -1;
 +
-+/* ---- Registration ---- */
++      this->addr = addr;
++      this->message = message;
++      this->ignore = 0;
++      INIT_LIST_HEAD(&this->list);
 +
-+#ifdef MODULE
-+#define INIT static __init
-+#define EXIT static __exit
-+#else
-+#define INIT
-+#define EXIT
-+#endif
++      node_array[index].peer_count++;
 +
-+INIT int toi_cluster_init(void)
-+{
-+      int temp = toi_register_module(&toi_cluster_ops), i;
-+      struct kobject *kobj = toi_cluster_ops.dir_kobj;
++      PRINTK("Node %d sees node %d.%d.%d.%d sending %s.\n", index,
++                      NIPQUAD(addr), str_message(message));
 +
-+      for (i = 0; i < MAX_LOCAL_NODES; i++) {
-+              node_array[i].current_message = 0;
-+              INIT_LIST_HEAD(&node_array[i].member_list);
-+              init_waitqueue_head(&node_array[i].member_events);
-+              spin_lock_init(&node_array[i].member_list_lock);
-+              spin_lock_init(&node_array[i].receive_lock);
++      if ((message & MSG_NACK) &&
++          (message & (MSG_HIBERNATE | MSG_IMAGE | MSG_IO)))
++              set_ignore(index, addr, this);
++      list_add_tail(&this->list, &node_array[index].member_list);
++      return 1;
++}
 +
-+              /* Set up sysfs entry */
-+              node_array[i].sysfs_data.attr.name = toi_kzalloc(8,
-+                              sizeof(node_array[i].sysfs_data.attr.name),
-+                              GFP_KERNEL);
-+              sprintf((char *) node_array[i].sysfs_data.attr.name, "node_%d",
-+                              i);
-+              node_array[i].sysfs_data.attr.mode = SYSFS_RW;
-+              node_array[i].sysfs_data.type = TOI_SYSFS_DATA_INTEGER;
-+              node_array[i].sysfs_data.flags = 0;
-+              node_array[i].sysfs_data.data.integer.variable =
-+                      (int *) &node_array[i].current_message;
-+              node_array[i].sysfs_data.data.integer.minimum = 0;
-+              node_array[i].sysfs_data.data.integer.maximum = INT_MAX;
-+              node_array[i].sysfs_data.write_side_effect =
-+                      node_write_side_effect;
-+              toi_register_sysfs_file(kobj, &node_array[i].sysfs_data);
-+      }
++static int add_update_member(int index, __be32 addr, int message)
++{
++      int result;
++      unsigned long flags;
++      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
++      result = __add_update_member(index, addr, message);
++      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
 +
-+      toi_cluster_ops.enabled = (strlen(toi_cluster_iface) > 0);
++      print_member_info(index);
 +
-+      if (toi_cluster_ops.enabled)
-+              toi_cluster_open_iface();
++      wake_up(&node_array[index].member_events);
 +
-+      return temp;
++      return result;
 +}
 +
-+EXIT void toi_cluster_exit(void)
++static void del_member(int index, __be32 addr)
 +{
-+      int i;
-+      toi_cluster_close_iface();
++      struct cluster_member *this;
++      unsigned long flags;
 +
-+      for (i = 0; i < MAX_LOCAL_NODES; i++)
-+              toi_unregister_sysfs_file(toi_cluster_ops.dir_kobj,
-+                              &node_array[i].sysfs_data);
-+      toi_unregister_module(&toi_cluster_ops);
-+}
++      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
++      this = __find_member(index, addr);
 +
-+static int __init toi_cluster_iface_setup(char *iface)
-+{
-+      toi_cluster_ops.enabled = (*iface &&
-+                      strcmp(iface, "off"));
++      if (this) {
++              list_del_init(&this->list);
++              toi_kfree(36, this, sizeof(*this));
++              node_array[index].peer_count--;
++      }
 +
-+      if (toi_cluster_ops.enabled)
-+              strncpy(toi_cluster_iface, iface, strlen(iface));
++      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
 +}
 +
-+__setup("toi_cluster=", toi_cluster_iface_setup);
-+
-+#ifdef MODULE
-+MODULE_LICENSE("GPL");
-+module_init(toi_cluster_init);
-+module_exit(toi_cluster_exit);
-+MODULE_AUTHOR("Nigel Cunningham");
-+MODULE_DESCRIPTION("Cluster Support for TuxOnIce");
-+#endif
-diff --git a/kernel/power/tuxonice_cluster.h b/kernel/power/tuxonice_cluster.h
-new file mode 100644
-index 0000000..b0f8918
---- /dev/null
-+++ b/kernel/power/tuxonice_cluster.h
-@@ -0,0 +1,19 @@
-+/*
-+ * kernel/power/tuxonice_cluster.h
-+ *
-+ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
-+ * Copyright (C) 2006 Red Hat, inc.
-+ *
-+ * This file is released under the GPLv2.
-+ */
++/*            === Message transmission ===    */
 +
-+#ifdef CONFIG_TOI_CLUSTER
-+extern int toi_cluster_init(void);
-+extern void toi_cluster_exit(void);
-+extern void toi_initiate_cluster_hibernate(void);
-+#else
-+static inline int toi_cluster_init(void) { return 0; }
-+static inline void toi_cluster_exit(void) { }
-+static inline void toi_initiate_cluster_hibernate(void) { }
-+#endif
++static void toi_send_if(int message, unsigned long my_id);
 +
-diff --git a/kernel/power/tuxonice_compress.c b/kernel/power/tuxonice_compress.c
-new file mode 100644
-index 0000000..1c7aaf3
---- /dev/null
-+++ b/kernel/power/tuxonice_compress.c
-@@ -0,0 +1,445 @@
 +/*
-+ * kernel/power/compression.c
-+ *
-+ * Copyright (C) 2003-2008 Nigel Cunningham (nigel at tuxonice net)
-+ *
-+ * This file is released under the GPLv2.
-+ *
-+ * This file contains data compression routines for TuxOnIce,
-+ * using cryptoapi.
++ *  Process received TOI packet.
 + */
++static int toi_recv(struct sk_buff *skb, struct net_device *dev,
++              struct packet_type *pt, struct net_device *orig_dev)
++{
++      struct toi_pkt *b;
++      struct iphdr *h;
++      int len, result, index;
++      unsigned long addr, message, ack;
 +
-+#include <linux/suspend.h>
-+#include <linux/highmem.h>
-+#include <linux/vmalloc.h>
-+#include <linux/crypto.h>
-+
-+#include "tuxonice_builtin.h"
-+#include "tuxonice.h"
-+#include "tuxonice_modules.h"
-+#include "tuxonice_sysfs.h"
-+#include "tuxonice_io.h"
-+#include "tuxonice_ui.h"
-+#include "tuxonice_alloc.h"
++      /* Perform verifications before taking the lock.  */
++      if (skb->pkt_type == PACKET_OTHERHOST)
++              goto drop;
 +
-+static int toi_expected_compression;
++      if (dev != net_dev)
++              goto drop;
 +
-+static struct toi_module_ops toi_compression_ops;
-+static struct toi_module_ops *next_driver;
++      skb = skb_share_check(skb, GFP_ATOMIC);
++      if (!skb)
++              return NET_RX_DROP;
 +
-+static char toi_compressor_name[32] = "lzo";
++      if (!pskb_may_pull(skb,
++                         sizeof(struct iphdr) +
++                         sizeof(struct udphdr)))
++              goto drop;
 +
-+static DEFINE_MUTEX(stats_lock);
++      b = (struct toi_pkt *)skb_network_header(skb);
++      h = &b->iph;
 +
-+struct cpu_context {
-+      u8 *page_buffer;
-+      struct crypto_comp *transform;
-+      unsigned int len;
-+      char *buffer_start;
-+      char *output_buffer;
-+};
++      if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)
++              goto drop;
 +
-+static DEFINE_PER_CPU(struct cpu_context, contexts);
++      /* Fragments are not supported */
++      if (h->frag_off & htons(IP_OFFSET | IP_MF)) {
++              if (net_ratelimit())
++                      printk(KERN_ERR "TuxOnIce: Ignoring fragmented "
++                             "cluster message.\n");
++              goto drop;
++      }
 +
-+static int toi_compress_prepare_result;
++      if (skb->len < ntohs(h->tot_len))
++              goto drop;
 +
-+/*
-+ * toi_compress_cleanup
-+ *
-+ * Frees memory allocated for our labours.
-+ */
-+static void toi_compress_cleanup(int toi_or_resume)
-+{
-+      int cpu;
++      if (ip_fast_csum((char *) h, h->ihl))
++              goto drop;
 +
-+      if (!toi_or_resume)
-+              return;
++      if (b->udph.source != htons(toi_cluster_port_send) ||
++          b->udph.dest != htons(toi_cluster_port_recv))
++              goto drop;
 +
-+      for_each_online_cpu(cpu) {
-+              struct cpu_context *this = &per_cpu(contexts, cpu);
-+              if (this->transform) {
-+                      crypto_free_comp(this->transform);
-+                      this->transform = NULL;
-+              }
++      if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
++              goto drop;
 +
-+              if (this->page_buffer)
-+                      toi_free_page(16, (unsigned long) this->page_buffer);
++      len = ntohs(b->udph.len) - sizeof(struct udphdr);
 +
-+              this->page_buffer = NULL;
++      /* Ok the front looks good, make sure we can get at the rest.  */
++      if (!pskb_may_pull(skb, skb->len))
++              goto drop;
 +
-+              if (this->output_buffer)
-+                      vfree(this->output_buffer);
++      b = (struct toi_pkt *)skb_network_header(skb);
++      h = &b->iph;
 +
-+              this->output_buffer = NULL;
-+      }
-+}
++      addr = SADDR;
++      PRINTK(">>> Message %s received from " NIPQUAD_FMT ".\n",
++                      str_message(b->message), NIPQUAD(addr));
 +
-+/*
-+ * toi_crypto_prepare
-+ *
-+ * Prepare to do some work by allocating buffers and transforms.
-+ */
-+static int toi_compress_crypto_prepare(void)
-+{
-+      int cpu;
++      message = b->message & MSG_STATE_MASK;
++      ack = b->message & MSG_ACK_MASK;
 +
-+      if (!*toi_compressor_name) {
-+              printk(KERN_INFO "TuxOnIce: Compression enabled but no "
-+                              "compressor name set.\n");
-+              return 1;
-+      }
++      for (index = 0; index < num_local_nodes; index++) {
++              int new_message = node_array[index].current_message,
++                  old_message = new_message;
 +
-+      for_each_online_cpu(cpu) {
-+              struct cpu_context *this = &per_cpu(contexts, cpu);
-+              this->transform = crypto_alloc_comp(toi_compressor_name, 0, 0);
-+              if (IS_ERR(this->transform)) {
-+                      printk(KERN_INFO "TuxOnIce: Failed to initialise the "
-+                                      "%s compression transform.\n",
-+                                      toi_compressor_name);
-+                      this->transform = NULL;
-+                      return 1;
++              if (index == SADDR || !old_message) {
++                      PRINTK("Ignoring node %d (offline or self).\n", index);
++                      continue;
 +              }
 +
-+              this->page_buffer =
-+                      (char *) toi_get_zeroed_page(16, TOI_ATOMIC_GFP);
++              /* One message at a time, please. */
++              spin_lock(&node_array[index].receive_lock);
 +
-+              if (!this->page_buffer) {
-+                      printk(KERN_ERR
-+                        "Failed to allocate a page buffer for TuxOnIce "
-+                        "compression driver.\n");
-+                      return -ENOMEM;
++              result = add_update_member(index, SADDR, b->message);
++              if (result == -1) {
++                      printk(KERN_INFO "Failed to add new cluster member "
++                                      NIPQUAD_FMT ".\n",
++                                      NIPQUAD(addr));
++                      goto drop_unlock;
 +              }
 +
-+              this->output_buffer =
-+                      (char *) vmalloc_32(2 * PAGE_SIZE);
++              switch (b->message & MSG_STATE_MASK) {
++              case MSG_PING:
++                      break;
++              case MSG_ABORT:
++                      break;
++              case MSG_BYE:
++                      break;
++              case MSG_HIBERNATE:
++                      /* Can I hibernate? */
++                      new_message = MSG_HIBERNATE |
++                              ((index & 1) ? MSG_NACK : MSG_ACK);
++                      break;
++              case MSG_IMAGE:
++                      /* Can I resume? */
++                      new_message = MSG_IMAGE |
++                              ((index & 1) ? MSG_NACK : MSG_ACK);
++                      if (new_message != old_message)
++                              printk(KERN_ERR "Setting whether I can resume "
++                                              "to %d.\n", new_message);
++                      break;
++              case MSG_IO:
++                      new_message = MSG_IO | MSG_ACK;
++                      break;
++              case MSG_RUNNING:
++                      break;
++              default:
++                      if (net_ratelimit())
++                              printk(KERN_ERR "Unrecognised TuxOnIce cluster"
++                                      " message %d from " NIPQUAD_FMT ".\n",
++                                      b->message, NIPQUAD(addr));
++              };
 +
-+              if (!this->output_buffer) {
-+                      printk(KERN_ERR
-+                        "Failed to allocate a output buffer for TuxOnIce "
-+                        "compression driver.\n");
-+                      return -ENOMEM;
++              if (old_message != new_message) {
++                      node_array[index].current_message = new_message;
++                      printk(KERN_INFO ">>> Sending new message for node "
++                                      "%d.\n", index);
++                      toi_send_if(new_message, index);
++              } else if (!ack) {
++                      printk(KERN_INFO ">>> Resending message for node %d.\n",
++                                      index);
++                      toi_send_if(new_message, index);
 +              }
++drop_unlock:
++              spin_unlock(&node_array[index].receive_lock);
++      };
 +
-+      }
++drop:
++      /* Throw the packet out. */
++      kfree_skb(skb);
 +
 +      return 0;
 +}
 +
 +/*
-+ * toi_compress_init
++ *  Send cluster message to single interface.
 + */
++static void toi_send_if(int message, unsigned long my_id)
++{
++      struct sk_buff *skb;
++      struct toi_pkt *b;
++      int hh_len = LL_RESERVED_SPACE(net_dev);
++      struct iphdr *h;
 +
-+static int toi_compress_init(int toi_or_resume)
++      /* Allocate packet */
++      skb = alloc_skb(sizeof(struct toi_pkt) + hh_len + 15, GFP_KERNEL);
++      if (!skb)
++              return;
++      skb_reserve(skb, hh_len);
++      b = (struct toi_pkt *) skb_put(skb, sizeof(struct toi_pkt));
++      memset(b, 0, sizeof(struct toi_pkt));
++
++      /* Construct IP header */
++      skb_reset_network_header(skb);
++      h = ip_hdr(skb);
++      h->version = 4;
++      h->ihl = 5;
++      h->tot_len = htons(sizeof(struct toi_pkt));
++      h->frag_off = htons(IP_DF);
++      h->ttl = 64;
++      h->protocol = IPPROTO_UDP;
++      h->daddr = htonl(INADDR_BROADCAST);
++      h->check = ip_fast_csum((unsigned char *) h, h->ihl);
++
++      /* Construct UDP header */
++      b->udph.source = htons(toi_cluster_port_send);
++      b->udph.dest = htons(toi_cluster_port_recv);
++      b->udph.len = htons(sizeof(struct toi_pkt) - sizeof(struct iphdr));
++      /* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
++
++      /* Construct message */
++      b->message = message;
++      b->sid = my_id;
++      b->htype = net_dev->type; /* can cause undefined behavior */
++      b->hlen = net_dev->addr_len;
++      memcpy(b->hw_addr, net_dev->dev_addr, net_dev->addr_len);
++      b->secs = htons(3); /* 3 seconds */
++
++      /* Chain packet down the line... */
++      skb->dev = net_dev;
++      skb->protocol = htons(ETH_P_IP);
++      if ((dev_hard_header(skb, net_dev, ntohs(skb->protocol),
++                   net_dev->broadcast, net_dev->dev_addr, skb->len) < 0) ||
++                      dev_queue_xmit(skb) < 0)
++              printk(KERN_INFO "E");
++}
++
++/*    =========================================               */
++
++/*                    kTOICluster                     */
++
++static atomic_t num_cluster_threads;
++static DECLARE_WAIT_QUEUE_HEAD(clusterd_events);
++
++static int kTOICluster(void *data)
 +{
-+      if (!toi_or_resume)
-+              return 0;
++      unsigned long my_id;
++
++      my_id = atomic_add_return(1, &num_cluster_threads) - 1;
++      node_array[my_id].current_message = (unsigned long) data;
 +
-+      toi_compress_bytes_in = 0;
-+      toi_compress_bytes_out = 0;
++      PRINTK("kTOICluster daemon %lu starting.\n", my_id);
 +
-+      next_driver = toi_get_next_filter(&toi_compression_ops);
++      current->flags |= PF_NOFREEZE;
 +
-+      if (!next_driver)
-+              return -ECHILD;
++      while (node_array[my_id].current_message) {
++              toi_send_if(node_array[my_id].current_message, my_id);
++              sleep_on_timeout(&clusterd_events,
++                              cluster_message_timeout);
++              PRINTK("Link state %lu is %d.\n", my_id,
++                              node_array[my_id].current_message);
++      }
 +
-+      toi_compress_prepare_result = toi_compress_crypto_prepare();
++      toi_send_if(MSG_BYE, my_id);
++      atomic_dec(&num_cluster_threads);
++      wake_up(&clusterd_events);
 +
++      PRINTK("kTOICluster daemon %lu exiting.\n", my_id);
++      __set_current_state(TASK_RUNNING);
 +      return 0;
 +}
 +
-+/*
-+ * toi_compress_rw_init()
-+ */
-+
-+static int toi_compress_rw_init(int rw, int stream_number)
++static void kill_clusterd(void)
 +{
-+      if (toi_compress_prepare_result) {
-+              printk(KERN_ERR "Failed to initialise compression "
-+                              "algorithm.\n");
-+              if (rw == READ) {
-+                      printk(KERN_INFO "Unable to read the image.\n");
-+                      return -ENODEV;
-+              } else {
-+                      printk(KERN_INFO "Continuing without "
-+                              "compressing the image.\n");
-+                      toi_compression_ops.enabled = 0;
++      int i;
++
++      for (i = 0; i < num_local_nodes; i++) {
++              if (node_array[i].current_message) {
++                      PRINTK("Seeking to kill clusterd %d.\n", i);
++                      node_array[i].current_message = 0;
 +              }
 +      }
++      wait_event(clusterd_events,
++                      !atomic_read(&num_cluster_threads));
++      PRINTK("All cluster daemons have exited.\n");
++}
 +
-+      return 0;
++static int peers_not_in_message(int index, int message, int precise)
++{
++      struct cluster_member *this;
++      unsigned long flags;
++      int result = 0;
++
++      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
++      list_for_each_entry(this, &node_array[index].member_list, list) {
++              if (this->ignore)
++                      continue;
++
++              PRINTK("Peer %d.%d.%d.%d sending %s. "
++                      "Seeking %s.\n",
++                      NIPQUAD(this->addr),
++                      str_message(this->message), str_message(message));
++              if ((precise ? this->message :
++                                      this->message & MSG_STATE_MASK) !=
++                                      message)
++                      result++;
++      }
++      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
++      PRINTK("%d peers in sought message.\n", result);
++      return result;
 +}
 +
-+/*
-+ * toi_compress_write_page()
-+ *
-+ * Compress a page of data, buffering output and passing on filled
-+ * pages to the next module in the pipeline.
-+ *
-+ * Buffer_page:       Pointer to a buffer of size PAGE_SIZE, containing
-+ * data to be compressed.
-+ *
-+ * Returns:   0 on success. Otherwise the error is that returned by later
-+ *            modules, -ECHILD if we have a broken pipeline or -EIO if
-+ *            zlib errs.
-+ */
-+static int toi_compress_write_page(unsigned long index,
-+              struct page *buffer_page, unsigned int buf_size)
++static void reset_ignored(int index)
 +{
-+      int ret, cpu = smp_processor_id();
-+      struct cpu_context *ctx = &per_cpu(contexts, cpu);
++      struct cluster_member *this;
++      unsigned long flags;
 +
-+      if (!ctx->transform)
-+              return next_driver->write_page(index, buffer_page, buf_size);
++      spin_lock_irqsave(&node_array[index].member_list_lock, flags);
++      list_for_each_entry(this, &node_array[index].member_list, list)
++              this->ignore = 0;
++      node_array[index].ignored_peer_count = 0;
++      spin_unlock_irqrestore(&node_array[index].member_list_lock, flags);
++}
 +
-+      ctx->buffer_start = kmap(buffer_page);
++static int peers_in_message(int index, int message, int precise)
++{
++      return node_array[index].peer_count -
++              node_array[index].ignored_peer_count -
++              peers_not_in_message(index, message, precise);
++}
 +
-+      ctx->len = buf_size;
++static int time_to_continue(int index, unsigned long start, int message)
++{
++      int first = peers_not_in_message(index, message, 0);
++      int second = peers_in_message(index, message, 1);
 +
-+      ret = crypto_comp_compress(ctx->transform,
-+                      ctx->buffer_start, buf_size,
-+                      ctx->output_buffer, &ctx->len);
++      PRINTK("First part returns %d, second returns %d.\n", first, second);
 +
-+      kunmap(buffer_page);
++      if (!first && !second) {
++              PRINTK("All peers answered message %d.\n",
++                      message);
++              return 1;
++      }
 +
-+      mutex_lock(&stats_lock);
-+      toi_compress_bytes_in += buf_size;
-+      toi_compress_bytes_out += ctx->len;
-+      mutex_unlock(&stats_lock);
++      if (time_after(jiffies, start + continue_delay)) {
++              PRINTK("Timeout reached.\n");
++              return 1;
++      }
 +
-+      if (!ret && ctx->len < buf_size) { /* some compression */
-+              memcpy(ctx->page_buffer, ctx->output_buffer, ctx->len);
-+              return next_driver->write_page(index,
-+                              virt_to_page(ctx->page_buffer),
-+                              ctx->len);
-+      } else
-+              return next_driver->write_page(index, buffer_page, buf_size);
++      PRINTK("Not time to continue yet (%lu < %lu).\n", jiffies,
++                      start + continue_delay);
++      return 0;
 +}
 +
-+/*
-+ * toi_compress_read_page()
-+ * @buffer_page: struct page *. Pointer to a buffer of size PAGE_SIZE.
-+ *
-+ * Retrieve data from later modules and decompress it until the input buffer
-+ * is filled.
-+ * Zero if successful. Error condition from me or from downstream on failure.
-+ */
-+static int toi_compress_read_page(unsigned long *index,
-+              struct page *buffer_page, unsigned int *buf_size)
++void toi_initiate_cluster_hibernate(void)
 +{
-+      int ret, cpu = smp_processor_id();
-+      unsigned int len;
-+      unsigned int outlen = PAGE_SIZE;
-+      char *buffer_start;
-+      struct cpu_context *ctx = &per_cpu(contexts, cpu);
++      int result;
++      unsigned long start;
 +
-+      if (!ctx->transform)
-+              return next_driver->read_page(index, buffer_page, buf_size);
++      result = do_toi_step(STEP_HIBERNATE_PREPARE_IMAGE);
++      if (result)
++              return;
 +
-+      /*
-+       * All our reads must be synchronous - we can't decompress
-+       * data that hasn't been read yet.
-+       */
++      toi_send_if(MSG_HIBERNATE, 0);
 +
-+      ret = next_driver->read_page(index, buffer_page, &len);
++      start = jiffies;
++      wait_event(node_array[0].member_events,
++                      time_to_continue(0, start, MSG_HIBERNATE));
 +
-+      /* Error or uncompressed data */
-+      if (ret || len == PAGE_SIZE)
-+              return ret;
++      if (test_action_state(TOI_FREEZER_TEST)) {
++              toi_send_if(MSG_ABORT, 0);
 +
-+      buffer_start = kmap(buffer_page);
-+      memcpy(ctx->page_buffer, buffer_start, len);
-+      ret = crypto_comp_decompress(
-+                      ctx->transform,
-+                      ctx->page_buffer,
-+                      len, buffer_start, &outlen);
-+      if (ret)
-+              abort_hibernate(TOI_FAILED_IO,
-+                      "Compress_read returned %d.\n", ret);
-+      else if (outlen != PAGE_SIZE) {
-+              abort_hibernate(TOI_FAILED_IO,
-+                      "Decompression yielded %d bytes instead of %ld.\n",
-+                      outlen, PAGE_SIZE);
-+              printk(KERN_ERR "Decompression yielded %d bytes instead of "
-+                              "%ld.\n", outlen, PAGE_SIZE);
-+              ret = -EIO;
-+              *buf_size = outlen;
++              start = jiffies;
++              wait_event(node_array[0].member_events,
++                      time_to_continue(0, start, MSG_RUNNING));
++
++              do_toi_step(STEP_QUIET_CLEANUP);
++              return;
 +      }
-+      kunmap(buffer_page);
-+      return ret;
++
++      toi_send_if(MSG_IO, 0);
++
++      result = do_toi_step(STEP_HIBERNATE_SAVE_IMAGE);
++      if (result)
++              return;
++
++      /* This code runs at resume time too! */
++      if (toi_in_hibernate)
++              result = do_toi_step(STEP_HIBERNATE_POWERDOWN);
 +}
++EXPORT_SYMBOL_GPL(toi_initiate_cluster_hibernate);
 +
-+/*
-+ * toi_compress_print_debug_stats
-+ * @buffer: Pointer to a buffer into which the debug info will be printed.
-+ * @size: Size of the buffer.
++/* toi_cluster_print_debug_stats
 + *
-+ * Print information to be recorded for debugging purposes into a buffer.
-+ * Returns: Number of characters written to the buffer.
++ * Description:       Print information to be recorded for debugging purposes into a
++ *            buffer.
++ * Arguments: buffer: Pointer to a buffer into which the debug info will be
++ *                    printed.
++ *            size:   Size of the buffer.
++ * Returns:   Number of characters written to the buffer.
 + */
-+
-+static int toi_compress_print_debug_stats(char *buffer, int size)
++static int toi_cluster_print_debug_stats(char *buffer, int size)
 +{
-+      unsigned long pages_in = toi_compress_bytes_in >> PAGE_SHIFT,
-+                    pages_out = toi_compress_bytes_out >> PAGE_SHIFT;
 +      int len;
 +
-+      /* Output the compression ratio achieved. */
-+      if (*toi_compressor_name)
-+              len = scnprintf(buffer, size, "- Compressor is '%s'.\n",
-+                              toi_compressor_name);
++      if (strlen(toi_cluster_iface))
++              len = scnprintf(buffer, size,
++                              "- Cluster interface is '%s'.\n",
++                              toi_cluster_iface);
 +      else
-+              len = scnprintf(buffer, size, "- Compressor is not set.\n");
-+
-+      if (pages_in)
-+              len += scnprintf(buffer+len, size - len, "  Compressed "
-+                      "%lu bytes into %lu (%ld percent compression).\n",
-+                toi_compress_bytes_in,
-+                toi_compress_bytes_out,
-+                (pages_in - pages_out) * 100 / pages_in);
++              len = scnprintf(buffer, size,
++                              "- Cluster support is disabled.\n");
 +      return len;
 +}
 +
-+/*
-+ * toi_compress_compression_memory_needed
-+ *
-+ * Tell the caller how much memory we need to operate during hibernate/resume.
-+ * Returns: Unsigned long. Maximum number of bytes of memory required for
-+ * operation.
++/* cluster_memory_needed
++ *
++ * Description:       Tell the caller how much memory we need to operate during
++ *            hibernate/resume.
++ * Returns:   Unsigned long. Maximum number of bytes of memory required for
++ *            operation.
 + */
-+static int toi_compress_memory_needed(void)
++static int toi_cluster_memory_needed(void)
 +{
-+      return 2 * PAGE_SIZE;
++      return 0;
 +}
 +
-+static int toi_compress_storage_needed(void)
++static int toi_cluster_storage_needed(void)
 +{
-+      return 4 * sizeof(unsigned long) + strlen(toi_compressor_name) + 1;
++      return 1 + strlen(toi_cluster_iface);
 +}
 +
-+/*
-+ * toi_compress_save_config_info
-+ * @buffer: Pointer to a buffer of size PAGE_SIZE.
++/* toi_cluster_save_config_info
 + *
-+ * Save informaton needed when reloading the image at resume time.
-+ * Returns: Number of bytes used for saving our data.
++ * Description:       Save informaton needed when reloading the image at resume time.
++ * Arguments: Buffer:         Pointer to a buffer of size PAGE_SIZE.
++ * Returns:   Number of bytes used for saving our data.
 + */
-+static int toi_compress_save_config_info(char *buffer)
++static int toi_cluster_save_config_info(char *buffer)
 +{
-+      int namelen = strlen(toi_compressor_name) + 1;
-+      int total_len;
-+
-+      *((unsigned long *) buffer) = toi_compress_bytes_in;
-+      *((unsigned long *) (buffer + 1 * sizeof(unsigned long))) =
-+              toi_compress_bytes_out;
-+      *((unsigned long *) (buffer + 2 * sizeof(unsigned long))) =
-+              toi_expected_compression;
-+      *((unsigned long *) (buffer + 3 * sizeof(unsigned long))) = namelen;
-+      strncpy(buffer + 4 * sizeof(unsigned long), toi_compressor_name,
-+                                                              namelen);
-+      total_len = 4 * sizeof(unsigned long) + namelen;
-+      return total_len;
++      strcpy(buffer, toi_cluster_iface);
++      return strlen(toi_cluster_iface + 1);
 +}
 +
-+/* toi_compress_load_config_info
-+ * @buffer: Pointer to the start of the data.
-+ * @size: Number of bytes that were saved.
++/* toi_cluster_load_config_info
 + *
-+ * Description:       Reload information needed for decompressing the image at
-+ * resume time.
++ * Description:       Reload information needed for declustering the image at
++ *            resume time.
++ * Arguments: Buffer:         Pointer to the start of the data.
++ *            Size:           Number of bytes that were saved.
 + */
-+static void toi_compress_load_config_info(char *buffer, int size)
++static void toi_cluster_load_config_info(char *buffer, int size)
 +{
-+      int namelen;
-+
-+      toi_compress_bytes_in = *((unsigned long *) buffer);
-+      toi_compress_bytes_out = *((unsigned long *) (buffer + 1 *
-+                              sizeof(unsigned long)));
-+      toi_expected_compression = *((unsigned long *) (buffer + 2 *
-+                              sizeof(unsigned long)));
-+      namelen = *((unsigned long *) (buffer + 3 * sizeof(unsigned long)));
-+      if (strncmp(toi_compressor_name, buffer + 4 * sizeof(unsigned long),
-+                              namelen)) {
-+              toi_compress_cleanup(1);
-+              strncpy(toi_compressor_name, buffer + 4 * sizeof(unsigned long),
-+                      namelen);
-+              toi_compress_crypto_prepare();
-+      }
++      strncpy(toi_cluster_iface, buffer, size);
 +      return;
 +}
 +
-+/*
-+ * toi_expected_compression_ratio
-+ *
-+ * Description:       Returns the expected ratio between data passed into this module
-+ *            and the amount of data output when writing.
-+ * Returns:   100 if the module is disabled. Otherwise the value set by the
-+ *            user via our sysfs entry.
-+ */
-+
-+static int toi_compress_expected_ratio(void)
++static void cluster_startup(void)
 +{
-+      if (!toi_compression_ops.enabled)
-+              return 100;
-+      else
-+              return 100 - toi_expected_compression;
-+}
++      int have_image = do_check_can_resume(), i;
++      unsigned long start = jiffies, initial_message;
++      struct task_struct *p;
 +
-+/*
-+ * data for our sysfs entries.
-+ */
-+static struct toi_sysfs_data sysfs_params[] = {
-+      SYSFS_INT("expected_compression", SYSFS_RW, &toi_expected_compression,
-+                      0, 99, 0, NULL),
-+      SYSFS_INT("enabled", SYSFS_RW, &toi_compression_ops.enabled, 0, 1, 0,
-+                      NULL),
-+      SYSFS_STRING("algorithm", SYSFS_RW, toi_compressor_name, 31, 0, NULL),
-+};
++      initial_message = MSG_IMAGE;
 +
-+/*
-+ * Ops structure.
-+ */
-+static struct toi_module_ops toi_compression_ops = {
-+      .type                   = FILTER_MODULE,
-+      .name                   = "compression",
-+      .directory              = "compression",
-+      .module                 = THIS_MODULE,
-+      .initialise             = toi_compress_init,
-+      .cleanup                = toi_compress_cleanup,
-+      .memory_needed          = toi_compress_memory_needed,
-+      .print_debug_info       = toi_compress_print_debug_stats,
-+      .save_config_info       = toi_compress_save_config_info,
-+      .load_config_info       = toi_compress_load_config_info,
-+      .storage_needed         = toi_compress_storage_needed,
-+      .expected_compression   = toi_compress_expected_ratio,
++      have_image = 1;
 +
-+      .rw_init                = toi_compress_rw_init,
++      for (i = 0; i < num_local_nodes; i++) {
++              PRINTK("Starting ktoiclusterd %d.\n", i);
++              p = kthread_create(kTOICluster, (void *) initial_message,
++                              "ktoiclusterd/%d", i);
++              if (IS_ERR(p)) {
++                      printk(KERN_ERR "Failed to start ktoiclusterd.\n");
++                      return;
++              }
 +
-+      .write_page             = toi_compress_write_page,
-+      .read_page              = toi_compress_read_page,
++              wake_up_process(p);
++      }
 +
-+      .sysfs_data             = sysfs_params,
-+      .num_sysfs_entries      = sizeof(sysfs_params) /
-+              sizeof(struct toi_sysfs_data),
-+};
++      /* Wait for delay or someone else sending first message */
++      wait_event(node_array[0].member_events, time_to_continue(0, start,
++                              MSG_IMAGE));
 +
-+/* ---- Registration ---- */
++      others_have_image = peers_in_message(0, MSG_IMAGE | MSG_ACK, 1);
 +
-+static __init int toi_compress_load(void)
-+{
-+      return toi_register_module(&toi_compression_ops);
-+}
++      printk(KERN_INFO "Continuing. I %shave an image. Peers with image:"
++              " %d.\n", have_image ? "" : "don't ", others_have_image);
 +
-+#ifdef MODULE
-+static __exit void toi_compress_unload(void)
-+{
-+      toi_unregister_module(&toi_compression_ops);
-+}
++      if (have_image) {
++              int result;
 +
-+module_init(toi_compress_load);
-+module_exit(toi_compress_unload);
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Nigel Cunningham");
-+MODULE_DESCRIPTION("Compression Support for TuxOnIce");
-+#else
-+late_initcall(toi_compress_load);
-+#endif
-diff --git a/kernel/power/tuxonice_extent.c b/kernel/power/tuxonice_extent.c
-new file mode 100644
-index 0000000..6a5a2a9
---- /dev/null
-+++ b/kernel/power/tuxonice_extent.c
-@@ -0,0 +1,314 @@
-+/*
-+ * kernel/power/tuxonice_extent.c
-+ *
-+ * Copyright (C) 2003-2008 Nigel Cunningham (nigel at tuxonice net)
-+ *
-+ * Distributed under GPLv2.
-+ *
-+ * These functions encapsulate the manipulation of storage metadata.
-+ */
++              /* Start to resume */
++              printk(KERN_INFO "  === Starting to resume ===  \n");
++              node_array[0].current_message = MSG_IO;
++              toi_send_if(MSG_IO, 0);
 +
-+#include <linux/suspend.h>
-+#include "tuxonice_modules.h"
-+#include "tuxonice_extent.h"
-+#include "tuxonice_alloc.h"
-+#include "tuxonice_ui.h"
-+#include "tuxonice.h"
++              /* result = do_toi_step(STEP_RESUME_LOAD_PS1); */
++              result = 0;
 +
-+/**
-+ * toi_get_extent - return a free extent
-+ *
-+ * May fail, returning NULL instead.
-+ **/
-+static struct hibernate_extent *toi_get_extent(void)
-+{
-+      return (struct hibernate_extent *) toi_kzalloc(2,
-+                      sizeof(struct hibernate_extent), TOI_ATOMIC_GFP);
-+}
++              if (!result) {
++                      /*
++                       * Atomic restore - we'll come back in the hibernation
++                       * path.
++                       */
 +
-+/**
-+ * toi_put_extent_chain - free a whole chain of extents
-+ * @chain:    Chain to free.
-+ **/
-+void toi_put_extent_chain(struct hibernate_extent_chain *chain)
-+{
-+      struct hibernate_extent *this;
++                      /* result = do_toi_step(STEP_RESUME_DO_RESTORE); */
++                      result = 0;
 +
-+      this = chain->first;
++                      /* do_toi_step(STEP_QUIET_CLEANUP); */
++              }
 +
-+      while (this) {
-+              struct hibernate_extent *next = this->next;
-+              toi_kfree(2, this, sizeof(*this));
-+              chain->num_extents--;
-+              this = next;
++              node_array[0].current_message |= MSG_NACK;
++
++              /* For debugging - disable for real life? */
++              wait_event(node_array[0].member_events,
++                              time_to_continue(0, start, MSG_IO));
 +      }
 +
-+      chain->first = NULL;
-+      chain->last_touched = NULL;
-+      chain->size = 0;
-+}
-+EXPORT_SYMBOL_GPL(toi_put_extent_chain);
++      if (others_have_image) {
++              /* Wait for them to resume */
++              printk(KERN_INFO "Waiting for other nodes to resume.\n");
++              start = jiffies;
++              wait_event(node_array[0].member_events,
++                              time_to_continue(0, start, MSG_RUNNING));
++              if (peers_not_in_message(0, MSG_RUNNING, 0))
++                      printk(KERN_INFO "Timed out while waiting for other "
++                                      "nodes to resume.\n");
++      }
 +
-+/**
-+ * toi_add_to_extent_chain - add an extent to an existing chain
-+ * @chain:    Chain to which the extend should be added
-+ * @start:    Start of the extent (first physical block)
-+ * @end:      End of the extent (last physical block)
-+ *
-+ * The chain information is updated if the insertion is successful.
-+ **/
-+int toi_add_to_extent_chain(struct hibernate_extent_chain *chain,
-+              unsigned long start, unsigned long end)
-+{
-+      struct hibernate_extent *new_ext = NULL, *cur_ext = NULL;
++      /* Find out whether an image exists here. Send ACK_IMAGE or NACK_IMAGE
++       * as appropriate.
++       *
++       * If we don't have an image:
++       * - Wait until someone else says they have one, or conditions are met
++       *   for continuing to boot (n machines or t seconds).
++       * - If anyone has an image, wait for them to resume before continuing
++       *   to boot.
++       *
++       * If we have an image:
++       * - Wait until conditions are met before continuing to resume (n
++       *   machines or t seconds). Send RESUME_PREP and freeze processes.
++       *   NACK_PREP if freezing fails (shouldn't) and follow logic for
++       *   us having no image above. On success, wait for [N]ACK_PREP from
++       *   other machines. Read image (including atomic restore) until done.
++       *   Wait for ACK_READ from others (should never fail). Thaw processes
++       *   and do post-resume. (The section after the atomic restore is done
++       *   via the code for hibernating).
++       */
 +
-+      /* Find the right place in the chain */
-+      if (chain->last_touched && chain->last_touched->start < start)
-+              cur_ext = chain->last_touched;
-+      else if (chain->first && chain->first->start < start)
-+              cur_ext = chain->first;
++      node_array[0].current_message = MSG_RUNNING;
++}
 +
-+      if (cur_ext) {
-+              while (cur_ext->next && cur_ext->next->start < start)
-+                      cur_ext = cur_ext->next;
++/* toi_cluster_open_iface
++ *
++ * Description:       Prepare to use an interface.
++ */
 +
-+              if (cur_ext->end == (start - 1)) {
-+                      struct hibernate_extent *next_ext = cur_ext->next;
-+                      cur_ext->end = end;
++static int toi_cluster_open_iface(void)
++{
++      struct net_device *dev;
 +
-+                      /* Merge with the following one? */
-+                      if (next_ext && cur_ext->end + 1 == next_ext->start) {
-+                              cur_ext->end = next_ext->end;
-+                              cur_ext->next = next_ext->next;
-+                              toi_kfree(2, next_ext, sizeof(*next_ext));
-+                              chain->num_extents--;
-+                      }
++      rtnl_lock();
 +
-+                      chain->last_touched = cur_ext;
-+                      chain->size += (end - start + 1);
++      for_each_netdev(&init_net, dev) {
++              if (/* dev == &init_net.loopback_dev || */
++                  strcmp(dev->name, toi_cluster_iface))
++                      continue;
 +
-+                      return 0;
-+              }
++              net_dev = dev;
++              break;
 +      }
 +
-+      new_ext = toi_get_extent();
-+      if (!new_ext) {
-+              printk(KERN_INFO "Error unable to append a new extent to the "
-+                              "chain.\n");
-+              return -ENOMEM;
++      rtnl_unlock();
++
++      if (!net_dev) {
++              printk(KERN_ERR MYNAME ": Device %s not found.\n",
++                              toi_cluster_iface);
++              return -ENODEV;
 +      }
 +
-+      chain->num_extents++;
-+      chain->size += (end - start + 1);
-+      new_ext->start = start;
-+      new_ext->end = end;
++      dev_add_pack(&toi_cluster_packet_type);
++      added_pack = 1;
 +
-+      chain->last_touched = new_ext;
++      loopback_mode = (net_dev == init_net.loopback_dev);
++      num_local_nodes = loopback_mode ? 8 : 1;
 +
-+      if (cur_ext) {
-+              new_ext->next = cur_ext->next;
-+              cur_ext->next = new_ext;
-+      } else {
-+              if (chain->first)
-+                      new_ext->next = chain->first;
-+              chain->first = new_ext;
-+      }
++      PRINTK("Loopback mode is %s. Number of local nodes is %d.\n",
++                      loopback_mode ? "on" : "off", num_local_nodes);
 +
++      cluster_startup();
 +      return 0;
 +}
-+EXPORT_SYMBOL_GPL(toi_add_to_extent_chain);
-+
-+/**
-+ * toi_serialise_extent_chain - write a chain in the image
-+ * @owner:    Module writing the chain.
-+ * @chain:    Chain to write.
-+ **/
-+int toi_serialise_extent_chain(struct toi_module_ops *owner,
-+              struct hibernate_extent_chain *chain)
-+{
-+      struct hibernate_extent *this;
-+      int ret, i = 0;
-+
-+      ret = toiActiveAllocator->rw_header_chunk(WRITE, owner, (char *) chain,
-+                      sizeof(chain->size) + sizeof(chain->num_extents));
-+      if (ret)
-+              return ret;
 +
-+      this = chain->first;
-+      while (this) {
-+              ret = toiActiveAllocator->rw_header_chunk(WRITE, owner,
-+                              (char *) this, 2 * sizeof(this->start));
-+              if (ret)
-+                      return ret;
-+              this = this->next;
-+              i++;
-+      }
++/* toi_cluster_close_iface
++ *
++ * Description: Stop using an interface.
++ */
 +
-+      if (i != chain->num_extents) {
-+              printk(KERN_EMERG "Saved %d extents but chain metadata says "
-+                      "there should be %d.\n", i, chain->num_extents);
-+              return 1;
++static int toi_cluster_close_iface(void)
++{
++      kill_clusterd();
++      if (added_pack) {
++              dev_remove_pack(&toi_cluster_packet_type);
++              added_pack = 0;
 +      }
-+
-+      return ret;
++      return 0;
 +}
-+EXPORT_SYMBOL_GPL(toi_serialise_extent_chain);
 +
-+/**
-+ * toi_load_extent_chain - read back a chain saved in the image
-+ * @chain:    Chain to load
-+ *
-+ * The linked list of extents is reconstructed from the disk. chain will point
-+ * to the first entry.
-+ **/
-+int toi_load_extent_chain(struct hibernate_extent_chain *chain)
++static void write_side_effect(void)
 +{
-+      struct hibernate_extent *this, *last = NULL;
-+      int i, ret;
-+
-+      /* Get the next page */
-+      ret = toiActiveAllocator->rw_header_chunk_noreadahead(READ, NULL,
-+                      (char *) chain, sizeof(chain->size) +
-+                      sizeof(chain->num_extents));
-+      if (ret) {
-+              printk(KERN_ERR "Failed to read the size of extent chain.\n");
-+              return 1;
-+      }
-+
-+      for (i = 0; i < chain->num_extents; i++) {
-+              this = toi_kzalloc(3, sizeof(struct hibernate_extent),
-+                              TOI_ATOMIC_GFP);
-+              if (!this) {
-+                      printk(KERN_INFO "Failed to allocate a new extent.\n");
-+                      return -ENOMEM;
-+              }
-+              this->next = NULL;
-+              /* Get the next page */
-+              ret = toiActiveAllocator->rw_header_chunk_noreadahead(READ,
-+                              NULL, (char *) this, 2 * sizeof(this->start));
-+              if (ret) {
-+                      printk(KERN_INFO "Failed to read an extent.\n");
-+                      return 1;
-+              }
-+              if (last)
-+                      last->next = this;
-+              else
-+                      chain->first = this;
-+              last = this;
++      if (toi_cluster_ops.enabled) {
++              toi_cluster_open_iface();
++              set_toi_state(TOI_CLUSTER_MODE);
++      } else {
++              toi_cluster_close_iface();
++              clear_toi_state(TOI_CLUSTER_MODE);
 +      }
-+      return 0;
 +}
-+EXPORT_SYMBOL_GPL(toi_load_extent_chain);
 +
-+/**
-+ * toi_extent_state_next - go to the next extent
-+ *
-+ * Given a state, progress to the next valid entry. We may begin in an
-+ * invalid state, as we do when invoked after extent_state_goto_start below.
-+ *
-+ * When using compression and expected_compression > 0, we let the image size
-+ * be larger than storage, so we can validly run out of data to return.
-+ **/
-+unsigned long toi_extent_state_next(struct toi_extent_iterate_state *state)
++static void node_write_side_effect(void)
 +{
-+      if (state->current_chain == state->num_chains)
-+              return 0;
-+
-+      if (state->current_extent) {
-+              if (state->current_offset == state->current_extent->end) {
-+                      if (state->current_extent->next) {
-+                              state->current_extent =
-+                                      state->current_extent->next;
-+                              state->current_offset =
-+                                      state->current_extent->start;
-+                      } else {
-+                              state->current_extent = NULL;
-+                              state->current_offset = 0;
-+                      }
-+              } else
-+                      state->current_offset++;
-+      }
++}
 +
-+      while (!state->current_extent) {
-+              int chain_num = ++(state->current_chain);
++/*
++ * data for our sysfs entries.
++ */
++static struct toi_sysfs_data sysfs_params[] = {
++      SYSFS_STRING("interface", SYSFS_RW, toi_cluster_iface, IFNAMSIZ, 0,
++                      NULL),
++      SYSFS_INT("enabled", SYSFS_RW, &toi_cluster_ops.enabled, 0, 1, 0,
++                      write_side_effect),
++      SYSFS_STRING("cluster_name", SYSFS_RW, toi_cluster_key, 32, 0, NULL),
++      SYSFS_STRING("pre-hibernate-script", SYSFS_RW, pre_hibernate_script,
++                      256, 0, NULL),
++      SYSFS_STRING("post-hibernate-script", SYSFS_RW, post_hibernate_script,
++                      256, 0, STRING),
++      SYSFS_UL("continue_delay", SYSFS_RW, &continue_delay, HZ / 2, 60 * HZ,
++                      0)
++};
 +
-+              if (chain_num == state->num_chains)
-+                      return 0;
++/*
++ * Ops structure.
++ */
 +
-+              state->current_extent = (state->chains + chain_num)->first;
++static struct toi_module_ops toi_cluster_ops = {
++      .type                   = FILTER_MODULE,
++      .name                   = "Cluster",
++      .directory              = "cluster",
++      .module                 = THIS_MODULE,
++      .memory_needed          = toi_cluster_memory_needed,
++      .print_debug_info       = toi_cluster_print_debug_stats,
++      .save_config_info       = toi_cluster_save_config_info,
++      .load_config_info       = toi_cluster_load_config_info,
++      .storage_needed         = toi_cluster_storage_needed,
 +
-+              if (!state->current_extent)
-+                      continue;
++      .sysfs_data             = sysfs_params,
++      .num_sysfs_entries      = sizeof(sysfs_params) /
++              sizeof(struct toi_sysfs_data),
++};
 +
-+              state->current_offset = state->current_extent->start;
-+      }
++/* ---- Registration ---- */
 +
-+      return state->current_offset;
-+}
-+EXPORT_SYMBOL_GPL(toi_extent_state_next);
++#ifdef MODULE
++#define INIT static __init
++#define EXIT static __exit
++#else
++#define INIT
++#define EXIT
++#endif
 +
-+/**
-+ * toi_extent_state_goto_start - reinitialize an extent chain iterator
-+ * @state:    Iterator to reinitialize
-+ **/
-+void toi_extent_state_goto_start(struct toi_extent_iterate_state *state)
++INIT int toi_cluster_init(void)
 +{
-+      state->current_chain = -1;
-+      state->current_extent = NULL;
-+      state->current_offset = 0;
-+}
-+EXPORT_SYMBOL_GPL(toi_extent_state_goto_start);
++      int temp = toi_register_module(&toi_cluster_ops), i;
++      struct kobject *kobj = toi_cluster_ops.dir_kobj;
 +
-+/**
-+ * toi_extent_state_save - save state of the iterator
-+ * @state:            Current state of the chain
-+ * @saved_state:      Iterator to populate
-+ *
-+ * Given a state and a struct hibernate_extent_state_store, save the current
-+ * position in a format that can be used with relocated chains (at
-+ * resume time).
-+ **/
-+void toi_extent_state_save(struct toi_extent_iterate_state *state,
-+              struct hibernate_extent_iterate_saved_state *saved_state)
-+{
-+      struct hibernate_extent *extent;
++      for (i = 0; i < MAX_LOCAL_NODES; i++) {
++              node_array[i].current_message = 0;
++              INIT_LIST_HEAD(&node_array[i].member_list);
++              init_waitqueue_head(&node_array[i].member_events);
++              spin_lock_init(&node_array[i].member_list_lock);
++              spin_lock_init(&node_array[i].receive_lock);
 +
-+      saved_state->chain_num = state->current_chain;
-+      saved_state->extent_num = 0;
-+      saved_state->offset = state->current_offset;
++              /* Set up sysfs entry */
++              node_array[i].sysfs_data.attr.name = toi_kzalloc(8,
++                              sizeof(node_array[i].sysfs_data.attr.name),
++                              GFP_KERNEL);
++              sprintf((char *) node_array[i].sysfs_data.attr.name, "node_%d",
++                              i);
++              node_array[i].sysfs_data.attr.mode = SYSFS_RW;
++              node_array[i].sysfs_data.type = TOI_SYSFS_DATA_INTEGER;
++              node_array[i].sysfs_data.flags = 0;
++              node_array[i].sysfs_data.data.integer.variable =
++                      (int *) &node_array[i].current_message;
++              node_array[i].sysfs_data.data.integer.minimum = 0;
++              node_array[i].sysfs_data.data.integer.maximum = INT_MAX;
++              node_array[i].sysfs_data.write_side_effect =
++                      node_write_side_effect;
++              toi_register_sysfs_file(kobj, &node_array[i].sysfs_data);
++      }
 +
-+      if (saved_state->chain_num == -1)
-+              return;
++      toi_cluster_ops.enabled = (strlen(toi_cluster_iface) > 0);
 +
-+      extent = (state->chains + state->current_chain)->first;
++      if (toi_cluster_ops.enabled)
++              toi_cluster_open_iface();
 +
-+      while (extent != state->current_extent) {
-+              saved_state->extent_num++;
-+              extent = extent->next;
-+      }
++      return temp;
 +}
-+EXPORT_SYMBOL_GPL(toi_extent_state_save);
 +
-+/**
-+ * toi_extent_state_restore - restore the position saved by extent_state_save
-+ * @state:            State to populate
-+ * @saved_state:      Iterator saved to restore
-+ **/
-+void toi_extent_state_restore(struct toi_extent_iterate_state *state,
-+              struct hibernate_extent_iterate_saved_state *saved_state)
++EXIT void toi_cluster_exit(void)
 +{
-+      int posn = saved_state->extent_num;
++      int i;
++      toi_cluster_close_iface();
 +
-+      if (saved_state->chain_num == -1) {
-+              toi_extent_state_goto_start(state);
-+              return;
-+      }
++      for (i = 0; i < MAX_LOCAL_NODES; i++)
++              toi_unregister_sysfs_file(toi_cluster_ops.dir_kobj,
++                              &node_array[i].sysfs_data);
++      toi_unregister_module(&toi_cluster_ops);
++}
 +
-+      state->current_chain = saved_state->chain_num;
-+      state->current_extent = (state->chains + state->current_chain)->first;
-+      state->current_offset = saved_state->offset;
++static int __init toi_cluster_iface_setup(char *iface)
++{
++      toi_cluster_ops.enabled = (*iface &&
++                      strcmp(iface, "off"));
 +
-+      while (posn--)
-+              state->current_extent = state->current_extent->next;
++      if (toi_cluster_ops.enabled)
++              strncpy(toi_cluster_iface, iface, strlen(iface));
 +}
-+EXPORT_SYMBOL_GPL(toi_extent_state_restore);
-diff --git a/kernel/power/tuxonice_extent.h b/kernel/power/tuxonice_extent.h
++
++__setup("toi_cluster=", toi_cluster_iface_setup);
++
++#ifdef MODULE
++MODULE_LICENSE("GPL");
++module_init(toi_cluster_init);
++module_exit(toi_cluster_exit);
++MODULE_AUTHOR("Nigel Cunningham");
++MODULE_DESCRIPTION("Cluster Support for TuxOnIce");
++#endif
+diff --git a/kernel/power/tuxonice_cluster.h b/kernel/power/tuxonice_cluster.h
 new file mode 100644
-index 0000000..f3530a3
+index 0000000..b0f8918
 --- /dev/null
-+++ b/kernel/power/tuxonice_extent.h
-@@ -0,0 +1,72 @@
++++ b/kernel/power/tuxonice_cluster.h
+@@ -0,0 +1,19 @@
 +/*
-+ * kernel/power/tuxonice_extent.h
++ * kernel/power/tuxonice_cluster.h
 + *
-+ * Copyright (C) 2003-2008 Nigel Cunningham (nigel at tuxonice net)
++ * Copyright (C) 2006-2008 Nigel Cunningham (nigel at tuxonice net)
++ * Copyright (C) 2006 Red Hat, inc.
 + *
 + * This file is released under the GPLv2.
-+ *
-+ * It contains declarations related to extents. Extents are
-+ * TuxOnIce's method of storing some of the metadata for the image.
-+ * See tuxonice_extent.c for more info.
-+ *
 + */
 +
-+#include "tuxonice_modules.h"
-+
-+#ifndef EXTENT_H
-+#define EXTENT_H
-+
-+struct hibernate_extent {
-+      unsigned long start, end;
-+      struct hibernate_extent *next;
-+};
-+
-+struct hibernate_extent_chain {
-+      unsigned long size; /* size of the chain ie sum (max-min+1) */
-+      int num_extents;
-+      struct hibernate_extent *first, *last_touched;
-+};
-+
-+struct toi_extent_iterate_state {
-+      struct hibernate_extent_chain *chains;
-+      int num_chains;
-+      int current_chain;
-+      struct hibernate_extent *current_extent;
-+      unsigned long current_offset;
-+};
-+
-+struct hibernate_extent_iterate_saved_state {
-+      int chain_num;
-+      int extent_num;
-+      unsigned long offset;
-+};
-+
-+#define toi_extent_state_eof(state) \
-+      ((state)->num_chains == (state)->current_chain)
-+
-+/* Simplify iterating through all the values in an extent chain */
-+#define toi_extent_for_each(extent_chain, extentpointer, value) \
-+if ((extent_chain)->first) \
-+      for ((extentpointer) = (extent_chain)->first, (value) = \
-+                      (extentpointer)->start; \
-+           ((extentpointer) && ((extentpointer)->next || (value) <= \
-+                               (extentpointer)->end)); \
-+           (((value) == (extentpointer)->end) ? \
-+              ((extentpointer) = (extentpointer)->next, (value) = \
-+               ((extentpointer) ? (extentpointer)->start : 0)) : \
-+                      (value)++))
-+
-+void toi_put_extent_chain(struct hibernate_extent_chain *chain);
-+int toi_add_to_extent_chain(struct hibernate_extent_chain *chain,
-+              unsigned long start, unsigned long end);
-+int toi_serialise_extent_chain(struct toi_module_ops *owner,
-+              struct hibernate_extent_chain *chain);
-+int toi_load_extent_chain(struct hibernate_extent_chain *chain);
-+
-+void toi_extent_state_save(struct toi_extent_iterate_state *state,
-+              struct hibernate_extent_iterate_saved_state *saved_state);
-+void toi_extent_state_restore(struct toi_extent_iterate_state *state,
-+              struct hibernate_extent_iterate_saved_state *saved_state);
-+void toi_extent_state_goto_start(struct toi_extent_iterate_state *state);
-+unsigned long toi_extent_state_next(struct toi_extent_iterate_state *state);
++#ifdef CONFIG_TOI_CLUSTER
++extern int toi_cluster_init(void);
++extern void toi_cluster_exit(void);
++extern void toi_initiate_cluster_hibernate(void);
++#else
++static inline int toi_cluster_init(void) { return 0; }
++static inline void toi_cluster_exit(void) { }
++static inline void toi_initiate_cluster_hibernate(void) { }
 +#endif
-diff --git a/kernel/power/tuxonice_file.c b/kernel/power/tuxonice_file.c
++
+diff --git a/kernel/power/tuxonice_compress.c b/kernel/power/tuxonice_compress.c
 new file mode 100644
-index 0000000..fe903bd
+index 0000000..1c7aaf3
 --- /dev/null
-+++ b/kernel/power/tuxonice_file.c
-@@ -0,0 +1,1254 @@
++++ b/kernel/power/tuxonice_compress.c
+@@ -0,0 +1,445 @@
 +/*
-+ * kernel/power/tuxonice_file.c
-+ *
-+ * Copyright (C) 2005-2008 Nigel Cunningham (nigel at tuxonice net)
-+ *
-+ * Distributed under GPLv2.
-+ *
-+ * This file encapsulates functions for usage of a simple file as a
-+ * backing store. It is based upon the swapallocator, and shares the
-+ * same basic working. Here, though, we have nothing to do with
-+ * swapspace, and only one device to worry about.
-+ *
-+ * The user can just
-+ *
-+ * echo TuxOnIce > /path/to/my_file
-+ *
-+ * dd if=/dev/zero bs=1M count=<file_size_desired> >> /path/to/my_file
-+ *
-+ * and
-+ *
-+ * echo /path/to/my_file > /sys/power/tuxonice/file/target
++ * kernel/power/compression.c
 + *
-+ * then put what they find in /sys/power/tuxonice/resume
-+ * as their resume= parameter in lilo.conf (and rerun lilo if using it).
++ * Copyright (C) 2003-2008 Nigel Cunningham (nigel at tuxonice net)
 + *
-+ * Having done this, they're ready to hibernate and resume.
++ * This file is released under the GPLv2.
 + *
-+ * TODO:
-+ * - File resizing.
++ * This file contains data compression routines for TuxOnIce,
++ * using cryptoapi.
 + */
 +
 +#include <linux/suspend.h>
-+#include <linux/blkdev.h>
-+#include <linux/file.h>
-+#include <linux/stat.h>
-+#include <linux/mount.h>
-+#include <linux/statfs.h>
-+#include <linux/syscalls.h>
-+#include <linux/namei.h>
-+#include <linux/fs.h>
-+#include <linux/root_dev.h>
-+#include <scsi/scsi_scan.h>
++#include <linux/highmem.h>
++#include <linux/vmalloc.h>
++#include <linux/crypto.h>
 +
++#include "tuxonice_builtin.h"
 +#include "tuxonice.h"
-+#include "tuxonice_sysfs.h"
 +#include "tuxonice_modules.h"
-+#include "tuxonice_ui.h"
-+#include "tuxonice_extent.h"
++#include "tuxonice_sysfs.h"
 +#include "tuxonice_io.h"
-+#include "tuxonice_storage.h"
-+#include "tuxonice_block_io.h"
++#include "tuxonice_ui.h"
 +#include "tuxonice_alloc.h"
-+#include "tuxonice_builtin.h"
-+
-+static struct toi_module_ops toi_fileops;
-+
-+/* Details of our target.  */
-+
-+static char toi_file_target[256];
-+static struct inode *target_inode;
-+static struct file *target_file;
-+static struct block_device *toi_file_target_bdev;
-+static dev_t resume_file_dev_t;
-+static int used_devt;
-+static int setting_toi_file_target;
-+static sector_t target_firstblock, target_header_start;
-+static int target_storage_available;
-+static int target_claim;
-+
-+/* Old signatures */
-+static char HaveImage[] = "HaveImage\n";
-+static char NoImage[] =   "TuxOnIce\n";
-+#define sig_size (sizeof(HaveImage) + 1)
-+
-+struct toi_file_header {
-+      char sig[sig_size];
-+      int resumed_before;
-+      unsigned long first_header_block;
-+      int have_image;
-+};
-+
-+/* Header Page Information */
-+static unsigned long header_pages_reserved;
-+
-+/* Main Storage Pages */
-+static unsigned long main_pages_allocated, main_pages_requested;
-+
-+#define target_is_normal_file() (S_ISREG(target_inode->i_mode))
-+
-+static struct toi_bdev_info devinfo;
-+
-+/* Extent chain for blocks */
-+static struct hibernate_extent_chain block_chain;
-+
-+/* Signature operations */
-+enum {
-+      GET_IMAGE_EXISTS,
-+      INVALIDATE,
-+      MARK_RESUME_ATTEMPTED,
-+      UNMARK_RESUME_ATTEMPTED,
-+};
-+
-+/**
-+ * set_devinfo - populate device information
-+ * @bdev:             Block device on which the file is.
-+ * @target_blkbits:   Number of bits in the page block size of the target
-+ *                    file inode.
-+ *
-+ * Populate the devinfo structure about the target device.
-+ *
-+ * Background: a sector represents a fixed amount of data (generally 512 bytes).
-+ * The hard drive sector size and the filesystem block size may be different.
-+ * If fs_blksize mesures the filesystem block size and hd_blksize the hard drive
-+ * sector size:
-+ *
-+ * sector << (fs_blksize - hd_blksize) converts hd sector into fs block
-+ * fs_block >> (fs_blksize - hd_blksize) converts fs block into hd sector number
-+ *
-+ * Here target_blkbits == fs_blksize and hd_blksize == 9, hence:
-+ *
-+ *    (fs_blksize - hd_blksize) == devinfo.bmap_shift
-+ *
-+ * The memory page size is defined by PAGE_SHIFT. devinfo.blocks_per_page is the
-+ * number of filesystem blocks per memory page.
-+ *
-+ * Note that blocks are stored after >>. They are used after being <<.
-+ * We always only use PAGE_SIZE aligned blocks.
-+ *
-+ * Side effects:
-+ *    devinfo.bdev, devinfo.bmap_shift and devinfo.blocks_per_page are set.
-+ */
-+static void set_devinfo(struct block_device *bdev, int target_blkbits)
-+{
-+      devinfo.bdev = bdev;
-+      if (!target_blkbits) {
-+              devinfo.bmap_shift = 0;
-+              devinfo.blocks_per_page = 0;
-+      } else {
-+              /* We are assuming a hard disk with 512 (2^9) bytes/sector */
-+              devinfo.bmap_shift = target_blkbits - 9;
-+              devinfo.blocks_per_page = (1 << (PAGE_SHIFT - target_blkbits));
-+      }
-+}
-+
-+static unsigned long raw_to_real(unsigned long raw)
-+{
-+      unsigned long result;
-+
-+      result = raw - (raw * (sizeof(unsigned long) + sizeof(int)) +
-+              (PAGE_SIZE + sizeof(unsigned long) + sizeof(int) + 1)) /
-+              (PAGE_SIZE + sizeof(unsigned long) + sizeof(int));
-+
-+      return result < 0 ? 0 : result;
-+}
-+
-+static unsigned long toi_file_storage_available(void)
-+{
-+      int result = 0;
-+      struct block_device *bdev = toi_file_target_bdev;
-+
-+      if (!target_inode)
-+              return 0;
-+
-+      switch (target_inode->i_mode & S_IFMT) {
-+      case S_IFSOCK:
-+      case S_IFCHR:
-+      case S_IFIFO: /* Socket, Char, Fifo */
-+              return -1;
-+      case S_IFREG: /* Regular file: current size - holes + free
-+                       space on part */
-+              result = target_storage_available;
-+              break;
-+      case S_IFBLK: /* Block device */
-+              if (!bdev->bd_disk) {
-+                      printk(KERN_INFO "bdev->bd_disk null.\n");
-+                      return 0;
-+              }
-+
-+              result = (bdev->bd_part ?
-+                      bdev->bd_part->nr_sects :
-+                      get_capacity(bdev->bd_disk)) >> (PAGE_SHIFT - 9);
-+      }
-+
-+      return raw_to_real(result);
-+}
-+
-+static int has_contiguous_blocks(int page_num)
-+{
-+      int j;
-+      sector_t last = 0;
 +
-+      for (j = 0; j < devinfo.blocks_per_page; j++) {
-+              sector_t this = bmap(target_inode,
-+                              page_num * devinfo.blocks_per_page + j);
-+
-+              if (!this || (last && (last + 1) != this))
-+                      break;
++static int toi_expected_compression;
 +
-+              last = this;
-+      }
++static struct toi_module_ops toi_compression_ops;
++static struct toi_module_ops *next_driver;
 +
-+      return j == devinfo.blocks_per_page;
-+}
++static char toi_compressor_name[32] = "lzo";
 +
-+static int size_ignoring_ignored_pages(void)
-+{
-+      int mappable = 0, i;
++static DEFINE_MUTEX(stats_lock);
 +
-+      if (!target_is_normal_file())
-+              return toi_file_storage_available();
++struct cpu_context {
++      u8 *page_buffer;
++      struct crypto_comp *transform;
++      unsigned int len;
++      char *buffer_start;
++      char *output_buffer;
++};
 +
-+      for (i = 0; i < (target_inode->i_size >> PAGE_SHIFT) ; i++)
-+              if (has_contiguous_blocks(i))
-+                      mappable++;
++static DEFINE_PER_CPU(struct cpu_context, contexts);
 +
-+      return mappable;
-+}
++static int toi_compress_prepare_result;
 +
-+/**
-+ * __populate_block_list - add an extent to the chain
-+ * @min:      Start of the extent (first physical block = sector)
-+ * @max:      End of the extent (last physical block = sector)
++/*
++ * toi_compress_cleanup
 + *
-+ * If TOI_TEST_BIO is set, print a debug message, outputting the min and max
-+ * fs block numbers.
-+ **/
-+static int __populate_block_list(int min, int max)
++ * Frees memory allocated for our labours.
++ */
++static void toi_compress_cleanup(int toi_or_resume)
 +{
-+      if (test_action_state(TOI_TEST_BIO))
-+              printk(KERN_INFO "Adding extent %d-%d.\n",
-+                      min << devinfo.bmap_shift,
-+                      ((max + 1) << devinfo.bmap_shift) - 1);
++      int cpu;
 +
-+      return toi_add_to_extent_chain(&block_chain, min, max);
-+}
++      if (!toi_or_resume)
++              return;
 +
-+static int apply_header_reservation(void)
-+{
-+      int i;
++      for_each_online_cpu(cpu) {
++              struct cpu_context *this = &per_cpu(contexts, cpu);
++              if (this->transform) {
++                      crypto_free_comp(this->transform);
++                      this->transform = NULL;
++              }
 +
-+      /* Apply header space reservation */
-+      toi_extent_state_goto_start(&toi_writer_posn);
++              if (this->page_buffer)
++                      toi_free_page(16, (unsigned long) this->page_buffer);
 +
-+      for (i = 0; i < header_pages_reserved; i++)
-+              if (toi_bio_ops.forward_one_page(1, 0))
-+                      return -ENOSPC;
++              this->page_buffer = NULL;
 +
-+      /* The end of header pages will be the start of pageset 2 */
-+      toi_extent_state_save(&toi_writer_posn, &toi_writer_posn_save[2]);
++              if (this->output_buffer)
++                      vfree(this->output_buffer);
 +
-+      return 0;
++              this->output_buffer = NULL;
++      }
 +}
 +
-+static int populate_block_list(void)
++/*
++ * toi_crypto_prepare
++ *
++ * Prepare to do some work by allocating buffers and transforms.
++ */
++static int toi_compress_crypto_prepare(void)
 +{
-+      int i, extent_min = -1, extent_max = -1, got_header = 0, result = 0;
-+
-+      if (block_chain.first)
-+              toi_put_extent_chain(&block_chain);
++      int cpu;
 +
-+      if (!target_is_normal_file()) {
-+              result = (target_storage_available > 0) ?
-+                      __populate_block_list(devinfo.blocks_per_page,
-+                              (target_storage_available + 1) *
-+                              devinfo.blocks_per_page - 1) : 0;
-+              if (result)
-+                      return result;
-+              goto out;
++      if (!*toi_compressor_name) {
++              printk(KERN_INFO "TuxOnIce: Compression enabled but no "
++                              "compressor name set.\n");
++              return 1;
 +      }
 +
-+      for (i = 0; i < (target_inode->i_size >> PAGE_SHIFT); i++) {
-+              sector_t new_sector;
-+
-+              if (!has_contiguous_blocks(i))
-+                      continue;
++      for_each_online_cpu(cpu) {
++              struct cpu_context *this = &per_cpu(contexts, cpu);
++              this->transform = crypto_alloc_comp(toi_compressor_name, 0, 0);
++              if (IS_ERR(this->transform)) {
++                      printk(KERN_INFO "TuxOnIce: Failed to initialise the "
++                                      "%s compression transform.\n",
++                                      toi_compressor_name);
++                      this->transform = NULL;
++                      return 1;
++              }
 +
-+              new_sector = bmap(target_inode, (i * devinfo.blocks_per_page));
++              this->page_buffer =
++                      (char *) toi_get_zeroed_page(16, TOI_ATOMIC_GFP);
 +
-+              /*
-+               * Ignore the first block in the file.
-+               * It gets the header.
-+               */
-+              if (new_sector == target_firstblock >> devinfo.bmap_shift) {
-+                      got_header = 1;
-+                      continue;
++              if (!this->page_buffer) {
++                      printk(KERN_ERR
++                        "Failed to allocate a page buffer for TuxOnIce "
++                        "compression driver.\n");
++                      return -ENOMEM;
 +              }
 +
-+              /*
-+               * I'd love to be able to fill in holes and resize
-+               * files, but not yet...
-+               */
-+
-+              if (new_sector == extent_max + 1)
-+                      extent_max += devinfo.blocks_per_page;
-+              else {
-+                      if (extent_min > -1) {
-+                              result = __populate_block_list(extent_min,
-+                                              extent_max);
-+                              if (result)
-+                                      return result;
-+                      }
++              this->output_buffer =
++                      (char *) vmalloc_32(2 * PAGE_SIZE);
 +
-+                      extent_min = new_sector;
-+                      extent_max = extent_min +
-+                              devinfo.blocks_per_page - 1;
++              if (!this->output_buffer) {
++                      printk(KERN_ERR
++                        "Failed to allocate a output buffer for TuxOnIce "
++                        "compression driver.\n");
++                      return -ENOMEM;
 +              }
-+      }
 +
-+      if (extent_min > -1) {
-+              result = __populate_block_list(extent_min, extent_max);
-+              if (result)
-+                      return result;
 +      }
 +
-+out:
-+      return apply_header_reservation();
++      return 0;
 +}
 +
-+static void toi_file_cleanup(int finishing_cycle)
++/*
++ * toi_compress_init
++ */
++
++static int toi_compress_init(int toi_or_resume)
 +{
-+      if (toi_file_target_bdev) {
-+              if (target_claim) {
-+                      bd_release(toi_file_target_bdev);
-+                      target_claim = 0;
-+              }
++      if (!toi_or_resume)
++              return 0;
 +
-+              if (used_devt) {
-+                      blkdev_put(toi_file_target_bdev,
-+                                      FMODE_READ | FMODE_NDELAY);
-+                      used_devt = 0;
-+              }
-+              toi_file_target_bdev = NULL;
-+              target_inode = NULL;
-+              set_devinfo(NULL, 0);
-+              target_storage_available = 0;
-+      }
++      toi_compress_bytes_in = 0;
++      toi_compress_bytes_out = 0;
 +
-+      if (target_file && !IS_ERR(target_file))
-+              filp_close(target_file, NULL);
++      next_driver = toi_get_next_filter(&toi_compression_ops);
 +
-+      target_file = NULL;
++      if (!next_driver)
++              return -ECHILD;
++
++      toi_compress_prepare_result = toi_compress_crypto_prepare();
++
++      return 0;
 +}
 +
-+/**
-+ * reopen_resume_devt - reset the devinfo struct
-+ *
-+ * Having opened resume= once, we remember the major and
-+ * minor nodes and use them to reopen the bdev for checking
-+ * whether an image exists (possibly when starting a resume).
-+ **/
-+static void reopen_resume_devt(void)
++/*
++ * toi_compress_rw_init()
++ */
++
++static int toi_compress_rw_init(int rw, int stream_number)
 +{
-+      toi_file_target_bdev = toi_open_by_devnum(resume_file_dev_t,
-+                      FMODE_READ | FMODE_NDELAY);
-+      if (IS_ERR(toi_file_target_bdev)) {
-+              printk(KERN_INFO "Got a dev_num (%lx) but failed to open it.\n",
-+                              (unsigned long) resume_file_dev_t);
-+              return;
++      if (toi_compress_prepare_result) {
++              printk(KERN_ERR "Failed to initialise compression "
++                              "algorithm.\n");
++              if (rw == READ) {
++                      printk(KERN_INFO "Unable to read the image.\n");
++                      return -ENODEV;
++              } else {
++                      printk(KERN_INFO "Continuing without "
++                              "compressing the image.\n");
++                      toi_compression_ops.enabled = 0;
++              }
 +      }
-+      target_inode = toi_file_target_bdev->bd_inode;
-+      set_devinfo(toi_file_target_bdev, target_inode->i_blkbits);
++
++      return 0;
 +}
 +
-+static void toi_file_get_target_info(char *target, int get_size,
-+              int resume_param)
++/*
++ * toi_compress_write_page()
++ *
++ * Compress a page of data, buffering output and passing on filled
++ * pages to the next module in the pipeline.
++ *
++ * Buffer_page:       Pointer to a buffer of size PAGE_SIZE, containing
++ * data to be compressed.
++ *
++ * Returns:   0 on success. Otherwise the error is that returned by later
++ *            modules, -ECHILD if we have a broken pipeline or -EIO if
++ *            zlib errs.
++ */
++static int toi_compress_write_page(unsigned long index,
++              struct page *buffer_page, unsigned int buf_size)
 +{
-+      if (target_file)
-+              toi_file_cleanup(0);
++      int ret, cpu = smp_processor_id();
++      struct cpu_context *ctx = &per_cpu(contexts, cpu);
 +
-+      if (!target || !strlen(target))
-+              return;
++      if (!ctx->transform)
++              return next_driver->write_page(index, buffer_page, buf_size);
 +
-+      target_file = filp_open(target, O_RDONLY|O_LARGEFILE, 0);
++      ctx->buffer_start = kmap(buffer_page);
 +
-+      if (IS_ERR(target_file) || !target_file) {
-+              wait_for_device_probe();
-+              scsi_complete_async_scans();
-+              target_file = filp_open(target, O_RDONLY|O_LARGEFILE, 0);
-+      }
++      ctx->len = buf_size;
 +
-+      if (IS_ERR(target_file) || !target_file) {
-+              target_file = NULL;
++      ret = crypto_comp_compress(ctx->transform,
++                      ctx->buffer_start, buf_size,
++                      ctx->output_buffer, &ctx->len);
 +
-+              if (!resume_param) {
-+                      printk(KERN_INFO "Open file %s returned %p.\n",
-+                                      target, target_file);
-+                      return;
-+              }
++      kunmap(buffer_page);
 +
-+              resume_file_dev_t = name_to_dev_t(target);
-+              if (!resume_file_dev_t) {
-+                      struct kstat stat;
-+                      int error = vfs_stat(target, &stat);
-+                      printk(KERN_INFO "Open file %s returned %p and "
-+                                      "name_to_devt failed.\n", target,
-+                                      target_file);
-+                      if (error)
-+                              printk(KERN_INFO "Stating the file also failed."
-+                                      " Nothing more we can do.\n");
-+                      else
-+                              resume_file_dev_t = stat.rdev;
-+                      return;
-+              }
++      mutex_lock(&stats_lock);
++      toi_compress_bytes_in += buf_size;
++      toi_compress_bytes_out += ctx->len;
++      mutex_unlock(&stats_lock);
 +
-+              toi_file_target_bdev = toi_open_by_devnum(resume_file_dev_t,
-+                              FMODE_READ | FMODE_NDELAY);
-+              if (IS_ERR(toi_file_target_bdev)) {
-+                      printk(KERN_INFO "Got a dev_num (%lx) but failed to "
-+                                      "open it.\n",
-+                                      (unsigned long) resume_file_dev_t);
-+                      return;
-+              }
-+              used_devt = 1;
-+              target_inode = toi_file_target_bdev->bd_inode;
++      if (!ret && ctx->len < buf_size) { /* some compression */
++              memcpy(ctx->page_buffer, ctx->output_buffer, ctx->len);
++              return next_driver->write_page(index,
++                              virt_to_page(ctx->page_buffer),
++                              ctx->len);
 +      } else
-+              target_inode = target_file->f_mapping->host;
-+
-+      if (S_ISLNK(target_inode->i_mode) || S_ISDIR(target_inode->i_mode) ||
-+          S_ISSOCK(target_inode->i_mode) || S_ISFIFO(target_inode->i_mode)) {
-+              printk(KERN_INFO "File support works with regular files,"
-+                              " character files and block devices.\n");
-+              goto cleanup;
-+      }
++              return next_driver->write_page(index, buffer_page, buf_size);
++}
 +
-+      if (!used_devt) {
-+              if (S_ISBLK(target_inode->i_mode)) {
-+                      toi_file_target_bdev = I_BDEV(target_inode);
-+                      if (!bd_claim(toi_file_target_bdev, &toi_fileops))
-+                              target_claim = 1;
-+              } else
-+                      toi_file_target_bdev = target_inode->i_sb->s_bdev;
-+              resume_file_dev_t = toi_file_target_bdev->bd_dev;
-+      }
++/*
++ * toi_compress_read_page()
++ * @buffer_page: struct page *. Pointer to a buffer of size PAGE_SIZE.
++ *
++ * Retrieve data from later modules and decompress it until the input buffer
++ * is filled.
++ * Zero if successful. Error condition from me or from downstream on failure.
++ */
++static int toi_compress_read_page(unsigned long *index,
++              struct page *buffer_page, unsigned int *buf_size)
++{
++      int ret, cpu = smp_processor_id();
++      unsigned int len;
++      unsigned int outlen = PAGE_SIZE;
++      char *buffer_start;
++      struct cpu_context *ctx = &per_cpu(contexts, cpu);
 +
-+      set_devinfo(toi_file_target_bdev, target_inode->i_blkbits);
++      if (!ctx->transform)
++              return next_driver->read_page(index, buffer_page, buf_size);
 +
-+      if (get_size)
-+              target_storage_available = size_ignoring_ignored_pages();
++      /*
++       * All our reads must be synchronous - we can't decompress
++       * data that hasn't been read yet.
++       */
 +
-+      if (!resume_param)
-+              target_firstblock = bmap(target_inode, 0) << devinfo.bmap_shift;
++      ret = next_driver->read_page(index, buffer_page, &len);
 +
-+      return;
-+cleanup:
-+      target_inode = NULL;
-+      if (target_file) {
-+              filp_close(target_file, NULL);
-+              target_file = NULL;
-+      }
-+      set_devinfo(NULL, 0);
-+      target_storage_available = 0;
-+}
++      /* Error or uncompressed data */
++      if (ret || len == PAGE_SIZE)
++              return ret;
 +
-+static void toi_file_noresume_reset(void)
-+{
-+      toi_bio_ops.rw_cleanup(READ);
++      buffer_start = kmap(buffer_page);
++      memcpy(ctx->page_buffer, buffer_start, len);
++      ret = crypto_comp_decompress(
++                      ctx->transform,
++                      ctx->page_buffer,
++                      len, buffer_start, &outlen);
++      if (ret)
++              abort_hibernate(TOI_FAILED_IO,
++                      "Compress_read returned %d.\n", ret);
++      else if (outlen != PAGE_SIZE) {
++              abort_hibernate(TOI_FAILED_IO,
++                      "Decompression yielded %d bytes instead of %ld.\n",
++                      outlen, PAGE_SIZE);
++              printk(KERN_ERR "Decompression yielded %d bytes instead of "
++                              "%ld.\n", outlen, PAGE_SIZE);
++              ret = -EIO;
++              *buf_size = outlen;
++      }
++      kunmap(buffer_page);
++      return ret;
 +}
 +
-+/**
-+ * parse_signature - check if the file is suitable for resuming
-+ * @header:   Signature of the file
++/*
++ * toi_compress_print_debug_stats
++ * @buffer: Pointer to a buffer into which the debug info will be printed.
++ * @size: Size of the buffer.
 + *
-+ * Given a file header, check the content of the file. Return true if it
-+ * contains a valid hibernate image.
-+ * TOI_RESUMED_BEFORE is set accordingly.
-+ **/
-+static int parse_signature(struct toi_file_header *header)
-+{
-+      int have_image = !memcmp(HaveImage, header->sig, sizeof(HaveImage) - 1);
-+      int no_image_header = !memcmp(NoImage, header->sig,
-+                      sizeof(NoImage) - 1);
-+      int binary_sig = !memcmp(tuxonice_signature, header->sig,
-+                      sizeof(tuxonice_signature));
-+
-+      if (no_image_header || (binary_sig && !header->have_image))
-+              return 0;
++ * Print information to be recorded for debugging purposes into a buffer.
++ * Returns: Number of characters written to the buffer.
++ */
 +
-+      if (!have_image && !binary_sig)
-+              return -1;
++static int toi_compress_print_debug_stats(char *buffer, int size)
++{
++      unsigned long pages_in = toi_compress_bytes_in >> PAGE_SHIFT,
++                    pages_out = toi_compress_bytes_out >> PAGE_SHIFT;
++      int len;
 +
-+      if (header->resumed_before)
-+              set_toi_state(TOI_RESUMED_BEFORE);
++      /* Output the compression ratio achieved. */
++      if (*toi_compressor_name)
++              len = scnprintf(buffer, size, "- Compressor is '%s'.\n",
++                              toi_compressor_name);
 +      else
-+              clear_toi_state(TOI_RESUMED_BEFORE);
++              len = scnprintf(buffer, size, "- Compressor is not set.\n");
 +
-+      target_header_start = header->first_header_block;
-+      return 1;
++      if (pages_in)
++              len += scnprintf(buffer+len, size - len, "  Compressed "
++                      "%lu bytes into %lu (%ld percent compression).\n",
++                toi_compress_bytes_in,
++                toi_compress_bytes_out,
++                (pages_in - pages_out) * 100 / pages_in);
++      return len;
 +}
 +
-+/**
-+ * prepare_signature - populate the signature structure
-+ * @current_header:   Signature structure to populate
-+ * @first_header_block:       Sector with the header containing the extents
-+ **/
-+static int prepare_signature(struct toi_file_header *current_header,
-+              unsigned long first_header_block)
++/*
++ * toi_compress_compression_memory_needed
++ *
++ * Tell the caller how much memory we need to operate during hibernate/resume.
++ * Returns: Unsigned long. Maximum number of bytes of memory required for
++ * operation.
++ */
++static int toi_compress_memory_needed(void)
 +{
-+      memcpy(current_header->sig, tuxonice_signature,
-+                      sizeof(tuxonice_signature));
-+      current_header->resumed_before = 0;
-+      current_header->first_header_block = first_header_block;
-+      current_header->have_image = 1;
-+      return 0;
++      return 2 * PAGE_SIZE;
 +}
 +
-+static unsigned long toi_file_storage_allocated(void)
++static int toi_compress_storage_needed(void)
 +{
-+      if (!target_inode)
-+              return 0;
-+
-+      if (target_is_normal_file())
-+              return raw_to_real(target_storage_available);
-+      else
-+              return raw_to_real(main_pages_requested);
++      return 4 * sizeof(unsigned long) + strlen(toi_compressor_name) + 1;
 +}
 +
-+/**
-+ * toi_file_release_storage - deallocate the block chain
-+ **/
-+static int toi_file_release_storage(void)
++/*
++ * toi_compress_save_config_info
++ * @buffer: Pointer to a buffer of size PAGE_SIZE.
++ *
++ * Save informaton needed when reloading the image at resume time.
++ * Returns: Number of bytes used for saving our data.
++ */
++static int toi_compress_save_config_info(char *buffer)
 +{
-+      toi_put_extent_chain(&block_chain);
-+
-+      header_pages_reserved = 0;
-+      main_pages_allocated = 0;
-+      main_pages_requested = 0;
-+      return 0;
-+}
++      int namelen = strlen(toi_compressor_name) + 1;
++      int total_len;
 +
-+static void toi_file_reserve_header_space(unsigned long request)
-+{
-+      header_pages_reserved = request;
++      *((unsigned long *) buffer) = toi_compress_bytes_in;
++      *((unsigned long *) (buffer + 1 * sizeof(unsigned long))) =
++              toi_compress_bytes_out;
++      *((unsigned long *) (buffer + 2 * sizeof(unsigned long))) =
++              toi_expected_compression;
++      *((unsigned long *) (buffer + 3 * sizeof(unsigned long))) = namelen;
++      strncpy(buffer + 4 * sizeof(unsigned long), toi_compressor_name,
++                                                              namelen);
++      total_len = 4 * sizeof(unsigned long) + namelen;
++      return total_len;
 +}
 +
-+static int toi_file_allocate_storage(unsigned long main_space_requested)
++/* toi_compress_load_config_info
++ * @buffer: Pointer to the start of the data.
++ * @size: Number of bytes that were saved.
++ *
++ * Description:       Reload information needed for decompressing the image at
++ * resume time.
++ */
++static void toi_compress_load_config_info(char *buffer, int size)
 +{
-+      int result = 0;
-+
-+      unsigned long extra_pages = DIV_ROUND_UP(main_space_requested *
-+                      (sizeof(unsigned long) + sizeof(int)), PAGE_SIZE),
-+                    pages_to_get = main_space_requested + extra_pages +
-+                            header_pages_reserved,
-+                    blocks_to_get = (pages_to_get > block_chain.size) ?
-+                            pages_to_get - block_chain.size : 0;
-+
-+      /* Only release_storage reduces the size */
-+      if (!blocks_to_get)
-+              return apply_header_reservation();
-+
-+      result = populate_block_list();
-+
-+      if (result)
-+              return result;
-+
-+      toi_message(TOI_WRITER, TOI_MEDIUM, 0,
-+              "Finished with block_chain.size == %d.\n",
-+              block_chain.size);
++      int namelen;
 +
-+      if (block_chain.size < pages_to_get) {
-+              printk(KERN_INFO "Block chain size (%lu) < header pages (%lu) + "
-+                               "extra pages (%lu) + main pages (%lu) (=%lu "
-+                               "pages).\n",
-+                               block_chain.size, header_pages_reserved,
-+                               extra_pages, main_space_requested,
-+                               pages_to_get);
-+              result = -ENOSPC;
++      toi_compress_bytes_in = *((unsigned long *) buffer);
++      toi_compress_bytes_out = *((unsigned long *) (buffer + 1 *
++                              sizeof(unsigned long)));
++      toi_expected_compression = *((unsigned long *) (buffer + 2 *
++                              sizeof(unsigned long)));
++      namelen = *((unsigned long *) (buffer + 3 * sizeof(unsigned long)));
++      if (strncmp(toi_compressor_name, buffer + 4 * sizeof(unsigned long),
++                              namelen)) {
++              toi_compress_cleanup(1);
++              strncpy(toi_compressor_name, buffer + 4 * sizeof(unsigned long),
++                      namelen);
++              toi_compress_crypto_prepare();
 +      }
-+
-+      main_pages_requested = main_space_requested;
-+      main_pages_allocated = main_space_requested + extra_pages;
-+      return result;
++      return;
 +}
 +
-+/**
-+ * toi_file_write_header_init - save the header on the image
-+ **/
-+static int toi_file_write_header_init(void)
-+{
-+      int result;
++/*
++ * toi_expected_compression_ratio
++ *
++ * Description:       Returns the expected ratio between data passed into this module
++ *            and the amount of data output when writing.
++ * Returns:   100 if the module is disabled. Otherwise the value set by the
++ *            user via our sysfs entry.
++ */
 +
-+      toi_bio_ops.rw_init(WRITE, 0);
-+      toi_writer_buffer_posn = 0;
++static int toi_compress_expected_ratio(void)
++{
++      if (!toi_compression_ops.enabled)
++              return 100;
++      else
++              return 100 - toi_expected_compression;
++}
 +
-+      /* Info needed to bootstrap goes at the start of the header.
-+       * First we save the basic info needed for reading, including the number
-+       * of header pages. Then we save the structs containing data needed
-+       * for reading the header pages back.
-+       * Note that even if header pages take more than one page, when we
-+       * read back the info, we will have restored the location of the
-+       * next header page by the time we go to use it.
-+       */
++/*
++ * data for our sysfs entries.
++ */
++static struct toi_sysfs_data sysfs_params[] = {
++      SYSFS_INT("expected_compression", SYSFS_RW, &toi_expected_compression,
++                      0, 99, 0, NULL),
++      SYSFS_INT("enabled", SYSFS_RW, &toi_compression_ops.enabled, 0, 1, 0,
++                      NULL),
++      SYSFS_STRING("algorithm", SYSFS_RW, toi_compressor_name, 31, 0, NULL),
++};
 +
-+      result = toi_bio_ops.rw_header_chunk(WRITE, &toi_fileops,
-+                      (char *) &toi_writer_posn_save,
-+                      sizeof(toi_writer_posn_save));
++/*
++ * Ops structure.
++ */
++static struct toi_module_ops toi_compression_ops = {
++      .type                   = FILTER_MODULE,
++      .name                   = "compression",
++      .directory              = "compression",
++      .module                 = THIS_MODULE,
++      .initialise             = toi_compress_init,
++      .cleanup                = toi_compress_cleanup,
++      .memory_needed          = toi_compress_memory_needed,
++      .print_debug_info       = toi_compress_print_debug_stats,
++      .save_config_info       = toi_compress_save_config_info,
++      .load_config_info       = toi_compress_load_config_info,
++      .storage_needed         = toi_compress_storage_needed,
++      .expected_compression   = toi_compress_expected_ratio,
 +
-+      if (result)
-+              return result;
++      .rw_init                = toi_compress_rw_init,
 +
-+      result = toi_bio_ops.rw_header_chunk(WRITE, &toi_fileops,
-+                      (char *) &devinfo, sizeof(devinfo));
++      .write_page             = toi_compress_write_page,
++      .read_page              = toi_compress_read_page,
 +
-+      if (result)
-+              return result;
++      .sysfs_data             = sysfs_params,
++      .num_sysfs_entries      = sizeof(sysfs_params) /
++              sizeof(struct toi_sysfs_data),
++};
 +
-+      /* Flush the chain */
-+      toi_serialise_extent_chain(&toi_fileops, &block_chain);
++/* ---- Registration ---- */
 +
-+      return 0;
++static __init int toi_compress_load(void)
++{
++      return toi_register_module(&toi_compression_ops);
 +}
 +
-+static int toi_file_write_header_cleanup(void)
++#ifdef MODULE
++static __exit void toi_compress_unload(void)
 +{
-+      struct toi_file_header *header;
-+      int result, result2;
-+      unsigned long sig_page = toi_get_zeroed_page(38, TOI_ATOMIC_GFP);
-+
-+      /* Write any unsaved data */
-+      result = toi_bio_ops.write_header_chunk_finish();
-+
-+      if (result)
-+              goto out;
-+
-+      toi_extent_state_goto_start(&toi_writer_posn);
-+      toi_bio_ops.forward_one_page(1, 1);
-+
-+      /* Adjust image header */
-+      result = toi_bio_ops.bdev_page_io(READ, toi_file_target_bdev,
-+                      target_firstblock,
-+                      virt_to_page(sig_page));
-+      if (result)
-+              goto out;
-+
-+      header = (struct toi_file_header *) sig_page;
-+
-+      prepare_signature(header,
-+                      toi_writer_posn.current_offset <<
-+                      devinfo.bmap_shift);
-+
-+      result = toi_bio_ops.bdev_page_io(WRITE, toi_file_target_bdev,
-+                      target_firstblock,
-+                      virt_to_page(sig_page));
-+
-+out:
-+      result2 = toi_bio_ops.finish_all_io();
-+      toi_free_page(38, sig_page);
-+
-+      return result ? result : result2;
++      toi_unregister_module(&toi_compression_ops);
 +}
 +
-+/* HEADER READING */
++module_init(toi_compress_load);
++module_exit(toi_compress_unload);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Nigel Cunningham");
++MODULE_DESCRIPTION("Compression Support for TuxOnIce");
++#else
++late_initcall(toi_compress_load);
++#endif
+diff --git a/kernel/power/tuxonice_extent.c b/kernel/power/tuxonice_extent.c
+new file mode 100644
+index 0000000..ff5afa9
+--- /dev/null
++++ b/kernel/power/tuxonice_extent.c
+@@ -0,0 +1,123 @@
++/*
++ * kernel/power/tuxonice_extent.c
++ *
++ * Copyright (C) 2003-2008 Nigel Cunningham (nigel at tuxonice net)
++ *
++ * Distributed under GPLv2.
++ *
++ * These functions encapsulate the manipulation of storage metadata.
++ */
++
++#include <linux/suspend.h>
++#include "tuxonice_modules.h"
++#include "tuxonice_extent.h"
++#include "tuxonice_alloc.h"
++#include "tuxonice_ui.h"
++#include "tuxonice.h"
 +
 +/**
-+ * toi_file_read_header_init - check content of signature
-+ *
-+ * Entry point of the resume path.
-+ * 1. Attempt to read the device specified with resume=.
-+ * 2. Check the contents of the header for our signature.
-+ * 3. Warn, ignore, reset and/or continue as appropriate.
-+ * 4. If continuing, read the toi_file configuration section
-+ *    of the header and set up block device info so we can read
-+ *    the rest of the header & image.
++ * toi_get_extent - return a free extent
 + *
-+ * Returns:
-+ *    May not return if user choose to reboot at a warning.
-+ *    -EINVAL if cannot resume at this time. Booting should continue
-+ *    normally.
++ * May fail, returning NULL instead.
 + **/
-+static int toi_file_read_header_init(void)
++static struct hibernate_extent *toi_get_extent(void)
 +{
-+      int result;
-+      struct block_device *tmp;
++      return (struct hibernate_extent *) toi_kzalloc(2,
++                      sizeof(struct hibernate_extent), TOI_ATOMIC_GFP);
++}
 +
-+      /* Allocate toi_writer_buffer */
-+      toi_bio_ops.read_header_init();
++/**
++ * toi_put_extent_chain - free a whole chain of extents
++ * @chain:    Chain to free.
++ **/
++void toi_put_extent_chain(struct hibernate_extent_chain *chain)
++{
++      struct hibernate_extent *this;
 +
-+      /*
-+       * Read toi_file configuration (header containing metadata).
-+       * target_header_start is the first sector of the header. It has been
-+       * set when checking if the file was suitable for resuming, see
-+       * do_toi_step(STEP_RESUME_CAN_RESUME).
-+       */
-+      result = toi_bio_ops.bdev_page_io(READ, toi_file_target_bdev,
-+                      target_header_start,
-+                      virt_to_page((unsigned long) toi_writer_buffer));
++      this = chain->first;
 +
-+      if (result) {
-+              printk(KERN_ERR "FileAllocator read header init: Failed to "
-+                              "initialise reading the first page of data.\n");
-+              toi_bio_ops.rw_cleanup(READ);
-+              return result;
++      while (this) {
++              struct hibernate_extent *next = this->next;
++              toi_kfree(2, this, sizeof(*this));
++              chain->num_extents--;
++              this = next;
 +      }
 +
-+      /* toi_writer_posn_save[0] contains the header */
-+      memcpy(&toi_writer_posn_save, toi_writer_buffer,
-+             sizeof(toi_writer_posn_save));
-+
-+      /* Save the position in the buffer */
-+      toi_writer_buffer_posn = sizeof(toi_writer_posn_save);
-+
-+      tmp = devinfo.bdev;
-+
-+      /* See tuxonice_block_io.h */
-+      memcpy(&devinfo,
-+             toi_writer_buffer + toi_writer_buffer_posn,
-+             sizeof(devinfo));
-+
-+      devinfo.bdev = tmp;
-+      toi_writer_buffer_posn += sizeof(devinfo);
-+
-+      /* Reinitialize the extent pointer */
-+      toi_extent_state_goto_start(&toi_writer_posn);
-+      /* Jump to the next page */
-+      toi_bio_ops.set_extra_page_forward();
-+
-+      /* Bring back the chain from disk: this will read
-+       * all extents.
-+       */
-+      return toi_load_extent_chain(&block_chain);
-+}
-+
-+static int toi_file_read_header_cleanup(void)
-+{
-+      toi_bio_ops.rw_cleanup(READ);
-+      return 0;
++      chain->first = NULL;
++      chain->last_touched = NULL;
++      chain->current_extent = NULL;
++      chain->size = 0;
 +}
++EXPORT_SYMBOL_GPL(toi_put_extent_chain);
 +
 +/**
-+ * toi_file_signature_op - perform an operation on the file signature
-+ * @op:       operation to perform
++ * toi_add_to_extent_chain - add an extent to an existing chain
++ * @chain:    Chain to which the extend should be added
++ * @start:    Start of the extent (first physical block)
++ * @end:      End of the extent (last physical block)
 + *
-+ * op is either GET_IMAGE_EXISTS, INVALIDATE, MARK_RESUME_ATTEMPTED or
-+ * UNMARK_RESUME_ATTEMPTED.
-+ * If the signature is changed, an I/O operation is performed.
-+ * The signature exists iff toi_file_signature_op(GET_IMAGE_EXISTS)>-1.
++ * The chain information is updated if the insertion is successful.
 + **/
-+static int toi_file_signature_op(int op)
++int toi_add_to_extent_chain(struct hibernate_extent_chain *chain,
++              unsigned long start, unsigned long end)
 +{
-+      char *cur;
-+      int result = 0, result2, changed = 0;
-+      struct toi_file_header *header;
++      struct hibernate_extent *new_ext = NULL, *cur_ext = NULL;
 +
-+      if (!toi_file_target_bdev || IS_ERR(toi_file_target_bdev))
-+              return -1;
++      toi_message(TOI_IO, TOI_VERBOSE, 0,
++              "Adding extent %lu-%lu to chain %p.\n", start, end, chain);
 +
-+      cur = (char *) toi_get_zeroed_page(17, TOI_ATOMIC_GFP);
-+      if (!cur) {
-+              printk(KERN_INFO "Unable to allocate a page for reading the "
-+                               "image signature.\n");
-+              return -ENOMEM;
-+      }
++      /* Find the right place in the chain */
++      if (chain->last_touched && chain->last_touched->start < start)
++              cur_ext = chain->last_touched;
++      else if (chain->first && chain->first->start < start)
++              cur_ext = chain->first;
 +
-+      result = toi_bio_ops.bdev_page_io(READ, toi_file_target_bdev,
-+                      target_firstblock,
-+                      virt_to_page(cur));
++      if (cur_ext) {
++              while (cur_ext->next && cur_ext->next->start < start)
++                      cur_ext = cur_ext->next;
 +
-+      if (result)
-+              goto out;
++              if (cur_ext->end == (start - 1)) {
++                      struct hibernate_extent *next_ext = cur_ext->next;
++                      cur_ext->end = end;
 +
-+      header = (struct toi_file_header *) cur;
-+      result = parse_signature(header);
++                      /* Merge with the following one? */
++                      if (next_ext && cur_ext->end + 1 == next_ext->start) {
++                              cur_ext->end = next_ext->end;
++                              cur_ext->next = next_ext->next;
++                              toi_kfree(2, next_ext, sizeof(*next_ext));
++                              chain->num_extents--;
++                      }
 +
-+      switch (op) {
-+      case INVALIDATE:
-+              if (result == -1)
-+                      goto out;
++                      chain->last_touched = cur_ext;
++                      chain->size += (end - start + 1);
 +
-+              memcpy(header->sig, tuxonice_signature,
-+                              sizeof(tuxonice_signature));
-+              header->resumed_before = 0;
-+              header->have_image = 0;
-+              result = 1;
-+              changed = 1;
-+              break;
-+      case MARK_RESUME_ATTEMPTED:
-+              if (result == 1) {
-+                      header->resumed_before = 1;
-+                      changed = 1;
-+              }
-+              break;
-+      case UNMARK_RESUME_ATTEMPTED:
-+              if (result == 1) {
-+                      header->resumed_before = 0;
-+                      changed = 1;
++                      return 0;
 +              }
-+              break;
 +      }
 +
-+      if (changed) {
-+              int io_result = toi_bio_ops.bdev_page_io(WRITE,
-+                              toi_file_target_bdev, target_firstblock,
-+                              virt_to_page(cur));
-+              if (io_result)
-+                      result = io_result;
++      new_ext = toi_get_extent();
++      if (!new_ext) {
++              printk(KERN_INFO "Error unable to append a new extent to the "
++                              "chain.\n");
++              return -ENOMEM;
 +      }
 +
-+out:
-+      result2 = toi_bio_ops.finish_all_io();
-+      toi_free_page(17, (unsigned long) cur);
-+      return result ? result : result2;
-+}
++      chain->num_extents++;
++      chain->size += (end - start + 1);
++      new_ext->start = start;
++      new_ext->end = end;
 +
-+/**
-+ * toi_file_print_debug_stats - print debug info
-+ * @buffer:   Buffer to data to populate
-+ * @size:     Size of the buffer
-+ **/
-+static int toi_file_print_debug_stats(char *buffer, int size)
-+{
-+      int len = 0;
++      chain->last_touched = new_ext;
 +
-+      if (toiActiveAllocator != &toi_fileops) {
-+              len = scnprintf(buffer, size,
-+                              "- FileAllocator inactive.\n");
-+              return len;
++      if (cur_ext) {
++              new_ext->next = cur_ext->next;
++              cur_ext->next = new_ext;
++      } else {
++              if (chain->first)
++                      new_ext->next = chain->first;
++              chain->first = new_ext;
 +      }
 +
-+      len = scnprintf(buffer, size, "- FileAllocator active.\n");
++      return 0;
++}
++EXPORT_SYMBOL_GPL(toi_add_to_extent_chain);
+diff --git a/kernel/power/tuxonice_extent.h b/kernel/power/tuxonice_extent.h
+new file mode 100644
+index 0000000..99e4734
+--- /dev/null
++++ b/kernel/power/tuxonice_extent.h
+@@ -0,0 +1,44 @@
++/*
++ * kernel/power/tuxonice_extent.h
++ *
++ * Copyright (C) 2003-2008 Nigel Cunningham (nigel at tuxonice net)
++ *
++ * This file is released under the GPLv2.
++ *
++ * It contains declarations related to extents. Extents are
++ * TuxOnIce's method of storing some of the metadata for the image.
++ * See tuxonice_extent.c for more info.
++ *
++ */
++
++#include "tuxonice_modules.h"
 +
-+      len += scnprintf(buffer+len, size-len, "  Storage available for "
-+                      "image: %lu pages.\n",
-+                      toi_file_storage_allocated());
++#ifndef EXTENT_H
++#define EXTENT_H
 +
-+      return len;
-+}
++struct hibernate_extent {
++      unsigned long start, end;
++      struct hibernate_extent *next;
++};
 +
-+/**
-+ * toi_file_storage_needed - storage needed
++struct hibernate_extent_chain {
++      unsigned long size; /* size of the chain ie sum (max-min+1) */
++      int num_extents;
++      struct hibernate_extent *first, *last_touched;
++      struct hibernate_extent *current_extent;
++      unsigned long current_offset;
++};
++
++/* Simplify iterating through all the values in an extent chain */
++#define toi_extent_for_each(extent_chain, extentpointer, value) \
++if ((extent_chain)->first) \
++      for ((extentpointer) = (extent_chain)->first, (value) = \
++                      (extentpointer)->start; \
++           ((extentpointer) && ((extentpointer)->next || (value) <= \
++                               (extentpointer)->end)); \
++           (((value) == (extentpointer)->end) ? \
++              ((extentpointer) = (extentpointer)->next, (value) = \
++               ((extentpointer) ? (extentpointer)->start : 0)) : \
++                      (value)++))
++
++#endif
+diff --git a/kernel/power/tuxonice_file.c b/kernel/power/tuxonice_file.c
+new file mode 100644
+index 0000000..c71be4b
+--- /dev/null
++++ b/kernel/power/tuxonice_file.c
+@@ -0,0 +1,477 @@
++/*
++ * kernel/power/tuxonice_file.c
 + *
-+ * Returns amount of space in the image header required
-+ * for the toi_file's data.
++ * Copyright (C) 2005-2008 Nigel Cunningham (nigel at tuxonice net)
 + *
-+ * We ensure the space is allocated, but actually save the
-+ * data from write_header_init and therefore don't also define a
-+ * save_config_info routine.
-+ **/
-+static int toi_file_storage_needed(void)
-+{
-+      return strlen(toi_file_target) + 1 +
-+              sizeof(toi_writer_posn_save) +
-+              sizeof(devinfo) +
-+              sizeof(block_chain.size) + sizeof(block_chain.num_extents) +
-+              (2 * sizeof(unsigned long) * block_chain.num_extents);
-+}
++ * Distributed under GPLv2.
++ *
++ * This file encapsulates functions for usage of a simple file as a
++ * backing store. It is based upon the swapallocator, and shares the
++ * same basic working. Here, though, we have nothing to do with
++ * swapspace, and only one device to worry about.
++ *
++ * The user can just
++ *
++ * echo TuxOnIce > /path/to/my_file
++ *
++ * dd if=/dev/zero bs=1M count=<file_size_desired> >> /path/to/my_file
++ *
++ * and
++ *
++ * echo /path/to/my_file > /sys/power/tuxonice/file/target
++ *
++ * then put what they find in /sys/power/tuxonice/resume
++ * as their resume= parameter in lilo.conf (and rerun lilo if using it).
++ *
++ * Having done this, they're ready to hibernate and resume.
++ *
++ * TODO:
++ * - File resizing.
++ */
 +
-+/**
-+ * toi_file_remove_image - invalidate the image
-+ **/
-+static int toi_file_remove_image(void)
-+{
-+      toi_file_release_storage();
-+      return toi_file_signature_op(INVALIDATE);
-+}
++#include <linux/blkdev.h>
++#include <linux/mount.h>
++#include <linux/fs.h>
++#include <linux/uuid.h>
 +
-+/**
-+ * toi_file_image_exists - test if an image exists
-+ *
-+ * Repopulate toi_file_target_bdev if needed.
-+ **/
-+static int toi_file_image_exists(int quiet)
-+{
-+      if (!toi_file_target_bdev)
-+              reopen_resume_devt();
-+      return toi_file_signature_op(GET_IMAGE_EXISTS);
-+}
++#include "tuxonice.h"
++#include "tuxonice_modules.h"
++#include "tuxonice_bio.h"
++#include "tuxonice_alloc.h"
++#include "tuxonice_builtin.h"
++#include "tuxonice_sysfs.h"
++#include "tuxonice_ui.h"
++#include "tuxonice_io.h"
 +
-+/**
-+ * toi_file_mark_resume_attempted - mark resume attempted if so
-+ * @mark:     attempted flag
-+ *
-+ * Record that we tried to resume from this image. Resuming
-+ * multiple times from the same image may be dangerous
-+ * (possible filesystem corruption).
-+ **/
-+static int toi_file_mark_resume_attempted(int mark)
++#define target_is_normal_file() (S_ISREG(target_inode->i_mode))
++
++static struct toi_module_ops toi_fileops;
++
++static struct file *target_file;
++static struct block_device *toi_file_target_bdev;
++static unsigned long pages_available, pages_allocated;
++static char toi_file_target[256];
++static struct inode *target_inode;
++static int file_target_priority;
++static int used_devt;
++static int target_claim;
++static dev_t toi_file_dev_t;
++static int sig_page_index;
++
++/* For test_toi_file_target */
++static struct toi_bdev_info *file_chain;
++
++static int has_contiguous_blocks(struct toi_bdev_info *dev_info, int page_num)
 +{
-+      return toi_file_signature_op(mark ? MARK_RESUME_ATTEMPTED :
-+              UNMARK_RESUME_ATTEMPTED);
-+}
++      int j;
++      sector_t last = 0;
++
++      for (j = 0; j < dev_info->blocks_per_page; j++) {
++              sector_t this = bmap(target_inode,
++                              page_num * dev_info->blocks_per_page + j);
++
++              if (!this || (last && (last + 1) != this))
++                      break;
 +
-+/**
-+ * toi_file_set_resume_param - validate the specified resume file
-+ *
-+ * Given a target filename, populate the resume parameter. This is
-+ * meant to be used by the user to populate the kernel command line.
-+ * By setting /sys/power/tuxonice/file/target, the valid resume
-+ * parameter to use is set and accessible through
-+ * /sys/power/tuxonice/resume.
-+ *
-+ * If the file could be located, we check if it contains a valid
-+ * signature.
-+ **/
-+static void toi_file_set_resume_param(void)
-+{
-+      char *buffer = (char *) toi_get_zeroed_page(18, TOI_ATOMIC_GFP);
-+      char *buffer2 = (char *) toi_get_zeroed_page(19, TOI_ATOMIC_GFP);
-+      unsigned long sector = bmap(target_inode, 0);
-+      int offset = 0;
-+
-+      if (!buffer || !buffer2) {
-+              if (buffer)
-+                      toi_free_page(18, (unsigned long) buffer);
-+              if (buffer2)
-+                      toi_free_page(19, (unsigned long) buffer2);
-+              printk(KERN_ERR "TuxOnIce: Failed to allocate memory while "
-+                              "setting resume= parameter.\n");
-+              return;
++              last = this;
 +      }
 +
-+      if (toi_file_target_bdev) {
-+              set_devinfo(toi_file_target_bdev, target_inode->i_blkbits);
++      return j == dev_info->blocks_per_page;
++}
 +
-+              bdevname(toi_file_target_bdev, buffer2);
-+              offset += snprintf(buffer + offset, PAGE_SIZE - offset,
-+                              "/dev/%s", buffer2);
++static unsigned long get_usable_pages(struct toi_bdev_info *dev_info)
++{
++      unsigned long result = 0;
++      struct block_device *bdev = dev_info->bdev;
++      int i;
 +
-+              if (sector)
-+                      /* The offset is: sector << (inode->i_blkbits - 9) */
-+                      offset += snprintf(buffer + offset, PAGE_SIZE - offset,
-+                              ":0x%lx", sector << devinfo.bmap_shift);
-+      } else
-+              offset += snprintf(buffer + offset, PAGE_SIZE - offset,
-+                              "%s is not a valid target.", toi_file_target);
++      switch (target_inode->i_mode & S_IFMT) {
++      case S_IFSOCK:
++      case S_IFCHR:
++      case S_IFIFO: /* Socket, Char, Fifo */
++              return -1;
++      case S_IFREG: /* Regular file: current size - holes + free
++                       space on part */
++              for (i = 0; i < (target_inode->i_size >> PAGE_SHIFT) ; i++) {
++                      if (has_contiguous_blocks(dev_info, i))
++                              result++;
++              }
++              break;
++      case S_IFBLK: /* Block device */
++              if (!bdev->bd_disk) {
++                      toi_message(TOI_IO, TOI_VERBOSE, 0,
++                                      "bdev->bd_disk null.");
++                      return 0;
++              }
 +
-+      sprintf(resume_file, "file:%s", buffer);
++              result = (bdev->bd_part ?
++                      bdev->bd_part->nr_sects :
++                      get_capacity(bdev->bd_disk)) >> (PAGE_SHIFT - 9);
++      }
 +
-+      toi_free_page(18, (unsigned long) buffer);
-+      toi_free_page(19, (unsigned long) buffer2);
 +
-+      toi_attempt_to_parse_resume_device(1);
++      return result;
 +}
 +
-+/**
-+ * __test_toi_file_target - is the file target valid for hibernating?
-+ * @target:           target file
-+ * @resume_param:     whether resume= has been specified
-+ * @quiet:            quiet flag
-+ *
-+ * Test whether the file target can be used for hibernating: valid target
-+ * and signature.
-+ * The resume parameter is set if needed.
-+ **/
-+static int __test_toi_file_target(char *target, int resume_param, int quiet)
++static int toi_file_register_storage(void)
 +{
-+      toi_file_get_target_info(target, 0, resume_param);
-+      if (toi_file_signature_op(GET_IMAGE_EXISTS) > -1) {
-+              if (!quiet)
-+                      printk(KERN_INFO "TuxOnIce: FileAllocator: File "
-+                                       "signature found.\n");
-+              if (!resume_param)
-+                      toi_file_set_resume_param();
++      struct toi_bdev_info *devinfo;
++      int result;
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_file_register_storage.");
++      if (!strlen(toi_file_target)) {
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Register file storage: "
++                              "No target filename set.");
++              return 0;
++      }
++
++      target_file = filp_open(toi_file_target, O_RDONLY|O_LARGEFILE, 0);
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "filp_open %s returned %p.",
++                      toi_file_target, target_file);
++
++      if (IS_ERR(target_file) || !target_file) {
++              target_file = NULL;
++              toi_file_dev_t = name_to_dev_t(toi_file_target);
++              if (!toi_file_dev_t) {
++                      struct kstat stat;
++                      int error = vfs_stat(toi_file_target, &stat);
++                      printk(KERN_INFO "Open file %s returned %p and "
++                                      "name_to_devt failed.\n",
++                                      toi_file_target, target_file);
++                      if (error) {
++                              printk(KERN_INFO "Stating the file also failed."
++                                      " Nothing more we can do.\n");
++                              return 0;
++                      } else
++                              toi_file_dev_t = stat.rdev;
++              }
 +
-+              toi_bio_ops.set_devinfo(&devinfo);
-+              toi_writer_posn.chains = &block_chain;
-+              toi_writer_posn.num_chains = 1;
++              toi_file_target_bdev = toi_open_by_devnum(toi_file_dev_t,
++                              FMODE_READ | FMODE_NDELAY);
++              if (IS_ERR(toi_file_target_bdev)) {
++                      printk(KERN_INFO "Got a dev_num (%lx) but failed to "
++                                      "open it.\n",
++                                      (unsigned long) toi_file_dev_t);
++                      toi_file_target_bdev = NULL;
++                      return 0;
++              }
++              used_devt = 1;
++              target_inode = toi_file_target_bdev->bd_inode;
++      } else
++              target_inode = target_file->f_mapping->host;
 +
-+              if (!resume_param)
-+                      set_toi_state(TOI_CAN_HIBERNATE);
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Succeeded in opening the target.");
++      if (S_ISLNK(target_inode->i_mode) || S_ISDIR(target_inode->i_mode) ||
++          S_ISSOCK(target_inode->i_mode) || S_ISFIFO(target_inode->i_mode)) {
++              printk(KERN_INFO "File support works with regular files,"
++                              " character files and block devices.\n");
++              /* Cleanup routine will undo the above */
 +              return 0;
 +      }
 +
-+      /*
-+       * Target unaccessible or no signature found
-+       * Most errors have already been reported
-+       */
++      if (!used_devt) {
++              if (S_ISBLK(target_inode->i_mode)) {
++                      toi_file_target_bdev = I_BDEV(target_inode);
++                      if (!bd_claim(toi_file_target_bdev, &toi_fileops))
++                              target_claim = 1;
++              } else
++                      toi_file_target_bdev = target_inode->i_sb->s_bdev;
++              toi_file_dev_t = toi_file_target_bdev->bd_dev;
++      }
 +
-+      clear_toi_state(TOI_CAN_HIBERNATE);
++      devinfo = toi_kzalloc(39, sizeof(struct toi_bdev_info), GFP_ATOMIC);
++      if (!devinfo) {
++              printk("Failed to allocate a toi_bdev_info struct for the file allocator.\n");
++              return -ENOMEM;
++      }
 +
-+      if (quiet)
-+              return 1;
++      devinfo->bdev = toi_file_target_bdev;
++      devinfo->allocator = &toi_fileops;
++      devinfo->allocator_index = 0;
 +
-+      if (*target)
-+              printk(KERN_INFO "TuxOnIce: FileAllocator: Sorry. No signature "
-+                               "found at  %s.\n", target);
-+      else
-+              if (!resume_param)
-+                      printk(KERN_INFO "TuxOnIce: FileAllocator: Sorry. "
-+                                      "Target is not set for hibernating.\n");
++      result = uuid_from_block_dev(toi_file_target_bdev, devinfo->uuid);
++      if (result)
++              printk(KERN_DEBUG "Failed to get uuid for file device (%d).\n",
++                              result);
++      devinfo->dev_t = toi_file_dev_t;
++      devinfo->prio = file_target_priority;
++      devinfo->bmap_shift = target_inode->i_blkbits - 9;
++      devinfo->blocks_per_page =
++              (1 << (PAGE_SHIFT - target_inode->i_blkbits));
++      file_chain = devinfo;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Dev_t is %lx. Prio is %d. Bmap "
++                      "shift is %d. Blocks per page %d.",
++                      devinfo->dev_t, devinfo->prio, devinfo->bmap_shift,
++                      devinfo->blocks_per_page);
++
++      /* Keep one aside for the signature */
++      pages_available = get_usable_pages(devinfo) - 1;
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Registering file storage, %lu "
++                      "pages.", pages_available);
++
++      toi_bio_ops.register_storage(devinfo);
++      return 0;
++}
 +
-+      return 1;
++static unsigned long toi_file_storage_available(void)
++{
++      return pages_available;
 +}
 +
-+/**
-+ * test_toi_file_target - sysfs callback for /sys/power/tuxonince/file/target
-+ *
-+ * Test wheter the target file is valid for hibernating.
-+ **/
-+static void test_toi_file_target(void)
++static int toi_file_allocate_storage(struct toi_bdev_info *chain,
++              unsigned long request)
 +{
-+      setting_toi_file_target = 1;
++      unsigned long available = pages_available - pages_allocated;
++      unsigned long to_add = min(available, request);
 +
-+      printk(KERN_INFO "TuxOnIce: Hibernating %sabled.\n",
-+                      __test_toi_file_target(toi_file_target, 0, 1) ?
-+                      "dis" : "en");
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Pages available is %lu. Allocated "
++              "is %lu. Allocating %lu pages from file.",
++              pages_available, pages_allocated, to_add);
++      pages_allocated += to_add;
 +
-+      setting_toi_file_target = 0;
++      return to_add;
 +}
 +
 +/**
-+ * toi_file_parse_sig_location - parse image Location
-+ * @commandline:      the resume parameter
-+ * @only_writer:      ??
-+ * @quiet:            quiet flag
-+ *
-+ * Attempt to parse a resume= parameter.
-+ * File Allocator accepts:
-+ *    resume=file:DEVNAME[:FIRSTBLOCK]
++ * __populate_block_list - add an extent to the chain
++ * @min:      Start of the extent (first physical block = sector)
++ * @max:      End of the extent (last physical block = sector)
 + *
-+ * Where:
-+ *    DEVNAME is convertable to a dev_t by name_to_dev_t
-+ *    FIRSTBLOCK is the location of the first block in the file.
-+ *    BLOCKSIZE is the logical blocksize >= SECTOR_SIZE &
-+ *                                    <= PAGE_SIZE,
-+ *    mod SECTOR_SIZE == 0 of the device.
-+ *
-+ * Data is validated by attempting to read a header from the
-+ * location given. Failure will result in toi_file refusing to
-+ * save an image, and a reboot with correct parameters will be
-+ * necessary.
++ * If TOI_TEST_BIO is set, print a debug message, outputting the min and max
++ * fs block numbers.
 + **/
-+static int toi_file_parse_sig_location(char *commandline,
-+              int only_writer, int quiet)
++static int __populate_block_list(struct toi_bdev_info *chain, int min, int max)
 +{
-+      char *thischar, *devstart = NULL, *colon = NULL, *at_symbol = NULL;
-+      int result = -EINVAL, target_blocksize = 0;
-+
-+      if (strncmp(commandline, "file:", 5)) {
-+              if (!only_writer)
-+                      return 1;
-+      } else
-+              commandline += 5;
++      if (test_action_state(TOI_TEST_BIO))
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Adding extent %d-%d.",
++                      min << chain->bmap_shift,
++                      ((max + 1) << chain->bmap_shift) - 1);
 +
-+      /*
-+       * Don't check signature again if we're beginning a cycle. If we already
-+       * did the initialisation successfully, assume we'll be okay when it
-+       * comes to resuming.
-+       */
-+      if (toi_file_target_bdev)
-+              return 0;
++      return toi_add_to_extent_chain(&chain->blocks, min, max);
++}
 +
-+      devstart = commandline;
-+      thischar = commandline;
-+      while ((*thischar != ':') && (*thischar != '@') &&
-+              ((thischar - commandline) < 250) && (*thischar))
-+              thischar++;
++static int get_main_pool_phys_params(struct toi_bdev_info *chain)
++{
++      int i, extent_min = -1, extent_max = -1, result = 0, have_sig_page = 0;
++      unsigned long pages_mapped = 0;
 +
-+      if (*thischar == ':') {
-+              colon = thischar;
-+              *colon = 0;
-+              thischar++;
-+      }
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Getting file allocator blocks.");
 +
-+      while ((*thischar != '@') && ((thischar - commandline) < 250)
-+                      && (*thischar))
-+              thischar++;
++      if (chain->blocks.first)
++              toi_put_extent_chain(&chain->blocks);
 +
-+      if (*thischar == '@') {
-+              at_symbol = thischar;
-+              *at_symbol = 0;
++      if (!target_is_normal_file()) {
++              result = (pages_available > 0) ?
++                      __populate_block_list(chain, chain->blocks_per_page,
++                              (pages_allocated + 1) *
++                              chain->blocks_per_page - 1) : 0;
++              return result;
 +      }
 +
 +      /*
-+       * For the toi_file, you can be able to resume, but not hibernate,
-+       * because the resume= is set correctly, but the toi_file_target
-+       * isn't.
-+       *
-+       * We may have come here as a result of setting resume or
-+       * toi_file_target. We only test the toi_file target in the
-+       * former case (it's already done in the later), and we do it before
-+       * setting the block number ourselves. It will overwrite the values
-+       * given on the command line if we don't.
++       * FIXME: We are assuming the first page is contiguous. Is that
++       * assumption always right?
 +       */
 +
-+      if (!setting_toi_file_target) /* Concurrent write via /sys? */
-+              __test_toi_file_target(toi_file_target, 1, 0);
++      for (i = 0; i < (target_inode->i_size >> PAGE_SHIFT); i++) {
++              sector_t new_sector;
 +
-+      if (colon) {
-+              unsigned long block;
-+              result = strict_strtoul(colon + 1, 0, &block);
-+              if (result)
-+                      goto out;
-+              target_firstblock = (int) block;
-+      } else
-+              target_firstblock = 0;
++              if (!has_contiguous_blocks(chain, i))
++                      continue;
 +
-+      if (at_symbol) {
-+              unsigned long block_size;
-+              result = strict_strtoul(at_symbol + 1, 0, &block_size);
-+              if (result)
-+                      goto out;
-+              target_blocksize = (int) block_size;
-+              if (target_blocksize & (SECTOR_SIZE - 1)) {
-+                      printk(KERN_INFO "FileAllocator: Blocksizes are "
-+                                       "multiples of %d.\n", SECTOR_SIZE);
-+                      result = -EINVAL;
-+                      goto out;
++              if (!have_sig_page) {
++                      have_sig_page = 1;
++                      sig_page_index = i;
++                      continue;
 +              }
-+      }
 +
-+      if (!quiet)
-+              printk(KERN_INFO "TuxOnIce FileAllocator: Testing whether you "
-+                               "can resume:\n");
++              pages_mapped++;
 +
-+      toi_file_get_target_info(commandline, 0, 1);
++              /* Ignore first page - it has the header */
++              if (pages_mapped == 1)
++                      continue;
 +
-+      if (!toi_file_target_bdev || IS_ERR(toi_file_target_bdev)) {
-+              toi_file_target_bdev = NULL;
-+              result = -1;
-+              goto out;
-+      }
++              new_sector = bmap(target_inode, (i * chain->blocks_per_page));
 +
-+      if (target_blocksize)
-+              set_devinfo(toi_file_target_bdev, ffs(target_blocksize));
++              /*
++               * I'd love to be able to fill in holes and resize
++               * files, but not yet...
++               */
 +
-+      result = __test_toi_file_target(commandline, 1, quiet);
++              if (new_sector == extent_max + 1)
++                      extent_max += chain->blocks_per_page;
++              else {
++                      if (extent_min > -1) {
++                              result = __populate_block_list(chain,
++                                              extent_min, extent_max);
++                              if (result)
++                                      return result;
++                      }
 +
-+out:
-+      if (result)
-+              clear_toi_state(TOI_CAN_HIBERNATE);
++                      extent_min = new_sector;
++                      extent_max = extent_min +
++                              chain->blocks_per_page - 1;
++              }
 +
-+      if (!quiet)
-+              printk(KERN_INFO "Resuming %sabled.\n",  result ? "dis" : "en");
++              if (pages_mapped == pages_allocated)
++                      break;
++      }
 +
-+      if (colon)
-+              *colon = ':';
-+      if (at_symbol)
-+              *at_symbol = '@';
++      if (extent_min > -1) {
++              result = __populate_block_list(chain, extent_min, extent_max);
++              if (result)
++                      return result;
++      }
 +
-+      return result;
++      return 0;
 +}
 +
-+/**
-+ * toi_file_save_config_info - populate toi_file_target
-+ * @buffer:   Pointer to a buffer of size PAGE_SIZE.
-+ *
-+ * Save the target's name, not for resume time, but for
-+ * all_settings.
-+ * Returns:
-+ *    Number of bytes used for saving our data.
-+ **/
-+static int toi_file_save_config_info(char *buffer)
++static void toi_file_free_storage(struct toi_bdev_info *chain)
 +{
-+      strcpy(buffer, toi_file_target);
-+      return strlen(toi_file_target) + 1;
++      pages_allocated = 0;
++      file_chain = NULL;
 +}
 +
 +/**
-+ * toi_file_load_config_info - reload target's name
-+ * @buffer:   pointer to the start of the data
-+ * @size:     number of bytes that were saved
-+ *
-+ * toi_file_target is set to buffer.
++ * toi_file_print_debug_stats - print debug info
++ * @buffer:   Buffer to data to populate
++ * @size:     Size of the buffer
 + **/
-+static void toi_file_load_config_info(char *buffer, int size)
++static int toi_file_print_debug_stats(char *buffer, int size)
 +{
-+      strlcpy(toi_file_target, buffer, size);
++      int len = scnprintf(buffer, size, "- File Allocator active.\n");
++
++      len += scnprintf(buffer+len, size-len, "  Storage available for "
++                      "image: %lu pages.\n", pages_available);
++
++      return len;
 +}
 +
-+static int toi_file_initialise(int starting_cycle)
++static void toi_file_cleanup(int finishing_cycle)
 +{
-+      if (starting_cycle) {
-+              if (toiActiveAllocator != &toi_fileops)
-+                      return 0;
++      if (toi_file_target_bdev) {
++              if (target_claim) {
++                      bd_release(toi_file_target_bdev);
++                      target_claim = 0;
++              }
 +
-+              if (starting_cycle & SYSFS_HIBERNATE && !*toi_file_target) {
-+                      printk(KERN_INFO "FileAllocator is the active writer,  "
-+                                      "but no filename has been set.\n");
-+                      return 1;
++              if (used_devt) {
++                      blkdev_put(toi_file_target_bdev,
++                                      FMODE_READ | FMODE_NDELAY);
++                      used_devt = 0;
 +              }
++              toi_file_target_bdev = NULL;
++              target_inode = NULL;
++      }
++
++      if (target_file) {
++              filp_close(target_file, NULL);
++              target_file = NULL;
 +      }
 +
-+      if (*toi_file_target)
-+              toi_file_get_target_info(toi_file_target, starting_cycle, 0);
++      pages_available = 0;
++}
 +
-+      if (starting_cycle && (toi_file_image_exists(1) == -1)) {
-+              printk("%s is does not have a valid signature for "
-+                              "hibernating.\n", toi_file_target);
-+              return 1;
++/**
++ * test_toi_file_target - sysfs callback for /sys/power/tuxonince/file/target
++ *
++ * Test wheter the target file is valid for hibernating.
++ **/
++static void test_toi_file_target(void)
++{
++      int result = toi_file_register_storage();
++      sector_t sector;
++      char uuid[17], buf[50];
++
++      if (result)
++              return;
++
++      /* This doesn't mean we're in business. Is any storage available? */
++      if (!pages_available)
++              goto out;
++
++      toi_file_allocate_storage(file_chain, 1);
++      result = get_main_pool_phys_params(file_chain);
++      if (result)
++              goto out;
++
++
++      sector = bmap(target_inode, sig_page_index *
++                      file_chain->blocks_per_page) << file_chain->bmap_shift;
++
++      /* Use the uuid, or the dev_t if that fails */
++      if (uuid_from_block_dev(toi_file_target_bdev, uuid)) {
++              bdevname(toi_file_target_bdev, buf);
++              sprintf(resume_file, "/dev/%s:%llu", buf,
++                              (unsigned long long) sector);
++      } else {
++              int i;
++              hex_dump_to_buffer(uuid, 16, 32, 1, buf, 50, 0);
++
++              /* Remove the spaces */
++              for (i = 1; i < 16; i++) {
++                      buf[2 * i] = buf[3 * i];
++                      buf[2 * i + 1] = buf[3 * i + 1];
++              }
++              buf[32] = 0;
++              sprintf(resume_file, "UUID=%s:%llu", buf,
++                              (unsigned long long) sector);
 +      }
 +
-+      return 0;
++      toi_attempt_to_parse_resume_device(0);
++out:
++      toi_file_free_storage(file_chain);
++      toi_bio_ops.free_storage();
 +}
 +
 +static struct toi_sysfs_data sysfs_params[] = {
-+
 +      SYSFS_STRING("target", SYSFS_RW, toi_file_target, 256,
 +              SYSFS_NEEDS_SM_FOR_WRITE, test_toi_file_target),
-+      SYSFS_INT("enabled", SYSFS_RW, &toi_fileops.enabled, 0, 1, 0,
-+              attempt_to_parse_resume_device2)
++      SYSFS_INT("enabled", SYSFS_RW, &toi_fileops.enabled, 0, 1, 0, NULL),
++      SYSFS_INT("priority", SYSFS_RW, &file_target_priority, -4095,
++                      4096, 0, NULL),
++};
++
++static struct toi_bio_allocator_ops toi_bio_fileops = {
++      .register_storage                       = toi_file_register_storage,
++      .storage_available                      = toi_file_storage_available,
++      .allocate_storage                       = toi_file_allocate_storage,
++      .bmap                                   = get_main_pool_phys_params,
++      .free_storage                           = toi_file_free_storage,
 +};
 +
 +static struct toi_module_ops toi_fileops = {
-+      .type                                   = WRITER_MODULE,
++      .type                                   = BIO_ALLOCATOR_MODULE,
 +      .name                                   = "file storage",
 +      .directory                              = "file",
 +      .module                                 = THIS_MODULE,
 +      .print_debug_info                       = toi_file_print_debug_stats,
-+      .save_config_info                       = toi_file_save_config_info,
-+      .load_config_info                       = toi_file_load_config_info,
-+      .storage_needed                         = toi_file_storage_needed,
-+      .initialise                             = toi_file_initialise,
 +      .cleanup                                = toi_file_cleanup,
-+
-+      .noresume_reset         = toi_file_noresume_reset,
-+      .storage_available      = toi_file_storage_available,
-+      .storage_allocated      = toi_file_storage_allocated,
-+      .reserve_header_space   = toi_file_reserve_header_space,
-+      .allocate_storage       = toi_file_allocate_storage,
-+      .image_exists           = toi_file_image_exists,
-+      .mark_resume_attempted  = toi_file_mark_resume_attempted,
-+      .write_header_init      = toi_file_write_header_init,
-+      .write_header_cleanup   = toi_file_write_header_cleanup,
-+      .read_header_init       = toi_file_read_header_init,
-+      .read_header_cleanup    = toi_file_read_header_cleanup,
-+      .remove_image           = toi_file_remove_image,
-+      .parse_sig_location     = toi_file_parse_sig_location,
++      .bio_allocator_ops                      = &toi_bio_fileops,
 +
 +      .sysfs_data             = sysfs_params,
 +      .num_sysfs_entries      = sizeof(sysfs_params) /
@@ -10090,18 +11454,6 @@ index 0000000..fe903bd
 +/* ---- Registration ---- */
 +static __init int toi_file_load(void)
 +{
-+      toi_fileops.rw_init = toi_bio_ops.rw_init;
-+      toi_fileops.rw_cleanup = toi_bio_ops.rw_cleanup;
-+      toi_fileops.read_page = toi_bio_ops.read_page;
-+      toi_fileops.write_page = toi_bio_ops.write_page;
-+      toi_fileops.rw_header_chunk = toi_bio_ops.rw_header_chunk;
-+      toi_fileops.rw_header_chunk_noreadahead =
-+              toi_bio_ops.rw_header_chunk_noreadahead;
-+      toi_fileops.io_flusher = toi_bio_ops.io_flusher;
-+      toi_fileops.update_throughput_throttle =
-+              toi_bio_ops.update_throughput_throttle;
-+      toi_fileops.finish_all_io = toi_bio_ops.finish_all_io;
-+
 +      return toi_register_module(&toi_fileops);
 +}
 +
@@ -10121,10 +11473,10 @@ index 0000000..fe903bd
 +#endif
 diff --git a/kernel/power/tuxonice_highlevel.c b/kernel/power/tuxonice_highlevel.c
 new file mode 100644
-index 0000000..29a442c
+index 0000000..8390946
 --- /dev/null
 +++ b/kernel/power/tuxonice_highlevel.c
-@@ -0,0 +1,1308 @@
+@@ -0,0 +1,1313 @@
 +/*
 + * kernel/power/tuxonice_highlevel.c
 + */
@@ -10201,6 +11553,7 @@ index 0000000..29a442c
 +#include <linux/console.h>
 +#include <linux/writeback.h>
 +#include <linux/uaccess.h> /* for get/set_fs & KERNEL_DS on i386 */
++#include <linux/bio.h>
 +
 +#include "tuxonice.h"
 +#include "tuxonice_modules.h"
@@ -10225,7 +11578,7 @@ index 0000000..29a442c
 +static int block_dump_save;
 +
 +/* Binary signature if an image is present */
-+char *tuxonice_signature = "\xed\xc3\x02\xe9\x98\x56\xe5\x0c";
++char tuxonice_signature[9] = "\xed\xc3\x02\xe9\x98\x56\xe5\x0c";
 +EXPORT_SYMBOL_GPL(tuxonice_signature);
 +
 +unsigned long boot_kernel_data_buffer;
@@ -10279,7 +11632,7 @@ index 0000000..29a442c
 +      toi_put_modules();
 +      if (hibernate_or_resume) {
 +              block_dump = block_dump_save;
-+              set_cpus_allowed(current, CPU_MASK_ALL);
++              set_cpus_allowed_ptr(current, cpu_all_mask);
 +              toi_alloc_print_debug_stats();
 +              atomic_inc(&snapshot_device_available);
 +              mutex_unlock(&pm_mutex);
@@ -10322,8 +11675,8 @@ index 0000000..29a442c
 +      if (hibernate_or_resume) {
 +              block_dump_save = block_dump;
 +              block_dump = 0;
-+              set_cpus_allowed(current,
-+                              cpumask_of_cpu(first_cpu(cpu_online_map)));
++              set_cpus_allowed_ptr(current,
++                              &cpumask_of_cpu(first_cpu(cpu_online_map)));
 +      }
 +
 +      if (toi_initialise_modules_early(hibernate_or_resume))
@@ -10339,8 +11692,9 @@ index 0000000..29a442c
 +early_init_err:
 +      if (hibernate_or_resume) {
 +              block_dump_save = block_dump;
-+              set_cpus_allowed(current, CPU_MASK_ALL);
++              set_cpus_allowed_ptr(current, cpu_all_mask);
 +      }
++      toi_put_modules();
 +prehibernate_err:
 +      if (hibernate_or_resume)
 +              atomic_inc(&snapshot_device_available);
@@ -10478,7 +11832,7 @@ index 0000000..29a442c
 +      SNPRINTF("- Kernel Version : " UTS_RELEASE "\n");
 +      SNPRINTF("- Compiler vers. : %d.%d\n", __GNUC__, __GNUC_MINOR__);
 +      SNPRINTF("- Attempt number : %d\n", nr_hibernates);
-+      SNPRINTF("- Parameters     : %ld %ld %ld %d %d %ld\n",
++      SNPRINTF("- Parameters     : %ld %ld %ld %d %ld %ld\n",
 +                      toi_result,
 +                      toi_bkd.toi_action,
 +                      toi_bkd.toi_debug_state,
@@ -10542,6 +11896,8 @@ index 0000000..29a442c
 +      int i = 0;
 +      char *buffer = NULL;
 +
++      trap_non_toi_io = 0;
++
 +      if (get_debug_info)
 +              toi_prepare_status(DONT_CLEAR_BAR, "Cleaning up...");
 +
@@ -10573,7 +11929,7 @@ index 0000000..29a442c
 +          !test_result_state(TOI_ABORTED)) {
 +              toi_message(TOI_ANY_SECTION, TOI_LOW, 1,
 +                      "TuxOnIce: Not invalidating the image due "
-+                      "to Keep Image being enabled.\n");
++                      "to Keep Image being enabled.");
 +              set_result_state(TOI_KEPT_IMAGE);
 +      } else
 +              if (toiActiveAllocator)
@@ -10771,7 +12127,7 @@ index 0000000..29a442c
 +      toi_prepare_status(DONT_CLEAR_BAR, "Starting to save the image..");
 +
 +      toi_message(TOI_ANY_SECTION, TOI_LOW, 1,
-+              " - Final values: %d and %d.\n",
++              " - Final values: %d and %d.",
 +              pagedir1.size, pagedir2.size);
 +
 +      toi_cond_pause(1, "About to write pagedir2.");
@@ -10829,7 +12185,7 @@ index 0000000..29a442c
 +
 +      toi_cond_pause(1, "About to write pageset1.");
 +
-+      toi_message(TOI_ANY_SECTION, TOI_LOW, 1, "-- Writing pageset1\n");
++      toi_message(TOI_ANY_SECTION, TOI_LOW, 1, "-- Writing pageset1");
 +
 +      temp_result = write_pageset(&pagedir1);
 +
@@ -10920,6 +12276,8 @@ index 0000000..29a442c
 +                      !test_result_state(TOI_ABORTED))
 +              return 0;
 +
++      trap_non_toi_io = 1;
++
 +      return 1;
 +}
 +
@@ -10932,19 +12290,18 @@ index 0000000..29a442c
 + **/
 +int do_check_can_resume(void)
 +{
-+      char *buf = (char *) toi_get_zeroed_page(21, TOI_ATOMIC_GFP);
-+      int result = 0;
++      int result = -1;
 +
-+      if (!buf)
-+              return 0;
++      if (toi_activate_storage(0))
++              return -1;
 +
-+      /* Only interested in first byte, so throw away return code. */
-+      image_exists_read(buf, PAGE_SIZE);
++      if (!test_toi_state(TOI_RESUME_DEVICE_OK))
++              toi_attempt_to_parse_resume_device(1);
 +
-+      if (buf[0] == '1')
-+              result = 1;
++      if (toiActiveAllocator)
++              result = toiActiveAllocator->image_exists(1);
 +
-+      toi_free_page(21, (unsigned long) buf);
++      toi_deactivate_storage(0);
 +      return result;
 +}
 +EXPORT_SYMBOL_GPL(do_check_can_resume);
@@ -11293,7 +12650,7 @@ index 0000000..29a442c
 +              int i;
 +              for (i = 0; i < arg; i++)
 +                      if (argv[i] && argv[i] != channel)
-+                              toi_kfree(5, argv[i], sizeof (*argv[i]));
++                              toi_kfree(5, argv[i], sizeof(*argv[i]));
 +      }
 +
 +      toi_kfree(4, channel, sizeof(*channel));
@@ -11301,8 +12658,6 @@ index 0000000..29a442c
 +      return retval;
 +}
 +
-+extern int freezer_sync;
-+
 +/*
 + * This array contains entries that are automatically registered at
 + * boot. Modules and the console code register their own entries separately.
@@ -11323,8 +12678,8 @@ index 0000000..29a442c
 +                      NULL),
 +      SYSFS_BIT("ignore_rootfs", SYSFS_RW, &toi_bkd.toi_action,
 +                      TOI_IGNORE_ROOTFS, 0),
-+      SYSFS_INT("image_size_limit", SYSFS_RW, &image_size_limit, -2,
-+                      INT_MAX, 0, NULL),
++      SYSFS_LONG("image_size_limit", SYSFS_RW, &image_size_limit, -2,
++                      INT_MAX, 0),
 +      SYSFS_UL("last_result", SYSFS_RW, &toi_result, 0, 0, 0),
 +      SYSFS_BIT("no_multithreaded_io", SYSFS_RW, &toi_bkd.toi_action,
 +                      TOI_NO_MULTITHREADED_IO, 0),
@@ -11352,6 +12707,8 @@ index 0000000..29a442c
 +                      TOI_NO_PS2_IF_UNNEEDED, 0),
 +      SYSFS_BIT("late_cpu_hotplug", SYSFS_RW, &toi_bkd.toi_action,
 +                      TOI_LATE_CPU_HOTPLUG, 0),
++      SYSFS_STRING("binary_signature", SYSFS_READONLY,
++                      tuxonice_signature, 9, 0, NULL),
 +#ifdef CONFIG_TOI_KEEP_IMAGE
 +      SYSFS_BIT("keep_image", SYSFS_RW , &toi_bkd.toi_action, TOI_KEEP_IMAGE,
 +                      0),
@@ -11435,10 +12792,10 @@ index 0000000..29a442c
 +#endif
 diff --git a/kernel/power/tuxonice_io.c b/kernel/power/tuxonice_io.c
 new file mode 100644
-index 0000000..9fa1067
+index 0000000..0876f2d
 --- /dev/null
 +++ b/kernel/power/tuxonice_io.c
-@@ -0,0 +1,1534 @@
+@@ -0,0 +1,1537 @@
 +/*
 + * kernel/power/tuxonice_io.c
 + *
@@ -11461,6 +12818,7 @@ index 0000000..9fa1067
 +#include <linux/kthread.h>
 +#include <linux/cpu.h>
 +#include <linux/fs_struct.h>
++#include <linux/bio.h>
 +#include <asm/tlbflush.h>
 +
 +#include "tuxonice.h"
@@ -11907,15 +13265,12 @@ index 0000000..9fa1067
 +      }
 +
 +      /*
-+       * See toi_bio_read_page in tuxonice_block_io.c:
++       * See toi_bio_read_page in tuxonice_bio.c:
 +       * read the next page in the image.
 +       */
 +      return first_filter->read_page(write_pfn, buffer, &buf_size);
 +}
 +
-+/**
-+ * 
-+ **/
 +static void use_read_page(unsigned long write_pfn, struct page *buffer)
 +{
 +      struct page *final_page = pfn_to_page(write_pfn),
@@ -12140,7 +13495,8 @@ index 0000000..9fa1067
 +      clear_toi_state(TOI_IO_STOPPED);
 +      memory_bm_position_reset(io_map);
 +
-+      if (!test_action_state(TOI_NO_MULTITHREADED_IO))
++      if (!test_action_state(TOI_NO_MULTITHREADED_IO) &&
++              (write || !toi_force_no_multithreaded))
 +              num_other_threads = start_other_threads();
 +
 +      if (!num_other_threads || !toiActiveAllocator->io_flusher ||
@@ -12175,7 +13531,7 @@ index 0000000..9fa1067
 +                                      "%ld.\n", next);
 +                      do {
 +                              cpu_relax();
-+                      } while(0);
++                      } while (0);
 +              }
 +      }
 +
@@ -12612,6 +13968,7 @@ index 0000000..9fa1067
 +{
 +      freeze_result = freeze_processes();
 +      wake_up(&freeze_wait);
++      trap_non_toi_io = 1;
 +}
 +
 +static DECLARE_WORK(freeze_work, do_freeze);
@@ -12638,7 +13995,7 @@ index 0000000..9fa1067
 +
 +      /* Check for an image */
 +      result = toiActiveAllocator->image_exists(1);
-+      if (!result) {
++      if (result != 1) {
 +              result = -ENODATA;
 +              noresume_reset_modules();
 +              printk(KERN_INFO "TuxOnIce: No image found.\n");
@@ -12717,9 +14074,11 @@ index 0000000..9fa1067
 +      memcpy((char *) &pagedir1,
 +              (char *) &toi_header->pagedir, sizeof(pagedir1));
 +      toi_result = toi_header->param0;
-+      toi_bkd.toi_action = toi_header->param1;
-+      toi_bkd.toi_debug_state = toi_header->param2;
-+      toi_bkd.toi_default_console_level = toi_header->param3;
++      if (!toi_bkd.toi_debug_state) {
++              toi_bkd.toi_action = toi_header->param1;
++              toi_bkd.toi_debug_state = toi_header->param2;
++              toi_bkd.toi_default_console_level = toi_header->param3;
++      }
 +      clear_toi_state(TOI_IGNORE_LOGLEVEL);
 +      pagedir2.size = toi_header->pageset_2_size;
 +      for (i = 0; i < 4; i++)
@@ -12763,14 +14122,14 @@ index 0000000..9fa1067
 +      toi_cond_pause(1, "About to read original pageset1 locations.");
 +
 +      /*
-+       * See _toi_rw_header_chunk in tuxonice_block_io.c:
++       * See _toi_rw_header_chunk in tuxonice_bio.c:
 +       * Initialize pageset1_map by reading the map from the image.
 +       */
 +      if (memory_bm_read(pageset1_map, toiActiveAllocator->rw_header_chunk))
 +              goto out_thaw;
 +
 +      /*
-+       * See toi_rw_cleanup in tuxonice_block_io.c:
++       * See toi_rw_cleanup in tuxonice_bio.c:
 +       * Clean up after reading the header.
 +       */
 +      result = toiActiveAllocator->read_header_cleanup();
@@ -12817,6 +14176,7 @@ index 0000000..9fa1067
 +
 +out_thaw:
 +      wait_event(freeze_wait, freeze_result != FREEZE_IN_PROGRESS);
++      trap_non_toi_io = 0;
 +      thaw_processes();
 +      usermodehelper_enable();
 +out_enable_nonboot_cpus:
@@ -13051,10 +14411,10 @@ index 0000000..01b3db6
 +extern int toi_bio_queue_flusher_should_finish;
 diff --git a/kernel/power/tuxonice_modules.c b/kernel/power/tuxonice_modules.c
 new file mode 100644
-index 0000000..c650f5c
+index 0000000..6599405
 --- /dev/null
 +++ b/kernel/power/tuxonice_modules.c
-@@ -0,0 +1,494 @@
+@@ -0,0 +1,492 @@
 +/*
 + * kernel/power/tuxonice_modules.c
 + *
@@ -13070,7 +14430,9 @@ index 0000000..c650f5c
 +
 +LIST_HEAD(toi_filters);
 +LIST_HEAD(toiAllocators);
++
 +LIST_HEAD(toi_modules);
++EXPORT_SYMBOL_GPL(toi_modules);
 +
 +struct toi_module_ops *toiActiveAllocator;
 +EXPORT_SYMBOL_GPL(toiActiveAllocator);
@@ -13292,6 +14654,7 @@ index 0000000..c650f5c
 +              break;
 +      case MISC_MODULE:
 +      case MISC_HIDDEN_MODULE:
++      case BIO_ALLOCATOR_MODULE:
 +              break;
 +      default:
 +              printk(KERN_ERR "Hmmm. Module '%s' has an invalid type."
@@ -13373,6 +14736,7 @@ index 0000000..c650f5c
 +              break;
 +      case MISC_MODULE:
 +      case MISC_HIDDEN_MODULE:
++      case BIO_ALLOCATOR_MODULE:
 +              break;
 +      default:
 +              printk(KERN_ERR "Module '%s' has an invalid type."
@@ -13402,6 +14766,7 @@ index 0000000..c650f5c
 +              break;
 +      case MISC_MODULE:
 +      case MISC_HIDDEN_MODULE:
++      case BIO_ALLOCATOR_MODULE:
 +              break;
 +      default:
 +              printk(KERN_ERR "Module '%s' has an invalid type."
@@ -13430,9 +14795,6 @@ index 0000000..c650f5c
 +              if (this_module->early != early)
 +                      continue;
 +              if (this_module->initialise) {
-+                      toi_message(TOI_MEMORY, TOI_MEDIUM, 1,
-+                              "Initialising module %s.\n",
-+                              this_module->name);
 +                      result = this_module->initialise(starting_cycle);
 +                      if (result) {
 +                              toi_cleanup_modules(starting_cycle);
@@ -13457,12 +14819,8 @@ index 0000000..c650f5c
 +      list_for_each_entry(this_module, &toi_modules, module_list) {
 +              if (!this_module->enabled || !this_module->initialised)
 +                      continue;
-+              if (this_module->cleanup) {
-+                      toi_message(TOI_MEMORY, TOI_MEDIUM, 1,
-+                              "Cleaning up module %s.\n",
-+                              this_module->name);
++              if (this_module->cleanup)
 +                      this_module->cleanup(finishing_cycle);
-+              }
 +              this_module->initialised = 0;
 +      }
 +}
@@ -13551,10 +14909,10 @@ index 0000000..c650f5c
 +}
 diff --git a/kernel/power/tuxonice_modules.h b/kernel/power/tuxonice_modules.h
 new file mode 100644
-index 0000000..d81087c
+index 0000000..5023ae9
 --- /dev/null
 +++ b/kernel/power/tuxonice_modules.h
-@@ -0,0 +1,181 @@
+@@ -0,0 +1,186 @@
 +/*
 + * kernel/power/tuxonice_modules.h
 + *
@@ -13587,7 +14945,8 @@ index 0000000..d81087c
 +enum {
 +      FILTER_MODULE,
 +      WRITER_MODULE,
-+      MISC_MODULE, /* Block writer, eg. */
++      BIO_ALLOCATOR_MODULE,
++      MISC_MODULE,
 +      MISC_HIDDEN_MODULE,
 +};
 +
@@ -13647,6 +15006,7 @@ index 0000000..d81087c
 +
 +      unsigned long (*storage_available) (void);
 +      void (*reserve_header_space) (unsigned long space_requested);
++      int (*register_storage) (void);
 +      int (*allocate_storage) (unsigned long space_requested);
 +      unsigned long (*storage_allocated) (void);
 +
@@ -13699,6 +15059,9 @@ index 0000000..d81087c
 +      /* Sysfs Data */
 +      struct toi_sysfs_data *sysfs_data;
 +      int num_sysfs_entries;
++
++      /* Block I/O allocator */
++      struct toi_bio_allocator_ops *bio_allocator_ops;
 +};
 +
 +extern int toi_num_modules, toiNumAllocators;
@@ -14710,10 +16073,10 @@ index 0000000..610625d
 +#endif
 diff --git a/kernel/power/tuxonice_power_off.c b/kernel/power/tuxonice_power_off.c
 new file mode 100644
-index 0000000..9cdb489
+index 0000000..63bb90b
 --- /dev/null
 +++ b/kernel/power/tuxonice_power_off.c
-@@ -0,0 +1,282 @@
+@@ -0,0 +1,285 @@
 +/*
 + * kernel/power/tuxonice_power_off.c
 + *
@@ -14783,6 +16146,8 @@ index 0000000..9cdb489
 +                      panic("Attempt to reload pagedir 2 failed. "
 +                                      "Try rebooting.");
 +
++              pm_prepare_console();
++
 +              error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
 +              if (!error) {
 +                      error = suspend_devices_and_enter(PM_SUSPEND_MEM);
@@ -14790,6 +16155,7 @@ index 0000000..9cdb489
 +                              did_suspend_to_both = 1;
 +              }
 +              pm_notifier_call_chain(PM_POST_SUSPEND);
++              pm_restore_console();
 +
 +              /* Success - we're now post-resume-from-ram */
 +              if (did_suspend_to_both)
@@ -15028,10 +16394,10 @@ index 0000000..a85633a
 +extern void platform_restore_cleanup(int platform_mode);
 diff --git a/kernel/power/tuxonice_prepare_image.c b/kernel/power/tuxonice_prepare_image.c
 new file mode 100644
-index 0000000..7f1d76c
+index 0000000..2626c0f
 --- /dev/null
 +++ b/kernel/power/tuxonice_prepare_image.c
-@@ -0,0 +1,1076 @@
+@@ -0,0 +1,1079 @@
 +/*
 + * kernel/power/tuxonice_prepare_image.c
 + *
@@ -15064,9 +16430,9 @@ index 0000000..7f1d76c
 +#include "tuxonice_modules.h"
 +#include "tuxonice_io.h"
 +#include "tuxonice_ui.h"
-+#include "tuxonice_extent.h"
 +#include "tuxonice_prepare_image.h"
 +#include "tuxonice.h"
++#include "tuxonice_extent.h"
 +#include "tuxonice_checksum.h"
 +#include "tuxonice_sysfs.h"
 +#include "tuxonice_alloc.h"
@@ -15074,8 +16440,9 @@ index 0000000..7f1d76c
 +
 +static unsigned long num_nosave, main_storage_allocated, storage_limit,
 +          header_storage_needed;
-+unsigned long extra_pd1_pages_allowance = CONFIG_TOI_DEFAULT_EXTRA_PAGES_ALLOWANCE;
-+int image_size_limit;
++unsigned long extra_pd1_pages_allowance =
++      CONFIG_TOI_DEFAULT_EXTRA_PAGES_ALLOWANCE;
++long image_size_limit;
 +static int no_ps2_needed;
 +
 +struct attention_list {
@@ -15531,12 +16898,12 @@ index 0000000..7f1d76c
 +      int use_soft_limit = use_image_size_limit && image_size_limit > 0;
 +      unsigned long current_size = current_image_size(),
 +                    soft_limit = use_soft_limit ? (image_size_limit << 8) : 0,
++                    to_free = use_soft_limit ? (current_size > soft_limit ?
++                                    current_size - soft_limit : 0) : 0,
 +                    storage_limit = storage_still_required(),
 +                    ram_limit = ram_still_required(),
-+                    first_max = max(soft_limit, storage_limit);
++                    first_max = max(to_free, storage_limit);
 +
-+      printk("Use soft limit is %d. Current size is %lu. Soft limit is %lu. Ram limit %lu. First max %lu.\n",
-+                      use_soft_limit, current_size, soft_limit, ram_limit, first_max);
 +      return max(first_max, ram_limit);
 +}
 +
@@ -15561,8 +16928,8 @@ index 0000000..7f1d76c
 +static int image_not_ready(int use_image_size_limit)
 +{
 +      toi_message(TOI_EAT_MEMORY, TOI_LOW, 1,
-+              "Amount still needed (%ld) > 0:%d,"
-+              " Storage allocd: %ld < %ld: %d.\n",
++              "Amount still needed (%lu) > 0:%u,"
++              " Storage allocd: %lu < %lu: %u.\n",
 +                      amount_needed(use_image_size_limit),
 +                      (amount_needed(use_image_size_limit) > 0),
 +                      main_storage_allocated,
@@ -15639,9 +17006,9 @@ index 0000000..7f1d76c
 +{
 +      char buffer[255];
 +      snprintf(buffer, 254,
-+              "Free:%ld(%ld). Sets:%ld(%ld),%ld(%ld). "
-+              "Nosave:%ld-%ld=%ld. Storage:%lu/%lu(%lu=>%lu). "
-+              "Needed:%ld,%ld,%ld(%d,%ld,%ld,%ld) (PS2:%s)\n",
++              "Free:%lu(%lu). Sets:%lu(%lu),%lu(%lu). "
++              "Nosave:%lu-%lu=%lu. Storage:%lu/%lu(%lu=>%lu). "
++              "Needed:%lu,%lu,%lu(%u,%lu,%lu,%ld) (PS2:%s)\n",
 +
 +              /* Free */
 +              real_nr_free_pages(all_zones_mask),
@@ -15666,7 +17033,7 @@ index 0000000..7f1d76c
 +              any_to_free(1),
 +              MIN_FREE_RAM, toi_memory_for_modules(0),
 +              extra_pd1_pages_allowance,
-+              ((unsigned long) image_size_limit) << 8,
++              image_size_limit,
 +
 +              need_pageset2() ? "yes" : "no");
 +
@@ -15713,9 +17080,11 @@ index 0000000..7f1d76c
 +                      struct per_cpu_pageset *pset = zone_pcp(zone, cpu);
 +                      struct per_cpu_pages *pcp = &pset->pcp;
 +                      struct page *page;
++                      int t;
 +
-+                      list_for_each_entry(page, &pcp->list, lru)
-+                              SetPageNosaveFree(page);
++                      for (t = 0; t < MIGRATE_PCPTYPES; t++)
++                              list_for_each_entry(page, &pcp->lists[t], lru)
++                                      SetPageNosaveFree(page);
 +              }
 +
 +              spin_unlock_irqrestore(&zone->lock, flags);
@@ -15899,8 +17268,7 @@ index 0000000..7f1d76c
 +              storage_limit = toiActiveAllocator->storage_available();
 +              seek = min(storage_limit, main_storage_needed(0, 0));
 +
-+              //toiActiveAllocator->allocate_storage(seek);
-+              result = toiActiveAllocator->allocate_storage(storage_limit);
++              result = toiActiveAllocator->allocate_storage(seek);
 +              if (result)
 +                      printk("Failed to allocate storage (%d).\n", result);
 +
@@ -16009,8 +17377,9 @@ index 0000000..7f1d76c
 +
 +              amount_wanted = amount_needed(1);
 +
-+              printk("Asked shrink_all_memory for %ld pages, got %ld.\n",
-+                              request, request - amount_wanted);
++              printk(KERN_DEBUG "Asked shrink_all_memory for %ld pages,"
++                              "got %ld.\n", request,
++                              request - amount_wanted);
 +
 +              toi_cond_pause(0, NULL);
 +
@@ -16110,7 +17479,7 @@ index 0000000..7f1d76c
 +}
 diff --git a/kernel/power/tuxonice_prepare_image.h b/kernel/power/tuxonice_prepare_image.h
 new file mode 100644
-index 0000000..35ddadf
+index 0000000..fc4ed05
 --- /dev/null
 +++ b/kernel/power/tuxonice_prepare_image.h
 @@ -0,0 +1,36 @@
@@ -16128,7 +17497,7 @@ index 0000000..35ddadf
 +extern int toi_prepare_image(void);
 +extern void toi_recalculate_image_contents(int storage_available);
 +extern unsigned long real_nr_free_pages(unsigned long zone_idx_mask);
-+extern int image_size_limit;
++extern long image_size_limit;
 +extern void toi_free_extra_pagedir_memory(void);
 +extern unsigned long extra_pd1_pages_allowance;
 +extern void free_attention_list(void);
@@ -16491,10 +17860,10 @@ index 0000000..24f8e8a
 +};
 diff --git a/kernel/power/tuxonice_swap.c b/kernel/power/tuxonice_swap.c
 new file mode 100644
-index 0000000..10e6280
+index 0000000..30890aa
 --- /dev/null
 +++ b/kernel/power/tuxonice_swap.c
-@@ -0,0 +1,1351 @@
+@@ -0,0 +1,478 @@
 +/*
 + * kernel/power/tuxonice_swap.c
 + *
@@ -16511,7 +17880,7 @@ index 0000000..10e6280
 +#include <linux/swapops.h>
 +#include <linux/swap.h>
 +#include <linux/syscalls.h>
-+#include <scsi/scsi_scan.h>
++#include <linux/uuid.h>
 +
 +#include "tuxonice.h"
 +#include "tuxonice_sysfs.h"
@@ -16519,492 +17888,88 @@ index 0000000..10e6280
 +#include "tuxonice_io.h"
 +#include "tuxonice_ui.h"
 +#include "tuxonice_extent.h"
-+#include "tuxonice_block_io.h"
++#include "tuxonice_bio.h"
 +#include "tuxonice_alloc.h"
 +#include "tuxonice_builtin.h"
 +
 +static struct toi_module_ops toi_swapops;
 +
-+/* --- Struct of pages stored on disk */
-+
-+struct sig_data {
-+      dev_t device;
-+      unsigned long sector;
-+      int resume_attempted;
-+      int orig_sig_type;
-+};
-+
-+union diskpage {
-+      union swap_header swh;  /* swh.magic is the only member used */
-+      struct sig_data sig_data;
-+};
-+
-+union p_diskpage {
-+      union diskpage *pointer;
-+      char *ptr;
-+      unsigned long address;
-+};
-+
-+enum {
-+      IMAGE_SIGNATURE,
-+      NO_IMAGE_SIGNATURE,
-+      TRIED_RESUME,
-+      NO_TRIED_RESUME,
-+};
-+
-+/*
-+ * Both of these point to versions of the swap header page. original_sig points
-+ * to the data we read from disk at the start of hibernating or checking whether
-+ * to resume. no_image is the page stored in the image header, showing what the
-+ * swap header page looked like at the start of hibernating.
-+ */
-+static char *current_signature_page;
-+static char no_image_signature_contents[sizeof(struct sig_data)];
-+
-+/* Devices used for swap */
-+static struct toi_bdev_info devinfo[MAX_SWAPFILES];
-+
-+/* Extent chains for swap & blocks */
-+static struct hibernate_extent_chain swapextents;
-+static struct hibernate_extent_chain block_chain[MAX_SWAPFILES];
-+
-+static dev_t header_dev_t;
-+static struct block_device *header_block_device;
-+static unsigned long headerblock;
-+
-+/* For swapfile automatically swapon/off'd. */
-+static char swapfilename[32] = "";
-+static int toi_swapon_status;
-+
-+/* Header Page Information */
-+static unsigned long header_pages_reserved;
-+
-+/* Swap Pages */
-+static unsigned long swap_pages_allocated;
-+
-+/* User Specified Parameters. */
-+
-+static unsigned long resume_firstblock;
-+static dev_t resume_swap_dev_t;
-+static struct block_device *resume_block_device;
-+
-+static struct sysinfo swapinfo;
-+
-+/* Block devices open. */
-+struct bdev_opened {
-+      dev_t device;
-+      struct block_device *bdev;
-+};
-+
-+/*
-+ * Entry MAX_SWAPFILES is the resume block device, which may
-+ * be a swap device not enabled when we hibernate.
-+ * Entry MAX_SWAPFILES + 1 is the header block device, which
-+ * is needed before we find out which slot it occupies.
-+ *
-+ * We use a separate struct to devInfo so that we can track
-+ * the bdevs we open, because if we need to abort resuming
-+ * prior to the atomic restore, they need to be closed, but
-+ * closing them after sucessfully resuming would be wrong.
-+ */
-+static struct bdev_opened *bdevs_opened[MAX_SWAPFILES + 2];
-+
-+/**
-+ * close_bdev: Close a swap bdev.
-+ *
-+ * int: The swap entry number to close.
-+ */
-+static void close_bdev(int i)
-+{
-+      struct bdev_opened *this = bdevs_opened[i];
-+
-+      if (!this)
-+              return;
-+
-+      blkdev_put(this->bdev, FMODE_READ | FMODE_NDELAY);
-+      toi_kfree(8, this, sizeof(*this));
-+      bdevs_opened[i] = NULL;
-+}
-+
-+/**
-+ * close_bdevs: Close all bdevs we opened.
-+ *
-+ * Close all bdevs that we opened and reset the related vars.
-+ */
-+static void close_bdevs(void)
-+{
-+      int i;
-+
-+      for (i = 0; i < MAX_SWAPFILES + 2; i++)
-+              close_bdev(i);
-+
-+      resume_block_device = NULL;
-+      header_block_device = NULL;
-+}
-+
-+/**
-+ * open_bdev: Open a bdev at resume time.
-+ *
-+ * index: The swap index. May be MAX_SWAPFILES for the resume_dev_t
-+ * (the user can have resume= pointing at a swap partition/file that isn't
-+ * swapon'd when they hibernate. MAX_SWAPFILES+1 for the first page of the
-+ * header. It will be from a swap partition that was enabled when we hibernated,
-+ * but we don't know it's real index until we read that first page.
-+ * dev_t: The device major/minor.
-+ * display_errs: Whether to try to do this quietly.
-+ *
-+ * We stored a dev_t in the image header. Open the matching device without
-+ * requiring /dev/<whatever> in most cases and record the details needed
-+ * to close it later and avoid duplicating work.
-+ */
-+static struct block_device *open_bdev(int index, dev_t device, int display_errs)
-+{
-+      struct bdev_opened *this;
-+      struct block_device *bdev;
-+
-+      if (bdevs_opened[index]) {
-+              if (bdevs_opened[index]->device == device)
-+                      return bdevs_opened[index]->bdev;
-+
-+              close_bdev(index);
-+      }
-+
-+      bdev = toi_open_by_devnum(device, FMODE_READ | FMODE_NDELAY);
-+
-+      if (IS_ERR(bdev) || !bdev) {
-+              if (display_errs)
-+                      toi_early_boot_message(1, TOI_CONTINUE_REQ,
-+                              "Failed to get access to block device "
-+                              "\"%x\" (error %d).\n Maybe you need "
-+                              "to run mknod and/or lvmsetup in an "
-+                              "initrd/ramfs?", device, bdev);
-+              return ERR_PTR(-EINVAL);
-+      }
-+
-+      this = toi_kzalloc(8, sizeof(struct bdev_opened), GFP_KERNEL);
-+      if (!this) {
-+              printk(KERN_WARNING "TuxOnIce: Failed to allocate memory for "
-+                              "opening a bdev.");
-+              blkdev_put(bdev, FMODE_READ | FMODE_NDELAY);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      bdevs_opened[index] = this;
-+      this->device = device;
-+      this->bdev = bdev;
-+
-+      return bdev;
-+}
-+
-+/**
-+ * enable_swapfile: Swapon the user specified swapfile prior to hibernating.
-+ *
-+ * Activate the given swapfile if it wasn't already enabled. Remember whether
-+ * we really did swapon it for swapoffing later.
-+ */
-+static void enable_swapfile(void)
-+{
-+      int activateswapresult = -EINVAL;
-+
-+      if (swapfilename[0]) {
-+              /* Attempt to swap on with maximum priority */
-+              activateswapresult = sys_swapon(swapfilename, 0xFFFF);
-+              if (activateswapresult && activateswapresult != -EBUSY)
-+                      printk("TuxOnIce: The swapfile/partition specified by "
-+                              "/sys/power/tuxonice/swap/swapfile "
-+                              "(%s) could not be turned on (error %d). "
-+                              "Attempting to continue.\n",
-+                              swapfilename, activateswapresult);
-+              if (!activateswapresult)
-+                      toi_swapon_status = 1;
-+      }
-+}
-+
-+/**
-+ * disable_swapfile: Swapoff any file swaponed at the start of the cycle.
-+ *
-+ * If we did successfully swapon a file at the start of the cycle, swapoff
-+ * it now (finishing up).
-+ */
-+static void disable_swapfile(void)
-+{
-+      if (!toi_swapon_status)
-+              return;
-+
-+      sys_swapoff(swapfilename);
-+      toi_swapon_status = 0;
-+}
-+
-+/**
-+ * try_to_parse_resume_device: Try to parse resume=
-+ *
-+ * Any "swap:" has been stripped away and we just have the path to deal with.
-+ * We attempt to do name_to_dev_t, open and stat the file. Having opened the
-+ * file, get the struct block_device * to match.
-+ */
-+static int try_to_parse_resume_device(char *commandline, int quiet)
-+{
-+      struct kstat stat;
-+      int error = 0;
-+
-+      resume_swap_dev_t = name_to_dev_t(commandline);
-+      if (!resume_swap_dev_t) {
-+              wait_for_device_probe();
-+              scsi_complete_async_scans();
-+              resume_swap_dev_t = name_to_dev_t(commandline);
-+      }
-+
-+      if (!resume_swap_dev_t) {
-+              struct file *file = filp_open(commandline,
-+                              O_RDONLY|O_LARGEFILE, 0);
-+
-+              if (!IS_ERR(file) && file) {
-+                      vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
-+                      filp_close(file, NULL);
-+              } else
-+                      error = vfs_stat(commandline, &stat);
-+              if (!error)
-+                      resume_swap_dev_t = stat.rdev;
-+      }
-+
-+      if (!resume_swap_dev_t) {
-+              if (quiet)
-+                      return 1;
-+
-+              if (test_toi_state(TOI_TRYING_TO_RESUME))
-+                      toi_early_boot_message(1, toi_translate_err_default,
-+                        "Failed to translate \"%s\" into a device id.\n",
-+                        commandline);
-+              else
-+                      printk("TuxOnIce: Can't translate \"%s\" into a device "
-+                                      "id yet.\n", commandline);
-+              return 1;
-+      }
-+
-+      resume_block_device = open_bdev(MAX_SWAPFILES, resume_swap_dev_t, 0);
-+      if (IS_ERR(resume_block_device)) {
-+              if (!quiet)
-+                      toi_early_boot_message(1, TOI_CONTINUE_REQ,
-+                              "Failed to get access to \"%s\", where"
-+                              " the swap header should be found.",
-+                              commandline);
-+              return 1;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-+ * If we have read part of the image, we might have filled  memory with
-+ * data that should be zeroed out.
-+ */
-+static void toi_swap_noresume_reset(void)
-+{
-+      toi_bio_ops.rw_cleanup(READ);
-+      memset((char *) &devinfo, 0, sizeof(devinfo));
-+}
-+
-+static int get_current_signature(void)
-+{
-+      if (!current_signature_page) {
-+              current_signature_page = (char *) toi_get_zeroed_page(38,
-+                      TOI_ATOMIC_GFP);
-+              if (!current_signature_page)
-+                      return -ENOMEM;
-+      }
-+
-+      return toi_bio_ops.bdev_page_io(READ, resume_block_device,
-+              resume_firstblock, virt_to_page(current_signature_page));
-+}
-+
-+static int parse_signature(void)
-+{
-+      union p_diskpage swap_header_page;
-+      struct sig_data *sig;
-+      int type;
-+      char *swap_header;
-+      const char *sigs[] = {
-+              "SWAP-SPACE", "SWAPSPACE2", "S1SUSP", "S2SUSP", "S1SUSPEND"
-+      };
-+
-+      int result = get_current_signature();
-+      if (result)
-+              return result;
-+
-+      swap_header_page = (union p_diskpage) current_signature_page;
-+      sig = (struct sig_data *) current_signature_page;
-+      swap_header = swap_header_page.pointer->swh.magic.magic;
-+
-+      for (type = 0; type < 5; type++)
-+              if (!memcmp(sigs[type], swap_header, strlen(sigs[type])))
-+                      return type;
-+
-+      if (memcmp(tuxonice_signature, swap_header, sizeof(tuxonice_signature)))
-+              return -1;
-+
-+      header_dev_t = sig->device;
-+      clear_toi_state(TOI_RESUMED_BEFORE);
-+      if (sig->resume_attempted)
-+              set_toi_state(TOI_RESUMED_BEFORE);
-+      headerblock = sig->sector;
-+
-+      return 10;
-+}
-+
-+static void forget_signatures(void)
-+{
-+      if (current_signature_page) {
-+              toi_free_page(38, (unsigned long) current_signature_page);
-+              current_signature_page = NULL;
-+      }
-+}
-+
-+/*
-+ * write_modified_signature
-+ *
-+ * Write a (potentially) modified signature page without forgetting the
-+ * original contents.
-+ */
-+static int write_modified_signature(int modification)
-+{
-+      union p_diskpage swap_header_page;
-+      struct swap_info_struct *si;
-+      int result;
-+      char *orig_sig;
-+
-+      /* In case we haven't already */
-+      result = get_current_signature();
-+
-+      if (result)
-+              return result;
-+
-+      swap_header_page.address = toi_get_zeroed_page(38, TOI_ATOMIC_GFP);
-+
-+      if (!swap_header_page.address)
-+              return -ENOMEM;
-+
-+      memcpy(swap_header_page.ptr, current_signature_page, PAGE_SIZE);
-+
-+      switch (modification) {
-+      case IMAGE_SIGNATURE:
-+
-+              memcpy(no_image_signature_contents, swap_header_page.ptr,
-+                              sizeof(no_image_signature_contents));
-+
-+              /* Get the details of the header first page. */
-+              toi_extent_state_goto_start(&toi_writer_posn);
-+              toi_bio_ops.forward_one_page(1, 1);
-+
-+              si = get_swap_info_struct(toi_writer_posn.current_chain);
-+
-+              /* Prepare the signature */
-+              swap_header_page.pointer->sig_data.device = si->bdev->bd_dev;
-+              swap_header_page.pointer->sig_data.sector =
-+                      toi_writer_posn.current_offset;
-+              swap_header_page.pointer->sig_data.resume_attempted = 0;
-+              swap_header_page.pointer->sig_data.orig_sig_type =
-+                      parse_signature();
-+
-+              memcpy(swap_header_page.pointer->swh.magic.magic,
-+                              tuxonice_signature, sizeof(tuxonice_signature));
-+
-+              break;
-+      case NO_IMAGE_SIGNATURE:
-+              if (!swap_header_page.pointer->sig_data.orig_sig_type)
-+                      orig_sig = "SWAP-SPACE";
-+              else
-+                      orig_sig = "SWAPSPACE2";
-+
-+              memcpy(swap_header_page.pointer->swh.magic.magic, orig_sig, 10);
-+              memcpy(swap_header_page.ptr, no_image_signature_contents,
-+                              sizeof(no_image_signature_contents));
-+              break;
-+      case TRIED_RESUME:
-+              swap_header_page.pointer->sig_data.resume_attempted = 1;
-+              break;
-+      case NO_TRIED_RESUME:
-+              swap_header_page.pointer->sig_data.resume_attempted = 0;
-+              break;
-+      }
-+
-+      result = toi_bio_ops.bdev_page_io(WRITE, resume_block_device,
-+              resume_firstblock, virt_to_page(swap_header_page.address));
-+
-+      memcpy(current_signature_page, swap_header_page.ptr, PAGE_SIZE);
++/* For swapfile automatically swapon/off'd. */
++static char swapfilename[255] = "";
++static int toi_swapon_status;
 +
-+      toi_free_page(38, swap_header_page.address);
++/* Swap Pages */
++static unsigned long swap_allocated;
 +
-+      return result;
-+}
++static struct sysinfo swapinfo;
 +
-+/*
-+ * apply_header_reservation
++/**
++ * enable_swapfile: Swapon the user specified swapfile prior to hibernating.
++ *
++ * Activate the given swapfile if it wasn't already enabled. Remember whether
++ * we really did swapon it for swapoffing later.
 + */
-+static int apply_header_reservation(void)
++static void enable_swapfile(void)
 +{
-+      unsigned long i;
-+
-+      toi_extent_state_goto_start(&toi_writer_posn);
-+
-+      printk("Applying header reservation for %lu pages.\n",
-+                      header_pages_reserved);
-+
-+      if (!header_pages_reserved)
-+              return 0;
-+
-+      for (i = 0; i < header_pages_reserved; i++)
-+              if (toi_bio_ops.forward_one_page(1, 0)) {
-+                      printk("Failed to advance to page %lu in reserving "
-+                                      "space for the header.\n", i);
-+                      return -ENOSPC;
-+              }
-+
-+      /* The end of header pages will be the start of pageset 2;
-+       * we are now sitting on the first pageset2 page. */
-+      toi_extent_state_save(&toi_writer_posn, &toi_writer_posn_save[2]);
-+      printk("Done.\n");
-+      return 0;
-+}
++      int activateswapresult = -EINVAL;
 +
-+static void toi_swap_reserve_header_space(unsigned long request)
-+{
-+      header_pages_reserved = request;
++      if (swapfilename[0]) {
++              /* Attempt to swap on with maximum priority */
++              activateswapresult = sys_swapon(swapfilename, 0xFFFF);
++              if (activateswapresult && activateswapresult != -EBUSY)
++                      printk(KERN_ERR "TuxOnIce: The swapfile/partition "
++                              "specified by /sys/power/tuxonice/swap/swapfile"
++                              " (%s) could not be turned on (error %d). "
++                              "Attempting to continue.\n",
++                              swapfilename, activateswapresult);
++              if (!activateswapresult)
++                      toi_swapon_status = 1;
++      }
 +}
 +
-+static void free_block_chains(void)
++/**
++ * disable_swapfile: Swapoff any file swaponed at the start of the cycle.
++ *
++ * If we did successfully swapon a file at the start of the cycle, swapoff
++ * it now (finishing up).
++ */
++static void disable_swapfile(void)
 +{
-+      int i;
++      if (!toi_swapon_status)
++              return;
 +
-+      for (i = 0; i < MAX_SWAPFILES; i++)
-+              if (block_chain[i].first)
-+                      toi_put_extent_chain(&block_chain[i]);
++      sys_swapoff(swapfilename);
++      toi_swapon_status = 0;
 +}
 +
-+static int add_blocks_to_extent_chain(int chain, unsigned long start, unsigned long end)
++static int add_blocks_to_extent_chain(struct toi_bdev_info *chain,
++              unsigned long start, unsigned long end)
 +{
 +      if (test_action_state(TOI_TEST_BIO))
-+              printk(KERN_INFO "Adding extent chain %d %lu-%lu.\n", chain,
-+                              start << devinfo[chain].bmap_shift,
-+                              end << devinfo[chain].bmap_shift);
-+
-+      if (toi_add_to_extent_chain(&block_chain[chain], start, end)) {
-+              free_block_chains();
-+              return -ENOMEM;
-+      }
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Adding extent %lu-%lu to "
++                              "chain %p.", start << chain->bmap_shift,
++                              end << chain->bmap_shift, chain);
 +
-+      return 0;
++      return toi_add_to_extent_chain(&chain->blocks, start, end);
 +}
 +
 +
-+static int get_main_pool_phys_params(void)
++static int get_main_pool_phys_params(struct toi_bdev_info *chain)
 +{
 +      struct hibernate_extent *extentpointer = NULL;
 +      unsigned long address, extent_min = 0, extent_max = 0;
-+      int last_chain = -1;
++      int empty = 1;
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "get main pool phys params for "
++                      "chain %d.", chain->allocator_index);
++
++      if (!chain->allocations.first)
++              return 0;
 +
-+      free_block_chains();
++      if (chain->blocks.first)
++              toi_put_extent_chain(&chain->blocks);
 +
-+      toi_extent_for_each(&swapextents, extentpointer, address) {
++      toi_extent_for_each(&chain->allocations, extentpointer, address) {
 +              swp_entry_t swap_address = (swp_entry_t) { address };
 +              pgoff_t offset = swp_offset(swap_address);
 +              unsigned swapfilenum = swp_type(swap_address);
@@ -17012,17 +17977,18 @@ index 0000000..10e6280
 +                      get_swap_info_struct(swapfilenum);
 +              sector_t new_sector = map_swap_page(sis, offset);
 +
-+              if (devinfo[swapfilenum].ignored)
++              if (empty) {
++                      empty = 0;
++                      extent_min = extent_max = new_sector;
 +                      continue;
++              }
 +
-+              if (last_chain >= 0 && new_sector == extent_max + 1 &&
-+                  last_chain == swapfilenum) {
++              if (new_sector == extent_max + 1) {
 +                      extent_max++;
 +                      continue;
 +              }
 +
-+              if (last_chain >= 0 && add_blocks_to_extent_chain(last_chain,
-+                                      extent_min, extent_max)) {
++              if (add_blocks_to_extent_chain(chain, extent_min, extent_max)) {
 +                      printk(KERN_ERR "Out of memory while making block "
 +                                      "chains.\n");
 +                      return -ENOMEM;
@@ -17030,32 +17996,15 @@ index 0000000..10e6280
 +
 +              extent_min = new_sector;
 +              extent_max = new_sector;
-+              last_chain = swapfilenum;
 +      }
 +
-+      if (last_chain > -1 && add_blocks_to_extent_chain(last_chain,
-+                              extent_min, extent_max)) {
++      if (!empty &&
++          add_blocks_to_extent_chain(chain, extent_min, extent_max)) {
 +              printk(KERN_ERR "Out of memory while making block chains.\n");
 +              return -ENOMEM;
 +      }
 +
-+      return apply_header_reservation();
-+}
-+
-+static unsigned long raw_to_real(unsigned long raw)
-+{
-+      unsigned long result;
-+
-+      result = raw - (raw * (sizeof(unsigned long) + sizeof(int)) +
-+              (PAGE_SIZE + sizeof(unsigned long) + sizeof(int) + 1)) /
-+              (PAGE_SIZE + sizeof(unsigned long) + sizeof(int));
-+
-+      return result < 0 ? 0 : result;
-+}
-+
-+static unsigned long toi_swap_storage_allocated(void)
-+{
-+      return raw_to_real(swap_pages_allocated - header_pages_reserved);
++      return 0;
 +}
 +
 +/*
@@ -17073,8 +18022,7 @@ index 0000000..10e6280
 +
 +      for (i = 0; i < MAX_SWAPFILES; i++) {
 +              struct swap_info_struct *si = get_swap_info_struct(i);
-+              if ((si->flags & SWP_USED) && si->swap_map &&
-+                  (si->flags & SWP_WRITEOK) &&
++              if ((si->flags & SWP_WRITEOK) &&
 +                  (strncmp(si->bdev->bd_disk->disk_name, "ram", 3))) {
 +                      val->totalswap += si->inuse_pages;
 +                      val->freeswap += si->pages - si->inuse_pages;
@@ -17087,368 +18035,158 @@ index 0000000..10e6280
 + */
 +static unsigned long toi_swap_storage_available(void)
 +{
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "In toi_swap_storage_available.");
 +      si_swapinfo_no_compcache(&swapinfo);
-+      return raw_to_real(swapinfo.freeswap +
-+                      swap_pages_allocated - header_pages_reserved);
++      return swapinfo.freeswap + swap_allocated;
 +}
 +
 +static int toi_swap_initialise(int starting_cycle)
 +{
-+      int result = 0;
-+
 +      if (!starting_cycle)
 +              return 0;
 +
 +      enable_swapfile();
-+
-+      if (resume_swap_dev_t && !resume_block_device) {
-+              resume_block_device = open_bdev(MAX_SWAPFILES,
-+                              resume_swap_dev_t, 1);
-+              if (IS_ERR(resume_block_device))
-+                      result = 1;
-+      }
-+
-+      return result;
++      return 0;
 +}
 +
 +static void toi_swap_cleanup(int ending_cycle)
 +{
 +      if (ending_cycle)
 +              disable_swapfile();
++}
 +
-+      close_bdevs();
-+
-+      forget_signatures();
-+}
-+
-+static int toi_swap_release_storage(void)
-+{
-+      header_pages_reserved = 0;
-+      swap_pages_allocated = 0;
-+
-+      if (swapextents.first) {
-+              /* Free swap entries */
-+              struct hibernate_extent *extentpointer;
-+              unsigned long extentvalue;
-+              toi_extent_for_each(&swapextents, extentpointer,
-+                              extentvalue)
-+                      swap_free((swp_entry_t) { extentvalue });
-+
-+              toi_put_extent_chain(&swapextents);
-+
-+              free_block_chains();
-+      }
-+
-+      return 0;
-+}
-+
-+static void free_swap_range(unsigned long min, unsigned long max)
-+{
-+      int j;
-+
-+      for (j = min; j <= max; j++)
-+              swap_free((swp_entry_t) { j });
-+}
-+
-+/*
-+ * Round robin allocation (where swap storage has the same priority).
-+ * could make this very inefficient, so we track extents allocated on
-+ * a per-swapfile basis.
-+ */
-+static int toi_swap_allocate_storage(unsigned long request)
-+{
-+      int i, result = 0, to_add = 0;
-+      unsigned long pages_to_get, extra_pages, gotten = 0, result2, needed;
-+      unsigned long extent_min = 0, extent_max = 0;
-+      unsigned swapfilenum = MAX_SWAPFILES;
-+
-+      extra_pages = DIV_ROUND_UP(request * (sizeof(unsigned long)
-+                             + sizeof(int)), PAGE_SIZE);
-+      needed = request + extra_pages + header_pages_reserved;
-+
-+      pages_to_get = needed > swapextents.size ?
-+              needed - swapextents.size : 0;
-+
-+      printk("Swap allocate storage: Request was %lu pages. Extra pages is %lu,"
-+              "swapextents size is %lu. Header pages reserved is %lu.\n", request,
-+              extra_pages, swapextents.size, header_pages_reserved);
-+
-+      if (pages_to_get < 1)
-+              return apply_header_reservation();
-+
-+      for (i = 0; i < MAX_SWAPFILES; i++) {
-+              struct swap_info_struct *si = get_swap_info_struct(i);
-+              devinfo[i].ignored = 1;
-+              if (!(si->flags & SWP_USED) || !si->swap_map ||
-+                  !(si->flags & SWP_WRITEOK))
-+                      continue;
-+              if (!strncmp(si->bdev->bd_disk->disk_name, "ram", 3)) {
-+                      continue;
-+              }
-+              devinfo[i].ignored = 0;
-+              devinfo[i].bdev = si->bdev;
-+              devinfo[i].dev_t = si->bdev->bd_dev;
-+              devinfo[i].bmap_shift = 3;
-+              devinfo[i].blocks_per_page = 1;
-+              if (swapfilenum == MAX_SWAPFILES)
-+                      swapfilenum = i;
-+      }
-+
-+      if (swapfilenum == MAX_SWAPFILES)
-+              return apply_header_reservation();
-+
-+      while (gotten < pages_to_get) {
-+              swp_entry_t entry;
-+              unsigned long new_value;
-+
-+              entry = get_swap_page_of_type(swapfilenum);
-+              if (!entry.val) {
-+                      if (to_add) {
-+                              result = toi_add_to_extent_chain(&swapextents,
-+                                              extent_min, extent_max);
-+                              if (result) {
-+                                      free_swap_range(extent_min, extent_max);
-+                                      gotten -= (extent_max - extent_min + 1);
-+                                      break;
-+                              }
-+                      }
-+                      swapfilenum++;
-+                      while (swapfilenum < MAX_SWAPFILES &&
-+                                      devinfo[swapfilenum].ignored)
-+                              swapfilenum++;
-+                      if (swapfilenum == MAX_SWAPFILES)
-+                              break;
-+              }
-+
-+              new_value = entry.val;
-+              gotten++;
-+
-+              if (!to_add) {
-+                      to_add = 1;
-+                      extent_min = new_value;
-+                      extent_max = new_value;
-+                      continue;
-+              }
-+
-+              if (new_value == extent_max + 1) {
-+                      extent_max++;
-+                      continue;
-+              }
-+
-+              if (toi_add_to_extent_chain(&swapextents, extent_min,
-+                                      extent_max)) {
-+                      printk(KERN_INFO "Failed to allocate extent for "
-+                                      "%lu-%lu.\n", extent_min, extent_max);
-+                      free_swap_range(extent_min, extent_max);
-+                      swap_free(entry);
-+                      gotten -= (extent_max - extent_min);
-+                      /* Don't try to add again below */
-+                      to_add = 0;
-+                      break;
-+              }
-+
-+              extent_min = new_value;
-+              extent_max = new_value;
-+      }
-+
-+      if (to_add) {
-+              int this_result = toi_add_to_extent_chain(&swapextents,
-+                              extent_min, extent_max);
-+
-+              if (this_result) {
-+                      result = this_result;
-+
-+                      free_swap_range(extent_min, extent_max);
-+                      gotten -= (extent_max - extent_min + 1);
-+              }
-+      }
-+
-+      if (gotten < pages_to_get) {
-+              printk("Got fewer pages than required "
-+                              "(%lu wanted, %lu gotten).\n",
-+                              pages_to_get, gotten);
-+              result = -ENOSPC;
-+      }
-+
-+      swap_pages_allocated += (long) gotten;
-+
-+      result2 = get_main_pool_phys_params();
-+
-+      return result ? result : result2;
-+}
-+
-+static int toi_swap_write_header_init(void)
-+{
-+      int i, result;
-+      struct swap_info_struct *si;
-+
-+      toi_bio_ops.rw_init(WRITE, 0);
-+      toi_writer_buffer_posn = 0;
-+
-+      /* Info needed to bootstrap goes at the start of the header.
-+       * First we save the positions and devinfo, including the number
-+       * of header pages. Then we save the structs containing data needed
-+       * for reading the header pages back.
-+       * Note that even if header pages take more than one page, when we
-+       * read back the info, we will have restored the location of the
-+       * next header page by the time we go to use it.
-+       */
-+
-+      result = toi_bio_ops.rw_header_chunk(WRITE, &toi_swapops,
-+                      (char *) &no_image_signature_contents,
-+                      sizeof(struct sig_data));
-+
-+      if (result)
-+              return result;
-+
-+      /* Forward one page will be done prior to the read */
-+      for (i = 0; i < MAX_SWAPFILES; i++) {
-+              si = get_swap_info_struct(i);
-+              if (si->flags & SWP_USED && si->swap_map &&
-+                  si->flags & SWP_WRITEOK)
-+                      devinfo[i].dev_t = si->bdev->bd_dev;
-+              else
-+                      devinfo[i].dev_t = (dev_t) 0;
-+      }
-+
-+      result = toi_bio_ops.rw_header_chunk(WRITE, &toi_swapops,
-+                      (char *) &toi_writer_posn_save,
-+                      sizeof(toi_writer_posn_save));
-+
-+      if (result)
-+              return result;
-+
-+      result = toi_bio_ops.rw_header_chunk(WRITE, &toi_swapops,
-+                      (char *) &devinfo, sizeof(devinfo));
-+
-+      if (result)
-+              return result;
-+
-+      for (i = 0; i < MAX_SWAPFILES; i++)
-+              toi_serialise_extent_chain(&toi_swapops, &block_chain[i]);
-+
-+      return 0;
-+}
-+
-+static int toi_swap_write_header_cleanup(void)
-+{
-+      int result = toi_bio_ops.write_header_chunk_finish();
-+
-+      /* Set signature to save we have an image */
-+      if (!result)
-+              result = write_modified_signature(IMAGE_SIGNATURE);
-+
-+      return result;
-+}
-+
-+/* ------------------------- HEADER READING ------------------------- */
-+
-+/*
-+ * read_header_init()
-+ *
-+ * Description:
-+ * 1. Attempt to read the device specified with resume=.
-+ * 2. Check the contents of the swap header for our signature.
-+ * 3. Warn, ignore, reset and/or continue as appropriate.
-+ * 4. If continuing, read the toi_swap configuration section
-+ *    of the header and set up block device info so we can read
-+ *    the rest of the header & image.
-+ *
-+ * Returns:
-+ * May not return if user choose to reboot at a warning.
-+ * -EINVAL if cannot resume at this time. Booting should continue
-+ * normally.
-+ */
-+
-+static int toi_swap_read_header_init(void)
-+{
-+      int i, result = 0;
-+      toi_writer_buffer_posn = 0;
-+
-+      if (!header_dev_t) {
-+              printk(KERN_INFO "read_header_init called when we haven't "
-+                              "verified there is an image!\n");
-+              return -EINVAL;
-+      }
-+
-+      /*
-+       * If the header is not on the resume_swap_dev_t, get the resume device
-+       * first.
-+       */
-+      if (header_dev_t != resume_swap_dev_t) {
-+              header_block_device = open_bdev(MAX_SWAPFILES + 1,
-+                              header_dev_t, 1);
-+
-+              if (IS_ERR(header_block_device))
-+                      return PTR_ERR(header_block_device);
-+      } else
-+              header_block_device = resume_block_device;
-+
-+      toi_bio_ops.read_header_init();
++static void toi_swap_free_storage(struct toi_bdev_info *chain)
++{
++      /* Free swap entries */
++      struct hibernate_extent *extentpointer;
++      unsigned long extentvalue;
 +
-+      /*
-+       * Read toi_swap configuration.
-+       * Headerblock size taken into account already.
-+       */
-+      result = toi_bio_ops.bdev_page_io(READ, header_block_device,
-+                      headerblock << 3,
-+                      virt_to_page((unsigned long) toi_writer_buffer));
-+      if (result)
-+              return result;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "Freeing storage for chain %p.",
++                      chain);
 +
-+      memcpy(&no_image_signature_contents, toi_writer_buffer,
-+                      sizeof(no_image_signature_contents));
++      swap_allocated -= chain->allocations.size;
++      toi_extent_for_each(&chain->allocations, extentpointer, extentvalue)
++              swap_free((swp_entry_t) { extentvalue });
 +
-+      toi_writer_buffer_posn = sizeof(no_image_signature_contents);
++      toi_put_extent_chain(&chain->allocations);
++}
 +
-+      memcpy(&toi_writer_posn_save, toi_writer_buffer +
-+                      toi_writer_buffer_posn, sizeof(toi_writer_posn_save));
++static void free_swap_range(unsigned long min, unsigned long max)
++{
++      int j;
 +
-+      toi_writer_buffer_posn += sizeof(toi_writer_posn_save);
++      for (j = min; j <= max; j++)
++              swap_free((swp_entry_t) { j });
++      swap_allocated -= (max - min + 1);
++}
 +
-+      memcpy(&devinfo, toi_writer_buffer + toi_writer_buffer_posn,
-+                      sizeof(devinfo));
++/*
++ * Allocation of a single swap type. Swap priorities are handled at the higher
++ * level.
++ */
++static int toi_swap_allocate_storage(struct toi_bdev_info *chain,
++              unsigned long request)
++{
++      int to_add = 0;
++      unsigned long gotten = 0;
++      unsigned long extent_min = 0, extent_max = 0;
 +
-+      toi_writer_buffer_posn += sizeof(devinfo);
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "  Swap allocate storage: Asked to"
++                      " allocate %lu pages from device %d.", request,
++                      chain->allocator_index);
 +
-+      /* Restore device info */
-+      for (i = 0; i < MAX_SWAPFILES; i++) {
-+              dev_t thisdevice = devinfo[i].dev_t;
-+              struct block_device *bdev_result;
++      while (gotten < request) {
++              swp_entry_t entry;
++              unsigned long new_value;
 +
-+              devinfo[i].bdev = NULL;
++              entry = get_swap_page_of_type(chain->allocator_index);
++              if (!entry.val)
++                      break;
 +
-+              if (!thisdevice || devinfo[i].ignored)
-+                      continue;
++              swap_allocated++;
++              new_value = entry.val;
++              gotten++;
 +
-+              if (thisdevice == resume_swap_dev_t) {
-+                      devinfo[i].bdev = resume_block_device;
++              if (!to_add) {
++                      to_add = 1;
++                      extent_min = new_value;
++                      extent_max = new_value;
 +                      continue;
 +              }
 +
-+              if (thisdevice == header_dev_t) {
-+                      devinfo[i].bdev = header_block_device;
++              if (new_value == extent_max + 1) {
++                      extent_max++;
 +                      continue;
 +              }
 +
-+              bdev_result = open_bdev(i, thisdevice, 1);
-+              if (IS_ERR(bdev_result))
-+                      return PTR_ERR(bdev_result);
-+              devinfo[i].bdev = bdevs_opened[i]->bdev;
++              if (toi_add_to_extent_chain(&chain->allocations, extent_min,
++                                      extent_max)) {
++                      printk(KERN_INFO "Failed to allocate extent for "
++                                      "%lu-%lu.\n", extent_min, extent_max);
++                      free_swap_range(extent_min, extent_max);
++                      swap_free(entry);
++                      gotten -= (extent_max - extent_min);
++                      /* Don't try to add again below */
++                      to_add = 0;
++                      break;
++              }
++
++              extent_min = new_value;
++              extent_max = new_value;
 +      }
 +
-+      toi_extent_state_goto_start(&toi_writer_posn);
-+      toi_bio_ops.set_extra_page_forward();
++      if (to_add) {
++              int this_result = toi_add_to_extent_chain(&chain->allocations,
++                              extent_min, extent_max);
 +
-+      for (i = 0; i < MAX_SWAPFILES && !result; i++)
-+              result = toi_load_extent_chain(&block_chain[i]);
++              if (this_result) {
++                      free_swap_range(extent_min, extent_max);
++                      gotten -= (extent_max - extent_min + 1);
++              }
++      }
 +
-+      return result;
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "  Allocated %lu pages.", gotten);
++      return gotten;
 +}
 +
-+static int toi_swap_read_header_cleanup(void)
++static int toi_swap_register_storage(void)
 +{
-+      toi_bio_ops.rw_cleanup(READ);
++      int i, result;
++
++      toi_message(TOI_IO, TOI_VERBOSE, 0, "toi_swap_register_storage.");
++      for (i = 0; i < MAX_SWAPFILES; i++) {
++              struct swap_info_struct *si = get_swap_info_struct(i);
++              struct toi_bdev_info *devinfo;
++              if (!(si->flags & SWP_WRITEOK) ||
++                  !strncmp(si->bdev->bd_disk->disk_name, "ram", 3))
++                      continue;
++
++              devinfo = toi_kzalloc(39, sizeof(struct toi_bdev_info),
++                              GFP_ATOMIC);
++              if (!devinfo) {
++                      printk("Failed to allocate devinfo struct for swap "
++                                      "device %d.\n", i);
++                      return -ENOMEM;
++              }
++
++              devinfo->bdev = si->bdev;
++              devinfo->allocator = &toi_swapops;
++              devinfo->allocator_index = i;
++
++              result = uuid_from_block_dev(si->bdev, devinfo->uuid);
++              if (result)
++                      printk("uuid from block dev returned %d.\n", result);
++              devinfo->dev_t = si->bdev->bd_dev;
++              devinfo->prio = si->prio;
++              devinfo->bmap_shift = 3;
++              devinfo->blocks_per_page = 1;
++
++              toi_message(TOI_IO, TOI_VERBOSE, 0, "Registering swap storage:"
++                              " Device %d (%lx), prio %d.", i,
++                              (unsigned long) devinfo->dev_t, devinfo->prio);
++              toi_bio_ops.register_storage(devinfo);
++      }
++
 +      return 0;
 +}
 +
@@ -17476,13 +18214,7 @@ index 0000000..10e6280
 +      int len = 0;
 +      struct sysinfo sysinfo;
 +
-+      if (toiActiveAllocator != &toi_swapops) {
-+              len = scnprintf(buffer, size,
-+                              "- SwapAllocator inactive.\n");
-+              return len;
-+      }
-+
-+      len = scnprintf(buffer, size, "- SwapAllocator active.\n");
++      len = scnprintf(buffer, size, "- Swap Allocator enabled.\n");
 +      if (swapfilename[0])
 +              len += scnprintf(buffer+len, size-len,
 +                      "  Attempting to automatically swapon: %s.\n",
@@ -17492,228 +18224,11 @@ index 0000000..10e6280
 +
 +      len += scnprintf(buffer+len, size-len,
 +                      "  Swap available for image: %lu pages.\n",
-+                      sysinfo.freeswap + toi_swap_storage_allocated());
++                      sysinfo.freeswap + swap_allocated);
 +
 +      return len;
 +}
 +
-+/*
-+ * Storage needed
-+ *
-+ * Returns amount of space in the swap header required
-+ * for the toi_swap's data. This ignores the links between
-+ * pages, which we factor in when allocating the space.
-+ *
-+ * We ensure the space is allocated, but actually save the
-+ * data from write_header_init and therefore don't also define a
-+ * save_config_info routine.
-+ */
-+static int toi_swap_storage_needed(void)
-+{
-+      int i, result;
-+      result = sizeof(struct sig_data) + sizeof(toi_writer_posn_save) +
-+              sizeof(devinfo);
-+
-+      for (i = 0; i < MAX_SWAPFILES; i++) {
-+              result += sizeof(block_chain[i].size) +
-+                        sizeof(block_chain[i].num_extents);
-+              result += (2 * sizeof(unsigned long) *
-+                      block_chain[i].num_extents);
-+      }
-+
-+      return result;
-+}
-+
-+/*
-+ * Image_exists
-+ *
-+ * Returns -1 if don't know, otherwise 0 (no) or 1 (yes).
-+ */
-+static int toi_swap_image_exists(int quiet)
-+{
-+      int signature_found;
-+
-+      if (!resume_swap_dev_t) {
-+              if (!quiet)
-+                      printk(KERN_INFO "Not even trying to read header "
-+                              "because resume_swap_dev_t is not set.\n");
-+              return -1;
-+      }
-+
-+      if (!resume_block_device) {
-+              resume_block_device = open_bdev(MAX_SWAPFILES,
-+                              resume_swap_dev_t, 1);
-+              if (IS_ERR(resume_block_device)) {
-+                      if (!quiet)
-+                              printk(KERN_INFO "Failed to open resume dev_t"
-+                                              " (%x).\n", resume_swap_dev_t);
-+                      return -1;
-+              }
-+      }
-+
-+      signature_found = parse_signature();
-+
-+      switch (signature_found) {
-+      case -ENOMEM:
-+              return -1;
-+      case -1:
-+              if (!quiet)
-+                      printk(KERN_ERR "TuxOnIce: Unable to find a signature."
-+                              " Could you have moved a swap file?\n");
-+              return -1;
-+      case 0:
-+      case 1:
-+              if (!quiet)
-+                      printk(KERN_INFO "TuxOnIce: Normal swapspace found.\n");
-+              return 0;
-+      case 2:
-+      case 3:
-+      case 4:
-+              if (!quiet)
-+                      printk(KERN_INFO "TuxOnIce: Detected another "
-+                              "implementation's signature.\n");
-+              return 0;
-+      case 10:
-+              if (!quiet)
-+                      printk(KERN_INFO "TuxOnIce: Detected TuxOnIce binary "
-+                              "signature.\n");
-+              return 1;
-+      }
-+
-+      printk("Unrecognised parse_signature result (%d).\n", signature_found);
-+      return 0;
-+}
-+
-+/* toi_swap_remove_image
-+ *
-+ */
-+static int toi_swap_remove_image(void)
-+{
-+      /*
-+       * If nr_hibernates == 0, we must be booting, so no swap pages
-+       * will be recorded as used yet.
-+       */
-+
-+      if (nr_hibernates)
-+              toi_swap_release_storage();
-+
-+      /*
-+       * We don't do a sanity check here: we want to restore the swap
-+       * whatever version of kernel made the hibernate image.
-+       *
-+       * We need to write swap, but swap may not be enabled so
-+       * we write the device directly
-+       *
-+       * If we don't have an current_signature_page, we didn't
-+       * read an image header, so don't change anything.
-+       */
-+
-+      return toi_swap_image_exists(1) ?
-+              write_modified_signature(NO_IMAGE_SIGNATURE) : 0;
-+}
-+
-+/*
-+ * Mark resume attempted.
-+ *
-+ * Record that we tried to resume from this image. We have already read the
-+ * signature in. We just need to write the modified version.
-+ */
-+static int toi_swap_mark_resume_attempted(int mark)
-+{
-+      if (!resume_swap_dev_t) {
-+              printk(KERN_INFO "Not even trying to record attempt at resuming"
-+                              " because resume_swap_dev_t is not set.\n");
-+              return -ENODEV;
-+      }
-+
-+      return write_modified_signature(mark ? TRIED_RESUME : NO_TRIED_RESUME);
-+}
-+
-+/*
-+ * Parse Image Location
-+ *
-+ * Attempt to parse a resume= parameter.
-+ * Swap Writer accepts:
-+ * resume=swap:DEVNAME[:FIRSTBLOCK][@BLOCKSIZE]
-+ *
-+ * Where:
-+ * DEVNAME is convertable to a dev_t by name_to_dev_t
-+ * FIRSTBLOCK is the location of the first block in the swap file
-+ * (specifying for a swap partition is nonsensical but not prohibited).
-+ * Data is validated by attempting to read a swap header from the
-+ * location given. Failure will result in toi_swap refusing to
-+ * save an image, and a reboot with correct parameters will be
-+ * necessary.
-+ */
-+static int toi_swap_parse_sig_location(char *commandline,
-+              int only_allocator, int quiet)
-+{
-+      char *thischar, *devstart, *colon = NULL;
-+      int signature_found, result = -EINVAL, temp_result = 0;
-+
-+      if (strncmp(commandline, "swap:", 5)) {
-+              /*
-+               * Failing swap:, we'll take a simple
-+               * resume=/dev/hda2, but fall through to
-+               * other allocators if /dev/ isn't matched.
-+               */
-+              if (strncmp(commandline, "/dev/", 5))
-+                      return 1;
-+      } else
-+              commandline += 5;
-+
-+      devstart = commandline;
-+      thischar = commandline;
-+      while ((*thischar != ':') && (*thischar != '@') &&
-+              ((thischar - commandline) < 250) && (*thischar))
-+              thischar++;
-+
-+      if (*thischar == ':') {
-+              colon = thischar;
-+              *colon = 0;
-+              thischar++;
-+      }
-+
-+      while ((thischar - commandline) < 250 && *thischar)
-+              thischar++;
-+
-+      if (colon) {
-+              unsigned long block;
-+              temp_result = strict_strtoul(colon + 1, 0, &block);
-+              if (!temp_result)
-+                      resume_firstblock = (int) block;
-+      } else
-+              resume_firstblock = 0;
-+
-+      clear_toi_state(TOI_CAN_HIBERNATE);
-+      clear_toi_state(TOI_CAN_RESUME);
-+
-+      if (!temp_result)
-+              temp_result = try_to_parse_resume_device(devstart, quiet);
-+
-+      if (colon)
-+              *colon = ':';
-+
-+      if (temp_result)
-+              return -EINVAL;
-+
-+      signature_found = toi_swap_image_exists(quiet);
-+
-+      if (signature_found != -1) {
-+              result = 0;
-+
-+              toi_bio_ops.set_devinfo(devinfo);
-+              toi_writer_posn.chains = &block_chain[0];
-+              toi_writer_posn.num_chains = MAX_SWAPFILES;
-+              set_toi_state(TOI_CAN_HIBERNATE);
-+              set_toi_state(TOI_CAN_RESUME);
-+      } else
-+              if (!quiet)
-+                      printk(KERN_ERR "TuxOnIce: SwapAllocator: No swap "
-+                              "signature found at %s.\n", devstart);
-+      return result;
-+}
-+
 +static int header_locations_read_sysfs(const char *page, int count)
 +{
 +      int i, printedpartitionsmessage = 0, len = 0, haveswap = 0;
@@ -17729,8 +18244,7 @@ index 0000000..10e6280
 +      for (i = 0; i < MAX_SWAPFILES; i++) {
 +              struct swap_info_struct *si =  get_swap_info_struct(i);
 +
-+              if ((!si->flags & SWP_USED) || si->swap_map ||
-+                  !(si->flags & SWP_WRITEOK))
++              if (!(si->flags & SWP_WRITEOK))
 +                      continue;
 +
 +              if (S_ISBLK(si->swap_file->f_mapping->host->i_mode)) {
@@ -17784,30 +18298,24 @@ index 0000000..10e6280
 +                      attempt_to_parse_resume_device2),
 +};
 +
++static struct toi_bio_allocator_ops toi_bio_swapops = {
++      .register_storage                       = toi_swap_register_storage,
++      .storage_available                      = toi_swap_storage_available,
++      .allocate_storage                       = toi_swap_allocate_storage,
++      .bmap                                   = get_main_pool_phys_params,
++      .free_storage                           = toi_swap_free_storage,
++};
++
 +static struct toi_module_ops toi_swapops = {
-+      .type                                   = WRITER_MODULE,
++      .type                                   = BIO_ALLOCATOR_MODULE,
 +      .name                                   = "swap storage",
 +      .directory                              = "swap",
 +      .module                                 = THIS_MODULE,
 +      .memory_needed                          = toi_swap_memory_needed,
 +      .print_debug_info                       = toi_swap_print_debug_stats,
-+      .storage_needed                         = toi_swap_storage_needed,
 +      .initialise                             = toi_swap_initialise,
 +      .cleanup                                = toi_swap_cleanup,
-+
-+      .noresume_reset         = toi_swap_noresume_reset,
-+      .storage_available      = toi_swap_storage_available,
-+      .storage_allocated      = toi_swap_storage_allocated,
-+      .reserve_header_space   = toi_swap_reserve_header_space,
-+      .allocate_storage       = toi_swap_allocate_storage,
-+      .image_exists           = toi_swap_image_exists,
-+      .mark_resume_attempted  = toi_swap_mark_resume_attempted,
-+      .write_header_init      = toi_swap_write_header_init,
-+      .write_header_cleanup   = toi_swap_write_header_cleanup,
-+      .read_header_init       = toi_swap_read_header_init,
-+      .read_header_cleanup    = toi_swap_read_header_cleanup,
-+      .remove_image           = toi_swap_remove_image,
-+      .parse_sig_location     = toi_swap_parse_sig_location,
++      .bio_allocator_ops                      = &toi_bio_swapops,
 +
 +      .sysfs_data             = sysfs_params,
 +      .num_sysfs_entries      = sizeof(sysfs_params) /
@@ -17817,18 +18325,6 @@ index 0000000..10e6280
 +/* ---- Registration ---- */
 +static __init int toi_swap_load(void)
 +{
-+      toi_swapops.rw_init = toi_bio_ops.rw_init;
-+      toi_swapops.rw_cleanup = toi_bio_ops.rw_cleanup;
-+      toi_swapops.read_page = toi_bio_ops.read_page;
-+      toi_swapops.write_page = toi_bio_ops.write_page;
-+      toi_swapops.rw_header_chunk = toi_bio_ops.rw_header_chunk;
-+      toi_swapops.rw_header_chunk_noreadahead =
-+              toi_bio_ops.rw_header_chunk_noreadahead;
-+      toi_swapops.io_flusher = toi_bio_ops.io_flusher;
-+      toi_swapops.update_throughput_throttle =
-+              toi_bio_ops.update_throughput_throttle;
-+      toi_swapops.finish_all_io = toi_bio_ops.finish_all_io;
-+
 +      return toi_register_module(&toi_swapops);
 +}
 +
@@ -18697,10 +19193,10 @@ index 0000000..dc45741
 +extern void toi_remove_ui_ops(struct ui_ops *this_ui);
 diff --git a/kernel/power/tuxonice_userui.c b/kernel/power/tuxonice_userui.c
 new file mode 100644
-index 0000000..c7b1053
+index 0000000..ad441c5
 --- /dev/null
 +++ b/kernel/power/tuxonice_userui.c
-@@ -0,0 +1,662 @@
+@@ -0,0 +1,668 @@
 +/*
 + * kernel/power/user_ui.c
 + *
@@ -18772,10 +19268,15 @@ index 0000000..c7b1053
 +              (1 << TOI_LOGALL) |
 +              (1 << TOI_SINGLESTEP) |
 +              (1 << TOI_PAUSE_NEAR_PAGESET_END);
++      static unsigned long new_action;
 +
-+      toi_bkd.toi_action = (toi_bkd.toi_action & (~toi_action_mask)) |
++      new_action = (toi_bkd.toi_action & (~toi_action_mask)) |
 +              (n & toi_action_mask);
 +
++      printk(KERN_DEBUG "n is %x. Action flags being changed from %lx "
++                      "to %lx.", n, toi_bkd.toi_action, new_action);
++      toi_bkd.toi_action = new_action;
++
 +      if (!test_action_state(TOI_PAUSE) &&
 +                      !test_action_state(TOI_SINGLESTEP))
 +              wake_up_interruptible(&userui_wait_for_key);
@@ -19086,7 +19587,8 @@ index 0000000..c7b1053
 + */
 +static void request_abort_hibernate(void)
 +{
-+      if (test_result_state(TOI_ABORT_REQUESTED))
++      if (test_result_state(TOI_ABORT_REQUESTED) ||
++         !test_action_state(TOI_CAN_CANCEL))
 +              return;
 +
 +      if (test_toi_state(TOI_NOW_RESUMING)) {
@@ -19376,7 +19878,7 @@ index bf0014d..d1c4ac2 100644
  static int snapshot_open(struct inode *inode, struct file *filp)
  {
 diff --git a/kernel/printk.c b/kernel/printk.c
-index b4d97b5..0fda643 100644
+index f38b07f..f0b3459 100644
 --- a/kernel/printk.c
 +++ b/kernel/printk.c
 @@ -32,6 +32,7 @@
@@ -19387,15 +19889,15 @@ index b4d97b5..0fda643 100644
  #include <linux/kexec.h>
  
  #include <asm/uaccess.h>
-@@ -60,6 +61,7 @@ int console_printk[4] = {
+@@ -66,6 +67,7 @@ int console_printk[4] = {
        MINIMUM_CONSOLE_LOGLEVEL,       /* minimum_console_loglevel */
        DEFAULT_CONSOLE_LOGLEVEL,       /* default_console_loglevel */
  };
 +EXPORT_SYMBOL_GPL(console_printk);
  
- /*
-  * Low level drivers may need that to know if they can schedule in
-@@ -926,6 +928,7 @@ void suspend_console(void)
+ static int saved_console_loglevel = -1;
+@@ -954,6 +956,7 @@ void suspend_console(void)
        console_suspended = 1;
        up(&console_sem);
  }
@@ -19403,7 +19905,7 @@ index b4d97b5..0fda643 100644
  
  void resume_console(void)
  {
-@@ -935,6 +938,7 @@ void resume_console(void)
+@@ -963,6 +966,7 @@ void resume_console(void)
        console_suspended = 0;
        release_console_sem();
  }
@@ -19412,7 +19914,7 @@ index b4d97b5..0fda643 100644
  /**
   * acquire_console_sem - lock the console system for exclusive use.
 diff --git a/mm/bootmem.c b/mm/bootmem.c
-index 701740c..72f84e3 100644
+index 555d5d2..cd66665 100644
 --- a/mm/bootmem.c
 +++ b/mm/bootmem.c
 @@ -23,6 +23,7 @@
@@ -19424,7 +19926,7 @@ index 701740c..72f84e3 100644
  #ifdef CONFIG_CRASH_DUMP
  /*
 diff --git a/mm/highmem.c b/mm/highmem.c
-index 25878cc..32a0767 100644
+index 9c1e627..b0facc3 100644
 --- a/mm/highmem.c
 +++ b/mm/highmem.c
 @@ -57,6 +57,7 @@ unsigned int nr_free_highpages (void)
@@ -19436,17 +19938,17 @@ index 25878cc..32a0767 100644
  static int pkmap_count[LAST_PKMAP];
  static unsigned int last_pkmap_nr;
 diff --git a/mm/memory.c b/mm/memory.c
-index aede2ce..5cc16dc 100644
+index 6ab19dd..377be88 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -1186,6 +1186,7 @@ no_page_table:
-       }
+@@ -1228,6 +1228,7 @@ no_page_table:
+               return ERR_PTR(-EFAULT);
        return page;
  }
 +EXPORT_SYMBOL_GPL(follow_page);
  
- /* Can we do the FOLL_ANON optimization? */
- static inline int use_zero_page(struct vm_area_struct *vma)
+ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+                    unsigned long start, int nr_pages, unsigned int gup_flags,
 diff --git a/mm/mmzone.c b/mm/mmzone.c
 index f5b7d17..72a6770 100644
 --- a/mm/mmzone.c
@@ -19476,10 +19978,10 @@ index f5b7d17..72a6770 100644
  static inline int zref_in_nodemask(struct zoneref *zref, nodemask_t *nodes)
  {
 diff --git a/mm/page-writeback.c b/mm/page-writeback.c
-index 81627eb..880d936 100644
+index 2c5d792..6d5d74f 100644
 --- a/mm/page-writeback.c
 +++ b/mm/page-writeback.c
-@@ -105,6 +105,7 @@ unsigned int dirty_expire_interval = 30 * 100; /* centiseconds */
+@@ -99,6 +99,7 @@ unsigned int dirty_expire_interval = 30 * 100; /* centiseconds */
   * Flag that makes the machine dump writes/reads and block dirtyings.
   */
  int block_dump;
@@ -19488,10 +19990,10 @@ index 81627eb..880d936 100644
  /*
   * Flag that puts the machine in "laptop mode". Doubles as a timeout in jiffies:
 diff --git a/mm/page_alloc.c b/mm/page_alloc.c
-index a0de15f..9bed1c3 100644
+index 2bc2ac6..f3a9a61 100644
 --- a/mm/page_alloc.c
 +++ b/mm/page_alloc.c
-@@ -2046,6 +2046,26 @@ static unsigned int nr_free_zone_pages(int offset)
+@@ -2098,6 +2098,26 @@ static unsigned int nr_free_zone_pages(int offset)
        return sum;
  }
  
@@ -19518,7 +20020,7 @@ index a0de15f..9bed1c3 100644
  /*
   * Amount of free RAM allocatable within ZONE_DMA and ZONE_NORMAL
   */
-@@ -2056,6 +2076,15 @@ unsigned int nr_free_buffer_pages(void)
+@@ -2108,6 +2128,15 @@ unsigned int nr_free_buffer_pages(void)
  EXPORT_SYMBOL_GPL(nr_free_buffer_pages);
  
  /*
@@ -19535,10 +20037,10 @@ index a0de15f..9bed1c3 100644
   */
  unsigned int nr_free_pagecache_pages(void)
 diff --git a/mm/shmem.c b/mm/shmem.c
-index d713239..26fafce 100644
+index 356dd99..94481cb 100644
 --- a/mm/shmem.c
 +++ b/mm/shmem.c
-@@ -1557,6 +1557,8 @@ static struct inode *shmem_get_inode(struct super_block *sb, int mode,
+@@ -1561,6 +1561,8 @@ static struct inode *shmem_get_inode(struct super_block *sb, int mode,
                memset(info, 0, (char *)inode - (char *)info);
                spin_lock_init(&info->lock);
                info->flags = flags & VM_NORESERVE;
@@ -19548,10 +20050,10 @@ index d713239..26fafce 100644
                cache_no_acl(inode);
  
 diff --git a/mm/swap_state.c b/mm/swap_state.c
-index 42cd38e..105973c 100644
+index 6d1daeb..eced4ef 100644
 --- a/mm/swap_state.c
 +++ b/mm/swap_state.c
-@@ -45,6 +45,7 @@ struct address_space swapper_space = {
+@@ -46,6 +46,7 @@ struct address_space swapper_space = {
        .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
        .backing_dev_info = &swap_backing_dev_info,
  };
@@ -19560,10 +20062,10 @@ index 42cd38e..105973c 100644
  #define INC_CACHE_INFO(x)     do { swap_cache_info.x++; } while (0)
  
 diff --git a/mm/swapfile.c b/mm/swapfile.c
-index 8ffdc0d..78df628 100644
+index 9c590ee..796bf72 100644
 --- a/mm/swapfile.c
 +++ b/mm/swapfile.c
-@@ -493,6 +493,7 @@ noswap:
+@@ -495,6 +495,7 @@ noswap:
        spin_unlock(&swap_lock);
        return (swp_entry_t) {0};
  }
@@ -19571,7 +20073,15 @@ index 8ffdc0d..78df628 100644
  
  /* The only caller of this function is now susupend routine */
  swp_entry_t get_swap_page_of_type(int type)
-@@ -627,6 +628,7 @@ void swapcache_free(swp_entry_t entry, struct page *page)
+@@ -517,6 +518,7 @@ swp_entry_t get_swap_page_of_type(int type)
+       spin_unlock(&swap_lock);
+       return (swp_entry_t) {0};
+ }
++EXPORT_SYMBOL_GPL(get_swap_page_of_type);
+ static struct swap_info_struct * swap_info_get(swp_entry_t entry)
+ {
+@@ -629,6 +631,7 @@ void swapcache_free(swp_entry_t entry, struct page *page)
        }
        return;
  }
@@ -19579,7 +20089,7 @@ index 8ffdc0d..78df628 100644
  
  /*
   * How many references to page are currently swapped out?
-@@ -1304,6 +1306,7 @@ sector_t map_swap_page(struct swap_info_struct *sis, pgoff_t offset)
+@@ -1305,6 +1308,7 @@ sector_t map_swap_page(struct swap_info_struct *sis, pgoff_t offset)
                BUG_ON(se == start_se);         /* It *must* be present */
        }
  }
@@ -19587,7 +20097,7 @@ index 8ffdc0d..78df628 100644
  
  #ifdef CONFIG_HIBERNATION
  /*
-@@ -1647,6 +1650,7 @@ out_dput:
+@@ -1648,6 +1652,7 @@ out_dput:
  out:
        return err;
  }
@@ -19595,7 +20105,7 @@ index 8ffdc0d..78df628 100644
  
  #ifdef CONFIG_PROC_FS
  /* iterator */
-@@ -2045,6 +2049,7 @@ out:
+@@ -2048,6 +2053,7 @@ out:
        }
        return error;
  }
@@ -19603,7 +20113,7 @@ index 8ffdc0d..78df628 100644
  
  void si_swapinfo(struct sysinfo *val)
  {
-@@ -2062,6 +2067,7 @@ void si_swapinfo(struct sysinfo *val)
+@@ -2065,6 +2071,7 @@ void si_swapinfo(struct sysinfo *val)
        val->totalswap = total_swap_pages + nr_to_be_unused;
        spin_unlock(&swap_lock);
  }
@@ -19611,7 +20121,7 @@ index 8ffdc0d..78df628 100644
  
  /*
   * Verify that a swap entry is valid and increment its swap map count.
-@@ -2162,6 +2168,7 @@ get_swap_info_struct(unsigned type)
+@@ -2165,6 +2172,7 @@ get_swap_info_struct(unsigned type)
  {
        return &swap_info[type];
  }
@@ -19620,10 +20130,10 @@ index 8ffdc0d..78df628 100644
  /*
   * swap_lock prevents swap_map being freed. Don't grab an extra
 diff --git a/mm/vmscan.c b/mm/vmscan.c
-index 94e86dd..b7dec80 100644
+index 777af57..70313d6 100644
 --- a/mm/vmscan.c
 +++ b/mm/vmscan.c
-@@ -2101,6 +2101,9 @@ void wakeup_kswapd(struct zone *zone, int order)
+@@ -2211,6 +2211,9 @@ void wakeup_kswapd(struct zone *zone, int order)
        if (!populated_zone(zone))
                return;
  
@@ -19633,7 +20143,7 @@ index 94e86dd..b7dec80 100644
        pgdat = zone->zone_pgdat;
        if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0))
                return;
-@@ -2261,6 +2264,7 @@ out:
+@@ -2403,6 +2406,7 @@ out:
  
        return sc.nr_reclaimed;
  }
@@ -19641,13 +20151,3 @@ index 94e86dd..b7dec80 100644
  #endif /* CONFIG_HIBERNATION */
  
  /* It's optimal to keep kswapds on the same CPUs as their memory, but
---- linux-2.6.31/mm/swapfile.c~        2009-09-13 09:09:36.506565318 +0200
-+++ linux-2.6.31/mm/swapfile.c 2009-09-14 08:14:30.692422596 +0200
-@@ -518,6 +518,7 @@
-       spin_unlock(&swap_lock);
-       return (swp_entry_t) {0};
- }
-+EXPORT_SYMBOL_GPL(get_swap_page_of_type);
- static struct swap_info_struct * swap_info_get(swp_entry_t entry)
- {
index 92c294d4456695394d9b5c6e1b257268f730d146..1185856738cab1b5e86e8405bd12c7d52e8d56c9 100644 (file)
@@ -1,7 +1,7 @@
-diff -NurpP --minimal linux-2.6.31.6/arch/alpha/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/Kconfig
---- linux-2.6.31.6/arch/alpha/Kconfig  2009-03-24 14:18:07.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/Kconfig    2009-09-10 16:11:43.000000000 +0200
-@@ -666,6 +666,8 @@ config DUMMY_CONSOLE
+diff -NurpP --minimal linux-2.6.32/arch/alpha/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/alpha/Kconfig
+--- linux-2.6.32/arch/alpha/Kconfig    2009-12-03 20:01:49.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/alpha/Kconfig      2009-12-03 20:04:56.000000000 +0100
+@@ -674,6 +674,8 @@ config DUMMY_CONSOLE
        depends on VGA_HOSE
        default y
  
@@ -10,9 +10,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/alpha/Kconfig linux-2.6.31.6-vs2.3.0.3
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/entry.S linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/entry.S
---- linux-2.6.31.6/arch/alpha/kernel/entry.S   2009-06-11 17:11:46.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/entry.S     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/alpha/kernel/entry.S linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/entry.S
+--- linux-2.6.32/arch/alpha/kernel/entry.S     2009-06-11 17:11:46.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/entry.S       2009-12-03 20:04:56.000000000 +0100
 @@ -874,24 +874,15 @@ sys_getxgid:
        .globl  sys_getxpid
        .ent    sys_getxpid
@@ -45,9 +45,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/entry.S linux-2.6.31.6-vs
        ret
  .end sys_getxpid
  
-diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/osf_sys.c linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/osf_sys.c
---- linux-2.6.31.6/arch/alpha/kernel/osf_sys.c 2009-09-10 15:25:14.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/osf_sys.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/alpha/kernel/osf_sys.c linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/osf_sys.c
+--- linux-2.6.32/arch/alpha/kernel/osf_sys.c   2009-09-10 15:25:14.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/osf_sys.c     2009-12-03 20:04:56.000000000 +0100
 @@ -872,7 +872,7 @@ SYSCALL_DEFINE2(osf_gettimeofday, struct
  {
        if (tv) {
@@ -57,9 +57,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/osf_sys.c linux-2.6.31.6-
                if (put_tv32(tv, &ktv))
                        return -EFAULT;
        }
-diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/ptrace.c
---- linux-2.6.31.6/arch/alpha/kernel/ptrace.c  2009-09-10 15:25:14.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/ptrace.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/alpha/kernel/ptrace.c linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/ptrace.c
+--- linux-2.6.32/arch/alpha/kernel/ptrace.c    2009-09-10 15:25:14.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/ptrace.c      2009-12-03 20:04:56.000000000 +0100
 @@ -14,6 +14,7 @@
  #include <linux/slab.h>
  #include <linux/security.h>
@@ -68,9 +68,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/ptrace.c linux-2.6.31.6-v
  
  #include <asm/uaccess.h>
  #include <asm/pgtable.h>
-diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/systbls.S linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/systbls.S
---- linux-2.6.31.6/arch/alpha/kernel/systbls.S 2009-03-24 14:18:08.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/systbls.S   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/alpha/kernel/systbls.S linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/systbls.S
+--- linux-2.6.32/arch/alpha/kernel/systbls.S   2009-03-24 14:18:08.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/systbls.S     2009-12-03 20:04:56.000000000 +0100
 @@ -446,7 +446,7 @@ sys_call_table:
        .quad sys_stat64                        /* 425 */
        .quad sys_lstat64
@@ -80,9 +80,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/systbls.S linux-2.6.31.6-
        .quad sys_ni_syscall                    /* sys_mbind */
        .quad sys_ni_syscall                    /* sys_get_mempolicy */
        .quad sys_ni_syscall                    /* sys_set_mempolicy */
-diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/traps.c
---- linux-2.6.31.6/arch/alpha/kernel/traps.c   2009-06-11 17:11:46.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/kernel/traps.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/alpha/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/traps.c
+--- linux-2.6.32/arch/alpha/kernel/traps.c     2009-06-11 17:11:46.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/alpha/kernel/traps.c       2009-12-03 20:04:56.000000000 +0100
 @@ -183,7 +183,8 @@ die_if_kernel(char * str, struct pt_regs
  #ifdef CONFIG_SMP
        printk("CPU %d ", hard_smp_processor_id());
@@ -93,9 +93,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/alpha/kernel/traps.c linux-2.6.31.6-vs
        dik_show_regs(regs, r9_15);
        add_taint(TAINT_DIE);
        dik_show_trace((unsigned long *)(regs+1));
-diff -NurpP --minimal linux-2.6.31.6/arch/alpha/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/mm/fault.c
---- linux-2.6.31.6/arch/alpha/mm/fault.c       2009-09-10 15:25:14.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/alpha/mm/fault.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/alpha/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/alpha/mm/fault.c
+--- linux-2.6.32/arch/alpha/mm/fault.c 2009-09-10 15:25:14.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/alpha/mm/fault.c   2009-12-03 20:04:56.000000000 +0100
 @@ -193,8 +193,8 @@ do_page_fault(unsigned long address, uns
                down_read(&mm->mmap_sem);
                goto survive;
@@ -107,10 +107,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/alpha/mm/fault.c linux-2.6.31.6-vs2.3.
        if (!user_mode(regs))
                goto no_context;
        do_group_exit(SIGKILL);
-diff -NurpP --minimal linux-2.6.31.6/arch/arm/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/arm/Kconfig
---- linux-2.6.31.6/arch/arm/Kconfig    2009-09-10 15:25:14.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/arm/Kconfig      2009-09-10 16:11:43.000000000 +0200
-@@ -1483,6 +1483,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/arm/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/arm/Kconfig
+--- linux-2.6.32/arch/arm/Kconfig      2009-12-03 20:01:49.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/arm/Kconfig        2009-12-03 20:04:56.000000000 +0100
+@@ -1512,6 +1512,8 @@ source "fs/Kconfig"
  
  source "arch/arm/Kconfig.debug"
  
@@ -119,9 +119,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/arm/Kconfig linux-2.6.31.6-vs2.3.0.36.
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/arm/kernel/calls.S linux-2.6.31.6-vs2.3.0.36.24/arch/arm/kernel/calls.S
---- linux-2.6.31.6/arch/arm/kernel/calls.S     2009-09-10 15:25:15.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/arm/kernel/calls.S       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/arm/kernel/calls.S linux-2.6.32-vs2.3.0.36.26/arch/arm/kernel/calls.S
+--- linux-2.6.32/arch/arm/kernel/calls.S       2009-12-03 20:01:50.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/arm/kernel/calls.S 2009-12-03 20:04:56.000000000 +0100
 @@ -322,7 +322,7 @@
  /* 310 */     CALL(sys_request_key)
                CALL(sys_keyctl)
@@ -131,9 +131,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/arm/kernel/calls.S linux-2.6.31.6-vs2.
                CALL(sys_ioprio_set)
  /* 315 */     CALL(sys_ioprio_get)
                CALL(sys_inotify_init)
-diff -NurpP --minimal linux-2.6.31.6/arch/arm/kernel/process.c linux-2.6.31.6-vs2.3.0.36.24/arch/arm/kernel/process.c
---- linux-2.6.31.6/arch/arm/kernel/process.c   2009-09-10 15:25:15.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/arm/kernel/process.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/arm/kernel/process.c linux-2.6.32-vs2.3.0.36.26/arch/arm/kernel/process.c
+--- linux-2.6.32/arch/arm/kernel/process.c     2009-12-03 20:01:50.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/arm/kernel/process.c       2009-12-03 20:04:56.000000000 +0100
 @@ -269,7 +269,8 @@ void __show_regs(struct pt_regs *regs)
  void show_regs(struct pt_regs * regs)
  {
@@ -144,36 +144,23 @@ diff -NurpP --minimal linux-2.6.31.6/arch/arm/kernel/process.c linux-2.6.31.6-vs
        __show_regs(regs);
        __backtrace();
  }
-diff -NurpP --minimal linux-2.6.31.6/arch/arm/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/arm/kernel/traps.c
---- linux-2.6.31.6/arch/arm/kernel/traps.c     2009-06-11 17:11:49.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/arm/kernel/traps.c       2009-09-10 16:11:43.000000000 +0200
-@@ -228,8 +228,8 @@ static void __die(const char *str, int e
-              str, err, ++die_counter);
+diff -NurpP --minimal linux-2.6.32/arch/arm/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/arm/kernel/traps.c
+--- linux-2.6.32/arch/arm/kernel/traps.c       2009-12-03 20:01:50.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/arm/kernel/traps.c 2009-12-03 20:04:56.000000000 +0100
+@@ -234,8 +234,8 @@ static void __die(const char *str, int e
+       sysfs_printk_last_file();
        print_modules();
        __show_regs(regs);
--      printk("Process %s (pid: %d, stack limit = 0x%p)\n",
--              tsk->comm, task_pid_nr(tsk), thread + 1);
-+      printk("Process %s (pid: %d:#%u, stack limit = 0x%p)\n",
-+              tsk->comm, task_pid_nr(tsk), tsk->xid, thread + 1);
+-      printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
+-              TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
++      printk(KERN_EMERG "Process %.*s (pid: %d:#%u, stack limit = 0x%p)\n",
++              TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), tsk->xid, thread + 1);
  
        if (!user_mode(regs) || in_interrupt()) {
-               dump_mem("Stack: ", regs->ARM_sp,
-diff -NurpP --minimal linux-2.6.31.6/arch/arm/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/arm/mm/fault.c
---- linux-2.6.31.6/arch/arm/mm/fault.c 2009-09-10 15:25:18.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/arm/mm/fault.c   2009-09-10 16:11:43.000000000 +0200
-@@ -294,7 +294,8 @@ do_page_fault(unsigned long addr, unsign
-                * happened to us that made us unable to handle
-                * the page fault gracefully.
-                */
--              printk("VM: killing process %s\n", tsk->comm);
-+              printk("VM: killing process %s(%d:#%u)\n",
-+                      tsk->comm, task_pid_nr(tsk), tsk->xid);
-               do_group_exit(SIGKILL);
-               return 0;
-       }
-diff -NurpP --minimal linux-2.6.31.6/arch/avr32/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/avr32/mm/fault.c
---- linux-2.6.31.6/arch/avr32/mm/fault.c       2009-09-10 15:25:20.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/avr32/mm/fault.c 2009-09-29 17:32:09.000000000 +0200
+               dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
+diff -NurpP --minimal linux-2.6.32/arch/avr32/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/avr32/mm/fault.c
+--- linux-2.6.32/arch/avr32/mm/fault.c 2009-09-10 15:25:20.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/avr32/mm/fault.c   2009-12-03 20:04:56.000000000 +0100
 @@ -216,7 +216,8 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
@@ -184,9 +171,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/avr32/mm/fault.c linux-2.6.31.6-vs2.3.
        if (user_mode(regs))
                do_group_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/cris/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/cris/Kconfig
---- linux-2.6.31.6/arch/cris/Kconfig   2009-06-11 17:11:56.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/cris/Kconfig     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/cris/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/cris/Kconfig
+--- linux-2.6.32/arch/cris/Kconfig     2009-06-11 17:11:56.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/cris/Kconfig       2009-12-03 20:04:56.000000000 +0100
 @@ -685,6 +685,8 @@ source "drivers/staging/Kconfig"
  
  source "arch/cris/Kconfig.debug"
@@ -196,9 +183,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/cris/Kconfig linux-2.6.31.6-vs2.3.0.36
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/cris/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/cris/mm/fault.c
---- linux-2.6.31.6/arch/cris/mm/fault.c        2009-09-10 15:25:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/cris/mm/fault.c  2009-09-29 17:25:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/cris/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/cris/mm/fault.c
+--- linux-2.6.32/arch/cris/mm/fault.c  2009-12-03 20:01:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/cris/mm/fault.c    2009-12-03 20:04:56.000000000 +0100
 @@ -245,7 +245,8 @@ do_page_fault(unsigned long address, str
  
   out_of_memory:
@@ -209,9 +196,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/cris/mm/fault.c linux-2.6.31.6-vs2.3.0
        if (user_mode(regs))
                do_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/frv/kernel/kernel_thread.S linux-2.6.31.6-vs2.3.0.36.24/arch/frv/kernel/kernel_thread.S
---- linux-2.6.31.6/arch/frv/kernel/kernel_thread.S     2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/frv/kernel/kernel_thread.S       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/frv/kernel/kernel_thread.S linux-2.6.32-vs2.3.0.36.26/arch/frv/kernel/kernel_thread.S
+--- linux-2.6.32/arch/frv/kernel/kernel_thread.S       2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/frv/kernel/kernel_thread.S 2009-12-03 20:04:56.000000000 +0100
 @@ -37,7 +37,7 @@ kernel_thread:
  
        # start by forking the current process, but with shared VM
@@ -221,9 +208,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/frv/kernel/kernel_thread.S linux-2.6.3
        sethi.p         #0xe4e4,gr9             ; second syscall arg    [newsp]
        setlo           #0xe4e4,gr9
        setlos.p        #0,gr10                 ; third syscall arg     [parent_tidptr]
-diff -NurpP --minimal linux-2.6.31.6/arch/frv/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/frv/mm/fault.c
---- linux-2.6.31.6/arch/frv/mm/fault.c 2009-09-10 15:25:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/frv/mm/fault.c   2009-09-29 17:25:48.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/frv/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/frv/mm/fault.c
+--- linux-2.6.32/arch/frv/mm/fault.c   2009-09-10 15:25:22.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/frv/mm/fault.c     2009-12-03 20:04:56.000000000 +0100
 @@ -257,7 +257,8 @@ asmlinkage void do_page_fault(int datamm
   */
   out_of_memory:
@@ -234,9 +221,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/frv/mm/fault.c linux-2.6.31.6-vs2.3.0.
        if (user_mode(__frame))
                do_group_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/h8300/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/h8300/Kconfig
---- linux-2.6.31.6/arch/h8300/Kconfig  2009-03-24 14:18:24.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/h8300/Kconfig    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/h8300/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/h8300/Kconfig
+--- linux-2.6.32/arch/h8300/Kconfig    2009-03-24 14:18:24.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/h8300/Kconfig      2009-12-03 20:04:56.000000000 +0100
 @@ -226,6 +226,8 @@ source "fs/Kconfig"
  
  source "arch/h8300/Kconfig.debug"
@@ -246,9 +233,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/h8300/Kconfig linux-2.6.31.6-vs2.3.0.3
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/ia32/ia32_entry.S linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/ia32/ia32_entry.S
---- linux-2.6.31.6/arch/ia64/ia32/ia32_entry.S 2009-06-11 17:11:57.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/ia32/ia32_entry.S   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/ia64/ia32/ia32_entry.S linux-2.6.32-vs2.3.0.36.26/arch/ia64/ia32/ia32_entry.S
+--- linux-2.6.32/arch/ia64/ia32/ia32_entry.S   2009-06-11 17:11:57.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/ia32/ia32_entry.S     2009-12-03 20:04:56.000000000 +0100
 @@ -451,7 +451,7 @@ ia32_syscall_table:
        data8 sys_tgkill        /* 270 */
        data8 compat_sys_utimes
@@ -258,10 +245,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/ia32/ia32_entry.S linux-2.6.31.6-
        data8 sys_ni_syscall
        data8 sys_ni_syscall    /* 275 */
        data8 sys_ni_syscall
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/Kconfig
---- linux-2.6.31.6/arch/ia64/Kconfig   2009-09-10 15:25:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/Kconfig     2009-09-10 16:11:43.000000000 +0200
-@@ -676,6 +676,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/ia64/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/ia64/Kconfig
+--- linux-2.6.32/arch/ia64/Kconfig     2009-12-03 20:01:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/Kconfig       2009-12-03 20:04:56.000000000 +0100
+@@ -685,6 +685,8 @@ source "fs/Kconfig"
  
  source "arch/ia64/Kconfig.debug"
  
@@ -270,9 +257,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/Kconfig linux-2.6.31.6-vs2.3.0.36
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/entry.S linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/entry.S
---- linux-2.6.31.6/arch/ia64/kernel/entry.S    2009-09-10 15:25:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/entry.S      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/ia64/kernel/entry.S linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/entry.S
+--- linux-2.6.32/arch/ia64/kernel/entry.S      2009-09-10 15:25:22.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/entry.S        2009-12-03 20:04:56.000000000 +0100
 @@ -1753,7 +1753,7 @@ sys_call_table:
        data8 sys_mq_notify
        data8 sys_mq_getsetattr
@@ -282,9 +269,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/entry.S linux-2.6.31.6-vs2
        data8 sys_waitid                        // 1270
        data8 sys_add_key
        data8 sys_request_key
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/perfmon.c linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/perfmon.c
---- linux-2.6.31.6/arch/ia64/kernel/perfmon.c  2009-09-10 15:25:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/perfmon.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/ia64/kernel/perfmon.c linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/perfmon.c
+--- linux-2.6.32/arch/ia64/kernel/perfmon.c    2009-09-10 15:25:22.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/perfmon.c      2009-12-03 20:04:56.000000000 +0100
 @@ -41,6 +41,7 @@
  #include <linux/rcupdate.h>
  #include <linux/completion.h>
@@ -302,9 +289,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/perfmon.c linux-2.6.31.6-v
        vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
                                                        vma_pages(vma));
        up_write(&task->mm->mmap_sem);
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/process.c linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/process.c
---- linux-2.6.31.6/arch/ia64/kernel/process.c  2009-06-11 17:11:57.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/process.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/ia64/kernel/process.c linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/process.c
+--- linux-2.6.32/arch/ia64/kernel/process.c    2009-12-03 20:01:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/process.c      2009-12-03 20:04:56.000000000 +0100
 @@ -110,8 +110,8 @@ show_regs (struct pt_regs *regs)
        unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
  
@@ -316,9 +303,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/process.c linux-2.6.31.6-v
        printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s (%s)\n",
               regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
               init_utsname()->release);
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/ptrace.c
---- linux-2.6.31.6/arch/ia64/kernel/ptrace.c   2009-09-10 15:25:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/ptrace.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/ia64/kernel/ptrace.c linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/ptrace.c
+--- linux-2.6.32/arch/ia64/kernel/ptrace.c     2009-09-10 15:25:22.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/ptrace.c       2009-12-03 20:04:56.000000000 +0100
 @@ -22,6 +22,7 @@
  #include <linux/regset.h>
  #include <linux/elf.h>
@@ -327,9 +314,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/ptrace.c linux-2.6.31.6-vs
  
  #include <asm/pgtable.h>
  #include <asm/processor.h>
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/traps.c
---- linux-2.6.31.6/arch/ia64/kernel/traps.c    2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/kernel/traps.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/ia64/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/traps.c
+--- linux-2.6.32/arch/ia64/kernel/traps.c      2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/kernel/traps.c        2009-12-03 20:04:56.000000000 +0100
 @@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re
        put_cpu();
  
@@ -354,9 +341,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/kernel/traps.c linux-2.6.31.6-vs2
                        }
                }
        }
-diff -NurpP --minimal linux-2.6.31.6/arch/ia64/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/mm/fault.c
---- linux-2.6.31.6/arch/ia64/mm/fault.c        2009-09-10 15:25:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/ia64/mm/fault.c  2009-09-29 17:26:21.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/ia64/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/ia64/mm/fault.c
+--- linux-2.6.32/arch/ia64/mm/fault.c  2009-09-10 15:25:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/ia64/mm/fault.c    2009-12-03 20:04:56.000000000 +0100
 @@ -10,6 +10,7 @@
  #include <linux/interrupt.h>
  #include <linux/kprobes.h>
@@ -375,9 +362,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/ia64/mm/fault.c linux-2.6.31.6-vs2.3.0
        if (user_mode(regs))
                do_group_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/m32r/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/m32r/kernel/traps.c
---- linux-2.6.31.6/arch/m32r/kernel/traps.c    2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m32r/kernel/traps.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/m32r/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/m32r/kernel/traps.c
+--- linux-2.6.32/arch/m32r/kernel/traps.c      2009-12-03 20:01:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/m32r/kernel/traps.c        2009-12-03 20:04:56.000000000 +0100
 @@ -196,8 +196,9 @@ static void show_registers(struct pt_reg
        } else {
                printk("SPI: %08lx\n", sp);
@@ -390,9 +377,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m32r/kernel/traps.c linux-2.6.31.6-vs2
  
        /*
         * When in-kernel, we also print out the stack and code at the
-diff -NurpP --minimal linux-2.6.31.6/arch/m32r/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/m32r/mm/fault.c
---- linux-2.6.31.6/arch/m32r/mm/fault.c        2009-09-10 15:25:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m32r/mm/fault.c  2009-09-29 17:26:48.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/m32r/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/m32r/mm/fault.c
+--- linux-2.6.32/arch/m32r/mm/fault.c  2009-09-10 15:25:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/m32r/mm/fault.c    2009-12-03 20:04:56.000000000 +0100
 @@ -276,7 +276,8 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
@@ -403,10 +390,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m32r/mm/fault.c linux-2.6.31.6-vs2.3.0
        if (error_code & ACE_USERMODE)
                do_group_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/m68k/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/Kconfig
---- linux-2.6.31.6/arch/m68k/Kconfig   2009-11-12 12:10:08.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/Kconfig     2009-11-12 12:26:38.000000000 +0100
-@@ -616,6 +616,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/m68k/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/m68k/Kconfig
+--- linux-2.6.32/arch/m68k/Kconfig     2009-12-03 20:01:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/m68k/Kconfig       2009-12-03 20:04:56.000000000 +0100
+@@ -622,6 +622,8 @@ source "fs/Kconfig"
  
  source "arch/m68k/Kconfig.debug"
  
@@ -415,9 +402,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m68k/Kconfig linux-2.6.31.6-vs2.3.0.36
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/m68k/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/kernel/ptrace.c
---- linux-2.6.31.6/arch/m68k/kernel/ptrace.c   2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/kernel/ptrace.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/m68k/kernel/ptrace.c linux-2.6.32-vs2.3.0.36.26/arch/m68k/kernel/ptrace.c
+--- linux-2.6.32/arch/m68k/kernel/ptrace.c     2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/m68k/kernel/ptrace.c       2009-12-03 20:04:56.000000000 +0100
 @@ -18,6 +18,7 @@
  #include <linux/ptrace.h>
  #include <linux/user.h>
@@ -435,9 +422,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m68k/kernel/ptrace.c linux-2.6.31.6-vs
  
        return ret;
  out_eio:
-diff -NurpP --minimal linux-2.6.31.6/arch/m68k/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/kernel/traps.c
---- linux-2.6.31.6/arch/m68k/kernel/traps.c    2009-09-10 15:25:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/kernel/traps.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/m68k/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/m68k/kernel/traps.c
+--- linux-2.6.32/arch/m68k/kernel/traps.c      2009-09-10 15:25:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/m68k/kernel/traps.c        2009-12-03 20:04:56.000000000 +0100
 @@ -906,8 +906,8 @@ void show_registers(struct pt_regs *regs
        printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
               regs->d4, regs->d5, regs->a0, regs->a1);
@@ -449,9 +436,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m68k/kernel/traps.c linux-2.6.31.6-vs2
        addr = (unsigned long)&fp->un;
        printk("Frame format=%X ", regs->format);
        switch (regs->format) {
-diff -NurpP --minimal linux-2.6.31.6/arch/m68k/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/mm/fault.c
---- linux-2.6.31.6/arch/m68k/mm/fault.c        2009-09-10 15:25:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m68k/mm/fault.c  2009-09-29 17:27:45.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/m68k/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/m68k/mm/fault.c
+--- linux-2.6.32/arch/m68k/mm/fault.c  2009-09-10 15:25:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/m68k/mm/fault.c    2009-12-03 20:04:56.000000000 +0100
 @@ -186,7 +186,8 @@ out_of_memory:
                goto survive;
        }
@@ -462,10 +449,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m68k/mm/fault.c linux-2.6.31.6-vs2.3.0
        if (user_mode(regs))
                do_group_exit(SIGKILL);
  
-diff -NurpP --minimal linux-2.6.31.6/arch/m68knommu/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/m68knommu/Kconfig
---- linux-2.6.31.6/arch/m68knommu/Kconfig      2009-06-11 17:11:59.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m68knommu/Kconfig        2009-09-10 16:11:43.000000000 +0200
-@@ -721,6 +721,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/m68knommu/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/m68knommu/Kconfig
+--- linux-2.6.32/arch/m68knommu/Kconfig        2009-12-03 20:01:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/m68knommu/Kconfig  2009-12-03 20:04:56.000000000 +0100
+@@ -727,6 +727,8 @@ source "fs/Kconfig"
  
  source "arch/m68knommu/Kconfig.debug"
  
@@ -474,9 +461,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m68knommu/Kconfig linux-2.6.31.6-vs2.3
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/m68knommu/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/m68knommu/kernel/traps.c
---- linux-2.6.31.6/arch/m68knommu/kernel/traps.c       2009-09-10 15:25:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/m68knommu/kernel/traps.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/m68knommu/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/m68knommu/kernel/traps.c
+--- linux-2.6.32/arch/m68knommu/kernel/traps.c 2009-09-10 15:25:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/m68knommu/kernel/traps.c   2009-12-03 20:04:56.000000000 +0100
 @@ -78,8 +78,9 @@ void die_if_kernel(char *str, struct pt_
        printk(KERN_EMERG "d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
               fp->d4, fp->d5, fp->a0, fp->a1);
@@ -489,9 +476,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/m68knommu/kernel/traps.c linux-2.6.31.
        show_stack(NULL, (unsigned long *)(fp + 1));
        add_taint(TAINT_DIE);
        do_exit(SIGSEGV);
-diff -NurpP --minimal linux-2.6.31.6/arch/microblaze/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/microblaze/mm/fault.c
---- linux-2.6.31.6/arch/microblaze/mm/fault.c  2009-09-10 15:25:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/microblaze/mm/fault.c    2009-09-29 17:28:08.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/microblaze/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/microblaze/mm/fault.c
+--- linux-2.6.32/arch/microblaze/mm/fault.c    2009-09-10 15:25:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/microblaze/mm/fault.c      2009-12-03 20:04:56.000000000 +0100
 @@ -279,7 +279,8 @@ out_of_memory:
                goto survive;
        }
@@ -502,10 +489,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/microblaze/mm/fault.c linux-2.6.31.6-v
        if (user_mode(regs))
                do_exit(SIGKILL);
        bad_page_fault(regs, address, SIGKILL);
-diff -NurpP --minimal linux-2.6.31.6/arch/mips/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/mips/Kconfig
---- linux-2.6.31.6/arch/mips/Kconfig   2009-09-10 15:25:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mips/Kconfig     2009-09-10 16:11:43.000000000 +0200
-@@ -2186,6 +2186,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/mips/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/mips/Kconfig
+--- linux-2.6.32/arch/mips/Kconfig     2009-12-03 20:01:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/mips/Kconfig       2009-12-03 20:04:56.000000000 +0100
+@@ -2188,6 +2188,8 @@ source "fs/Kconfig"
  
  source "arch/mips/Kconfig.debug"
  
@@ -514,9 +501,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mips/Kconfig linux-2.6.31.6-vs2.3.0.36
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/ptrace.c
---- linux-2.6.31.6/arch/mips/kernel/ptrace.c   2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/ptrace.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/mips/kernel/ptrace.c linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/ptrace.c
+--- linux-2.6.32/arch/mips/kernel/ptrace.c     2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/ptrace.c       2009-12-03 20:04:56.000000000 +0100
 @@ -25,6 +25,7 @@
  #include <linux/security.h>
  #include <linux/audit.h>
@@ -535,10 +522,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/ptrace.c linux-2.6.31.6-vs
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */
-diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall32-o32.S linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall32-o32.S
---- linux-2.6.31.6/arch/mips/kernel/scall32-o32.S      2009-09-10 15:25:38.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall32-o32.S        2009-09-10 16:11:43.000000000 +0200
-@@ -597,7 +597,7 @@ einval:    li      v0, -ENOSYS
+diff -NurpP --minimal linux-2.6.32/arch/mips/kernel/scall32-o32.S linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall32-o32.S
+--- linux-2.6.32/arch/mips/kernel/scall32-o32.S        2009-12-03 20:01:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall32-o32.S  2009-12-03 20:04:56.000000000 +0100
+@@ -525,7 +525,7 @@ einval:    li      v0, -ENOSYS
        sys     sys_mq_timedreceive     5
        sys     sys_mq_notify           2       /* 4275 */
        sys     sys_mq_getsetattr       3
@@ -547,10 +534,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall32-o32.S linux-2.6.31
        sys     sys_waitid              5
        sys     sys_ni_syscall          0       /* available, was setaltroot */
        sys     sys_add_key             5       /* 4280 */
-diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall64-64.S linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall64-64.S
---- linux-2.6.31.6/arch/mips/kernel/scall64-64.S       2009-09-10 15:25:38.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall64-64.S 2009-09-10 16:11:43.000000000 +0200
-@@ -434,7 +434,7 @@ sys_call_table:
+diff -NurpP --minimal linux-2.6.32/arch/mips/kernel/scall64-64.S linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall64-64.S
+--- linux-2.6.32/arch/mips/kernel/scall64-64.S 2009-12-03 20:01:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall64-64.S   2009-12-03 20:04:56.000000000 +0100
+@@ -362,7 +362,7 @@ sys_call_table:
        PTR     sys_mq_timedreceive
        PTR     sys_mq_notify
        PTR     sys_mq_getsetattr               /* 5235 */
@@ -559,9 +546,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall64-64.S linux-2.6.31.
        PTR     sys_waitid
        PTR     sys_ni_syscall                  /* available, was setaltroot */
        PTR     sys_add_key
-diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall64-n32.S linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall64-n32.S
---- linux-2.6.31.6/arch/mips/kernel/scall64-n32.S      2009-09-10 15:25:38.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall64-n32.S        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/mips/kernel/scall64-n32.S linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall64-n32.S
+--- linux-2.6.32/arch/mips/kernel/scall64-n32.S        2009-12-03 20:01:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall64-n32.S  2009-12-03 20:04:56.000000000 +0100
 @@ -360,7 +360,7 @@ EXPORT(sysn32_call_table)
        PTR     compat_sys_mq_timedreceive
        PTR     compat_sys_mq_notify
@@ -571,9 +558,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall64-n32.S linux-2.6.31
        PTR     compat_sys_waitid
        PTR     sys_ni_syscall                  /* available, was setaltroot */
        PTR     sys_add_key
-diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall64-o32.S linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall64-o32.S
---- linux-2.6.31.6/arch/mips/kernel/scall64-o32.S      2009-09-10 15:25:38.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/scall64-o32.S        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/mips/kernel/scall64-o32.S linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall64-o32.S
+--- linux-2.6.32/arch/mips/kernel/scall64-o32.S        2009-12-03 20:01:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/scall64-o32.S  2009-12-03 20:04:56.000000000 +0100
 @@ -480,7 +480,7 @@ sys_call_table:
        PTR     compat_sys_mq_timedreceive
        PTR     compat_sys_mq_notify            /* 4275 */
@@ -583,9 +570,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/scall64-o32.S linux-2.6.31
        PTR     sys_32_waitid
        PTR     sys_ni_syscall                  /* available, was setaltroot */
        PTR     sys_add_key                     /* 4280 */
-diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/traps.c
---- linux-2.6.31.6/arch/mips/kernel/traps.c    2009-09-10 15:25:38.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mips/kernel/traps.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/mips/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/traps.c
+--- linux-2.6.32/arch/mips/kernel/traps.c      2009-12-03 20:01:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/mips/kernel/traps.c        2009-12-03 20:04:56.000000000 +0100
 @@ -335,9 +335,10 @@ void show_registers(const struct pt_regs
  
        __show_regs(regs);
@@ -600,9 +587,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mips/kernel/traps.c linux-2.6.31.6-vs2
        if (cpu_has_userlocal) {
                unsigned long tls;
  
-diff -NurpP --minimal linux-2.6.31.6/arch/mn10300/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/mn10300/mm/fault.c
---- linux-2.6.31.6/arch/mn10300/mm/fault.c     2009-09-10 15:25:39.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/mn10300/mm/fault.c       2009-09-29 17:28:34.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/mn10300/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/mn10300/mm/fault.c
+--- linux-2.6.32/arch/mn10300/mm/fault.c       2009-09-10 15:25:39.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/mn10300/mm/fault.c 2009-12-03 20:04:56.000000000 +0100
 @@ -339,7 +339,8 @@ no_context:
  out_of_memory:
        up_read(&mm->mmap_sem);
@@ -613,10 +600,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/mn10300/mm/fault.c linux-2.6.31.6-vs2.
        if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR)
                do_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/parisc/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/Kconfig
---- linux-2.6.31.6/arch/parisc/Kconfig 2009-09-10 15:25:39.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/Kconfig   2009-09-10 16:11:43.000000000 +0200
-@@ -293,6 +293,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/parisc/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/parisc/Kconfig
+--- linux-2.6.32/arch/parisc/Kconfig   2009-12-03 20:02:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/parisc/Kconfig     2009-12-03 20:04:56.000000000 +0100
+@@ -294,6 +294,8 @@ source "fs/Kconfig"
  
  source "arch/parisc/Kconfig.debug"
  
@@ -625,9 +612,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/parisc/Kconfig linux-2.6.31.6-vs2.3.0.
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/parisc/kernel/syscall_table.S linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/kernel/syscall_table.S
---- linux-2.6.31.6/arch/parisc/kernel/syscall_table.S  2009-09-10 15:25:40.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/kernel/syscall_table.S    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/parisc/kernel/syscall_table.S linux-2.6.32-vs2.3.0.36.26/arch/parisc/kernel/syscall_table.S
+--- linux-2.6.32/arch/parisc/kernel/syscall_table.S    2009-12-03 20:02:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/parisc/kernel/syscall_table.S      2009-12-03 20:04:56.000000000 +0100
 @@ -361,7 +361,7 @@
        ENTRY_COMP(mbind)               /* 260 */
        ENTRY_COMP(get_mempolicy)
@@ -637,9 +624,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/parisc/kernel/syscall_table.S linux-2.
        ENTRY_SAME(add_key)
        ENTRY_SAME(request_key)         /* 265 */
        ENTRY_SAME(keyctl)
-diff -NurpP --minimal linux-2.6.31.6/arch/parisc/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/kernel/traps.c
---- linux-2.6.31.6/arch/parisc/kernel/traps.c  2009-09-10 15:25:40.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/kernel/traps.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/parisc/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/parisc/kernel/traps.c
+--- linux-2.6.32/arch/parisc/kernel/traps.c    2009-09-10 15:25:40.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/parisc/kernel/traps.c      2009-12-03 20:04:56.000000000 +0100
 @@ -236,8 +236,9 @@ void die_if_kernel(char *str, struct pt_
                if (err == 0)
                        return; /* STFU */
@@ -663,9 +650,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/parisc/kernel/traps.c linux-2.6.31.6-v
  
        /* Wot's wrong wif bein' racy? */
        if (current->thread.flags & PARISC_KERNEL_DEATH) {
-diff -NurpP --minimal linux-2.6.31.6/arch/parisc/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/mm/fault.c
---- linux-2.6.31.6/arch/parisc/mm/fault.c      2009-09-10 15:25:40.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/parisc/mm/fault.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/parisc/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/parisc/mm/fault.c
+--- linux-2.6.32/arch/parisc/mm/fault.c        2009-09-10 15:25:40.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/parisc/mm/fault.c  2009-12-03 20:04:56.000000000 +0100
 @@ -237,8 +237,9 @@ bad_area:
  
  #ifdef PRINT_USER_FAULTS
@@ -688,9 +675,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/parisc/mm/fault.c linux-2.6.31.6-vs2.3
        if (user_mode(regs))
                do_group_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/include/asm/unistd.h linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/include/asm/unistd.h
---- linux-2.6.31.6/arch/powerpc/include/asm/unistd.h   2009-09-10 15:25:41.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/include/asm/unistd.h     2009-10-22 01:07:37.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/powerpc/include/asm/unistd.h linux-2.6.32-vs2.3.0.36.26/arch/powerpc/include/asm/unistd.h
+--- linux-2.6.32/arch/powerpc/include/asm/unistd.h     2009-12-03 20:02:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/powerpc/include/asm/unistd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -275,7 +275,7 @@
  #endif
  #define __NR_rtas             255
@@ -700,10 +687,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/include/asm/unistd.h linux-2.6
  #define __NR_migrate_pages    258
  #define __NR_mbind            259
  #define __NR_get_mempolicy    260
-diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/Kconfig
---- linux-2.6.31.6/arch/powerpc/Kconfig        2009-09-10 15:25:40.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/Kconfig  2009-09-10 16:11:43.000000000 +0200
-@@ -933,6 +933,8 @@ source "lib/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/powerpc/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/powerpc/Kconfig
+--- linux-2.6.32/arch/powerpc/Kconfig  2009-12-03 20:02:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/powerpc/Kconfig    2009-12-03 20:04:56.000000000 +0100
+@@ -943,6 +943,8 @@ source "lib/Kconfig"
  
  source "arch/powerpc/Kconfig.debug"
  
@@ -712,20 +699,20 @@ diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/Kconfig linux-2.6.31.6-vs2.3.0
  source "security/Kconfig"
  
  config KEYS_COMPAT
-diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/kernel/irq.c linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/irq.c
---- linux-2.6.31.6/arch/powerpc/kernel/irq.c   2009-09-10 15:25:41.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/irq.c     2009-09-10 16:15:56.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/powerpc/kernel/irq.c linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/irq.c
+--- linux-2.6.32/arch/powerpc/kernel/irq.c     2009-12-03 20:02:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/irq.c       2009-12-03 20:04:56.000000000 +0100
 @@ -54,6 +54,7 @@
  #include <linux/pci.h>
  #include <linux/debugfs.h>
- #include <linux/perf_counter.h>
-+#include <linux/vs_context.h>
+ #include <linux/perf_event.h>
++// #include <linux/vs_context.h>
  
  #include <asm/uaccess.h>
  #include <asm/system.h>
-diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/kernel/process.c linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/process.c
---- linux-2.6.31.6/arch/powerpc/kernel/process.c       2009-09-10 15:25:41.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/process.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/powerpc/kernel/process.c linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/process.c
+--- linux-2.6.32/arch/powerpc/kernel/process.c 2009-12-03 20:02:02.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/process.c   2009-12-03 20:04:56.000000000 +0100
 @@ -519,8 +519,9 @@ void show_regs(struct pt_regs * regs)
  #else
                printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
@@ -738,9 +725,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/kernel/process.c linux-2.6.31.
  
  #ifdef CONFIG_SMP
        printk(" CPU: %d", raw_smp_processor_id());
-diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/kernel/traps.c linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/traps.c
---- linux-2.6.31.6/arch/powerpc/kernel/traps.c 2009-09-10 15:25:41.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/traps.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/powerpc/kernel/traps.c linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/traps.c
+--- linux-2.6.32/arch/powerpc/kernel/traps.c   2009-09-10 15:25:41.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/traps.c     2009-12-03 20:04:56.000000000 +0100
 @@ -931,8 +931,9 @@ void nonrecoverable_exception(struct pt_
  
  void trace_syscall(struct pt_regs *regs)
@@ -753,10 +740,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/kernel/traps.c linux-2.6.31.6-
               regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
  }
  
-diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/kernel/vdso.c linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/vdso.c
---- linux-2.6.31.6/arch/powerpc/kernel/vdso.c  2009-03-24 14:18:35.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/kernel/vdso.c    2009-09-10 16:11:43.000000000 +0200
-@@ -22,6 +22,7 @@
+diff -NurpP --minimal linux-2.6.32/arch/powerpc/kernel/vdso.c linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/vdso.c
+--- linux-2.6.32/arch/powerpc/kernel/vdso.c    2009-12-03 20:02:02.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/powerpc/kernel/vdso.c      2009-12-03 20:04:56.000000000 +0100
+@@ -23,6 +23,7 @@
  #include <linux/security.h>
  #include <linux/bootmem.h>
  #include <linux/lmb.h>
@@ -764,9 +751,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/kernel/vdso.c linux-2.6.31.6-v
  
  #include <asm/pgtable.h>
  #include <asm/system.h>
-diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/mm/fault.c
---- linux-2.6.31.6/arch/powerpc/mm/fault.c     2009-09-10 15:25:41.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/powerpc/mm/fault.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/powerpc/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/powerpc/mm/fault.c
+--- linux-2.6.32/arch/powerpc/mm/fault.c       2009-12-03 20:02:02.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/powerpc/mm/fault.c 2009-12-03 20:04:56.000000000 +0100
 @@ -358,7 +358,8 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
@@ -777,10 +764,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/powerpc/mm/fault.c linux-2.6.31.6-vs2.
        if (user_mode(regs))
                do_group_exit(SIGKILL);
        return SIGKILL;
-diff -NurpP --minimal linux-2.6.31.6/arch/s390/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/s390/Kconfig
---- linux-2.6.31.6/arch/s390/Kconfig   2009-09-10 15:25:42.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/s390/Kconfig     2009-09-10 16:11:43.000000000 +0200
-@@ -624,6 +624,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/s390/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/s390/Kconfig
+--- linux-2.6.32/arch/s390/Kconfig     2009-12-03 20:02:03.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/s390/Kconfig       2009-12-03 20:04:56.000000000 +0100
+@@ -616,6 +616,8 @@ source "fs/Kconfig"
  
  source "arch/s390/Kconfig.debug"
  
@@ -789,9 +776,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/s390/Kconfig linux-2.6.31.6-vs2.3.0.36
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/s390/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.24/arch/s390/kernel/ptrace.c
---- linux-2.6.31.6/arch/s390/kernel/ptrace.c   2009-09-10 15:25:43.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/s390/kernel/ptrace.c     2009-09-10 16:17:22.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/s390/kernel/ptrace.c linux-2.6.32-vs2.3.0.36.26/arch/s390/kernel/ptrace.c
+--- linux-2.6.32/arch/s390/kernel/ptrace.c     2009-12-03 20:02:03.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/s390/kernel/ptrace.c       2009-12-03 20:04:56.000000000 +0100
 @@ -36,6 +36,7 @@
  #include <linux/regset.h>
  #include <linux/tracehook.h>
@@ -800,9 +787,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/s390/kernel/ptrace.c linux-2.6.31.6-vs
  #include <trace/syscall.h>
  #include <asm/compat.h>
  #include <asm/segment.h>
-diff -NurpP --minimal linux-2.6.31.6/arch/s390/kernel/syscalls.S linux-2.6.31.6-vs2.3.0.36.24/arch/s390/kernel/syscalls.S
---- linux-2.6.31.6/arch/s390/kernel/syscalls.S 2009-09-10 15:25:43.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/s390/kernel/syscalls.S   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/s390/kernel/syscalls.S linux-2.6.32-vs2.3.0.36.26/arch/s390/kernel/syscalls.S
+--- linux-2.6.32/arch/s390/kernel/syscalls.S   2009-12-03 20:02:03.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/s390/kernel/syscalls.S     2009-12-03 20:04:56.000000000 +0100
 @@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett
  SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper)      /* 260 */
  SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper)
@@ -812,9 +799,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/s390/kernel/syscalls.S linux-2.6.31.6-
  SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper)
  SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper)
  SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper)
-diff -NurpP --minimal linux-2.6.31.6/arch/s390/lib/uaccess_pt.c linux-2.6.31.6-vs2.3.0.36.24/arch/s390/lib/uaccess_pt.c
---- linux-2.6.31.6/arch/s390/lib/uaccess_pt.c  2009-09-10 15:25:43.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/s390/lib/uaccess_pt.c    2009-09-29 17:29:02.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/s390/lib/uaccess_pt.c linux-2.6.32-vs2.3.0.36.26/arch/s390/lib/uaccess_pt.c
+--- linux-2.6.32/arch/s390/lib/uaccess_pt.c    2009-09-10 15:25:43.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/s390/lib/uaccess_pt.c      2009-12-03 20:04:56.000000000 +0100
 @@ -90,7 +90,8 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
@@ -825,10 +812,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/s390/lib/uaccess_pt.c linux-2.6.31.6-v
        return ret;
  
  out_sigbus:
-diff -NurpP --minimal linux-2.6.31.6/arch/sh/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/sh/Kconfig
---- linux-2.6.31.6/arch/sh/Kconfig     2009-09-10 15:25:43.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sh/Kconfig       2009-09-10 16:11:43.000000000 +0200
-@@ -813,6 +813,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/sh/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/sh/Kconfig
+--- linux-2.6.32/arch/sh/Kconfig       2009-12-03 20:02:03.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sh/Kconfig 2009-12-03 20:04:56.000000000 +0100
+@@ -853,6 +853,8 @@ source "fs/Kconfig"
  
  source "arch/sh/Kconfig.debug"
  
@@ -837,20 +824,20 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sh/Kconfig linux-2.6.31.6-vs2.3.0.36.2
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/sh/kernel/irq.c linux-2.6.31.6-vs2.3.0.36.24/arch/sh/kernel/irq.c
---- linux-2.6.31.6/arch/sh/kernel/irq.c        2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sh/kernel/irq.c  2009-09-10 16:11:43.000000000 +0200
-@@ -11,6 +11,7 @@
- #include <linux/module.h>
+diff -NurpP --minimal linux-2.6.32/arch/sh/kernel/irq.c linux-2.6.32-vs2.3.0.36.26/arch/sh/kernel/irq.c
+--- linux-2.6.32/arch/sh/kernel/irq.c  2009-12-03 20:02:10.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sh/kernel/irq.c    2009-12-03 20:04:56.000000000 +0100
+@@ -12,6 +12,7 @@
  #include <linux/kernel_stat.h>
  #include <linux/seq_file.h>
-+#include <linux/vs_context.h>
+ #include <linux/ftrace.h>
++// #include <linux/vs_context.h>
  #include <asm/processor.h>
  #include <asm/machvec.h>
  #include <asm/uaccess.h>
-diff -NurpP --minimal linux-2.6.31.6/arch/sh/kernel/vsyscall/vsyscall.c linux-2.6.31.6-vs2.3.0.36.24/arch/sh/kernel/vsyscall/vsyscall.c
---- linux-2.6.31.6/arch/sh/kernel/vsyscall/vsyscall.c  2009-03-24 14:18:42.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sh/kernel/vsyscall/vsyscall.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/sh/kernel/vsyscall/vsyscall.c linux-2.6.32-vs2.3.0.36.26/arch/sh/kernel/vsyscall/vsyscall.c
+--- linux-2.6.32/arch/sh/kernel/vsyscall/vsyscall.c    2009-03-24 14:18:42.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sh/kernel/vsyscall/vsyscall.c      2009-12-03 20:04:56.000000000 +0100
 @@ -19,6 +19,7 @@
  #include <linux/elf.h>
  #include <linux/sched.h>
@@ -859,10 +846,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sh/kernel/vsyscall/vsyscall.c linux-2.
  
  /*
   * Should the kernel map a VDSO page into processes and pass its
-diff -NurpP --minimal linux-2.6.31.6/arch/sh/mm/fault_32.c linux-2.6.31.6-vs2.3.0.36.24/arch/sh/mm/fault_32.c
---- linux-2.6.31.6/arch/sh/mm/fault_32.c       2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sh/mm/fault_32.c 2009-09-29 17:29:36.000000000 +0200
-@@ -246,7 +246,8 @@ out_of_memory:
+diff -NurpP --minimal linux-2.6.32/arch/sh/mm/fault_32.c linux-2.6.32-vs2.3.0.36.26/arch/sh/mm/fault_32.c
+--- linux-2.6.32/arch/sh/mm/fault_32.c 2009-12-03 20:02:14.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sh/mm/fault_32.c   2009-12-03 20:04:56.000000000 +0100
+@@ -292,7 +292,8 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
        }
@@ -872,9 +859,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sh/mm/fault_32.c linux-2.6.31.6-vs2.3.
        if (user_mode(regs))
                do_group_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/sh/mm/tlbflush_64.c linux-2.6.31.6-vs2.3.0.36.24/arch/sh/mm/tlbflush_64.c
---- linux-2.6.31.6/arch/sh/mm/tlbflush_64.c    2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sh/mm/tlbflush_64.c      2009-09-29 17:29:54.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/sh/mm/tlbflush_64.c linux-2.6.32-vs2.3.0.36.26/arch/sh/mm/tlbflush_64.c
+--- linux-2.6.32/arch/sh/mm/tlbflush_64.c      2009-12-03 20:02:14.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sh/mm/tlbflush_64.c        2009-12-03 20:04:56.000000000 +0100
 @@ -306,7 +306,8 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
@@ -885,9 +872,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sh/mm/tlbflush_64.c linux-2.6.31.6-vs2
        if (user_mode(regs))
                do_group_exit(SIGKILL);
        goto no_context;
-diff -NurpP --minimal linux-2.6.31.6/arch/sparc/include/asm/tlb_64.h linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/include/asm/tlb_64.h
---- linux-2.6.31.6/arch/sparc/include/asm/tlb_64.h     2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/include/asm/tlb_64.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/sparc/include/asm/tlb_64.h linux-2.6.32-vs2.3.0.36.26/arch/sparc/include/asm/tlb_64.h
+--- linux-2.6.32/arch/sparc/include/asm/tlb_64.h       2009-09-10 15:25:45.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/sparc/include/asm/tlb_64.h 2009-12-03 20:04:56.000000000 +0100
 @@ -3,6 +3,7 @@
  
  #include <linux/swap.h>
@@ -896,9 +883,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sparc/include/asm/tlb_64.h linux-2.6.3
  #include <asm/pgalloc.h>
  #include <asm/tlbflush.h>
  #include <asm/mmu_context.h>
-diff -NurpP --minimal linux-2.6.31.6/arch/sparc/include/asm/unistd.h linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/include/asm/unistd.h
---- linux-2.6.31.6/arch/sparc/include/asm/unistd.h     2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/include/asm/unistd.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/sparc/include/asm/unistd.h linux-2.6.32-vs2.3.0.36.26/arch/sparc/include/asm/unistd.h
+--- linux-2.6.32/arch/sparc/include/asm/unistd.h       2009-12-03 20:02:15.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sparc/include/asm/unistd.h 2009-12-03 20:04:56.000000000 +0100
 @@ -335,7 +335,7 @@
  #define __NR_timer_getoverrun 264
  #define __NR_timer_delete     265
@@ -908,10 +895,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sparc/include/asm/unistd.h linux-2.6.3
  #define __NR_io_setup         268
  #define __NR_io_destroy               269
  #define __NR_io_submit                270
-diff -NurpP --minimal linux-2.6.31.6/arch/sparc/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/Kconfig
---- linux-2.6.31.6/arch/sparc/Kconfig  2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/Kconfig    2009-09-10 16:11:43.000000000 +0200
-@@ -530,6 +530,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/sparc/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/sparc/Kconfig
+--- linux-2.6.32/arch/sparc/Kconfig    2009-12-03 20:02:14.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sparc/Kconfig      2009-12-03 20:04:56.000000000 +0100
+@@ -550,6 +550,8 @@ source "fs/Kconfig"
  
  source "arch/sparc/Kconfig.debug"
  
@@ -920,9 +907,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sparc/Kconfig linux-2.6.31.6-vs2.3.0.3
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/sparc/kernel/systbls_32.S linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/kernel/systbls_32.S
---- linux-2.6.31.6/arch/sparc/kernel/systbls_32.S      2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/kernel/systbls_32.S        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/sparc/kernel/systbls_32.S linux-2.6.32-vs2.3.0.36.26/arch/sparc/kernel/systbls_32.S
+--- linux-2.6.32/arch/sparc/kernel/systbls_32.S        2009-12-03 20:02:15.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sparc/kernel/systbls_32.S  2009-12-03 20:04:56.000000000 +0100
 @@ -70,7 +70,7 @@ sys_call_table:
  /*250*/       .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
  /*255*/       .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
@@ -932,9 +919,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sparc/kernel/systbls_32.S linux-2.6.31
  /*270*/       .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
  /*275*/       .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
  /*280*/       .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
-diff -NurpP --minimal linux-2.6.31.6/arch/sparc/kernel/systbls_64.S linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/kernel/systbls_64.S
---- linux-2.6.31.6/arch/sparc/kernel/systbls_64.S      2009-09-10 15:25:45.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/sparc/kernel/systbls_64.S        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/sparc/kernel/systbls_64.S linux-2.6.32-vs2.3.0.36.26/arch/sparc/kernel/systbls_64.S
+--- linux-2.6.32/arch/sparc/kernel/systbls_64.S        2009-12-03 20:02:15.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/sparc/kernel/systbls_64.S  2009-12-03 20:04:56.000000000 +0100
 @@ -71,7 +71,7 @@ sys_call_table32:
  /*250*/       .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
        .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
@@ -953,9 +940,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/sparc/kernel/systbls_64.S linux-2.6.31
  /*270*/       .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
        .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
  /*280*/       .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
-diff -NurpP --minimal linux-2.6.31.6/arch/x86/ia32/ia32entry.S linux-2.6.31.6-vs2.3.0.36.24/arch/x86/ia32/ia32entry.S
---- linux-2.6.31.6/arch/x86/ia32/ia32entry.S   2009-11-12 12:10:08.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/x86/ia32/ia32entry.S     2009-11-12 12:26:38.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/arch/x86/ia32/ia32entry.S linux-2.6.32-vs2.3.0.36.26/arch/x86/ia32/ia32entry.S
+--- linux-2.6.32/arch/x86/ia32/ia32entry.S     2009-12-03 20:02:15.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/x86/ia32/ia32entry.S       2009-12-03 20:04:56.000000000 +0100
 @@ -777,7 +777,7 @@ ia32_sys_call_table:
        .quad sys_tgkill                /* 270 */
        .quad compat_sys_utimes
@@ -965,9 +952,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/x86/ia32/ia32entry.S linux-2.6.31.6-vs
        .quad sys_mbind
        .quad compat_sys_get_mempolicy  /* 275 */
        .quad sys_set_mempolicy
-diff -NurpP --minimal linux-2.6.31.6/arch/x86/include/asm/unistd_64.h linux-2.6.31.6-vs2.3.0.36.24/arch/x86/include/asm/unistd_64.h
---- linux-2.6.31.6/arch/x86/include/asm/unistd_64.h    2009-09-10 15:25:47.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/x86/include/asm/unistd_64.h      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/x86/include/asm/unistd_64.h linux-2.6.32-vs2.3.0.36.26/arch/x86/include/asm/unistd_64.h
+--- linux-2.6.32/arch/x86/include/asm/unistd_64.h      2009-12-03 20:02:16.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/x86/include/asm/unistd_64.h        2009-12-03 20:04:56.000000000 +0100
 @@ -535,7 +535,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill)
  #define __NR_utimes                           235
  __SYSCALL(__NR_utimes, sys_utimes)
@@ -977,10 +964,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/x86/include/asm/unistd_64.h linux-2.6.
  #define __NR_mbind                            237
  __SYSCALL(__NR_mbind, sys_mbind)
  #define __NR_set_mempolicy                    238
-diff -NurpP --minimal linux-2.6.31.6/arch/x86/Kconfig linux-2.6.31.6-vs2.3.0.36.24/arch/x86/Kconfig
---- linux-2.6.31.6/arch/x86/Kconfig    2009-09-10 15:25:46.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/x86/Kconfig      2009-09-10 16:11:43.000000000 +0200
-@@ -2088,6 +2088,8 @@ source "fs/Kconfig"
+diff -NurpP --minimal linux-2.6.32/arch/x86/Kconfig linux-2.6.32-vs2.3.0.36.26/arch/x86/Kconfig
+--- linux-2.6.32/arch/x86/Kconfig      2009-12-03 20:02:15.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/x86/Kconfig        2009-12-03 20:04:56.000000000 +0100
+@@ -2085,6 +2085,8 @@ source "fs/Kconfig"
  
  source "arch/x86/Kconfig.debug"
  
@@ -989,9 +976,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/x86/Kconfig linux-2.6.31.6-vs2.3.0.36.
  source "security/Kconfig"
  
  source "crypto/Kconfig"
-diff -NurpP --minimal linux-2.6.31.6/arch/x86/kernel/syscall_table_32.S linux-2.6.31.6-vs2.3.0.36.24/arch/x86/kernel/syscall_table_32.S
---- linux-2.6.31.6/arch/x86/kernel/syscall_table_32.S  2009-09-10 15:25:47.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/x86/kernel/syscall_table_32.S    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/x86/kernel/syscall_table_32.S linux-2.6.32-vs2.3.0.36.26/arch/x86/kernel/syscall_table_32.S
+--- linux-2.6.32/arch/x86/kernel/syscall_table_32.S    2009-12-03 20:02:16.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/arch/x86/kernel/syscall_table_32.S      2009-12-03 20:04:56.000000000 +0100
 @@ -272,7 +272,7 @@ ENTRY(sys_call_table)
        .long sys_tgkill        /* 270 */
        .long sys_utimes
@@ -1001,9 +988,9 @@ diff -NurpP --minimal linux-2.6.31.6/arch/x86/kernel/syscall_table_32.S linux-2.
        .long sys_mbind
        .long sys_get_mempolicy
        .long sys_set_mempolicy
-diff -NurpP --minimal linux-2.6.31.6/arch/xtensa/mm/fault.c linux-2.6.31.6-vs2.3.0.36.24/arch/xtensa/mm/fault.c
---- linux-2.6.31.6/arch/xtensa/mm/fault.c      2009-09-10 15:25:48.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/arch/xtensa/mm/fault.c        2009-09-29 17:30:14.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/arch/xtensa/mm/fault.c linux-2.6.32-vs2.3.0.36.26/arch/xtensa/mm/fault.c
+--- linux-2.6.32/arch/xtensa/mm/fault.c        2009-09-10 15:25:48.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/arch/xtensa/mm/fault.c  2009-12-03 20:04:56.000000000 +0100
 @@ -151,7 +151,8 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
@@ -1014,10 +1001,10 @@ diff -NurpP --minimal linux-2.6.31.6/arch/xtensa/mm/fault.c linux-2.6.31.6-vs2.3
        if (user_mode(regs))
                do_group_exit(SIGKILL);
        bad_page_fault(regs, address, SIGKILL);
-diff -NurpP --minimal linux-2.6.31.6/Documentation/scheduler/sched-cfs-hard-limits.txt linux-2.6.31.6-vs2.3.0.36.24/Documentation/scheduler/sched-cfs-hard-limits.txt
---- linux-2.6.31.6/Documentation/scheduler/sched-cfs-hard-limits.txt   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/Documentation/scheduler/sched-cfs-hard-limits.txt     2009-10-06 04:39:46.000000000 +0200
-@@ -0,0 +1,52 @@
+diff -NurpP --minimal linux-2.6.32/Documentation/scheduler/sched-cfs-hard-limits.txt linux-2.6.32-vs2.3.0.36.26/Documentation/scheduler/sched-cfs-hard-limits.txt
+--- linux-2.6.32/Documentation/scheduler/sched-cfs-hard-limits.txt     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/Documentation/scheduler/sched-cfs-hard-limits.txt       2009-12-03 20:04:56.000000000 +0100
+@@ -0,0 +1,48 @@
 +CPU HARD LIMITS FOR CFS GROUPS
 +==============================
 +
@@ -1046,19 +1033,16 @@ diff -NurpP --minimal linux-2.6.31.6/Documentation/scheduler/sched-cfs-hard-limi
 +2. Interface
 +------------
 +
-+Hard limit feature adds 3 cgroup files for CFS group scheduler:
++Hard limit feature adds 2 cgroup files for CFS group scheduler:
 +
 +cfs_runtime_us: Hard limit for the group in microseconds.
 +
 +cfs_period_us: Time period in microseconds within which hard limits is
 +enforced.
 +
-+cfs_hard_limit: The control file to enable or disable hard limiting for the
-+group.
-+
-+A group gets created with default values for runtime and period and with
-+hard limit disabled. Each group can set its own values for runtime and period
-+independent of other groups in the system.
++A group gets created with default values for runtime (infinite runtime which
++means hard limits disabled) and period (0.5s). Each group can set its own
++values for runtime and period independent of other groups in the system.
 +
 +3. Examples
 +-----------
@@ -1069,10 +1053,9 @@ diff -NurpP --minimal linux-2.6.31.6/Documentation/scheduler/sched-cfs-hard-limi
 +# cd 1/
 +# echo 250000 > cfs_runtime_us /* set a 250ms runtime or limit */
 +# echo 500000 > cfs_period_us /* set a 500ms period */
-+# echo 1 > cfs_hard_limit /* enable hard limiting for group 1/ */
-diff -NurpP --minimal linux-2.6.31.6/Documentation/vserver/debug.txt linux-2.6.31.6-vs2.3.0.36.24/Documentation/vserver/debug.txt
---- linux-2.6.31.6/Documentation/vserver/debug.txt     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/Documentation/vserver/debug.txt       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/Documentation/vserver/debug.txt linux-2.6.32-vs2.3.0.36.26/Documentation/vserver/debug.txt
+--- linux-2.6.32/Documentation/vserver/debug.txt       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/Documentation/vserver/debug.txt 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,154 @@
 +
 +debug_cvirt:
@@ -1228,9 +1211,9 @@ diff -NurpP --minimal linux-2.6.31.6/Documentation/vserver/debug.txt linux-2.6.3
 + m 2^m        "vx_acc_page[%5d,%s,%2d]: %5d%s"
 +      "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
 +      "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
-diff -NurpP --minimal linux-2.6.31.6/drivers/block/Kconfig linux-2.6.31.6-vs2.3.0.36.24/drivers/block/Kconfig
---- linux-2.6.31.6/drivers/block/Kconfig       2009-09-10 15:25:49.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/block/Kconfig 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/block/Kconfig linux-2.6.32-vs2.3.0.36.26/drivers/block/Kconfig
+--- linux-2.6.32/drivers/block/Kconfig 2009-09-10 15:25:49.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/drivers/block/Kconfig   2009-12-03 20:04:56.000000000 +0100
 @@ -271,6 +271,13 @@ config BLK_DEV_CRYPTOLOOP
          instead, which can be configured to be on-disk compatible with the
          cryptoloop device.
@@ -1245,9 +1228,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/block/Kconfig linux-2.6.31.6-vs2.3.
  config BLK_DEV_NBD
        tristate "Network block device support"
        depends on NET
-diff -NurpP --minimal linux-2.6.31.6/drivers/block/loop.c linux-2.6.31.6-vs2.3.0.36.24/drivers/block/loop.c
---- linux-2.6.31.6/drivers/block/loop.c        2009-09-10 15:25:49.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/block/loop.c  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/block/loop.c linux-2.6.32-vs2.3.0.36.26/drivers/block/loop.c
+--- linux-2.6.32/drivers/block/loop.c  2009-12-03 20:02:19.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/block/loop.c    2009-12-03 20:04:56.000000000 +0100
 @@ -74,6 +74,7 @@
  #include <linux/gfp.h>
  #include <linux/kthread.h>
@@ -1301,9 +1284,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/block/loop.c linux-2.6.31.6-vs2.3.0
        mutex_lock(&lo->lo_ctl_mutex);
        lo->lo_refcnt++;
        mutex_unlock(&lo->lo_ctl_mutex);
-diff -NurpP --minimal linux-2.6.31.6/drivers/block/Makefile linux-2.6.31.6-vs2.3.0.36.24/drivers/block/Makefile
---- linux-2.6.31.6/drivers/block/Makefile      2009-09-10 15:25:49.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/block/Makefile        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/block/Makefile linux-2.6.32-vs2.3.0.36.26/drivers/block/Makefile
+--- linux-2.6.32/drivers/block/Makefile        2009-09-10 15:25:49.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/drivers/block/Makefile  2009-12-03 20:04:56.000000000 +0100
 @@ -34,6 +34,7 @@ obj-$(CONFIG_VIODASD)                += viodasd.o
  obj-$(CONFIG_BLK_DEV_SX8)     += sx8.o
  obj-$(CONFIG_BLK_DEV_UB)      += ub.o
@@ -1312,9 +1295,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/block/Makefile linux-2.6.31.6-vs2.3
  
  obj-$(CONFIG_XEN_BLKDEV_FRONTEND)     += xen-blkfront.o
  
-diff -NurpP --minimal linux-2.6.31.6/drivers/block/vroot.c linux-2.6.31.6-vs2.3.0.36.24/drivers/block/vroot.c
---- linux-2.6.31.6/drivers/block/vroot.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/block/vroot.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/block/vroot.c linux-2.6.32-vs2.3.0.36.26/drivers/block/vroot.c
+--- linux-2.6.32/drivers/block/vroot.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/block/vroot.c   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,281 @@
 +/*
 + *  linux/drivers/block/vroot.c
@@ -1597,10 +1580,10 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/block/vroot.c linux-2.6.31.6-vs2.3.
 +
 +#endif
 +
-diff -NurpP --minimal linux-2.6.31.6/drivers/char/sysrq.c linux-2.6.31.6-vs2.3.0.36.24/drivers/char/sysrq.c
---- linux-2.6.31.6/drivers/char/sysrq.c        2009-09-10 15:25:50.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/char/sysrq.c  2009-09-10 16:11:43.000000000 +0200
-@@ -37,6 +37,7 @@
+diff -NurpP --minimal linux-2.6.32/drivers/char/sysrq.c linux-2.6.32-vs2.3.0.36.26/drivers/char/sysrq.c
+--- linux-2.6.32/drivers/char/sysrq.c  2009-12-03 20:02:20.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/char/sysrq.c    2009-12-03 20:04:56.000000000 +0100
+@@ -38,6 +38,7 @@
  #include <linux/workqueue.h>
  #include <linux/hrtimer.h>
  #include <linux/oom.h>
@@ -1608,7 +1591,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/char/sysrq.c linux-2.6.31.6-vs2.3.0
  
  #include <asm/ptrace.h>
  #include <asm/irq_regs.h>
-@@ -382,6 +383,21 @@ static struct sysrq_key_op sysrq_unrt_op
+@@ -391,6 +392,21 @@ static struct sysrq_key_op sysrq_unrt_op
        .enable_mask    = SYSRQ_ENABLE_RTNICE,
  };
  
@@ -1630,7 +1613,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/char/sysrq.c linux-2.6.31.6-vs2.3.0
  /* Key Operations table and lock */
  static DEFINE_SPINLOCK(sysrq_key_table_lock);
  
-@@ -436,7 +452,11 @@ static struct sysrq_key_op *sysrq_key_ta
+@@ -445,7 +461,11 @@ static struct sysrq_key_op *sysrq_key_ta
        NULL,                           /* v */
        &sysrq_showstate_blocked_op,    /* w */
        /* x: May be registered on ppc/powerpc for xmon */
@@ -1642,7 +1625,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/char/sysrq.c linux-2.6.31.6-vs2.3.0
        /* y: May be registered on sparc64 for global register dump */
        NULL,                           /* y */
        &sysrq_ftrace_dump_op,          /* z */
-@@ -451,6 +471,8 @@ static int sysrq_key_table_key2index(int
+@@ -460,6 +480,8 @@ static int sysrq_key_table_key2index(int
                retval = key - '0';
        else if ((key >= 'a') && (key <= 'z'))
                retval = key + 10 - 'a';
@@ -1651,9 +1634,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/char/sysrq.c linux-2.6.31.6-vs2.3.0
        else
                retval = -1;
        return retval;
-diff -NurpP --minimal linux-2.6.31.6/drivers/char/tty_io.c linux-2.6.31.6-vs2.3.0.36.24/drivers/char/tty_io.c
---- linux-2.6.31.6/drivers/char/tty_io.c       2009-11-12 12:10:09.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/char/tty_io.c 2009-10-05 23:35:52.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/char/tty_io.c linux-2.6.32-vs2.3.0.36.26/drivers/char/tty_io.c
+--- linux-2.6.32/drivers/char/tty_io.c 2009-12-03 20:02:20.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/char/tty_io.c   2009-12-03 20:04:56.000000000 +0100
 @@ -106,6 +106,7 @@
  
  #include <linux/kmod.h>
@@ -1662,7 +1645,17 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/char/tty_io.c linux-2.6.31.6-vs2.3.
  
  #undef TTY_DEBUG_HANGUP
  
-@@ -2236,6 +2237,7 @@ static int tiocspgrp(struct tty_struct *
+@@ -1966,7 +1967,8 @@ static int tiocsti(struct tty_struct *tt
+       char ch, mbz = 0;
+       struct tty_ldisc *ld;
+-      if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
++      if (((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) ||
++              !vx_ccaps(VXC_TIOCSTI))
+               return -EPERM;
+       if (get_user(ch, p))
+               return -EFAULT;
+@@ -2254,6 +2256,7 @@ static int tiocspgrp(struct tty_struct *
                return -ENOTTY;
        if (get_user(pgrp_nr, p))
                return -EFAULT;
@@ -1670,18 +1663,18 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/char/tty_io.c linux-2.6.31.6-vs2.3.
        if (pgrp_nr < 0)
                return -EINVAL;
        rcu_read_lock();
-diff -NurpP --minimal linux-2.6.31.6/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.31.6-vs2.3.0.36.24/drivers/infiniband/hw/ipath/ipath_user_pages.c
---- linux-2.6.31.6/drivers/infiniband/hw/ipath/ipath_user_pages.c      2009-06-11 17:12:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/infiniband/hw/ipath/ipath_user_pages.c        2009-09-10 16:11:43.000000000 +0200
-@@ -33,6 +33,7 @@
+diff -NurpP --minimal linux-2.6.32/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.32-vs2.3.0.36.26/drivers/infiniband/hw/ipath/ipath_user_pages.c
+--- linux-2.6.32/drivers/infiniband/hw/ipath/ipath_user_pages.c        2009-12-03 20:02:23.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/infiniband/hw/ipath/ipath_user_pages.c  2009-12-03 20:04:56.000000000 +0100
+@@ -34,6 +34,7 @@
  #include <linux/mm.h>
  #include <linux/device.h>
-+#include <linux/vs_memory.h>
+ #include <linux/sched.h>
++// #include <linux/vs_memory.h>
  
  #include "ipath_kernel.h"
  
-@@ -61,7 +62,8 @@ static int __get_user_pages(unsigned lon
+@@ -62,7 +63,8 @@ static int __get_user_pages(unsigned lon
        lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
                PAGE_SHIFT;
  
@@ -1691,7 +1684,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/infiniband/hw/ipath/ipath_user_page
                ret = -ENOMEM;
                goto bail;
        }
-@@ -78,7 +80,7 @@ static int __get_user_pages(unsigned lon
+@@ -79,7 +81,7 @@ static int __get_user_pages(unsigned lon
                        goto bail_release;
        }
  
@@ -1700,7 +1693,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/infiniband/hw/ipath/ipath_user_page
  
        ret = 0;
        goto bail;
-@@ -177,7 +179,7 @@ void ipath_release_user_pages(struct pag
+@@ -178,7 +180,7 @@ void ipath_release_user_pages(struct pag
  
        __ipath_release_user_pages(p, num_pages, 1);
  
@@ -1709,7 +1702,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/infiniband/hw/ipath/ipath_user_page
  
        up_write(&current->mm->mmap_sem);
  }
-@@ -194,7 +196,7 @@ static void user_pages_account(struct wo
+@@ -195,7 +197,7 @@ static void user_pages_account(struct wo
                container_of(_work, struct ipath_user_pages_work, work);
  
        down_write(&work->mm->mmap_sem);
@@ -1718,9 +1711,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/infiniband/hw/ipath/ipath_user_page
        up_write(&work->mm->mmap_sem);
        mmput(work->mm);
        kfree(work);
-diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm.c linux-2.6.31.6-vs2.3.0.36.24/drivers/md/dm.c
---- linux-2.6.31.6/drivers/md/dm.c     2009-11-12 12:10:10.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/md/dm.c       2009-11-12 12:26:38.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/drivers/md/dm.c linux-2.6.32-vs2.3.0.36.26/drivers/md/dm.c
+--- linux-2.6.32/drivers/md/dm.c       2009-12-03 20:02:25.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/md/dm.c 2009-12-03 20:04:56.000000000 +0100
 @@ -19,6 +19,7 @@
  #include <linux/slab.h>
  #include <linux/idr.h>
@@ -1771,7 +1764,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm.c linux-2.6.31.6-vs2.3.0.36.2
  }
  
  static int dm_blk_close(struct gendisk *disk, fmode_t mode)
-@@ -551,6 +555,14 @@ int dm_set_geometry(struct mapped_device
+@@ -553,6 +557,14 @@ int dm_set_geometry(struct mapped_device
        return 0;
  }
  
@@ -1786,7 +1779,7 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm.c linux-2.6.31.6-vs2.3.0.36.2
  /*-----------------------------------------------------------------
   * CRUD START:
   *   A more elegant soln is in the works that uses the queue
-@@ -1760,6 +1772,7 @@ static struct mapped_device *alloc_dev(i
+@@ -1762,6 +1774,7 @@ static struct mapped_device *alloc_dev(i
        INIT_LIST_HEAD(&md->uevent_list);
        spin_lock_init(&md->uevent_lock);
  
@@ -1794,9 +1787,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm.c linux-2.6.31.6-vs2.3.0.36.2
        md->queue = blk_init_queue(dm_request_fn, NULL);
        if (!md->queue)
                goto bad_queue;
-diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm.h linux-2.6.31.6-vs2.3.0.36.24/drivers/md/dm.h
---- linux-2.6.31.6/drivers/md/dm.h     2009-09-10 15:25:55.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/md/dm.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/md/dm.h linux-2.6.32-vs2.3.0.36.26/drivers/md/dm.h
+--- linux-2.6.32/drivers/md/dm.h       2009-09-10 15:25:55.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/drivers/md/dm.h 2009-12-03 20:04:56.000000000 +0100
 @@ -41,6 +41,8 @@ struct dm_dev_internal {
  struct dm_table;
  struct dm_md_mempools;
@@ -1806,9 +1799,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm.h linux-2.6.31.6-vs2.3.0.36.2
  /*-----------------------------------------------------------------
   * Internal table functions.
   *---------------------------------------------------------------*/
-diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm-ioctl.c linux-2.6.31.6-vs2.3.0.36.24/drivers/md/dm-ioctl.c
---- linux-2.6.31.6/drivers/md/dm-ioctl.c       2009-09-10 15:25:55.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/md/dm-ioctl.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/md/dm-ioctl.c linux-2.6.32-vs2.3.0.36.26/drivers/md/dm-ioctl.c
+--- linux-2.6.32/drivers/md/dm-ioctl.c 2009-12-03 20:02:25.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/md/dm-ioctl.c   2009-12-03 20:04:56.000000000 +0100
 @@ -16,6 +16,7 @@
  #include <linux/dm-ioctl.h>
  #include <linux/hdreg.h>
@@ -1890,9 +1883,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/md/dm-ioctl.c linux-2.6.31.6-vs2.3.
                return -EACCES;
  
        if (_IOC_TYPE(command) != DM_IOCTL)
-diff -NurpP --minimal linux-2.6.31.6/drivers/net/tun.c linux-2.6.31.6-vs2.3.0.36.24/drivers/net/tun.c
---- linux-2.6.31.6/drivers/net/tun.c   2009-11-12 12:10:10.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/drivers/net/tun.c     2009-10-15 03:50:05.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/drivers/net/tun.c linux-2.6.32-vs2.3.0.36.26/drivers/net/tun.c
+--- linux-2.6.32/drivers/net/tun.c     2009-12-03 20:02:32.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/drivers/net/tun.c       2009-12-03 20:04:56.000000000 +0100
 @@ -61,6 +61,7 @@
  #include <linux/crc32.h>
  #include <linux/nsproxy.h>
@@ -1907,18 +1900,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/net/tun.c linux-2.6.31.6-vs2.3.0.36
        gid_t                   group;
 +      nid_t                   nid;
  
-       struct sk_buff_head     readq;
-@@ -138,7 +140,7 @@ static int tun_attach(struct tun_struct 
-       /* Check permissions */
-       if (((tun->owner != -1 && cred->euid != tun->owner) ||
-            (tun->group != -1 && !in_egroup_p(tun->group))) &&
--              !capable(CAP_NET_ADMIN))
-+              !cap_raised(current_cap(), CAP_NET_ADMIN))
-               return -EPERM;
-       netif_tx_lock_bh(tun->dev);
-@@ -823,6 +825,7 @@ static void tun_setup(struct net_device 
+       struct net_device       *dev;
+       struct fasync_struct    *fasync;
+@@ -816,6 +818,7 @@ static void tun_setup(struct net_device 
  
        tun->owner = -1;
        tun->group = -1;
@@ -1926,26 +1910,35 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/net/tun.c linux-2.6.31.6-vs2.3.0.36
  
        dev->ethtool_ops = &tun_ethtool_ops;
        dev->destructor = tun_free_netdev;
-@@ -935,6 +938,9 @@ static int tun_set_iff(struct net *net, 
-               else
-                       return -EINVAL;
+@@ -932,7 +935,7 @@ static int tun_set_iff(struct net *net, 
  
-+              if (!nx_check(tun->nid, VS_IDENT | VS_HOSTID | VS_ADMIN_P))
-+                      return -EPERM;
-+
-               err = tun_attach(tun, file);
+               if (((tun->owner != -1 && cred->euid != tun->owner) ||
+                    (tun->group != -1 && !in_egroup_p(tun->group))) &&
+-                  !capable(CAP_NET_ADMIN))
++              !cap_raised(current_cap(), CAP_NET_ADMIN))
+                       return -EPERM;
+               err = security_tun_dev_attach(tun->socket.sk);
                if (err < 0)
-                       return err;
-@@ -943,7 +949,7 @@ static int tun_set_iff(struct net *net, 
+@@ -946,7 +949,7 @@ static int tun_set_iff(struct net *net, 
                char *name;
                unsigned long flags = 0;
  
 -              if (!capable(CAP_NET_ADMIN))
 +              if (!nx_capable(CAP_NET_ADMIN, NXC_TUN_CREATE))
                        return -EPERM;
+               err = security_tun_dev_create();
+               if (err < 0)
+@@ -1013,6 +1016,9 @@ static int tun_set_iff(struct net *net, 
+               sk->sk_destruct = tun_sock_destruct;
  
-               /* Set dev type */
-@@ -1190,6 +1196,16 @@ static long tun_chr_ioctl(struct file *f
++              if (!nx_check(tun->nid, VS_IDENT | VS_HOSTID | VS_ADMIN_P))
++                      return -EPERM;
++
+               err = tun_attach(tun, file);
+               if (err < 0)
+                       goto failed;
+@@ -1202,6 +1208,16 @@ static long tun_chr_ioctl(struct file *f
                DBG(KERN_INFO "%s: group set to %d\n", tun->dev->name, tun->group);
                break;
  
@@ -1962,9 +1955,9 @@ diff -NurpP --minimal linux-2.6.31.6/drivers/net/tun.c linux-2.6.31.6-vs2.3.0.36
        case TUNSETLINK:
                /* Only allow setting the type when the interface is down */
                if (tun->dev->flags & IFF_UP) {
-diff -NurpP --minimal linux-2.6.31.6/fs/attr.c linux-2.6.31.6-vs2.3.0.36.24/fs/attr.c
---- linux-2.6.31.6/fs/attr.c   2009-06-11 17:13:01.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/attr.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/attr.c linux-2.6.32-vs2.3.0.36.26/fs/attr.c
+--- linux-2.6.32/fs/attr.c     2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/attr.c       2009-12-03 20:04:56.000000000 +0100
 @@ -14,6 +14,9 @@
  #include <linux/fcntl.h>
  #include <linux/quotaops.h>
@@ -1975,7 +1968,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/attr.c linux-2.6.31.6-vs2.3.0.36.24/fs/a
  
  /* Taken over from the old code... */
  
-@@ -55,6 +58,10 @@ int inode_change_ok(struct inode *inode,
+@@ -55,6 +58,10 @@ int inode_change_ok(const struct inode *
                if (!is_owner_or_cap(inode))
                        goto error;
        }
@@ -1986,7 +1979,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/attr.c linux-2.6.31.6-vs2.3.0.36.24/fs/a
  fine:
        retval = 0;
  error:
-@@ -78,6 +85,8 @@ int inode_setattr(struct inode * inode, 
+@@ -120,6 +127,8 @@ int inode_setattr(struct inode * inode, 
                inode->i_uid = attr->ia_uid;
        if (ia_valid & ATTR_GID)
                inode->i_gid = attr->ia_gid;
@@ -1995,7 +1988,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/attr.c linux-2.6.31.6-vs2.3.0.36.24/fs/a
        if (ia_valid & ATTR_ATIME)
                inode->i_atime = timespec_trunc(attr->ia_atime,
                                                inode->i_sb->s_time_gran);
-@@ -172,7 +181,8 @@ int notify_change(struct dentry * dentry
+@@ -214,7 +223,8 @@ int notify_change(struct dentry * dentry
                error = inode_change_ok(inode, attr);
                if (!error) {
                        if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
@@ -2005,9 +1998,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/attr.c linux-2.6.31.6-vs2.3.0.36.24/fs/a
                                error = vfs_dq_transfer(inode, attr) ?
                                        -EDQUOT : 0;
                        if (!error)
-diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_aout.c linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_aout.c
---- linux-2.6.31.6/fs/binfmt_aout.c    2009-03-24 14:22:24.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_aout.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/binfmt_aout.c linux-2.6.32-vs2.3.0.36.26/fs/binfmt_aout.c
+--- linux-2.6.32/fs/binfmt_aout.c      2009-03-24 14:22:24.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/binfmt_aout.c        2009-12-03 20:04:56.000000000 +0100
 @@ -24,6 +24,7 @@
  #include <linux/binfmts.h>
  #include <linux/personality.h>
@@ -2016,9 +2009,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_aout.c linux-2.6.31.6-vs2.3.0.36.
  
  #include <asm/system.h>
  #include <asm/uaccess.h>
-diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_elf.c linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_elf.c
---- linux-2.6.31.6/fs/binfmt_elf.c     2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_elf.c       2009-09-29 17:02:58.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/binfmt_elf.c linux-2.6.32-vs2.3.0.36.26/fs/binfmt_elf.c
+--- linux-2.6.32/fs/binfmt_elf.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/binfmt_elf.c 2009-12-03 20:04:56.000000000 +0100
 @@ -31,6 +31,7 @@
  #include <linux/random.h>
  #include <linux/elf.h>
@@ -2027,9 +2020,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_elf.c linux-2.6.31.6-vs2.3.0.36.2
  #include <asm/uaccess.h>
  #include <asm/param.h>
  #include <asm/page.h>
-diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_flat.c linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_flat.c
---- linux-2.6.31.6/fs/binfmt_flat.c    2009-09-10 15:26:20.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_flat.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/binfmt_flat.c linux-2.6.32-vs2.3.0.36.26/fs/binfmt_flat.c
+--- linux-2.6.32/fs/binfmt_flat.c      2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/binfmt_flat.c        2009-12-03 20:04:56.000000000 +0100
 @@ -35,6 +35,7 @@
  #include <linux/init.h>
  #include <linux/flat.h>
@@ -2038,9 +2031,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_flat.c linux-2.6.31.6-vs2.3.0.36.
  
  #include <asm/byteorder.h>
  #include <asm/system.h>
-diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_som.c linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_som.c
---- linux-2.6.31.6/fs/binfmt_som.c     2009-06-11 17:13:02.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/binfmt_som.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/binfmt_som.c linux-2.6.32-vs2.3.0.36.26/fs/binfmt_som.c
+--- linux-2.6.32/fs/binfmt_som.c       2009-06-11 17:13:02.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/binfmt_som.c 2009-12-03 20:04:56.000000000 +0100
 @@ -28,6 +28,7 @@
  #include <linux/shm.h>
  #include <linux/personality.h>
@@ -2049,9 +2042,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/binfmt_som.c linux-2.6.31.6-vs2.3.0.36.2
  
  #include <asm/uaccess.h>
  #include <asm/pgtable.h>
-diff -NurpP --minimal linux-2.6.31.6/fs/block_dev.c linux-2.6.31.6-vs2.3.0.36.24/fs/block_dev.c
---- linux-2.6.31.6/fs/block_dev.c      2009-09-10 15:26:20.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/block_dev.c        2009-09-10 17:01:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/block_dev.c linux-2.6.32-vs2.3.0.36.26/fs/block_dev.c
+--- linux-2.6.32/fs/block_dev.c        2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/block_dev.c  2009-12-03 20:04:56.000000000 +0100
 @@ -26,6 +26,7 @@
  #include <linux/namei.h>
  #include <linux/log2.h>
@@ -2060,7 +2053,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/block_dev.c linux-2.6.31.6-vs2.3.0.36.24
  #include <asm/uaccess.h>
  #include "internal.h"
  
-@@ -550,6 +551,7 @@ struct block_device *bdget(dev_t dev)
+@@ -555,6 +556,7 @@ struct block_device *bdget(dev_t dev)
                bdev->bd_invalidated = 0;
                inode->i_mode = S_IFBLK;
                inode->i_rdev = dev;
@@ -2068,7 +2061,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/block_dev.c linux-2.6.31.6-vs2.3.0.36.24
                inode->i_bdev = bdev;
                inode->i_data.a_ops = &def_blk_aops;
                mapping_set_gfp_mask(&inode->i_data, GFP_USER);
-@@ -596,6 +598,11 @@ EXPORT_SYMBOL(bdput);
+@@ -601,6 +603,11 @@ EXPORT_SYMBOL(bdput);
  static struct block_device *bd_acquire(struct inode *inode)
  {
        struct block_device *bdev;
@@ -2080,7 +2073,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/block_dev.c linux-2.6.31.6-vs2.3.0.36.24
  
        spin_lock(&bdev_lock);
        bdev = inode->i_bdev;
-@@ -606,7 +613,7 @@ static struct block_device *bd_acquire(s
+@@ -611,7 +618,7 @@ static struct block_device *bd_acquire(s
        }
        spin_unlock(&bdev_lock);
  
@@ -2089,10 +2082,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/block_dev.c linux-2.6.31.6-vs2.3.0.36.24
        if (bdev) {
                spin_lock(&bdev_lock);
                if (!inode->i_bdev) {
-diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/ctree.h linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/ctree.h
---- linux-2.6.31.6/fs/btrfs/ctree.h    2009-09-10 15:26:20.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/ctree.h      2009-10-08 07:39:48.000000000 +0200
-@@ -540,11 +540,14 @@ struct btrfs_inode_item {
+diff -NurpP --minimal linux-2.6.32/fs/btrfs/ctree.h linux-2.6.32-vs2.3.0.36.26/fs/btrfs/ctree.h
+--- linux-2.6.32/fs/btrfs/ctree.h      2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/btrfs/ctree.h        2009-12-03 20:04:56.000000000 +0100
+@@ -544,11 +544,14 @@ struct btrfs_inode_item {
        /* modification sequence number for NFS */
        __le64 sequence;
  
@@ -2108,16 +2101,16 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/ctree.h linux-2.6.31.6-vs2.3.0.36.
        struct btrfs_timespec atime;
        struct btrfs_timespec ctime;
        struct btrfs_timespec mtime;
-@@ -1119,6 +1122,8 @@ struct btrfs_root {
- #define BTRFS_MOUNT_SSD_SPREAD                (1 << 8)
+@@ -1155,6 +1158,8 @@ struct btrfs_root {
  #define BTRFS_MOUNT_NOSSD             (1 << 9)
+ #define BTRFS_MOUNT_DISCARD           (1 << 10)
  
 +#define BTRFS_MOUNT_TAGGED            (1 << 24)
 +
  #define btrfs_clear_opt(o, opt)               ((o) &= ~BTRFS_MOUNT_##opt)
  #define btrfs_set_opt(o, opt)         ((o) |= BTRFS_MOUNT_##opt)
  #define btrfs_test_opt(root, opt)     ((root)->fs_info->mount_opt & \
-@@ -1138,6 +1143,10 @@ struct btrfs_root {
+@@ -1174,6 +1179,10 @@ struct btrfs_root {
  #define BTRFS_INODE_NOATIME           (1 << 9)
  #define BTRFS_INODE_DIRSYNC           (1 << 10)
  
@@ -2128,7 +2121,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/ctree.h linux-2.6.31.6-vs2.3.0.36.
  
  /* some macros to generate set/get funcs for the struct fields.  This
   * assumes there is a lefoo_to_cpu for every type, so lets make a simple
-@@ -1340,6 +1349,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
+@@ -1376,6 +1385,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
  BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32);
  BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32);
  BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32);
@@ -2136,7 +2129,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/ctree.h linux-2.6.31.6-vs2.3.0.36.
  BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32);
  BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64);
  BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64);
-@@ -2280,6 +2290,7 @@ int btrfs_cont_expand(struct inode *inod
+@@ -2338,6 +2348,7 @@ extern const struct dentry_operations bt
  long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
  void btrfs_update_iflags(struct inode *inode);
  void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
@@ -2144,10 +2137,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/ctree.h linux-2.6.31.6-vs2.3.0.36.
  
  /* file.c */
  int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync);
-diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/disk-io.c linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/disk-io.c
---- linux-2.6.31.6/fs/btrfs/disk-io.c  2009-09-10 15:26:20.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/disk-io.c    2009-10-08 06:43:17.000000000 +0200
-@@ -1673,6 +1673,9 @@ struct btrfs_root *open_ctree(struct sup
+diff -NurpP --minimal linux-2.6.32/fs/btrfs/disk-io.c linux-2.6.32-vs2.3.0.36.26/fs/btrfs/disk-io.c
+--- linux-2.6.32/fs/btrfs/disk-io.c    2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/btrfs/disk-io.c      2009-12-03 20:04:56.000000000 +0100
+@@ -1723,6 +1723,9 @@ struct btrfs_root *open_ctree(struct sup
                goto fail_iput;
        }
  
@@ -2157,9 +2150,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/disk-io.c linux-2.6.31.6-vs2.3.0.3
        features = btrfs_super_incompat_flags(disk_super) &
                ~BTRFS_FEATURE_INCOMPAT_SUPP;
        if (features) {
-diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/inode.c
---- linux-2.6.31.6/fs/btrfs/inode.c    2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/inode.c      2009-10-08 14:17:12.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/btrfs/inode.c linux-2.6.32-vs2.3.0.36.26/fs/btrfs/inode.c
+--- linux-2.6.32/fs/btrfs/inode.c      2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/btrfs/inode.c        2009-12-03 20:04:56.000000000 +0100
 @@ -36,6 +36,8 @@
  #include <linux/xattr.h>
  #include <linux/posix_acl.h>
@@ -2169,7 +2162,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/inode.c linux-2.6.31.6-vs2.3.0.36.
  #include "compat.h"
  #include "ctree.h"
  #include "disk-io.h"
-@@ -2072,6 +2074,8 @@ static void btrfs_read_locked_inode(stru
+@@ -2242,6 +2244,8 @@ static void btrfs_read_locked_inode(stru
        int maybe_acls;
        u64 alloc_group_block;
        u32 rdev;
@@ -2178,7 +2171,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/inode.c linux-2.6.31.6-vs2.3.0.36.
        int ret;
  
        path = btrfs_alloc_path();
-@@ -2088,8 +2092,13 @@ static void btrfs_read_locked_inode(stru
+@@ -2258,8 +2262,13 @@ static void btrfs_read_locked_inode(stru
  
        inode->i_mode = btrfs_inode_mode(leaf, inode_item);
        inode->i_nlink = btrfs_inode_nlink(leaf, inode_item);
@@ -2194,7 +2187,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/inode.c linux-2.6.31.6-vs2.3.0.36.
        btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
  
        tspec = btrfs_inode_atime(inode_item);
-@@ -2171,8 +2180,15 @@ static void fill_inode_item(struct btrfs
+@@ -2341,8 +2350,15 @@ static void fill_inode_item(struct btrfs
                            struct btrfs_inode_item *item,
                            struct inode *inode)
  {
@@ -2212,7 +2205,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/inode.c linux-2.6.31.6-vs2.3.0.36.
        btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size);
        btrfs_set_inode_mode(leaf, item, inode->i_mode);
        btrfs_set_inode_nlink(leaf, item, inode->i_nlink);
-@@ -3615,6 +3631,7 @@ static struct inode *btrfs_new_inode(str
+@@ -4065,6 +4081,7 @@ static struct inode *btrfs_new_inode(str
        } else
                inode->i_gid = current_fsgid();
  
@@ -2220,25 +2213,25 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/inode.c linux-2.6.31.6-vs2.3.0.36.
        inode->i_mode = mode;
        inode->i_ino = objectid;
        inode_set_bytes(inode, 0);
-@@ -5218,6 +5235,7 @@ static struct inode_operations btrfs_dir
+@@ -5836,6 +5853,7 @@ static const struct inode_operations btr
        .listxattr      = btrfs_listxattr,
        .removexattr    = btrfs_removexattr,
        .permission     = btrfs_permission,
 +      .sync_flags     = btrfs_sync_flags,
  };
- static struct inode_operations btrfs_dir_ro_inode_operations = {
+ static const struct inode_operations btrfs_dir_ro_inode_operations = {
        .lookup         = btrfs_lookup,
-@@ -5289,6 +5307,7 @@ static struct inode_operations btrfs_fil
+@@ -5911,6 +5929,7 @@ static const struct inode_operations btr
        .permission     = btrfs_permission,
        .fallocate      = btrfs_fallocate,
        .fiemap         = btrfs_fiemap,
 +      .sync_flags     = btrfs_sync_flags,
  };
- static struct inode_operations btrfs_special_inode_operations = {
+ static const struct inode_operations btrfs_special_inode_operations = {
        .getattr        = btrfs_getattr,
-diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/ioctl.c
---- linux-2.6.31.6/fs/btrfs/ioctl.c    2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/ioctl.c      2009-10-08 05:58:29.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/btrfs/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/btrfs/ioctl.c
+--- linux-2.6.32/fs/btrfs/ioctl.c      2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/btrfs/ioctl.c        2009-12-03 20:04:56.000000000 +0100
 @@ -67,10 +67,13 @@ static unsigned int btrfs_flags_to_ioctl
  {
        unsigned int iflags = 0;
@@ -2420,32 +2413,31 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/ioctl.c linux-2.6.31.6-vs2.3.0.36.
        if (flags & FS_APPEND_FL)
                ip->flags |= BTRFS_INODE_APPEND;
        else
-diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/super.c
---- linux-2.6.31.6/fs/btrfs/super.c    2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/btrfs/super.c      2009-10-08 07:27:04.000000000 +0200
-@@ -66,7 +66,8 @@ enum {
-       Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
+diff -NurpP --minimal linux-2.6.32/fs/btrfs/super.c linux-2.6.32-vs2.3.0.36.26/fs/btrfs/super.c
+--- linux-2.6.32/fs/btrfs/super.c      2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/btrfs/super.c        2009-12-03 20:04:56.000000000 +0100
+@@ -67,7 +67,7 @@ enum {
        Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
        Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
--      Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err,
-+      Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
-+      Opt_tag, Opt_notag, Opt_tagid, Opt_err,
+       Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
+-      Opt_discard, Opt_err,
++      Opt_tag, Opt_notag, Opt_tagid, Opt_discard, Opt_err,
  };
  
  static match_table_t tokens = {
-@@ -88,6 +89,9 @@ static match_table_t tokens = {
-       {Opt_notreelog, "notreelog"},
+@@ -90,6 +90,9 @@ static match_table_t tokens = {
        {Opt_flushoncommit, "flushoncommit"},
        {Opt_ratio, "metadata_ratio=%d"},
+       {Opt_discard, "discard"},
 +      {Opt_tag, "tag"},
 +      {Opt_notag, "notag"},
 +      {Opt_tagid, "tagid=%u"},
        {Opt_err, NULL},
  };
  
-@@ -257,6 +261,22 @@ int btrfs_parse_options(struct btrfs_roo
-                                      info->metadata_ratio);
-                       }
+@@ -262,6 +265,22 @@ int btrfs_parse_options(struct btrfs_roo
+               case Opt_discard:
+                       btrfs_set_opt(info->mount_opt, DISCARD);
                        break;
 +#ifndef CONFIG_TAGGING_NONE
 +              case Opt_tag:
@@ -2466,7 +2458,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/super.c linux-2.6.31.6-vs2.3.0.36.
                default:
                        break;
                }
-@@ -568,6 +588,12 @@ static int btrfs_remount(struct super_bl
+@@ -575,6 +594,12 @@ static int btrfs_remount(struct super_bl
        if (ret)
                return -EINVAL;
  
@@ -2479,9 +2471,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/btrfs/super.c linux-2.6.31.6-vs2.3.0.36.
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
  
-diff -NurpP --minimal linux-2.6.31.6/fs/char_dev.c linux-2.6.31.6-vs2.3.0.36.24/fs/char_dev.c
---- linux-2.6.31.6/fs/char_dev.c       2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/char_dev.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/char_dev.c linux-2.6.32-vs2.3.0.36.26/fs/char_dev.c
+--- linux-2.6.32/fs/char_dev.c 2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/char_dev.c   2009-12-03 20:04:56.000000000 +0100
 @@ -20,6 +20,8 @@
  #include <linux/cdev.h>
  #include <linux/mutex.h>
@@ -2491,7 +2483,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/char_dev.c linux-2.6.31.6-vs2.3.0.36.24/
  
  #include "internal.h"
  
-@@ -357,14 +359,21 @@ static int chrdev_open(struct inode *ino
+@@ -368,14 +370,21 @@ static int chrdev_open(struct inode *ino
        struct cdev *p;
        struct cdev *new = NULL;
        int ret = 0;
@@ -2514,18 +2506,18 @@ diff -NurpP --minimal linux-2.6.31.6/fs/char_dev.c linux-2.6.31.6-vs2.3.0.36.24/
                if (!kobj)
                        return -ENXIO;
                new = container_of(kobj, struct cdev, kobj);
-diff -NurpP --minimal linux-2.6.31.6/fs/dcache.c linux-2.6.31.6-vs2.3.0.36.24/fs/dcache.c
---- linux-2.6.31.6/fs/dcache.c 2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/dcache.c   2009-09-10 16:11:43.000000000 +0200
-@@ -32,6 +32,7 @@
- #include <linux/swap.h>
+diff -NurpP --minimal linux-2.6.32/fs/dcache.c linux-2.6.32-vs2.3.0.36.26/fs/dcache.c
+--- linux-2.6.32/fs/dcache.c   2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/dcache.c     2009-12-03 20:04:56.000000000 +0100
+@@ -33,6 +33,7 @@
  #include <linux/bootmem.h>
  #include <linux/fs_struct.h>
+ #include <linux/hardirq.h>
 +#include <linux/vs_limit.h>
  #include "internal.h"
  
  int sysctl_vfs_cache_pressure __read_mostly = 100;
-@@ -229,6 +230,8 @@ repeat:
+@@ -230,6 +231,8 @@ repeat:
                return;
        }
  
@@ -2534,7 +2526,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/dcache.c linux-2.6.31.6-vs2.3.0.36.24/fs
        /*
         * AV: ->d_delete() is _NOT_ allowed to block now.
         */
-@@ -320,6 +323,7 @@ static inline struct dentry * __dget_loc
+@@ -321,6 +324,7 @@ static inline struct dentry * __dget_loc
  {
        atomic_inc(&dentry->d_count);
        dentry_lru_del_init(dentry);
@@ -2542,7 +2534,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/dcache.c linux-2.6.31.6-vs2.3.0.36.24/fs
        return dentry;
  }
  
-@@ -918,6 +922,9 @@ struct dentry *d_alloc(struct dentry * p
+@@ -919,6 +923,9 @@ struct dentry *d_alloc(struct dentry * p
        struct dentry *dentry;
        char *dname;
  
@@ -2552,7 +2544,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/dcache.c linux-2.6.31.6-vs2.3.0.36.24/fs
        dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
        if (!dentry)
                return NULL;
-@@ -963,6 +970,7 @@ struct dentry *d_alloc(struct dentry * p
+@@ -964,6 +971,7 @@ struct dentry *d_alloc(struct dentry * p
        if (parent)
                list_add(&dentry->d_u.d_child, &parent->d_subdirs);
        dentry_stat.nr_dentry++;
@@ -2560,7 +2552,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/dcache.c linux-2.6.31.6-vs2.3.0.36.24/fs
        spin_unlock(&dcache_lock);
  
        return dentry;
-@@ -1406,6 +1414,7 @@ struct dentry * __d_lookup(struct dentry
+@@ -1407,6 +1415,7 @@ struct dentry * __d_lookup(struct dentry
                }
  
                atomic_inc(&dentry->d_count);
@@ -2568,25 +2560,18 @@ diff -NurpP --minimal linux-2.6.31.6/fs/dcache.c linux-2.6.31.6-vs2.3.0.36.24/fs
                found = dentry;
                spin_unlock(&dentry->d_lock);
                break;
-diff -NurpP --minimal linux-2.6.31.6/fs/devpts/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/devpts/inode.c
---- linux-2.6.31.6/fs/devpts/inode.c   2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/devpts/inode.c     2009-09-10 16:11:43.000000000 +0200
-@@ -19,12 +19,12 @@
- #include <linux/tty.h>
- #include <linux/mutex.h>
- #include <linux/idr.h>
-+#include <linux/magic.h>
- #include <linux/devpts_fs.h>
+diff -NurpP --minimal linux-2.6.32/fs/devpts/inode.c linux-2.6.32-vs2.3.0.36.26/fs/devpts/inode.c
+--- linux-2.6.32/fs/devpts/inode.c     2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/devpts/inode.c       2009-12-03 20:04:56.000000000 +0100
+@@ -24,6 +24,7 @@
  #include <linux/parser.h>
  #include <linux/fsnotify.h>
  #include <linux/seq_file.h>
--
--#define DEVPTS_SUPER_MAGIC 0x1cd1
 +#include <linux/vs_base.h>
  
  #define DEVPTS_DEFAULT_MODE 0600
  /*
-@@ -36,6 +36,20 @@
+@@ -35,6 +36,20 @@
  #define DEVPTS_DEFAULT_PTMX_MODE 0000
  #define PTMX_MINOR    2
  
@@ -2607,7 +2592,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/devpts/inode.c linux-2.6.31.6-vs2.3.0.36
  extern int pty_limit;                 /* Config limit on Unix98 ptys */
  static DEFINE_MUTEX(allocated_ptys_lock);
  
-@@ -263,6 +277,25 @@ static int devpts_show_options(struct se
+@@ -262,6 +277,25 @@ static int devpts_show_options(struct se
        return 0;
  }
  
@@ -2633,7 +2618,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/devpts/inode.c linux-2.6.31.6-vs2.3.0.36
  static const struct super_operations devpts_sops = {
        .statfs         = simple_statfs,
        .remount_fs     = devpts_remount,
-@@ -302,12 +335,15 @@ devpts_fill_super(struct super_block *s,
+@@ -301,12 +335,15 @@ devpts_fill_super(struct super_block *s,
        inode = new_inode(s);
        if (!inode)
                goto free_fsi;
@@ -2650,7 +2635,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/devpts/inode.c linux-2.6.31.6-vs2.3.0.36
  
        s->s_root = d_alloc_root(inode);
        if (s->s_root)
-@@ -498,6 +534,9 @@ int devpts_pty_new(struct inode *ptmx_in
+@@ -497,6 +534,9 @@ int devpts_pty_new(struct inode *ptmx_in
        inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
        init_special_inode(inode, S_IFCHR|opts->mode, device);
@@ -2660,10 +2645,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/devpts/inode.c linux-2.6.31.6-vs2.3.0.36
        inode->i_private = tty;
        tty->driver_data = inode;
  
-diff -NurpP --minimal linux-2.6.31.6/fs/exec.c linux-2.6.31.6-vs2.3.0.36.24/fs/exec.c
---- linux-2.6.31.6/fs/exec.c   2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/exec.c     2009-09-10 16:11:43.000000000 +0200
-@@ -249,7 +249,9 @@ static int __bprm_mm_init(struct linux_b
+diff -NurpP --minimal linux-2.6.32/fs/exec.c linux-2.6.32-vs2.3.0.36.26/fs/exec.c
+--- linux-2.6.32/fs/exec.c     2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/exec.c       2009-12-03 20:04:56.000000000 +0100
+@@ -251,7 +251,9 @@ static int __bprm_mm_init(struct linux_b
        if (err)
                goto err;
  
@@ -2674,7 +2659,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/exec.c linux-2.6.31.6-vs2.3.0.36.24/fs/e
        up_write(&mm->mmap_sem);
        bprm->p = vma->vm_end - sizeof(void *);
        return 0;
-@@ -1471,7 +1473,7 @@ static int format_corename(char *corenam
+@@ -1474,7 +1476,7 @@ static int format_corename(char *corenam
                        /* UNIX time of coredump */
                        case 't': {
                                struct timeval tv;
@@ -2683,9 +2668,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/exec.c linux-2.6.31.6-vs2.3.0.36.24/fs/e
                                rc = snprintf(out_ptr, out_end - out_ptr,
                                              "%lu", tv.tv_sec);
                                if (rc > out_end - out_ptr)
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/balloc.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/balloc.c
---- linux-2.6.31.6/fs/ext2/balloc.c    2009-06-11 17:13:03.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/balloc.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/balloc.c linux-2.6.32-vs2.3.0.36.26/fs/ext2/balloc.c
+--- linux-2.6.32/fs/ext2/balloc.c      2009-06-11 17:13:03.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/balloc.c        2009-12-03 20:04:56.000000000 +0100
 @@ -701,7 +701,6 @@ ext2_try_to_allocate(struct super_block 
                        start = 0;
                end = EXT2_BLOCKS_PER_GROUP(sb);
@@ -2694,9 +2679,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/balloc.c linux-2.6.31.6-vs2.3.0.36.
        BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
  
  repeat:
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/ext2.h linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/ext2.h
---- linux-2.6.31.6/fs/ext2/ext2.h      2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/ext2.h        2009-10-07 01:23:12.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/ext2.h linux-2.6.32-vs2.3.0.36.26/fs/ext2/ext2.h
+--- linux-2.6.32/fs/ext2/ext2.h        2009-09-10 15:26:21.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/ext2.h  2009-12-03 20:04:56.000000000 +0100
 @@ -131,6 +131,7 @@ extern int ext2_fiemap(struct inode *ino
  int __ext2_write_begin(struct file *file, struct address_space *mapping,
                loff_t pos, unsigned len, unsigned flags,
@@ -2705,18 +2690,18 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/ext2.h linux-2.6.31.6-vs2.3.0.36.24
  
  /* ioctl.c */
  extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/file.c
---- linux-2.6.31.6/fs/ext2/file.c      2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/file.c        2009-10-07 01:03:12.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/file.c linux-2.6.32-vs2.3.0.36.26/fs/ext2/file.c
+--- linux-2.6.32/fs/ext2/file.c        2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/file.c  2009-12-03 20:04:56.000000000 +0100
 @@ -87,4 +87,5 @@ const struct inode_operations ext2_file_
        .setattr        = ext2_setattr,
-       .permission     = ext2_permission,
+       .check_acl      = ext2_check_acl,
        .fiemap         = ext2_fiemap,
 +      .sync_flags     = ext2_sync_flags,
  };
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/ialloc.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/ialloc.c
---- linux-2.6.31.6/fs/ext2/ialloc.c    2009-06-11 17:13:03.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/ialloc.c      2009-10-12 05:05:34.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/ialloc.c linux-2.6.32-vs2.3.0.36.26/fs/ext2/ialloc.c
+--- linux-2.6.32/fs/ext2/ialloc.c      2009-06-11 17:13:03.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/ialloc.c        2009-12-03 20:04:56.000000000 +0100
 @@ -17,6 +17,7 @@
  #include <linux/backing-dev.h>
  #include <linux/buffer_head.h>
@@ -2733,9 +2718,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/ialloc.c linux-2.6.31.6-vs2.3.0.36.
  
        inode->i_ino = ino;
        inode->i_blocks = 0;
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/inode.c
---- linux-2.6.31.6/fs/ext2/inode.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/inode.c       2009-10-06 19:45:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/inode.c linux-2.6.32-vs2.3.0.36.26/fs/ext2/inode.c
+--- linux-2.6.32/fs/ext2/inode.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/inode.c 2009-12-03 20:04:56.000000000 +0100
 @@ -33,6 +33,7 @@
  #include <linux/mpage.h>
  #include <linux/fiemap.h>
@@ -2744,7 +2729,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
  #include "ext2.h"
  #include "acl.h"
  #include "xip.h"
-@@ -1038,7 +1039,7 @@ void ext2_truncate(struct inode *inode)
+@@ -1040,7 +1041,7 @@ void ext2_truncate(struct inode *inode)
                return;
        if (ext2_inode_is_fast_symlink(inode))
                return;
@@ -2753,7 +2738,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
                return;
  
        blocksize = inode->i_sb->s_blocksize;
-@@ -1176,36 +1177,61 @@ void ext2_set_inode_flags(struct inode *
+@@ -1178,36 +1179,61 @@ void ext2_set_inode_flags(struct inode *
  {
        unsigned int flags = EXT2_I(inode)->i_flags;
  
@@ -2822,7 +2807,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
  }
  
  struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
-@@ -1215,6 +1241,8 @@ struct inode *ext2_iget (struct super_bl
+@@ -1217,6 +1243,8 @@ struct inode *ext2_iget (struct super_bl
        struct ext2_inode *raw_inode;
        struct inode *inode;
        long ret = -EIO;
@@ -2831,7 +2816,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
        int n;
  
        inode = iget_locked(sb, ino);
-@@ -1233,12 +1261,17 @@ struct inode *ext2_iget (struct super_bl
+@@ -1235,12 +1263,17 @@ struct inode *ext2_iget (struct super_bl
        }
  
        inode->i_mode = le16_to_cpu(raw_inode->i_mode);
@@ -2853,7 +2838,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
        inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
        inode->i_size = le32_to_cpu(raw_inode->i_size);
        inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
-@@ -1336,8 +1369,8 @@ int ext2_write_inode(struct inode *inode
+@@ -1338,8 +1371,8 @@ int ext2_write_inode(struct inode *inode
        struct ext2_inode_info *ei = EXT2_I(inode);
        struct super_block *sb = inode->i_sb;
        ino_t ino = inode->i_ino;
@@ -2864,7 +2849,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
        struct buffer_head * bh;
        struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
        int n;
-@@ -1373,6 +1406,9 @@ int ext2_write_inode(struct inode *inode
+@@ -1375,6 +1408,9 @@ int ext2_write_inode(struct inode *inode
                raw_inode->i_uid_high = 0;
                raw_inode->i_gid_high = 0;
        }
@@ -2874,7 +2859,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
        raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
        raw_inode->i_size = cpu_to_le32(inode->i_size);
        raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
-@@ -1454,7 +1490,8 @@ int ext2_setattr(struct dentry *dentry, 
+@@ -1456,7 +1492,8 @@ int ext2_setattr(struct dentry *dentry, 
        if (error)
                return error;
        if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
@@ -2884,9 +2869,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/inode.c linux-2.6.31.6-vs2.3.0.36.2
                error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0;
                if (error)
                        return error;
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/ioctl.c
---- linux-2.6.31.6/fs/ext2/ioctl.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/ioctl.c       2009-10-07 01:01:20.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/ext2/ioctl.c
+--- linux-2.6.32/fs/ext2/ioctl.c       2009-09-10 15:26:21.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/ioctl.c 2009-12-03 20:04:56.000000000 +0100
 @@ -17,6 +17,16 @@
  #include <asm/uaccess.h>
  
@@ -2936,9 +2921,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/ioctl.c linux-2.6.31.6-vs2.3.0.36.2
                flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
                ei->i_flags = flags;
                mutex_unlock(&inode->i_mutex);
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/namei.c
---- linux-2.6.31.6/fs/ext2/namei.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/namei.c       2009-10-07 01:08:06.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/namei.c linux-2.6.32-vs2.3.0.36.26/fs/ext2/namei.c
+--- linux-2.6.32/fs/ext2/namei.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/namei.c 2009-12-03 20:04:56.000000000 +0100
 @@ -31,6 +31,7 @@
   */
  
@@ -2958,14 +2943,14 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/namei.c linux-2.6.31.6-vs2.3.0.36.2
 @@ -401,6 +403,7 @@ const struct inode_operations ext2_dir_i
  #endif
        .setattr        = ext2_setattr,
-       .permission     = ext2_permission,
+       .check_acl      = ext2_check_acl,
 +      .sync_flags     = ext2_sync_flags,
  };
  
  const struct inode_operations ext2_special_inode_operations = {
-diff -NurpP --minimal linux-2.6.31.6/fs/ext2/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/super.c
---- linux-2.6.31.6/fs/ext2/super.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext2/super.c       2009-10-06 22:47:11.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext2/super.c linux-2.6.32-vs2.3.0.36.26/fs/ext2/super.c
+--- linux-2.6.32/fs/ext2/super.c       2009-09-10 15:26:21.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext2/super.c 2009-12-03 20:04:56.000000000 +0100
 @@ -382,7 +382,8 @@ enum {
        Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
        Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
@@ -3031,19 +3016,19 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext2/super.c linux-2.6.31.6-vs2.3.0.36.2
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
                ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
  
-diff -NurpP --minimal linux-2.6.31.6/fs/ext3/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/file.c
---- linux-2.6.31.6/fs/ext3/file.c      2009-06-11 17:13:03.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/file.c        2009-10-06 23:23:15.000000000 +0200
-@@ -139,5 +139,6 @@ const struct inode_operations ext3_file_
+diff -NurpP --minimal linux-2.6.32/fs/ext3/file.c linux-2.6.32-vs2.3.0.36.26/fs/ext3/file.c
+--- linux-2.6.32/fs/ext3/file.c        2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext3/file.c  2009-12-03 20:04:56.000000000 +0100
+@@ -80,5 +80,6 @@ const struct inode_operations ext3_file_
  #endif
-       .permission     = ext3_permission,
+       .check_acl      = ext3_check_acl,
        .fiemap         = ext3_fiemap,
 +      .sync_flags     = ext3_sync_flags,
  };
  
-diff -NurpP --minimal linux-2.6.31.6/fs/ext3/ialloc.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/ialloc.c
---- linux-2.6.31.6/fs/ext3/ialloc.c    2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/ialloc.c      2009-10-12 05:06:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext3/ialloc.c linux-2.6.32-vs2.3.0.36.26/fs/ext3/ialloc.c
+--- linux-2.6.32/fs/ext3/ialloc.c      2009-09-10 15:26:21.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext3/ialloc.c        2009-12-03 20:04:56.000000000 +0100
 @@ -23,6 +23,7 @@
  #include <linux/buffer_head.h>
  #include <linux/random.h>
@@ -3060,9 +3045,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/ialloc.c linux-2.6.31.6-vs2.3.0.36.
  
        inode->i_ino = ino;
        /* This is the optimal IO size (for stat), not the fs block size */
-diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/inode.c
---- linux-2.6.31.6/fs/ext3/inode.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/inode.c       2009-10-06 19:45:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext3/inode.c linux-2.6.32-vs2.3.0.36.26/fs/ext3/inode.c
+--- linux-2.6.32/fs/ext3/inode.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext3/inode.c 2009-12-03 20:04:56.000000000 +0100
 @@ -38,6 +38,7 @@
  #include <linux/bio.h>
  #include <linux/fiemap.h>
@@ -3071,7 +3056,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
  #include "xattr.h"
  #include "acl.h"
  
-@@ -2312,7 +2313,7 @@ static void ext3_free_branches(handle_t 
+@@ -2333,7 +2334,7 @@ static void ext3_free_branches(handle_t 
  
  int ext3_can_truncate(struct inode *inode)
  {
@@ -3080,7 +3065,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
                return 0;
        if (S_ISREG(inode->i_mode))
                return 1;
-@@ -2697,36 +2698,60 @@ void ext3_set_inode_flags(struct inode *
+@@ -2718,36 +2719,60 @@ void ext3_set_inode_flags(struct inode *
  {
        unsigned int flags = EXT3_I(inode)->i_flags;
  
@@ -3148,8 +3133,8 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
  }
  
  struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
-@@ -2738,6 +2763,8 @@ struct inode *ext3_iget(struct super_blo
-       struct inode *inode;
+@@ -2761,6 +2786,8 @@ struct inode *ext3_iget(struct super_blo
+       transaction_t *transaction;
        long ret;
        int block;
 +      uid_t uid;
@@ -3157,7 +3142,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
  
        inode = iget_locked(sb, ino);
        if (!inode)
-@@ -2754,12 +2781,17 @@ struct inode *ext3_iget(struct super_blo
+@@ -2777,12 +2804,17 @@ struct inode *ext3_iget(struct super_blo
        bh = iloc.bh;
        raw_inode = ext3_raw_inode(&iloc);
        inode->i_mode = le16_to_cpu(raw_inode->i_mode);
@@ -3179,7 +3164,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
        inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
        inode->i_size = le32_to_cpu(raw_inode->i_size);
        inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
-@@ -2890,6 +2922,8 @@ static int ext3_do_update_inode(handle_t
+@@ -2937,6 +2969,8 @@ static int ext3_do_update_inode(handle_t
        struct ext3_inode *raw_inode = ext3_raw_inode(iloc);
        struct ext3_inode_info *ei = EXT3_I(inode);
        struct buffer_head *bh = iloc->bh;
@@ -3187,8 +3172,8 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
 +      gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
        int err = 0, rc, block;
  
-       /* For fields not not tracking in the in-memory inode,
-@@ -2900,29 +2934,32 @@ static int ext3_do_update_inode(handle_t
+ again:
+@@ -2951,29 +2985,32 @@ again:
        ext3_get_inode_flags(ei);
        raw_inode->i_mode = cpu_to_le16(inode->i_mode);
        if(!(test_opt(inode->i_sb, NO_UID32))) {
@@ -3227,7 +3212,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
        raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
        raw_inode->i_size = cpu_to_le32(ei->i_disksize);
        raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
-@@ -3074,7 +3111,8 @@ int ext3_setattr(struct dentry *dentry, 
+@@ -3131,7 +3168,8 @@ int ext3_setattr(struct dentry *dentry, 
                return error;
  
        if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
@@ -3237,7 +3222,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
                handle_t *handle;
  
                /* (user+group)*(old+new) structure, inode write (sb,
-@@ -3096,6 +3134,8 @@ int ext3_setattr(struct dentry *dentry, 
+@@ -3153,6 +3191,8 @@ int ext3_setattr(struct dentry *dentry, 
                        inode->i_uid = attr->ia_uid;
                if (attr->ia_valid & ATTR_GID)
                        inode->i_gid = attr->ia_gid;
@@ -3246,9 +3231,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/inode.c linux-2.6.31.6-vs2.3.0.36.2
                error = ext3_mark_inode_dirty(handle, inode);
                ext3_journal_stop(handle);
        }
-diff -NurpP --minimal linux-2.6.31.6/fs/ext3/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/ioctl.c
---- linux-2.6.31.6/fs/ext3/ioctl.c     2009-06-11 17:13:03.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/ioctl.c       2009-10-07 00:08:00.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext3/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/ext3/ioctl.c
+--- linux-2.6.32/fs/ext3/ioctl.c       2009-06-11 17:13:03.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext3/ioctl.c 2009-12-03 20:04:56.000000000 +0100
 @@ -8,6 +8,7 @@
   */
  
@@ -3324,9 +3309,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/ioctl.c linux-2.6.31.6-vs2.3.0.36.2
                flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
                ei->i_flags = flags;
  
-diff -NurpP --minimal linux-2.6.31.6/fs/ext3/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/namei.c
---- linux-2.6.31.6/fs/ext3/namei.c     2009-06-11 17:13:03.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/namei.c       2009-10-06 23:24:04.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext3/namei.c linux-2.6.32-vs2.3.0.36.26/fs/ext3/namei.c
+--- linux-2.6.32/fs/ext3/namei.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext3/namei.c 2009-12-03 20:04:56.000000000 +0100
 @@ -36,6 +36,7 @@
  #include <linux/quotaops.h>
  #include <linux/buffer_head.h>
@@ -3346,15 +3331,15 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/namei.c linux-2.6.31.6-vs2.3.0.36.2
 @@ -2446,6 +2448,7 @@ const struct inode_operations ext3_dir_i
        .removexattr    = generic_removexattr,
  #endif
-       .permission     = ext3_permission,
+       .check_acl      = ext3_check_acl,
 +      .sync_flags     = ext3_sync_flags,
  };
  
  const struct inode_operations ext3_special_inode_operations = {
-diff -NurpP --minimal linux-2.6.31.6/fs/ext3/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/super.c
---- linux-2.6.31.6/fs/ext3/super.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext3/super.c       2009-10-06 22:46:25.000000000 +0200
-@@ -787,7 +787,7 @@ enum {
+diff -NurpP --minimal linux-2.6.32/fs/ext3/super.c linux-2.6.32-vs2.3.0.36.26/fs/ext3/super.c
+--- linux-2.6.32/fs/ext3/super.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext3/super.c 2009-12-03 20:04:56.000000000 +0100
+@@ -789,7 +789,7 @@ enum {
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
        Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
@@ -3363,7 +3348,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/super.c linux-2.6.31.6-vs2.3.0.36.2
  };
  
  static const match_table_t tokens = {
-@@ -840,6 +840,9 @@ static const match_table_t tokens = {
+@@ -842,6 +842,9 @@ static const match_table_t tokens = {
        {Opt_usrquota, "usrquota"},
        {Opt_barrier, "barrier=%u"},
        {Opt_resize, "resize"},
@@ -3373,7 +3358,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/super.c linux-2.6.31.6-vs2.3.0.36.2
        {Opt_err, NULL},
  };
  
-@@ -932,6 +935,20 @@ static int parse_options (char *options,
+@@ -934,6 +937,20 @@ static int parse_options (char *options,
                case Opt_nouid32:
                        set_opt (sbi->s_mount_opt, NO_UID32);
                        break;
@@ -3394,7 +3379,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/super.c linux-2.6.31.6-vs2.3.0.36.2
                case Opt_nocheck:
                        clear_opt (sbi->s_mount_opt, CHECK);
                        break;
-@@ -1656,6 +1673,9 @@ static int ext3_fill_super (struct super
+@@ -1658,6 +1675,9 @@ static int ext3_fill_super (struct super
                            NULL, 0))
                goto failed_mount;
  
@@ -3404,7 +3389,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/super.c linux-2.6.31.6-vs2.3.0.36.2
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
                ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
  
-@@ -2514,6 +2534,14 @@ static int ext3_remount (struct super_bl
+@@ -2527,6 +2547,14 @@ static int ext3_remount (struct super_bl
        if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
                ext3_abort(sb, __func__, "Abort forced by user");
  
@@ -3419,13 +3404,13 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext3/super.c linux-2.6.31.6-vs2.3.0.36.2
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
                ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
  
-diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ext4.h linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/ext4.h
---- linux-2.6.31.6/fs/ext4/ext4.h      2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/ext4.h        2009-10-07 01:23:25.000000000 +0200
-@@ -252,8 +252,12 @@ struct flex_groups {
+diff -NurpP --minimal linux-2.6.32/fs/ext4/ext4.h linux-2.6.32-vs2.3.0.36.26/fs/ext4/ext4.h
+--- linux-2.6.32/fs/ext4/ext4.h        2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext4/ext4.h  2009-12-03 20:04:56.000000000 +0100
+@@ -284,8 +284,12 @@ struct flex_groups {
+ #define EXT4_TOPDIR_FL                        0x00020000 /* Top of directory hierarchies*/
  #define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
  #define EXT4_EXTENTS_FL                       0x00080000 /* Inode uses extents */
- #define EXT4_EXT_MIGRATE              0x00100000 /* Inode is migrating */
 +#define EXT4_IXUNLINK_FL              0x08000000 /* Immutable invert on unlink */
  #define EXT4_RESERVED_FL              0x80000000 /* reserved for ext4 lib */
  
@@ -3435,7 +3420,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ext4.h linux-2.6.31.6-vs2.3.0.36.24
  #define EXT4_FL_USER_VISIBLE          0x000BDFFF /* User visible flags */
  #define EXT4_FL_USER_MODIFIABLE               0x000B80FF /* User modifiable flags */
  
-@@ -423,7 +427,8 @@ struct ext4_inode {
+@@ -469,7 +473,8 @@ struct ext4_inode {
                        __le16  l_i_file_acl_high;
                        __le16  l_i_uid_high;   /* these 2 fields */
                        __le16  l_i_gid_high;   /* were reserved2[0] */
@@ -3445,7 +3430,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ext4.h linux-2.6.31.6-vs2.3.0.36.24
                } linux2;
                struct {
                        __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
-@@ -538,6 +543,7 @@ do {                                                                              \
+@@ -583,6 +588,7 @@ do {                                                                              \
  #define i_gid_low     i_gid
  #define i_uid_high    osd2.linux2.l_i_uid_high
  #define i_gid_high    osd2.linux2.l_i_gid_high
@@ -3453,7 +3438,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ext4.h linux-2.6.31.6-vs2.3.0.36.24
  #define i_reserved2   osd2.linux2.l_i_reserved2
  
  #elif defined(__GNU__)
-@@ -694,6 +700,7 @@ struct ext4_inode_info {
+@@ -744,6 +750,7 @@ struct ext4_inode_info {
  #define EXT4_MOUNT_QUOTA              0x80000 /* Some quota option set */
  #define EXT4_MOUNT_USRQUOTA           0x100000 /* "old" user quota */
  #define EXT4_MOUNT_GRPQUOTA           0x200000 /* "old" group quota */
@@ -3461,7 +3446,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ext4.h linux-2.6.31.6-vs2.3.0.36.24
  #define EXT4_MOUNT_JOURNAL_CHECKSUM   0x800000 /* Journal checksums */
  #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT       0x1000000 /* Journal Async Commit */
  #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
-@@ -1655,6 +1662,7 @@ extern int ext4_get_blocks(handle_t *han
+@@ -1734,6 +1741,7 @@ extern int ext4_get_blocks(handle_t *han
                           struct buffer_head *bh, int flags);
  extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                        __u64 start, __u64 len);
@@ -3469,19 +3454,19 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ext4.h linux-2.6.31.6-vs2.3.0.36.24
  /* move_extent.c */
  extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
                             __u64 start_orig, __u64 start_donor,
-diff -NurpP --minimal linux-2.6.31.6/fs/ext4/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/file.c
---- linux-2.6.31.6/fs/ext4/file.c      2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/file.c        2009-10-07 01:03:26.000000000 +0200
-@@ -210,5 +210,6 @@ const struct inode_operations ext4_file_
-       .permission     = ext4_permission,
+diff -NurpP --minimal linux-2.6.32/fs/ext4/file.c linux-2.6.32-vs2.3.0.36.26/fs/ext4/file.c
+--- linux-2.6.32/fs/ext4/file.c        2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext4/file.c  2009-12-03 20:04:56.000000000 +0100
+@@ -161,5 +161,6 @@ const struct inode_operations ext4_file_
+       .check_acl      = ext4_check_acl,
        .fallocate      = ext4_fallocate,
        .fiemap         = ext4_fiemap,
 +      .sync_flags     = ext4_sync_flags,
  };
  
-diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ialloc.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/ialloc.c
---- linux-2.6.31.6/fs/ext4/ialloc.c    2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/ialloc.c      2009-10-12 05:06:42.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext4/ialloc.c linux-2.6.32-vs2.3.0.36.26/fs/ext4/ialloc.c
+--- linux-2.6.32/fs/ext4/ialloc.c      2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext4/ialloc.c        2009-12-03 20:04:56.000000000 +0100
 @@ -22,6 +22,7 @@
  #include <linux/random.h>
  #include <linux/bitops.h>
@@ -3498,18 +3483,18 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ialloc.c linux-2.6.31.6-vs2.3.0.36.
  
        inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
        /* This is the optimal IO size (for stat), not the fs block size */
-diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/inode.c
---- linux-2.6.31.6/fs/ext4/inode.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/inode.c       2009-10-06 19:45:13.000000000 +0200
-@@ -37,6 +37,7 @@
- #include <linux/namei.h>
+diff -NurpP --minimal linux-2.6.32/fs/ext4/inode.c linux-2.6.32-vs2.3.0.36.26/fs/ext4/inode.c
+--- linux-2.6.32/fs/ext4/inode.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext4/inode.c 2009-12-03 20:04:56.000000000 +0100
+@@ -38,6 +38,7 @@
  #include <linux/uio.h>
  #include <linux/bio.h>
+ #include <linux/workqueue.h>
 +#include <linux/vs_tag.h>
  
  #include "ext4_jbd2.h"
  #include "xattr.h"
-@@ -3901,7 +3902,7 @@ static void ext4_free_branches(handle_t 
+@@ -4370,7 +4371,7 @@ static void ext4_free_branches(handle_t 
  
  int ext4_can_truncate(struct inode *inode)
  {
@@ -3518,7 +3503,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
                return 0;
        if (S_ISREG(inode->i_mode))
                return 1;
-@@ -4253,36 +4254,60 @@ void ext4_set_inode_flags(struct inode *
+@@ -4721,36 +4722,60 @@ void ext4_set_inode_flags(struct inode *
  {
        unsigned int flags = EXT4_I(inode)->i_flags;
  
@@ -3586,7 +3571,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
  }
  
  static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
-@@ -4317,6 +4342,8 @@ struct inode *ext4_iget(struct super_blo
+@@ -4785,6 +4810,8 @@ struct inode *ext4_iget(struct super_blo
        struct inode *inode;
        long ret;
        int block;
@@ -3595,7 +3580,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
  
        inode = iget_locked(sb, ino);
        if (!inode)
-@@ -4332,12 +4359,16 @@ struct inode *ext4_iget(struct super_blo
+@@ -4800,12 +4827,16 @@ struct inode *ext4_iget(struct super_blo
        bh = iloc.bh;
        raw_inode = ext4_raw_inode(&iloc);
        inode->i_mode = le16_to_cpu(raw_inode->i_mode);
@@ -3616,7 +3601,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
        inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
  
        ei->i_state = 0;
-@@ -4538,6 +4569,8 @@ static int ext4_do_update_inode(handle_t
+@@ -5006,6 +5037,8 @@ static int ext4_do_update_inode(handle_t
        struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
        struct ext4_inode_info *ei = EXT4_I(inode);
        struct buffer_head *bh = iloc->bh;
@@ -3625,7 +3610,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
        int err = 0, rc, block;
  
        /* For fields not not tracking in the in-memory inode,
-@@ -4548,29 +4581,32 @@ static int ext4_do_update_inode(handle_t
+@@ -5016,29 +5049,32 @@ static int ext4_do_update_inode(handle_t
        ext4_get_inode_flags(ei);
        raw_inode->i_mode = cpu_to_le16(inode->i_mode);
        if (!(test_opt(inode->i_sb, NO_UID32))) {
@@ -3664,7 +3649,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
        raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
  
        EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
-@@ -4734,7 +4770,8 @@ int ext4_setattr(struct dentry *dentry, 
+@@ -5222,7 +5258,8 @@ int ext4_setattr(struct dentry *dentry, 
                return error;
  
        if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
@@ -3674,7 +3659,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
                handle_t *handle;
  
                /* (user+group)*(old+new) structure, inode write (sb,
-@@ -4756,6 +4793,8 @@ int ext4_setattr(struct dentry *dentry, 
+@@ -5244,6 +5281,8 @@ int ext4_setattr(struct dentry *dentry, 
                        inode->i_uid = attr->ia_uid;
                if (attr->ia_valid & ATTR_GID)
                        inode->i_gid = attr->ia_gid;
@@ -3683,9 +3668,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/inode.c linux-2.6.31.6-vs2.3.0.36.2
                error = ext4_mark_inode_dirty(handle, inode);
                ext4_journal_stop(handle);
        }
-diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/ioctl.c
---- linux-2.6.31.6/fs/ext4/ioctl.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/ioctl.c       2009-10-07 04:03:02.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext4/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/ext4/ioctl.c
+--- linux-2.6.32/fs/ext4/ioctl.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext4/ioctl.c 2009-12-03 20:04:56.000000000 +0100
 @@ -14,10 +14,39 @@
  #include <linux/compat.h>
  #include <linux/mount.h>
@@ -3749,9 +3734,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/ioctl.c linux-2.6.31.6-vs2.3.0.36.2
                        if (!capable(CAP_LINUX_IMMUTABLE))
                                goto flags_out;
                }
-diff -NurpP --minimal linux-2.6.31.6/fs/ext4/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/namei.c
---- linux-2.6.31.6/fs/ext4/namei.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/namei.c       2009-10-07 01:08:37.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ext4/namei.c linux-2.6.32-vs2.3.0.36.26/fs/ext4/namei.c
+--- linux-2.6.32/fs/ext4/namei.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext4/namei.c 2009-12-03 20:04:56.000000000 +0100
 @@ -34,6 +34,7 @@
  #include <linux/quotaops.h>
  #include <linux/buffer_head.h>
@@ -3768,18 +3753,18 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/namei.c linux-2.6.31.6-vs2.3.0.36.2
                }
                if ((bh = bh_use[ra_ptr++]) == NULL)
                        goto next;
-@@ -2538,6 +2540,7 @@ const struct inode_operations ext4_dir_i
+@@ -2539,6 +2541,7 @@ const struct inode_operations ext4_dir_i
  #endif
-       .permission     = ext4_permission,
+       .check_acl      = ext4_check_acl,
        .fiemap         = ext4_fiemap,
 +      .sync_flags     = ext4_sync_flags,
  };
  
  const struct inode_operations ext4_special_inode_operations = {
-diff -NurpP --minimal linux-2.6.31.6/fs/ext4/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/super.c
---- linux-2.6.31.6/fs/ext4/super.c     2009-09-10 15:26:21.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ext4/super.c       2009-10-06 22:47:27.000000000 +0200
-@@ -1057,7 +1057,8 @@ enum {
+diff -NurpP --minimal linux-2.6.32/fs/ext4/super.c linux-2.6.32-vs2.3.0.36.26/fs/ext4/super.c
+--- linux-2.6.32/fs/ext4/super.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ext4/super.c 2009-12-03 20:04:56.000000000 +0100
+@@ -1079,7 +1079,8 @@ enum {
        Opt_usrquota, Opt_grpquota, Opt_i_version,
        Opt_stripe, Opt_delalloc, Opt_nodelalloc,
        Opt_block_validity, Opt_noblock_validity,
@@ -3789,7 +3774,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/super.c linux-2.6.31.6-vs2.3.0.36.2
  };
  
  static const match_table_t tokens = {
-@@ -1123,6 +1124,9 @@ static const match_table_t tokens = {
+@@ -1144,6 +1145,9 @@ static const match_table_t tokens = {
        {Opt_auto_da_alloc, "auto_da_alloc=%u"},
        {Opt_auto_da_alloc, "auto_da_alloc"},
        {Opt_noauto_da_alloc, "noauto_da_alloc"},
@@ -3799,7 +3784,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/super.c linux-2.6.31.6-vs2.3.0.36.2
        {Opt_err, NULL},
  };
  
-@@ -1220,6 +1224,20 @@ static int parse_options(char *options, 
+@@ -1241,6 +1245,20 @@ static int parse_options(char *options, 
                case Opt_nouid32:
                        set_opt(sbi->s_mount_opt, NO_UID32);
                        break;
@@ -3820,7 +3805,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/super.c linux-2.6.31.6-vs2.3.0.36.2
                case Opt_debug:
                        set_opt(sbi->s_mount_opt, DEBUG);
                        break;
-@@ -2385,6 +2403,9 @@ static int ext4_fill_super(struct super_
+@@ -2435,6 +2453,9 @@ static int ext4_fill_super(struct super_
                           &journal_ioprio, NULL, 0))
                goto failed_mount;
  
@@ -3830,7 +3815,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/super.c linux-2.6.31.6-vs2.3.0.36.2
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
                ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
  
-@@ -3441,6 +3462,14 @@ static int ext4_remount(struct super_blo
+@@ -3492,6 +3513,14 @@ static int ext4_remount(struct super_blo
        if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
                ext4_abort(sb, __func__, "Abort forced by user");
  
@@ -3845,9 +3830,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ext4/super.c linux-2.6.31.6-vs2.3.0.36.2
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
                ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
  
-diff -NurpP --minimal linux-2.6.31.6/fs/fcntl.c linux-2.6.31.6-vs2.3.0.36.24/fs/fcntl.c
---- linux-2.6.31.6/fs/fcntl.c  2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/fcntl.c    2009-09-10 17:00:41.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/fcntl.c linux-2.6.32-vs2.3.0.36.26/fs/fcntl.c
+--- linux-2.6.32/fs/fcntl.c    2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/fcntl.c      2009-12-03 20:04:56.000000000 +0100
 @@ -19,6 +19,7 @@
  #include <linux/signal.h>
  #include <linux/rcupdate.h>
@@ -3865,7 +3850,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/fcntl.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  
        return newfd;
  
-@@ -347,6 +350,8 @@ SYSCALL_DEFINE3(fcntl, unsigned int, fd,
+@@ -426,6 +429,8 @@ SYSCALL_DEFINE3(fcntl, unsigned int, fd,
        filp = fget(fd);
        if (!filp)
                goto out;
@@ -3874,10 +3859,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/fcntl.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  
        err = security_file_fcntl(filp, cmd, arg);
        if (err) {
-diff -NurpP --minimal linux-2.6.31.6/fs/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/file.c
---- linux-2.6.31.6/fs/file.c   2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/file.c     2009-09-10 16:11:43.000000000 +0200
-@@ -19,6 +19,7 @@
+diff -NurpP --minimal linux-2.6.32/fs/file.c linux-2.6.32-vs2.3.0.36.26/fs/file.c
+--- linux-2.6.32/fs/file.c     2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/file.c       2009-12-03 20:04:56.000000000 +0100
+@@ -20,6 +20,7 @@
  #include <linux/spinlock.h>
  #include <linux/rcupdate.h>
  #include <linux/workqueue.h>
@@ -3885,7 +3870,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/f
  
  struct fdtable_defer {
        spinlock_t lock;
-@@ -367,6 +368,8 @@ struct files_struct *dup_fd(struct files
+@@ -368,6 +369,8 @@ struct files_struct *dup_fd(struct files
                struct file *f = *old_fds++;
                if (f) {
                        get_file(f);
@@ -3894,7 +3879,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/f
                } else {
                        /*
                         * The fd may be claimed in the fd bitmap but not yet
-@@ -475,6 +478,7 @@ repeat:
+@@ -476,6 +479,7 @@ repeat:
        else
                FD_CLR(fd, fdt->close_on_exec);
        error = fd;
@@ -3902,9 +3887,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/f
  #if 1
        /* Sanity check */
        if (rcu_dereference(fdt->fd[fd]) != NULL) {
-diff -NurpP --minimal linux-2.6.31.6/fs/file_table.c linux-2.6.31.6-vs2.3.0.36.24/fs/file_table.c
---- linux-2.6.31.6/fs/file_table.c     2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/file_table.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/file_table.c linux-2.6.32-vs2.3.0.36.26/fs/file_table.c
+--- linux-2.6.32/fs/file_table.c       2009-12-03 20:02:51.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/file_table.c 2009-12-03 20:04:56.000000000 +0100
 @@ -22,6 +22,8 @@
  #include <linux/fsnotify.h>
  #include <linux/sysctl.h>
@@ -3941,9 +3926,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/file_table.c linux-2.6.31.6-vs2.3.0.36.2
                file_kill(file);
                file_free(file);
        }
-diff -NurpP --minimal linux-2.6.31.6/fs/fs_struct.c linux-2.6.31.6-vs2.3.0.36.24/fs/fs_struct.c
---- linux-2.6.31.6/fs/fs_struct.c      2009-06-11 17:13:04.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/fs_struct.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/fs_struct.c linux-2.6.32-vs2.3.0.36.26/fs/fs_struct.c
+--- linux-2.6.32/fs/fs_struct.c        2009-06-11 17:13:04.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/fs_struct.c  2009-12-03 20:04:56.000000000 +0100
 @@ -4,6 +4,7 @@
  #include <linux/path.h>
  #include <linux/slab.h>
@@ -3968,10 +3953,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/fs_struct.c linux-2.6.31.6-vs2.3.0.36.24
        }
        return fs;
  }
-diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/gfs2/file.c
---- linux-2.6.31.6/fs/gfs2/file.c      2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/gfs2/file.c        2009-10-07 18:47:19.000000000 +0200
-@@ -133,6 +133,9 @@ static const u32 fsflags_to_gfs2[32] = {
+diff -NurpP --minimal linux-2.6.32/fs/gfs2/file.c linux-2.6.32-vs2.3.0.36.26/fs/gfs2/file.c
+--- linux-2.6.32/fs/gfs2/file.c        2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/gfs2/file.c  2009-12-03 20:04:56.000000000 +0100
+@@ -132,6 +132,9 @@ static const u32 fsflags_to_gfs2[32] = {
        [7] = GFS2_DIF_NOATIME,
        [12] = GFS2_DIF_EXHASH,
        [14] = GFS2_DIF_INHERIT_JDATA,
@@ -3981,7 +3966,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/file.c linux-2.6.31.6-vs2.3.0.36.24
  };
  
  static const u32 gfs2_to_fsflags[32] = {
-@@ -142,6 +145,9 @@ static const u32 gfs2_to_fsflags[32] = {
+@@ -141,6 +144,9 @@ static const u32 gfs2_to_fsflags[32] = {
        [gfs2fl_NoAtime] = FS_NOATIME_FL,
        [gfs2fl_ExHash] = FS_INDEX_FL,
        [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
@@ -3991,7 +3976,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/file.c linux-2.6.31.6-vs2.3.0.36.24
  };
  
  static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
-@@ -172,10 +178,16 @@ void gfs2_set_inode_flags(struct inode *
+@@ -171,10 +177,16 @@ void gfs2_set_inode_flags(struct inode *
  {
        struct gfs2_inode *ip = GFS2_I(inode);
        unsigned int flags = inode->i_flags;
@@ -4009,7 +3994,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/file.c linux-2.6.31.6-vs2.3.0.36.24
        if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
                flags |= S_APPEND;
        if (ip->i_diskflags & GFS2_DIF_NOATIME)
-@@ -183,6 +195,43 @@ void gfs2_set_inode_flags(struct inode *
+@@ -182,6 +194,43 @@ void gfs2_set_inode_flags(struct inode *
        if (ip->i_diskflags & GFS2_DIF_SYNC)
                flags |= S_SYNC;
        inode->i_flags = flags;
@@ -4053,7 +4038,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/file.c linux-2.6.31.6-vs2.3.0.36.24
  }
  
  /* Flags that can be set by user space */
-@@ -287,6 +336,37 @@ static int gfs2_set_flags(struct file *f
+@@ -286,6 +335,37 @@ static int gfs2_set_flags(struct file *f
        return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
  }
  
@@ -4091,9 +4076,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/file.c linux-2.6.31.6-vs2.3.0.36.24
  static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  {
        switch(cmd) {
-diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/inode.h linux-2.6.31.6-vs2.3.0.36.24/fs/gfs2/inode.h
---- linux-2.6.31.6/fs/gfs2/inode.h     2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/gfs2/inode.h       2009-10-07 18:16:33.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/gfs2/inode.h linux-2.6.32-vs2.3.0.36.26/fs/gfs2/inode.h
+--- linux-2.6.32/fs/gfs2/inode.h       2009-09-10 15:26:22.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/gfs2/inode.h 2009-12-03 20:04:56.000000000 +0100
 @@ -109,6 +109,7 @@ extern const struct file_operations gfs2
  extern const struct file_operations gfs2_dir_fops_nolock;
  
@@ -4102,10 +4087,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/inode.h linux-2.6.31.6-vs2.3.0.36.2
   
  #ifdef CONFIG_GFS2_FS_LOCKING_DLM
  extern const struct file_operations gfs2_file_fops;
-diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/ops_inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/gfs2/ops_inode.c
---- linux-2.6.31.6/fs/gfs2/ops_inode.c 2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/gfs2/ops_inode.c   2009-10-07 18:15:45.000000000 +0200
-@@ -1409,6 +1409,7 @@ const struct inode_operations gfs2_file_
+diff -NurpP --minimal linux-2.6.32/fs/gfs2/ops_inode.c linux-2.6.32-vs2.3.0.36.26/fs/gfs2/ops_inode.c
+--- linux-2.6.32/fs/gfs2/ops_inode.c   2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/gfs2/ops_inode.c     2009-12-03 20:04:56.000000000 +0100
+@@ -1400,6 +1400,7 @@ const struct inode_operations gfs2_file_
        .listxattr = gfs2_listxattr,
        .removexattr = gfs2_removexattr,
        .fiemap = gfs2_fiemap,
@@ -4113,7 +4098,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/ops_inode.c linux-2.6.31.6-vs2.3.0.
  };
  
  const struct inode_operations gfs2_dir_iops = {
-@@ -1429,6 +1430,7 @@ const struct inode_operations gfs2_dir_i
+@@ -1420,6 +1421,7 @@ const struct inode_operations gfs2_dir_i
        .listxattr = gfs2_listxattr,
        .removexattr = gfs2_removexattr,
        .fiemap = gfs2_fiemap,
@@ -4121,9 +4106,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/gfs2/ops_inode.c linux-2.6.31.6-vs2.3.0.
  };
  
  const struct inode_operations gfs2_symlink_iops = {
-diff -NurpP --minimal linux-2.6.31.6/fs/hfsplus/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/hfsplus/ioctl.c
---- linux-2.6.31.6/fs/hfsplus/ioctl.c  2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/hfsplus/ioctl.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/hfsplus/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/hfsplus/ioctl.c
+--- linux-2.6.32/fs/hfsplus/ioctl.c    2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/hfsplus/ioctl.c      2009-12-03 20:04:56.000000000 +0100
 @@ -17,6 +17,7 @@
  #include <linux/mount.h>
  #include <linux/sched.h>
@@ -4132,10 +4117,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/hfsplus/ioctl.c linux-2.6.31.6-vs2.3.0.3
  #include <asm/uaccess.h>
  #include "hfsplus_fs.h"
  
-diff -NurpP --minimal linux-2.6.31.6/fs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/inode.c
---- linux-2.6.31.6/fs/inode.c  2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/inode.c    2009-10-05 23:35:52.000000000 +0200
-@@ -128,6 +128,9 @@ int inode_init_always(struct super_block
+diff -NurpP --minimal linux-2.6.32/fs/inode.c linux-2.6.32-vs2.3.0.36.26/fs/inode.c
+--- linux-2.6.32/fs/inode.c    2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/inode.c      2009-12-03 20:04:56.000000000 +0100
+@@ -133,6 +133,9 @@ int inode_init_always(struct super_block
        struct address_space *const mapping = &inode->i_data;
  
        inode->i_sb = sb;
@@ -4145,7 +4130,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        inode->i_blkbits = sb->s_blocksize_bits;
        inode->i_flags = 0;
        atomic_set(&inode->i_count, 1);
-@@ -148,6 +151,7 @@ int inode_init_always(struct super_block
+@@ -153,6 +156,7 @@ int inode_init_always(struct super_block
        inode->i_bdev = NULL;
        inode->i_cdev = NULL;
        inode->i_rdev = 0;
@@ -4153,7 +4138,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        inode->dirtied_when = 0;
  
        if (security_inode_alloc(inode))
-@@ -304,6 +308,8 @@ void __iget(struct inode *inode)
+@@ -307,6 +311,8 @@ void __iget(struct inode *inode)
        inodes_stat.nr_unused--;
  }
  
@@ -4162,7 +4147,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  /**
   * clear_inode - clear an inode
   * @inode: inode to clear
-@@ -1588,9 +1594,11 @@ void init_special_inode(struct inode *in
+@@ -1611,9 +1617,11 @@ void init_special_inode(struct inode *in
        if (S_ISCHR(mode)) {
                inode->i_fop = &def_chr_fops;
                inode->i_rdev = rdev;
@@ -4174,9 +4159,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        } else if (S_ISFIFO(mode))
                inode->i_fop = &def_fifo_fops;
        else if (S_ISSOCK(mode))
-diff -NurpP --minimal linux-2.6.31.6/fs/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/ioctl.c
---- linux-2.6.31.6/fs/ioctl.c  2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ioctl.c    2009-09-10 17:13:08.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/ioctl.c
+--- linux-2.6.32/fs/ioctl.c    2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ioctl.c      2009-12-03 20:04:56.000000000 +0100
 @@ -16,6 +16,9 @@
  #include <linux/writeback.h>
  #include <linux/buffer_head.h>
@@ -4187,9 +4172,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  
  #include <asm/ioctls.h>
  
-diff -NurpP --minimal linux-2.6.31.6/fs/ioprio.c linux-2.6.31.6-vs2.3.0.36.24/fs/ioprio.c
---- linux-2.6.31.6/fs/ioprio.c 2009-03-24 14:22:26.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ioprio.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ioprio.c linux-2.6.32-vs2.3.0.36.26/fs/ioprio.c
+--- linux-2.6.32/fs/ioprio.c   2009-03-24 14:22:26.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ioprio.c     2009-12-03 20:04:56.000000000 +0100
 @@ -26,6 +26,7 @@
  #include <linux/syscalls.h>
  #include <linux/security.h>
@@ -4216,10 +4201,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ioprio.c linux-2.6.31.6-vs2.3.0.36.24/fs
                                tmpio = get_task_ioprio(p);
                                if (tmpio < 0)
                                        continue;
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/acl.c linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/acl.c
---- linux-2.6.31.6/fs/jfs/acl.c        2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/acl.c  2009-09-10 16:11:43.000000000 +0200
-@@ -221,7 +221,8 @@ int jfs_setattr(struct dentry *dentry, s
+diff -NurpP --minimal linux-2.6.32/fs/jfs/acl.c linux-2.6.32-vs2.3.0.36.26/fs/jfs/acl.c
+--- linux-2.6.32/fs/jfs/acl.c  2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/acl.c    2009-12-03 20:04:56.000000000 +0100
+@@ -216,7 +216,8 @@ int jfs_setattr(struct dentry *dentry, s
                return rc;
  
        if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
@@ -4229,20 +4214,20 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/acl.c linux-2.6.31.6-vs2.3.0.36.24/f
                if (vfs_dq_transfer(inode, iattr))
                        return -EDQUOT;
        }
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/file.c
---- linux-2.6.31.6/fs/jfs/file.c       2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/file.c 2009-10-07 01:05:32.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/file.c linux-2.6.32-vs2.3.0.36.26/fs/jfs/file.c
+--- linux-2.6.32/fs/jfs/file.c 2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/file.c   2009-12-03 20:04:56.000000000 +0100
 @@ -98,6 +98,7 @@ const struct inode_operations jfs_file_i
        .setattr        = jfs_setattr,
-       .permission     = jfs_permission,
+       .check_acl      = jfs_check_acl,
  #endif
 +      .sync_flags     = jfs_sync_flags,
  };
  
  const struct file_operations jfs_file_operations = {
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/ioctl.c
---- linux-2.6.31.6/fs/jfs/ioctl.c      2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/ioctl.c        2009-10-07 04:09:15.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/jfs/ioctl.c
+--- linux-2.6.32/fs/jfs/ioctl.c        2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/ioctl.c  2009-12-03 20:04:56.000000000 +0100
 @@ -11,6 +11,7 @@
  #include <linux/mount.h>
  #include <linux/time.h>
@@ -4300,9 +4285,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/ioctl.c linux-2.6.31.6-vs2.3.0.36.24
                flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
                jfs_inode->mode2 = flags;
  
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_dinode.h linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_dinode.h
---- linux-2.6.31.6/fs/jfs/jfs_dinode.h 2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_dinode.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/jfs_dinode.h linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_dinode.h
+--- linux-2.6.32/fs/jfs/jfs_dinode.h   2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_dinode.h     2009-12-03 20:04:56.000000000 +0100
 @@ -161,9 +161,13 @@ struct dinode {
  
  #define JFS_APPEND_FL         0x01000000 /* writes to file may only append */
@@ -4319,9 +4304,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_dinode.h linux-2.6.31.6-vs2.3.0.
  #define JFS_FL_INHERIT                0x03C80000
  
  /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_filsys.h linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_filsys.h
---- linux-2.6.31.6/fs/jfs/jfs_filsys.h 2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_filsys.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/jfs_filsys.h linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_filsys.h
+--- linux-2.6.32/fs/jfs/jfs_filsys.h   2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_filsys.h     2009-12-03 20:04:56.000000000 +0100
 @@ -263,6 +263,7 @@
  #define JFS_NAME_MAX  255
  #define JFS_PATH_MAX  BPSIZE
@@ -4330,9 +4315,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_filsys.h linux-2.6.31.6-vs2.3.0.
  
  /*
   *    file system state (superblock state)
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_imap.c linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_imap.c
---- linux-2.6.31.6/fs/jfs/jfs_imap.c   2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_imap.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/jfs_imap.c linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_imap.c
+--- linux-2.6.32/fs/jfs/jfs_imap.c     2009-09-10 15:26:22.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_imap.c       2009-12-03 20:04:56.000000000 +0100
 @@ -45,6 +45,7 @@
  #include <linux/buffer_head.h>
  #include <linux/pagemap.h>
@@ -4392,9 +4377,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_imap.c linux-2.6.31.6-vs2.3.0.36
        jfs_get_inode_flags(jfs_ip);
        /*
         * mode2 is only needed for storing the higher order bits.
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_inode.c
---- linux-2.6.31.6/fs/jfs/jfs_inode.c  2009-06-11 17:13:05.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_inode.c    2009-10-12 05:07:16.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/jfs_inode.c linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_inode.c
+--- linux-2.6.32/fs/jfs/jfs_inode.c    2009-06-11 17:13:05.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_inode.c      2009-12-03 20:04:56.000000000 +0100
 @@ -18,6 +18,7 @@
  
  #include <linux/fs.h>
@@ -4476,9 +4461,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_inode.c linux-2.6.31.6-vs2.3.0.3
  
        /*
         * New inodes need to save sane values on disk when
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_inode.h linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_inode.h
---- linux-2.6.31.6/fs/jfs/jfs_inode.h  2009-06-11 17:13:05.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/jfs_inode.h    2009-10-07 01:25:26.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/jfs_inode.h linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_inode.h
+--- linux-2.6.32/fs/jfs/jfs_inode.h    2009-06-11 17:13:05.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/jfs_inode.h      2009-12-03 20:04:56.000000000 +0100
 @@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s
  extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
        int fh_len, int fh_type);
@@ -4487,9 +4472,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/jfs_inode.h linux-2.6.31.6-vs2.3.0.3
  extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
  
  extern const struct address_space_operations jfs_aops;
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/namei.c
---- linux-2.6.31.6/fs/jfs/namei.c      2009-06-11 17:13:05.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/namei.c        2009-10-07 01:09:16.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/jfs/namei.c linux-2.6.32-vs2.3.0.36.26/fs/jfs/namei.c
+--- linux-2.6.32/fs/jfs/namei.c        2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/namei.c  2009-12-03 20:04:56.000000000 +0100
 @@ -21,6 +21,7 @@
  #include <linux/ctype.h>
  #include <linux/quotaops.h>
@@ -4508,16 +4493,16 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/namei.c linux-2.6.31.6-vs2.3.0.36.24
        if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
 @@ -1545,6 +1547,7 @@ const struct inode_operations jfs_dir_in
        .setattr        = jfs_setattr,
-       .permission     = jfs_permission,
+       .check_acl      = jfs_check_acl,
  #endif
 +      .sync_flags     = jfs_sync_flags,
  };
  
  const struct file_operations jfs_dir_operations = {
-diff -NurpP --minimal linux-2.6.31.6/fs/jfs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/super.c
---- linux-2.6.31.6/fs/jfs/super.c      2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/jfs/super.c        2009-09-10 17:10:55.000000000 +0200
-@@ -194,7 +194,8 @@ static void jfs_put_super(struct super_b
+diff -NurpP --minimal linux-2.6.32/fs/jfs/super.c linux-2.6.32-vs2.3.0.36.26/fs/jfs/super.c
+--- linux-2.6.32/fs/jfs/super.c        2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/jfs/super.c  2009-12-03 20:04:56.000000000 +0100
+@@ -192,7 +192,8 @@ static void jfs_put_super(struct super_b
  enum {
        Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
        Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
@@ -4527,7 +4512,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/super.c linux-2.6.31.6-vs2.3.0.36.24
  };
  
  static const match_table_t tokens = {
-@@ -204,6 +205,10 @@ static const match_table_t tokens = {
+@@ -202,6 +203,10 @@ static const match_table_t tokens = {
        {Opt_resize, "resize=%u"},
        {Opt_resize_nosize, "resize"},
        {Opt_errors, "errors=%s"},
@@ -4538,7 +4523,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/super.c linux-2.6.31.6-vs2.3.0.36.24
        {Opt_ignore, "noquota"},
        {Opt_ignore, "quota"},
        {Opt_usrquota, "usrquota"},
-@@ -338,6 +343,20 @@ static int parse_options(char *options, 
+@@ -336,6 +341,20 @@ static int parse_options(char *options, 
                        }
                        break;
                }
@@ -4559,7 +4544,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/super.c linux-2.6.31.6-vs2.3.0.36.24
                default:
                        printk("jfs: Unrecognized mount option \"%s\" "
                                        " or missing value\n", p);
-@@ -369,6 +388,12 @@ static int jfs_remount(struct super_bloc
+@@ -366,6 +385,12 @@ static int jfs_remount(struct super_bloc
        if (!parse_options(data, sb, &newLVSize, &flag)) {
                return -EINVAL;
        }
@@ -4572,7 +4557,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/super.c linux-2.6.31.6-vs2.3.0.36.24
        lock_kernel();
        if (newLVSize) {
                if (sb->s_flags & MS_RDONLY) {
-@@ -452,6 +477,9 @@ static int jfs_fill_super(struct super_b
+@@ -449,6 +474,9 @@ static int jfs_fill_super(struct super_b
  #ifdef CONFIG_JFS_POSIX_ACL
        sb->s_flags |= MS_POSIXACL;
  #endif
@@ -4582,9 +4567,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/jfs/super.c linux-2.6.31.6-vs2.3.0.36.24
  
        if (newLVSize) {
                printk(KERN_ERR "resize option for remount only\n");
-diff -NurpP --minimal linux-2.6.31.6/fs/libfs.c linux-2.6.31.6-vs2.3.0.36.24/fs/libfs.c
---- linux-2.6.31.6/fs/libfs.c  2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/libfs.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/libfs.c linux-2.6.32-vs2.3.0.36.26/fs/libfs.c
+--- linux-2.6.32/fs/libfs.c    2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/libfs.c      2009-12-03 20:04:56.000000000 +0100
 @@ -127,7 +127,8 @@ static inline unsigned char dt_type(stru
   * both impossible due to the lock on directory.
   */
@@ -4623,7 +4608,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/libfs.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
  {
        return -EISDIR;
-@@ -836,6 +851,7 @@ EXPORT_SYMBOL(dcache_dir_close);
+@@ -841,6 +856,7 @@ EXPORT_SYMBOL(dcache_dir_close);
  EXPORT_SYMBOL(dcache_dir_lseek);
  EXPORT_SYMBOL(dcache_dir_open);
  EXPORT_SYMBOL(dcache_readdir);
@@ -4631,9 +4616,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/libfs.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  EXPORT_SYMBOL(generic_read_dir);
  EXPORT_SYMBOL(get_sb_pseudo);
  EXPORT_SYMBOL(simple_write_begin);
-diff -NurpP --minimal linux-2.6.31.6/fs/locks.c linux-2.6.31.6-vs2.3.0.36.24/fs/locks.c
---- linux-2.6.31.6/fs/locks.c  2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/locks.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/locks.c linux-2.6.32-vs2.3.0.36.26/fs/locks.c
+--- linux-2.6.32/fs/locks.c    2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/locks.c      2009-12-03 20:04:56.000000000 +0100
 @@ -127,6 +127,8 @@
  #include <linux/time.h>
  #include <linux/rcupdate.h>
@@ -4710,7 +4695,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/locks.c linux-2.6.31.6-vs2.3.0.36.24/fs/
                locks_free_lock(fl);
 @@ -770,6 +788,7 @@ static int flock_lock_file(struct file *
        if (found)
-               cond_resched_bkl();
+               cond_resched();
  
 +      new_fl->fl_xid = -1;
  find_conflict:
@@ -4819,9 +4804,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/locks.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  
        f->private++;
        return 0;
-diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/namei.c
---- linux-2.6.31.6/fs/namei.c  2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/namei.c    2009-10-15 03:49:19.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/namei.c linux-2.6.32-vs2.3.0.36.26/fs/namei.c
+--- linux-2.6.32/fs/namei.c    2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/namei.c      2009-12-03 20:04:56.000000000 +0100
 @@ -33,6 +33,14 @@
  #include <linux/fcntl.h>
  #include <linux/device_cgroup.h>
@@ -4841,7 +4826,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  EXPORT_SYMBOL(putname);
  #endif
  
-+static inline int dx_barrier(struct inode *inode)
++static inline int dx_barrier(const struct inode *inode)
 +{
 +      if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
 +              vxwprintk_task(1, "did hit the barrier.");
@@ -4850,7 +4835,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
 +      return 0;
 +}
 +
-+static int __dx_permission(struct inode *inode, int mask)
++static int __dx_permission(const struct inode *inode, int mask)
 +{
 +      if (dx_barrier(inode))
 +              return -EACCES;
@@ -4901,7 +4886,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
 +      return -EACCES;
 +}
 +
-+int dx_permission(struct inode *inode, int mask)
++int dx_permission(const struct inode *inode, int mask)
 +{
 +      int ret = __dx_permission(inode, mask);
 +      if (unlikely(ret)) {
@@ -4912,10 +4897,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
 +      return ret;
 +}
 +
- /**
-  * generic_permission  -  check for access rights on a Posix-like filesystem
-@@ -255,10 +334,14 @@ int inode_permission(struct inode *inode
+ /*
+  * This does basic POSIX ACL permission checking
+  */
+@@ -268,10 +347,14 @@ int inode_permission(struct inode *inode
                /*
                 * Nobody gets write access to an immutable file.
                 */
@@ -4931,16 +4916,17 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        if (inode->i_op->permission)
                retval = inode->i_op->permission(inode, mask);
        else
-@@ -434,6 +517,8 @@ static int exec_permission_lite(struct i
+@@ -447,6 +530,9 @@ static int exec_permission_lite(struct i
  {
-       umode_t mode = inode->i_mode;
+       int ret;
  
 +      if (dx_barrier(inode))
 +              return -EACCES;
-       if (inode->i_op->permission)
-               return -EAGAIN;
-@@ -756,7 +841,8 @@ static __always_inline void follow_dotdo
++
+       if (inode->i_op->permission) {
+               ret = inode->i_op->permission(inode, MAY_EXEC);
+               if (!ret)
+@@ -762,7 +848,8 @@ static __always_inline void follow_dotdo
  
                if (nd->path.dentry == nd->root.dentry &&
                    nd->path.mnt == nd->root.mnt) {
@@ -4950,7 +4936,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
                }
                spin_lock(&dcache_lock);
                if (nd->path.dentry != nd->path.mnt->mnt_root) {
-@@ -792,16 +878,30 @@ static int do_lookup(struct nameidata *n
+@@ -798,16 +885,30 @@ static int do_lookup(struct nameidata *n
  {
        struct vfsmount *mnt = nd->path.mnt;
        struct dentry *dentry = __d_lookup(nd->path.dentry, name);
@@ -4981,7 +4967,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  
  need_lookup:
        dentry = real_lookup(nd->path.dentry, name, nd);
-@@ -1389,7 +1489,7 @@ static int may_delete(struct inode *dir,
+@@ -1389,7 +1490,7 @@ static int may_delete(struct inode *dir,
        if (IS_APPEND(dir))
                return -EPERM;
        if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
@@ -4990,7 +4976,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
                return -EPERM;
        if (isdir) {
                if (!S_ISDIR(victim->d_inode->i_mode))
-@@ -1529,6 +1629,14 @@ int may_open(struct path *path, int acc_
+@@ -1529,6 +1630,14 @@ int may_open(struct path *path, int acc_
                break;
        }
  
@@ -5005,7 +4991,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        error = inode_permission(inode, acc_mode);
        if (error)
                return error;
-@@ -1677,7 +1785,11 @@ struct file *do_filp_open(int dfd, const
+@@ -1677,7 +1786,11 @@ struct file *do_filp_open(int dfd, const
        int count = 0;
        int will_write;
        int flag = open_to_namei_flags(open_flag);
@@ -5018,7 +5004,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        if (!acc_mode)
                acc_mode = MAY_OPEN | ACC_MODE(flag);
  
-@@ -1825,6 +1937,25 @@ ok:
+@@ -1825,6 +1938,25 @@ ok:
                        goto exit;
        }
        error = may_open(&nd.path, acc_mode, flag);
@@ -5044,7 +5030,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        if (error) {
                if (will_write)
                        mnt_drop_write(nd.path.mnt);
-@@ -1987,9 +2118,17 @@ int vfs_mknod(struct inode *dir, struct 
+@@ -1987,9 +2119,17 @@ int vfs_mknod(struct inode *dir, struct 
        if (error)
                return error;
  
@@ -5063,7 +5049,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        if (!dir->i_op->mknod)
                return -EPERM;
  
-@@ -2456,7 +2595,7 @@ int vfs_link(struct dentry *old_dentry, 
+@@ -2456,7 +2596,7 @@ int vfs_link(struct dentry *old_dentry, 
        /*
         * A link to an append-only or immutable file cannot be created.
         */
@@ -5072,7 +5058,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
                return -EPERM;
        if (!dir->i_op->link)
                return -EPERM;
-@@ -2829,6 +2968,219 @@ int vfs_follow_link(struct nameidata *nd
+@@ -2829,6 +2969,219 @@ int vfs_follow_link(struct nameidata *nd
        return __vfs_follow_link(nd, link);
  }
  
@@ -5292,9 +5278,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  /* get the link contents into pagecache */
  static char *page_getlink(struct dentry * dentry, struct page **ppage)
  {
-diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24/fs/namespace.c
---- linux-2.6.31.6/fs/namespace.c      2009-09-10 15:26:22.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/namespace.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/namespace.c linux-2.6.32-vs2.3.0.36.26/fs/namespace.c
+--- linux-2.6.32/fs/namespace.c        2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/namespace.c  2009-12-03 20:04:56.000000000 +0100
 @@ -29,6 +29,11 @@
  #include <linux/log2.h>
  #include <linux/idr.h>
@@ -5514,7 +5500,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
                return -EPERM;
  
        lock_kernel();
-@@ -1891,6 +1952,7 @@ long do_mount(char *dev_name, char *dir_
+@@ -1908,6 +1969,7 @@ long do_mount(char *dev_name, char *dir_
        struct path path;
        int retval = 0;
        int mnt_flags = 0;
@@ -5522,7 +5508,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
  
        /* Discard magic */
        if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
-@@ -1910,6 +1972,12 @@ long do_mount(char *dev_name, char *dir_
+@@ -1925,6 +1987,12 @@ long do_mount(char *dev_name, char *dir_
        if (!(flags & MS_NOATIME))
                mnt_flags |= MNT_RELATIME;
  
@@ -5535,7 +5521,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
        /* Separate the per-mountpoint flags */
        if (flags & MS_NOSUID)
                mnt_flags |= MNT_NOSUID;
-@@ -1926,6 +1994,8 @@ long do_mount(char *dev_name, char *dir_
+@@ -1941,6 +2009,8 @@ long do_mount(char *dev_name, char *dir_
        if (flags & MS_RDONLY)
                mnt_flags |= MNT_READONLY;
  
@@ -5544,7 +5530,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
        flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
                   MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
                   MS_STRICTATIME);
-@@ -1942,9 +2012,9 @@ long do_mount(char *dev_name, char *dir_
+@@ -1957,9 +2027,9 @@ long do_mount(char *dev_name, char *dir_
  
        if (flags & MS_REMOUNT)
                retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
@@ -5556,7 +5542,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
        else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
                retval = do_change_type(&path, flags);
        else if (flags & MS_MOVE)
-@@ -2023,6 +2093,7 @@ static struct mnt_namespace *dup_mnt_ns(
+@@ -2038,6 +2108,7 @@ static struct mnt_namespace *dup_mnt_ns(
                q = next_mnt(q, new_ns->root);
        }
        up_write(&namespace_sem);
@@ -5564,7 +5550,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
  
        if (rootmnt)
                mntput(rootmnt);
-@@ -2165,9 +2236,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
+@@ -2182,9 +2253,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
        down_write(&namespace_sem);
        mutex_lock(&old.dentry->d_inode->i_mutex);
        error = -EINVAL;
@@ -5577,7 +5563,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
                goto out2;
        if (!check_mnt(root.mnt))
                goto out2;
-@@ -2303,6 +2375,7 @@ void put_mnt_ns(struct mnt_namespace *ns
+@@ -2320,6 +2392,7 @@ void put_mnt_ns(struct mnt_namespace *ns
        spin_unlock(&vfsmount_lock);
        up_write(&namespace_sem);
        release_mounts(&umount_list);
@@ -5585,10 +5571,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/namespace.c linux-2.6.31.6-vs2.3.0.36.24
        kfree(ns);
  }
  EXPORT_SYMBOL(put_mnt_ns);
-diff -NurpP --minimal linux-2.6.31.6/fs/nfs/client.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/client.c
---- linux-2.6.31.6/fs/nfs/client.c     2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/client.c       2009-11-12 12:26:38.000000000 +0100
-@@ -732,6 +732,9 @@ static int nfs_init_server_rpcclient(str
+diff -NurpP --minimal linux-2.6.32/fs/nfs/client.c linux-2.6.32-vs2.3.0.36.26/fs/nfs/client.c
+--- linux-2.6.32/fs/nfs/client.c       2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfs/client.c 2009-12-03 20:04:56.000000000 +0100
+@@ -738,6 +738,9 @@ static int nfs_init_server_rpcclient(str
        if (server->flags & NFS_MOUNT_SOFT)
                server->client->cl_softrtry = 1;
  
@@ -5598,7 +5584,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/client.c linux-2.6.31.6-vs2.3.0.36.2
        return 0;
  }
  
-@@ -899,6 +902,10 @@ static void nfs_server_set_fsinfo(struct
+@@ -909,6 +912,10 @@ static void nfs_server_set_fsinfo(struct
                server->acdirmin = server->acdirmax = 0;
        }
  
@@ -5609,9 +5595,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/client.c linux-2.6.31.6-vs2.3.0.36.2
        server->maxfilesize = fsinfo->maxfilesize;
  
        /* We're airborne Set socket buffersize */
-diff -NurpP --minimal linux-2.6.31.6/fs/nfs/dir.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/dir.c
---- linux-2.6.31.6/fs/nfs/dir.c        2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/dir.c  2009-11-12 12:26:38.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/fs/nfs/dir.c linux-2.6.32-vs2.3.0.36.26/fs/nfs/dir.c
+--- linux-2.6.32/fs/nfs/dir.c  2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfs/dir.c    2009-12-03 20:04:56.000000000 +0100
 @@ -33,6 +33,7 @@
  #include <linux/namei.h>
  #include <linux/mount.h>
@@ -5628,9 +5614,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/dir.c linux-2.6.31.6-vs2.3.0.36.24/f
  no_entry:
        res = d_materialise_unique(dentry, inode);
        if (res != NULL) {
-diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/inode.c
---- linux-2.6.31.6/fs/nfs/inode.c      2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/inode.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/nfs/inode.c linux-2.6.32-vs2.3.0.36.26/fs/nfs/inode.c
+--- linux-2.6.32/fs/nfs/inode.c        2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfs/inode.c  2009-12-03 20:04:56.000000000 +0100
 @@ -36,6 +36,7 @@
  #include <linux/vfs.h>
  #include <linux/inet.h>
@@ -5639,7 +5625,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
  
  #include <asm/system.h>
  #include <asm/uaccess.h>
-@@ -278,6 +279,8 @@ nfs_fhget(struct super_block *sb, struct
+@@ -279,6 +280,8 @@ nfs_fhget(struct super_block *sb, struct
        if (inode->i_state & I_NEW) {
                struct nfs_inode *nfsi = NFS_I(inode);
                unsigned long now = jiffies;
@@ -5648,7 +5634,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
  
                /* We set i_ino for the few things that still rely on it,
                 * such as stat(2) */
-@@ -321,8 +324,8 @@ nfs_fhget(struct super_block *sb, struct
+@@ -327,8 +330,8 @@ nfs_fhget(struct super_block *sb, struct
                nfsi->change_attr = 0;
                inode->i_size = 0;
                inode->i_nlink = 0;
@@ -5659,19 +5645,23 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
                inode->i_blocks = 0;
                memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
  
-@@ -341,9 +344,9 @@ nfs_fhget(struct super_block *sb, struct
-               if (fattr->valid & NFS_ATTR_FATTR_NLINK)
-                       inode->i_nlink = fattr->nlink;
+@@ -365,13 +368,13 @@ nfs_fhget(struct super_block *sb, struct
+               else if (nfs_server_capable(inode, NFS_CAP_NLINK))
+                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
                if (fattr->valid & NFS_ATTR_FATTR_OWNER)
 -                      inode->i_uid = fattr->uid;
 +                      uid = fattr->uid;
+               else if (nfs_server_capable(inode, NFS_CAP_OWNER))
+                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR
+                               | NFS_INO_INVALID_ACCESS
+                               | NFS_INO_INVALID_ACL;
                if (fattr->valid & NFS_ATTR_FATTR_GROUP)
 -                      inode->i_gid = fattr->gid;
 +                      gid = fattr->gid;
-               if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
-                       inode->i_blocks = fattr->du.nfs2.blocks;
-               if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
-@@ -352,6 +355,11 @@ nfs_fhget(struct super_block *sb, struct
+               else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
+                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR
+                               | NFS_INO_INVALID_ACCESS
+@@ -384,6 +387,11 @@ nfs_fhget(struct super_block *sb, struct
                         */
                        inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
                }
@@ -5683,7 +5673,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
                nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
                nfsi->attrtimeo_timestamp = now;
                nfsi->access_cache = RB_ROOT;
-@@ -492,6 +500,8 @@ void nfs_setattr_update_inode(struct ino
+@@ -496,6 +504,8 @@ void nfs_setattr_update_inode(struct ino
                        inode->i_uid = attr->ia_uid;
                if ((attr->ia_valid & ATTR_GID) != 0)
                        inode->i_gid = attr->ia_gid;
@@ -5692,7 +5682,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
                NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
                spin_unlock(&inode->i_lock);
        }
-@@ -902,6 +912,9 @@ static int nfs_check_inode_attributes(st
+@@ -906,6 +916,9 @@ static int nfs_check_inode_attributes(st
        struct nfs_inode *nfsi = NFS_I(inode);
        loff_t cur_size, new_isize;
        unsigned long invalid = 0;
@@ -5702,7 +5692,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
  
  
        /* Has the inode gone and changed behind our back? */
-@@ -925,13 +938,18 @@ static int nfs_check_inode_attributes(st
+@@ -929,13 +942,18 @@ static int nfs_check_inode_attributes(st
                        invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
        }
  
@@ -5723,19 +5713,19 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
  
        /* Has the link count changed? */
        if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
-@@ -1145,6 +1163,9 @@ static int nfs_update_inode(struct inode
-       loff_t cur_isize, new_isize;
+@@ -1150,6 +1168,9 @@ static int nfs_update_inode(struct inode
        unsigned long invalid = 0;
        unsigned long now = jiffies;
+       unsigned long save_cache_validity;
 +      uid_t uid;
 +      gid_t gid;
 +      tag_t tag;
  
        dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
                        __func__, inode->i_sb->s_id, inode->i_ino,
-@@ -1233,6 +1254,9 @@ static int nfs_update_inode(struct inode
-               }
-       }
+@@ -1252,6 +1273,9 @@ static int nfs_update_inode(struct inode
+                               | NFS_INO_REVAL_PAGECACHE
+                               | NFS_INO_REVAL_FORCED);
  
 +      uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
 +      gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
@@ -5743,9 +5733,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
  
        if (fattr->valid & NFS_ATTR_FATTR_ATIME)
                memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
-@@ -1244,18 +1268,22 @@ static int nfs_update_inode(struct inode
-               }
-       }
+@@ -1271,9 +1295,9 @@ static int nfs_update_inode(struct inode
+                               | NFS_INO_REVAL_FORCED);
        if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
 -              if (inode->i_uid != fattr->uid) {
 +              if (uid != fattr->uid) {
@@ -5753,7 +5743,11 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
 -                      inode->i_uid = fattr->uid;
 +                      uid = fattr->uid;
                }
-       }
+       } else if (server->caps & NFS_CAP_OWNER)
+               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+@@ -1282,9 +1306,9 @@ static int nfs_update_inode(struct inode
+                               | NFS_INO_REVAL_FORCED);
        if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
 -              if (inode->i_gid != fattr->gid) {
 +              if (gid != fattr->gid) {
@@ -5761,7 +5755,11 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
 -                      inode->i_gid = fattr->gid;
 +                      gid = fattr->gid;
                }
-       }
+       } else if (server->caps & NFS_CAP_OWNER_GROUP)
+               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+@@ -1292,6 +1316,10 @@ static int nfs_update_inode(struct inode
+                               | NFS_INO_INVALID_ACL
+                               | NFS_INO_REVAL_FORCED);
  
 +      inode->i_uid = uid;
 +      inode->i_gid = gid;
@@ -5770,10 +5768,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/inode.c linux-2.6.31.6-vs2.3.0.36.24
        if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
                if (inode->i_nlink != fattr->nlink) {
                        invalid |= NFS_INO_INVALID_ATTR;
-diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/nfs3xdr.c
---- linux-2.6.31.6/fs/nfs/nfs3xdr.c    2009-06-11 17:13:06.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/nfs3xdr.c      2009-09-10 16:11:43.000000000 +0200
-@@ -22,6 +22,7 @@
+diff -NurpP --minimal linux-2.6.32/fs/nfs/nfs3xdr.c linux-2.6.32-vs2.3.0.36.26/fs/nfs/nfs3xdr.c
+--- linux-2.6.32/fs/nfs/nfs3xdr.c      2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfs/nfs3xdr.c        2009-12-03 20:04:56.000000000 +0100
+@@ -21,6 +21,7 @@
  #include <linux/nfs3.h>
  #include <linux/nfs_fs.h>
  #include <linux/nfsacl.h>
@@ -5781,7 +5779,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
  #include "internal.h"
  
  #define NFSDBG_FACILITY               NFSDBG_XDR
-@@ -177,7 +178,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_f
+@@ -176,7 +177,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_f
  }
  
  static inline __be32 *
@@ -5790,7 +5788,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
  {
        if (attr->ia_valid & ATTR_MODE) {
                *p++ = xdr_one;
-@@ -185,15 +186,17 @@ xdr_encode_sattr(__be32 *p, struct iattr
+@@ -184,15 +185,17 @@ xdr_encode_sattr(__be32 *p, struct iattr
        } else {
                *p++ = xdr_zero;
        }
@@ -5812,7 +5810,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
        } else {
                *p++ = xdr_zero;
        }
-@@ -280,7 +283,8 @@ static int
+@@ -279,7 +282,8 @@ static int
  nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
  {
        p = xdr_encode_fhandle(p, args->fh);
@@ -5822,7 +5820,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
        *p++ = htonl(args->guard);
        if (args->guard)
                p = xdr_encode_time3(p, &args->guardtime);
-@@ -385,7 +389,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req
+@@ -384,7 +388,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req
                *p++ = args->verifier[0];
                *p++ = args->verifier[1];
        } else
@@ -5832,7 +5830,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
  
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
        return 0;
-@@ -399,7 +404,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req,
+@@ -398,7 +403,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req,
  {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -5842,7 +5840,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
        return 0;
  }
-@@ -412,7 +418,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re
+@@ -411,7 +417,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re
  {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_array(p, args->fromname, args->fromlen);
@@ -5852,7 +5850,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
        *p++ = htonl(args->pathlen);
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  
-@@ -430,7 +437,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req,
+@@ -429,7 +436,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req,
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
        *p++ = htonl(args->type);
@@ -5862,9 +5860,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.
        if (args->type == NF3CHR || args->type == NF3BLK) {
                *p++ = htonl(MAJOR(args->rdev));
                *p++ = htonl(MINOR(args->rdev));
-diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfsroot.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/nfsroot.c
---- linux-2.6.31.6/fs/nfs/nfsroot.c    2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/nfsroot.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/nfs/nfsroot.c linux-2.6.32-vs2.3.0.36.26/fs/nfs/nfsroot.c
+--- linux-2.6.32/fs/nfs/nfsroot.c      2009-09-10 15:26:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfs/nfsroot.c        2009-12-03 20:04:56.000000000 +0100
 @@ -122,12 +122,12 @@ static int mount_port __initdata = 0;            /
  enum {
        /* Options that take integer arguments */
@@ -5911,9 +5909,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/nfsroot.c linux-2.6.31.6-vs2.3.0.36.
                        default:
                                printk(KERN_WARNING "Root-NFS: unknown "
                                        "option: %s\n", p);
-diff -NurpP --minimal linux-2.6.31.6/fs/nfs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/super.c
---- linux-2.6.31.6/fs/nfs/super.c      2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfs/super.c        2009-11-12 12:26:38.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/fs/nfs/super.c linux-2.6.32-vs2.3.0.36.26/fs/nfs/super.c
+--- linux-2.6.32/fs/nfs/super.c        2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfs/super.c  2009-12-03 20:04:56.000000000 +0100
 @@ -53,6 +53,7 @@
  #include <linux/nfs_xdr.h>
  #include <linux/magic.h>
@@ -5922,7 +5920,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/super.c linux-2.6.31.6-vs2.3.0.36.24
  
  #include <asm/system.h>
  #include <asm/uaccess.h>
-@@ -546,6 +547,7 @@ static void nfs_show_mount_options(struc
+@@ -551,6 +552,7 @@ static void nfs_show_mount_options(struc
                { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
                { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
                { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
@@ -5930,9 +5928,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfs/super.c linux-2.6.31.6-vs2.3.0.36.24
                { 0, NULL, NULL }
        };
        const struct proc_nfs_info *nfs_infop;
-diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/auth.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/auth.c
---- linux-2.6.31.6/fs/nfsd/auth.c      2009-03-24 14:22:26.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/auth.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/nfsd/auth.c linux-2.6.32-vs2.3.0.36.26/fs/nfsd/auth.c
+--- linux-2.6.32/fs/nfsd/auth.c        2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfsd/auth.c  2009-12-03 20:04:56.000000000 +0100
 @@ -10,6 +10,7 @@
  #include <linux/sunrpc/svcauth.h>
  #include <linux/nfsd/nfsd.h>
@@ -5941,7 +5939,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/auth.c linux-2.6.31.6-vs2.3.0.36.24
  #include "auth.h"
  
  int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
-@@ -42,6 +43,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
+@@ -44,6 +45,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
  
        new->fsuid = rqstp->rq_cred.cr_uid;
        new->fsgid = rqstp->rq_cred.cr_gid;
@@ -5951,9 +5949,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/auth.c linux-2.6.31.6-vs2.3.0.36.24
  
        rqgi = rqstp->rq_cred.cr_group_info;
  
-diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/nfs3xdr.c
---- linux-2.6.31.6/fs/nfsd/nfs3xdr.c   2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/nfs3xdr.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/nfsd/nfs3xdr.c linux-2.6.32-vs2.3.0.36.26/fs/nfsd/nfs3xdr.c
+--- linux-2.6.32/fs/nfsd/nfs3xdr.c     2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfsd/nfs3xdr.c       2009-12-03 20:04:56.000000000 +0100
 @@ -21,6 +21,7 @@
  #include <linux/sunrpc/svc.h>
  #include <linux/nfsd/nfsd.h>
@@ -6004,9 +6002,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/nfs3xdr.c linux-2.6.31.6-vs2.3.0.36
        if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
                p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
        } else {
-diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/nfs4xdr.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/nfs4xdr.c
---- linux-2.6.31.6/fs/nfsd/nfs4xdr.c   2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/nfs4xdr.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/nfsd/nfs4xdr.c linux-2.6.32-vs2.3.0.36.26/fs/nfsd/nfs4xdr.c
+--- linux-2.6.32/fs/nfsd/nfs4xdr.c     2009-12-03 20:02:52.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfsd/nfs4xdr.c       2009-12-03 20:04:56.000000000 +0100
 @@ -57,6 +57,7 @@
  #include <linux/nfs4_acl.h>
  #include <linux/sunrpc/gss_api.h>
@@ -6015,7 +6013,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/nfs4xdr.c linux-2.6.31.6-vs2.3.0.36
  
  #define NFSDDBG_FACILITY              NFSDDBG_XDR
  
-@@ -2052,14 +2053,18 @@ out_acl:
+@@ -2050,14 +2051,18 @@ out_acl:
                WRITE32(stat.nlink);
        }
        if (bmval1 & FATTR4_WORD1_OWNER) {
@@ -6036,9 +6034,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/nfs4xdr.c linux-2.6.31.6-vs2.3.0.36
                if (status == nfserr_resource)
                        goto out_resource;
                if (status)
-diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/nfsxdr.c linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/nfsxdr.c
---- linux-2.6.31.6/fs/nfsd/nfsxdr.c    2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/nfsd/nfsxdr.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/nfsd/nfsxdr.c linux-2.6.32-vs2.3.0.36.26/fs/nfsd/nfsxdr.c
+--- linux-2.6.32/fs/nfsd/nfsxdr.c      2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/nfsd/nfsxdr.c        2009-12-03 20:04:56.000000000 +0100
 @@ -15,6 +15,7 @@
  #include <linux/nfsd/nfsd.h>
  #include <linux/nfsd/xdr.h>
@@ -6087,9 +6085,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/nfsd/nfsxdr.c linux-2.6.31.6-vs2.3.0.36.
  
        if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
                *p++ = htonl(NFS_MAXPATHLEN);
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlm/dlmfs.c linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/dlm/dlmfs.c
---- linux-2.6.31.6/fs/ocfs2/dlm/dlmfs.c        2009-03-24 14:22:27.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/dlm/dlmfs.c  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/dlm/dlmfs.c linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/dlm/dlmfs.c
+--- linux-2.6.32/fs/ocfs2/dlm/dlmfs.c  2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/dlm/dlmfs.c    2009-12-03 20:04:56.000000000 +0100
 @@ -43,6 +43,7 @@
  #include <linux/init.h>
  #include <linux/string.h>
@@ -6098,7 +6096,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlm/dlmfs.c linux-2.6.31.6-vs2.3.0
  
  #include <asm/uaccess.h>
  
-@@ -341,6 +342,7 @@ static struct inode *dlmfs_get_root_inod
+@@ -342,6 +343,7 @@ static struct inode *dlmfs_get_root_inod
                inode->i_mode = mode;
                inode->i_uid = current_fsuid();
                inode->i_gid = current_fsgid();
@@ -6106,7 +6104,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlm/dlmfs.c linux-2.6.31.6-vs2.3.0
                inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                inc_nlink(inode);
-@@ -366,6 +368,7 @@ static struct inode *dlmfs_get_inode(str
+@@ -367,6 +369,7 @@ static struct inode *dlmfs_get_inode(str
        inode->i_mode = mode;
        inode->i_uid = current_fsuid();
        inode->i_gid = current_fsgid();
@@ -6114,10 +6112,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlm/dlmfs.c linux-2.6.31.6-vs2.3.0
        inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlmglue.c linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/dlmglue.c
---- linux-2.6.31.6/fs/ocfs2/dlmglue.c  2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/dlmglue.c    2009-09-10 16:11:43.000000000 +0200
-@@ -1960,6 +1960,7 @@ static void __ocfs2_stuff_meta_lvb(struc
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/dlmglue.c linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/dlmglue.c
+--- linux-2.6.32/fs/ocfs2/dlmglue.c    2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/dlmglue.c      2009-12-03 20:04:56.000000000 +0100
+@@ -1991,6 +1991,7 @@ static void __ocfs2_stuff_meta_lvb(struc
        lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
        lvb->lvb_iuid      = cpu_to_be32(inode->i_uid);
        lvb->lvb_igid      = cpu_to_be32(inode->i_gid);
@@ -6125,7 +6123,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlmglue.c linux-2.6.31.6-vs2.3.0.3
        lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
        lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
        lvb->lvb_iatime_packed  =
-@@ -2014,6 +2015,7 @@ static void ocfs2_refresh_inode_from_lvb
+@@ -2045,6 +2046,7 @@ static void ocfs2_refresh_inode_from_lvb
  
        inode->i_uid     = be32_to_cpu(lvb->lvb_iuid);
        inode->i_gid     = be32_to_cpu(lvb->lvb_igid);
@@ -6133,9 +6131,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlmglue.c linux-2.6.31.6-vs2.3.0.3
        inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
        inode->i_nlink   = be16_to_cpu(lvb->lvb_inlink);
        ocfs2_unpack_timespec(&inode->i_atime,
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlmglue.h linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/dlmglue.h
---- linux-2.6.31.6/fs/ocfs2/dlmglue.h  2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/dlmglue.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/dlmglue.h linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/dlmglue.h
+--- linux-2.6.32/fs/ocfs2/dlmglue.h    2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/dlmglue.h      2009-12-03 20:04:56.000000000 +0100
 @@ -46,7 +46,8 @@ struct ocfs2_meta_lvb {
        __be16       lvb_inlink;
        __be32       lvb_iattr;
@@ -6146,10 +6144,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/dlmglue.h linux-2.6.31.6-vs2.3.0.3
  };
  
  #define OCFS2_QINFO_LVB_VERSION 1
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/file.c
---- linux-2.6.31.6/fs/ocfs2/file.c     2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/file.c       2009-10-06 19:45:13.000000000 +0200
-@@ -914,13 +914,15 @@ int ocfs2_setattr(struct dentry *dentry,
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/file.c linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/file.c
+--- linux-2.6.32/fs/ocfs2/file.c       2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/file.c 2009-12-03 20:04:56.000000000 +0100
+@@ -960,13 +960,15 @@ int ocfs2_setattr(struct dentry *dentry,
                mlog(0, "uid change: %d\n", attr->ia_uid);
        if (attr->ia_valid & ATTR_GID)
                mlog(0, "gid change: %d\n", attr->ia_gid);
@@ -6166,9 +6164,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/file.c linux-2.6.31.6-vs2.3.0.36.2
        if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
                mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
                return 0;
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/inode.c
---- linux-2.6.31.6/fs/ocfs2/inode.c    2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/inode.c      2009-10-06 19:45:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/inode.c linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/inode.c
+--- linux-2.6.32/fs/ocfs2/inode.c      2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/inode.c        2009-12-03 20:04:56.000000000 +0100
 @@ -29,6 +29,7 @@
  #include <linux/highmem.h>
  #include <linux/pagemap.h>
@@ -6177,7 +6175,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.c linux-2.6.31.6-vs2.3.0.36.
  
  #include <asm/byteorder.h>
  
-@@ -78,11 +79,13 @@ void ocfs2_set_inode_flags(struct inode 
+@@ -79,11 +80,13 @@ void ocfs2_set_inode_flags(struct inode 
  {
        unsigned int flags = OCFS2_I(inode)->ip_attr;
  
@@ -6192,7 +6190,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.c linux-2.6.31.6-vs2.3.0.36.
  
        if (flags & OCFS2_SYNC_FL)
                inode->i_flags |= S_SYNC;
-@@ -92,25 +95,44 @@ void ocfs2_set_inode_flags(struct inode 
+@@ -93,25 +96,44 @@ void ocfs2_set_inode_flags(struct inode 
                inode->i_flags |= S_NOATIME;
        if (flags & OCFS2_DIRSYNC_FL)
                inode->i_flags |= S_DIRSYNC;
@@ -6241,7 +6239,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.c linux-2.6.31.6-vs2.3.0.36.
  }
  
  struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
-@@ -245,6 +267,8 @@ void ocfs2_populate_inode(struct inode *
+@@ -246,6 +268,8 @@ void ocfs2_populate_inode(struct inode *
        struct super_block *sb;
        struct ocfs2_super *osb;
        int use_plocks = 1;
@@ -6250,7 +6248,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.c linux-2.6.31.6-vs2.3.0.36.
  
        mlog_entry("(0x%p, size:%llu)\n", inode,
                   (unsigned long long)le64_to_cpu(fe->i_size));
-@@ -276,8 +300,12 @@ void ocfs2_populate_inode(struct inode *
+@@ -277,8 +301,12 @@ void ocfs2_populate_inode(struct inode *
        inode->i_generation = le32_to_cpu(fe->i_generation);
        inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
        inode->i_mode = le16_to_cpu(fe->i_mode);
@@ -6265,10 +6263,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.c linux-2.6.31.6-vs2.3.0.36.
  
        /* Fast symlinks will have i_size but no allocated clusters. */
        if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.h linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/inode.h
---- linux-2.6.31.6/fs/ocfs2/inode.h    2009-06-11 17:13:07.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/inode.h      2009-10-07 01:26:15.000000000 +0200
-@@ -152,6 +152,7 @@ struct buffer_head *ocfs2_bread(struct i
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/inode.h linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/inode.h
+--- linux-2.6.32/fs/ocfs2/inode.h      2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/inode.h        2009-12-03 20:04:56.000000000 +0100
+@@ -150,6 +150,7 @@ struct buffer_head *ocfs2_bread(struct i
  
  void ocfs2_set_inode_flags(struct inode *inode);
  void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
@@ -6276,10 +6274,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/inode.h linux-2.6.31.6-vs2.3.0.36.
  
  static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
  {
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/ioctl.c
---- linux-2.6.31.6/fs/ocfs2/ioctl.c    2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/ioctl.c      2009-10-07 04:20:18.000000000 +0200
-@@ -41,7 +41,41 @@ static int ocfs2_get_inode_attr(struct i
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/ioctl.c
+--- linux-2.6.32/fs/ocfs2/ioctl.c      2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/ioctl.c        2009-12-03 20:04:56.000000000 +0100
+@@ -42,7 +42,41 @@ static int ocfs2_get_inode_attr(struct i
        return status;
  }
  
@@ -6322,7 +6320,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ioctl.c linux-2.6.31.6-vs2.3.0.36.
                                unsigned mask)
  {
        struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
-@@ -66,6 +100,11 @@ static int ocfs2_set_inode_attr(struct i
+@@ -67,6 +101,11 @@ static int ocfs2_set_inode_attr(struct i
        if (!S_ISDIR(inode->i_mode))
                flags &= ~OCFS2_DIRSYNC_FL;
  
@@ -6334,7 +6332,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ioctl.c linux-2.6.31.6-vs2.3.0.36.
        handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
        if (IS_ERR(handle)) {
                status = PTR_ERR(handle);
-@@ -107,6 +146,7 @@ bail:
+@@ -108,6 +147,7 @@ bail:
        return status;
  }
  
@@ -6342,9 +6340,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ioctl.c linux-2.6.31.6-vs2.3.0.36.
  long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  {
        struct inode *inode = filp->f_path.dentry->d_inode;
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/namei.c
---- linux-2.6.31.6/fs/ocfs2/namei.c    2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/namei.c      2009-10-06 19:45:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/namei.c linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/namei.c
+--- linux-2.6.32/fs/ocfs2/namei.c      2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/namei.c        2009-12-03 20:04:56.000000000 +0100
 @@ -41,6 +41,7 @@
  #include <linux/slab.h>
  #include <linux/highmem.h>
@@ -6353,14 +6351,14 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/namei.c linux-2.6.31.6-vs2.3.0.36.
  
  #define MLOG_MASK_PREFIX ML_NAMEI
  #include <cluster/masklog.h>
-@@ -478,6 +479,7 @@ static int ocfs2_mknod_locked(struct ocf
+@@ -481,6 +482,7 @@ static int ocfs2_mknod_locked(struct ocf
        u64 fe_blkno = 0;
        u16 suballoc_bit;
        u16 feat;
 +      tag_t tag;
  
-       mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
-                  inode->i_mode, (unsigned long)dev, dentry->d_name.len,
+       *new_fe_bh = NULL;
 @@ -524,8 +526,11 @@ static int ocfs2_mknod_locked(struct ocf
        fe->i_blkno = cpu_to_le64(fe_blkno);
        fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
@@ -6375,11 +6373,11 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/namei.c linux-2.6.31.6-vs2.3.0.36.
        fe->i_mode = cpu_to_le16(inode->i_mode);
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ocfs2_fs.h linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/ocfs2_fs.h
---- linux-2.6.31.6/fs/ocfs2/ocfs2_fs.h 2009-06-11 17:13:07.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/ocfs2_fs.h   2009-09-10 16:11:43.000000000 +0200
-@@ -225,18 +225,23 @@
- #define OCFS2_INDEXED_DIR_FL  (0x0008)
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/ocfs2_fs.h linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/ocfs2_fs.h
+--- linux-2.6.32/fs/ocfs2/ocfs2_fs.h   2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/ocfs2_fs.h     2009-12-03 20:04:56.000000000 +0100
+@@ -231,18 +231,23 @@
+ #define OCFS2_HAS_REFCOUNT_FL   (0x0010)
  
  /* Inode attributes, keep in sync with EXT2 */
 -#define OCFS2_SECRM_FL                (0x00000001)    /* Secure deletion */
@@ -6413,10 +6411,10 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ocfs2_fs.h linux-2.6.31.6-vs2.3.0.
  
  /*
   * Extent record flags (e_node.leaf.flags)
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ocfs2.h linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/ocfs2.h
---- linux-2.6.31.6/fs/ocfs2/ocfs2.h    2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/ocfs2.h      2009-09-10 16:11:43.000000000 +0200
-@@ -222,6 +222,7 @@ enum ocfs2_mount_options
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/ocfs2.h linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/ocfs2.h
+--- linux-2.6.32/fs/ocfs2/ocfs2.h      2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/ocfs2.h        2009-12-03 20:04:56.000000000 +0100
+@@ -248,6 +248,7 @@ enum ocfs2_mount_options
        OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* POSIX access control lists */
        OCFS2_MOUNT_USRQUOTA = 1 << 9, /* We support user quotas */
        OCFS2_MOUNT_GRPQUOTA = 1 << 10, /* We support group quotas */
@@ -6424,9 +6422,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/ocfs2.h linux-2.6.31.6-vs2.3.0.36.
  };
  
  #define OCFS2_OSB_SOFT_RO                     0x0001
-diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/super.c
---- linux-2.6.31.6/fs/ocfs2/super.c    2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/ocfs2/super.c      2009-10-06 22:50:39.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/ocfs2/super.c linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/super.c
+--- linux-2.6.32/fs/ocfs2/super.c      2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/ocfs2/super.c        2009-12-03 20:04:56.000000000 +0100
 @@ -173,6 +173,7 @@ enum {
        Opt_noacl,
        Opt_usrquota,
@@ -6459,7 +6457,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/super.c linux-2.6.31.6-vs2.3.0.36.
        if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
            (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
                ret = -EINVAL;
-@@ -1146,6 +1157,9 @@ static int ocfs2_fill_super(struct super
+@@ -1148,6 +1159,9 @@ static int ocfs2_fill_super(struct super
  
        ocfs2_complete_mount_recovery(osb);
  
@@ -6469,7 +6467,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/super.c linux-2.6.31.6-vs2.3.0.36.
        if (ocfs2_mount_local(osb))
                snprintf(nodestr, sizeof(nodestr), "local");
        else
-@@ -1424,6 +1438,20 @@ static int ocfs2_parse_options(struct su
+@@ -1426,6 +1440,20 @@ static int ocfs2_parse_options(struct su
                        printk(KERN_INFO "ocfs2 (no)acl options not supported\n");
                        break;
  #endif
@@ -6490,9 +6488,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/ocfs2/super.c linux-2.6.31.6-vs2.3.0.36.
                default:
                        mlog(ML_ERROR,
                             "Unrecognized mount option \"%s\" "
-diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/open.c
---- linux-2.6.31.6/fs/open.c   2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/open.c     2009-10-15 03:54:42.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/open.c linux-2.6.32-vs2.3.0.36.26/fs/open.c
+--- linux-2.6.32/fs/open.c     2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/open.c       2009-12-03 20:04:56.000000000 +0100
 @@ -30,22 +30,30 @@
  #include <linux/audit.h>
  #include <linux/falloc.h>
@@ -6526,7 +6524,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/o
        }
        return retval;
  }
-@@ -639,6 +647,10 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
+@@ -640,6 +648,10 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
        error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
        if (error)
                goto out;
@@ -6537,7 +6535,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/o
        inode = path.dentry->d_inode;
  
        error = mnt_want_write(path.mnt);
-@@ -672,11 +684,11 @@ static int chown_common(struct dentry * 
+@@ -673,11 +685,11 @@ static int chown_common(struct dentry * 
        newattrs.ia_valid =  ATTR_CTIME;
        if (user != (uid_t) -1) {
                newattrs.ia_valid |= ATTR_UID;
@@ -6551,7 +6549,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/o
        }
        if (!S_ISDIR(inode->i_mode))
                newattrs.ia_valid |=
-@@ -699,7 +711,11 @@ SYSCALL_DEFINE3(chown, const char __user
+@@ -700,7 +712,11 @@ SYSCALL_DEFINE3(chown, const char __user
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_release;
@@ -6564,7 +6562,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/o
        mnt_drop_write(path.mnt);
  out_release:
        path_put(&path);
-@@ -724,7 +740,11 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons
+@@ -725,7 +741,11 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_release;
@@ -6577,7 +6575,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/o
        mnt_drop_write(path.mnt);
  out_release:
        path_put(&path);
-@@ -743,7 +763,11 @@ SYSCALL_DEFINE3(lchown, const char __use
+@@ -744,7 +764,11 @@ SYSCALL_DEFINE3(lchown, const char __use
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_release;
@@ -6590,7 +6588,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/o
        mnt_drop_write(path.mnt);
  out_release:
        path_put(&path);
-@@ -987,6 +1011,7 @@ static void __put_unused_fd(struct files
+@@ -990,6 +1014,7 @@ static void __put_unused_fd(struct files
        __FD_CLR(fd, fdt->open_fds);
        if (fd < files->next_fd)
                files->next_fd = fd;
@@ -6598,19 +6596,19 @@ diff -NurpP --minimal linux-2.6.31.6/fs/open.c linux-2.6.31.6-vs2.3.0.36.24/fs/o
  }
  
  void put_unused_fd(unsigned int fd)
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/array.c
---- linux-2.6.31.6/fs/proc/array.c     2009-06-11 17:13:07.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/array.c       2009-09-10 16:11:43.000000000 +0200
-@@ -82,6 +82,8 @@
- #include <linux/pid_namespace.h>
+diff -NurpP --minimal linux-2.6.32/fs/proc/array.c linux-2.6.32-vs2.3.0.36.26/fs/proc/array.c
+--- linux-2.6.32/fs/proc/array.c       2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/array.c 2009-12-03 20:04:56.000000000 +0100
+@@ -83,6 +83,8 @@
  #include <linux/ptrace.h>
  #include <linux/tracehook.h>
+ #include <linux/swapops.h>
 +#include <linux/vs_context.h>
 +#include <linux/vs_network.h>
  
  #include <asm/pgtable.h>
  #include <asm/processor.h>
-@@ -138,8 +140,9 @@ static const char *task_state_array[] = 
+@@ -139,8 +141,9 @@ static const char *task_state_array[] = 
        "D (disk sleep)",       /*  2 */
        "T (stopped)",          /*  4 */
        "T (tracing stop)",     /*  8 */
@@ -6622,7 +6620,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.2
  };
  
  static inline const char *get_task_state(struct task_struct *tsk)
-@@ -166,6 +169,9 @@ static inline void task_state(struct seq
+@@ -167,6 +170,9 @@ static inline void task_state(struct seq
        rcu_read_lock();
        ppid = pid_alive(p) ?
                task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
@@ -6632,7 +6630,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.2
        tpid = 0;
        if (pid_alive(p)) {
                struct task_struct *tracer = tracehook_tracer_task(p);
-@@ -281,7 +287,7 @@ static inline void task_sig(struct seq_f
+@@ -282,7 +288,7 @@ static inline void task_sig(struct seq_f
  }
  
  static void render_cap_t(struct seq_file *m, const char *header,
@@ -6641,7 +6639,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.2
  {
        unsigned __capi;
  
-@@ -306,10 +312,11 @@ static inline void task_cap(struct seq_f
+@@ -307,10 +313,11 @@ static inline void task_cap(struct seq_f
        cap_bset        = cred->cap_bset;
        rcu_read_unlock();
  
@@ -6657,9 +6655,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.2
  }
  
  static inline void task_context_switch_counts(struct seq_file *m,
-@@ -321,6 +328,42 @@ static inline void task_context_switch_c
-                       p->nivcsw);
+@@ -410,6 +417,42 @@ static void task_show_stack_usage(struct
  }
+ #endif                /* CONFIG_MMU */
  
 +int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
 +                      struct pid *pid, struct task_struct *task)
@@ -6700,7 +6698,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.2
  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
                        struct pid *pid, struct task_struct *task)
  {
-@@ -336,6 +379,7 @@ int proc_pid_status(struct seq_file *m, 
+@@ -425,6 +468,7 @@ int proc_pid_status(struct seq_file *m, 
        task_sig(m, task);
        task_cap(m, task);
        cpuset_task_status_allowed(m, task);
@@ -6708,7 +6706,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.2
  #if defined(CONFIG_S390)
        task_show_regs(m, task);
  #endif
-@@ -452,6 +496,17 @@ static int do_task_stat(struct seq_file 
+@@ -542,6 +586,17 @@ static int do_task_stat(struct seq_file 
        /* convert nsec -> ticks */
        start_time = nsec_to_clock_t(start_time);
  
@@ -6726,9 +6724,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/array.c linux-2.6.31.6-vs2.3.0.36.2
        seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
  %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
  %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/base.c
---- linux-2.6.31.6/fs/proc/base.c      2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/base.c        2009-10-03 01:56:26.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/proc/base.c linux-2.6.32-vs2.3.0.36.26/fs/proc/base.c
+--- linux-2.6.32/fs/proc/base.c        2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/base.c  2009-12-03 20:04:56.000000000 +0100
 @@ -81,6 +81,8 @@
  #include <linux/elf.h>
  #include <linux/pid_namespace.h>
@@ -6738,23 +6736,26 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
  #include "internal.h"
  
  /* NOTE:
-@@ -1032,10 +1034,14 @@ static ssize_t oom_adjust_write(struct f
-       task = get_proc_task(file->f_path.dentry->d_inode);
-       if (!task)
+@@ -1047,12 +1049,17 @@ static ssize_t oom_adjust_write(struct f
                return -ESRCH;
--      if (oom_adjust < task->oomkilladj && !capable(CAP_SYS_RESOURCE)) {
-+      if (oom_adjust < task->oomkilladj &&
+       }
+-      if (oom_adjust < task->signal->oom_adj && !capable(CAP_SYS_RESOURCE)) {
++      if (oom_adjust < task->signal->oom_adj &&
 +              !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
+               unlock_task_sighand(task, &flags);
                put_task_struct(task);
                return -EACCES;
        }
 +      /* prevent guest processes from circumventing the oom killer */
 +      if (vx_current_xid() && (oom_adjust == OOM_DISABLE))
 +              oom_adjust = OOM_ADJUST_MIN;
-       task->oomkilladj = oom_adjust;
-       put_task_struct(task);
-       if (end - buffer == 0)
-@@ -1074,7 +1080,7 @@ static ssize_t proc_loginuid_write(struc
++
+       task->signal->oom_adj = oom_adjust;
+       unlock_task_sighand(task, &flags);
+@@ -1092,7 +1099,7 @@ static ssize_t proc_loginuid_write(struc
        ssize_t length;
        uid_t loginuid;
  
@@ -6763,7 +6764,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
                return -EPERM;
  
        if (current != pid_task(proc_pid(inode), PIDTYPE_PID))
-@@ -1441,6 +1447,8 @@ static struct inode *proc_pid_make_inode
+@@ -1458,6 +1465,8 @@ static struct inode *proc_pid_make_inode
                inode->i_gid = cred->egid;
                rcu_read_unlock();
        }
@@ -6772,7 +6773,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
        security_task_to_inode(task, inode);
  
  out:
-@@ -1991,6 +1999,13 @@ static struct dentry *proc_pident_lookup
+@@ -2008,6 +2017,13 @@ static struct dentry *proc_pident_lookup
        if (!task)
                goto out_no_task;
  
@@ -6786,7 +6787,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
        /*
         * Yes, it does not scale. And it should not. Don't add
         * new entries into /proc/<tgid>/ without very good reasons.
-@@ -2382,7 +2397,7 @@ out_iput:
+@@ -2399,7 +2415,7 @@ out_iput:
  static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
  {
        struct dentry *error;
@@ -6795,7 +6796,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
        const struct pid_entry *p, *last;
  
        error = ERR_PTR(-ENOENT);
-@@ -2472,6 +2487,9 @@ static int proc_pid_personality(struct s
+@@ -2489,6 +2505,9 @@ static int proc_pid_personality(struct s
  static const struct file_operations proc_task_operations;
  static const struct inode_operations proc_task_inode_operations;
  
@@ -6805,7 +6806,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
  static const struct pid_entry tgid_base_stuff[] = {
        DIR("task",       S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
        DIR("fd",         S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
-@@ -2530,6 +2548,8 @@ static const struct pid_entry tgid_base_
+@@ -2547,6 +2566,8 @@ static const struct pid_entry tgid_base_
  #ifdef CONFIG_CGROUPS
        REG("cgroup",  S_IRUGO, proc_cgroup_operations),
  #endif
@@ -6814,7 +6815,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
        INF("oom_score",  S_IRUGO, proc_oom_score),
        REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
  #ifdef CONFIG_AUDITSYSCALL
-@@ -2545,6 +2565,7 @@ static const struct pid_entry tgid_base_
+@@ -2562,6 +2583,7 @@ static const struct pid_entry tgid_base_
  #ifdef CONFIG_TASK_IO_ACCOUNTING
        INF("io",       S_IRUGO, proc_tgid_io_accounting),
  #endif
@@ -6822,7 +6823,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
  };
  
  static int proc_tgid_base_readdir(struct file * filp,
-@@ -2741,7 +2762,7 @@ retry:
+@@ -2753,7 +2775,7 @@ retry:
        iter.task = NULL;
        pid = find_ge_pid(iter.tgid, ns);
        if (pid) {
@@ -6831,7 +6832,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
                iter.task = pid_task(pid, PIDTYPE_PID);
                /* What we to know is if the pid we have find is the
                 * pid of a thread_group_leader.  Testing for task
-@@ -2771,7 +2792,7 @@ static int proc_pid_fill_cache(struct fi
+@@ -2783,7 +2805,7 @@ static int proc_pid_fill_cache(struct fi
        struct tgid_iter iter)
  {
        char name[PROC_NUMBUF];
@@ -6840,7 +6841,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
        return proc_fill_cache(filp, dirent, filldir, name, len,
                                proc_pid_instantiate, iter.task, NULL);
  }
-@@ -2780,7 +2801,7 @@ static int proc_pid_fill_cache(struct fi
+@@ -2792,7 +2814,7 @@ static int proc_pid_fill_cache(struct fi
  int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
  {
        unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
@@ -6849,7 +6850,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
        struct tgid_iter iter;
        struct pid_namespace *ns;
  
-@@ -2800,6 +2821,8 @@ int proc_pid_readdir(struct file * filp,
+@@ -2812,6 +2834,8 @@ int proc_pid_readdir(struct file * filp,
             iter.task;
             iter.tgid += 1, iter = next_tgid(ns, iter)) {
                filp->f_pos = iter.tgid + TGID_OFFSET;
@@ -6858,7 +6859,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
                if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
                        put_task_struct(iter.task);
                        goto out;
-@@ -2946,6 +2969,8 @@ static struct dentry *proc_task_lookup(s
+@@ -2958,6 +2982,8 @@ static struct dentry *proc_task_lookup(s
        tid = name_to_int(dentry);
        if (tid == ~0U)
                goto out;
@@ -6867,9 +6868,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/base.c linux-2.6.31.6-vs2.3.0.36.24
  
        ns = dentry->d_sb->s_fs_info;
        rcu_read_lock();
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/generic.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/generic.c
---- linux-2.6.31.6/fs/proc/generic.c   2009-06-11 17:13:07.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/generic.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/proc/generic.c linux-2.6.32-vs2.3.0.36.26/fs/proc/generic.c
+--- linux-2.6.32/fs/proc/generic.c     2009-06-11 17:13:07.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/generic.c       2009-12-03 20:04:56.000000000 +0100
 @@ -20,6 +20,7 @@
  #include <linux/bitops.h>
  #include <linux/spinlock.h>
@@ -6931,9 +6932,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/generic.c linux-2.6.31.6-vs2.3.0.36
                } else {
                        kfree(ent);
                        ent = NULL;
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/inode.c
---- linux-2.6.31.6/fs/proc/inode.c     2009-06-11 17:13:07.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/inode.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/proc/inode.c linux-2.6.32-vs2.3.0.36.26/fs/proc/inode.c
+--- linux-2.6.32/fs/proc/inode.c       2009-06-11 17:13:07.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/inode.c 2009-12-03 20:04:56.000000000 +0100
 @@ -459,6 +459,8 @@ struct inode *proc_get_inode(struct supe
                        inode->i_uid = de->uid;
                        inode->i_gid = de->gid;
@@ -6943,9 +6944,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/inode.c linux-2.6.31.6-vs2.3.0.36.2
                if (de->size)
                        inode->i_size = de->size;
                if (de->nlink)
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/internal.h linux-2.6.31.6-vs2.3.0.36.24/fs/proc/internal.h
---- linux-2.6.31.6/fs/proc/internal.h  2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/internal.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/proc/internal.h linux-2.6.32-vs2.3.0.36.26/fs/proc/internal.h
+--- linux-2.6.32/fs/proc/internal.h    2009-09-10 15:26:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/internal.h      2009-12-03 20:04:56.000000000 +0100
 @@ -10,6 +10,7 @@
   */
  
@@ -6982,9 +6983,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/internal.h linux-2.6.31.6-vs2.3.0.3
  static inline int proc_fd(struct inode *inode)
  {
        return PROC_I(inode)->fd;
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/loadavg.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/loadavg.c
---- linux-2.6.31.6/fs/proc/loadavg.c   2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/loadavg.c     2009-11-05 04:12:09.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/fs/proc/loadavg.c linux-2.6.32-vs2.3.0.36.26/fs/proc/loadavg.c
+--- linux-2.6.32/fs/proc/loadavg.c     2009-09-10 15:26:23.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/loadavg.c       2009-12-03 20:04:56.000000000 +0100
 @@ -12,15 +12,27 @@
  
  static int loadavg_proc_show(struct seq_file *m, void *v)
@@ -7014,9 +7015,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/loadavg.c linux-2.6.31.6-vs2.3.0.36
                task_active_pid_ns(current)->last_pid);
        return 0;
  }
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/meminfo.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/meminfo.c
---- linux-2.6.31.6/fs/proc/meminfo.c   2009-09-10 15:26:23.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/meminfo.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/proc/meminfo.c linux-2.6.32-vs2.3.0.36.26/fs/proc/meminfo.c
+--- linux-2.6.32/fs/proc/meminfo.c     2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/meminfo.c       2009-12-03 20:04:56.000000000 +0100
 @@ -41,7 +41,7 @@ static int meminfo_proc_show(struct seq_
  
        cached = global_page_state(NR_FILE_PAGES) -
@@ -7026,9 +7027,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/meminfo.c linux-2.6.31.6-vs2.3.0.36
                cached = 0;
  
        get_vmalloc_info(&vmi);
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/root.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/root.c
---- linux-2.6.31.6/fs/proc/root.c      2009-06-11 17:13:07.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/root.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/proc/root.c linux-2.6.32-vs2.3.0.36.26/fs/proc/root.c
+--- linux-2.6.32/fs/proc/root.c        2009-06-11 17:13:07.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/root.c  2009-12-03 20:04:56.000000000 +0100
 @@ -18,9 +18,14 @@
  #include <linux/bitops.h>
  #include <linux/mount.h>
@@ -7060,9 +7061,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/root.c linux-2.6.31.6-vs2.3.0.36.24
  };
  
  int pid_ns_prepare_proc(struct pid_namespace *ns)
-diff -NurpP --minimal linux-2.6.31.6/fs/proc/uptime.c linux-2.6.31.6-vs2.3.0.36.24/fs/proc/uptime.c
---- linux-2.6.31.6/fs/proc/uptime.c    2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/proc/uptime.c      2009-10-05 23:35:52.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/proc/uptime.c linux-2.6.32-vs2.3.0.36.26/fs/proc/uptime.c
+--- linux-2.6.32/fs/proc/uptime.c      2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/proc/uptime.c        2009-12-03 20:04:56.000000000 +0100
 @@ -4,22 +4,22 @@
  #include <linux/sched.h>
  #include <linux/seq_file.h>
@@ -7092,9 +7093,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/proc/uptime.c linux-2.6.31.6-vs2.3.0.36.
        seq_printf(m, "%lu.%02lu %lu.%02lu\n",
                        (unsigned long) uptime.tv_sec,
                        (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
-diff -NurpP --minimal linux-2.6.31.6/fs/quota/quota.c linux-2.6.31.6-vs2.3.0.36.24/fs/quota/quota.c
---- linux-2.6.31.6/fs/quota/quota.c    2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/quota/quota.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/quota/quota.c linux-2.6.32-vs2.3.0.36.26/fs/quota/quota.c
+--- linux-2.6.32/fs/quota/quota.c      2009-09-10 15:26:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/quota/quota.c        2009-12-03 20:04:56.000000000 +0100
 @@ -18,6 +18,7 @@
  #include <linux/capability.h>
  #include <linux/quotaops.h>
@@ -7200,18 +7201,18 @@ diff -NurpP --minimal linux-2.6.31.6/fs/quota/quota.c linux-2.6.31.6-vs2.3.0.36.
        sb = get_super(bdev);
        bdput(bdev);
        if (!sb)
-diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/file.c linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/file.c
---- linux-2.6.31.6/fs/reiserfs/file.c  2009-06-11 17:13:08.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/file.c    2009-10-07 01:04:14.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/reiserfs/file.c linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/file.c
+--- linux-2.6.32/fs/reiserfs/file.c    2009-06-11 17:13:08.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/file.c      2009-12-03 20:04:56.000000000 +0100
 @@ -307,4 +307,5 @@ const struct inode_operations reiserfs_f
        .listxattr = reiserfs_listxattr,
        .removexattr = reiserfs_removexattr,
        .permission = reiserfs_permission,
 +      .sync_flags = reiserfs_sync_flags,
  };
-diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/inode.c
---- linux-2.6.31.6/fs/reiserfs/inode.c 2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/inode.c   2009-10-06 19:45:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/reiserfs/inode.c linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/inode.c
+--- linux-2.6.32/fs/reiserfs/inode.c   2009-09-10 15:26:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/inode.c     2009-12-03 20:04:56.000000000 +0100
 @@ -18,6 +18,7 @@
  #include <linux/writeback.h>
  #include <linux/quotaops.h>
@@ -7380,9 +7381,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/inode.c linux-2.6.31.6-vs2.3.0.
                                mark_inode_dirty(inode);
                                error =
                                    journal_end(&th, inode->i_sb, jbegin_count);
-diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/ioctl.c
---- linux-2.6.31.6/fs/reiserfs/ioctl.c 2009-06-11 17:13:08.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/ioctl.c   2009-10-12 03:53:52.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/reiserfs/ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/ioctl.c
+--- linux-2.6.32/fs/reiserfs/ioctl.c   2009-06-11 17:13:08.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/ioctl.c     2009-12-03 20:04:56.000000000 +0100
 @@ -7,11 +7,27 @@
  #include <linux/mount.h>
  #include <linux/reiserfs_fs.h>
@@ -7450,9 +7451,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/ioctl.c linux-2.6.31.6-vs2.3.0.
                        sd_attrs_to_i_attrs(flags, inode);
                        REISERFS_I(inode)->i_attrs = flags;
                        inode->i_ctime = CURRENT_TIME_SEC;
-diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/namei.c linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/namei.c
---- linux-2.6.31.6/fs/reiserfs/namei.c 2009-06-11 17:13:08.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/namei.c   2009-10-07 01:09:49.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/reiserfs/namei.c linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/namei.c
+--- linux-2.6.32/fs/reiserfs/namei.c   2009-06-11 17:13:08.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/namei.c     2009-12-03 20:04:56.000000000 +0100
 @@ -17,6 +17,7 @@
  #include <linux/reiserfs_acl.h>
  #include <linux/reiserfs_xattr.h>
@@ -7485,9 +7486,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/namei.c linux-2.6.31.6-vs2.3.0.
  };
  
  /*
-diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/super.c
---- linux-2.6.31.6/fs/reiserfs/super.c 2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/super.c   2009-10-07 03:27:01.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/reiserfs/super.c linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/super.c
+--- linux-2.6.32/fs/reiserfs/super.c   2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/super.c     2009-12-03 20:04:56.000000000 +0100
 @@ -884,6 +884,14 @@ static int reiserfs_parse_options(struct
                {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
                {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
@@ -7529,9 +7530,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/super.c linux-2.6.31.6-vs2.3.0.
        rs = SB_DISK_SUPER_BLOCK(s);
        /* Let's do basic sanity check to verify that underlying device is not
           smaller than the filesystem. If the check fails then abort and scream,
-diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/xattr.c linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/xattr.c
---- linux-2.6.31.6/fs/reiserfs/xattr.c 2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/reiserfs/xattr.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/reiserfs/xattr.c linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/xattr.c
+--- linux-2.6.32/fs/reiserfs/xattr.c   2009-09-10 15:26:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/reiserfs/xattr.c     2009-12-03 20:04:56.000000000 +0100
 @@ -39,6 +39,7 @@
  #include <linux/namei.h>
  #include <linux/errno.h>
@@ -7540,9 +7541,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/reiserfs/xattr.c linux-2.6.31.6-vs2.3.0.
  #include <linux/file.h>
  #include <linux/pagemap.h>
  #include <linux/xattr.h>
-diff -NurpP --minimal linux-2.6.31.6/fs/stat.c linux-2.6.31.6-vs2.3.0.36.24/fs/stat.c
---- linux-2.6.31.6/fs/stat.c   2009-06-11 17:13:08.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/stat.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/stat.c linux-2.6.32-vs2.3.0.36.26/fs/stat.c
+--- linux-2.6.32/fs/stat.c     2009-06-11 17:13:08.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/stat.c       2009-12-03 20:04:56.000000000 +0100
 @@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
        stat->nlink = inode->i_nlink;
        stat->uid = inode->i_uid;
@@ -7551,9 +7552,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/stat.c linux-2.6.31.6-vs2.3.0.36.24/fs/s
        stat->rdev = inode->i_rdev;
        stat->atime = inode->i_atime;
        stat->mtime = inode->i_mtime;
-diff -NurpP --minimal linux-2.6.31.6/fs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/super.c
---- linux-2.6.31.6/fs/super.c  2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/super.c    2009-09-10 17:00:57.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/super.c linux-2.6.32-vs2.3.0.36.26/fs/super.c
+--- linux-2.6.32/fs/super.c    2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/super.c      2009-12-03 20:04:56.000000000 +0100
 @@ -37,6 +37,9 @@
  #include <linux/kobject.h>
  #include <linux/mutex.h>
@@ -7564,7 +7565,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  #include <asm/uaccess.h>
  #include "internal.h"
  
-@@ -859,12 +862,18 @@ struct vfsmount *
+@@ -913,12 +916,18 @@ struct vfsmount *
  vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
  {
        struct vfsmount *mnt;
@@ -7583,7 +7584,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        error = -ENOMEM;
        mnt = alloc_vfsmnt(name);
        if (!mnt)
-@@ -883,9 +892,17 @@ vfs_kern_mount(struct file_system_type *
+@@ -937,9 +946,17 @@ vfs_kern_mount(struct file_system_type *
        error = type->get_sb(type, flags, name, data, mnt);
        if (error < 0)
                goto out_free_secdata;
@@ -7603,9 +7604,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/super.c linux-2.6.31.6-vs2.3.0.36.24/fs/
        if (error)
                goto out_sb;
  
-diff -NurpP --minimal linux-2.6.31.6/fs/sysfs/mount.c linux-2.6.31.6-vs2.3.0.36.24/fs/sysfs/mount.c
---- linux-2.6.31.6/fs/sysfs/mount.c    2009-06-11 17:13:08.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/sysfs/mount.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/sysfs/mount.c linux-2.6.32-vs2.3.0.36.26/fs/sysfs/mount.c
+--- linux-2.6.32/fs/sysfs/mount.c      2009-06-11 17:13:08.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/sysfs/mount.c        2009-12-03 20:04:56.000000000 +0100
 @@ -47,7 +47,7 @@ static int sysfs_fill_super(struct super
  
        sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -7615,9 +7616,40 @@ diff -NurpP --minimal linux-2.6.31.6/fs/sysfs/mount.c linux-2.6.31.6-vs2.3.0.36.
        sb->s_op = &sysfs_ops;
        sb->s_time_gran = 1;
        sysfs_sb = sb;
-diff -NurpP --minimal linux-2.6.31.6/fs/utimes.c linux-2.6.31.6-vs2.3.0.36.24/fs/utimes.c
---- linux-2.6.31.6/fs/utimes.c 2009-03-24 14:22:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/utimes.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/.tmp_dcache.ver linux-2.6.32-vs2.3.0.36.26/fs/.tmp_dcache.ver
+--- linux-2.6.32/fs/.tmp_dcache.ver    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/.tmp_dcache.ver      2009-12-03 20:07:43.000000000 +0100
+@@ -0,0 +1,27 @@
++__crc_sysctl_vfs_cache_pressure = 0x82d79b51 ;
++__crc_dcache_lock = 0x58e482c7 ;
++__crc_d_instantiate_unique = 0x7c189418 ;
++__crc_d_obtain_alias = 0xbcd8dfe6 ;
++__crc_d_genocide = 0x761de69d ;
++__crc_d_alloc = 0x4491e67e ;
++__crc_d_alloc_root = 0xb6aa3916 ;
++__crc_d_delete = 0xc921f8ba ;
++__crc_d_find_alias = 0xe28b75d1 ;
++__crc_d_instantiate = 0x01b0011d ;
++__crc_d_invalidate = 0xfe4bec19 ;
++__crc_d_lookup = 0xb2a5ca18 ;
++__crc_d_move = 0xe574db65 ;
++__crc_d_materialise_unique = 0xa5c0aff6 ;
++__crc_d_path = 0x9db28e8c ;
++__crc_d_prune_aliases = 0x916c21f8 ;
++__crc_d_rehash = 0x57bab990 ;
++__crc_d_splice_alias = 0x65a3aa7d ;
++__crc_d_add_ci = 0x8097dd72 ;
++__crc_d_validate = 0xa68ca558 ;
++__crc_dget_locked = 0x860c45d4 ;
++__crc_dput = 0x9515eed3 ;
++__crc_find_inode_number = 0xb4fb4528 ;
++__crc_have_submounts = 0x9ea1ad9e ;
++__crc_names_cachep = 0x28306992 ;
++__crc_shrink_dcache_parent = 0x6876d637 ;
++__crc_shrink_dcache_sb = 0x0c87c8c6 ;
+diff -NurpP --minimal linux-2.6.32/fs/utimes.c linux-2.6.32-vs2.3.0.36.26/fs/utimes.c
+--- linux-2.6.32/fs/utimes.c   2009-03-24 14:22:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/utimes.c     2009-12-03 20:04:56.000000000 +0100
 @@ -8,6 +8,8 @@
  #include <linux/stat.h>
  #include <linux/utime.h>
@@ -7627,9 +7659,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/utimes.c linux-2.6.31.6-vs2.3.0.36.24/fs
  #include <asm/uaccess.h>
  #include <asm/unistd.h>
  
-diff -NurpP --minimal linux-2.6.31.6/fs/xattr.c linux-2.6.31.6-vs2.3.0.36.24/fs/xattr.c
---- linux-2.6.31.6/fs/xattr.c  2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xattr.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xattr.c linux-2.6.32-vs2.3.0.36.26/fs/xattr.c
+--- linux-2.6.32/fs/xattr.c    2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xattr.c      2009-12-03 20:04:56.000000000 +0100
 @@ -18,6 +18,7 @@
  #include <linux/module.h>
  #include <linux/fsnotify.h>
@@ -7638,9 +7670,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xattr.c linux-2.6.31.6-vs2.3.0.36.24/fs/
  #include <asm/uaccess.h>
  
  
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_ioctl.c
---- linux-2.6.31.6/fs/xfs/linux-2.6/xfs_ioctl.c        2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_ioctl.c  2009-10-07 15:57:55.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_ioctl.c
+--- linux-2.6.32/fs/xfs/linux-2.6/xfs_ioctl.c  2009-09-10 15:26:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_ioctl.c    2009-12-03 20:04:56.000000000 +0100
 @@ -34,7 +34,6 @@
  #include "xfs_dir2_sf.h"
  #include "xfs_dinode.h"
@@ -7708,9 +7740,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.31.6
                return xfs_ioc_setxflags(ip, filp, arg);
  
        case XFS_IOC_FSSETDM: {
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_ioctl.h linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_ioctl.h
---- linux-2.6.31.6/fs/xfs/linux-2.6/xfs_ioctl.h        2009-03-24 14:22:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_ioctl.h  2009-10-07 15:59:45.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/linux-2.6/xfs_ioctl.h linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_ioctl.h
+--- linux-2.6.32/fs/xfs/linux-2.6/xfs_ioctl.h  2009-03-24 14:22:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_ioctl.h    2009-12-03 20:04:56.000000000 +0100
 @@ -70,6 +70,12 @@ xfs_handle_to_dentry(
        void __user             *uhandle,
        u32                     hlen);
@@ -7724,9 +7756,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_ioctl.h linux-2.6.31.6
  extern long
  xfs_file_ioctl(
        struct file             *filp,
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_iops.c
---- linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c 2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_iops.c   2009-10-07 05:23:00.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_iops.c
+--- linux-2.6.32/fs/xfs/linux-2.6/xfs_iops.c   2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_iops.c     2009-12-03 20:04:56.000000000 +0100
 @@ -36,6 +36,7 @@
  #include "xfs_attr_sf.h"
  #include "xfs_dinode.h"
@@ -7735,23 +7767,23 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.6-
  #include "xfs_bmap.h"
  #include "xfs_btree.h"
  #include "xfs_ialloc.h"
-@@ -56,6 +57,7 @@
+@@ -55,6 +56,7 @@
  #include <linux/security.h>
  #include <linux/falloc.h>
  #include <linux/fiemap.h>
 +#include <linux/vs_tag.h>
  
  /*
-  * Bring the atime in the XFS inode uptodate.
-@@ -513,6 +515,7 @@ xfs_vn_getattr(
+  * Bring the timestamps in the XFS inode uptodate.
+@@ -495,6 +497,7 @@ xfs_vn_getattr(
        stat->nlink = ip->i_d.di_nlink;
        stat->uid = ip->i_d.di_uid;
        stat->gid = ip->i_d.di_gid;
 +      stat->tag = ip->i_d.di_tag;
        stat->ino = ip->i_ino;
        stat->atime = inode->i_atime;
-       stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec;
-@@ -706,6 +709,7 @@ static const struct inode_operations xfs
+       stat->mtime = inode->i_mtime;
+@@ -686,6 +689,7 @@ static const struct inode_operations xfs
        .listxattr              = xfs_vn_listxattr,
        .fallocate              = xfs_vn_fallocate,
        .fiemap                 = xfs_vn_fiemap,
@@ -7759,7 +7791,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.6-
  };
  
  static const struct inode_operations xfs_dir_inode_operations = {
-@@ -731,6 +735,7 @@ static const struct inode_operations xfs
+@@ -711,6 +715,7 @@ static const struct inode_operations xfs
        .getxattr               = generic_getxattr,
        .removexattr            = generic_removexattr,
        .listxattr              = xfs_vn_listxattr,
@@ -7767,7 +7799,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.6-
  };
  
  static const struct inode_operations xfs_dir_ci_inode_operations = {
-@@ -780,6 +785,10 @@ xfs_diflags_to_iflags(
+@@ -760,6 +765,10 @@ xfs_diflags_to_iflags(
                inode->i_flags |= S_IMMUTABLE;
        else
                inode->i_flags &= ~S_IMMUTABLE;
@@ -7778,7 +7810,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.6-
        if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
                inode->i_flags |= S_APPEND;
        else
-@@ -792,6 +801,15 @@ xfs_diflags_to_iflags(
+@@ -772,6 +781,15 @@ xfs_diflags_to_iflags(
                inode->i_flags |= S_NOATIME;
        else
                inode->i_flags &= ~S_NOATIME;
@@ -7794,7 +7826,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.6-
  }
  
  /*
-@@ -820,6 +838,7 @@ xfs_setup_inode(
+@@ -800,6 +818,7 @@ xfs_setup_inode(
        inode->i_nlink  = ip->i_d.di_nlink;
        inode->i_uid    = ip->i_d.di_uid;
        inode->i_gid    = ip->i_d.di_gid;
@@ -7802,9 +7834,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.6-
  
        switch (inode->i_mode & S_IFMT) {
        case S_IFBLK:
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_linux.h
---- linux-2.6.31.6/fs/xfs/linux-2.6/xfs_linux.h        2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_linux.h  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_linux.h
+--- linux-2.6.32/fs/xfs/linux-2.6/xfs_linux.h  2009-09-10 15:26:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_linux.h    2009-12-03 20:04:56.000000000 +0100
 @@ -119,6 +119,7 @@
  
  #define current_cpu()         (raw_smp_processor_id())
@@ -7813,9 +7845,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.31.6
  #define current_test_flags(f) (current->flags & (f))
  #define current_set_flags_nested(sp, f)               \
                (*(sp) = current->flags, current->flags |= (f))
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_super.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_super.c
---- linux-2.6.31.6/fs/xfs/linux-2.6/xfs_super.c        2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/linux-2.6/xfs_super.c  2009-09-10 17:01:53.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/linux-2.6/xfs_super.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_super.c
+--- linux-2.6.32/fs/xfs/linux-2.6/xfs_super.c  2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/linux-2.6/xfs_super.c    2009-12-03 20:04:56.000000000 +0100
 @@ -117,6 +117,9 @@ mempool_t *xfs_ioend_pool;
  #define MNTOPT_DMAPI  "dmapi"         /* DMI enabled (DMAPI / XDSM) */
  #define MNTOPT_XDSM   "xdsm"          /* DMI enabled (DMAPI / XDSM) */
@@ -7861,7 +7893,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_super.c linux-2.6.31.6
                } else {
                        cmn_err(CE_WARN,
                                "XFS: unknown mount option [%s].", this_char);
-@@ -1244,6 +1264,16 @@ xfs_fs_remount(
+@@ -1270,6 +1290,16 @@ xfs_fs_remount(
                case Opt_nobarrier:
                        mp->m_flags &= ~XFS_MOUNT_BARRIER;
                        break;
@@ -7878,7 +7910,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_super.c linux-2.6.31.6
                default:
                        /*
                         * Logically we would return an error here to prevent
-@@ -1451,6 +1481,9 @@ xfs_fs_fill_super(
+@@ -1477,6 +1507,9 @@ xfs_fs_fill_super(
  
        XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname);
  
@@ -7888,9 +7920,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/linux-2.6/xfs_super.c linux-2.6.31.6
        sb->s_magic = XFS_SB_MAGIC;
        sb->s_blocksize = mp->m_sb.sb_blocksize;
        sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_dinode.h linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_dinode.h
---- linux-2.6.31.6/fs/xfs/xfs_dinode.h 2009-06-11 17:13:09.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_dinode.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_dinode.h linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_dinode.h
+--- linux-2.6.32/fs/xfs/xfs_dinode.h   2009-06-11 17:13:09.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_dinode.h     2009-12-03 20:04:56.000000000 +0100
 @@ -50,7 +50,9 @@ typedef struct xfs_dinode {
        __be32          di_gid;         /* owner's group id */
        __be32          di_nlink;       /* number of links to file */
@@ -7931,9 +7963,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_dinode.h linux-2.6.31.6-vs2.3.0.
 +#define XFS_DIVFLAG_COW               0x02
  
  #endif        /* __XFS_DINODE_H__ */
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_fs.h linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_fs.h
---- linux-2.6.31.6/fs/xfs/xfs_fs.h     2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_fs.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_fs.h linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_fs.h
+--- linux-2.6.32/fs/xfs/xfs_fs.h       2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_fs.h 2009-12-03 20:04:56.000000000 +0100
 @@ -67,6 +67,9 @@ struct fsxattr {
  #define XFS_XFLAG_EXTSZINHERIT        0x00001000      /* inherit inode extent size */
  #define XFS_XFLAG_NODEFRAG    0x00002000      /* do not defragment */
@@ -7954,9 +7986,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_fs.h linux-2.6.31.6-vs2.3.0.36.2
        __u32           bs_dmevmask;    /* DMIG event mask              */
        __u16           bs_dmstate;     /* DMIG state info              */
        __u16           bs_aextents;    /* attribute number of extents  */
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_ialloc.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_ialloc.c
---- linux-2.6.31.6/fs/xfs/xfs_ialloc.c 2009-06-11 17:13:09.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_ialloc.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_ialloc.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_ialloc.c
+--- linux-2.6.32/fs/xfs/xfs_ialloc.c   2009-12-03 20:02:53.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_ialloc.c     2009-12-03 20:04:56.000000000 +0100
 @@ -41,7 +41,6 @@
  #include "xfs_error.h"
  #include "xfs_bmap.h"
@@ -7965,9 +7997,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_ialloc.c linux-2.6.31.6-vs2.3.0.
  /*
   * Allocation group level functions.
   */
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_inode.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_inode.c
---- linux-2.6.31.6/fs/xfs/xfs_inode.c  2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_inode.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_inode.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_inode.c
+--- linux-2.6.32/fs/xfs/xfs_inode.c    2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_inode.c      2009-12-03 20:04:56.000000000 +0100
 @@ -249,6 +249,7 @@ xfs_inotobp(
        return 0;
  }
@@ -7977,7 +8009,7 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_inode.c linux-2.6.31.6-vs2.3.0.3
  /*
   * This routine is called to map an inode to the buffer containing
 @@ -654,15 +655,25 @@ xfs_iformat_btree(
- void
STATIC void
  xfs_dinode_from_disk(
        xfs_icdinode_t          *to,
 -      xfs_dinode_t            *from)
@@ -8142,9 +8174,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_inode.c linux-2.6.31.6-vs2.3.0.3
  
        /* Wrap, we never let the log put out DI_MAX_FLUSH */
        if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_inode.h linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_inode.h
---- linux-2.6.31.6/fs/xfs/xfs_inode.h  2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_inode.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_inode.h linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_inode.h
+--- linux-2.6.32/fs/xfs/xfs_inode.h    2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_inode.h      2009-12-03 20:04:56.000000000 +0100
 @@ -135,7 +135,9 @@ typedef struct xfs_icdinode {
        __uint32_t      di_gid;         /* owner's group id */
        __uint32_t      di_nlink;       /* number of links to file */
@@ -8156,32 +8188,29 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_inode.h linux-2.6.31.6-vs2.3.0.3
        __uint16_t      di_flushiter;   /* incremented on flush */
        xfs_ictimestamp_t di_atime;     /* time last accessed */
        xfs_ictimestamp_t di_mtime;     /* time last modified */
-@@ -573,9 +575,9 @@ int                xfs_itobp(struct xfs_mount *, struc
+@@ -569,7 +571,7 @@ int                xfs_itobp(struct xfs_mount *, struc
  int           xfs_iread(struct xfs_mount *, struct xfs_trans *,
                          struct xfs_inode *, xfs_daddr_t, uint);
- void          xfs_dinode_from_disk(struct xfs_icdinode *,
--                                   struct xfs_dinode *);
-+                                   struct xfs_dinode *, int);
  void          xfs_dinode_to_disk(struct xfs_dinode *,
 -                                 struct xfs_icdinode *);
 +                                 struct xfs_icdinode *, int);
  void          xfs_idestroy_fork(struct xfs_inode *, int);
  void          xfs_idata_realloc(struct xfs_inode *, int, int);
  void          xfs_iroot_realloc(struct xfs_inode *, int, int);
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_itable.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_itable.c
---- linux-2.6.31.6/fs/xfs/xfs_itable.c 2009-06-11 17:13:09.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_itable.c   2009-09-10 16:11:43.000000000 +0200
-@@ -82,6 +82,7 @@ xfs_bulkstat_one_iget(
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_itable.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_itable.c
+--- linux-2.6.32/fs/xfs/xfs_itable.c   2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_itable.c     2009-12-03 20:04:56.000000000 +0100
+@@ -84,6 +84,7 @@ xfs_bulkstat_one_iget(
        buf->bs_mode = dic->di_mode;
        buf->bs_uid = dic->di_uid;
        buf->bs_gid = dic->di_gid;
 +      buf->bs_tag = dic->di_tag;
        buf->bs_size = dic->di_size;
        /*
-        * We are reading the atime from the Linux inode because the
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_log_recover.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_log_recover.c
---- linux-2.6.31.6/fs/xfs/xfs_log_recover.c    2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_log_recover.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_log_recover.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_log_recover.c
+--- linux-2.6.32/fs/xfs/xfs_log_recover.c      2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_log_recover.c        2009-12-03 20:04:56.000000000 +0100
 @@ -2467,7 +2467,8 @@ xlog_recover_do_inode_trans(
        }
  
@@ -8192,9 +8221,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_log_recover.c linux-2.6.31.6-vs2
  
        /* the rest is in on-disk format */
        if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) {
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_mount.h linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_mount.h
---- linux-2.6.31.6/fs/xfs/xfs_mount.h  2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_mount.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_mount.h linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_mount.h
+--- linux-2.6.32/fs/xfs/xfs_mount.h    2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_mount.h      2009-12-03 20:04:56.000000000 +0100
 @@ -283,6 +283,7 @@ typedef struct xfs_mount {
                                                   allocator */
  #define XFS_MOUNT_NOATTR2     (1ULL << 25)    /* disable use of attr2 format */
@@ -8203,9 +8232,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_mount.h linux-2.6.31.6-vs2.3.0.3
  
  /*
   * Default minimum read and write sizes.
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_vnodeops.c linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_vnodeops.c
---- linux-2.6.31.6/fs/xfs/xfs_vnodeops.c       2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_vnodeops.c 2009-10-07 15:57:06.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_vnodeops.c linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_vnodeops.c
+--- linux-2.6.32/fs/xfs/xfs_vnodeops.c 2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_vnodeops.c   2009-12-03 20:04:56.000000000 +0100
 @@ -54,6 +54,80 @@
  #include "xfs_filestream.h"
  #include "xfs_vnodeops.h"
@@ -8345,9 +8374,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_vnodeops.c linux-2.6.31.6-vs2.3.
                if (iuid != uid) {
                        if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) {
                                ASSERT(mask & ATTR_UID);
-diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_vnodeops.h linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_vnodeops.h
---- linux-2.6.31.6/fs/xfs/xfs_vnodeops.h       2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/fs/xfs/xfs_vnodeops.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/fs/xfs/xfs_vnodeops.h linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_vnodeops.h
+--- linux-2.6.32/fs/xfs/xfs_vnodeops.h 2009-09-10 15:26:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/fs/xfs/xfs_vnodeops.h   2009-12-03 20:04:56.000000000 +0100
 @@ -14,6 +14,7 @@ struct xfs_inode;
  struct xfs_iomap;
  
@@ -8356,9 +8385,9 @@ diff -NurpP --minimal linux-2.6.31.6/fs/xfs/xfs_vnodeops.h linux-2.6.31.6-vs2.3.
  int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags);
  #define       XFS_ATTR_DMI            0x01    /* invocation from a DMI function */
  #define       XFS_ATTR_NONBLOCK       0x02    /* return EAGAIN if operation would block */
-diff -NurpP --minimal linux-2.6.31.6/include/asm-generic/tlb.h linux-2.6.31.6-vs2.3.0.36.24/include/asm-generic/tlb.h
---- linux-2.6.31.6/include/asm-generic/tlb.h   2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/asm-generic/tlb.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/asm-generic/tlb.h linux-2.6.32-vs2.3.0.36.26/include/asm-generic/tlb.h
+--- linux-2.6.32/include/asm-generic/tlb.h     2009-09-10 15:26:24.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/asm-generic/tlb.h       2009-12-03 20:04:56.000000000 +0100
 @@ -14,6 +14,7 @@
  #define _ASM_GENERIC__TLB_H
  
@@ -8367,9 +8396,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/asm-generic/tlb.h linux-2.6.31.6-vs
  #include <asm/pgalloc.h>
  #include <asm/tlbflush.h>
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/capability.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/capability.h
---- linux-2.6.31.6/include/linux/capability.h  2009-06-11 17:13:13.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/capability.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/capability.h linux-2.6.32-vs2.3.0.36.26/include/linux/capability.h
+--- linux-2.6.32/include/linux/capability.h    2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/capability.h      2009-12-03 20:04:56.000000000 +0100
 @@ -285,6 +285,7 @@ struct cpu_vfs_cap_data {
     arbitrary SCSI commands */
  /* Allow setting encryption key on loopback filesystem */
@@ -8393,18 +8422,18 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/capability.h linux-2.6.31.6-v
  
  #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/devpts_fs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/devpts_fs.h
---- linux-2.6.31.6/include/linux/devpts_fs.h   2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/devpts_fs.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/devpts_fs.h linux-2.6.32-vs2.3.0.36.26/include/linux/devpts_fs.h
+--- linux-2.6.32/include/linux/devpts_fs.h     2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/devpts_fs.h       2009-12-03 20:04:56.000000000 +0100
 @@ -45,5 +45,4 @@ static inline void devpts_pty_kill(struc
  
  #endif
  
 -
  #endif /* _LINUX_DEVPTS_FS_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/ext2_fs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/ext2_fs.h
---- linux-2.6.31.6/include/linux/ext2_fs.h     2009-03-24 14:22:41.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/ext2_fs.h       2009-10-12 05:20:23.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/ext2_fs.h linux-2.6.32-vs2.3.0.36.26/include/linux/ext2_fs.h
+--- linux-2.6.32/include/linux/ext2_fs.h       2009-03-24 14:22:41.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/ext2_fs.h 2009-12-03 20:04:56.000000000 +0100
 @@ -189,8 +189,12 @@ struct ext2_group_desc
  #define EXT2_NOTAIL_FL                        FS_NOTAIL_FL    /* file tail should not be merged */
  #define EXT2_DIRSYNC_FL                       FS_DIRSYNC_FL   /* dirsync behaviour (directories only) */
@@ -8444,9 +8473,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/ext2_fs.h linux-2.6.31.6-vs2.
  
  
  #define clear_opt(o, opt)             o &= ~EXT2_MOUNT_##opt
-diff -NurpP --minimal linux-2.6.31.6/include/linux/ext3_fs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/ext3_fs.h
---- linux-2.6.31.6/include/linux/ext3_fs.h     2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/ext3_fs.h       2009-10-12 05:20:40.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/ext3_fs.h linux-2.6.32-vs2.3.0.36.26/include/linux/ext3_fs.h
+--- linux-2.6.32/include/linux/ext3_fs.h       2009-09-10 15:26:25.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/ext3_fs.h 2009-12-03 20:04:56.000000000 +0100
 @@ -173,10 +173,14 @@ struct ext3_group_desc
  #define EXT3_NOTAIL_FL                        0x00008000 /* file tail should not be merged */
  #define EXT3_DIRSYNC_FL                       0x00010000 /* dirsync behaviour (directories only) */
@@ -8498,9 +8527,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/ext3_fs.h linux-2.6.31.6-vs2.
  
  /* ioctl.c */
  extern long ext3_ioctl(struct file *, unsigned int, unsigned long);
-diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/fs.h
---- linux-2.6.31.6/include/linux/fs.h  2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/fs.h    2009-10-06 23:35:53.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/fs.h linux-2.6.32-vs2.3.0.36.26/include/linux/fs.h
+--- linux-2.6.32/include/linux/fs.h    2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/fs.h      2009-12-03 20:04:56.000000000 +0100
 @@ -205,6 +205,9 @@ struct inodes_stat_t {
  #define MS_KERNMOUNT  (1<<22) /* this is a kern_mount call */
  #define MS_I_VERSION  (1<<23) /* Update inode I_version field */
@@ -8561,7 +8590,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  /* the read-only stuff doesn't really belong here, but any other place is
     probably as bad and I don't want to create yet another include file. */
  
-@@ -343,11 +367,14 @@ struct inodes_stat_t {
+@@ -347,11 +371,14 @@ struct inodes_stat_t {
  #define FS_TOPDIR_FL                  0x00020000 /* Top of directory hierarchies*/
  #define FS_EXTENT_FL                  0x00080000 /* Extents */
  #define FS_DIRECTIO_FL                        0x00100000 /* Use direct i/o */
@@ -8578,7 +8607,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  
  #define SYNC_FILE_RANGE_WAIT_BEFORE   1
  #define SYNC_FILE_RANGE_WRITE         2
-@@ -429,6 +456,7 @@ typedef void (dio_iodone_t)(struct kiocb
+@@ -433,6 +460,7 @@ typedef void (dio_iodone_t)(struct kiocb
  #define ATTR_KILL_PRIV        (1 << 14)
  #define ATTR_OPEN     (1 << 15) /* Truncating from open(O_TRUNC) */
  #define ATTR_TIMES_SET        (1 << 16)
@@ -8586,7 +8615,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  
  /*
   * This is the Inode Attributes structure, used for notify_change().  It
-@@ -444,6 +472,7 @@ struct iattr {
+@@ -448,6 +476,7 @@ struct iattr {
        umode_t         ia_mode;
        uid_t           ia_uid;
        gid_t           ia_gid;
@@ -8594,7 +8623,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
        loff_t          ia_size;
        struct timespec ia_atime;
        struct timespec ia_mtime;
-@@ -457,6 +486,9 @@ struct iattr {
+@@ -461,6 +490,9 @@ struct iattr {
        struct file     *ia_file;
  };
  
@@ -8604,7 +8633,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  /*
   * Includes for diskquotas.
   */
-@@ -723,7 +755,9 @@ struct inode {
+@@ -726,7 +758,9 @@ struct inode {
        unsigned int            i_nlink;
        uid_t                   i_uid;
        gid_t                   i_gid;
@@ -8614,7 +8643,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
        u64                     i_version;
        loff_t                  i_size;
  #ifdef __NEED_I_SIZE_ORDERED
-@@ -770,7 +804,8 @@ struct inode {
+@@ -773,7 +807,8 @@ struct inode {
        unsigned long           i_state;
        unsigned long           dirtied_when;   /* jiffies of first dirtying */
  
@@ -8624,7 +8653,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  
        atomic_t                i_writecount;
  #ifdef CONFIG_SECURITY
-@@ -858,12 +893,12 @@ static inline void i_size_write(struct i
+@@ -861,12 +896,12 @@ static inline void i_size_write(struct i
  
  static inline unsigned iminor(const struct inode *inode)
  {
@@ -8639,7 +8668,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  }
  
  extern struct block_device *I_BDEV(struct inode *inode);
-@@ -922,6 +957,7 @@ struct file {
+@@ -925,6 +960,7 @@ struct file {
        loff_t                  f_pos;
        struct fown_struct      f_owner;
        const struct cred       *f_cred;
@@ -8647,7 +8676,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
        struct file_ra_state    f_ra;
  
        u64                     f_version;
-@@ -1063,6 +1099,7 @@ struct file_lock {
+@@ -1066,6 +1102,7 @@ struct file_lock {
        struct file *fl_file;
        loff_t fl_start;
        loff_t fl_end;
@@ -8655,7 +8684,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  
        struct fasync_struct *  fl_fasync; /* for lease break notifications */
        unsigned long fl_break_time;    /* for nonblocking lease breaks */
-@@ -1534,6 +1571,7 @@ struct inode_operations {
+@@ -1531,6 +1568,7 @@ struct inode_operations {
        ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
        ssize_t (*listxattr) (struct dentry *, char *, size_t);
        int (*removexattr) (struct dentry *, const char *);
@@ -8663,7 +8692,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
        void (*truncate_range)(struct inode *, loff_t, loff_t);
        long (*fallocate)(struct inode *inode, int mode, loff_t offset,
                          loff_t len);
-@@ -1554,6 +1592,7 @@ extern ssize_t vfs_readv(struct file *, 
+@@ -1551,6 +1589,7 @@ extern ssize_t vfs_readv(struct file *, 
                unsigned long, loff_t *);
  extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
                unsigned long, loff_t *);
@@ -8671,7 +8700,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  
  struct super_operations {
        struct inode *(*alloc_inode)(struct super_block *sb);
-@@ -2328,6 +2367,7 @@ extern int dcache_dir_open(struct inode 
+@@ -2347,6 +2386,7 @@ extern int dcache_dir_open(struct inode 
  extern int dcache_dir_close(struct inode *, struct file *);
  extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
  extern int dcache_readdir(struct file *, void *, filldir_t);
@@ -8679,9 +8708,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/fs.h linux-2.6.31.6-vs2.3.0.3
  extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
  extern int simple_statfs(struct dentry *, struct kstatfs *);
  extern int simple_link(struct dentry *, struct inode *, struct dentry *);
-diff -NurpP --minimal linux-2.6.31.6/include/linux/gfs2_ondisk.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/gfs2_ondisk.h
---- linux-2.6.31.6/include/linux/gfs2_ondisk.h 2009-03-24 14:22:41.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/gfs2_ondisk.h   2009-10-07 18:20:44.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/gfs2_ondisk.h linux-2.6.32-vs2.3.0.36.26/include/linux/gfs2_ondisk.h
+--- linux-2.6.32/include/linux/gfs2_ondisk.h   2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/gfs2_ondisk.h     2009-12-03 20:04:56.000000000 +0100
 @@ -235,6 +235,9 @@ enum {
        gfs2fl_NoAtime          = 7,
        gfs2fl_Sync             = 8,
@@ -8702,9 +8731,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/gfs2_ondisk.h linux-2.6.31.6-
  #define GFS2_DIF_TRUNC_IN_PROG                0x20000000 /* New in gfs2 */
  #define GFS2_DIF_INHERIT_DIRECTIO     0x40000000
  #define GFS2_DIF_INHERIT_JDATA                0x80000000
-diff -NurpP --minimal linux-2.6.31.6/include/linux/if_tun.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/if_tun.h
---- linux-2.6.31.6/include/linux/if_tun.h      2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/if_tun.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/if_tun.h linux-2.6.32-vs2.3.0.36.26/include/linux/if_tun.h
+--- linux-2.6.32/include/linux/if_tun.h        2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/if_tun.h  2009-12-03 20:04:56.000000000 +0100
 @@ -48,6 +48,7 @@
  #define TUNGETIFF      _IOR('T', 210, unsigned int)
  #define TUNGETSNDBUF   _IOR('T', 211, int)
@@ -8713,13 +8742,13 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/if_tun.h linux-2.6.31.6-vs2.3
  
  /* TUNSETIFF ifr flags */
  #define IFF_TUN               0x0001
-diff -NurpP --minimal linux-2.6.31.6/include/linux/init_task.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/init_task.h
---- linux-2.6.31.6/include/linux/init_task.h   2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/init_task.h     2009-09-10 17:13:45.000000000 +0200
-@@ -173,6 +173,10 @@ extern struct cred init_cred;
-       INIT_LOCKDEP                                                    \
+diff -NurpP --minimal linux-2.6.32/include/linux/init_task.h linux-2.6.32-vs2.3.0.36.26/include/linux/init_task.h
+--- linux-2.6.32/include/linux/init_task.h     2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/init_task.h       2009-12-03 20:04:56.000000000 +0100
+@@ -184,6 +184,10 @@ extern struct cred init_cred;
        INIT_FTRACE_GRAPH                                               \
        INIT_TRACE_RECURSION                                            \
+       INIT_TASK_RCU_PREEMPT(tsk)                                      \
 +      .xid            = 0,                                            \
 +      .vx_info        = NULL,                                         \
 +      .nid            = 0,                                            \
@@ -8727,23 +8756,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/init_task.h linux-2.6.31.6-vs
  }
  
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/interrupt.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/interrupt.h
---- linux-2.6.31.6/include/linux/interrupt.h   2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/interrupt.h     2009-09-10 16:11:43.000000000 +0200
-@@ -9,8 +9,8 @@
- #include <linux/cpumask.h>
- #include <linux/irqreturn.h>
- #include <linux/irqnr.h>
--#include <linux/hardirq.h>
- #include <linux/sched.h>
-+#include <linux/hardirq.h>
- #include <linux/irqflags.h>
- #include <linux/smp.h>
- #include <linux/percpu.h>
-diff -NurpP --minimal linux-2.6.31.6/include/linux/ipc.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/ipc.h
---- linux-2.6.31.6/include/linux/ipc.h 2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/ipc.h   2009-09-10 16:11:43.000000000 +0200
-@@ -93,6 +93,7 @@ struct kern_ipc_perm
+diff -NurpP --minimal linux-2.6.32/include/linux/ipc.h linux-2.6.32-vs2.3.0.36.26/include/linux/ipc.h
+--- linux-2.6.32/include/linux/ipc.h   2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/ipc.h     2009-12-03 20:04:56.000000000 +0100
+@@ -91,6 +91,7 @@ struct kern_ipc_perm
        key_t           key;
        uid_t           uid;
        gid_t           gid;
@@ -8751,10 +8767,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/ipc.h linux-2.6.31.6-vs2.3.0.
        uid_t           cuid;
        gid_t           cgid;
        mode_t          mode; 
-diff -NurpP --minimal linux-2.6.31.6/include/linux/Kbuild linux-2.6.31.6-vs2.3.0.36.24/include/linux/Kbuild
---- linux-2.6.31.6/include/linux/Kbuild        2009-09-10 15:26:24.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/Kbuild  2009-09-10 16:11:43.000000000 +0200
-@@ -376,5 +376,8 @@ unifdef-y += xattr.h
+diff -NurpP --minimal linux-2.6.32/include/linux/Kbuild linux-2.6.32-vs2.3.0.36.26/include/linux/Kbuild
+--- linux-2.6.32/include/linux/Kbuild  2009-12-03 20:02:54.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/Kbuild    2009-12-03 20:04:56.000000000 +0100
+@@ -382,5 +382,8 @@ unifdef-y += xattr.h
  unifdef-y += xfrm.h
  
  objhdr-y += version.h
@@ -8763,9 +8779,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/Kbuild linux-2.6.31.6-vs2.3.0
  header-y += wimax.h
  header-y += wimax/
 +
-diff -NurpP --minimal linux-2.6.31.6/include/linux/loop.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/loop.h
---- linux-2.6.31.6/include/linux/loop.h        2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/loop.h  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/loop.h linux-2.6.32-vs2.3.0.36.26/include/linux/loop.h
+--- linux-2.6.32/include/linux/loop.h  2009-09-10 15:26:25.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/loop.h    2009-12-03 20:04:56.000000000 +0100
 @@ -45,6 +45,7 @@ struct loop_device {
        struct loop_func_table *lo_encryption;
        __u32           lo_init[2];
@@ -8774,9 +8790,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/loop.h linux-2.6.31.6-vs2.3.0
        int             (*ioctl)(struct loop_device *, int cmd, 
                                 unsigned long arg); 
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/magic.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/magic.h
---- linux-2.6.31.6/include/linux/magic.h       2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/magic.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/magic.h linux-2.6.32-vs2.3.0.36.26/include/linux/magic.h
+--- linux-2.6.32/include/linux/magic.h 2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/magic.h   2009-12-03 20:04:56.000000000 +0100
 @@ -3,7 +3,7 @@
  
  #define ADFS_SUPER_MAGIC      0xadf5
@@ -8786,7 +8802,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/magic.h linux-2.6.31.6-vs2.3.
  #define AUTOFS_SUPER_MAGIC    0x0187
  #define CODA_SUPER_MAGIC      0x73757245
  #define CRAMFS_MAGIC          0x28cd3d45      /* some random number */
-@@ -36,6 +36,7 @@
+@@ -38,6 +38,7 @@
  #define NFS_SUPER_MAGIC               0x6969
  #define OPENPROM_SUPER_MAGIC  0x9fa1
  #define PROC_SUPER_MAGIC      0x9fa0
@@ -8794,9 +8810,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/magic.h linux-2.6.31.6-vs2.3.
  #define QNX4_SUPER_MAGIC      0x002f          /* qnx4 fs detection */
  
  #define REISERFS_SUPER_MAGIC  0x52654973      /* used by gcc */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/major.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/major.h
---- linux-2.6.31.6/include/linux/major.h       2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/major.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/major.h linux-2.6.32-vs2.3.0.36.26/include/linux/major.h
+--- linux-2.6.32/include/linux/major.h 2009-09-10 15:26:25.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/major.h   2009-12-03 20:04:56.000000000 +0100
 @@ -15,6 +15,7 @@
  #define HD_MAJOR              IDE0_MAJOR
  #define PTY_SLAVE_MAJOR               3
@@ -8805,10 +8821,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/major.h linux-2.6.31.6-vs2.3.
  #define TTYAUX_MAJOR          5
  #define LP_MAJOR              6
  #define VCS_MAJOR             7
-diff -NurpP --minimal linux-2.6.31.6/include/linux/mm_types.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/mm_types.h
---- linux-2.6.31.6/include/linux/mm_types.h    2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/mm_types.h      2009-09-10 16:11:43.000000000 +0200
-@@ -244,6 +244,7 @@ struct mm_struct {
+diff -NurpP --minimal linux-2.6.32/include/linux/mm_types.h linux-2.6.32-vs2.3.0.36.26/include/linux/mm_types.h
+--- linux-2.6.32/include/linux/mm_types.h      2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/mm_types.h        2009-12-03 20:04:56.000000000 +0100
+@@ -246,6 +246,7 @@ struct mm_struct {
  
        /* Architecture-specific MM context */
        mm_context_t context;
@@ -8816,9 +8832,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/mm_types.h linux-2.6.31.6-vs2
  
        /* Swap token stuff */
        /*
-diff -NurpP --minimal linux-2.6.31.6/include/linux/mount.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/mount.h
---- linux-2.6.31.6/include/linux/mount.h       2009-09-10 15:26:25.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/mount.h 2009-09-10 17:14:39.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/mount.h linux-2.6.32-vs2.3.0.36.26/include/linux/mount.h
+--- linux-2.6.32/include/linux/mount.h 2009-09-10 15:26:25.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/mount.h   2009-12-03 20:04:56.000000000 +0100
 @@ -36,6 +36,9 @@ struct mnt_namespace;
  #define MNT_UNBINDABLE        0x2000  /* if the vfsmount is a unbindable mount */
  #define MNT_PNODE_MASK        0x3000  /* propagation flag mask */
@@ -8837,10 +8853,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/mount.h linux-2.6.31.6-vs2.3.
  };
  
  static inline int *get_mnt_writers_ptr(struct vfsmount *mnt)
-diff -NurpP --minimal linux-2.6.31.6/include/linux/net.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/net.h
---- linux-2.6.31.6/include/linux/net.h 2009-06-11 17:13:15.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/net.h   2009-09-10 16:11:43.000000000 +0200
-@@ -68,6 +68,7 @@ struct net;
+diff -NurpP --minimal linux-2.6.32/include/linux/net.h linux-2.6.32-vs2.3.0.36.26/include/linux/net.h
+--- linux-2.6.32/include/linux/net.h   2009-12-03 20:02:55.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/net.h     2009-12-03 20:04:56.000000000 +0100
+@@ -69,6 +69,7 @@ struct net;
  #define SOCK_NOSPACE          2
  #define SOCK_PASSCRED         3
  #define SOCK_PASSSEC          4
@@ -8848,9 +8864,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/net.h linux-2.6.31.6-vs2.3.0.
  
  #ifndef ARCH_HAS_SOCKET_TYPES
  /**
-diff -NurpP --minimal linux-2.6.31.6/include/linux/nfs_mount.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/nfs_mount.h
---- linux-2.6.31.6/include/linux/nfs_mount.h   2009-03-24 14:22:43.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/nfs_mount.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/nfs_mount.h linux-2.6.32-vs2.3.0.36.26/include/linux/nfs_mount.h
+--- linux-2.6.32/include/linux/nfs_mount.h     2009-03-24 14:22:43.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/nfs_mount.h       2009-12-03 20:04:56.000000000 +0100
 @@ -63,7 +63,8 @@ struct nfs_mount_data {
  #define NFS_MOUNT_SECFLAVOUR  0x2000  /* 5 */
  #define NFS_MOUNT_NORDIRPLUS  0x4000  /* 5 */
@@ -8861,9 +8877,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/nfs_mount.h linux-2.6.31.6-vs
  
  /* The following are for internal use only */
  #define NFS_MOUNT_LOOKUP_CACHE_NONEG  0x10000
-diff -NurpP --minimal linux-2.6.31.6/include/linux/nsproxy.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/nsproxy.h
---- linux-2.6.31.6/include/linux/nsproxy.h     2009-06-11 17:13:17.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/nsproxy.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/nsproxy.h linux-2.6.32-vs2.3.0.36.26/include/linux/nsproxy.h
+--- linux-2.6.32/include/linux/nsproxy.h       2009-06-11 17:13:17.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/nsproxy.h 2009-12-03 20:04:56.000000000 +0100
 @@ -3,6 +3,7 @@
  
  #include <linux/spinlock.h>
@@ -8912,9 +8928,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/nsproxy.h linux-2.6.31.6-vs2.
  }
  
  #ifdef CONFIG_CGROUP_NS
-diff -NurpP --minimal linux-2.6.31.6/include/linux/pid.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/pid.h
---- linux-2.6.31.6/include/linux/pid.h 2009-03-24 14:22:43.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/pid.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/pid.h linux-2.6.32-vs2.3.0.36.26/include/linux/pid.h
+--- linux-2.6.32/include/linux/pid.h   2009-03-24 14:22:43.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/pid.h     2009-12-03 20:04:56.000000000 +0100
 @@ -8,7 +8,8 @@ enum pid_type
        PIDTYPE_PID,
        PIDTYPE_PGID,
@@ -8933,9 +8949,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/pid.h linux-2.6.31.6-vs2.3.0.
  pid_t pid_vnr(struct pid *pid);
  
  #define do_each_pid_task(pid, type, task)                             \
-diff -NurpP --minimal linux-2.6.31.6/include/linux/proc_fs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/proc_fs.h
---- linux-2.6.31.6/include/linux/proc_fs.h     2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/proc_fs.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/proc_fs.h linux-2.6.32-vs2.3.0.36.26/include/linux/proc_fs.h
+--- linux-2.6.32/include/linux/proc_fs.h       2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/proc_fs.h 2009-12-03 20:04:56.000000000 +0100
 @@ -56,6 +56,7 @@ struct proc_dir_entry {
        nlink_t nlink;
        uid_t uid;
@@ -8944,8 +8960,8 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/proc_fs.h linux-2.6.31.6-vs2.
        loff_t size;
        const struct inode_operations *proc_iops;
        /*
-@@ -240,12 +241,18 @@ static inline void kclist_add(struct kco
- extern void kclist_add(struct kcore_list *, void *, size_t);
+@@ -250,12 +251,18 @@ kclist_add(struct kcore_list *new, void 
+ extern void kclist_add(struct kcore_list *, void *, size_t, int type);
  #endif
  
 +struct vx_info;
@@ -8963,7 +8979,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/proc_fs.h linux-2.6.31.6-vs2.
  };
  
  struct ctl_table_header;
-@@ -253,6 +260,7 @@ struct ctl_table;
+@@ -263,6 +270,7 @@ struct ctl_table;
  
  struct proc_inode {
        struct pid *pid;
@@ -8971,9 +8987,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/proc_fs.h linux-2.6.31.6-vs2.
        int fd;
        union proc_op op;
        struct proc_dir_entry *pde;
-diff -NurpP --minimal linux-2.6.31.6/include/linux/quotaops.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/quotaops.h
---- linux-2.6.31.6/include/linux/quotaops.h    2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/quotaops.h      2009-10-12 02:07:55.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/quotaops.h linux-2.6.32-vs2.3.0.36.26/include/linux/quotaops.h
+--- linux-2.6.32/include/linux/quotaops.h      2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/quotaops.h        2009-12-03 20:04:56.000000000 +0100
 @@ -8,6 +8,7 @@
  #define _LINUX_QUOTAOPS_
  
@@ -9131,9 +9147,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/quotaops.h linux-2.6.31.6-vs2
        inode_sub_bytes(inode, nr);
  }
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/reiserfs_fs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/reiserfs_fs.h
---- linux-2.6.31.6/include/linux/reiserfs_fs.h 2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/reiserfs_fs.h   2009-10-07 01:27:41.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/reiserfs_fs.h linux-2.6.32-vs2.3.0.36.26/include/linux/reiserfs_fs.h
+--- linux-2.6.32/include/linux/reiserfs_fs.h   2009-09-10 15:26:26.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/reiserfs_fs.h     2009-12-03 20:04:56.000000000 +0100
 @@ -899,6 +899,11 @@ struct stat_data_v1 {
  #define REISERFS_COMPR_FL     FS_COMPR_FL
  #define REISERFS_NOTAIL_FL    FS_NOTAIL_FL
@@ -9164,9 +9180,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/reiserfs_fs.h linux-2.6.31.6-
  
  /* namei.c */
  void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
-diff -NurpP --minimal linux-2.6.31.6/include/linux/reiserfs_fs_sb.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/reiserfs_fs_sb.h
---- linux-2.6.31.6/include/linux/reiserfs_fs_sb.h      2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/reiserfs_fs_sb.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/reiserfs_fs_sb.h linux-2.6.32-vs2.3.0.36.26/include/linux/reiserfs_fs_sb.h
+--- linux-2.6.32/include/linux/reiserfs_fs_sb.h        2009-09-10 15:26:26.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/reiserfs_fs_sb.h  2009-12-03 20:04:56.000000000 +0100
 @@ -456,6 +456,7 @@ enum reiserfs_mount_options {
        REISERFS_EXPOSE_PRIVROOT,
        REISERFS_BARRIER_NONE,
@@ -9175,10 +9191,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/reiserfs_fs_sb.h linux-2.6.31
  
        /* Actions on error */
        REISERFS_ERROR_PANIC,
-diff -NurpP --minimal linux-2.6.31.6/include/linux/sched.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/sched.h
---- linux-2.6.31.6/include/linux/sched.h       2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/sched.h 2009-10-06 04:39:26.000000000 +0200
-@@ -383,25 +383,28 @@ extern void arch_unmap_area_topdown(stru
+diff -NurpP --minimal linux-2.6.32/include/linux/sched.h linux-2.6.32-vs2.3.0.36.26/include/linux/sched.h
+--- linux-2.6.32/include/linux/sched.h 2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/sched.h   2009-12-03 20:04:56.000000000 +0100
+@@ -390,25 +390,28 @@ extern void arch_unmap_area_topdown(stru
   * The mm counters are not protected by its page_table_lock,
   * so must be incremented atomically.
   */
@@ -9216,24 +9232,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sched.h linux-2.6.31.6-vs2.3.
  #define get_mm_rss(mm)                                        \
        (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
  #define update_hiwater_rss(mm)        do {                    \
-@@ -1024,7 +1027,7 @@ struct sched_domain;
- struct sched_class {
-       const struct sched_class *next;
--      void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup);
-+      int (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup);
-       void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
-       void (*yield_task) (struct rq *rq);
-@@ -1124,6 +1127,7 @@ struct sched_entity {
-       u64                     nr_failed_migrations_affine;
-       u64                     nr_failed_migrations_running;
-       u64                     nr_failed_migrations_hot;
-+      u64                     nr_failed_migrations_throttled;
-       u64                     nr_forced_migrations;
-       u64                     nr_forced2_migrations;
-@@ -1136,6 +1140,12 @@ struct sched_entity {
+@@ -1183,6 +1186,12 @@ struct sched_entity {
        u64                     nr_wakeups_affine_attempts;
        u64                     nr_wakeups_passive;
        u64                     nr_wakeups_idle;
@@ -9246,7 +9245,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sched.h linux-2.6.31.6-vs2.3.
  #endif
  
  #ifdef CONFIG_FAIR_GROUP_SCHED
-@@ -1335,6 +1345,14 @@ struct task_struct {
+@@ -1393,6 +1402,14 @@ struct task_struct {
  #endif
        seccomp_t seccomp;
  
@@ -9261,7 +9260,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sched.h linux-2.6.31.6-vs2.3.
  /* Thread group tracking */
        u32 parent_exec_id;
        u32 self_exec_id;
-@@ -1559,6 +1577,11 @@ struct pid_namespace;
+@@ -1618,6 +1635,11 @@ struct pid_namespace;
  pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
                        struct pid_namespace *ns);
  
@@ -9273,7 +9272,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sched.h linux-2.6.31.6-vs2.3.
  static inline pid_t task_pid_nr(struct task_struct *tsk)
  {
        return tsk->pid;
-@@ -1572,7 +1595,8 @@ static inline pid_t task_pid_nr_ns(struc
+@@ -1631,7 +1653,8 @@ static inline pid_t task_pid_nr_ns(struc
  
  static inline pid_t task_pid_vnr(struct task_struct *tsk)
  {
@@ -9283,7 +9282,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sched.h linux-2.6.31.6-vs2.3.
  }
  
  
-@@ -1585,7 +1609,7 @@ pid_t task_tgid_nr_ns(struct task_struct
+@@ -1644,7 +1667,7 @@ pid_t task_tgid_nr_ns(struct task_struct
  
  static inline pid_t task_tgid_vnr(struct task_struct *tsk)
  {
@@ -9292,9 +9291,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sched.h linux-2.6.31.6-vs2.3.
  }
  
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/shmem_fs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/shmem_fs.h
---- linux-2.6.31.6/include/linux/shmem_fs.h    2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/shmem_fs.h      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/shmem_fs.h linux-2.6.32-vs2.3.0.36.26/include/linux/shmem_fs.h
+--- linux-2.6.32/include/linux/shmem_fs.h      2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/shmem_fs.h        2009-12-03 20:04:56.000000000 +0100
 @@ -8,6 +8,9 @@
  
  #define SHMEM_NR_DIRECT 16
@@ -9305,9 +9304,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/shmem_fs.h linux-2.6.31.6-vs2
  struct shmem_inode_info {
        spinlock_t              lock;
        unsigned long           flags;
-diff -NurpP --minimal linux-2.6.31.6/include/linux/stat.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/stat.h
---- linux-2.6.31.6/include/linux/stat.h        2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/stat.h  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/stat.h linux-2.6.32-vs2.3.0.36.26/include/linux/stat.h
+--- linux-2.6.32/include/linux/stat.h  2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/stat.h    2009-12-03 20:04:56.000000000 +0100
 @@ -66,6 +66,7 @@ struct kstat {
        unsigned int    nlink;
        uid_t           uid;
@@ -9316,9 +9315,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/stat.h linux-2.6.31.6-vs2.3.0
        dev_t           rdev;
        loff_t          size;
        struct timespec  atime;
-diff -NurpP --minimal linux-2.6.31.6/include/linux/sunrpc/auth.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/sunrpc/auth.h
---- linux-2.6.31.6/include/linux/sunrpc/auth.h 2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/sunrpc/auth.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/sunrpc/auth.h linux-2.6.32-vs2.3.0.36.26/include/linux/sunrpc/auth.h
+--- linux-2.6.32/include/linux/sunrpc/auth.h   2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/sunrpc/auth.h     2009-12-03 20:04:56.000000000 +0100
 @@ -25,6 +25,7 @@
  struct auth_cred {
        uid_t   uid;
@@ -9327,10 +9326,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sunrpc/auth.h linux-2.6.31.6-
        struct group_info *group_info;
        unsigned char machine_cred : 1;
  };
-diff -NurpP --minimal linux-2.6.31.6/include/linux/sunrpc/clnt.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/sunrpc/clnt.h
---- linux-2.6.31.6/include/linux/sunrpc/clnt.h 2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/sunrpc/clnt.h   2009-09-10 16:11:43.000000000 +0200
-@@ -43,7 +43,8 @@ struct rpc_clnt {
+diff -NurpP --minimal linux-2.6.32/include/linux/sunrpc/clnt.h linux-2.6.32-vs2.3.0.36.26/include/linux/sunrpc/clnt.h
+--- linux-2.6.32/include/linux/sunrpc/clnt.h   2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/sunrpc/clnt.h     2009-12-03 20:04:56.000000000 +0100
+@@ -49,7 +49,8 @@ struct rpc_clnt {
        unsigned int            cl_softrtry : 1,/* soft timeouts */
                                cl_discrtry : 1,/* disconnect before retry */
                                cl_autobind : 1,/* use getport() */
@@ -9340,10 +9339,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sunrpc/clnt.h linux-2.6.31.6-
  
        struct rpc_rtt *        cl_rtt;         /* RTO estimator data */
        const struct rpc_timeout *cl_timeout;   /* Timeout strategy */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/syscalls.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/syscalls.h
---- linux-2.6.31.6/include/linux/syscalls.h    2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/syscalls.h      2009-09-10 16:11:43.000000000 +0200
-@@ -428,6 +428,8 @@ asmlinkage long sys_symlink(const char _
+diff -NurpP --minimal linux-2.6.32/include/linux/syscalls.h linux-2.6.32-vs2.3.0.36.26/include/linux/syscalls.h
+--- linux-2.6.32/include/linux/syscalls.h      2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/syscalls.h        2009-12-03 20:04:56.000000000 +0100
+@@ -546,6 +546,8 @@ asmlinkage long sys_symlink(const char _
  asmlinkage long sys_unlink(const char __user *pathname);
  asmlinkage long sys_rename(const char __user *oldname,
                                const char __user *newname);
@@ -9352,10 +9351,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/syscalls.h linux-2.6.31.6-vs2
  asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
  asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/sysctl.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/sysctl.h
---- linux-2.6.31.6/include/linux/sysctl.h      2009-06-11 17:13:18.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/sysctl.h        2009-09-10 16:11:43.000000000 +0200
-@@ -70,6 +70,7 @@ enum
+diff -NurpP --minimal linux-2.6.32/include/linux/sysctl.h linux-2.6.32-vs2.3.0.36.26/include/linux/sysctl.h
+--- linux-2.6.32/include/linux/sysctl.h        2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/sysctl.h  2009-12-03 20:04:56.000000000 +0100
+@@ -69,6 +69,7 @@ enum
        CTL_ABI=9,              /* Binary emulation */
        CTL_CPU=10,             /* CPU stuff (speed scaling, etc) */
        CTL_ARLAN=254,          /* arlan wireless driver */
@@ -9363,7 +9362,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sysctl.h linux-2.6.31.6-vs2.3
        CTL_S390DBF=5677,       /* s390 debug */
        CTL_SUNRPC=7249,        /* sunrpc debug */
        CTL_PM=9899,            /* frv power management */
-@@ -104,6 +105,7 @@ enum
+@@ -103,6 +104,7 @@ enum
  
        KERN_PANIC=15,          /* int: panic timeout */
        KERN_REALROOTDEV=16,    /* real root device to mount after initrd */
@@ -9371,9 +9370,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sysctl.h linux-2.6.31.6-vs2.3
  
        KERN_SPARC_REBOOT=21,   /* reboot command on Sparc */
        KERN_CTLALTDEL=22,      /* int: allow ctl-alt-del to reboot */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/sysfs.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/sysfs.h
---- linux-2.6.31.6/include/linux/sysfs.h       2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/sysfs.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/sysfs.h linux-2.6.32-vs2.3.0.36.26/include/linux/sysfs.h
+--- linux-2.6.32/include/linux/sysfs.h 2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/sysfs.h   2009-12-03 20:04:56.000000000 +0100
 @@ -17,6 +17,8 @@
  #include <linux/list.h>
  #include <asm/atomic.h>
@@ -9383,10 +9382,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/sysfs.h linux-2.6.31.6-vs2.3.
  struct kobject;
  struct module;
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/time.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/time.h
---- linux-2.6.31.6/include/linux/time.h        2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/time.h  2009-09-10 16:11:43.000000000 +0200
-@@ -205,6 +205,9 @@ static __always_inline void timespec_add
+diff -NurpP --minimal linux-2.6.32/include/linux/time.h linux-2.6.32-vs2.3.0.36.26/include/linux/time.h
+--- linux-2.6.32/include/linux/time.h  2009-12-03 20:02:56.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/time.h    2009-12-03 20:04:56.000000000 +0100
+@@ -237,6 +237,9 @@ static __always_inline void timespec_add
        a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
        a->tv_nsec = ns;
  }
@@ -9396,9 +9395,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/time.h linux-2.6.31.6-vs2.3.0
  #endif /* __KERNEL__ */
  
  #define NFDBITS                       __NFDBITS
-diff -NurpP --minimal linux-2.6.31.6/include/linux/types.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/types.h
---- linux-2.6.31.6/include/linux/types.h       2009-09-10 15:26:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/types.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/types.h linux-2.6.32-vs2.3.0.36.26/include/linux/types.h
+--- linux-2.6.32/include/linux/types.h 2009-09-10 15:26:26.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/types.h   2009-12-03 20:04:56.000000000 +0100
 @@ -37,6 +37,9 @@ typedef __kernel_uid32_t     uid_t;
  typedef __kernel_gid32_t      gid_t;
  typedef __kernel_uid16_t        uid16_t;
@@ -9409,9 +9408,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/types.h linux-2.6.31.6-vs2.3.
  
  typedef unsigned long         uintptr_t;
  
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vroot.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vroot.h
---- linux-2.6.31.6/include/linux/vroot.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vroot.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vroot.h linux-2.6.32-vs2.3.0.36.26/include/linux/vroot.h
+--- linux-2.6.32/include/linux/vroot.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vroot.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,51 @@
 +
 +/*
@@ -9464,9 +9463,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vroot.h linux-2.6.31.6-vs2.3.
 +#define VROOT_CLR_DEV         0x5601
 +
 +#endif /* _LINUX_VROOT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_base.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_base.h
---- linux-2.6.31.6/include/linux/vs_base.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_base.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_base.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_base.h
+--- linux-2.6.32/include/linux/vs_base.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_base.h 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,10 @@
 +#ifndef _VS_BASE_H
 +#define _VS_BASE_H
@@ -9478,9 +9477,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_base.h linux-2.6.31.6-vs2.
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_context.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_context.h
---- linux-2.6.31.6/include/linux/vs_context.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_context.h    2009-09-30 02:28:59.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_context.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_context.h
+--- linux-2.6.32/include/linux/vs_context.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_context.h      2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,242 @@
 +#ifndef _VS_CONTEXT_H
 +#define _VS_CONTEXT_H
@@ -9724,9 +9723,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_context.h linux-2.6.31.6-v
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_cowbl.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_cowbl.h
---- linux-2.6.31.6/include/linux/vs_cowbl.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_cowbl.h      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_cowbl.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_cowbl.h
+--- linux-2.6.32/include/linux/vs_cowbl.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_cowbl.h        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,47 @@
 +#ifndef _VS_COWBL_H
 +#define _VS_COWBL_H
@@ -9775,9 +9774,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_cowbl.h linux-2.6.31.6-vs2
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_cvirt.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_cvirt.h
---- linux-2.6.31.6/include/linux/vs_cvirt.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_cvirt.h      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_cvirt.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_cvirt.h
+--- linux-2.6.32/include/linux/vs_cvirt.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_cvirt.h        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,50 @@
 +#ifndef _VS_CVIRT_H
 +#define _VS_CVIRT_H
@@ -9829,9 +9828,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_cvirt.h linux-2.6.31.6-vs2
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_device.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_device.h
---- linux-2.6.31.6/include/linux/vs_device.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_device.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_device.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_device.h
+--- linux-2.6.32/include/linux/vs_device.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_device.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,45 @@
 +#ifndef _VS_DEVICE_H
 +#define _VS_DEVICE_H
@@ -9878,9 +9877,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_device.h linux-2.6.31.6-vs
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_dlimit.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_dlimit.h
---- linux-2.6.31.6/include/linux/vs_dlimit.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_dlimit.h     2009-10-12 02:50:50.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_dlimit.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_dlimit.h
+--- linux-2.6.32/include/linux/vs_dlimit.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_dlimit.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,216 @@
 +#ifndef _VS_DLIMIT_H
 +#define _VS_DLIMIT_H
@@ -10098,10 +10097,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_dlimit.h linux-2.6.31.6-vs
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/base.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/base.h
---- linux-2.6.31.6/include/linux/vserver/base.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/base.h  2009-11-05 04:16:31.000000000 +0100
-@@ -0,0 +1,159 @@
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/base.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/base.h
+--- linux-2.6.32/include/linux/vserver/base.h  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/base.h    2009-12-03 20:04:56.000000000 +0100
+@@ -0,0 +1,170 @@
 +#ifndef _VX_BASE_H
 +#define _VX_BASE_H
 +
@@ -10251,6 +10250,17 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/base.h linux-2.6.31.6
 +#define vx_current_initpid(n) vx_task_initpid(current, n)
 +
 +
++/* context unshare mask */
++
++#define __vx_umask(v)         ((v)->vx_umask)
++
++#define vx_current_umask()    __vx_umask(current_vx_info())
++
++#define vx_can_unshare(b, f) (capable(b) || \
++      (cap_raised(current_cap(), b) && \
++      !((f) & ~vx_current_umask())))
++
++
 +#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
 +
 +#define vx_info_state(v, m)   (__vx_state(v) & (m))
@@ -10261,9 +10271,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/base.h linux-2.6.31.6
 +#define nx_info_state(n, m)   (__nx_state(n) & (m))
 +
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct_cmd.h
---- linux-2.6.31.6/include/linux/vserver/cacct_cmd.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct_cmd.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/cacct_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct_cmd.h
+--- linux-2.6.32/include/linux/vserver/cacct_cmd.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct_cmd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,23 @@
 +#ifndef _VX_CACCT_CMD_H
 +#define _VX_CACCT_CMD_H
@@ -10288,9 +10298,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct_cmd.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_CACCT_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct_def.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct_def.h
---- linux-2.6.31.6/include/linux/vserver/cacct_def.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct_def.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/cacct_def.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct_def.h
+--- linux-2.6.32/include/linux/vserver/cacct_def.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct_def.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,43 @@
 +#ifndef _VX_CACCT_DEF_H
 +#define _VX_CACCT_DEF_H
@@ -10335,9 +10345,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct_def.h linux-2.6
 +#endif
 +
 +#endif        /* _VX_CACCT_DEF_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct.h
---- linux-2.6.31.6/include/linux/vserver/cacct.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/cacct.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct.h
+--- linux-2.6.32/include/linux/vserver/cacct.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,15 @@
 +#ifndef _VX_CACCT_H
 +#define _VX_CACCT_H
@@ -10354,9 +10364,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct.h linux-2.6.31.
 +};
 +
 +#endif        /* _VX_CACCT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct_int.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct_int.h
---- linux-2.6.31.6/include/linux/vserver/cacct_int.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cacct_int.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/cacct_int.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct_int.h
+--- linux-2.6.32/include/linux/vserver/cacct_int.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cacct_int.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,21 @@
 +#ifndef _VX_CACCT_INT_H
 +#define _VX_CACCT_INT_H
@@ -10379,9 +10389,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cacct_int.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_CACCT_INT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/check.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/check.h
---- linux-2.6.31.6/include/linux/vserver/check.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/check.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/check.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/check.h
+--- linux-2.6.32/include/linux/vserver/check.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/check.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,89 @@
 +#ifndef _VS_CHECK_H
 +#define _VS_CHECK_H
@@ -10472,10 +10482,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/check.h linux-2.6.31.
 +#define nx_weak_check(c, m)   ((m) ? nx_check(c, m) : 1)
 +
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/context_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/context_cmd.h
---- linux-2.6.31.6/include/linux/vserver/context_cmd.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/context_cmd.h   2009-09-10 16:11:43.000000000 +0200
-@@ -0,0 +1,128 @@
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/context_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/context_cmd.h
+--- linux-2.6.32/include/linux/vserver/context_cmd.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/context_cmd.h     2009-12-03 20:04:56.000000000 +0100
+@@ -0,0 +1,145 @@
 +#ifndef _VX_CONTEXT_CMD_H
 +#define _VX_CONTEXT_CMD_H
 +
@@ -10589,6 +10599,23 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/context_cmd.h linux-2
 +#endif        /* __KERNEL__ */
 +
 +
++/* umask commands */
++
++#define VCMD_get_umask                VC_CMD(FLAGS, 13, 0)
++#define VCMD_set_umask                VC_CMD(FLAGS, 14, 0)
++
++struct        vcmd_umask {
++      uint64_t umask;
++      uint64_t mask;
++};
++
++#ifdef        __KERNEL__
++extern int vc_get_umask(struct vx_info *, void __user *);
++extern int vc_set_umask(struct vx_info *, void __user *);
++
++#endif        /* __KERNEL__ */
++
++
 +/* OOM badness */
 +
 +#define VCMD_get_badness      VC_CMD(MEMCTRL, 5, 0)
@@ -10604,10 +10631,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/context_cmd.h linux-2
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_CONTEXT_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/context.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/context.h
---- linux-2.6.31.6/include/linux/vserver/context.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/context.h       2009-10-03 01:55:20.000000000 +0200
-@@ -0,0 +1,182 @@
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/context.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/context.h
+--- linux-2.6.32/include/linux/vserver/context.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/context.h 2009-12-03 20:04:56.000000000 +0100
+@@ -0,0 +1,183 @@
 +#ifndef _VX_CONTEXT_H
 +#define _VX_CONTEXT_H
 +
@@ -10670,6 +10697,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/context.h linux-2.6.3
 +#define VXC_SET_UTSNAME               0x00000001
 +#define VXC_SET_RLIMIT                0x00000002
 +#define VXC_FS_SECURITY               0x00000004
++#define VXC_TIOCSTI           0x00000010
 +
 +/* was        VXC_RAW_ICMP            0x00000100 */
 +#define VXC_SYSLOG            0x00001000
@@ -10722,7 +10750,7 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/context.h linux-2.6.3
 +      uint64_t vx_flags;                      /* context flags */
 +      uint64_t vx_ccaps;                      /* context caps (vserver) */
 +      kernel_cap_t vx_bcaps;                  /* bounding caps (system) */
-+      // kernel_cap_t vx_cap_bset;            /* the guest's bset */
++      unsigned long vx_umask;                 /* unshare mask (guest) */
 +
 +      struct task_struct *vx_reaper;          /* guest reaper process */
 +      pid_t vx_initpid;                       /* PID of guest init */
@@ -10790,9 +10818,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/context.h linux-2.6.3
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_CONTEXT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cvirt_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cvirt_cmd.h
---- linux-2.6.31.6/include/linux/vserver/cvirt_cmd.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cvirt_cmd.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/cvirt_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cvirt_cmd.h
+--- linux-2.6.32/include/linux/vserver/cvirt_cmd.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cvirt_cmd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,53 @@
 +#ifndef _VX_CVIRT_CMD_H
 +#define _VX_CVIRT_CMD_H
@@ -10847,9 +10875,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cvirt_cmd.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_CVIRT_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cvirt_def.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cvirt_def.h
---- linux-2.6.31.6/include/linux/vserver/cvirt_def.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cvirt_def.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/cvirt_def.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cvirt_def.h
+--- linux-2.6.32/include/linux/vserver/cvirt_def.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cvirt_def.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,80 @@
 +#ifndef _VX_CVIRT_DEF_H
 +#define _VX_CVIRT_DEF_H
@@ -10931,9 +10959,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cvirt_def.h linux-2.6
 +#endif
 +
 +#endif        /* _VX_CVIRT_DEF_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cvirt.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cvirt.h
---- linux-2.6.31.6/include/linux/vserver/cvirt.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/cvirt.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/cvirt.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cvirt.h
+--- linux-2.6.32/include/linux/vserver/cvirt.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/cvirt.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,20 @@
 +#ifndef _VX_CVIRT_H
 +#define _VX_CVIRT_H
@@ -10955,9 +10983,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/cvirt.h linux-2.6.31.
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_CVIRT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/debug_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/debug_cmd.h
---- linux-2.6.31.6/include/linux/vserver/debug_cmd.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/debug_cmd.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/debug_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/debug_cmd.h
+--- linux-2.6.32/include/linux/vserver/debug_cmd.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/debug_cmd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,58 @@
 +#ifndef _VX_DEBUG_CMD_H
 +#define _VX_DEBUG_CMD_H
@@ -11017,9 +11045,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/debug_cmd.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_DEBUG_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/debug.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/debug.h
---- linux-2.6.31.6/include/linux/vserver/debug.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/debug.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/debug.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/debug.h
+--- linux-2.6.32/include/linux/vserver/debug.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/debug.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,127 @@
 +#ifndef _VX_DEBUG_H
 +#define _VX_DEBUG_H
@@ -11148,9 +11176,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/debug.h linux-2.6.31.
 +
 +
 +#endif /* _VX_DEBUG_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/device_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/device_cmd.h
---- linux-2.6.31.6/include/linux/vserver/device_cmd.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/device_cmd.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/device_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/device_cmd.h
+--- linux-2.6.32/include/linux/vserver/device_cmd.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/device_cmd.h      2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,44 @@
 +#ifndef _VX_DEVICE_CMD_H
 +#define _VX_DEVICE_CMD_H
@@ -11196,9 +11224,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/device_cmd.h linux-2.
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_DEVICE_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/device_def.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/device_def.h
---- linux-2.6.31.6/include/linux/vserver/device_def.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/device_def.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/device_def.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/device_def.h
+--- linux-2.6.32/include/linux/vserver/device_def.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/device_def.h      2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,17 @@
 +#ifndef _VX_DEVICE_DEF_H
 +#define _VX_DEVICE_DEF_H
@@ -11217,9 +11245,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/device_def.h linux-2.
 +};
 +
 +#endif        /* _VX_DEVICE_DEF_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/device.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/device.h
---- linux-2.6.31.6/include/linux/vserver/device.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/device.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/device.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/device.h
+--- linux-2.6.32/include/linux/vserver/device.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/device.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,15 @@
 +#ifndef _VX_DEVICE_H
 +#define _VX_DEVICE_H
@@ -11236,10 +11264,10 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/device.h linux-2.6.31
 +#else /* _VX_DEVICE_H */
 +#warning duplicate inclusion
 +#endif        /* _VX_DEVICE_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/dlimit_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/dlimit_cmd.h
---- linux-2.6.31.6/include/linux/vserver/dlimit_cmd.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/dlimit_cmd.h    2009-09-10 16:11:43.000000000 +0200
-@@ -0,0 +1,74 @@
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/dlimit_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/dlimit_cmd.h
+--- linux-2.6.32/include/linux/vserver/dlimit_cmd.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/dlimit_cmd.h      2009-12-03 20:04:56.000000000 +0100
+@@ -0,0 +1,109 @@
 +#ifndef _VX_DLIMIT_CMD_H
 +#define _VX_DLIMIT_CMD_H
 +
@@ -11271,6 +11299,41 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/dlimit_cmd.h linux-2.
 +#define CDLIM_INFINITY                ((uint32_t)~0UL)
 +#define CDLIM_KEEP            ((uint32_t)~1UL)
 +
++#define DLIME_UNIT    0
++#define DLIME_KILO    1
++#define DLIME_MEGA    2
++#define DLIME_GIGA    3
++
++#define DLIMF_SHIFT   0x10
++
++#define DLIMS_USED    0
++#define DLIMS_TOTAL   2
++
++static inline
++uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
++{
++      int exp = (flags & DLIMF_SHIFT) ?
++              (flags >> shift) & DLIME_GIGA : DLIME_KILO;
++      return val << (10LL * exp);
++}
++
++static inline
++uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
++{
++      int exp = 0;
++
++      if (*flags & DLIMF_SHIFT) {
++              while (val > (1LL << 32) && (exp < 3)) {
++                      val >>= 10LL;
++                      exp++;
++              }
++              *flags &= ~(DLIME_GIGA << shift);
++              *flags |= exp << shift;
++      } else
++              val >>= 10LL;
++      return val;
++}
++
 +#ifdef        __KERNEL__
 +
 +#ifdef        CONFIG_COMPAT
@@ -11314,9 +11377,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/dlimit_cmd.h linux-2.
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_DLIMIT_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/dlimit.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/dlimit.h
---- linux-2.6.31.6/include/linux/vserver/dlimit.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/dlimit.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/dlimit.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/dlimit.h
+--- linux-2.6.32/include/linux/vserver/dlimit.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/dlimit.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,54 @@
 +#ifndef _VX_DLIMIT_H
 +#define _VX_DLIMIT_H
@@ -11372,9 +11435,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/dlimit.h linux-2.6.31
 +#else /* _VX_DLIMIT_H */
 +#warning duplicate inclusion
 +#endif        /* _VX_DLIMIT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/global.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/global.h
---- linux-2.6.31.6/include/linux/vserver/global.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/global.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/global.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/global.h
+--- linux-2.6.32/include/linux/vserver/global.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/global.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,19 @@
 +#ifndef _VX_GLOBAL_H
 +#define _VX_GLOBAL_H
@@ -11395,9 +11458,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/global.h linux-2.6.31
 +
 +
 +#endif /* _VX_GLOBAL_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/history.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/history.h
---- linux-2.6.31.6/include/linux/vserver/history.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/history.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/history.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/history.h
+--- linux-2.6.32/include/linux/vserver/history.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/history.h 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,197 @@
 +#ifndef _VX_HISTORY_H
 +#define _VX_HISTORY_H
@@ -11596,9 +11659,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/history.h linux-2.6.3
 +#endif /* CONFIG_VSERVER_HISTORY */
 +
 +#endif /* _VX_HISTORY_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/inode_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/inode_cmd.h
---- linux-2.6.31.6/include/linux/vserver/inode_cmd.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/inode_cmd.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/inode_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/inode_cmd.h
+--- linux-2.6.32/include/linux/vserver/inode_cmd.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/inode_cmd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,59 @@
 +#ifndef _VX_INODE_CMD_H
 +#define _VX_INODE_CMD_H
@@ -11659,9 +11722,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/inode_cmd.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_INODE_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/inode.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/inode.h
---- linux-2.6.31.6/include/linux/vserver/inode.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/inode.h 2009-10-06 23:34:11.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/inode.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/inode.h
+--- linux-2.6.32/include/linux/vserver/inode.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/inode.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,39 @@
 +#ifndef _VX_INODE_H
 +#define _VX_INODE_H
@@ -11702,9 +11765,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/inode.h linux-2.6.31.
 +#else /* _VX_INODE_H */
 +#warning duplicate inclusion
 +#endif        /* _VX_INODE_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/Kbuild linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/Kbuild
---- linux-2.6.31.6/include/linux/vserver/Kbuild        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/Kbuild  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/Kbuild linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/Kbuild
+--- linux-2.6.32/include/linux/vserver/Kbuild  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/Kbuild    2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,8 @@
 +
 +unifdef-y += context_cmd.h network_cmd.h space_cmd.h \
@@ -11714,9 +11777,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/Kbuild linux-2.6.31.6
 +
 +unifdef-y += switch.h network.h monitor.h inode.h device.h
 +
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit_cmd.h
---- linux-2.6.31.6/include/linux/vserver/limit_cmd.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit_cmd.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/limit_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit_cmd.h
+--- linux-2.6.32/include/linux/vserver/limit_cmd.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit_cmd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,71 @@
 +#ifndef _VX_LIMIT_CMD_H
 +#define _VX_LIMIT_CMD_H
@@ -11789,9 +11852,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit_cmd.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_LIMIT_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit_def.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit_def.h
---- linux-2.6.31.6/include/linux/vserver/limit_def.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit_def.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/limit_def.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit_def.h
+--- linux-2.6.32/include/linux/vserver/limit_def.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit_def.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,47 @@
 +#ifndef _VX_LIMIT_DEF_H
 +#define _VX_LIMIT_DEF_H
@@ -11840,9 +11903,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit_def.h linux-2.6
 +#endif
 +
 +#endif        /* _VX_LIMIT_DEF_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit.h
---- linux-2.6.31.6/include/linux/vserver/limit.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/limit.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit.h
+--- linux-2.6.32/include/linux/vserver/limit.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,70 @@
 +#ifndef _VX_LIMIT_H
 +#define _VX_LIMIT_H
@@ -11914,9 +11977,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit.h linux-2.6.31.
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_LIMIT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit_int.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit_int.h
---- linux-2.6.31.6/include/linux/vserver/limit_int.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/limit_int.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/limit_int.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit_int.h
+--- linux-2.6.32/include/linux/vserver/limit_int.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/limit_int.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,198 @@
 +#ifndef _VX_LIMIT_INT_H
 +#define _VX_LIMIT_INT_H
@@ -12116,9 +12179,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/limit_int.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_LIMIT_INT_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/monitor.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/monitor.h
---- linux-2.6.31.6/include/linux/vserver/monitor.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/monitor.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/monitor.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/monitor.h
+--- linux-2.6.32/include/linux/vserver/monitor.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/monitor.h 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,96 @@
 +#ifndef _VX_MONITOR_H
 +#define _VX_MONITOR_H
@@ -12216,9 +12279,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/monitor.h linux-2.6.3
 +
 +
 +#endif /* _VX_MONITOR_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/network_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/network_cmd.h
---- linux-2.6.31.6/include/linux/vserver/network_cmd.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/network_cmd.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/network_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/network_cmd.h
+--- linux-2.6.32/include/linux/vserver/network_cmd.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/network_cmd.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,150 @@
 +#ifndef _VX_NETWORK_CMD_H
 +#define _VX_NETWORK_CMD_H
@@ -12370,9 +12433,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/network_cmd.h linux-2
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_CONTEXT_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/network.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/network.h
---- linux-2.6.31.6/include/linux/vserver/network.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/network.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/network.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/network.h
+--- linux-2.6.32/include/linux/vserver/network.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/network.h 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,146 @@
 +#ifndef _VX_NETWORK_H
 +#define _VX_NETWORK_H
@@ -12520,9 +12583,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/network.h linux-2.6.3
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_NETWORK_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/percpu.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/percpu.h
---- linux-2.6.31.6/include/linux/vserver/percpu.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/percpu.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/percpu.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/percpu.h
+--- linux-2.6.32/include/linux/vserver/percpu.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/percpu.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,14 @@
 +#ifndef _VX_PERCPU_H
 +#define _VX_PERCPU_H
@@ -12538,9 +12601,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/percpu.h linux-2.6.31
 +#define       PERCPU_PERCTX   (sizeof(struct _vx_percpu))
 +
 +#endif        /* _VX_PERCPU_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/pid.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/pid.h
---- linux-2.6.31.6/include/linux/vserver/pid.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/pid.h   2009-11-05 04:17:16.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/pid.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/pid.h
+--- linux-2.6.32/include/linux/vserver/pid.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/pid.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,51 @@
 +#ifndef _VSERVER_PID_H
 +#define _VSERVER_PID_H
@@ -12593,9 +12656,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/pid.h linux-2.6.31.6-
 +}
 +
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/sched_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/sched_cmd.h
---- linux-2.6.31.6/include/linux/vserver/sched_cmd.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/sched_cmd.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/sched_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/sched_cmd.h
+--- linux-2.6.32/include/linux/vserver/sched_cmd.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/sched_cmd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,108 @@
 +#ifndef _VX_SCHED_CMD_H
 +#define _VX_SCHED_CMD_H
@@ -12705,9 +12768,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/sched_cmd.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_SCHED_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/sched_def.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/sched_def.h
---- linux-2.6.31.6/include/linux/vserver/sched_def.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/sched_def.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/sched_def.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/sched_def.h
+--- linux-2.6.32/include/linux/vserver/sched_def.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/sched_def.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,68 @@
 +#ifndef _VX_SCHED_DEF_H
 +#define _VX_SCHED_DEF_H
@@ -12777,9 +12840,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/sched_def.h linux-2.6
 +#endif
 +
 +#endif        /* _VX_SCHED_DEF_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/sched.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/sched.h
---- linux-2.6.31.6/include/linux/vserver/sched.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/sched.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/sched.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/sched.h
+--- linux-2.6.32/include/linux/vserver/sched.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/sched.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,26 @@
 +#ifndef _VX_SCHED_H
 +#define _VX_SCHED_H
@@ -12807,9 +12870,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/sched.h linux-2.6.31.
 +#else /* _VX_SCHED_H */
 +#warning duplicate inclusion
 +#endif        /* _VX_SCHED_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/signal_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/signal_cmd.h
---- linux-2.6.31.6/include/linux/vserver/signal_cmd.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/signal_cmd.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/signal_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/signal_cmd.h
+--- linux-2.6.32/include/linux/vserver/signal_cmd.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/signal_cmd.h      2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,43 @@
 +#ifndef _VX_SIGNAL_CMD_H
 +#define _VX_SIGNAL_CMD_H
@@ -12854,9 +12917,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/signal_cmd.h linux-2.
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_SIGNAL_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/signal.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/signal.h
---- linux-2.6.31.6/include/linux/vserver/signal.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/signal.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/signal.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/signal.h
+--- linux-2.6.32/include/linux/vserver/signal.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/signal.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,14 @@
 +#ifndef _VX_SIGNAL_H
 +#define _VX_SIGNAL_H
@@ -12872,9 +12935,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/signal.h linux-2.6.31
 +#else /* _VX_SIGNAL_H */
 +#warning duplicate inclusion
 +#endif        /* _VX_SIGNAL_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/space_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/space_cmd.h
---- linux-2.6.31.6/include/linux/vserver/space_cmd.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/space_cmd.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/space_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/space_cmd.h
+--- linux-2.6.32/include/linux/vserver/space_cmd.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/space_cmd.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,38 @@
 +#ifndef _VX_SPACE_CMD_H
 +#define _VX_SPACE_CMD_H
@@ -12914,9 +12977,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/space_cmd.h linux-2.6
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_SPACE_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/space.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/space.h
---- linux-2.6.31.6/include/linux/vserver/space.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/space.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/space.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/space.h
+--- linux-2.6.32/include/linux/vserver/space.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/space.h   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,12 @@
 +#ifndef _VX_SPACE_H
 +#define _VX_SPACE_H
@@ -12930,9 +12993,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/space.h linux-2.6.31.
 +#else /* _VX_SPACE_H */
 +#warning duplicate inclusion
 +#endif        /* _VX_SPACE_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/switch.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/switch.h
---- linux-2.6.31.6/include/linux/vserver/switch.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/switch.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/switch.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/switch.h
+--- linux-2.6.32/include/linux/vserver/switch.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/switch.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,98 @@
 +#ifndef _VX_SWITCH_H
 +#define _VX_SWITCH_H
@@ -13032,9 +13095,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/switch.h linux-2.6.31
 +
 +#endif        /* _VX_SWITCH_H */
 +
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/tag_cmd.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/tag_cmd.h
---- linux-2.6.31.6/include/linux/vserver/tag_cmd.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/tag_cmd.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/tag_cmd.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/tag_cmd.h
+--- linux-2.6.32/include/linux/vserver/tag_cmd.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/tag_cmd.h 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,22 @@
 +#ifndef _VX_TAG_CMD_H
 +#define _VX_TAG_CMD_H
@@ -13058,9 +13121,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/tag_cmd.h linux-2.6.3
 +
 +#endif        /* __KERNEL__ */
 +#endif        /* _VX_TAG_CMD_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/tag.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/tag.h
---- linux-2.6.31.6/include/linux/vserver/tag.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vserver/tag.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vserver/tag.h linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/tag.h
+--- linux-2.6.32/include/linux/vserver/tag.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vserver/tag.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,143 @@
 +#ifndef _DX_TAG_H
 +#define _DX_TAG_H
@@ -13205,9 +13268,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vserver/tag.h linux-2.6.31.6-
 +#endif
 +
 +#endif /* _DX_TAG_H */
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_inet6.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_inet6.h
---- linux-2.6.31.6/include/linux/vs_inet6.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_inet6.h      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_inet6.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_inet6.h
+--- linux-2.6.32/include/linux/vs_inet6.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_inet6.h        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,246 @@
 +#ifndef _VS_INET6_H
 +#define _VS_INET6_H
@@ -13455,9 +13518,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_inet6.h linux-2.6.31.6-vs2
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_inet.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_inet.h
---- linux-2.6.31.6/include/linux/vs_inet.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_inet.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_inet.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_inet.h
+--- linux-2.6.32/include/linux/vs_inet.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_inet.h 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,342 @@
 +#ifndef _VS_INET_H
 +#define _VS_INET_H
@@ -13801,9 +13864,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_inet.h linux-2.6.31.6-vs2.
 +#else
 +// #warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_limit.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_limit.h
---- linux-2.6.31.6/include/linux/vs_limit.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_limit.h      2009-11-05 04:14:38.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_limit.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_limit.h
+--- linux-2.6.32/include/linux/vs_limit.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_limit.h        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,140 @@
 +#ifndef _VS_LIMIT_H
 +#define _VS_LIMIT_H
@@ -13945,9 +14008,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_limit.h linux-2.6.31.6-vs2
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_memory.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_memory.h
---- linux-2.6.31.6/include/linux/vs_memory.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_memory.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_memory.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_memory.h
+--- linux-2.6.32/include/linux/vs_memory.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_memory.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,159 @@
 +#ifndef _VS_MEMORY_H
 +#define _VS_MEMORY_H
@@ -14108,9 +14171,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_memory.h linux-2.6.31.6-vs
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_network.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_network.h
---- linux-2.6.31.6/include/linux/vs_network.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_network.h    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_network.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_network.h
+--- linux-2.6.32/include/linux/vs_network.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_network.h      2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,169 @@
 +#ifndef _NX_VS_NETWORK_H
 +#define _NX_VS_NETWORK_H
@@ -14281,9 +14344,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_network.h linux-2.6.31.6-v
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_pid.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_pid.h
---- linux-2.6.31.6/include/linux/vs_pid.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_pid.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_pid.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_pid.h
+--- linux-2.6.32/include/linux/vs_pid.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_pid.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,95 @@
 +#ifndef _VS_PID_H
 +#define _VS_PID_H
@@ -14380,9 +14443,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_pid.h linux-2.6.31.6-vs2.3
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_sched.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_sched.h
---- linux-2.6.31.6/include/linux/vs_sched.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_sched.h      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_sched.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_sched.h
+--- linux-2.6.32/include/linux/vs_sched.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_sched.h        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,110 @@
 +#ifndef _VS_SCHED_H
 +#define _VS_SCHED_H
@@ -14494,9 +14557,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_sched.h linux-2.6.31.6-vs2
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_socket.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_socket.h
---- linux-2.6.31.6/include/linux/vs_socket.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_socket.h     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_socket.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_socket.h
+--- linux-2.6.32/include/linux/vs_socket.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_socket.h       2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,67 @@
 +#ifndef _VS_SOCKET_H
 +#define _VS_SOCKET_H
@@ -14565,9 +14628,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_socket.h linux-2.6.31.6-vs
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_tag.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_tag.h
---- linux-2.6.31.6/include/linux/vs_tag.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_tag.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_tag.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_tag.h
+--- linux-2.6.32/include/linux/vs_tag.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_tag.h  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,47 @@
 +#ifndef _VS_TAG_H
 +#define _VS_TAG_H
@@ -14610,15 +14673,15 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_tag.h linux-2.6.31.6-vs2.3
 +}
 +
 +struct inode;
-+int dx_permission(struct inode *inode, int mask);
++int dx_permission(const struct inode *inode, int mask);
 +
 +
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_time.h linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_time.h
---- linux-2.6.31.6/include/linux/vs_time.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/linux/vs_time.h       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/linux/vs_time.h linux-2.6.32-vs2.3.0.36.26/include/linux/vs_time.h
+--- linux-2.6.32/include/linux/vs_time.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/linux/vs_time.h 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,19 @@
 +#ifndef _VS_TIME_H
 +#define _VS_TIME_H
@@ -14639,9 +14702,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/linux/vs_time.h linux-2.6.31.6-vs2.
 +#else
 +#warning duplicate inclusion
 +#endif
-diff -NurpP --minimal linux-2.6.31.6/include/net/addrconf.h linux-2.6.31.6-vs2.3.0.36.24/include/net/addrconf.h
---- linux-2.6.31.6/include/net/addrconf.h      2009-06-11 17:13:18.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/net/addrconf.h        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/net/addrconf.h linux-2.6.32-vs2.3.0.36.26/include/net/addrconf.h
+--- linux-2.6.32/include/net/addrconf.h        2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/net/addrconf.h  2009-12-03 20:04:56.000000000 +0100
 @@ -84,7 +84,8 @@ extern int                   ipv6_dev_get_saddr(struct n
                                               struct net_device *dev,
                                               const struct in6_addr *daddr,
@@ -14652,9 +14715,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/net/addrconf.h linux-2.6.31.6-vs2.3
  extern int                    ipv6_get_lladdr(struct net_device *dev,
                                                struct in6_addr *addr,
                                                unsigned char banned_flags);
-diff -NurpP --minimal linux-2.6.31.6/include/net/af_unix.h linux-2.6.31.6-vs2.3.0.36.24/include/net/af_unix.h
---- linux-2.6.31.6/include/net/af_unix.h       2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/net/af_unix.h 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/net/af_unix.h linux-2.6.32-vs2.3.0.36.26/include/net/af_unix.h
+--- linux-2.6.32/include/net/af_unix.h 2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/net/af_unix.h   2009-12-03 20:04:56.000000000 +0100
 @@ -4,6 +4,7 @@
  #include <linux/socket.h>
  #include <linux/un.h>
@@ -14663,9 +14726,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/net/af_unix.h linux-2.6.31.6-vs2.3.
  #include <net/sock.h>
  
  extern void unix_inflight(struct file *fp);
-diff -NurpP --minimal linux-2.6.31.6/include/net/inet_timewait_sock.h linux-2.6.31.6-vs2.3.0.36.24/include/net/inet_timewait_sock.h
---- linux-2.6.31.6/include/net/inet_timewait_sock.h    2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/net/inet_timewait_sock.h      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/net/inet_timewait_sock.h linux-2.6.32-vs2.3.0.36.26/include/net/inet_timewait_sock.h
+--- linux-2.6.32/include/net/inet_timewait_sock.h      2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/net/inet_timewait_sock.h        2009-12-03 20:04:56.000000000 +0100
 @@ -117,6 +117,10 @@ struct inet_timewait_sock {
  #define tw_hash                       __tw_common.skc_hash
  #define tw_prot                       __tw_common.skc_prot
@@ -14677,9 +14740,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/net/inet_timewait_sock.h linux-2.6.
        int                     tw_timeout;
        volatile unsigned char  tw_substate;
        /* 3 bits hole, try to pack */
-diff -NurpP --minimal linux-2.6.31.6/include/net/route.h linux-2.6.31.6-vs2.3.0.36.24/include/net/route.h
---- linux-2.6.31.6/include/net/route.h 2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/net/route.h   2009-11-05 03:48:31.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/include/net/route.h linux-2.6.32-vs2.3.0.36.26/include/net/route.h
+--- linux-2.6.32/include/net/route.h   2009-09-10 15:26:27.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/include/net/route.h     2009-12-03 20:04:56.000000000 +0100
 @@ -135,6 +135,9 @@ static inline void ip_rt_put(struct rtab
                dst_release(&rt->u.dst);
  }
@@ -14726,9 +14789,9 @@ diff -NurpP --minimal linux-2.6.31.6/include/net/route.h linux-2.6.31.6-vs2.3.0.
                err = __ip_route_output_key(net, rp, &fl);
                if (err)
                        return err;
-diff -NurpP --minimal linux-2.6.31.6/include/net/sock.h linux-2.6.31.6-vs2.3.0.36.24/include/net/sock.h
---- linux-2.6.31.6/include/net/sock.h  2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/include/net/sock.h    2009-09-10 17:15:39.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/include/net/sock.h linux-2.6.32-vs2.3.0.36.26/include/net/sock.h
+--- linux-2.6.32/include/net/sock.h    2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/include/net/sock.h      2009-12-03 20:04:56.000000000 +0100
 @@ -139,6 +139,10 @@ struct sock_common {
  #ifdef CONFIG_NET_NS
        struct net              *skc_net;
@@ -14749,12 +14812,12 @@ diff -NurpP --minimal linux-2.6.31.6/include/net/sock.h linux-2.6.31.6-vs2.3.0.3
 +#define sk_nid                        __sk_common.skc_nid
 +#define sk_nx_info            __sk_common.skc_nx_info
        kmemcheck_bitfield_begin(flags);
-       unsigned char           sk_shutdown : 2,
-                               sk_no_check : 2,
-diff -NurpP --minimal linux-2.6.31.6/init/Kconfig linux-2.6.31.6-vs2.3.0.36.24/init/Kconfig
---- linux-2.6.31.6/init/Kconfig        2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/init/Kconfig  2009-10-06 04:38:47.000000000 +0200
-@@ -492,6 +492,19 @@ config CGROUP_SCHED
+       unsigned int            sk_shutdown  : 2,
+                               sk_no_check  : 2,
+diff -NurpP --minimal linux-2.6.32/init/Kconfig linux-2.6.32-vs2.3.0.36.26/init/Kconfig
+--- linux-2.6.32/init/Kconfig  2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/init/Kconfig    2009-12-03 20:04:56.000000000 +0100
+@@ -477,6 +477,19 @@ config CGROUP_SCHED
  
  endchoice
  
@@ -14774,37 +14837,20 @@ diff -NurpP --minimal linux-2.6.31.6/init/Kconfig linux-2.6.31.6-vs2.3.0.36.24/i
  menuconfig CGROUPS
        boolean "Control Group support"
        help
-diff -NurpP --minimal linux-2.6.31.6/init/main.c linux-2.6.31.6-vs2.3.0.36.24/init/main.c
---- linux-2.6.31.6/init/main.c 2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/init/main.c   2009-09-10 16:11:43.000000000 +0200
-@@ -69,6 +69,7 @@
- #include <linux/kmemcheck.h>
- #include <linux/kmemtrace.h>
+diff -NurpP --minimal linux-2.6.32/init/main.c linux-2.6.32-vs2.3.0.36.26/init/main.c
+--- linux-2.6.32/init/main.c   2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/init/main.c     2009-12-03 20:04:56.000000000 +0100
+@@ -70,6 +70,7 @@
+ #include <linux/sfi.h>
+ #include <linux/shmem_fs.h>
  #include <trace/boot.h>
 +#include <linux/vserver/percpu.h>
  
  #include <asm/io.h>
  #include <asm/bugs.h>
-@@ -381,12 +382,14 @@ EXPORT_SYMBOL(__per_cpu_offset);
- static void __init setup_per_cpu_areas(void)
- {
--      unsigned long size, i;
-+      unsigned long size, vspc, i;
-       char *ptr;
-       unsigned long nr_possible_cpus = num_possible_cpus();
-+      vspc = PERCPU_PERCTX * CONFIG_VSERVER_CONTEXTS;
-+
-       /* Copy section for each CPU (we discard the original) */
--      size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
-+      size = ALIGN(PERCPU_ENOUGH_ROOM + vspc, PAGE_SIZE);
-       ptr = alloc_bootmem_pages(size * nr_possible_cpus);
-       for_each_possible_cpu(i) {
-diff -NurpP --minimal linux-2.6.31.6/ipc/mqueue.c linux-2.6.31.6-vs2.3.0.36.24/ipc/mqueue.c
---- linux-2.6.31.6/ipc/mqueue.c        2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/ipc/mqueue.c  2009-09-10 16:31:20.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/ipc/mqueue.c linux-2.6.32-vs2.3.0.36.26/ipc/mqueue.c
+--- linux-2.6.32/ipc/mqueue.c  2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/ipc/mqueue.c    2009-12-03 20:04:56.000000000 +0100
 @@ -33,6 +33,8 @@
  #include <linux/pid.h>
  #include <linux/ipc_namespace.h>
@@ -14886,9 +14932,9 @@ diff -NurpP --minimal linux-2.6.31.6/ipc/mqueue.c linux-2.6.31.6-vs2.3.0.36.24/i
                free_uid(user);
        }
        if (ipc_ns)
-diff -NurpP --minimal linux-2.6.31.6/ipc/msg.c linux-2.6.31.6-vs2.3.0.36.24/ipc/msg.c
---- linux-2.6.31.6/ipc/msg.c   2009-03-24 14:22:44.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/ipc/msg.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/ipc/msg.c linux-2.6.32-vs2.3.0.36.26/ipc/msg.c
+--- linux-2.6.32/ipc/msg.c     2009-03-24 14:22:44.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/ipc/msg.c       2009-12-03 20:04:56.000000000 +0100
 @@ -38,6 +38,7 @@
  #include <linux/rwsem.h>
  #include <linux/nsproxy.h>
@@ -14905,9 +14951,9 @@ diff -NurpP --minimal linux-2.6.31.6/ipc/msg.c linux-2.6.31.6-vs2.3.0.36.24/ipc/
  
        msq->q_perm.security = NULL;
        retval = security_msg_queue_alloc(msq);
-diff -NurpP --minimal linux-2.6.31.6/ipc/namespace.c linux-2.6.31.6-vs2.3.0.36.24/ipc/namespace.c
---- linux-2.6.31.6/ipc/namespace.c     2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/ipc/namespace.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/ipc/namespace.c linux-2.6.32-vs2.3.0.36.26/ipc/namespace.c
+--- linux-2.6.32/ipc/namespace.c       2009-09-10 15:26:27.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/ipc/namespace.c 2009-12-03 20:04:56.000000000 +0100
 @@ -11,6 +11,8 @@
  #include <linux/slab.h>
  #include <linux/fs.h>
@@ -14917,9 +14963,9 @@ diff -NurpP --minimal linux-2.6.31.6/ipc/namespace.c linux-2.6.31.6-vs2.3.0.36.2
  
  #include "util.h"
  
-diff -NurpP --minimal linux-2.6.31.6/ipc/sem.c linux-2.6.31.6-vs2.3.0.36.24/ipc/sem.c
---- linux-2.6.31.6/ipc/sem.c   2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/ipc/sem.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/ipc/sem.c linux-2.6.32-vs2.3.0.36.26/ipc/sem.c
+--- linux-2.6.32/ipc/sem.c     2009-09-10 15:26:27.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/ipc/sem.c       2009-12-03 20:04:56.000000000 +0100
 @@ -83,6 +83,8 @@
  #include <linux/rwsem.h>
  #include <linux/nsproxy.h>
@@ -14957,9 +15003,9 @@ diff -NurpP --minimal linux-2.6.31.6/ipc/sem.c linux-2.6.31.6-vs2.3.0.36.24/ipc/
        security_sem_free(sma);
        ipc_rcu_putref(sma);
  }
-diff -NurpP --minimal linux-2.6.31.6/ipc/shm.c linux-2.6.31.6-vs2.3.0.36.24/ipc/shm.c
---- linux-2.6.31.6/ipc/shm.c   2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/ipc/shm.c     2009-11-05 04:17:37.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/ipc/shm.c linux-2.6.32-vs2.3.0.36.26/ipc/shm.c
+--- linux-2.6.32/ipc/shm.c     2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/ipc/shm.c       2009-12-03 20:04:56.000000000 +0100
 @@ -40,6 +40,8 @@
  #include <linux/mount.h>
  #include <linux/ipc_namespace.h>
@@ -15015,9 +15061,9 @@ diff -NurpP --minimal linux-2.6.31.6/ipc/shm.c linux-2.6.31.6-vs2.3.0.36.24/ipc/
        return error;
  
  no_id:
-diff -NurpP --minimal linux-2.6.31.6/kernel/capability.c linux-2.6.31.6-vs2.3.0.36.24/kernel/capability.c
---- linux-2.6.31.6/kernel/capability.c 2009-03-24 14:22:44.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/capability.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/capability.c linux-2.6.32-vs2.3.0.36.26/kernel/capability.c
+--- linux-2.6.32/kernel/capability.c   2009-03-24 14:22:44.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/capability.c     2009-12-03 20:04:56.000000000 +0100
 @@ -14,6 +14,7 @@
  #include <linux/security.h>
  #include <linux/syscalls.h>
@@ -15053,9 +15099,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/capability.c linux-2.6.31.6-vs2.3.0.
        if (unlikely(!cap_valid(cap))) {
                printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap);
                BUG();
-diff -NurpP --minimal linux-2.6.31.6/kernel/compat.c linux-2.6.31.6-vs2.3.0.36.24/kernel/compat.c
---- linux-2.6.31.6/kernel/compat.c     2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/compat.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/compat.c linux-2.6.32-vs2.3.0.36.26/kernel/compat.c
+--- linux-2.6.32/kernel/compat.c       2009-09-10 15:26:27.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/kernel/compat.c 2009-12-03 20:04:56.000000000 +0100
 @@ -902,7 +902,7 @@ asmlinkage long compat_sys_time(compat_t
        compat_time_t i;
        struct timeval tv;
@@ -15074,13 +15120,13 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/compat.c linux-2.6.31.6-vs2.3.0.36.2
        return 0;
  }
  
-diff -NurpP --minimal linux-2.6.31.6/kernel/exit.c linux-2.6.31.6-vs2.3.0.36.24/kernel/exit.c
---- linux-2.6.31.6/kernel/exit.c       2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/exit.c 2009-10-15 03:49:19.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/exit.c linux-2.6.32-vs2.3.0.36.26/kernel/exit.c
+--- linux-2.6.32/kernel/exit.c 2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/exit.c   2009-12-03 20:04:56.000000000 +0100
 @@ -48,6 +48,10 @@
  #include <linux/fs_struct.h>
  #include <linux/init_task.h>
- #include <linux/perf_counter.h>
+ #include <linux/perf_event.h>
 +#include <linux/vs_limit.h>
 +#include <linux/vs_context.h>
 +#include <linux/vs_network.h>
@@ -15100,15 +15146,16 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/exit.c linux-2.6.31.6-vs2.3.0.36.24/
                }
        }
  }
-@@ -1007,10 +1013,15 @@ NORET_TYPE void do_exit(long code)
-       if (tsk->splice_pipe)
-               __free_pipe_info(tsk->splice_pipe);
+@@ -1011,11 +1017,16 @@ NORET_TYPE void do_exit(long code)
+       validate_creds_for_do_exit(tsk);
  
 +      /* needs to stay after exit_notify() */
 +      exit_vx_info(tsk, code);
 +      exit_nx_info(tsk);
 +
        preempt_disable();
+       exit_rcu();
        /* causes final put_task_struct in finish_task_switch(). */
        tsk->state = TASK_DEAD;
        schedule();
@@ -15116,13 +15163,13 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/exit.c linux-2.6.31.6-vs2.3.0.36.24/
        BUG();
        /* Avoid "noreturn function does return".  */
        for (;;)
-diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/kernel/fork.c
---- linux-2.6.31.6/kernel/fork.c       2009-11-12 12:10:11.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/fork.c 2009-11-05 04:17:43.000000000 +0100
-@@ -62,6 +62,10 @@
- #include <linux/fs_struct.h>
+diff -NurpP --minimal linux-2.6.32/kernel/fork.c linux-2.6.32-vs2.3.0.36.26/kernel/fork.c
+--- linux-2.6.32/kernel/fork.c 2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/fork.c   2009-12-03 20:04:56.000000000 +0100
+@@ -64,6 +64,10 @@
  #include <linux/magic.h>
- #include <linux/perf_counter.h>
+ #include <linux/perf_event.h>
+ #include <linux/posix-timers.h>
 +#include <linux/vs_context.h>
 +#include <linux/vs_network.h>
 +#include <linux/vs_limit.h>
@@ -15130,8 +15177,8 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
  
  #include <asm/pgtable.h>
  #include <asm/pgalloc.h>
-@@ -141,6 +145,8 @@ void free_task(struct task_struct *tsk)
-       prop_local_destroy_single(&tsk->dirties);
+@@ -151,6 +155,8 @@ void free_task(struct task_struct *tsk)
+       account_kernel_stack(tsk->stack, -1);
        free_thread_info(tsk->stack);
        rt_mutex_debug_task_free(tsk);
 +      clr_vx_info(&tsk->vx_info);
@@ -15139,7 +15186,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
        ftrace_graph_exit_task(tsk);
        free_task_struct(tsk);
  }
-@@ -284,6 +290,8 @@ static int dup_mmap(struct mm_struct *mm
+@@ -296,6 +302,8 @@ static int dup_mmap(struct mm_struct *mm
        mm->free_area_cache = oldmm->mmap_base;
        mm->cached_hole_size = ~0UL;
        mm->map_count = 0;
@@ -15148,7 +15195,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
        cpumask_clear(mm_cpumask(mm));
        mm->mm_rb = RB_ROOT;
        rb_link = &mm->mm_rb.rb_node;
-@@ -295,7 +303,7 @@ static int dup_mmap(struct mm_struct *mm
+@@ -310,7 +318,7 @@ static int dup_mmap(struct mm_struct *mm
  
                if (mpnt->vm_flags & VM_DONTCOPY) {
                        long pages = vma_pages(mpnt);
@@ -15157,8 +15204,8 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
                        vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
                                                                -pages);
                        continue;
-@@ -428,8 +436,8 @@ static struct mm_struct * mm_init(struct
-       mm->flags = (current->mm) ? current->mm->flags : default_dump_filter;
+@@ -452,8 +460,8 @@ static struct mm_struct * mm_init(struct
+               (current->mm->flags & MMF_INIT_MASK) : default_dump_filter;
        mm->core_state = NULL;
        mm->nr_ptes = 0;
 -      set_mm_counter(mm, file_rss, 0);
@@ -15166,9 +15213,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
 +      __set_mm_counter(mm, file_rss, 0);
 +      __set_mm_counter(mm, anon_rss, 0);
        spin_lock_init(&mm->page_table_lock);
-       spin_lock_init(&mm->ioctx_lock);
-       INIT_HLIST_HEAD(&mm->ioctx_list);
-@@ -440,6 +448,7 @@ static struct mm_struct * mm_init(struct
+       mm->free_area_cache = TASK_UNMAPPED_BASE;
+       mm->cached_hole_size = ~0UL;
+@@ -463,6 +471,7 @@ static struct mm_struct * mm_init(struct
        if (likely(!mm_alloc_pgd(mm))) {
                mm->def_flags = 0;
                mmu_notifier_mm_init(mm);
@@ -15176,7 +15223,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
                return mm;
        }
  
-@@ -473,6 +482,7 @@ void __mmdrop(struct mm_struct *mm)
+@@ -496,6 +505,7 @@ void __mmdrop(struct mm_struct *mm)
        mm_free_pgd(mm);
        destroy_context(mm);
        mmu_notifier_mm_destroy(mm);
@@ -15184,7 +15231,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
        free_mm(mm);
  }
  EXPORT_SYMBOL_GPL(__mmdrop);
-@@ -605,6 +615,7 @@ struct mm_struct *dup_mm(struct task_str
+@@ -631,6 +641,7 @@ struct mm_struct *dup_mm(struct task_str
                goto fail_nomem;
  
        memcpy(mm, oldmm, sizeof(*mm));
@@ -15192,7 +15239,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
  
        /* Initializing for Swap token stuff */
        mm->token_priority = 0;
-@@ -638,6 +649,7 @@ fail_nocontext:
+@@ -669,6 +680,7 @@ fail_nocontext:
         * If init_new_context() failed, we cannot use mmput() to free the mm
         * because it calls destroy_context()
         */
@@ -15200,7 +15247,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
        mm_free_pgd(mm);
        free_mm(mm);
        return NULL;
-@@ -946,6 +958,8 @@ static struct task_struct *copy_process(
+@@ -980,6 +992,8 @@ static struct task_struct *copy_process(
        int retval;
        struct task_struct *p;
        int cgroup_callbacks_done = 0;
@@ -15209,7 +15256,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
  
        if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
                return ERR_PTR(-EINVAL);
-@@ -982,12 +996,28 @@ static struct task_struct *copy_process(
+@@ -1026,12 +1040,28 @@ static struct task_struct *copy_process(
        DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
        DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
  #endif
@@ -15239,7 +15286,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
        }
  
        retval = copy_creds(p, clone_flags);
-@@ -1260,6 +1290,18 @@ static struct task_struct *copy_process(
+@@ -1300,6 +1330,18 @@ static struct task_struct *copy_process(
  
        total_forks++;
        spin_unlock(&current->sighand->siglock);
@@ -15258,19 +15305,19 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/fork.c linux-2.6.31.6-vs2.3.0.36.24/
        write_unlock_irq(&tasklist_lock);
        proc_fork_connector(p);
        cgroup_post_fork(p);
-@@ -1305,6 +1347,9 @@ bad_fork_cleanup_count:
+@@ -1341,6 +1383,9 @@ bad_fork_cleanup_cgroup:
+ bad_fork_cleanup_count:
        atomic_dec(&p->cred->user->processes);
-       put_cred(p->real_cred);
-       put_cred(p->cred);
+       exit_creds(p);
 +bad_fork_cleanup_vm:
 +      if (p->mm && !(clone_flags & CLONE_VM))
 +              vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm);
  bad_fork_free:
        free_task(p);
  fork_out:
-diff -NurpP --minimal linux-2.6.31.6/kernel/kthread.c linux-2.6.31.6-vs2.3.0.36.24/kernel/kthread.c
---- linux-2.6.31.6/kernel/kthread.c    2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/kthread.c      2009-09-10 16:43:27.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/kthread.c linux-2.6.32-vs2.3.0.36.26/kernel/kthread.c
+--- linux-2.6.32/kernel/kthread.c      2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/kthread.c        2009-12-03 20:04:56.000000000 +0100
 @@ -14,6 +14,7 @@
  #include <linux/file.h>
  #include <linux/module.h>
@@ -15278,10 +15325,10 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/kthread.c linux-2.6.31.6-vs2.3.0.36.
 +#include <linux/vs_pid.h>
  #include <trace/events/sched.h>
  
- #define KTHREAD_NICE_LEVEL (-5)
-diff -NurpP --minimal linux-2.6.31.6/kernel/Makefile linux-2.6.31.6-vs2.3.0.36.24/kernel/Makefile
---- linux-2.6.31.6/kernel/Makefile     2009-09-10 15:26:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/Makefile       2009-09-10 16:11:43.000000000 +0200
+ static DEFINE_SPINLOCK(kthread_create_lock);
+diff -NurpP --minimal linux-2.6.32/kernel/Makefile linux-2.6.32-vs2.3.0.36.26/kernel/Makefile
+--- linux-2.6.32/kernel/Makefile       2009-12-03 20:02:57.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/Makefile 2009-12-03 20:04:56.000000000 +0100
 @@ -23,6 +23,7 @@ CFLAGS_REMOVE_cgroup-debug.o = -pg
  CFLAGS_REMOVE_sched_clock.o = -pg
  endif
@@ -15290,9 +15337,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/Makefile linux-2.6.31.6-vs2.3.0.36.2
  obj-$(CONFIG_FREEZER) += freezer.o
  obj-$(CONFIG_PROFILING) += profile.o
  obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o
-diff -NurpP --minimal linux-2.6.31.6/kernel/nsproxy.c linux-2.6.31.6-vs2.3.0.36.24/kernel/nsproxy.c
---- linux-2.6.31.6/kernel/nsproxy.c    2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/nsproxy.c      2009-09-10 17:37:49.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/nsproxy.c linux-2.6.32-vs2.3.0.36.26/kernel/nsproxy.c
+--- linux-2.6.32/kernel/nsproxy.c      2009-09-10 15:26:28.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/kernel/nsproxy.c        2009-12-03 20:04:56.000000000 +0100
 @@ -19,6 +19,8 @@
  #include <linux/mnt_namespace.h>
  #include <linux/utsname.h>
@@ -15433,7 +15480,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/nsproxy.c linux-2.6.31.6-vs2.3.0.36.
                return 0;
  
 -      if (!capable(CAP_SYS_ADMIN)) {
-+      if (!vx_capable(CAP_SYS_ADMIN, VXC_NAMESPACE)) {
++      if (!vx_can_unshare(CAP_SYS_ADMIN, flags)) {
                err = -EPERM;
                goto out;
        }
@@ -15471,13 +15518,13 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/nsproxy.c linux-2.6.31.6-vs2.3.0.36.
                return 0;
  
 -      if (!capable(CAP_SYS_ADMIN))
-+      if (!vx_capable(CAP_SYS_ADMIN, VXC_NAMESPACE))
++      if (!vx_can_unshare(CAP_SYS_ADMIN, unshare_flags))
                return -EPERM;
  
        *new_nsp = create_new_namespaces(unshare_flags, current,
-diff -NurpP --minimal linux-2.6.31.6/kernel/pid.c linux-2.6.31.6-vs2.3.0.36.24/kernel/pid.c
---- linux-2.6.31.6/kernel/pid.c        2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/pid.c  2009-09-10 16:36:49.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/pid.c linux-2.6.32-vs2.3.0.36.26/kernel/pid.c
+--- linux-2.6.32/kernel/pid.c  2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/pid.c    2009-12-03 20:04:56.000000000 +0100
 @@ -36,6 +36,7 @@
  #include <linux/pid_namespace.h>
  #include <linux/init_task.h>
@@ -15535,9 +15582,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/pid.c linux-2.6.31.6-vs2.3.0.36.24/k
  pid_t pid_vnr(struct pid *pid)
  {
        return pid_nr_ns(pid, current->nsproxy->pid_ns);
-diff -NurpP --minimal linux-2.6.31.6/kernel/pid_namespace.c linux-2.6.31.6-vs2.3.0.36.24/kernel/pid_namespace.c
---- linux-2.6.31.6/kernel/pid_namespace.c      2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/pid_namespace.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/pid_namespace.c linux-2.6.32-vs2.3.0.36.26/kernel/pid_namespace.c
+--- linux-2.6.32/kernel/pid_namespace.c        2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/pid_namespace.c  2009-12-03 20:04:56.000000000 +0100
 @@ -13,6 +13,7 @@
  #include <linux/syscalls.h>
  #include <linux/err.h>
@@ -15562,9 +15609,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/pid_namespace.c linux-2.6.31.6-vs2.3
        kmem_cache_free(pid_ns_cachep, ns);
  }
  
-diff -NurpP --minimal linux-2.6.31.6/kernel/posix-timers.c linux-2.6.31.6-vs2.3.0.36.24/kernel/posix-timers.c
---- linux-2.6.31.6/kernel/posix-timers.c       2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/posix-timers.c 2009-10-24 23:47:04.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/posix-timers.c linux-2.6.32-vs2.3.0.36.26/kernel/posix-timers.c
+--- linux-2.6.32/kernel/posix-timers.c 2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/posix-timers.c   2009-12-03 20:04:56.000000000 +0100
 @@ -46,6 +46,7 @@
  #include <linux/wait.h>
  #include <linux/workqueue.h>
@@ -15573,7 +15620,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/posix-timers.c linux-2.6.31.6-vs2.3.
  
  /*
   * Management arrays for POSIX timers.         Timers are kept in slab memory
-@@ -328,6 +329,7 @@ int posix_timer_event(struct k_itimer *t
+@@ -363,6 +364,7 @@ int posix_timer_event(struct k_itimer *t
  {
        struct task_struct *task;
        int shared, ret = -1;
@@ -15581,7 +15628,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/posix-timers.c linux-2.6.31.6-vs2.3.
        /*
         * FIXME: if ->sigq is queued we can race with
         * dequeue_signal()->do_schedule_next_timer().
-@@ -344,10 +346,18 @@ int posix_timer_event(struct k_itimer *t
+@@ -379,10 +381,18 @@ int posix_timer_event(struct k_itimer *t
        rcu_read_lock();
        task = pid_task(timr->it_pid, PIDTYPE_PID);
        if (task) {
@@ -15600,9 +15647,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/posix-timers.c linux-2.6.31.6-vs2.3.
        /* If we failed to send the signal the timer stops. */
        return ret > 0;
  }
-diff -NurpP --minimal linux-2.6.31.6/kernel/printk.c linux-2.6.31.6-vs2.3.0.36.24/kernel/printk.c
---- linux-2.6.31.6/kernel/printk.c     2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/printk.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/printk.c linux-2.6.32-vs2.3.0.36.26/kernel/printk.c
+--- linux-2.6.32/kernel/printk.c       2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/printk.c 2009-12-03 20:04:56.000000000 +0100
 @@ -33,6 +33,7 @@
  #include <linux/bootmem.h>
  #include <linux/syscalls.h>
@@ -15611,7 +15658,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/printk.c linux-2.6.31.6-vs2.3.0.36.2
  
  #include <asm/uaccess.h>
  
-@@ -270,18 +271,13 @@ int do_syslog(int type, char __user *buf
+@@ -276,18 +277,13 @@ int do_syslog(int type, char __user *buf
        unsigned i, j, limit, count;
        int do_clear = 0;
        char c;
@@ -15632,7 +15679,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/printk.c linux-2.6.31.6-vs2.3.0.36.2
                error = -EINVAL;
                if (!buf || len < 0)
                        goto out;
-@@ -292,6 +288,16 @@ int do_syslog(int type, char __user *buf
+@@ -298,6 +294,16 @@ int do_syslog(int type, char __user *buf
                        error = -EFAULT;
                        goto out;
                }
@@ -15649,7 +15696,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/printk.c linux-2.6.31.6-vs2.3.0.36.2
                error = wait_event_interruptible(log_wait,
                                                        (log_start - log_end));
                if (error)
-@@ -316,16 +322,6 @@ int do_syslog(int type, char __user *buf
+@@ -322,16 +328,6 @@ int do_syslog(int type, char __user *buf
                do_clear = 1;
                /* FALL THRU */
        case 3:         /* Read last kernel messages */
@@ -15666,9 +15713,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/printk.c linux-2.6.31.6-vs2.3.0.36.2
                count = len;
                if (count > log_buf_len)
                        count = log_buf_len;
-diff -NurpP --minimal linux-2.6.31.6/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.24/kernel/ptrace.c
---- linux-2.6.31.6/kernel/ptrace.c     2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/ptrace.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/ptrace.c linux-2.6.32-vs2.3.0.36.26/kernel/ptrace.c
+--- linux-2.6.32/kernel/ptrace.c       2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/ptrace.c 2009-12-03 20:04:56.000000000 +0100
 @@ -22,6 +22,7 @@
  #include <linux/pid_namespace.h>
  #include <linux/syscalls.h>
@@ -15687,9 +15734,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.2
 +              !task_vx_flags(task, VXF_STATE_ADMIN, 0))
 +              return -EACCES;
  
-       return security_ptrace_may_access(task, mode);
+       return security_ptrace_access_check(task, mode);
  }
-@@ -618,6 +624,10 @@ SYSCALL_DEFINE4(ptrace, long, request, l
+@@ -621,6 +627,10 @@ SYSCALL_DEFINE4(ptrace, long, request, l
                goto out;
        }
  
@@ -15700,10 +15747,10 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/ptrace.c linux-2.6.31.6-vs2.3.0.36.2
        if (request == PTRACE_ATTACH) {
                ret = ptrace_attach(child);
                /*
-diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24/kernel/sched.c
---- linux-2.6.31.6/kernel/sched.c      2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/sched.c        2009-11-05 04:17:49.000000000 +0100
-@@ -72,6 +72,8 @@
+diff -NurpP --minimal linux-2.6.32/kernel/sched.c linux-2.6.32-vs2.3.0.36.26/kernel/sched.c
+--- linux-2.6.32/kernel/sched.c        2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/sched.c  2009-12-03 20:04:56.000000000 +0100
+@@ -71,6 +71,8 @@
  #include <linux/debugfs.h>
  #include <linux/ctype.h>
  #include <linux/ftrace.h>
@@ -15712,7 +15759,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
  
  #include <asm/tlb.h>
  #include <asm/irq_regs.h>
-@@ -262,6 +264,15 @@ static DEFINE_MUTEX(sched_domains_mutex)
+@@ -237,6 +239,15 @@ static DEFINE_MUTEX(sched_domains_mutex)
  
  #include <linux/cgroup.h>
  
@@ -15728,19 +15775,17 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
  struct cfs_rq;
  
  static LIST_HEAD(task_groups);
-@@ -282,6 +293,11 @@ struct task_group {
+@@ -257,6 +268,9 @@ struct task_group {
        /* runqueue "owned" by this group on each cpu */
        struct cfs_rq **cfs_rq;
        unsigned long shares;
 +#ifdef CONFIG_CFS_HARD_LIMITS
 +      struct cfs_bandwidth cfs_bandwidth;
-+      /* If set, throttle when the group exceeds its bandwidth */
-+      int hard_limit_enabled;
 +#endif
  #endif
  
  #ifdef CONFIG_RT_GROUP_SCHED
-@@ -477,6 +493,20 @@ struct cfs_rq {
+@@ -446,6 +460,19 @@ struct cfs_rq {
        unsigned long rq_weight;
  #endif
  #endif
@@ -15753,27 +15798,14 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +
 +      /* runtime available to the group on this rq */
 +      u64 cfs_runtime;
++
++      /* Protects the cfs runtime related fields of this cfs_rq */
++      spinlock_t cfs_runtime_lock;
 +#endif
-+      /*
-+       * Number of tasks at this heirarchy.
-+       */
-+      unsigned long nr_tasks_running;
  };
  
  /* Real-Time classes' related field in a runqueue: */
-@@ -661,6 +691,11 @@ struct rq {
-       /* BKL stats */
-       unsigned int bkl_count;
- #endif
-+      /*
-+       * Protects the cfs runtime related fields of all cfs_rqs under
-+       * this rq
-+       */
-+      spinlock_t runtime_lock;
- };
- static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
-@@ -1552,6 +1587,7 @@ update_group_shares_cpu(struct task_grou
+@@ -1607,6 +1634,7 @@ static void update_group_shares_cpu(stru
        }
  }
  
@@ -15781,37 +15813,19 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
  /*
   * Re-compute the task group their per cpu shares over the given domain.
   * This needs to be done in a bottom-up fashion because the rq weight of a
-@@ -1569,9 +1605,11 @@ static int tg_shares_up(struct task_grou
+@@ -1634,8 +1662,10 @@ static int tg_shares_up(struct task_grou
                 * If there are currently no tasks on the cpu pretend there
                 * is one of average load so that when a new task gets to
                 * run here it will not get delayed by group starvation.
 +               * Also if the group is throttled on this cpu, pretend that
 +               * it has no tasks.
                 */
-               weight = tg->cfs_rq[i]->load.weight;
 -              if (!weight)
 +              if (!weight || cfs_rq_throttled(tg->cfs_rq[i]))
                        weight = NICE_0_LOAD;
  
-               tg->cfs_rq[i]->rq_weight = weight;
-@@ -1595,6 +1633,7 @@ static int tg_shares_up(struct task_grou
-  * Compute the cpu's hierarchical load factor for each task group.
-  * This needs to be done in a top-down fashion because the load of a child
-  * group is a fraction of its parents load.
-+ * A throttled group's h_load is set to 0.
-  */
- static int tg_load_down(struct task_group *tg, void *data)
- {
-@@ -1603,6 +1642,8 @@ static int tg_load_down(struct task_grou
-       if (!tg->parent) {
-               load = cpu_rq(cpu)->load.weight;
-+      } else if (cfs_rq_throttled(tg->cfs_rq[cpu])) {
-+              load = 0;
-       } else {
-               load = tg->parent->cfs_rq[cpu]->h_load;
-               load *= tg->cfs_rq[cpu]->shares;
-@@ -1732,6 +1773,187 @@ static void cfs_rq_set_shares(struct cfs
+               rq_weight += weight;
+@@ -1811,6 +1841,175 @@ static void cfs_rq_set_shares(struct cfs
  
  static void calc_load_account_active(struct rq *this_rq);
  
@@ -15863,22 +15877,16 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +      return RUNTIME_INF;
 +}
 +
-+int task_group_throttled(struct task_group *tg, int cpu);
 +void do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b);
 +
-+static inline int cfs_bandwidth_enabled(struct task_group *tg)
-+{
-+      return tg->hard_limit_enabled;
-+}
-+
-+static inline void rq_runtime_lock(struct rq *rq)
++static inline void cfs_rq_runtime_lock(struct cfs_rq *cfs_rq)
 +{
-+      spin_lock(&rq->runtime_lock);
++      spin_lock(&cfs_rq->cfs_runtime_lock);
 +}
 +
-+static inline void rq_runtime_unlock(struct rq *rq)
++static inline void cfs_rq_runtime_unlock(struct cfs_rq *cfs_rq)
 +{
-+      spin_unlock(&rq->runtime_lock);
++      spin_unlock(&cfs_rq->cfs_runtime_lock);
 +}
 +
 +/*
@@ -15904,10 +15912,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +      struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
 +
 +      /*
-+       * Timer isn't setup for groups with infinite runtime or for groups
-+       * for which hard limiting isn't enabled.
++       * Timer isn't setup for groups with infinite runtime
 +       */
-+      if (!cfs_bandwidth_enabled(tg) || (cfs_b->cfs_runtime == RUNTIME_INF))
++      if (cfs_b->cfs_runtime == RUNTIME_INF)
 +              return;
 +
 +      if (hrtimer_active(&cfs_b->cfs_period_timer))
@@ -15941,7 +15948,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +      cfs_rq->cfs_time = 0;
 +      cfs_rq->cfs_throttled = 0;
 +      cfs_rq->cfs_runtime = tg->cfs_bandwidth.cfs_runtime;
-+      tg->hard_limit_enabled = 0;
++      spin_lock_init(&cfs_rq->cfs_runtime_lock);
 +}
 +
 +#else /* !CONFIG_CFS_HARD_LIMITS */
@@ -15961,12 +15968,12 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +      return;
 +}
 +
-+static inline void rq_runtime_lock(struct rq *rq)
++static inline void cfs_rq_runtime_lock(struct cfs_rq *cfs_rq)
 +{
 +      return;
 +}
 +
-+static inline void rq_runtime_unlock(struct rq *rq)
++static inline void cfs_rq_runtime_unlock(struct cfs_rq *cfs_rq)
 +{
 +      return;
 +}
@@ -15974,21 +15981,16 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +#endif /* CONFIG_CFS_HARD_LIMITS */
 +#else /* !CONFIG_FAIR_GROUP_SCHED */
 +
-+static inline void rq_runtime_lock(struct rq *rq)
++static inline void cfs_rq_runtime_lock(struct cfs_rq *cfs_rq)
 +{
 +      return;
 +}
 +
-+static inline void rq_runtime_unlock(struct rq *rq)
++static inline void cfs_rq_runtime_unlock(struct cfs_rq *cfs_rq)
 +{
 +      return;
 +}
 +
-+int task_group_throttled(struct task_group *tg, int cpu)
-+{
-+      return 0;
-+}
-+
 +static inline int cfs_rq_throttled(struct cfs_rq *cfs_rq)
 +{
 +      return 0;
@@ -15999,45 +16001,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
  #include "sched_stats.h"
  #include "sched_idletask.c"
  #include "sched_fair.c"
-@@ -1781,14 +2003,17 @@ static void update_avg(u64 *avg, u64 sam
-       *avg += diff >> 3;
- }
--static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
-+static int enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
- {
-+      int ret;
-+
-       if (wakeup)
-               p->se.start_runtime = p->se.sum_exec_runtime;
-       sched_info_queued(p);
--      p->sched_class->enqueue_task(rq, p, wakeup);
-+      ret = p->sched_class->enqueue_task(rq, p, wakeup);
-       p->se.on_rq = 1;
-+      return ret;
- }
- static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
-@@ -1863,8 +2088,15 @@ static void activate_task(struct rq *rq,
-       if (task_contributes_to_load(p))
-               rq->nr_uninterruptible--;
--      enqueue_task(rq, p, wakeup);
--      inc_nr_running(rq);
-+      /*
-+       * Increment rq->nr_running only if enqueue_task() succeeds.
-+       * enqueue_task() can fail when the task being activated belongs
-+       * to a throttled group. In this case, the task gets enqueued to
-+       * throttled group and the group will be enqueued later when it
-+       * gets unthrottled. rq->nr_running gets incremented at that time.
-+       */
-+      if (!enqueue_task(rq, p, wakeup))
-+              inc_nr_running(rq);
- }
- /*
-@@ -2981,9 +3213,17 @@ EXPORT_SYMBOL(avenrun);
+@@ -2965,9 +3164,17 @@ EXPORT_SYMBOL(avenrun);
   */
  void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
  {
@@ -16058,34 +16022,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
  }
  
  static unsigned long
-@@ -3201,6 +3441,7 @@ int can_migrate_task(struct task_struct 
-        * 1) running (obviously), or
-        * 2) cannot be migrated to this CPU due to cpus_allowed, or
-        * 3) are cache-hot on their current CPU.
-+       * 4) end up in throttled task groups on this CPU.
-        */
-       if (!cpumask_test_cpu(this_cpu, &p->cpus_allowed)) {
-               schedstat_inc(p, se.nr_failed_migrations_affine);
-@@ -3214,6 +3455,18 @@ int can_migrate_task(struct task_struct 
-       }
-       /*
-+       * Don't migrate the task if it belongs to a
-+       * - throttled group on its current cpu
-+       * - throttled group on this_cpu
-+       * - group whose hierarchy is throttled on this_cpu
-+       */
-+      if (cfs_rq_throttled(cfs_rq_of(&p->se)) ||
-+              task_group_throttled(task_group(p), this_cpu)) {
-+              schedstat_inc(p, se.nr_failed_migrations_throttled);
-+              return 0;
-+      }
-+
-+      /*
-        * Aggressive migration if:
-        * 1) task is cache cold, or
-        * 2) too many balance attempts have failed.
-@@ -4912,16 +5165,19 @@ void account_user_time(struct task_struc
+@@ -5006,16 +5213,19 @@ void account_user_time(struct task_struc
                       cputime_t cputime_scaled)
  {
        struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
@@ -16106,7 +16043,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
                cpustat->nice = cputime64_add(cpustat->nice, tmp);
        else
                cpustat->user = cputime64_add(cpustat->user, tmp);
-@@ -4967,6 +5223,7 @@ void account_system_time(struct task_str
+@@ -5061,6 +5271,7 @@ void account_system_time(struct task_str
                         cputime_t cputime, cputime_t cputime_scaled)
  {
        struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
@@ -16114,7 +16051,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
        cputime64_t tmp;
  
        if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
-@@ -4977,6 +5234,7 @@ void account_system_time(struct task_str
+@@ -5071,6 +5282,7 @@ void account_system_time(struct task_str
        /* Add system time to process. */
        p->stime = cputime_add(p->stime, cputime);
        p->stimescaled = cputime_add(p->stimescaled, cputime_scaled);
@@ -16122,51 +16059,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
        account_group_system_time(p, cputime);
  
        /* Add system time to cpustat. */
-@@ -5896,8 +6154,10 @@ void rt_mutex_setprio(struct task_struct
-       oldprio = p->prio;
-       on_rq = p->se.on_rq;
-       running = task_current(rq, p);
--      if (on_rq)
-+      if (on_rq) {
-               dequeue_task(rq, p, 0);
-+              dec_nr_running(rq);
-+      }
-       if (running)
-               p->sched_class->put_prev_task(rq, p);
-@@ -5911,7 +6171,8 @@ void rt_mutex_setprio(struct task_struct
-       if (running)
-               p->sched_class->set_curr_task(rq);
-       if (on_rq) {
--              enqueue_task(rq, p, 0);
-+              if (!enqueue_task(rq, p, 0))
-+                      inc_nr_running(rq);
-               check_class_changed(rq, p, prev_class, oldprio, running);
-       }
-@@ -5945,8 +6206,10 @@ void set_user_nice(struct task_struct *p
-               goto out_unlock;
-       }
-       on_rq = p->se.on_rq;
--      if (on_rq)
-+      if (on_rq) {
-               dequeue_task(rq, p, 0);
-+              dec_nr_running(rq);
-+      }
-       p->static_prio = NICE_TO_PRIO(nice);
-       set_load_weight(p);
-@@ -5955,7 +6218,8 @@ void set_user_nice(struct task_struct *p
-       delta = p->prio - old_prio;
-       if (on_rq) {
--              enqueue_task(rq, p, 0);
-+              if (!enqueue_task(rq, p, 0))
-+                      inc_nr_running(rq);
-               /*
-                * If the task increased its priority or is running and
-                * lowered its priority, then reschedule its CPU:
-@@ -6012,7 +6276,7 @@ SYSCALL_DEFINE1(nice, int, increment)
+@@ -6106,7 +6318,7 @@ SYSCALL_DEFINE1(nice, int, increment)
                nice = 19;
  
        if (increment < 0 && !can_nice(current, nice))
@@ -16175,7 +16068,40 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
  
        retval = security_task_setnice(current, nice);
        if (retval)
-@@ -9119,6 +9383,7 @@ static void init_tg_cfs_entry(struct tas
+@@ -9164,6 +9376,32 @@ static int update_sched_domains(struct n
+ }
+ #endif
++#ifdef CONFIG_SMP
++static void disable_runtime(struct rq *rq)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&rq->lock, flags);
++#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_CFS_HARD_LIMITS)
++      disable_runtime_cfs(rq);
++#endif
++      disable_runtime_rt(rq);
++      spin_unlock_irqrestore(&rq->lock, flags);
++}
++
++static void enable_runtime(struct rq *rq)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&rq->lock, flags);
++#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_CFS_HARD_LIMITS)
++      enable_runtime_cfs(rq);
++#endif
++      enable_runtime_rt(rq);
++      spin_unlock_irqrestore(&rq->lock, flags);
++}
++#endif
++
+ static int update_runtime(struct notifier_block *nfb,
+                               unsigned long action, void *hcpu)
+ {
+@@ -9296,6 +9534,7 @@ static void init_tg_cfs_entry(struct tas
        struct rq *rq = cpu_rq(cpu);
        tg->cfs_rq[cpu] = cfs_rq;
        init_cfs_rq(cfs_rq, rq);
@@ -16183,7 +16109,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
        cfs_rq->tg = tg;
        if (add)
                list_add(&cfs_rq->leaf_cfs_rq_list, &rq->leaf_cfs_rq_list);
-@@ -9248,6 +9513,10 @@ void __init sched_init(void)
+@@ -9425,6 +9664,10 @@ void __init sched_init(void)
  #endif /* CONFIG_USER_SCHED */
  #endif /* CONFIG_RT_GROUP_SCHED */
  
@@ -16194,15 +16120,15 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
  #ifdef CONFIG_GROUP_SCHED
        list_add(&init_task_group.list, &task_groups);
        INIT_LIST_HEAD(&init_task_group.children);
-@@ -9264,6 +9533,7 @@ void __init sched_init(void)
-               rq = cpu_rq(i);
-               spin_lock_init(&rq->lock);
-+              spin_lock_init(&rq->runtime_lock);
-               rq->nr_running = 0;
-               rq->calc_load_active = 0;
-               rq->calc_load_update = jiffies + LOAD_FREQ;
-@@ -9537,6 +9807,7 @@ static void free_fair_sched_group(struct
+@@ -9451,6 +9694,7 @@ void __init sched_init(void)
+               init_cfs_rq(&rq->cfs, rq);
+               init_rt_rq(&rq->rt, rq);
+ #ifdef CONFIG_FAIR_GROUP_SCHED
++              init_cfs_hard_limits(&rq->cfs, &init_task_group);
+               init_task_group.shares = init_task_group_load;
+               INIT_LIST_HEAD(&rq->leaf_cfs_rq_list);
+ #ifdef CONFIG_CGROUP_SCHED
+@@ -9726,6 +9970,7 @@ static void free_fair_sched_group(struct
  {
        int i;
  
@@ -16210,7 +16136,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
        for_each_possible_cpu(i) {
                if (tg->cfs_rq)
                        kfree(tg->cfs_rq[i]);
-@@ -9563,6 +9834,7 @@ int alloc_fair_sched_group(struct task_g
+@@ -9752,6 +9997,7 @@ int alloc_fair_sched_group(struct task_g
        if (!tg->se)
                goto err;
  
@@ -16218,29 +16144,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
        tg->shares = NICE_0_LOAD;
  
        for_each_possible_cpu(i) {
-@@ -9795,8 +10067,10 @@ void sched_move_task(struct task_struct 
-       running = task_current(rq, tsk);
-       on_rq = tsk->se.on_rq;
--      if (on_rq)
-+      if (on_rq) {
-               dequeue_task(rq, tsk, 0);
-+              dec_nr_running(rq);
-+      }
-       if (unlikely(running))
-               tsk->sched_class->put_prev_task(rq, tsk);
-@@ -9810,7 +10084,8 @@ void sched_move_task(struct task_struct 
-       if (unlikely(running))
-               tsk->sched_class->set_curr_task(rq);
-       if (on_rq)
--              enqueue_task(rq, tsk, 0);
-+              if (!enqueue_task(rq, tsk, 0))
-+                      inc_nr_running(rq);
-       task_rq_unlock(rq, &flags);
- }
-@@ -10257,6 +10532,134 @@ static u64 cpu_shares_read_u64(struct cg
+@@ -10475,6 +10721,100 @@ static u64 cpu_shares_read_u64(struct cg
  
        return (u64) tg->shares;
  }
@@ -16250,7 +16154,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +static int tg_set_cfs_bandwidth(struct task_group *tg,
 +              u64 cfs_period, u64 cfs_runtime)
 +{
-+      int i, err = 0;
++      int i;
 +
 +      spin_lock_irq(&tg->cfs_bandwidth.cfs_runtime_lock);
 +      tg->cfs_bandwidth.cfs_period = ns_to_ktime(cfs_period);
@@ -16259,14 +16163,14 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +      for_each_possible_cpu(i) {
 +              struct cfs_rq *cfs_rq = tg->cfs_rq[i];
 +
-+              rq_runtime_lock(rq_of(cfs_rq));
++              cfs_rq_runtime_lock(cfs_rq);
 +              cfs_rq->cfs_runtime = cfs_runtime;
-+              rq_runtime_unlock(rq_of(cfs_rq));
++              cfs_rq_runtime_unlock(cfs_rq);
 +      }
 +
 +      start_cfs_bandwidth(tg);
 +      spin_unlock_irq(&tg->cfs_bandwidth.cfs_runtime_lock);
-+      return err;
++      return 0;
 +}
 +
 +int tg_set_cfs_runtime(struct task_group *tg, long cfs_runtime_us)
@@ -16315,29 +16219,6 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +      return cfs_period_us;
 +}
 +
-+int tg_set_hard_limit_enabled(struct task_group *tg, u64 val)
-+{
-+      local_irq_disable();
-+      spin_lock(&tg->cfs_bandwidth.cfs_runtime_lock);
-+      if (val > 0) {
-+              tg->hard_limit_enabled = 1;
-+              start_cfs_bandwidth(tg);
-+              spin_unlock(&tg->cfs_bandwidth.cfs_runtime_lock);
-+      } else {
-+              destroy_cfs_bandwidth(tg);
-+              tg->hard_limit_enabled = 0;
-+              spin_unlock(&tg->cfs_bandwidth.cfs_runtime_lock);
-+              /*
-+               * Hard limiting is being disabled for this group.
-+               * Refresh runtimes and put the throttled entities
-+               * of the group back onto runqueue.
-+               */
-+              do_sched_cfs_period_timer(&tg->cfs_bandwidth);
-+      }
-+      local_irq_enable();
-+      return 0;
-+}
-+
 +static s64 cpu_cfs_runtime_read_s64(struct cgroup *cgrp, struct cftype *cft)
 +{
 +      return tg_get_cfs_runtime(cgroup_tg(cgrp));
@@ -16360,22 +16241,11 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +      return tg_set_cfs_period(cgroup_tg(cgrp), cfs_period_us);
 +}
 +
-+static u64 cpu_cfs_hard_limit_read_u64(struct cgroup *cgrp, struct cftype *cft)
-+{
-+      return cfs_bandwidth_enabled(cgroup_tg(cgrp));
-+}
-+
-+static int cpu_cfs_hard_limit_write_u64(struct cgroup *cgrp,
-+              struct cftype *cftype, u64 val)
-+{
-+      return tg_set_hard_limit_enabled(cgroup_tg(cgrp), val);
-+}
-+
 +#endif /* CONFIG_CFS_HARD_LIMITS */
  #endif /* CONFIG_FAIR_GROUP_SCHED */
  
  #ifdef CONFIG_RT_GROUP_SCHED
-@@ -10290,6 +10693,23 @@ static struct cftype cpu_files[] = {
+@@ -10508,6 +10848,18 @@ static struct cftype cpu_files[] = {
                .read_u64 = cpu_shares_read_u64,
                .write_u64 = cpu_shares_write_u64,
        },
@@ -16390,18 +16260,13 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched.c linux-2.6.31.6-vs2.3.0.36.24
 +              .read_u64 = cpu_cfs_period_read_u64,
 +              .write_u64 = cpu_cfs_period_write_u64,
 +      },
-+      {
-+              .name = "cfs_hard_limit",
-+              .read_u64 = cpu_cfs_hard_limit_read_u64,
-+              .write_u64 = cpu_cfs_hard_limit_write_u64,
-+      },
 +#endif /* CONFIG_CFS_HARD_LIMITS */
  #endif
  #ifdef CONFIG_RT_GROUP_SCHED
        {
-diff -NurpP --minimal linux-2.6.31.6/kernel/sched_debug.c linux-2.6.31.6-vs2.3.0.36.24/kernel/sched_debug.c
---- linux-2.6.31.6/kernel/sched_debug.c        2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/sched_debug.c  2009-10-06 04:39:26.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/sched_debug.c linux-2.6.32-vs2.3.0.36.26/kernel/sched_debug.c
+--- linux-2.6.32/kernel/sched_debug.c  2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/sched_debug.c    2009-12-03 20:04:56.000000000 +0100
 @@ -80,6 +80,11 @@ static void print_cfs_group_stats(struct
        PN(se->wait_max);
        PN(se->wait_sum);
@@ -16414,12 +16279,10 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_debug.c linux-2.6.31.6-vs2.3.0
  #endif
        P(se->load.weight);
  #undef PN
-@@ -214,6 +219,18 @@ void print_cfs_rq(struct seq_file *m, in
+@@ -214,6 +219,16 @@ void print_cfs_rq(struct seq_file *m, in
  #ifdef CONFIG_SMP
        SEQ_printf(m, "  .%-30s: %lu\n", "shares", cfs_rq->shares);
  #endif
-+      SEQ_printf(m, "  .%-30s: %ld\n", "nr_tasks_running",
-+                      cfs_rq->nr_tasks_running);
 +#ifdef CONFIG_CFS_HARD_LIMITS
 +      spin_lock_irqsave(&rq->lock, flags);
 +      SEQ_printf(m, "  .%-30s: %d\n", "cfs_throttled",
@@ -16429,11 +16292,11 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_debug.c linux-2.6.31.6-vs2.3.0
 +      SEQ_printf(m, "  .%-30s: %Ld.%06ld\n", "cfs_runtime",
 +                      SPLIT_NS(cfs_rq->cfs_runtime));
 +      spin_unlock_irqrestore(&rq->lock, flags);
-+#endif
++#endif /* CONFIG_CFS_HARD_LIMITS */
        print_cfs_group_stats(m, cpu, cfs_rq->tg);
  #endif
  }
-@@ -310,7 +327,7 @@ static int sched_debug_show(struct seq_f
+@@ -310,7 +325,7 @@ static int sched_debug_show(struct seq_f
        u64 now = ktime_to_ns(ktime_get());
        int cpu;
  
@@ -16442,29 +16305,14 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_debug.c linux-2.6.31.6-vs2.3.0
                init_utsname()->release,
                (int)strcspn(init_utsname()->version, " "),
                init_utsname()->version);
-@@ -415,6 +432,7 @@ void proc_sched_show_task(struct task_st
-       P(se.nr_failed_migrations_affine);
-       P(se.nr_failed_migrations_running);
-       P(se.nr_failed_migrations_hot);
-+      P(se.nr_failed_migrations_throttled);
-       P(se.nr_forced_migrations);
-       P(se.nr_forced2_migrations);
-       P(se.nr_wakeups);
-@@ -489,6 +507,7 @@ void proc_sched_set_task(struct task_str
-       p->se.nr_failed_migrations_affine       = 0;
-       p->se.nr_failed_migrations_running      = 0;
-       p->se.nr_failed_migrations_hot          = 0;
-+      p->se.nr_failed_migrations_throttled    = 0;
-       p->se.nr_forced_migrations              = 0;
-       p->se.nr_forced2_migrations             = 0;
-       p->se.nr_wakeups                        = 0;
-diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.36.24/kernel/sched_fair.c
---- linux-2.6.31.6/kernel/sched_fair.c 2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/sched_fair.c   2009-10-06 04:39:37.000000000 +0200
-@@ -186,6 +186,286 @@ find_matching_se(struct sched_entity **s
+diff -NurpP --minimal linux-2.6.32/kernel/sched_fair.c linux-2.6.32-vs2.3.0.36.26/kernel/sched_fair.c
+--- linux-2.6.32/kernel/sched_fair.c   2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/sched_fair.c     2009-12-03 20:04:56.000000000 +0100
+@@ -189,7 +189,308 @@ find_matching_se(struct sched_entity **s
        }
  }
  
+-#else /* !CONFIG_FAIR_GROUP_SCHED */
 +#ifdef CONFIG_CFS_HARD_LIMITS
 +
 +static inline void update_stats_throttle_start(struct cfs_rq *cfs_rq,
@@ -16484,38 +16332,11 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 +      schedstat_set(se->throttle_start, 0);
 +}
 +
-+static void double_rq_runtime_lock(struct rq *rq1, struct rq *rq2)
-+      __acquires(rq1->runtime_lock)
-+      __acquires(rq2->runtime_lock)
-+{
-+      BUG_ON(!irqs_disabled());
-+      if (rq1 == rq2) {
-+              spin_lock(&rq1->runtime_lock);
-+              __acquire(rq2->runtime_lock);   /* Fake it out ;) */
-+      } else {
-+              if (rq1 < rq2) {
-+                      spin_lock(&rq1->runtime_lock);
-+                      spin_lock_nested(&rq2->runtime_lock,
-+                                      SINGLE_DEPTH_NESTING);
-+              } else {
-+                      spin_lock(&rq2->runtime_lock);
-+                      spin_lock_nested(&rq1->runtime_lock,
-+                                      SINGLE_DEPTH_NESTING);
-+              }
-+      }
-+      update_rq_clock(rq1);
-+      update_rq_clock(rq2);
-+}
-+
-+static void double_rq_runtime_unlock(struct rq *rq1, struct rq *rq2)
-+      __releases(rq1->runtime_lock)
-+      __releases(rq2->runtime_lock)
++static inline
++struct cfs_rq *sched_cfs_period_cfs_rq(struct cfs_bandwidth *cfs_b, int cpu)
 +{
-+      spin_unlock(&rq1->runtime_lock);
-+      if (rq1 != rq2)
-+              spin_unlock(&rq2->runtime_lock);
-+      else
-+              __release(rq2->runtime_lock);
++      return container_of(cfs_b, struct task_group,
++                      cfs_bandwidth)->cfs_rq[cpu];
 +}
 +
 +static inline int cfs_rq_throttled(struct cfs_rq *cfs_rq)
@@ -16523,35 +16344,137 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 +      return cfs_rq->cfs_throttled;
 +}
 +
++#ifdef CONFIG_SMP
 +/*
-+ * Ran out of runtime, check if we can borrow some from others
-+ * instead of getting throttled right away.
++ * Ensure this RQ takes back all the runtime it lend to its neighbours.
++ */
++static void disable_runtime_cfs(struct rq *rq)
++{
++      struct root_domain *rd = rq->rd;
++      struct cfs_rq *cfs_rq;
++
++      if (unlikely(!scheduler_running))
++              return;
++
++      for_each_leaf_cfs_rq(rq, cfs_rq) {
++              struct cfs_bandwidth *cfs_b = &cfs_rq->tg->cfs_bandwidth;
++              s64 want;
++              int i;
++
++              spin_lock(&cfs_b->cfs_runtime_lock);
++              spin_lock(&cfs_rq->cfs_runtime_lock);
++
++              /*
++               * Either we're all are infinity and nobody needs to borrow,
++               * or we're already disabled and this have nothing to do, or
++               * we have exactly the right amount of runtime to take out.
++               */
++               if (cfs_rq->cfs_runtime == RUNTIME_INF ||
++                              cfs_rq->cfs_runtime == cfs_b->cfs_runtime)
++                      goto balanced;
++              spin_unlock(&cfs_rq->cfs_runtime_lock);
++
++              /*
++               * Calculate the difference between what we started out with
++               * and what we current have, that's the amount of runtime
++               * we lend and now have to reclaim.
++               */
++               want = cfs_b->cfs_runtime - cfs_rq->cfs_runtime;
++
++              /*
++               * Greedy reclaim, take back as much as possible.
++               */
++              for_each_cpu(i, rd->span) {
++                      struct cfs_rq *iter = sched_cfs_period_cfs_rq(cfs_b, i);
++                      s64 diff;
++
++                      /*
++                       * Can't reclaim from ourselves or disabled runqueues.
++                       */
++                      if (iter == cfs_rq || iter->cfs_runtime == RUNTIME_INF)
++                              continue;
++
++                      spin_lock(&iter->cfs_runtime_lock);
++                      if (want > 0) {
++                              diff = min_t(s64, iter->cfs_runtime, want);
++                              iter->cfs_runtime -= diff;
++                              want -= diff;
++                      } else {
++                              iter->cfs_runtime -= want;
++                              want -= want;
++                      }
++
++                      spin_unlock(&iter->cfs_runtime_lock);
++                      if (!want)
++                              break;
++              }
++
++              spin_lock(&cfs_rq->cfs_runtime_lock);
++              /*
++               * We cannot be left wanting - that would mean some
++               * runtime leaked out of the system.
++               */
++              BUG_ON(want);
++balanced:
++              /*
++               * Disable all the borrow logic by pretending we have infinite
++               * runtime - in which case borrowing doesn't make sense.
++               */
++               cfs_rq->cfs_runtime = RUNTIME_INF;
++               spin_unlock(&cfs_rq->cfs_runtime_lock);
++               spin_unlock(&cfs_b->cfs_runtime_lock);
++      }
++}
++
++static void enable_runtime_cfs(struct rq *rq)
++{
++      struct cfs_rq *cfs_rq;
++
++      if (unlikely(!scheduler_running))
++              return;
++
++      /*
++       * Reset each runqueue's bandwidth settings
++       */
++      for_each_leaf_cfs_rq(rq, cfs_rq) {
++              struct cfs_bandwidth *cfs_b = &cfs_rq->tg->cfs_bandwidth;
++
++              spin_lock(&cfs_b->cfs_runtime_lock);
++              spin_lock(&cfs_rq->cfs_runtime_lock);
++              cfs_rq->cfs_runtime = cfs_b->cfs_runtime;
++              cfs_rq->cfs_time = 0;
++              cfs_rq->cfs_throttled = 0;
++              spin_unlock(&cfs_rq->cfs_runtime_lock);
++              spin_unlock(&cfs_b->cfs_runtime_lock);
++      }
++}
++
++/*
++ * Ran out of runtime, check if we can borrow some from others
++ * instead of getting throttled right away.
 + */
 +static void do_cfs_balance_runtime(struct cfs_rq *cfs_rq)
 +{
-+      struct rq *rq = rq_of(cfs_rq);
 +      struct cfs_bandwidth *cfs_b = &cfs_rq->tg->cfs_bandwidth;
 +      const struct cpumask *span = sched_bw_period_mask();
 +      int i, weight;
 +      u64 cfs_period;
-+      struct task_group *tg = container_of(cfs_b, struct task_group,
-+                              cfs_bandwidth);
 +
 +      weight = cpumask_weight(span);
 +      spin_lock(&cfs_b->cfs_runtime_lock);
 +      cfs_period = ktime_to_ns(cfs_b->cfs_period);
 +
 +      for_each_cpu(i, span) {
-+              struct cfs_rq *borrow_cfs_rq = tg->cfs_rq[i];
-+              struct rq *borrow_rq = rq_of(borrow_cfs_rq);
++              struct cfs_rq *borrow_cfs_rq =
++                              sched_cfs_period_cfs_rq(cfs_b, i);
 +              s64 diff;
 +
 +              if (borrow_cfs_rq == cfs_rq)
 +                      continue;
 +
-+              double_rq_runtime_lock(rq, borrow_rq);
++              cfs_rq_runtime_lock(borrow_cfs_rq);
 +              if (borrow_cfs_rq->cfs_runtime == RUNTIME_INF) {
-+                      double_rq_runtime_unlock(rq, borrow_rq);
++                      cfs_rq_runtime_unlock(borrow_cfs_rq);
 +                      continue;
 +              }
 +
@@ -16563,11 +16486,11 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 +                      borrow_cfs_rq->cfs_runtime -= diff;
 +                      cfs_rq->cfs_runtime += diff;
 +                      if (cfs_rq->cfs_runtime == cfs_period) {
-+                              double_rq_runtime_unlock(rq, borrow_rq);
++                              cfs_rq_runtime_unlock(borrow_cfs_rq);
 +                              break;
 +                      }
 +              }
-+              double_rq_runtime_unlock(rq, borrow_rq);
++              cfs_rq_runtime_unlock(borrow_cfs_rq);
 +      }
 +      spin_unlock(&cfs_b->cfs_runtime_lock);
 +}
@@ -16577,12 +16500,18 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 + */
 +static void cfs_balance_runtime(struct cfs_rq *cfs_rq)
 +{
-+      struct rq *rq = rq_of(cfs_rq);
-+
-+      rq_runtime_unlock(rq);
++      cfs_rq_runtime_unlock(cfs_rq);
 +      do_cfs_balance_runtime(cfs_rq);
-+      rq_runtime_lock(rq);
++      cfs_rq_runtime_lock(cfs_rq);
++}
++
++#else /* !CONFIG_SMP */
++
++static void cfs_balance_runtime(struct cfs_rq *cfs_rq)
++{
++      return;
 +}
++#endif /* CONFIG_SMP */
 +
 +/*
 + * Check if group entity exceeded its runtime. If so, mark the cfs_rq as
@@ -16595,9 +16524,6 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 +
 +      cfs_rq = group_cfs_rq(se);
 +
-+      if (!cfs_bandwidth_enabled(cfs_rq->tg))
-+              return;
-+
 +      if (cfs_rq->cfs_runtime == RUNTIME_INF)
 +              return;
 +
@@ -16616,76 +16542,25 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 +      }
 +}
 +
-+/*
-+ * Check if the entity is throttled.
-+ */
-+static int entity_throttled(struct sched_entity *se)
++static inline void update_curr_group(struct sched_entity *curr,
++              unsigned long delta_exec, struct task_struct *tsk_curr)
 +{
-+      struct cfs_rq *cfs_rq;
-+
-+      /* Only group entities can be throttled */
-+      if (entity_is_task(se))
-+              return 0;
-+
-+      cfs_rq = group_cfs_rq(se);
-+      if (cfs_rq_throttled(cfs_rq))
-+              return 1;
-+      return 0;
-+}
-+
-+int task_group_throttled(struct task_group *tg, int cpu)
-+{
-+      struct sched_entity *se = tg->se[cpu];
-+
-+      for_each_sched_entity(se) {
-+              if (entity_throttled(se))
-+                      return 1;
-+      }
-+      return 0;
++      sched_cfs_runtime_exceeded(curr, tsk_curr, delta_exec);
 +}
 +
 +static void enqueue_entity_locked(struct cfs_rq *cfs_rq,
 +              struct sched_entity *se, int wakeup);
-+static void add_cfs_rq_tasks_running(struct sched_entity *se,
-+              unsigned long count);
-+static void sub_cfs_rq_tasks_running(struct sched_entity *se,
-+              unsigned long count);
 +
 +static void enqueue_throttled_entity(struct rq *rq, struct sched_entity *se)
 +{
-+      unsigned long nr_tasks = 0;
-+      struct sched_entity *se_tmp = se;
-+      int throttled = 0;
-+
 +      for_each_sched_entity(se) {
-+              if (se->on_rq)
-+                      break;
++              struct cfs_rq *gcfs_rq = group_cfs_rq(se);
 +
-+              if (entity_throttled(se)) {
-+                      throttled = 1;
++              if (se->on_rq || cfs_rq_throttled(gcfs_rq) ||
++                              !gcfs_rq->nr_running)
 +                      break;
-+              }
-+
 +              enqueue_entity_locked(cfs_rq_of(se), se, 0);
-+              nr_tasks += group_cfs_rq(se)->nr_tasks_running;
 +      }
-+
-+      if (!nr_tasks)
-+              return;
-+
-+      /*
-+       * Add the number of tasks this entity has to
-+       * all of its parent entities.
-+       */
-+      add_cfs_rq_tasks_running(se_tmp, nr_tasks);
-+
-+      /*
-+       * Add the number of tasks this entity has to
-+       * this cpu's rq only if the entity got enqueued all the
-+       * way up without any throttled entity in the hierarchy.
-+       */
-+      if (!throttled)
-+              rq->nr_running += nr_tasks;
 +}
 +
 +/*
@@ -16697,17 +16572,15 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 +{
 +      int i;
 +      const struct cpumask *span = sched_bw_period_mask();
-+      struct task_group *tg = container_of(cfs_b, struct task_group,
-+                                      cfs_bandwidth);
 +      unsigned long flags;
 +
 +      for_each_cpu(i, span) {
 +              struct rq *rq = cpu_rq(i);
-+              struct cfs_rq *cfs_rq = tg->cfs_rq[i];
-+              struct sched_entity *se = tg->se[i];
++              struct cfs_rq *cfs_rq = sched_cfs_period_cfs_rq(cfs_b, i);
++              struct sched_entity *se = cfs_rq->tg->se[i];
 +
 +              spin_lock_irqsave(&rq->lock, flags);
-+              rq_runtime_lock(rq);
++              cfs_rq_runtime_lock(cfs_rq);
 +              cfs_rq->cfs_time = 0;
 +              if (cfs_rq_throttled(cfs_rq)) {
 +                      update_rq_clock(rq);
@@ -16715,127 +16588,128 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 +                      cfs_rq->cfs_throttled = 0;
 +                      enqueue_throttled_entity(rq, se);
 +              }
-+              rq_runtime_unlock(rq);
++              cfs_rq_runtime_unlock(cfs_rq);
 +              spin_unlock_irqrestore(&rq->lock, flags);
 +      }
 +}
 +
 +#else
 +
-+static inline int cfs_rq_throttled(struct cfs_rq *cfs_rq)
-+{
-+      return 0;
-+}
-+
-+int task_group_throttled(struct task_group *tg, int cpu)
-+{
-+      return 0;
-+}
-+
-+static void sched_cfs_runtime_exceeded(struct sched_entity *se,
-+      struct task_struct *tsk_curr, unsigned long delta_exec)
++static inline void update_curr_group(struct sched_entity *curr,
++              unsigned long delta_exec, struct task_struct *tsk_curr)
 +{
 +      return;
 +}
 +
-+static int entity_throttled(struct sched_entity *se)
++static inline int cfs_rq_throttled(struct cfs_rq *cfs_rq)
 +{
 +      return 0;
 +}
 +
 +#endif /* CONFIG_CFS_HARD_LIMITS */
 +
- #else /* CONFIG_FAIR_GROUP_SCHED */
- static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
-@@ -241,8 +521,47 @@ find_matching_se(struct sched_entity **s
- {
- }
-+static void sched_cfs_runtime_exceeded(struct sched_entity *se,
-+      struct task_struct *tsk_curr, unsigned long delta_exec)
-+{
-+      return;
-+}
++#else /* CONFIG_FAIR_GROUP_SCHED */
 +
-+static int entity_throttled(struct sched_entity *se)
++static inline void update_curr_group(struct sched_entity *curr,
++              unsigned long delta_exec, struct task_struct *tsk_curr)
 +{
-+      return 0;
++      return;
 +}
-+
- #endif        /* CONFIG_FAIR_GROUP_SCHED */
  
-+static void add_cfs_rq_tasks_running(struct sched_entity *se,
-+              unsigned long count)
-+{
-+      struct cfs_rq *cfs_rq;
-+
-+      for_each_sched_entity(se) {
-+              /*
-+               * If any entity in the hierarchy is throttled, don't
-+               * propogate the tasks count up since this entity isn't
-+               * on rq yet.
-+               */
-+              if (entity_throttled(se))
-+                      break;
-+              cfs_rq = cfs_rq_of(se);
-+              cfs_rq->nr_tasks_running += count;
-+      }
-+}
-+
-+static void sub_cfs_rq_tasks_running(struct sched_entity *se,
-+              unsigned long count)
-+{
-+      struct cfs_rq *cfs_rq;
-+
-+      for_each_sched_entity(se) {
-+              cfs_rq = cfs_rq_of(se);
-+              cfs_rq->nr_tasks_running -= count;
-+      }
-+}
+ static inline struct task_struct *task_of(struct sched_entity *se)
+ {
+@@ -251,7 +552,6 @@ find_matching_se(struct sched_entity **s
+ #endif        /* CONFIG_FAIR_GROUP_SCHED */
  
+-
  /**************************************************************
   * Scheduling class tree data structure manipulation methods:
-@@ -481,10 +800,12 @@ __update_curr(struct cfs_rq *cfs_rq, str
+  */
+@@ -489,14 +789,25 @@ __update_curr(struct cfs_rq *cfs_rq, str
        update_min_vruntime(cfs_rq);
  }
  
 -static void update_curr(struct cfs_rq *cfs_rq)
-+static void update_curr_common(struct cfs_rq *cfs_rq)
++static void update_curr_task(struct sched_entity *curr,
++              unsigned long delta_exec)
++{
++      struct task_struct *curtask = task_of(curr);
++
++      trace_sched_stat_runtime(curtask, delta_exec, curr->vruntime);
++      cpuacct_charge(curtask, delta_exec);
++      account_group_exec_runtime(curtask, delta_exec);
++}
++
++static int update_curr_common(struct cfs_rq *cfs_rq, unsigned long *delta)
  {
        struct sched_entity *curr = cfs_rq->curr;
 -      u64 now = rq_of(cfs_rq)->clock;
 +      struct rq *rq = rq_of(cfs_rq);
-+      struct task_struct *tsk_curr = rq->curr;
 +      u64 now = rq->clock;
        unsigned long delta_exec;
  
        if (unlikely(!curr))
-@@ -507,9 +828,23 @@ static void update_curr(struct cfs_rq *c
+-              return;
++              return 1;
  
-               cpuacct_charge(curtask, delta_exec);
-               account_group_exec_runtime(curtask, delta_exec);
-+      } else {
-+              sched_cfs_runtime_exceeded(curr, tsk_curr, delta_exec);
-       }
- }
+       /*
+        * Get the amount of time the current task was running
+@@ -505,20 +816,47 @@ static void update_curr(struct cfs_rq *c
+        */
+       delta_exec = (unsigned long)(now - curr->exec_start);
+       if (!delta_exec)
+-              return;
++              return 1;
  
+       __update_curr(cfs_rq, curr, delta_exec);
+       curr->exec_start = now;
++      *delta = delta_exec;
++      return 0;
++}
+-      if (entity_is_task(curr)) {
+-              struct task_struct *curtask = task_of(curr);
 +static void update_curr(struct cfs_rq *cfs_rq)
 +{
-+      rq_runtime_lock(rq_of(cfs_rq));
-+      update_curr_common(cfs_rq);
-+      rq_runtime_unlock(rq_of(cfs_rq));
-+}
++      struct sched_entity *curr = cfs_rq->curr;
++      struct rq *rq = rq_of(cfs_rq);
++      unsigned long delta_exec;
+-              trace_sched_stat_runtime(curtask, delta_exec, curr->vruntime);
+-              cpuacct_charge(curtask, delta_exec);
+-              account_group_exec_runtime(curtask, delta_exec);
++      if (update_curr_common(cfs_rq, &delta_exec))
++              return ;
 +
-+static inline void update_curr_locked(struct cfs_rq *cfs_rq)
++      if (entity_is_task(curr))
++              update_curr_task(curr, delta_exec);
++      else {
++              cfs_rq_runtime_lock(group_cfs_rq(curr));
++              update_curr_group(curr, delta_exec, rq->curr);
++              cfs_rq_runtime_unlock(group_cfs_rq(curr));
+       }
+ }
++static void update_curr_locked(struct cfs_rq *cfs_rq)
 +{
-+      update_curr_common(cfs_rq);
++      struct sched_entity *curr = cfs_rq->curr;
++      struct rq *rq = rq_of(cfs_rq);
++      unsigned long delta_exec;
++
++      if (update_curr_common(cfs_rq, &delta_exec))
++              return ;
++
++      if (entity_is_task(curr))
++              update_curr_task(curr, delta_exec);
++      else
++              update_curr_group(curr, delta_exec, rq->curr);
 +}
 +
  static inline void
  update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
  {
-@@ -713,13 +1048,9 @@ place_entity(struct cfs_rq *cfs_rq, stru
+@@ -740,13 +1078,9 @@ place_entity(struct cfs_rq *cfs_rq, stru
        se->vruntime = vruntime;
  }
  
@@ -16851,7 +16725,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
        account_entity_enqueue(cfs_rq, se);
  
        if (wakeup) {
-@@ -731,6 +1062,29 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
+@@ -758,6 +1092,29 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
        check_spread(cfs_rq, se);
        if (se != cfs_rq->curr)
                __enqueue_entity(cfs_rq, se);
@@ -16881,7 +16755,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
  }
  
  static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
-@@ -774,6 +1128,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
+@@ -801,6 +1158,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
  
        if (se != cfs_rq->curr)
                __dequeue_entity(cfs_rq, se);
@@ -16890,7 +16764,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
        account_entity_dequeue(cfs_rq, se);
        update_min_vruntime(cfs_rq);
  }
-@@ -844,8 +1200,40 @@ static struct sched_entity *pick_next_en
+@@ -897,6 +1256,32 @@ static struct sched_entity *pick_next_en
        return se;
  }
  
@@ -16899,124 +16773,134 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_fair.c linux-2.6.31.6-vs2.3.0.
 + * If a group entity (@se) is found to be throttled, it will not be put back
 + * on @cfs_rq, which is equivalent to dequeing it.
 + */
-+static void dequeue_throttled_entity(struct cfs_rq *cfs_rq,
++static int dequeue_throttled_entity(struct cfs_rq *cfs_rq,
 +              struct sched_entity *se)
 +{
-+      unsigned long nr_tasks = group_cfs_rq(se)->nr_tasks_running;
++      struct cfs_rq *gcfs_rq = group_cfs_rq(se);
++
++      if (entity_is_task(se))
++              return 0;
++
++      cfs_rq_runtime_lock(gcfs_rq);
++      if (!cfs_rq_throttled(gcfs_rq) && gcfs_rq->nr_running) {
++              cfs_rq_runtime_unlock(gcfs_rq);
++              return 0;
++      }
 +
 +      __clear_buddies(cfs_rq, se);
 +      account_entity_dequeue(cfs_rq, se);
 +      cfs_rq->curr = NULL;
-+
-+      if (!nr_tasks)
-+              return;
-+
-+      /*
-+       * Decrement the number of tasks this entity has from
-+       * all of its parent entities.
-+       */
-+      sub_cfs_rq_tasks_running(se, nr_tasks);
-+
-+      /*
-+       * Decrement the number of tasks this entity has from
-+       * this cpu's rq.
-+       */
-+      rq_of(cfs_rq)->nr_running -= nr_tasks;
++      cfs_rq_runtime_unlock(gcfs_rq);
++      return 1;
 +}
 +
  static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
  {
-+      struct cfs_rq *gcfs_rq = group_cfs_rq(prev);
-+
        /*
-        * If still on the runqueue then deactivate_task()
-        * was not called and update_curr() has to be done:
-@@ -855,6 +1243,18 @@ static void put_prev_entity(struct cfs_r
+@@ -908,6 +1293,8 @@ static void put_prev_entity(struct cfs_r
  
        check_spread(cfs_rq, prev);
        if (prev->on_rq) {
-+              /*
-+               * If the group entity is throttled or if it has no
-+               * no child entities, then don't enqueue it back.
-+               */
-+              rq_runtime_lock(rq_of(cfs_rq));
-+              if (entity_throttled(prev) ||
-+                      (gcfs_rq && !gcfs_rq->nr_running)) {
-+                      dequeue_throttled_entity(cfs_rq, prev);
-+                      rq_runtime_unlock(rq_of(cfs_rq));
++              if (dequeue_throttled_entity(cfs_rq, prev))
 +                      return;
-+              }
-+              rq_runtime_unlock(rq_of(cfs_rq));
                update_stats_wait_start(cfs_rq, prev);
                /* Put 'current' back into the tree. */
                __enqueue_entity(cfs_rq, prev);
-@@ -955,21 +1355,32 @@ static inline void hrtick_update(struct 
+@@ -1004,10 +1391,28 @@ static inline void hrtick_update(struct 
+ }
+ #endif
++static int enqueue_group_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
++               int wakeup)
++{
++      struct cfs_rq *gcfs_rq = group_cfs_rq(se);
++      int ret = 0;
++
++      cfs_rq_runtime_lock(gcfs_rq);
++      if (cfs_rq_throttled(gcfs_rq)) {
++              ret = 1;
++              goto out;
++      }
++      enqueue_entity_locked(cfs_rq, se, wakeup);
++out:
++      cfs_rq_runtime_unlock(gcfs_rq);
++      return ret;
++}
++
+ /*
   * The enqueue_task method is called before nr_running is
   * increased. Here we update the fair scheduling stats and
   * then put the task into the rbtree:
 + * Don't enqueue a throttled entity further into the hierarchy.
   */
--static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
-+static int enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
+ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
  {
-       struct cfs_rq *cfs_rq;
-       struct sched_entity *se = &p->se;
-+      int throttled = 0;
-+      rq_runtime_lock(rq);
+@@ -1017,11 +1422,15 @@ static void enqueue_task_fair(struct rq 
        for_each_sched_entity(se) {
                if (se->on_rq)
                        break;
-+              if (entity_throttled(se)) {
-+                      throttled = 1;
-+                      break;
-+              }
++
                cfs_rq = cfs_rq_of(se);
 -              enqueue_entity(cfs_rq, se, wakeup);
-+              enqueue_entity_locked(cfs_rq, se, wakeup);
++              if (entity_is_task(se))
++                      enqueue_entity(cfs_rq, se, wakeup);
++              else
++                      if (enqueue_group_entity(cfs_rq, se, wakeup))
++                              break;
                wakeup = 1;
        }
-+      add_cfs_rq_tasks_running(&p->se, 1);
-+      rq_runtime_unlock(rq);
-+
+-
        hrtick_update(rq);
-+      return throttled;
  }
  
- /*
-@@ -991,6 +1402,7 @@ static void dequeue_task_fair(struct rq 
+@@ -1041,6 +1450,17 @@ static void dequeue_task_fair(struct rq 
+               /* Don't dequeue parent if it has other entities besides us */
+               if (cfs_rq->load.weight)
+                       break;
++
++              /*
++               * If this cfs_rq is throttled, then it is already
++               * dequeued.
++               */
++              cfs_rq_runtime_lock(cfs_rq);
++              if (cfs_rq_throttled(cfs_rq)) {
++                      cfs_rq_runtime_unlock(cfs_rq);
++                      break;
++              }
++              cfs_rq_runtime_unlock(cfs_rq);
                sleep = 1;
        }
  
-+      sub_cfs_rq_tasks_running(&p->se, 1);
-       hrtick_update(rq);
- }
-@@ -1518,6 +1930,7 @@ static struct task_struct *pick_next_tas
-       do {
-               se = pick_next_entity(cfs_rq);
-+
-               /*
-                * If se was a buddy, clear it so that it will have to earn
-                * the favour again.
-@@ -1627,9 +2040,9 @@ load_balance_fair(struct rq *this_rq, in
+@@ -1788,9 +2208,10 @@ load_balance_fair(struct rq *this_rq, in
                u64 rem_load, moved_load;
  
                /*
 -               * empty group
-+               * empty group or a group with no h_load (throttled)
++               * empty group or throttled group
                 */
 -              if (!busiest_cfs_rq->task_weight)
-+              if (!busiest_cfs_rq->task_weight || !busiest_h_load)
++              if (!busiest_cfs_rq->task_weight ||
++                              cfs_rq_throttled(busiest_cfs_rq))
                        continue;
  
                rem_load = (u64)rem_load_move * busiest_weight;
-diff -NurpP --minimal linux-2.6.31.6/kernel/sched_rt.c linux-2.6.31.6-vs2.3.0.36.24/kernel/sched_rt.c
---- linux-2.6.31.6/kernel/sched_rt.c   2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/sched_rt.c     2009-10-06 04:39:02.000000000 +0200
-@@ -222,18 +222,6 @@ static int rt_se_boosted(struct sched_rt
+@@ -1839,6 +2260,12 @@ move_one_task_fair(struct rq *this_rq, i
+       for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
+               /*
++               * Don't move task from a throttled cfs_rq
++               */
++              if (cfs_rq_throttled(busy_cfs_rq))
++                      continue;
++
++              /*
+                * pass busy_cfs_rq argument into
+                * load_balance_[start|next]_fair iterators
+                */
+diff -NurpP --minimal linux-2.6.32/kernel/sched_rt.c linux-2.6.32-vs2.3.0.36.26/kernel/sched_rt.c
+--- linux-2.6.32/kernel/sched_rt.c     2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/sched_rt.c       2009-12-03 20:04:56.000000000 +0100
+@@ -235,18 +235,6 @@ static int rt_se_boosted(struct sched_rt
        return p->prio != p->normal_prio;
  }
  
@@ -17035,7 +16919,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_rt.c linux-2.6.31.6-vs2.3.0.36
  static inline
  struct rt_rq *sched_rt_period_rt_rq(struct rt_bandwidth *rt_b, int cpu)
  {
-@@ -283,11 +271,6 @@ static inline int rt_rq_throttled(struct
+@@ -296,11 +284,6 @@ static inline int rt_rq_throttled(struct
        return rt_rq->rt_throttled;
  }
  
@@ -17047,7 +16931,50 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_rt.c linux-2.6.31.6-vs2.3.0.36
  static inline
  struct rt_rq *sched_rt_period_rt_rq(struct rt_bandwidth *rt_b, int cpu)
  {
-@@ -505,7 +488,7 @@ static int do_sched_rt_period_timer(stru
+@@ -373,7 +356,7 @@ next:
+ /*
+  * Ensure this RQ takes back all the runtime it lend to its neighbours.
+  */
+-static void __disable_runtime(struct rq *rq)
++static void disable_runtime_rt(struct rq *rq)
+ {
+       struct root_domain *rd = rq->rd;
+       struct rt_rq *rt_rq;
+@@ -450,16 +433,7 @@ balanced:
+       }
+ }
+-static void disable_runtime(struct rq *rq)
+-{
+-      unsigned long flags;
+-
+-      spin_lock_irqsave(&rq->lock, flags);
+-      __disable_runtime(rq);
+-      spin_unlock_irqrestore(&rq->lock, flags);
+-}
+-
+-static void __enable_runtime(struct rq *rq)
++static void enable_runtime_rt(struct rq *rq)
+ {
+       struct rt_rq *rt_rq;
+@@ -482,15 +456,6 @@ static void __enable_runtime(struct rq *
+       }
+ }
+-static void enable_runtime(struct rq *rq)
+-{
+-      unsigned long flags;
+-
+-      spin_lock_irqsave(&rq->lock, flags);
+-      __enable_runtime(rq);
+-      spin_unlock_irqrestore(&rq->lock, flags);
+-}
+-
+ static int balance_runtime(struct rt_rq *rt_rq)
+ {
+       int more = 0;
+@@ -518,7 +483,7 @@ static int do_sched_rt_period_timer(stru
        if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF)
                return 1;
  
@@ -17056,26 +16983,27 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sched_rt.c linux-2.6.31.6-vs2.3.0.36
        for_each_cpu(i, span) {
                int enqueue = 0;
                struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i);
-@@ -863,7 +846,7 @@ static void dequeue_rt_entity(struct sch
- /*
-  * Adding/removing a task to/from a priority array:
-  */
--static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
-+static int enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
- {
-       struct sched_rt_entity *rt_se = &p->rt;
+@@ -1564,7 +1529,7 @@ static void rq_online_rt(struct rq *rq)
+       if (rq->rt.overloaded)
+               rt_set_overload(rq);
  
-@@ -876,6 +859,7 @@ static void enqueue_task_rt(struct rq *r
-               enqueue_pushable_task(rq, p);
+-      __enable_runtime(rq);
++      enable_runtime_rt(rq);
  
-       inc_cpu_load(rq, p->se.load.weight);
-+      return 0;
+       cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr);
  }
+@@ -1575,7 +1540,7 @@ static void rq_offline_rt(struct rq *rq)
+       if (rq->rt.overloaded)
+               rt_clear_overload(rq);
  
- static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
-diff -NurpP --minimal linux-2.6.31.6/kernel/signal.c linux-2.6.31.6-vs2.3.0.36.24/kernel/signal.c
---- linux-2.6.31.6/kernel/signal.c     2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/signal.c       2009-09-10 16:43:45.000000000 +0200
+-      __disable_runtime(rq);
++      disable_runtime_rt(rq);
+       cpupri_set(&rq->rd->cpupri, rq->cpu, CPUPRI_INVALID);
+ }
+diff -NurpP --minimal linux-2.6.32/kernel/signal.c linux-2.6.32-vs2.3.0.36.26/kernel/signal.c
+--- linux-2.6.32/kernel/signal.c       2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/signal.c 2009-12-03 20:04:56.000000000 +0100
 @@ -27,6 +27,8 @@
  #include <linux/freezer.h>
  #include <linux/pid_namespace.h>
@@ -17152,7 +17080,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/signal.c linux-2.6.31.6-vs2.3.0.36.2
                                int err = group_send_sig_info(sig, info, p);
                                ++count;
                                if (err != -EPERM)
-@@ -1892,6 +1918,11 @@ relock:
+@@ -1871,6 +1897,11 @@ relock:
                                !sig_kernel_only(signr))
                        continue;
  
@@ -17164,9 +17092,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/signal.c linux-2.6.31.6-vs2.3.0.36.2
                if (sig_kernel_stop(signr)) {
                        /*
                         * The default action is to stop all threads in
-diff -NurpP --minimal linux-2.6.31.6/kernel/softirq.c linux-2.6.31.6-vs2.3.0.36.24/kernel/softirq.c
---- linux-2.6.31.6/kernel/softirq.c    2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/softirq.c      2009-09-10 16:33:13.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/softirq.c linux-2.6.32-vs2.3.0.36.26/kernel/softirq.c
+--- linux-2.6.32/kernel/softirq.c      2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/softirq.c        2009-12-03 20:04:56.000000000 +0100
 @@ -24,6 +24,7 @@
  #include <linux/ftrace.h>
  #include <linux/smp.h>
@@ -17175,9 +17103,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/softirq.c linux-2.6.31.6-vs2.3.0.36.
  
  #define CREATE_TRACE_POINTS
  #include <trace/events/irq.h>
-diff -NurpP --minimal linux-2.6.31.6/kernel/sys.c linux-2.6.31.6-vs2.3.0.36.24/kernel/sys.c
---- linux-2.6.31.6/kernel/sys.c        2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/sys.c  2009-10-06 03:52:09.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/sys.c linux-2.6.32-vs2.3.0.36.26/kernel/sys.c
+--- linux-2.6.32/kernel/sys.c  2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/sys.c    2009-12-03 20:04:56.000000000 +0100
 @@ -41,6 +41,7 @@
  #include <linux/syscalls.h>
  #include <linux/kprobes.h>
@@ -17236,7 +17164,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sys.c linux-2.6.31.6-vs2.3.0.36.24/k
        lock_kernel();
        switch (cmd) {
        case LINUX_REBOOT_CMD_RESTART:
-@@ -1131,7 +1145,7 @@ SYSCALL_DEFINE2(sethostname, char __user
+@@ -1133,7 +1147,7 @@ SYSCALL_DEFINE2(sethostname, char __user
        int errno;
        char tmp[__NEW_UTS_LEN];
  
@@ -17245,7 +17173,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sys.c linux-2.6.31.6-vs2.3.0.36.24/k
                return -EPERM;
        if (len < 0 || len > __NEW_UTS_LEN)
                return -EINVAL;
-@@ -1180,7 +1194,7 @@ SYSCALL_DEFINE2(setdomainname, char __us
+@@ -1182,7 +1196,7 @@ SYSCALL_DEFINE2(setdomainname, char __us
        int errno;
        char tmp[__NEW_UTS_LEN];
  
@@ -17254,7 +17182,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sys.c linux-2.6.31.6-vs2.3.0.36.24/k
                return -EPERM;
        if (len < 0 || len > __NEW_UTS_LEN)
                return -EINVAL;
-@@ -1249,7 +1263,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+@@ -1251,7 +1265,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
                return -EINVAL;
        old_rlim = current->signal->rlim + resource;
        if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
@@ -17263,10 +17191,10 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sys.c linux-2.6.31.6-vs2.3.0.36.24/k
                return -EPERM;
        if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
                return -EPERM;
-diff -NurpP --minimal linux-2.6.31.6/kernel/sysctl.c linux-2.6.31.6-vs2.3.0.36.24/kernel/sysctl.c
---- linux-2.6.31.6/kernel/sysctl.c     2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/sysctl.c       2009-09-10 16:11:43.000000000 +0200
-@@ -119,6 +119,7 @@ static int ngroups_max = NGROUPS_MAX;
+diff -NurpP --minimal linux-2.6.32/kernel/sysctl.c linux-2.6.32-vs2.3.0.36.26/kernel/sysctl.c
+--- linux-2.6.32/kernel/sysctl.c       2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/sysctl.c 2009-12-03 20:04:56.000000000 +0100
+@@ -124,6 +124,7 @@ static int ngroups_max = NGROUPS_MAX;
  extern char modprobe_path[];
  extern int modules_disabled;
  #endif
@@ -17274,7 +17202,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sysctl.c linux-2.6.31.6-vs2.3.0.36.2
  #ifdef CONFIG_CHR_DEV_SG
  extern int sg_big_buff;
  #endif
-@@ -572,6 +573,15 @@ static struct ctl_table kern_table[] = {
+@@ -593,6 +594,15 @@ static struct ctl_table kern_table[] = {
                .strategy       = &sysctl_string,
        },
  #endif
@@ -17290,9 +17218,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sysctl.c linux-2.6.31.6-vs2.3.0.36.2
  #ifdef CONFIG_CHR_DEV_SG
        {
                .ctl_name       = KERN_SG_BIG_BUFF,
-diff -NurpP --minimal linux-2.6.31.6/kernel/sysctl_check.c linux-2.6.31.6-vs2.3.0.36.24/kernel/sysctl_check.c
---- linux-2.6.31.6/kernel/sysctl_check.c       2009-06-11 17:13:26.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/sysctl_check.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/sysctl_check.c linux-2.6.32-vs2.3.0.36.26/kernel/sysctl_check.c
+--- linux-2.6.32/kernel/sysctl_check.c 2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/sysctl_check.c   2009-12-03 20:04:56.000000000 +0100
 @@ -39,6 +39,7 @@ static const struct trans_ctl_table tran
  
        { KERN_PANIC,                   "panic" },
@@ -17332,9 +17260,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/sysctl_check.c linux-2.6.31.6-vs2.3.
        {}
  };
  
-diff -NurpP --minimal linux-2.6.31.6/kernel/time.c linux-2.6.31.6-vs2.3.0.36.24/kernel/time.c
---- linux-2.6.31.6/kernel/time.c       2009-03-24 14:22:45.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/time.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/time.c linux-2.6.32-vs2.3.0.36.26/kernel/time.c
+--- linux-2.6.32/kernel/time.c 2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/time.c   2009-12-03 20:04:56.000000000 +0100
 @@ -63,6 +63,7 @@ EXPORT_SYMBOL(sys_tz);
  SYSCALL_DEFINE1(time, time_t __user *, tloc)
  {
@@ -17379,12 +17307,12 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/time.c linux-2.6.31.6-vs2.3.0.36.24/
        tv->tv_sec = x.tv_sec;
        tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
  }
-diff -NurpP --minimal linux-2.6.31.6/kernel/timer.c linux-2.6.31.6-vs2.3.0.36.24/kernel/timer.c
---- linux-2.6.31.6/kernel/timer.c      2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/timer.c        2009-10-06 04:09:06.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/timer.c linux-2.6.32-vs2.3.0.36.26/kernel/timer.c
+--- linux-2.6.32/kernel/timer.c        2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/timer.c  2009-12-03 20:04:56.000000000 +0100
 @@ -39,6 +39,10 @@
  #include <linux/kallsyms.h>
- #include <linux/perf_counter.h>
+ #include <linux/perf_event.h>
  #include <linux/sched.h>
 +#include <linux/vs_base.h>
 +#include <linux/vs_cvirt.h>
@@ -17393,7 +17321,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/timer.c linux-2.6.31.6-vs2.3.0.36.24
  
  #include <asm/uaccess.h>
  #include <asm/unistd.h>
-@@ -1214,12 +1218,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, sec
+@@ -1255,12 +1259,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, sec
  
  #endif
  
@@ -17406,7 +17334,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/timer.c linux-2.6.31.6-vs2.3.0.36.24
  
  /**
   * sys_getpid - return the thread group id of the current process
-@@ -1248,10 +1246,23 @@ SYSCALL_DEFINE0(getppid)
+@@ -1289,10 +1287,23 @@ SYSCALL_DEFINE0(getppid)
        rcu_read_lock();
        pid = task_tgid_vnr(current->real_parent);
        rcu_read_unlock();
@@ -17431,9 +17359,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/timer.c linux-2.6.31.6-vs2.3.0.36.24
  SYSCALL_DEFINE0(getuid)
  {
        /* Only we change this so SMP safe */
-diff -NurpP --minimal linux-2.6.31.6/kernel/user.c linux-2.6.31.6-vs2.3.0.36.24/kernel/user.c
---- linux-2.6.31.6/kernel/user.c       2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/user.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/user.c linux-2.6.32-vs2.3.0.36.26/kernel/user.c
+--- linux-2.6.32/kernel/user.c 2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/user.c   2009-12-03 20:04:56.000000000 +0100
 @@ -251,10 +251,10 @@ static struct kobj_type uids_ktype = {
   *
   * See Documentation/scheduler/sched-design-CFS.txt for ramifications.
@@ -17475,9 +17403,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/user.c linux-2.6.31.6-vs2.3.0.36.24/
                        goto out_destoy_sched;
  
                /*
-diff -NurpP --minimal linux-2.6.31.6/kernel/user_namespace.c linux-2.6.31.6-vs2.3.0.36.24/kernel/user_namespace.c
---- linux-2.6.31.6/kernel/user_namespace.c     2009-03-24 14:22:45.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/user_namespace.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/user_namespace.c linux-2.6.32-vs2.3.0.36.26/kernel/user_namespace.c
+--- linux-2.6.32/kernel/user_namespace.c       2009-03-24 14:22:45.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/user_namespace.c 2009-12-03 20:04:56.000000000 +0100
 @@ -10,6 +10,7 @@
  #include <linux/slab.h>
  #include <linux/user_namespace.h>
@@ -17503,9 +17431,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/user_namespace.c linux-2.6.31.6-vs2.
        INIT_WORK(&ns->destroyer, free_user_ns_work);
        schedule_work(&ns->destroyer);
  }
-diff -NurpP --minimal linux-2.6.31.6/kernel/utsname.c linux-2.6.31.6-vs2.3.0.36.24/kernel/utsname.c
---- linux-2.6.31.6/kernel/utsname.c    2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/utsname.c      2009-09-10 16:44:37.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/utsname.c linux-2.6.32-vs2.3.0.36.26/kernel/utsname.c
+--- linux-2.6.32/kernel/utsname.c      2009-09-10 15:26:28.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/kernel/utsname.c        2009-12-03 20:04:56.000000000 +0100
 @@ -14,14 +14,17 @@
  #include <linux/utsname.h>
  #include <linux/err.h>
@@ -17532,9 +17460,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/utsname.c linux-2.6.31.6-vs2.3.0.36.
 +      atomic_dec(&vs_global_uts_ns);
        kfree(ns);
  }
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cacct.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cacct.c
---- linux-2.6.31.6/kernel/vserver/cacct.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cacct.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/cacct.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cacct.c
+--- linux-2.6.32/kernel/vserver/cacct.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cacct.c  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,42 @@
 +/*
 + *  linux/kernel/vserver/cacct.c
@@ -17578,9 +17506,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cacct.c linux-2.6.31.6-vs2.3
 +      return 0;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cacct_init.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cacct_init.h
---- linux-2.6.31.6/kernel/vserver/cacct_init.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cacct_init.h   2009-09-29 17:15:22.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/cacct_init.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cacct_init.h
+--- linux-2.6.32/kernel/vserver/cacct_init.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cacct_init.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,25 @@
 +
 +
@@ -17607,9 +17535,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cacct_init.h linux-2.6.31.6-
 +      return;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cacct_proc.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cacct_proc.h
---- linux-2.6.31.6/kernel/vserver/cacct_proc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cacct_proc.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/cacct_proc.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cacct_proc.h
+--- linux-2.6.32/kernel/vserver/cacct_proc.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cacct_proc.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,53 @@
 +#ifndef _VX_CACCT_PROC_H
 +#define _VX_CACCT_PROC_H
@@ -17664,10 +17592,10 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cacct_proc.h linux-2.6.31.6-
 +}
 +
 +#endif        /* _VX_CACCT_PROC_H */
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/context.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/context.c
---- linux-2.6.31.6/kernel/vserver/context.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/context.c      2009-11-05 04:18:09.000000000 +0100
-@@ -0,0 +1,1032 @@
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/context.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/context.c
+--- linux-2.6.32/kernel/vserver/context.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/context.c        2009-12-03 20:04:56.000000000 +0100
+@@ -0,0 +1,1057 @@
 +/*
 + *  linux/kernel/vserver/context.c
 + *
@@ -17784,7 +17712,7 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/context.c linux-2.6.31.6-vs2
 +      new->vx_flags = VXF_INIT_SET;
 +      cap_set_init_eff(new->vx_bcaps);
 +      new->vx_ccaps = 0;
-+      // new->vx_cap_bset = current->cap_bset;
++      new->vx_umask = 0;
 +
 +      new->reboot_cmd = 0;
 +      new->exit_code = 0;
@@ -18674,6 +18602,31 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/context.c linux-2.6.31.6-vs2
 +}
 +
 +
++int vc_get_umask(struct vx_info *vxi, void __user *data)
++{
++      struct vcmd_umask vc_data;
++
++      vc_data.umask = vxi->vx_umask;
++      vc_data.mask = ~0ULL;
++
++      if (copy_to_user(data, &vc_data, sizeof(vc_data)))
++              return -EFAULT;
++      return 0;
++}
++
++int vc_set_umask(struct vx_info *vxi, void __user *data)
++{
++      struct vcmd_umask vc_data;
++
++      if (copy_from_user(&vc_data, data, sizeof(vc_data)))
++              return -EFAULT;
++
++      vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
++              vc_data.umask, vc_data.mask);
++      return 0;
++}
++
++
 +int vc_get_badness(struct vx_info *vxi, void __user *data)
 +{
 +      struct vcmd_badness_v0 vc_data;
@@ -18700,9 +18653,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/context.c linux-2.6.31.6-vs2
 +
 +EXPORT_SYMBOL_GPL(free_vx_info);
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cvirt.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cvirt.c
---- linux-2.6.31.6/kernel/vserver/cvirt.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cvirt.c        2009-11-05 04:21:59.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/cvirt.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cvirt.c
+--- linux-2.6.32/kernel/vserver/cvirt.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cvirt.c  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,304 @@
 +/*
 + *  linux/kernel/vserver/cvirt.c
@@ -19008,9 +18961,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cvirt.c linux-2.6.31.6-vs2.3
 +
 +#endif
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cvirt_init.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cvirt_init.h
---- linux-2.6.31.6/kernel/vserver/cvirt_init.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cvirt_init.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/cvirt_init.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cvirt_init.h
+--- linux-2.6.32/kernel/vserver/cvirt_init.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cvirt_init.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,69 @@
 +
 +
@@ -19081,9 +19034,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cvirt_init.h linux-2.6.31.6-
 +      return;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cvirt_proc.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cvirt_proc.h
---- linux-2.6.31.6/kernel/vserver/cvirt_proc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/cvirt_proc.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/cvirt_proc.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cvirt_proc.h
+--- linux-2.6.32/kernel/vserver/cvirt_proc.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/cvirt_proc.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,135 @@
 +#ifndef _VX_CVIRT_PROC_H
 +#define _VX_CVIRT_PROC_H
@@ -19220,9 +19173,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/cvirt_proc.h linux-2.6.31.6-
 +}
 +
 +#endif        /* _VX_CVIRT_PROC_H */
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/debug.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/debug.c
---- linux-2.6.31.6/kernel/vserver/debug.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/debug.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/debug.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/debug.c
+--- linux-2.6.32/kernel/vserver/debug.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/debug.c  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,32 @@
 +/*
 + *  kernel/vserver/debug.c
@@ -19256,9 +19209,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/debug.c linux-2.6.31.6-vs2.3
 +
 +EXPORT_SYMBOL_GPL(dump_vx_info);
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/device.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/device.c
---- linux-2.6.31.6/kernel/vserver/device.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/device.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/device.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/device.c
+--- linux-2.6.32/kernel/vserver/device.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/device.c 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,443 @@
 +/*
 + *  linux/kernel/vserver/device.c
@@ -19703,19 +19656,20 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/device.c linux-2.6.31.6-vs2.
 +#endif        /* CONFIG_COMPAT */
 +
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/dlimit.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/dlimit.c
---- linux-2.6.31.6/kernel/vserver/dlimit.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/dlimit.c       2009-09-10 16:11:43.000000000 +0200
-@@ -0,0 +1,522 @@
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/dlimit.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/dlimit.c
+--- linux-2.6.32/kernel/vserver/dlimit.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/dlimit.c 2009-12-03 20:04:56.000000000 +0100
+@@ -0,0 +1,529 @@
 +/*
 + *  linux/kernel/vserver/dlimit.c
 + *
 + *  Virtual Server: Context Disk Limits
 + *
-+ *  Copyright (C) 2004-2007  Herbert Pötzl
++ *  Copyright (C) 2004-2009  Herbert Pötzl
 + *
 + *  V0.01  initial version
 + *  V0.02  compat32 splitup
++ *  V0.03  extended interface
 + *
 + */
 +
@@ -19996,6 +19950,8 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/dlimit.c linux-2.6.31.6-vs2.
 +                      goto out_release;
 +              if (!(sb = path.dentry->d_inode->i_sb))
 +                      goto out_release;
++
++              /* sanity checks */
 +              if ((reserved != CDLIM_KEEP &&
 +                      reserved > 100) ||
 +                      (inodes_used != CDLIM_KEEP &&
@@ -20015,16 +19971,16 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/dlimit.c linux-2.6.31.6-vs2.
 +                      dli->dl_inodes_used = inodes_used;
 +              if (inodes_total != CDLIM_KEEP)
 +                      dli->dl_inodes_total = inodes_total;
-+              if (space_used != CDLIM_KEEP) {
-+                      dli->dl_space_used = space_used;
-+                      dli->dl_space_used <<= 10;
-+              }
++              if (space_used != CDLIM_KEEP)
++                      dli->dl_space_used = dlimit_space_32to64(
++                              space_used, flags, DLIMS_USED);
++
 +              if (space_total == CDLIM_INFINITY)
 +                      dli->dl_space_total = DLIM_INFINITY;
-+              else if (space_total != CDLIM_KEEP) {
-+                      dli->dl_space_total = space_total;
-+                      dli->dl_space_total <<= 10;
-+              }
++              else if (space_total != CDLIM_KEEP)
++                      dli->dl_space_total = dlimit_space_32to64(
++                              space_total, flags, DLIMS_TOTAL);
++
 +              if (reserved != CDLIM_KEEP)
 +                      dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
 +
@@ -20098,11 +20054,15 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/dlimit.c linux-2.6.31.6-vs2.
 +              spin_lock(&dli->dl_lock);
 +              *inodes_used = dli->dl_inodes_used;
 +              *inodes_total = dli->dl_inodes_total;
-+              *space_used = dli->dl_space_used >> 10;
++
++              *space_used = dlimit_space_64to32(
++                      dli->dl_space_used, flags, DLIMS_USED);
++
 +              if (dli->dl_space_total == DLIM_INFINITY)
 +                      *space_total = CDLIM_INFINITY;
 +              else
-+                      *space_total = dli->dl_space_total >> 10;
++                      *space_total = dlimit_space_64to32(
++                              dli->dl_space_total, flags, DLIMS_TOTAL);
 +
 +              *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
 +              spin_unlock(&dli->dl_lock);
@@ -20229,9 +20189,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/dlimit.c linux-2.6.31.6-vs2.
 +EXPORT_SYMBOL_GPL(locate_dl_info);
 +EXPORT_SYMBOL_GPL(rcu_free_dl_info);
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/helper.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/helper.c
---- linux-2.6.31.6/kernel/vserver/helper.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/helper.c       2009-11-05 04:22:08.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/helper.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/helper.c
+--- linux-2.6.32/kernel/vserver/helper.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/helper.c 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,199 @@
 +/*
 + *  linux/kernel/vserver/helper.c
@@ -20432,9 +20392,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/helper.c linux-2.6.31.6-vs2.
 +      return do_vshelper(vshelper_path, argv, envp, 1);
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/history.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/history.c
---- linux-2.6.31.6/kernel/vserver/history.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/history.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/history.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/history.c
+--- linux-2.6.32/kernel/vserver/history.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/history.c        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,258 @@
 +/*
 + *  kernel/vserver/history.c
@@ -20694,9 +20654,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/history.c linux-2.6.31.6-vs2
 +
 +#endif        /* CONFIG_COMPAT */
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/inet.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/inet.c
---- linux-2.6.31.6/kernel/vserver/inet.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/inet.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/inet.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/inet.c
+--- linux-2.6.32/kernel/vserver/inet.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/inet.c   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,225 @@
 +
 +#include <linux/in.h>
@@ -20923,9 +20883,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/inet.c linux-2.6.31.6-vs2.3.
 +
 +EXPORT_SYMBOL_GPL(ip_v4_find_src);
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/init.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/init.c
---- linux-2.6.31.6/kernel/vserver/init.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/init.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/init.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/init.c
+--- linux-2.6.32/kernel/vserver/init.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/init.c   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,45 @@
 +/*
 + *  linux/kernel/init.c
@@ -20972,9 +20932,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/init.c linux-2.6.31.6-vs2.3.
 +module_init(init_vserver);
 +module_exit(exit_vserver);
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/inode.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/inode.c
---- linux-2.6.31.6/kernel/vserver/inode.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/inode.c        2009-10-09 20:55:03.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/inode.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/inode.c
+--- linux-2.6.32/kernel/vserver/inode.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/inode.c  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,433 @@
 +/*
 + *  linux/kernel/vserver/inode.c
@@ -21409,9 +21369,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/inode.c linux-2.6.31.6-vs2.3
 +
 +#endif        /* CONFIG_PROPAGATE */
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/Kconfig linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/Kconfig
---- linux-2.6.31.6/kernel/vserver/Kconfig      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/Kconfig        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/Kconfig linux-2.6.32-vs2.3.0.36.26/kernel/vserver/Kconfig
+--- linux-2.6.32/kernel/vserver/Kconfig        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/Kconfig  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,251 @@
 +#
 +# Linux VServer configuration
@@ -21664,9 +21624,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/Kconfig linux-2.6.31.6-vs2.3
 +      default y
 +      select SECURITY_CAPABILITIES
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/limit.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/limit.c
---- linux-2.6.31.6/kernel/vserver/limit.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/limit.c        2009-11-05 04:22:22.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/limit.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/limit.c
+--- linux-2.6.32/kernel/vserver/limit.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/limit.c  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,333 @@
 +/*
 + *  linux/kernel/vserver/limit.c
@@ -22001,9 +21961,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/limit.c linux-2.6.31.6-vs2.3
 +      return points;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/limit_init.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/limit_init.h
---- linux-2.6.31.6/kernel/vserver/limit_init.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/limit_init.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/limit_init.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/limit_init.h
+--- linux-2.6.32/kernel/vserver/limit_init.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/limit_init.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,31 @@
 +
 +
@@ -22036,9 +21996,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/limit_init.h linux-2.6.31.6-
 +      }
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/limit_proc.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/limit_proc.h
---- linux-2.6.31.6/kernel/vserver/limit_proc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/limit_proc.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/limit_proc.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/limit_proc.h
+--- linux-2.6.32/kernel/vserver/limit_proc.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/limit_proc.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,57 @@
 +#ifndef _VX_LIMIT_PROC_H
 +#define _VX_LIMIT_PROC_H
@@ -22097,9 +22057,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/limit_proc.h linux-2.6.31.6-
 +#endif        /* _VX_LIMIT_PROC_H */
 +
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/Makefile linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/Makefile
---- linux-2.6.31.6/kernel/vserver/Makefile     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/Makefile       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/Makefile linux-2.6.32-vs2.3.0.36.26/kernel/vserver/Makefile
+--- linux-2.6.32/kernel/vserver/Makefile       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/Makefile 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,18 @@
 +#
 +# Makefile for the Linux vserver routines.
@@ -22119,9 +22079,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/Makefile linux-2.6.31.6-vs2.
 +vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
 +vserver-$(CONFIG_VSERVER_DEVICE) += device.o
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/monitor.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/monitor.c
---- linux-2.6.31.6/kernel/vserver/monitor.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/monitor.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/monitor.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/monitor.c
+--- linux-2.6.32/kernel/vserver/monitor.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/monitor.c        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,138 @@
 +/*
 + *  kernel/vserver/monitor.c
@@ -22261,9 +22221,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/monitor.c linux-2.6.31.6-vs2
 +
 +#endif        /* CONFIG_COMPAT */
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/network.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/network.c
---- linux-2.6.31.6/kernel/vserver/network.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/network.c      2009-11-05 03:49:07.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/network.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/network.c
+--- linux-2.6.32/kernel/vserver/network.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/network.c        2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,864 @@
 +/*
 + *  linux/kernel/vserver/network.c
@@ -23129,9 +23089,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/network.c linux-2.6.31.6-vs2
 +EXPORT_SYMBOL_GPL(free_nx_info);
 +EXPORT_SYMBOL_GPL(unhash_nx_info);
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/proc.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/proc.c
---- linux-2.6.31.6/kernel/vserver/proc.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/proc.c 2009-09-10 17:45:54.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/proc.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/proc.c
+--- linux-2.6.32/kernel/vserver/proc.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/proc.c   2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,1098 @@
 +/*
 + *  linux/kernel/vserver/proc.c
@@ -24231,9 +24191,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/proc.c linux-2.6.31.6-vs2.3.
 +      return buffer - orig;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sched.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sched.c
---- linux-2.6.31.6/kernel/vserver/sched.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sched.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/sched.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sched.c
+--- linux-2.6.32/kernel/vserver/sched.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sched.c  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,414 @@
 +/*
 + *  linux/kernel/vserver/sched.c
@@ -24649,9 +24609,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sched.c linux-2.6.31.6-vs2.3
 +      return 0;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sched_init.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sched_init.h
---- linux-2.6.31.6/kernel/vserver/sched_init.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sched_init.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/sched_init.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sched_init.h
+--- linux-2.6.32/kernel/vserver/sched_init.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sched_init.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,50 @@
 +
 +static inline void vx_info_init_sched(struct _vx_sched *sched)
@@ -24703,9 +24663,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sched_init.h linux-2.6.31.6-
 +{
 +      return;
 +}
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sched_proc.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sched_proc.h
---- linux-2.6.31.6/kernel/vserver/sched_proc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sched_proc.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/sched_proc.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sched_proc.h
+--- linux-2.6.32/kernel/vserver/sched_proc.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sched_proc.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,57 @@
 +#ifndef _VX_SCHED_PROC_H
 +#define _VX_SCHED_PROC_H
@@ -24764,9 +24724,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sched_proc.h linux-2.6.31.6-
 +}
 +
 +#endif        /* _VX_SCHED_PROC_H */
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/signal.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/signal.c
---- linux-2.6.31.6/kernel/vserver/signal.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/signal.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/signal.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/signal.c
+--- linux-2.6.32/kernel/vserver/signal.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/signal.c 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,132 @@
 +/*
 + *  linux/kernel/vserver/signal.c
@@ -24900,9 +24860,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/signal.c linux-2.6.31.6-vs2.
 +      return ret;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/space.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/space.c
---- linux-2.6.31.6/kernel/vserver/space.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/space.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/space.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/space.c
+--- linux-2.6.32/kernel/vserver/space.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/space.c  2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,375 @@
 +/*
 + *  linux/kernel/vserver/space.c
@@ -25279,9 +25239,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/space.c linux-2.6.31.6-vs2.3
 +      return 0;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/switch.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/switch.c
---- linux-2.6.31.6/kernel/vserver/switch.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/switch.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/switch.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/switch.c
+--- linux-2.6.32/kernel/vserver/switch.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/switch.c 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,546 @@
 +/*
 + *  linux/kernel/vserver/switch.c
@@ -25829,9 +25789,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/switch.c linux-2.6.31.6-vs2.
 +}
 +
 +#endif        /* CONFIG_COMPAT */
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sysctl.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sysctl.c
---- linux-2.6.31.6/kernel/vserver/sysctl.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/sysctl.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/sysctl.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sysctl.c
+--- linux-2.6.32/kernel/vserver/sysctl.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/sysctl.c 2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,244 @@
 +/*
 + *  kernel/vserver/sysctl.c
@@ -26077,9 +26037,9 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/sysctl.c linux-2.6.31.6-vs2.
 +EXPORT_SYMBOL_GPL(vx_debug_space);
 +EXPORT_SYMBOL_GPL(vx_debug_misc);
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/tag.c linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/tag.c
---- linux-2.6.31.6/kernel/vserver/tag.c        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/tag.c  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/tag.c linux-2.6.32-vs2.3.0.36.26/kernel/vserver/tag.c
+--- linux-2.6.32/kernel/vserver/tag.c  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/tag.c    2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,63 @@
 +/*
 + *  linux/kernel/vserver/tag.c
@@ -26144,14 +26104,14 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/tag.c linux-2.6.31.6-vs2.3.0
 +}
 +
 +
-diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/vci_config.h linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/vci_config.h
---- linux-2.6.31.6/kernel/vserver/vci_config.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/kernel/vserver/vci_config.h   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/kernel/vserver/vci_config.h linux-2.6.32-vs2.3.0.36.26/kernel/vserver/vci_config.h
+--- linux-2.6.32/kernel/vserver/vci_config.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/kernel/vserver/vci_config.h     2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,81 @@
 +
 +/*  interface version */
 +
-+#define VCI_VERSION           0x00020304
++#define VCI_VERSION           0x00020305
 +
 +
 +enum {
@@ -26229,9 +26189,29 @@ diff -NurpP --minimal linux-2.6.31.6/kernel/vserver/vci_config.h linux-2.6.31.6-
 +      0;
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/mm/filemap_xip.c linux-2.6.31.6-vs2.3.0.36.24/mm/filemap_xip.c
---- linux-2.6.31.6/mm/filemap_xip.c    2009-06-11 17:13:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/filemap_xip.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/mm/allocpercpu.c linux-2.6.32-vs2.3.0.36.26/mm/allocpercpu.c
+--- linux-2.6.32/mm/allocpercpu.c      2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/allocpercpu.c        2009-12-03 20:04:56.000000000 +0100
+@@ -160,12 +160,14 @@ EXPORT_SYMBOL(__per_cpu_offset);
+ void __init setup_per_cpu_areas(void)
+ {
+-      unsigned long size, i;
++      unsigned long size, vspc, i;
+       char *ptr;
+       unsigned long nr_possible_cpus = num_possible_cpus();
++      vspc = PERCPU_PERCTX * CONFIG_VSERVER_CONTEXTS;
++
+       /* Copy section for each CPU (we discard the original) */
+-      size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
++      size = ALIGN(PERCPU_ENOUGH_ROOM + vspc, PAGE_SIZE);
+       ptr = alloc_bootmem_pages(size * nr_possible_cpus);
+       for_each_possible_cpu(i) {
+diff -NurpP --minimal linux-2.6.32/mm/filemap_xip.c linux-2.6.32-vs2.3.0.36.26/mm/filemap_xip.c
+--- linux-2.6.32/mm/filemap_xip.c      2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/filemap_xip.c        2009-12-03 20:04:56.000000000 +0100
 @@ -17,6 +17,7 @@
  #include <linux/sched.h>
  #include <linux/seqlock.h>
@@ -26240,9 +26220,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/filemap_xip.c linux-2.6.31.6-vs2.3.0.36.
  #include <asm/tlbflush.h>
  #include <asm/io.h>
  
-diff -NurpP --minimal linux-2.6.31.6/mm/fremap.c linux-2.6.31.6-vs2.3.0.36.24/mm/fremap.c
---- linux-2.6.31.6/mm/fremap.c 2009-03-24 14:22:45.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/fremap.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/mm/fremap.c linux-2.6.32-vs2.3.0.36.26/mm/fremap.c
+--- linux-2.6.32/mm/fremap.c   2009-03-24 14:22:45.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/fremap.c     2009-12-03 20:04:56.000000000 +0100
 @@ -16,6 +16,7 @@
  #include <linux/module.h>
  #include <linux/syscalls.h>
@@ -26251,9 +26231,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/fremap.c linux-2.6.31.6-vs2.3.0.36.24/mm
  
  #include <asm/mmu_context.h>
  #include <asm/cacheflush.h>
-diff -NurpP --minimal linux-2.6.31.6/mm/hugetlb.c linux-2.6.31.6-vs2.3.0.36.24/mm/hugetlb.c
---- linux-2.6.31.6/mm/hugetlb.c        2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/hugetlb.c  2009-10-05 23:35:52.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/mm/hugetlb.c linux-2.6.32-vs2.3.0.36.26/mm/hugetlb.c
+--- linux-2.6.32/mm/hugetlb.c  2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/hugetlb.c    2009-12-03 20:04:56.000000000 +0100
 @@ -24,6 +24,7 @@
  #include <asm/io.h>
  
@@ -26262,18 +26242,18 @@ diff -NurpP --minimal linux-2.6.31.6/mm/hugetlb.c linux-2.6.31.6-vs2.3.0.36.24/m
  #include "internal.h"
  
  const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
-diff -NurpP --minimal linux-2.6.31.6/mm/memory.c linux-2.6.31.6-vs2.3.0.36.24/mm/memory.c
---- linux-2.6.31.6/mm/memory.c 2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/memory.c   2009-10-05 23:35:52.000000000 +0200
-@@ -55,6 +55,7 @@
+diff -NurpP --minimal linux-2.6.32/mm/memory.c linux-2.6.32-vs2.3.0.36.26/mm/memory.c
+--- linux-2.6.32/mm/memory.c   2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/memory.c     2009-12-03 20:04:56.000000000 +0100
+@@ -56,6 +56,7 @@
  #include <linux/kallsyms.h>
  #include <linux/swapops.h>
  #include <linux/elf.h>
 +// #include <linux/vs_memory.h>
  
+ #include <asm/io.h>
  #include <asm/pgalloc.h>
- #include <asm/uaccess.h>
-@@ -613,6 +614,9 @@ static int copy_pte_range(struct mm_stru
+@@ -647,6 +648,9 @@ static int copy_pte_range(struct mm_stru
        int progress = 0;
        int rss[2];
  
@@ -26283,7 +26263,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/memory.c linux-2.6.31.6-vs2.3.0.36.24/mm
  again:
        rss[1] = rss[0] = 0;
        dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
-@@ -2627,6 +2631,8 @@ static int do_anonymous_page(struct mm_s
+@@ -2645,6 +2649,8 @@ static int do_anonymous_page(struct mm_s
        /* Allocate our own private page. */
        pte_unmap(page_table);
  
@@ -26292,7 +26272,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/memory.c linux-2.6.31.6-vs2.3.0.36.24/mm
        if (unlikely(anon_vma_prepare(vma)))
                goto oom;
        page = alloc_zeroed_user_highpage_movable(vma, address);
-@@ -2910,6 +2916,7 @@ static inline int handle_pte_fault(struc
+@@ -2936,6 +2942,7 @@ static inline int handle_pte_fault(struc
  {
        pte_t entry;
        spinlock_t *ptl;
@@ -26300,7 +26280,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/memory.c linux-2.6.31.6-vs2.3.0.36.24/mm
  
        entry = *pte;
        if (!pte_present(entry)) {
-@@ -2934,9 +2941,12 @@ static inline int handle_pte_fault(struc
+@@ -2960,9 +2967,12 @@ static inline int handle_pte_fault(struc
        if (unlikely(!pte_same(*pte, entry)))
                goto unlock;
        if (flags & FAULT_FLAG_WRITE) {
@@ -26315,7 +26295,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/memory.c linux-2.6.31.6-vs2.3.0.36.24/mm
                entry = pte_mkdirty(entry);
        }
        entry = pte_mkyoung(entry);
-@@ -2954,7 +2964,10 @@ static inline int handle_pte_fault(struc
+@@ -2980,7 +2990,10 @@ static inline int handle_pte_fault(struc
        }
  unlock:
        pte_unmap_unlock(pte, ptl);
@@ -26327,9 +26307,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/memory.c linux-2.6.31.6-vs2.3.0.36.24/mm
  }
  
  /*
-diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/mlock.c
---- linux-2.6.31.6/mm/mlock.c  2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/mlock.c    2009-10-05 23:35:52.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/mm/mlock.c linux-2.6.32-vs2.3.0.36.26/mm/mlock.c
+--- linux-2.6.32/mm/mlock.c    2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/mlock.c      2009-12-03 20:04:56.000000000 +0100
 @@ -18,6 +18,7 @@
  #include <linux/rmap.h>
  #include <linux/mmzone.h>
@@ -26338,7 +26318,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
  
  #include "internal.h"
  
-@@ -378,7 +379,7 @@ success:
+@@ -401,7 +402,7 @@ success:
        nr_pages = (end - start) >> PAGE_SHIFT;
        if (!lock)
                nr_pages = -nr_pages;
@@ -26347,7 +26327,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
  
        /*
         * vm_flags is protected by the mmap_sem held in write mode.
-@@ -451,7 +452,7 @@ static int do_mlock(unsigned long start,
+@@ -474,7 +475,7 @@ static int do_mlock(unsigned long start,
  
  SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
  {
@@ -26356,7 +26336,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
        unsigned long lock_limit;
        int error = -ENOMEM;
  
-@@ -464,8 +465,10 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
+@@ -487,8 +488,10 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
        len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
        start &= PAGE_MASK;
  
@@ -26369,7 +26349,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
  
        lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
        lock_limit >>= PAGE_SHIFT;
-@@ -473,6 +476,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
+@@ -496,6 +499,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
        /* check against resource limits */
        if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
                error = do_mlock(start, len, 1);
@@ -26377,7 +26357,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
        up_write(&current->mm->mmap_sem);
        return error;
  }
-@@ -534,6 +538,8 @@ SYSCALL_DEFINE1(mlockall, int, flags)
+@@ -557,6 +561,8 @@ SYSCALL_DEFINE1(mlockall, int, flags)
        lock_limit >>= PAGE_SHIFT;
  
        ret = -ENOMEM;
@@ -26386,7 +26366,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
        if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
            capable(CAP_IPC_LOCK))
                ret = do_mlockall(flags);
-@@ -608,8 +614,10 @@ int account_locked_memory(struct mm_stru
+@@ -631,8 +637,10 @@ int account_locked_memory(struct mm_stru
        if (lim < vm)
                goto out;
  
@@ -26399,7 +26379,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
  
        error = 0;
   out:
-@@ -623,8 +631,10 @@ void refund_locked_memory(struct mm_stru
+@@ -646,8 +654,10 @@ void refund_locked_memory(struct mm_stru
  
        down_write(&mm->mmap_sem);
  
@@ -26412,12 +26392,12 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mlock.c linux-2.6.31.6-vs2.3.0.36.24/mm/
  
        up_write(&mm->mmap_sem);
  }
-diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/mmap.c
---- linux-2.6.31.6/mm/mmap.c   2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/mmap.c     2009-10-05 23:35:52.000000000 +0200
-@@ -1222,7 +1222,8 @@ munmap_back:
+diff -NurpP --minimal linux-2.6.32/mm/mmap.c linux-2.6.32-vs2.3.0.36.26/mm/mmap.c
+--- linux-2.6.32/mm/mmap.c     2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/mmap.c       2009-12-03 20:04:56.000000000 +0100
+@@ -1236,7 +1236,8 @@ munmap_back:
  out:
-       perf_counter_mmap(vma);
+       perf_event_mmap(vma);
  
 -      mm->total_vm += len >> PAGE_SHIFT;
 +      // mm->total_vm += len >> PAGE_SHIFT;
@@ -26425,7 +26405,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
        vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
        if (vm_flags & VM_LOCKED) {
                /*
-@@ -1231,7 +1232,8 @@ out:
+@@ -1245,7 +1246,8 @@ out:
                long nr_pages = mlock_vma_pages_range(vma, addr, addr + len);
                if (nr_pages < 0)
                        return nr_pages;        /* vma gone! */
@@ -26435,7 +26415,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
        } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
                make_pages_present(addr, addr + len);
        return addr;
-@@ -1578,9 +1580,9 @@ static int acct_stack_growth(struct vm_a
+@@ -1592,9 +1594,9 @@ static int acct_stack_growth(struct vm_a
                return -ENOMEM;
  
        /* Ok, everything looks good - let it rip */
@@ -26447,7 +26427,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
        vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
        return 0;
  }
-@@ -1755,7 +1757,8 @@ static void remove_vma_list(struct mm_st
+@@ -1769,7 +1771,8 @@ static void remove_vma_list(struct mm_st
        do {
                long nrpages = vma_pages(vma);
  
@@ -26457,7 +26437,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
                vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
                vma = remove_vma(vma);
        } while (vma);
-@@ -1927,7 +1930,8 @@ int do_munmap(struct mm_struct *mm, unsi
+@@ -1941,7 +1944,8 @@ int do_munmap(struct mm_struct *mm, unsi
                struct vm_area_struct *tmp = vma;
                while (tmp && tmp->vm_start < end) {
                        if (tmp->vm_flags & VM_LOCKED) {
@@ -26467,7 +26447,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
                                munlock_vma_pages_all(tmp);
                        }
                        tmp = tmp->vm_next;
-@@ -2016,6 +2020,8 @@ unsigned long do_brk(unsigned long addr,
+@@ -2030,6 +2034,8 @@ unsigned long do_brk(unsigned long addr,
                lock_limit >>= PAGE_SHIFT;
                if (locked > lock_limit && !capable(CAP_IPC_LOCK))
                        return -EAGAIN;
@@ -26476,7 +26456,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
        }
  
        /*
-@@ -2042,7 +2048,8 @@ unsigned long do_brk(unsigned long addr,
+@@ -2056,7 +2062,8 @@ unsigned long do_brk(unsigned long addr,
        if (mm->map_count > sysctl_max_map_count)
                return -ENOMEM;
  
@@ -26486,7 +26466,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
                return -ENOMEM;
  
        /* Can we just expand an old private anonymous mapping? */
-@@ -2068,10 +2075,13 @@ unsigned long do_brk(unsigned long addr,
+@@ -2082,10 +2089,13 @@ unsigned long do_brk(unsigned long addr,
        vma->vm_page_prot = vm_get_page_prot(flags);
        vma_link(mm, vma, prev, rb_link, rb_parent);
  out:
@@ -26502,7 +26482,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
        }
        return addr;
  }
-@@ -2114,6 +2124,11 @@ void exit_mmap(struct mm_struct *mm)
+@@ -2129,6 +2139,11 @@ void exit_mmap(struct mm_struct *mm)
        free_pgtables(tlb, vma, FIRST_USER_ADDRESS, 0);
        tlb_finish_mmu(tlb, 0, end);
  
@@ -26514,7 +26494,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
        /*
         * Walk the list again, actually closing and freeing it,
         * with preemption enabled, without holding any MM locks.
-@@ -2153,7 +2168,8 @@ int insert_vm_struct(struct mm_struct * 
+@@ -2168,7 +2183,8 @@ int insert_vm_struct(struct mm_struct * 
        if (__vma && __vma->vm_start < vma->vm_end)
                return -ENOMEM;
        if ((vma->vm_flags & VM_ACCOUNT) &&
@@ -26524,7 +26504,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
                return -ENOMEM;
        vma_link(mm, vma, prev, rb_link, rb_parent);
        return 0;
-@@ -2229,6 +2245,8 @@ int may_expand_vm(struct mm_struct *mm, 
+@@ -2244,6 +2260,8 @@ int may_expand_vm(struct mm_struct *mm, 
  
        if (cur + npages > lim)
                return 0;
@@ -26533,19 +26513,19 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/m
        return 1;
  }
  
-@@ -2306,7 +2324,7 @@ int install_special_mapping(struct mm_st
+@@ -2321,7 +2339,7 @@ int install_special_mapping(struct mm_st
                return -ENOMEM;
        }
  
 -      mm->total_vm += len >> PAGE_SHIFT;
 +      vx_vmpages_add(mm, len >> PAGE_SHIFT);
  
-       perf_counter_mmap(vma);
+       perf_event_mmap(vma);
  
-diff -NurpP --minimal linux-2.6.31.6/mm/mremap.c linux-2.6.31.6-vs2.3.0.36.24/mm/mremap.c
---- linux-2.6.31.6/mm/mremap.c 2009-03-24 14:22:45.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/mremap.c   2009-09-10 16:11:43.000000000 +0200
-@@ -19,6 +19,7 @@
+diff -NurpP --minimal linux-2.6.32/mm/mremap.c linux-2.6.32-vs2.3.0.36.26/mm/mremap.c
+--- linux-2.6.32/mm/mremap.c   2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/mremap.c     2009-12-03 20:04:56.000000000 +0100
+@@ -20,6 +20,7 @@
  #include <linux/security.h>
  #include <linux/syscalls.h>
  #include <linux/mmu_notifier.h>
@@ -26553,7 +26533,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mremap.c linux-2.6.31.6-vs2.3.0.36.24/mm
  
  #include <asm/uaccess.h>
  #include <asm/cacheflush.h>
-@@ -220,7 +221,7 @@ static unsigned long move_vma(struct vm_
+@@ -234,7 +235,7 @@ static unsigned long move_vma(struct vm_
         * If this were a serious issue, we'd add a flag to do_munmap().
         */
        hiwater_vm = mm->hiwater_vm;
@@ -26562,7 +26542,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mremap.c linux-2.6.31.6-vs2.3.0.36.24/mm
        vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
  
        if (do_munmap(mm, old_addr, old_len) < 0) {
-@@ -238,7 +239,7 @@ static unsigned long move_vma(struct vm_
+@@ -252,7 +253,7 @@ static unsigned long move_vma(struct vm_
        }
  
        if (vm_flags & VM_LOCKED) {
@@ -26571,7 +26551,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mremap.c linux-2.6.31.6-vs2.3.0.36.24/mm
                if (new_len > old_len)
                        mlock_vma_pages_range(new_vma, new_addr + old_len,
                                                       new_addr + new_len);
-@@ -349,6 +350,9 @@ unsigned long do_mremap(unsigned long ad
+@@ -363,6 +364,9 @@ unsigned long do_mremap(unsigned long ad
                ret = -EAGAIN;
                if (locked > lock_limit && !capable(CAP_IPC_LOCK))
                        goto out;
@@ -26581,7 +26561,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mremap.c linux-2.6.31.6-vs2.3.0.36.24/mm
        }
        if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
                ret = -ENOMEM;
-@@ -377,10 +381,12 @@ unsigned long do_mremap(unsigned long ad
+@@ -391,10 +395,12 @@ unsigned long do_mremap(unsigned long ad
                        vma_adjust(vma, vma->vm_start,
                                addr + new_len, vma->vm_pgoff, NULL);
  
@@ -26596,10 +26576,10 @@ diff -NurpP --minimal linux-2.6.31.6/mm/mremap.c linux-2.6.31.6-vs2.3.0.36.24/mm
                                mlock_vma_pages_range(vma, addr + old_len,
                                                   addr + new_len);
                        }
-diff -NurpP --minimal linux-2.6.31.6/mm/nommu.c linux-2.6.31.6-vs2.3.0.36.24/mm/nommu.c
---- linux-2.6.31.6/mm/nommu.c  2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/nommu.c    2009-11-12 12:26:38.000000000 +0100
-@@ -1368,7 +1368,7 @@ unsigned long do_mmap_pgoff(struct file 
+diff -NurpP --minimal linux-2.6.32/mm/nommu.c linux-2.6.32-vs2.3.0.36.26/mm/nommu.c
+--- linux-2.6.32/mm/nommu.c    2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/nommu.c      2009-12-03 20:04:56.000000000 +0100
+@@ -1346,7 +1346,7 @@ unsigned long do_mmap_pgoff(struct file 
        /* okay... we have a mapping; now we have to register it */
        result = vma->vm_start;
  
@@ -26608,7 +26588,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/nommu.c linux-2.6.31.6-vs2.3.0.36.24/mm/
  
  share:
        add_vma_to_mm(current->mm, vma);
-@@ -1628,7 +1628,7 @@ void exit_mmap(struct mm_struct *mm)
+@@ -1606,7 +1606,7 @@ void exit_mmap(struct mm_struct *mm)
  
        kenter("");
  
@@ -26617,9 +26597,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/nommu.c linux-2.6.31.6-vs2.3.0.36.24/mm/
  
        while ((vma = mm->mmap)) {
                mm->mmap = vma->vm_next;
-diff -NurpP --minimal linux-2.6.31.6/mm/oom_kill.c linux-2.6.31.6-vs2.3.0.36.24/mm/oom_kill.c
---- linux-2.6.31.6/mm/oom_kill.c       2009-06-11 17:13:27.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/oom_kill.c 2009-11-12 12:50:49.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/mm/oom_kill.c linux-2.6.32-vs2.3.0.36.26/mm/oom_kill.c
+--- linux-2.6.32/mm/oom_kill.c 2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/oom_kill.c   2009-12-03 20:04:56.000000000 +0100
 @@ -27,6 +27,8 @@
  #include <linux/notifier.h>
  #include <linux/memcontrol.h>
@@ -26629,8 +26609,8 @@ diff -NurpP --minimal linux-2.6.31.6/mm/oom_kill.c linux-2.6.31.6-vs2.3.0.36.24/
  
  int sysctl_panic_on_oom;
  int sysctl_oom_kill_allocating_task;
-@@ -159,9 +161,21 @@ unsigned long badness(struct task_struct
-                       points >>= -(p->oomkilladj);
+@@ -186,9 +188,21 @@ unsigned long badness(struct task_struct
+                       points >>= -(oom_adj);
        }
  
 +      /*
@@ -26653,7 +26633,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/oom_kill.c linux-2.6.31.6-vs2.3.0.36.24/
  #endif
        return points;
  }
-@@ -215,8 +229,8 @@ static struct task_struct *select_bad_pr
+@@ -242,8 +256,8 @@ static struct task_struct *select_bad_pr
                 */
                if (!p->mm)
                        continue;
@@ -26664,7 +26644,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/oom_kill.c linux-2.6.31.6-vs2.3.0.36.24/
                        continue;
                if (mem && !task_in_mem_cgroup(p, mem))
                        continue;
-@@ -330,8 +344,8 @@ static void __oom_kill_task(struct task_
+@@ -357,8 +371,8 @@ static void __oom_kill_task(struct task_
        }
  
        if (verbose)
@@ -26675,7 +26655,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/oom_kill.c linux-2.6.31.6-vs2.3.0.36.24/
  
        /*
         * We give our sacrificial lamb high priority and access to
-@@ -415,8 +429,8 @@ static int oom_kill_process(struct task_
+@@ -419,8 +433,8 @@ static int oom_kill_process(struct task_
                return 0;
        }
  
@@ -26686,19 +26666,19 @@ diff -NurpP --minimal linux-2.6.31.6/mm/oom_kill.c linux-2.6.31.6-vs2.3.0.36.24/
  
        /* Try to kill a child first */
        list_for_each_entry(c, &p->children, sibling) {
-diff -NurpP --minimal linux-2.6.31.6/mm/page_alloc.c linux-2.6.31.6-vs2.3.0.36.24/mm/page_alloc.c
---- linux-2.6.31.6/mm/page_alloc.c     2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/page_alloc.c       2009-10-05 23:35:52.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/mm/page_alloc.c linux-2.6.32-vs2.3.0.36.26/mm/page_alloc.c
+--- linux-2.6.32/mm/page_alloc.c       2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/page_alloc.c 2009-12-03 20:04:56.000000000 +0100
 @@ -48,6 +48,8 @@
  #include <linux/page_cgroup.h>
  #include <linux/debugobjects.h>
  #include <linux/kmemleak.h>
 +#include <linux/vs_base.h>
 +#include <linux/vs_limit.h>
+ #include <trace/events/kmem.h>
  
  #include <asm/tlbflush.h>
- #include <asm/div64.h>
-@@ -2078,6 +2080,9 @@ void si_meminfo(struct sysinfo *val)
+@@ -2130,6 +2132,9 @@ void si_meminfo(struct sysinfo *val)
        val->totalhigh = totalhigh_pages;
        val->freehigh = nr_free_highpages();
        val->mem_unit = PAGE_SIZE;
@@ -26708,7 +26688,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/page_alloc.c linux-2.6.31.6-vs2.3.0.36.2
  }
  
  EXPORT_SYMBOL(si_meminfo);
-@@ -2098,6 +2103,9 @@ void si_meminfo_node(struct sysinfo *val
+@@ -2150,6 +2155,9 @@ void si_meminfo_node(struct sysinfo *val
        val->freehigh = 0;
  #endif
        val->mem_unit = PAGE_SIZE;
@@ -26718,10 +26698,10 @@ diff -NurpP --minimal linux-2.6.31.6/mm/page_alloc.c linux-2.6.31.6-vs2.3.0.36.2
  }
  #endif
  
-diff -NurpP --minimal linux-2.6.31.6/mm/rmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/rmap.c
---- linux-2.6.31.6/mm/rmap.c   2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/rmap.c     2009-09-10 16:11:43.000000000 +0200
-@@ -50,6 +50,7 @@
+diff -NurpP --minimal linux-2.6.32/mm/rmap.c linux-2.6.32-vs2.3.0.36.26/mm/rmap.c
+--- linux-2.6.32/mm/rmap.c     2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/rmap.c       2009-12-03 20:04:56.000000000 +0100
+@@ -55,6 +55,7 @@
  #include <linux/memcontrol.h>
  #include <linux/mmu_notifier.h>
  #include <linux/migrate.h>
@@ -26729,10 +26709,10 @@ diff -NurpP --minimal linux-2.6.31.6/mm/rmap.c linux-2.6.31.6-vs2.3.0.36.24/mm/r
  
  #include <asm/tlbflush.h>
  
-diff -NurpP --minimal linux-2.6.31.6/mm/shmem.c linux-2.6.31.6-vs2.3.0.36.24/mm/shmem.c
---- linux-2.6.31.6/mm/shmem.c  2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/shmem.c    2009-09-10 16:11:43.000000000 +0200
-@@ -1777,7 +1777,7 @@ static int shmem_statfs(struct dentry *d
+diff -NurpP --minimal linux-2.6.32/mm/shmem.c linux-2.6.32-vs2.3.0.36.26/mm/shmem.c
+--- linux-2.6.32/mm/shmem.c    2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/shmem.c      2009-12-03 20:04:56.000000000 +0100
+@@ -1781,7 +1781,7 @@ static int shmem_statfs(struct dentry *d
  {
        struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
  
@@ -26741,7 +26721,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/shmem.c linux-2.6.31.6-vs2.3.0.36.24/mm/
        buf->f_bsize = PAGE_CACHE_SIZE;
        buf->f_namelen = NAME_MAX;
        spin_lock(&sbinfo->stat_lock);
-@@ -2346,7 +2346,7 @@ static int shmem_fill_super(struct super
+@@ -2346,7 +2346,7 @@ int shmem_fill_super(struct super_block 
        sb->s_maxbytes = SHMEM_MAX_BYTES;
        sb->s_blocksize = PAGE_CACHE_SIZE;
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -26750,9 +26730,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/shmem.c linux-2.6.31.6-vs2.3.0.36.24/mm/
        sb->s_op = &shmem_ops;
        sb->s_time_gran = 1;
  #ifdef CONFIG_TMPFS_POSIX_ACL
-diff -NurpP --minimal linux-2.6.31.6/mm/slab.c linux-2.6.31.6-vs2.3.0.36.24/mm/slab.c
---- linux-2.6.31.6/mm/slab.c   2009-09-10 15:26:28.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/slab.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/mm/slab.c linux-2.6.32-vs2.3.0.36.26/mm/slab.c
+--- linux-2.6.32/mm/slab.c     2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/slab.c       2009-12-03 20:04:56.000000000 +0100
 @@ -431,6 +431,8 @@ static void kmem_list3_init(struct kmem_
  #define STATS_INC_FREEMISS(x) do { } while (0)
  #endif
@@ -26786,9 +26766,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/slab.c linux-2.6.31.6-vs2.3.0.36.24/mm/s
  
        kmemcheck_slab_free(cachep, objp, obj_size(cachep));
  
-diff -NurpP --minimal linux-2.6.31.6/mm/slab_vs.h linux-2.6.31.6-vs2.3.0.36.24/mm/slab_vs.h
---- linux-2.6.31.6/mm/slab_vs.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/slab_vs.h  2009-11-05 04:25:04.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/mm/slab_vs.h linux-2.6.32-vs2.3.0.36.26/mm/slab_vs.h
+--- linux-2.6.32/mm/slab_vs.h  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/slab_vs.h    2009-12-03 20:04:56.000000000 +0100
 @@ -0,0 +1,29 @@
 +
 +#include <linux/vserver/context.h>
@@ -26819,9 +26799,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/slab_vs.h linux-2.6.31.6-vs2.3.0.36.24/m
 +      atomic_sub(cachep->buffer_size, &vxi->cacct.slab[what]);
 +}
 +
-diff -NurpP --minimal linux-2.6.31.6/mm/swapfile.c linux-2.6.31.6-vs2.3.0.36.24/mm/swapfile.c
---- linux-2.6.31.6/mm/swapfile.c       2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/mm/swapfile.c 2009-11-12 12:26:38.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/mm/swapfile.c linux-2.6.32-vs2.3.0.36.26/mm/swapfile.c
+--- linux-2.6.32/mm/swapfile.c 2009-12-03 20:02:58.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/mm/swapfile.c   2009-12-03 20:04:56.000000000 +0100
 @@ -34,6 +34,8 @@
  #include <asm/tlbflush.h>
  #include <linux/swapops.h>
@@ -26831,7 +26811,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/swapfile.c linux-2.6.31.6-vs2.3.0.36.24/
  
  static DEFINE_SPINLOCK(swap_lock);
  static unsigned int nr_swapfiles;
-@@ -1678,6 +1680,8 @@ static void *swap_next(struct seq_file *
+@@ -1680,6 +1682,8 @@ static void *swap_next(struct seq_file *
        if (v == SEQ_START_TOKEN)
                ptr = swap_info;
        else {
@@ -26840,7 +26820,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/swapfile.c linux-2.6.31.6-vs2.3.0.36.24/
                ptr = v;
                ptr++;
        }
-@@ -1705,6 +1709,16 @@ static int swap_show(struct seq_file *sw
+@@ -1707,6 +1711,16 @@ static int swap_show(struct seq_file *sw
  
        if (ptr == SEQ_START_TOKEN) {
                seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
@@ -26857,7 +26837,7 @@ diff -NurpP --minimal linux-2.6.31.6/mm/swapfile.c linux-2.6.31.6-vs2.3.0.36.24/
                return 0;
        }
  
-@@ -2060,6 +2074,8 @@ void si_swapinfo(struct sysinfo *val)
+@@ -2064,6 +2078,8 @@ void si_swapinfo(struct sysinfo *val)
        val->freeswap = nr_swap_pages + nr_to_be_unused;
        val->totalswap = total_swap_pages + nr_to_be_unused;
        spin_unlock(&swap_lock);
@@ -26866,9 +26846,9 @@ diff -NurpP --minimal linux-2.6.31.6/mm/swapfile.c linux-2.6.31.6-vs2.3.0.36.24/
  }
  
  /*
-diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24/net/core/dev.c
---- linux-2.6.31.6/net/core/dev.c      2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/core/dev.c        2009-11-08 16:59:44.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/net/core/dev.c linux-2.6.32-vs2.3.0.36.26/net/core/dev.c
+--- linux-2.6.32/net/core/dev.c        2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/core/dev.c  2009-12-03 20:04:56.000000000 +0100
 @@ -126,6 +126,7 @@
  #include <linux/in.h>
  #include <linux/jhash.h>
@@ -26877,7 +26857,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
  #include <trace/events/napi.h>
  
  #include "net-sysfs.h"
-@@ -586,7 +587,8 @@ struct net_device *__dev_get_by_name(str
+@@ -591,7 +592,8 @@ struct net_device *__dev_get_by_name(str
        hlist_for_each(p, dev_name_hash(net, name)) {
                struct net_device *dev
                        = hlist_entry(p, struct net_device, name_hlist);
@@ -26887,7 +26867,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
                        return dev;
        }
        return NULL;
-@@ -635,7 +637,8 @@ struct net_device *__dev_get_by_index(st
+@@ -642,7 +644,8 @@ struct net_device *__dev_get_by_index(st
        hlist_for_each(p, dev_index_hash(net, ifindex)) {
                struct net_device *dev
                        = hlist_entry(p, struct net_device, index_hlist);
@@ -26897,7 +26877,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
                        return dev;
        }
        return NULL;
-@@ -686,10 +689,12 @@ struct net_device *dev_getbyhwaddr(struc
+@@ -695,10 +698,12 @@ struct net_device *dev_getbyhwaddr(struc
  
        ASSERT_RTNL();
  
@@ -26912,7 +26892,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
  
        return NULL;
  }
-@@ -701,9 +706,11 @@ struct net_device *__dev_getfirstbyhwtyp
+@@ -709,9 +714,11 @@ struct net_device *__dev_getfirstbyhwtyp
        struct net_device *dev;
  
        ASSERT_RTNL();
@@ -26926,7 +26906,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
  
        return NULL;
  }
-@@ -821,6 +828,8 @@ static int __dev_alloc_name(struct net *
+@@ -830,6 +837,8 @@ static int __dev_alloc_name(struct net *
                                continue;
                        if (i < 0 || i >= max_netdevices)
                                continue;
@@ -26935,7 +26915,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
  
                        /*  avoid cases where sscanf is not exact inverse of printf */
                        snprintf(buf, IFNAMSIZ, name, i);
-@@ -2941,6 +2950,8 @@ static int dev_ifconf(struct net *net, c
+@@ -2984,6 +2993,8 @@ static int dev_ifconf(struct net *net, c
  
        total = 0;
        for_each_netdev(net, dev) {
@@ -26944,7 +26924,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
                for (i = 0; i < NPROTO; i++) {
                        if (gifconf_list[i]) {
                                int done;
-@@ -3009,6 +3020,9 @@ static void dev_seq_printf_stats(struct 
+@@ -3052,6 +3063,9 @@ static void dev_seq_printf_stats(struct 
  {
        const struct net_device_stats *stats = dev_get_stats(dev);
  
@@ -26954,7 +26934,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
        seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
                   "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
                   dev->name, stats->rx_bytes, stats->rx_packets,
-@@ -5257,6 +5271,15 @@ int dev_change_net_namespace(struct net_
+@@ -5313,6 +5327,15 @@ int dev_change_net_namespace(struct net_
                goto out;
  #endif
  
@@ -26970,32 +26950,10 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/dev.c linux-2.6.31.6-vs2.3.0.36.24
        /* Ensure the device has been registrered */
        err = -EINVAL;
        if (dev->reg_state != NETREG_REGISTERED)
-@@ -5317,6 +5340,8 @@ int dev_change_net_namespace(struct net_
-       netdev_unregister_kobject(dev);
-+      netdev_unregister_kobject(dev);
-+
-       /* Actually switch the network namespace */
-       dev_net_set(dev, net);
-diff -NurpP --minimal linux-2.6.31.6/net/core/net-sysfs.c linux-2.6.31.6-vs2.3.0.36.24/net/core/net-sysfs.c
---- linux-2.6.31.6/net/core/net-sysfs.c        2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/core/net-sysfs.c  2009-09-10 16:11:43.000000000 +0200
-@@ -513,6 +513,9 @@ int netdev_register_kobject(struct net_d
-       if (dev_net(net) != &init_net)
-               return 0;
-+      if (dev_net(net) != &init_net)
-+              return 0;
-+
-       return device_add(dev);
- }
-diff -NurpP --minimal linux-2.6.31.6/net/core/rtnetlink.c linux-2.6.31.6-vs2.3.0.36.24/net/core/rtnetlink.c
---- linux-2.6.31.6/net/core/rtnetlink.c        2009-06-11 17:13:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/core/rtnetlink.c  2009-11-05 03:50:06.000000000 +0100
-@@ -690,6 +690,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
+diff -NurpP --minimal linux-2.6.32/net/core/rtnetlink.c linux-2.6.32-vs2.3.0.36.26/net/core/rtnetlink.c
+--- linux-2.6.32/net/core/rtnetlink.c  2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/core/rtnetlink.c    2009-12-03 20:04:56.000000000 +0100
+@@ -688,6 +688,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
  
        idx = 0;
        for_each_netdev(net, dev) {
@@ -27004,7 +26962,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/rtnetlink.c linux-2.6.31.6-vs2.3.0
                if (idx < s_idx)
                        goto cont;
                if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
-@@ -1235,6 +1237,9 @@ void rtmsg_ifinfo(int type, struct net_d
+@@ -1222,6 +1224,9 @@ void rtmsg_ifinfo(int type, struct net_d
        struct sk_buff *skb;
        int err = -ENOBUFS;
  
@@ -27014,9 +26972,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/rtnetlink.c linux-2.6.31.6-vs2.3.0
        skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
        if (skb == NULL)
                goto errout;
-diff -NurpP --minimal linux-2.6.31.6/net/core/sock.c linux-2.6.31.6-vs2.3.0.36.24/net/core/sock.c
---- linux-2.6.31.6/net/core/sock.c     2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/core/sock.c       2009-11-05 04:25:28.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/net/core/sock.c linux-2.6.32-vs2.3.0.36.26/net/core/sock.c
+--- linux-2.6.32/net/core/sock.c       2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/core/sock.c 2009-12-03 20:04:56.000000000 +0100
 @@ -125,6 +125,10 @@
  #include <linux/ipsec.h>
  
@@ -27028,7 +26986,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/sock.c linux-2.6.31.6-vs2.3.0.36.2
  
  #ifdef CONFIG_INET
  #include <net/tcp.h>
-@@ -974,6 +978,8 @@ static struct sock *sk_prot_alloc(struct
+@@ -984,6 +988,8 @@ static struct sock *sk_prot_alloc(struct
                if (!try_module_get(prot->owner))
                        goto out_free_sec;
        }
@@ -27037,7 +26995,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/sock.c linux-2.6.31.6-vs2.3.0.36.2
  
        return sk;
  
-@@ -1053,6 +1059,11 @@ static void __sk_free(struct sock *sk)
+@@ -1063,6 +1069,11 @@ static void __sk_free(struct sock *sk)
                       __func__, atomic_read(&sk->sk_omem_alloc));
  
        put_net(sock_net(sk));
@@ -27049,7 +27007,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/sock.c linux-2.6.31.6-vs2.3.0.36.2
        sk_prot_free(sk->sk_prot_creator, sk);
  }
  
-@@ -1100,6 +1111,8 @@ struct sock *sk_clone(const struct sock 
+@@ -1110,6 +1121,8 @@ struct sock *sk_clone(const struct sock 
  
                /* SANITY */
                get_net(sock_net(newsk));
@@ -27058,7 +27016,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/sock.c linux-2.6.31.6-vs2.3.0.36.2
                sk_node_init(&newsk->sk_node);
                sock_lock_init(newsk);
                bh_lock_sock(newsk);
-@@ -1154,6 +1167,12 @@ struct sock *sk_clone(const struct sock 
+@@ -1164,6 +1177,12 @@ struct sock *sk_clone(const struct sock 
                smp_wmb();
                atomic_set(&newsk->sk_refcnt, 2);
  
@@ -27071,7 +27029,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/sock.c linux-2.6.31.6-vs2.3.0.36.2
                /*
                 * Increment the counter in the same struct proto as the master
                 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
-@@ -1872,6 +1891,12 @@ void sock_init_data(struct socket *sock,
+@@ -1882,6 +1901,12 @@ void sock_init_data(struct socket *sock,
  
        sk->sk_stamp = ktime_set(-1L, 0);
  
@@ -27084,9 +27042,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/core/sock.c linux-2.6.31.6-vs2.3.0.36.2
        /*
         * Before updating sk_refcnt, we must commit prior changes to memory
         * (Documentation/RCU/rculist_nulls.txt for details)
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/af_inet.c
---- linux-2.6.31.6/net/ipv4/af_inet.c  2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/af_inet.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/af_inet.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/af_inet.c
+--- linux-2.6.32/net/ipv4/af_inet.c    2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/af_inet.c      2009-12-03 20:04:56.000000000 +0100
 @@ -115,6 +115,7 @@
  #ifdef CONFIG_IP_MROUTE
  #include <linux/mroute.h>
@@ -27095,7 +27053,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.3
  
  
  /* The inetsw table contains everything that inet_create needs to
-@@ -324,9 +325,12 @@ lookup_protocol:
+@@ -325,9 +326,12 @@ lookup_protocol:
        }
  
        err = -EPERM;
@@ -27109,7 +27067,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.3
        err = -EAFNOSUPPORT;
        if (!inet_netns_ok(net, protocol))
                goto out_rcu_unlock;
-@@ -444,6 +448,7 @@ int inet_bind(struct socket *sock, struc
+@@ -447,6 +451,7 @@ int inet_bind(struct socket *sock, struc
        struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
        struct sock *sk = sock->sk;
        struct inet_sock *inet = inet_sk(sk);
@@ -27117,7 +27075,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.3
        unsigned short snum;
        int chk_addr_ret;
        int err;
-@@ -457,7 +462,11 @@ int inet_bind(struct socket *sock, struc
+@@ -460,7 +465,11 @@ int inet_bind(struct socket *sock, struc
        if (addr_len < sizeof(struct sockaddr_in))
                goto out;
  
@@ -27130,7 +27088,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.3
  
        /* Not specified by any standard per-se, however it breaks too
         * many applications when removed.  It is unfortunate since
-@@ -469,7 +478,7 @@ int inet_bind(struct socket *sock, struc
+@@ -472,7 +481,7 @@ int inet_bind(struct socket *sock, struc
        err = -EADDRNOTAVAIL;
        if (!sysctl_ip_nonlocal_bind &&
            !(inet->freebind || inet->transparent) &&
@@ -27139,7 +27097,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.3
            chk_addr_ret != RTN_LOCAL &&
            chk_addr_ret != RTN_MULTICAST &&
            chk_addr_ret != RTN_BROADCAST)
-@@ -494,7 +503,7 @@ int inet_bind(struct socket *sock, struc
+@@ -497,7 +506,7 @@ int inet_bind(struct socket *sock, struc
        if (sk->sk_state != TCP_CLOSE || inet->num)
                goto out_release_sock;
  
@@ -27148,7 +27106,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.3
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->saddr = 0;  /* Use device */
  
-@@ -687,11 +696,13 @@ int inet_getname(struct socket *sock, st
+@@ -694,11 +703,13 @@ int inet_getname(struct socket *sock, st
                     peer == 1))
                        return -ENOTCONN;
                sin->sin_port = inet->dport;
@@ -27163,9 +27121,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/af_inet.c linux-2.6.31.6-vs2.3.0.3
                sin->sin_port = inet->sport;
                sin->sin_addr.s_addr = addr;
        }
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/devinet.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/devinet.c
---- linux-2.6.31.6/net/ipv4/devinet.c  2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/devinet.c    2009-11-05 03:50:40.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/net/ipv4/devinet.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/devinet.c
+--- linux-2.6.32/net/ipv4/devinet.c    2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/devinet.c      2009-12-03 20:04:56.000000000 +0100
 @@ -413,6 +413,7 @@ struct in_device *inetdev_by_index(struc
        return in_dev;
  }
@@ -27215,7 +27173,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/devinet.c linux-2.6.31.6-vs2.3.0.3
                if (!buf) {
                        done += sizeof(ifr);
                        continue;
-@@ -1164,6 +1174,7 @@ static int inet_dump_ifaddr(struct sk_bu
+@@ -1174,6 +1184,7 @@ static int inet_dump_ifaddr(struct sk_bu
        struct net_device *dev;
        struct in_device *in_dev;
        struct in_ifaddr *ifa;
@@ -27223,7 +27181,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/devinet.c linux-2.6.31.6-vs2.3.0.3
        int s_ip_idx, s_idx = cb->args[0];
  
        s_ip_idx = ip_idx = cb->args[1];
-@@ -1178,6 +1189,8 @@ static int inet_dump_ifaddr(struct sk_bu
+@@ -1188,6 +1199,8 @@ static int inet_dump_ifaddr(struct sk_bu
  
                for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
                     ifa = ifa->ifa_next, ip_idx++) {
@@ -27232,9 +27190,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/devinet.c linux-2.6.31.6-vs2.3.0.3
                        if (ip_idx < s_ip_idx)
                                continue;
                        if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/fib_hash.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/fib_hash.c
---- linux-2.6.31.6/net/ipv4/fib_hash.c 2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/fib_hash.c   2009-11-05 03:50:54.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/net/ipv4/fib_hash.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/fib_hash.c
+--- linux-2.6.32/net/ipv4/fib_hash.c   2009-09-10 15:26:29.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/fib_hash.c     2009-12-03 20:04:56.000000000 +0100
 @@ -1021,7 +1021,7 @@ static int fib_seq_show(struct seq_file 
        prefix  = f->fn_key;
        mask    = FZ_MASK(iter->zone);
@@ -27244,9 +27202,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/fib_hash.c linux-2.6.31.6-vs2.3.0.
                seq_printf(seq,
                         "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n",
                         fi->fib_dev ? fi->fib_dev->name : "*", prefix,
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/inet_connection_sock.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/inet_connection_sock.c
---- linux-2.6.31.6/net/ipv4/inet_connection_sock.c     2009-06-11 17:13:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/inet_connection_sock.c       2009-11-05 04:54:58.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/net/ipv4/inet_connection_sock.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/inet_connection_sock.c
+--- linux-2.6.32/net/ipv4/inet_connection_sock.c       2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/inet_connection_sock.c 2009-12-03 20:04:56.000000000 +0100
 @@ -49,10 +49,40 @@ void inet_get_local_port_range(int *low,
  }
  EXPORT_SYMBOL(inet_get_local_port_range);
@@ -27300,9 +27258,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/inet_connection_sock.c linux-2.6.3
                                        break;
                        }
                }
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/inet_diag.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/inet_diag.c
---- linux-2.6.31.6/net/ipv4/inet_diag.c        2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/inet_diag.c  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/inet_diag.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/inet_diag.c
+--- linux-2.6.32/net/ipv4/inet_diag.c  2009-09-10 15:26:29.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/inet_diag.c    2009-12-03 20:04:56.000000000 +0100
 @@ -32,6 +32,8 @@
  #include <linux/stddef.h>
  
@@ -27404,9 +27362,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/inet_diag.c linux-2.6.31.6-vs2.3.0
                                if (num < s_num)
                                        goto next_dying;
                                if (r->id.idiag_sport != tw->tw_sport &&
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/inet_hashtables.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/inet_hashtables.c
---- linux-2.6.31.6/net/ipv4/inet_hashtables.c  2009-06-11 17:13:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/inet_hashtables.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/inet_hashtables.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/inet_hashtables.c
+--- linux-2.6.32/net/ipv4/inet_hashtables.c    2009-06-11 17:13:29.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/inet_hashtables.c      2009-12-03 20:04:56.000000000 +0100
 @@ -21,6 +21,7 @@
  
  #include <net/inet_connection_sock.h>
@@ -27443,9 +27401,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/inet_hashtables.c linux-2.6.31.6-v
        /*
         * if the nulls value we got at the end of this lookup is
         * not the expected one, we must restart lookup.
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/netfilter/nf_nat_helper.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/netfilter/nf_nat_helper.c
---- linux-2.6.31.6/net/ipv4/netfilter/nf_nat_helper.c  2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/netfilter/nf_nat_helper.c    2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/netfilter/nf_nat_helper.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/netfilter/nf_nat_helper.c
+--- linux-2.6.32/net/ipv4/netfilter/nf_nat_helper.c    2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/netfilter/nf_nat_helper.c      2009-12-03 20:04:56.000000000 +0100
 @@ -19,6 +19,7 @@
  #include <net/route.h>
  
@@ -27454,9 +27412,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/netfilter/nf_nat_helper.c linux-2.
  #include <net/netfilter/nf_conntrack.h>
  #include <net/netfilter/nf_conntrack_helper.h>
  #include <net/netfilter/nf_conntrack_ecache.h>
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/netfilter.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/netfilter.c
---- linux-2.6.31.6/net/ipv4/netfilter.c        2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/netfilter.c  2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/netfilter.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/netfilter.c
+--- linux-2.6.32/net/ipv4/netfilter.c  2009-09-10 15:26:29.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/netfilter.c    2009-12-03 20:04:56.000000000 +0100
 @@ -4,7 +4,7 @@
  #include <linux/netfilter_ipv4.h>
  #include <linux/ip.h>
@@ -27466,9 +27424,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/netfilter.c linux-2.6.31.6-vs2.3.0
  #include <net/xfrm.h>
  #include <net/ip.h>
  #include <net/netfilter/nf_queue.h>
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/raw.c
---- linux-2.6.31.6/net/ipv4/raw.c      2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/raw.c        2009-09-10 17:17:12.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/raw.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/raw.c
+--- linux-2.6.32/net/ipv4/raw.c        2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/raw.c  2009-12-03 20:04:56.000000000 +0100
 @@ -117,7 +117,7 @@ static struct sock *__raw_v4_lookup(stru
  
                if (net_eq(sock_net(sk), net) && inet->num == num       &&
@@ -27478,7 +27436,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
                    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
                        goto found; /* gotcha */
        }
-@@ -372,6 +372,12 @@ static int raw_send_hdrinc(struct sock *
+@@ -383,6 +383,12 @@ static int raw_send_hdrinc(struct sock *
                icmp_out_count(net, ((struct icmphdr *)
                        skb_transport_header(skb))->type);
  
@@ -27491,15 +27449,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
        err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
                      dst_output);
        if (err > 0)
-@@ -383,6 +389,7 @@ out:
- error_fault:
-       err = -EFAULT;
-+error_free:
-       kfree_skb(skb);
- error:
-       IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
-@@ -551,6 +558,13 @@ static int raw_sendmsg(struct kiocb *ioc
+@@ -563,6 +569,13 @@ static int raw_sendmsg(struct kiocb *ioc
                }
  
                security_sk_classify_flow(sk, &fl);
@@ -27513,7 +27463,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
                err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1);
        }
        if (err)
-@@ -620,17 +634,19 @@ static int raw_bind(struct sock *sk, str
+@@ -635,17 +648,19 @@ static int raw_bind(struct sock *sk, str
  {
        struct inet_sock *inet = inet_sk(sk);
        struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
@@ -27536,7 +27486,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->saddr = 0;  /* Use device */
        sk_dst_reset(sk);
-@@ -682,7 +698,8 @@ static int raw_recvmsg(struct kiocb *ioc
+@@ -697,7 +712,8 @@ static int raw_recvmsg(struct kiocb *ioc
        /* Copy the address. */
        if (sin) {
                sin->sin_family = AF_INET;
@@ -27546,7 +27496,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
                sin->sin_port = 0;
                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
        }
-@@ -860,7 +877,8 @@ static struct sock *raw_get_first(struct
+@@ -875,7 +891,8 @@ static struct sock *raw_get_first(struct
                struct hlist_node *node;
  
                sk_for_each(sk, node, &state->h->ht[state->bucket])
@@ -27556,7 +27506,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
                                goto found;
        }
        sk = NULL;
-@@ -876,7 +894,8 @@ static struct sock *raw_get_next(struct 
+@@ -891,7 +908,8 @@ static struct sock *raw_get_next(struct 
                sk = sk_next(sk);
  try_again:
                ;
@@ -27566,7 +27516,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
  
        if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
                sk = sk_head(&state->h->ht[state->bucket]);
-@@ -935,7 +954,10 @@ static void raw_sock_seq_show(struct seq
+@@ -950,7 +968,10 @@ static void raw_sock_seq_show(struct seq
  
        seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
@@ -27578,9 +27528,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/raw.c linux-2.6.31.6-vs2.3.0.36.24
                sk_wmem_alloc_get(sp),
                sk_rmem_alloc_get(sp),
                0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/tcp.c
---- linux-2.6.31.6/net/ipv4/tcp.c      2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/tcp.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/tcp.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/tcp.c
+--- linux-2.6.32/net/ipv4/tcp.c        2009-12-03 20:02:59.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/tcp.c  2009-12-03 20:04:56.000000000 +0100
 @@ -264,6 +264,7 @@
  #include <linux/cache.h>
  #include <linux/err.h>
@@ -27589,10 +27539,10 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp.c linux-2.6.31.6-vs2.3.0.36.24
  
  #include <net/icmp.h>
  #include <net/tcp.h>
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/tcp_ipv4.c
---- linux-2.6.31.6/net/ipv4/tcp_ipv4.c 2009-09-10 15:26:29.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/tcp_ipv4.c   2009-09-10 16:11:43.000000000 +0200
-@@ -1887,6 +1887,12 @@ static void *listening_get_next(struct s
+diff -NurpP --minimal linux-2.6.32/net/ipv4/tcp_ipv4.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/tcp_ipv4.c
+--- linux-2.6.32/net/ipv4/tcp_ipv4.c   2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/tcp_ipv4.c     2009-12-03 20:04:56.000000000 +0100
+@@ -1925,6 +1925,12 @@ static void *listening_get_next(struct s
                req = req->dl_next;
                while (1) {
                        while (req) {
@@ -27605,7 +27555,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                                if (req->rsk_ops->family == st->family) {
                                        cur = req;
                                        goto out;
-@@ -1911,6 +1917,10 @@ get_req:
+@@ -1949,6 +1955,10 @@ get_req:
        }
  get_sk:
        sk_nulls_for_each_from(sk, node) {
@@ -27616,7 +27566,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) {
                        cur = sk;
                        goto out;
-@@ -1974,6 +1984,11 @@ static void *established_get_first(struc
+@@ -2012,6 +2022,11 @@ static void *established_get_first(struc
  
                spin_lock_bh(lock);
                sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
@@ -27628,7 +27578,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                        if (sk->sk_family != st->family ||
                            !net_eq(sock_net(sk), net)) {
                                continue;
-@@ -1984,6 +1999,11 @@ static void *established_get_first(struc
+@@ -2022,6 +2037,11 @@ static void *established_get_first(struc
                st->state = TCP_SEQ_STATE_TIME_WAIT;
                inet_twsk_for_each(tw, node,
                                   &tcp_hashinfo.ehash[st->bucket].twchain) {
@@ -27640,7 +27590,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                        if (tw->tw_family != st->family ||
                            !net_eq(twsk_net(tw), net)) {
                                continue;
-@@ -2012,7 +2032,9 @@ static void *established_get_next(struct
+@@ -2050,7 +2070,9 @@ static void *established_get_next(struct
                tw = cur;
                tw = tw_next(tw);
  get_tw:
@@ -27651,7 +27601,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                        tw = tw_next(tw);
                }
                if (tw) {
-@@ -2035,6 +2057,11 @@ get_tw:
+@@ -2073,6 +2095,11 @@ get_tw:
                sk = sk_nulls_next(sk);
  
        sk_nulls_for_each_from(sk, node) {
@@ -27663,7 +27613,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
                        goto found;
        }
-@@ -2186,9 +2213,9 @@ static void get_openreq4(struct sock *sk
+@@ -2224,9 +2251,9 @@ static void get_openreq4(struct sock *sk
        seq_printf(f, "%4d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p%n",
                i,
@@ -27675,7 +27625,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                ntohs(ireq->rmt_port),
                TCP_SYN_RECV,
                0, 0, /* could print option size, but that is af dependent. */
-@@ -2231,7 +2258,10 @@ static void get_tcp4_sock(struct sock *s
+@@ -2269,7 +2296,10 @@ static void get_tcp4_sock(struct sock *s
  
        seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
                        "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n",
@@ -27687,7 +27637,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                tp->write_seq - tp->snd_una,
                sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
                                             (tp->rcv_nxt - tp->copied_seq),
-@@ -2267,7 +2297,10 @@ static void get_timewait4_sock(struct in
+@@ -2305,7 +2335,10 @@ static void get_timewait4_sock(struct in
  
        seq_printf(f, "%4d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n",
@@ -27699,9 +27649,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_ipv4.c linux-2.6.31.6-vs2.3.0.
                3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
                atomic_read(&tw->tw_refcnt), tw, len);
  }
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_minisocks.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/tcp_minisocks.c
---- linux-2.6.31.6/net/ipv4/tcp_minisocks.c    2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/tcp_minisocks.c      2009-10-15 03:49:19.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv4/tcp_minisocks.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/tcp_minisocks.c
+--- linux-2.6.32/net/ipv4/tcp_minisocks.c      2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/tcp_minisocks.c        2009-12-03 20:04:56.000000000 +0100
 @@ -26,6 +26,10 @@
  #include <net/inet_common.h>
  #include <net/xfrm.h>
@@ -27725,26 +27675,26 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/tcp_minisocks.c linux-2.6.31.6-vs2
  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                if (tw->tw_family == PF_INET6) {
                        struct ipv6_pinfo *np = inet6_sk(sk);
-diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/udp.c
---- linux-2.6.31.6/net/ipv4/udp.c      2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv4/udp.c        2009-11-05 04:54:58.000000000 +0100
-@@ -222,14 +222,7 @@ fail:
-       return error;
+diff -NurpP --minimal linux-2.6.32/net/ipv4/udp.c linux-2.6.32-vs2.3.0.36.26/net/ipv4/udp.c
+--- linux-2.6.32/net/ipv4/udp.c        2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv4/udp.c  2009-12-03 20:04:56.000000000 +0100
+@@ -224,14 +224,7 @@ fail:
  }
+ EXPORT_SYMBOL(udp_lib_get_port);
  
 -static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
 -{
 -      struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
 -
--      return  ( !ipv6_only_sock(sk2)  &&
--                (!inet1->rcv_saddr || !inet2->rcv_saddr ||
--                 inet1->rcv_saddr == inet2->rcv_saddr      ));
+-      return  (!ipv6_only_sock(sk2)  &&
+-               (!inet1->rcv_saddr || !inet2->rcv_saddr ||
+-                 inet1->rcv_saddr == inet2->rcv_saddr));
 -}
 +extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
  
  int udp_v4_get_port(struct sock *sk, unsigned short snum)
  {
-@@ -251,6 +244,11 @@ static inline int compute_score(struct s
+@@ -253,6 +246,11 @@ static inline int compute_score(struct s
                        if (inet->rcv_saddr != daddr)
                                return -1;
                        score += 2;
@@ -27756,7 +27706,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
                }
                if (inet->daddr) {
                        if (inet->daddr != saddr)
-@@ -271,6 +269,7 @@ static inline int compute_score(struct s
+@@ -273,6 +271,7 @@ static inline int compute_score(struct s
        return score;
  }
  
@@ -27764,7 +27714,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
  /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
   * harder than this. -DaveM
   */
-@@ -292,6 +291,11 @@ begin:
+@@ -294,6 +293,11 @@ begin:
        sk_nulls_for_each_rcu(sk, node, &hslot->head) {
                score = compute_score(sk, net, saddr, hnum, sport,
                                      daddr, dport, dif);
@@ -27776,7 +27726,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
                if (score > badness) {
                        result = sk;
                        badness = score;
-@@ -305,6 +309,7 @@ begin:
+@@ -307,6 +311,7 @@ begin:
        if (get_nulls_value(node) != hash)
                goto begin;
  
@@ -27784,7 +27734,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
        if (result) {
                if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
                        result = NULL;
-@@ -314,6 +319,7 @@ begin:
+@@ -316,6 +321,7 @@ begin:
                        goto begin;
                }
        }
@@ -27792,7 +27742,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
        rcu_read_unlock();
        return result;
  }
-@@ -356,7 +362,7 @@ static inline struct sock *udp_v4_mcast_
+@@ -358,7 +364,7 @@ static inline struct sock *udp_v4_mcast_
                    s->sk_hash != hnum                                  ||
                    (inet->daddr && inet->daddr != rmt_addr)            ||
                    (inet->dport != rmt_port && inet->dport)            ||
@@ -27801,7 +27751,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
                    ipv6_only_sock(s)                                   ||
                    (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
                        continue;
-@@ -698,8 +704,13 @@ int udp_sendmsg(struct kiocb *iocb, stru
+@@ -707,8 +713,13 @@ int udp_sendmsg(struct kiocb *iocb, stru
                                               { .sport = inet->sport,
                                                 .dport = dport } } };
                struct net *net = sock_net(sk);
@@ -27815,8 +27765,8 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
                err = ip_route_output_flow(net, &rt, &fl, sk, 1);
                if (err) {
                        if (err == -ENETUNREACH)
-@@ -945,7 +956,8 @@ try_again:
-       {
+@@ -988,7 +999,8 @@ try_again:
+       if (sin) {
                sin->sin_family = AF_INET;
                sin->sin_port = udp_hdr(skb)->source;
 -              sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
@@ -27825,7 +27775,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
                memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
        }
        if (inet->cmsg_flags)
-@@ -1599,6 +1611,8 @@ static struct sock *udp_get_first(struct
+@@ -1627,6 +1639,8 @@ static struct sock *udp_get_first(struct
                sk_nulls_for_each(sk, node, &hslot->head) {
                        if (!net_eq(sock_net(sk), net))
                                continue;
@@ -27834,7 +27784,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
                        if (sk->sk_family == state->family)
                                goto found;
                }
-@@ -1616,7 +1630,9 @@ static struct sock *udp_get_next(struct 
+@@ -1644,7 +1658,9 @@ static struct sock *udp_get_next(struct 
  
        do {
                sk = sk_nulls_next(sk);
@@ -27845,7 +27795,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
  
        if (!sk) {
                if (state->bucket < UDP_HTABLE_SIZE)
-@@ -1721,7 +1737,10 @@ static void udp4_format_sock(struct sock
+@@ -1751,7 +1767,10 @@ static void udp4_format_sock(struct sock
  
        seq_printf(f, "%4d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n",
@@ -27857,9 +27807,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv4/udp.c linux-2.6.31.6-vs2.3.0.36.24
                sk_wmem_alloc_get(sp),
                sk_rmem_alloc_get(sp),
                0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/addrconf.c
---- linux-2.6.31.6/net/ipv6/addrconf.c 2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/addrconf.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/addrconf.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/addrconf.c
+--- linux-2.6.32/net/ipv6/addrconf.c   2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/addrconf.c     2009-12-03 20:04:56.000000000 +0100
 @@ -86,6 +86,8 @@
  
  #include <linux/proc_fs.h>
@@ -27869,7 +27819,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
  
  /* Set to 3 to get tracing... */
  #define ACONF_DEBUG 2
-@@ -1117,7 +1119,7 @@ out:
+@@ -1119,7 +1121,7 @@ out:
  
  int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
                       const struct in6_addr *daddr, unsigned int prefs,
@@ -27878,7 +27828,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
  {
        struct ipv6_saddr_score scores[2],
                                *score = &scores[0], *hiscore = &scores[1];
-@@ -1190,6 +1192,8 @@ int ipv6_dev_get_saddr(struct net *net, 
+@@ -1192,6 +1194,8 @@ int ipv6_dev_get_saddr(struct net *net, 
                                               dev->name);
                                continue;
                        }
@@ -27887,7 +27837,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
  
                        score->rule = -1;
                        bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
-@@ -2979,7 +2983,10 @@ static void if6_seq_stop(struct seq_file
+@@ -3000,7 +3004,10 @@ static void if6_seq_stop(struct seq_file
  static int if6_seq_show(struct seq_file *seq, void *v)
  {
        struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
@@ -27899,7 +27849,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
                   &ifp->addr,
                   ifp->idev->dev->ifindex,
                   ifp->prefix_len,
-@@ -3476,6 +3483,12 @@ static int inet6_dump_addr(struct sk_buf
+@@ -3497,6 +3504,12 @@ static int inet6_dump_addr(struct sk_buf
        struct ifmcaddr6 *ifmca;
        struct ifacaddr6 *ifaca;
        struct net *net = sock_net(skb->sk);
@@ -27912,7 +27862,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
  
        s_idx = cb->args[0];
        s_ip_idx = ip_idx = cb->args[1];
-@@ -3497,6 +3510,8 @@ static int inet6_dump_addr(struct sk_buf
+@@ -3518,6 +3531,8 @@ static int inet6_dump_addr(struct sk_buf
                             ifa = ifa->if_next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
@@ -27921,7 +27871,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
                                err = inet6_fill_ifaddr(skb, ifa,
                                                        NETLINK_CB(cb->skb).pid,
                                                        cb->nlh->nlmsg_seq,
-@@ -3510,6 +3525,8 @@ static int inet6_dump_addr(struct sk_buf
+@@ -3531,6 +3546,8 @@ static int inet6_dump_addr(struct sk_buf
                             ifmca = ifmca->next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
@@ -27930,7 +27880,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
                                err = inet6_fill_ifmcaddr(skb, ifmca,
                                                          NETLINK_CB(cb->skb).pid,
                                                          cb->nlh->nlmsg_seq,
-@@ -3523,6 +3540,8 @@ static int inet6_dump_addr(struct sk_buf
+@@ -3544,6 +3561,8 @@ static int inet6_dump_addr(struct sk_buf
                             ifaca = ifaca->aca_next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
@@ -27939,7 +27889,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
                                err = inet6_fill_ifacaddr(skb, ifaca,
                                                          NETLINK_CB(cb->skb).pid,
                                                          cb->nlh->nlmsg_seq,
-@@ -3809,12 +3828,19 @@ static int inet6_dump_ifinfo(struct sk_b
+@@ -3830,12 +3849,19 @@ static int inet6_dump_ifinfo(struct sk_b
        int s_idx = cb->args[0];
        struct net_device *dev;
        struct inet6_dev *idev;
@@ -27959,9 +27909,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/addrconf.c linux-2.6.31.6-vs2.3.0.
                if ((idev = in6_dev_get(dev)) == NULL)
                        goto cont;
                err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid,
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/af_inet6.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/af_inet6.c
---- linux-2.6.31.6/net/ipv6/af_inet6.c 2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/af_inet6.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/af_inet6.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/af_inet6.c
+--- linux-2.6.32/net/ipv6/af_inet6.c   2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/af_inet6.c     2009-12-03 20:04:56.000000000 +0100
 @@ -41,6 +41,8 @@
  #include <linux/netdevice.h>
  #include <linux/icmpv6.h>
@@ -28057,9 +28007,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/af_inet6.c linux-2.6.31.6-vs2.3.0.
                if (ipv6_addr_any(&np->rcv_saddr))
                        ipv6_addr_copy(&sin->sin6_addr, &np->saddr);
                else
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/fib6_rules.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/fib6_rules.c
---- linux-2.6.31.6/net/ipv6/fib6_rules.c       2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/fib6_rules.c 2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/fib6_rules.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/fib6_rules.c
+--- linux-2.6.32/net/ipv6/fib6_rules.c 2009-09-10 15:26:30.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/fib6_rules.c   2009-12-03 20:04:56.000000000 +0100
 @@ -96,7 +96,7 @@ static int fib6_rule_action(struct fib_r
                        if (ipv6_dev_get_saddr(net,
                                               ip6_dst_idev(&rt->u.dst)->dev,
@@ -28069,9 +28019,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/fib6_rules.c linux-2.6.31.6-vs2.3.
                                goto again;
                        if (!ipv6_prefix_equal(&saddr, &r->src.addr,
                                               r->src.plen))
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/inet6_hashtables.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/inet6_hashtables.c
---- linux-2.6.31.6/net/ipv6/inet6_hashtables.c 2009-03-24 14:22:46.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/inet6_hashtables.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/inet6_hashtables.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/inet6_hashtables.c
+--- linux-2.6.32/net/ipv6/inet6_hashtables.c   2009-03-24 14:22:46.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/inet6_hashtables.c     2009-12-03 20:04:56.000000000 +0100
 @@ -16,6 +16,7 @@
  
  #include <linux/module.h>
@@ -28107,10 +28057,10 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/inet6_hashtables.c linux-2.6.31.6-
                }
                if (sk->sk_bound_dev_if) {
                        if (sk->sk_bound_dev_if != dif)
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/ip6_output.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/ip6_output.c
---- linux-2.6.31.6/net/ipv6/ip6_output.c       2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/ip6_output.c 2009-09-10 16:11:43.000000000 +0200
-@@ -951,7 +951,7 @@ static int ip6_dst_lookup_tail(struct so
+diff -NurpP --minimal linux-2.6.32/net/ipv6/ip6_output.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/ip6_output.c
+--- linux-2.6.32/net/ipv6/ip6_output.c 2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/ip6_output.c   2009-12-03 20:04:56.000000000 +0100
+@@ -934,7 +934,7 @@ static int ip6_dst_lookup_tail(struct so
                err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
                                         &fl->fl6_dst,
                                         sk ? inet6_sk(sk)->srcprefs : 0,
@@ -28119,9 +28069,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/ip6_output.c linux-2.6.31.6-vs2.3.
                if (err)
                        goto out_err_release;
        }
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/Kconfig linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/Kconfig
---- linux-2.6.31.6/net/ipv6/Kconfig    2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/Kconfig      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/Kconfig linux-2.6.32-vs2.3.0.36.26/net/ipv6/Kconfig
+--- linux-2.6.32/net/ipv6/Kconfig      2009-09-10 15:26:30.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/Kconfig        2009-12-03 20:04:56.000000000 +0100
 @@ -4,8 +4,8 @@
  
  #   IPv6 as module will cause a CRASH if you try to unload it
@@ -28133,9 +28083,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/Kconfig linux-2.6.31.6-vs2.3.0.36.
        ---help---
          This is complemental support for the IP version 6.
          You will still be able to do traditional IPv4 networking as well.
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/ndisc.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/ndisc.c
---- linux-2.6.31.6/net/ipv6/ndisc.c    2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/ndisc.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/ndisc.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/ndisc.c
+--- linux-2.6.32/net/ipv6/ndisc.c      2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/ndisc.c        2009-12-03 20:04:56.000000000 +0100
 @@ -589,7 +589,7 @@ static void ndisc_send_na(struct net_dev
        } else {
                if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
@@ -28145,9 +28095,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/ndisc.c linux-2.6.31.6-vs2.3.0.36.
                        return;
                src_addr = &tmpaddr;
        }
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/raw.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/raw.c
---- linux-2.6.31.6/net/ipv6/raw.c      2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/raw.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/raw.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/raw.c
+--- linux-2.6.32/net/ipv6/raw.c        2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/raw.c  2009-12-03 20:04:56.000000000 +0100
 @@ -29,6 +29,7 @@
  #include <linux/icmpv6.h>
  #include <linux/netfilter.h>
@@ -28170,9 +28120,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/raw.c linux-2.6.31.6-vs2.3.0.36.24
                /* ipv4 addr of the socket is invalid.  Only the
                 * unspecified and mapped address have a v4 equivalent.
                 */
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/route.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/route.c
---- linux-2.6.31.6/net/ipv6/route.c    2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/route.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/route.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/route.c
+--- linux-2.6.32/net/ipv6/route.c      2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/route.c        2009-12-03 20:04:56.000000000 +0100
 @@ -2257,7 +2257,8 @@ static int rt6_fill_node(struct net *net
                struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst);
                struct in6_addr saddr_buf;
@@ -28183,9 +28133,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/route.c linux-2.6.31.6-vs2.3.0.36.
                        NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
        }
  
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/tcp_ipv6.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/tcp_ipv6.c
---- linux-2.6.31.6/net/ipv6/tcp_ipv6.c 2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/tcp_ipv6.c   2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/tcp_ipv6.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/tcp_ipv6.c
+--- linux-2.6.32/net/ipv6/tcp_ipv6.c   2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/tcp_ipv6.c     2009-12-03 20:04:56.000000000 +0100
 @@ -68,6 +68,7 @@
  
  #include <linux/crypto.h>
@@ -28212,9 +28162,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/tcp_ipv6.c linux-2.6.31.6-vs2.3.0.
  
        addr_type = ipv6_addr_type(&usin->sin6_addr);
  
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/udp.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/udp.c
---- linux-2.6.31.6/net/ipv6/udp.c      2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/udp.c        2009-11-05 05:04:49.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/net/ipv6/udp.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/udp.c
+--- linux-2.6.32/net/ipv6/udp.c        2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/udp.c  2009-12-03 20:04:56.000000000 +0100
 @@ -47,6 +47,7 @@
  
  #include <linux/proc_fs.h>
@@ -28290,9 +28240,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/udp.c linux-2.6.31.6-vs2.3.0.36.24
                }
                if (!ipv6_addr_any(&np->daddr)) {
                        if (!ipv6_addr_equal(&np->daddr, saddr))
-diff -NurpP --minimal linux-2.6.31.6/net/ipv6/xfrm6_policy.c linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/xfrm6_policy.c
---- linux-2.6.31.6/net/ipv6/xfrm6_policy.c     2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/ipv6/xfrm6_policy.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/ipv6/xfrm6_policy.c linux-2.6.32-vs2.3.0.36.26/net/ipv6/xfrm6_policy.c
+--- linux-2.6.32/net/ipv6/xfrm6_policy.c       2009-12-03 20:03:00.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/ipv6/xfrm6_policy.c 2009-12-03 20:04:56.000000000 +0100
 @@ -63,7 +63,7 @@ static int xfrm6_get_saddr(struct net *n
        dev = ip6_dst_idev(dst)->dev;
        ipv6_dev_get_saddr(dev_net(dev), dev,
@@ -28302,9 +28252,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/ipv6/xfrm6_policy.c linux-2.6.31.6-vs2.
        dst_release(dst);
        return 0;
  }
-diff -NurpP --minimal linux-2.6.31.6/net/netlink/af_netlink.c linux-2.6.31.6-vs2.3.0.36.24/net/netlink/af_netlink.c
---- linux-2.6.31.6/net/netlink/af_netlink.c    2009-09-10 15:26:30.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/netlink/af_netlink.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/netlink/af_netlink.c linux-2.6.32-vs2.3.0.36.26/net/netlink/af_netlink.c
+--- linux-2.6.32/net/netlink/af_netlink.c      2009-12-03 20:03:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/netlink/af_netlink.c        2009-12-03 20:04:56.000000000 +0100
 @@ -55,6 +55,9 @@
  #include <linux/types.h>
  #include <linux/audit.h>
@@ -28315,7 +28265,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/netlink/af_netlink.c linux-2.6.31.6-vs2
  
  #include <net/net_namespace.h>
  #include <net/sock.h>
-@@ -1831,6 +1834,8 @@ static struct sock *netlink_seq_socket_i
+@@ -1899,6 +1902,8 @@ static struct sock *netlink_seq_socket_i
                        sk_for_each(s, node, &hash->table[j]) {
                                if (sock_net(s) != seq_file_net(seq))
                                        continue;
@@ -28324,7 +28274,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/netlink/af_netlink.c linux-2.6.31.6-vs2
                                if (off == pos) {
                                        iter->link = i;
                                        iter->hash_idx = j;
-@@ -1865,7 +1870,8 @@ static void *netlink_seq_next(struct seq
+@@ -1933,7 +1938,8 @@ static void *netlink_seq_next(struct seq
        s = v;
        do {
                s = sk_next(s);
@@ -28334,7 +28284,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/netlink/af_netlink.c linux-2.6.31.6-vs2
        if (s)
                return s;
  
-@@ -1877,7 +1883,8 @@ static void *netlink_seq_next(struct seq
+@@ -1945,7 +1951,8 @@ static void *netlink_seq_next(struct seq
  
                for (; j <= hash->mask; j++) {
                        s = sk_head(&hash->table[j]);
@@ -28344,9 +28294,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/netlink/af_netlink.c linux-2.6.31.6-vs2
                                s = sk_next(s);
                        if (s) {
                                iter->link = i;
-diff -NurpP --minimal linux-2.6.31.6/net/sctp/ipv6.c linux-2.6.31.6-vs2.3.0.36.24/net/sctp/ipv6.c
---- linux-2.6.31.6/net/sctp/ipv6.c     2009-09-10 15:26:31.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/sctp/ipv6.c       2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/sctp/ipv6.c linux-2.6.32-vs2.3.0.36.26/net/sctp/ipv6.c
+--- linux-2.6.32/net/sctp/ipv6.c       2009-12-03 20:03:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/sctp/ipv6.c 2009-12-03 20:04:56.000000000 +0100
 @@ -316,7 +316,8 @@ static void sctp_v6_get_saddr(struct sct
                                   dst ? ip6_dst_idev(dst)->dev : NULL,
                                   &daddr->v6.sin6_addr,
@@ -28357,10 +28307,10 @@ diff -NurpP --minimal linux-2.6.31.6/net/sctp/ipv6.c linux-2.6.31.6-vs2.3.0.36.2
                SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n",
                                  &saddr->v6.sin6_addr);
                return;
-diff -NurpP --minimal linux-2.6.31.6/net/socket.c linux-2.6.31.6-vs2.3.0.36.24/net/socket.c
---- linux-2.6.31.6/net/socket.c        2009-09-10 15:26:31.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/socket.c  2009-09-10 16:11:43.000000000 +0200
-@@ -95,6 +95,10 @@
+diff -NurpP --minimal linux-2.6.32/net/socket.c linux-2.6.32-vs2.3.0.36.26/net/socket.c
+--- linux-2.6.32/net/socket.c  2009-12-03 20:03:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/socket.c    2009-12-03 20:04:56.000000000 +0100
+@@ -96,6 +96,10 @@
  
  #include <net/sock.h>
  #include <linux/netfilter.h>
@@ -28468,9 +28418,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/socket.c linux-2.6.31.6-vs2.3.0.36.24/n
  
        err = sock1->ops->socketpair(sock1, sock2);
        if (err < 0)
-diff -NurpP --minimal linux-2.6.31.6/net/sunrpc/auth.c linux-2.6.31.6-vs2.3.0.36.24/net/sunrpc/auth.c
---- linux-2.6.31.6/net/sunrpc/auth.c   2009-03-24 14:22:48.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/sunrpc/auth.c     2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/sunrpc/auth.c linux-2.6.32-vs2.3.0.36.26/net/sunrpc/auth.c
+--- linux-2.6.32/net/sunrpc/auth.c     2009-12-03 20:03:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/sunrpc/auth.c       2009-12-03 20:04:56.000000000 +0100
 @@ -14,6 +14,7 @@
  #include <linux/hash.h>
  #include <linux/sunrpc/clnt.h>
@@ -28495,9 +28445,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/sunrpc/auth.c linux-2.6.31.6-vs2.3.0.36
        };
        struct rpc_cred *ret;
  
-diff -NurpP --minimal linux-2.6.31.6/net/sunrpc/auth_unix.c linux-2.6.31.6-vs2.3.0.36.24/net/sunrpc/auth_unix.c
---- linux-2.6.31.6/net/sunrpc/auth_unix.c      2008-12-25 00:26:37.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/sunrpc/auth_unix.c        2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/sunrpc/auth_unix.c linux-2.6.32-vs2.3.0.36.26/net/sunrpc/auth_unix.c
+--- linux-2.6.32/net/sunrpc/auth_unix.c        2008-12-25 00:26:37.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/sunrpc/auth_unix.c  2009-12-03 20:04:56.000000000 +0100
 @@ -11,12 +11,14 @@
  #include <linux/module.h>
  #include <linux/sunrpc/clnt.h>
@@ -28556,10 +28506,10 @@ diff -NurpP --minimal linux-2.6.31.6/net/sunrpc/auth_unix.c linux-2.6.31.6-vs2.3
        hold = p++;
        for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
                *p++ = htonl((u32) cred->uc_gids[i]);
-diff -NurpP --minimal linux-2.6.31.6/net/sunrpc/clnt.c linux-2.6.31.6-vs2.3.0.36.24/net/sunrpc/clnt.c
---- linux-2.6.31.6/net/sunrpc/clnt.c   2009-09-10 15:26:31.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/sunrpc/clnt.c     2009-09-10 16:11:43.000000000 +0200
-@@ -31,6 +31,7 @@
+diff -NurpP --minimal linux-2.6.32/net/sunrpc/clnt.c linux-2.6.32-vs2.3.0.36.26/net/sunrpc/clnt.c
+--- linux-2.6.32/net/sunrpc/clnt.c     2009-12-03 20:03:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/sunrpc/clnt.c       2009-12-03 20:04:56.000000000 +0100
+@@ -33,6 +33,7 @@
  #include <linux/utsname.h>
  #include <linux/workqueue.h>
  #include <linux/in6.h>
@@ -28567,7 +28517,7 @@ diff -NurpP --minimal linux-2.6.31.6/net/sunrpc/clnt.c linux-2.6.31.6-vs2.3.0.36
  
  #include <linux/sunrpc/clnt.h>
  #include <linux/sunrpc/rpc_pipe_fs.h>
-@@ -339,6 +340,9 @@ struct rpc_clnt *rpc_create(struct rpc_c
+@@ -358,6 +359,9 @@ struct rpc_clnt *rpc_create(struct rpc_c
        if (!(args->flags & RPC_CLNT_CREATE_QUIET))
                clnt->cl_chatty = 1;
  
@@ -28577,9 +28527,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/sunrpc/clnt.c linux-2.6.31.6-vs2.3.0.36
        return clnt;
  }
  EXPORT_SYMBOL_GPL(rpc_create);
-diff -NurpP --minimal linux-2.6.31.6/net/unix/af_unix.c linux-2.6.31.6-vs2.3.0.36.24/net/unix/af_unix.c
---- linux-2.6.31.6/net/unix/af_unix.c  2009-11-12 12:10:12.000000000 +0100
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/unix/af_unix.c    2009-11-12 12:26:38.000000000 +0100
+diff -NurpP --minimal linux-2.6.32/net/unix/af_unix.c linux-2.6.32-vs2.3.0.36.26/net/unix/af_unix.c
+--- linux-2.6.32/net/unix/af_unix.c    2009-12-03 20:03:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/unix/af_unix.c      2009-12-03 20:04:56.000000000 +0100
 @@ -114,6 +114,8 @@
  #include <linux/mount.h>
  #include <net/checksum.h>
@@ -28617,9 +28567,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/unix/af_unix.c linux-2.6.31.6-vs2.3.0.3
                sk = next_unix_socket(&iter->i, sk);
        return sk;
  }
-diff -NurpP --minimal linux-2.6.31.6/net/x25/af_x25.c linux-2.6.31.6-vs2.3.0.36.24/net/x25/af_x25.c
---- linux-2.6.31.6/net/x25/af_x25.c    2009-09-10 15:26:31.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/net/x25/af_x25.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/net/x25/af_x25.c linux-2.6.32-vs2.3.0.36.26/net/x25/af_x25.c
+--- linux-2.6.32/net/x25/af_x25.c      2009-12-03 20:03:01.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/net/x25/af_x25.c        2009-12-03 20:04:56.000000000 +0100
 @@ -519,7 +519,10 @@ static int x25_create(struct net *net, s
  
        x25 = x25_sk(sk);
@@ -28632,9 +28582,9 @@ diff -NurpP --minimal linux-2.6.31.6/net/x25/af_x25.c linux-2.6.31.6-vs2.3.0.36.
  
        x25_init_timers(sk);
  
-diff -NurpP --minimal linux-2.6.31.6/scripts/checksyscalls.sh linux-2.6.31.6-vs2.3.0.36.24/scripts/checksyscalls.sh
---- linux-2.6.31.6/scripts/checksyscalls.sh    2009-09-10 15:26:31.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/scripts/checksyscalls.sh      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/scripts/checksyscalls.sh linux-2.6.32-vs2.3.0.36.26/scripts/checksyscalls.sh
+--- linux-2.6.32/scripts/checksyscalls.sh      2009-09-10 15:26:31.000000000 +0200
++++ linux-2.6.32-vs2.3.0.36.26/scripts/checksyscalls.sh        2009-12-03 20:04:56.000000000 +0100
 @@ -194,7 +194,6 @@ cat << EOF
  #define __IGNORE_afs_syscall
  #define __IGNORE_getpmsg
@@ -28643,9 +28593,9 @@ diff -NurpP --minimal linux-2.6.31.6/scripts/checksyscalls.sh linux-2.6.31.6-vs2
  EOF
  }
  
-diff -NurpP --minimal linux-2.6.31.6/security/commoncap.c linux-2.6.31.6-vs2.3.0.36.24/security/commoncap.c
---- linux-2.6.31.6/security/commoncap.c        2009-09-10 15:26:32.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/security/commoncap.c  2009-09-10 16:32:54.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/security/commoncap.c linux-2.6.32-vs2.3.0.36.26/security/commoncap.c
+--- linux-2.6.32/security/commoncap.c  2009-12-03 20:03:02.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/security/commoncap.c    2009-12-03 20:04:56.000000000 +0100
 @@ -27,6 +27,7 @@
  #include <linux/sched.h>
  #include <linux/prctl.h>
@@ -28719,9 +28669,9 @@ diff -NurpP --minimal linux-2.6.31.6/security/commoncap.c linux-2.6.31.6-vs2.3.0
        return ret;
  }
 +
-diff -NurpP --minimal linux-2.6.31.6/security/selinux/hooks.c linux-2.6.31.6-vs2.3.0.36.24/security/selinux/hooks.c
---- linux-2.6.31.6/security/selinux/hooks.c    2009-09-10 15:26:32.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/security/selinux/hooks.c      2009-09-10 16:11:43.000000000 +0200
+diff -NurpP --minimal linux-2.6.32/security/selinux/hooks.c linux-2.6.32-vs2.3.0.36.26/security/selinux/hooks.c
+--- linux-2.6.32/security/selinux/hooks.c      2009-12-03 20:03:02.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/security/selinux/hooks.c        2009-12-03 20:04:56.000000000 +0100
 @@ -64,7 +64,6 @@
  #include <linux/dccp.h>
  #include <linux/quota.h>
@@ -28730,10 +28680,10 @@ diff -NurpP --minimal linux-2.6.31.6/security/selinux/hooks.c linux-2.6.31.6-vs2
  #include <linux/parser.h>
  #include <linux/nfs_mount.h>
  #include <net/ipv6.h>
-diff -NurpP --minimal linux-2.6.31.6/security/selinux/include/av_permissions.h linux-2.6.31.6-vs2.3.0.36.24/security/selinux/include/av_permissions.h
---- linux-2.6.31.6/security/selinux/include/av_permissions.h   2009-06-11 17:13:33.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/security/selinux/include/av_permissions.h     2009-09-29 17:20:23.000000000 +0200
-@@ -542,6 +542,7 @@
+diff -NurpP --minimal linux-2.6.32/security/selinux/include/av_permissions.h linux-2.6.32-vs2.3.0.36.26/security/selinux/include/av_permissions.h
+--- linux-2.6.32/security/selinux/include/av_permissions.h     2009-12-03 20:03:02.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/security/selinux/include/av_permissions.h       2009-12-03 20:04:56.000000000 +0100
+@@ -565,6 +565,7 @@
  #define CAPABILITY__SETFCAP                       0x80000000UL
  #define CAPABILITY2__MAC_OVERRIDE                 0x00000001UL
  #define CAPABILITY2__MAC_ADMIN                    0x00000002UL
@@ -28741,10 +28691,10 @@ diff -NurpP --minimal linux-2.6.31.6/security/selinux/include/av_permissions.h l
  #define NETLINK_ROUTE_SOCKET__IOCTL               0x00000001UL
  #define NETLINK_ROUTE_SOCKET__READ                0x00000002UL
  #define NETLINK_ROUTE_SOCKET__WRITE               0x00000004UL
-diff -NurpP --minimal linux-2.6.31.6/security/selinux/include/av_perm_to_string.h linux-2.6.31.6-vs2.3.0.36.24/security/selinux/include/av_perm_to_string.h
---- linux-2.6.31.6/security/selinux/include/av_perm_to_string.h        2009-06-11 17:13:33.000000000 +0200
-+++ linux-2.6.31.6-vs2.3.0.36.24/security/selinux/include/av_perm_to_string.h  2009-09-29 17:20:23.000000000 +0200
-@@ -141,6 +141,7 @@
+diff -NurpP --minimal linux-2.6.32/security/selinux/include/av_perm_to_string.h linux-2.6.32-vs2.3.0.36.26/security/selinux/include/av_perm_to_string.h
+--- linux-2.6.32/security/selinux/include/av_perm_to_string.h  2009-12-03 20:03:02.000000000 +0100
++++ linux-2.6.32-vs2.3.0.36.26/security/selinux/include/av_perm_to_string.h    2009-12-03 20:04:56.000000000 +0100
+@@ -142,6 +142,7 @@
     S_(SECCLASS_CAPABILITY, CAPABILITY__SETFCAP, "setfcap")
     S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_OVERRIDE, "mac_override")
     S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_ADMIN, "mac_admin")
index 3089220f704d5569066b6c59cfa1c2d1ad3c057b..f10dcc7331707c9caa3ca7734ff9b2ec90286f71 100644 (file)
@@ -1,59 +1,3 @@
---- linux-2.6.27/arch/sparc/include/asm/spinlock_64.h~ 2007-02-04 19:44:54.000000000 +0100
-+++ linux-2.6.27/arch/sparc/include/asm/spinlock_64.h  2007-04-10 01:05:35.426190250 +0200
-@@ -105,7 +105,7 @@
- /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
--static void inline __read_lock(raw_rwlock_t *lock)
-+static inline void __read_lock(raw_rwlock_t *lock)
- {
-       unsigned long tmp1, tmp2;
-@@ -130,7 +130,7 @@
-       : "memory");
- }
--static int inline __read_trylock(raw_rwlock_t *lock)
-+static inline int __read_trylock(raw_rwlock_t *lock)
- {
-       int tmp1, tmp2;
-@@ -152,7 +152,7 @@
-       return tmp1;
- }
--static void inline __read_unlock(raw_rwlock_t *lock)
-+static inline void __read_unlock(raw_rwlock_t *lock)
- {
-       unsigned long tmp1, tmp2;
-@@ -169,7 +169,7 @@
-       : "memory");
- }
--static void inline __write_lock(raw_rwlock_t *lock)
-+static inline void __write_lock(raw_rwlock_t *lock)
- {
-       unsigned long mask, tmp1, tmp2;
-@@ -196,7 +196,7 @@
-       : "memory");
- }
--static void inline __write_unlock(raw_rwlock_t *lock)
-+static inline void __write_unlock(raw_rwlock_t *lock)
- {
-       __asm__ __volatile__(
- "     membar          #LoadStore | #StoreStore\n"
-@@ -206,7 +206,7 @@
-       : "memory");
- }
--static int inline __write_trylock(raw_rwlock_t *lock)
-+static inline int __write_trylock(raw_rwlock_t *lock)
- {
-       unsigned long mask, tmp1, tmp2, result;
 --- linux-2.6.20/arch/powerpc/kernel/prom_init.c~      2007-02-04 19:44:54.000000000 +0100
 +++ linux-2.6.20/arch/powerpc/kernel/prom_init.c       2007-04-10 01:59:33.712570500 +0200
 @@ -429,14 +429,14 @@
index e6642ad9b0dddeab87ffd4227809dfb68e2bc871..c56cac1c8366a3ca3d4ed11b47376cd43fe198b2 100644 (file)
@@ -229,7 +229,7 @@ diff -urN linux-2.6.26.2.org/net/sched/Makefile linux-2.6.26.2/net/sched/Makefil
 @@ -3,6 +3,7 @@
  #
  
- obj-y := sch_generic.o
+ obj-y := sch_generic.o sch_mq.o
 +sch_wrr-objs = wrr.o wrr_proxydict.o
  
  obj-$(CONFIG_NET_SCHED)               += sch_api.o sch_blackhole.o
diff --git a/kernel-xfs-recover-quota.patch b/kernel-xfs-recover-quota.patch
deleted file mode 100644 (file)
index f1e4f33..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---- linux-2.6.31.5/fs/xfs/xfs_log_recover.c.orig       2009-11-01 23:59:52.194846209 +0100
-+++ linux-2.6.31.5/fs/xfs/xfs_log_recover.c    2009-11-16 12:47:11.601490963 +0100
-@@ -1980,7 +1980,7 @@
-                                       "XFS: NULL dquot in %s.", __func__);
-                               goto next;
-                       }
--                      if (item->ri_buf[i].i_len < sizeof(xfs_dqblk_t)) {
-+                      if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
-                               cmn_err(CE_ALERT,
-                                       "XFS: dquot too small (%d) in %s.",
-                                       item->ri_buf[i].i_len, __func__);
-@@ -2636,7 +2636,7 @@
-                       "XFS: NULL dquot in %s.", __func__);
-               return XFS_ERROR(EIO);
-       }
--      if (item->ri_buf[1].i_len < sizeof(xfs_dqblk_t)) {
-+      if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) {
-               cmn_err(CE_ALERT,
-                       "XFS: dquot too small (%d) in %s.",
-                       item->ri_buf[1].i_len, __func__);
index 6e8af7ebc3e9f5a43deba912be3a72a16e290f9b..ec13347c0bffcfd3dc31ea6c1d68fd36726668b3 100644 (file)
@@ -263,7 +263,7 @@ Patch58:    kernel-PF_RING.patch
 Patch59:       kernel-rndis_host-wm5.patch
 
 # Project suspend2 renamed to tuxonice
-# http://www.tuxonice.net/downloads/all/current-tuxonice-for-2.6.31.patch-20090911-v1.bz2
+# http://www.tuxonice.net/downloads/all/tuxonice-3.0.99.32-for-2.6.32.patch.bz2
 Patch69:       kernel-tuxonice.patch
 Patch70:       kernel-tuxonice-headers.patch
 
@@ -274,7 +274,7 @@ Patch85:    kernel-hostap.patch
 # Taken from http://download.opensuse.org/factory/repo/src-oss/suse/src/kernel-source-2.6.30-10.3.src.rpm
 Patch90:       kernel-mpt-fusion.patch
 
-# based on http://vserver.13thfloor.at/Experimental/patch-2.6.31.5-vs2.3.0.36.23.diff
+# based on http://vserver.13thfloor.at/Experimental/patch-2.6.32-vs2.3.0.36.26.diff
 Patch100:      kernel-vserver-2.3.patch
 Patch101:      kernel-vserver-fixes.patch
 
@@ -309,8 +309,6 @@ Patch1000:  kernel-grsec-minimal.patch
 Patch2000:     kernel-small_fixes.patch
 Patch2001:     kernel-pwc-uncompress.patch
 Patch2003:     kernel-regressions.patch
-# fix regression in XFS with log recovery problems on fs with quota
-Patch2004:     kernel-xfs-recover-quota.patch
 
 # kill some thousands of warnings
 # (only warnings, so just remove parts of this patch if conflics)
@@ -807,7 +805,8 @@ install %{SOURCE5} Makefile.ppclibs
 %patch55 -p1
 %patch56 -p1
 
-%patch58 -p1
+# FIXME
+#%patch58 -p1
 
 # kernel-rndis_host-wm5.patch
 %patch59 -p1
@@ -874,7 +873,8 @@ install %{SOURCE5} Makefile.ppclibs
 %patch5000 -p1
 %endif
 
-%patch150 -p1
+# FIXME
+#%patch150 -p1
 
 %ifarch ppc ppc64
 #patch200 -p1
@@ -887,7 +887,6 @@ install %{SOURCE5} Makefile.ppclibs
 %patch2000 -p1
 %patch2001 -p1
 #%patch2003 -p1
-%patch2004 -p1
 
 # Fix EXTRAVERSION in main Makefile
 sed -i 's#EXTRAVERSION =.*#EXTRAVERSION = %{postver}%{?alt_kernel:_%{alt_kernel}}#g' Makefile
This page took 2.076025 seconds and 4 git commands to generate.