packages: kernel/kernel-tuxonice.patch, kernel/kernel.spec - tuxonice 3.1.1.1

arekm arekm at pld-linux.org
Thu Jul 1 18:04:31 CEST 2010


Author: arekm                        Date: Thu Jul  1 16:04:31 2010 GMT
Module: packages                      Tag: HEAD
---- Log message:
- tuxonice 3.1.1.1

---- Files affected:
packages/kernel:
   kernel-tuxonice.patch (1.13 -> 1.14) , kernel.spec (1.792 -> 1.793) 

---- Diffs:

================================================================
Index: packages/kernel/kernel-tuxonice.patch
diff -u packages/kernel/kernel-tuxonice.patch:1.13 packages/kernel/kernel-tuxonice.patch:1.14
--- packages/kernel/kernel-tuxonice.patch:1.13	Sun May 23 15:36:51 2010
+++ packages/kernel/kernel-tuxonice.patch	Thu Jul  1 18:04:25 2010
@@ -1609,7 +1609,7 @@
  	 * 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 d13ba76..a69521c 100644
+index d13ba76..efa1792 100644
 --- a/block/genhd.c
 +++ b/block/genhd.c
 @@ -18,6 +18,8 @@
@@ -1617,33 +1617,35 @@
  #include <linux/mutex.h>
  #include <linux/idr.h>
 +#include <linux/ctype.h>
-+#include <linux/uuid.h>
++#include <linux/fs_uuid.h>
  
  #include "blk.h"
  
-@@ -1286,3 +1288,82 @@ int invalidate_partition(struct gendisk *disk, int partno)
+@@ -1286,3 +1288,84 @@ int invalidate_partition(struct gendisk *disk, int partno)
  }
  
  EXPORT_SYMBOL(invalidate_partition);
 +
-+dev_t blk_lookup_uuid(const char *uuid)
++dev_t blk_lookup_fs_info(struct fs_info *seek)
 +{
 +	dev_t devt = MKDEV(0, 0);
 +	struct class_dev_iter iter;
 +	struct device *dev;
++	int best_score = 0;
 +
 +	class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
-+	while (!devt && (dev = class_dev_iter_next(&iter))) {
++	while (best_score < 3 && (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)) {
++		while (best_score < 3 && (part = disk_part_iter_next(&piter))) {
++			int score = part_matches_fs_info(part, seek);
++			if (score > best_score) {
 +				devt = part_devt(part);
-+				break;
++				best_score = score;
 +			}
 +		}
 +		disk_part_iter_exit(&piter);
@@ -1651,7 +1653,7 @@
 +	class_dev_iter_exit(&iter);
 +	return devt;
 +}
-+EXPORT_SYMBOL_GPL(blk_lookup_uuid);
++EXPORT_SYMBOL_GPL(blk_lookup_fs_info);
 +
 +/* Caller uses NULL, key to start. For each match found, we return a bdev on
 + * which we have done blkdev_get, and we do the blkdev_put on block devices
@@ -1706,13 +1708,13 @@
 +EXPORT_SYMBOL_GPL(next_bdev_of_type);
 diff --git a/block/uuid.c b/block/uuid.c
 new file mode 100644
-index 0000000..0feb956
+index 0000000..37fd8e4
 --- /dev/null
 +++ b/block/uuid.c
-@@ -0,0 +1,527 @@
+@@ -0,0 +1,492 @@
 +#include <linux/blkdev.h>
 +#include <linux/ctype.h>
-+#include <linux/uuid.h>
++#include <linux/fs_uuid.h>
 +#include <linux/slab.h>
 +
 +static int debug_enabled;
@@ -1857,7 +1859,8 @@
 +{
 +	struct page *page = bio->bi_io_vec[0].bv_page;
 +
-+	BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
++	if(!test_bit(BIO_UPTODATE, &bio->bi_flags))
++		SetPageError(page);
 +
 +	unlock_page(page);
 +	bio_put(bio);
@@ -1899,7 +1902,7 @@
 +		__free_page(page);
 +		printk(KERN_DEBUG "read_bdev_page freed page %p (in error "
 +				"path).\n", page);
-+		return ERR_PTR(-EFAULT);
++		return NULL;
 +	}
 +
 +	lock_page(page);
@@ -1907,6 +1910,10 @@
 +			(1 << BIO_RW_UNPLUG), bio);
 +
 +	wait_on_page_locked(page);
++	if (PageError(page)) {
++		__free_page(page);
++		page = NULL;
++	}
 +	return page;
 +}
 +
@@ -1954,10 +1961,8 @@
 +			if (data_page)
 +				__free_page(data_page);
 +			data_page = read_bdev_page(bdev, pg_num);
-+			if (!data_page) {
-+				result = -ENOMEM;
-+				break;
-+			}
++			if (!data_page)
++				continue;
 +			data = page_address(data_page);
 +		}
 +
@@ -1976,29 +1981,35 @@
 +	return result;
 +}
 +
-+int part_matches_uuid(struct hd_struct *part, const char *uuid)
++/* 
++ * part_matches_fs_info - Does the given partition match the details given?
++ *
++ * Returns a score saying how good the match is.
++ * 0 = no UUID match.
++ * 1 = UUID but last mount time differs.
++ * 2 = UUID, last mount time but not dev_t
++ * 3 = perfect match
++ *
++ * This lets us cope elegantly with probing resulting in dev_ts changing
++ * from boot to boot, and with the case where a user copies a partition
++ * (UUID is non unique), and we need to check the last mount time of the
++ * correct partition.
++ */
++int part_matches_fs_info(struct hd_struct *part, struct fs_info *seek)
 +{
 +	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 = -1, last_uuid_pg_num = 0;
++	struct fs_info *got;
 +	int result = 0;
 +	char buf[50];
 +
-+	if (null_uuid(uuid)) {
++	if (null_uuid((char *) &seek->uuid)) {
 +		PRINTK("Refusing to find a NULL uuid.\n");
 +		return 0;
 +	}
 +
 +	bdev = bdget(part_devt(part));
 +
-+	PRINTK("blkdev_get %p.\n", part);
++	PRINTK("part_matches fs info considering %x.\n", part_devt(part));
 +
 +	if (blkdev_get(bdev, FMODE_READ)) {
 +		PRINTK("blkdev_get failed.\n");
@@ -2017,72 +2028,32 @@
 +		goto out;
 +	}
 +
-+	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;
++	got = fs_info_from_block_dev(bdev);
 +
-+		/* Ignore partition types with no UUID offset */
-+		if (!dat->uuid_offset)
-+			continue;
-+
-+		if (pg_num != last_pg_num) {
-+			if (data_page)
-+				__free_page(data_page);
-+			data_page = read_bdev_page(bdev, pg_num);
-+			if (!data_page) {
-+				result = -ENOMEM;
-+				break;
-+			}
-+			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_page(bdev, uuid_pg_num);
-+			if (!uuid_data_page) {
-+				result = -ENOMEM;
-+				break;
-+			}
-+			uuid_data = page_address(uuid_data_page);
-+		}
-+
-+		last_uuid_pg_num = uuid_pg_num;
++	if (got && !memcmp(got->uuid, seek->uuid, 16)) {
++		PRINTK(" Having matching UUID.\n");
++		PRINTK(" Got: LMS %d, LM %p.\n", got->last_mount_size, got->last_mount);
++		PRINTK(" Seek: LMS %d, LM %p.\n", seek->last_mount_size, seek->last_mount);
++		result = 1;
 +
-+		if (!memcmp(&uuid_data[uuid_pg_off], uuid, 16)) {
-+			PRINT_HEX_DUMP(KERN_EMERG, "part_matches_uuid "
-+				"matched ",	DUMP_PREFIX_NONE, 16, 1,
-+				&uuid_data[uuid_pg_off], 16, 0);
-+
-+			PRINTK("UUID found on device %s, type %s.\n", buf,
-+					dat->name);
-+			result = 1;
-+			break;
++		if (got->last_mount_size == seek->last_mount_size &&
++		    got->last_mount && seek->last_mount &&
++		    !memcmp(got->last_mount, seek->last_mount,
++			    got->last_mount_size)) {
++			result = 2;
++
++			PRINTK(" Matching last mount time.\n");
++
++			if (part_devt(part) == seek->dev_t) {
++				result = 3;
++				PRINTK(" Matching dev_t.\n");
++			} else
++				PRINTK("Dev_ts differ (%x vs %x).\n", part_devt(part), seek->dev_t);
 +		}
 +	}
 +
-+	if (data_page)
-+		__free_page(data_page);
-+
-+	if (uuid_data_page)
-+		__free_page(uuid_data_page);
-+
++	PRINTK(" Score for %x is %d.\n", part_devt(part), result);
++	free_fs_info(got);
 +out:
 +	blkdev_put(bdev, FMODE_READ);
 +	return result;
@@ -2116,8 +2087,7 @@
 +
 +	bdevname(bdev, buf);
 +
-+	PRINTK(KERN_EMERG "uuid_from_block_dev looking for partition type "
-+			"of %s.\n", buf);
++	PRINTK("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];
@@ -2138,10 +2108,8 @@
 +			if (data_page)
 +				__free_page(data_page);
 +			data_page = read_bdev_page(bdev, pg_num);
-+			if (!data_page) {
-+				fs_info = ERR_PTR(-ENOMEM);
-+				break;
-+			}
++			if (!data_page)
++				continue;
 +			data = page_address(data_page);
 +		}
 +
@@ -2169,15 +2137,14 @@
 +			if (uuid_data_page)
 +				__free_page(uuid_data_page);
 +			uuid_data_page = read_bdev_page(bdev, uuid_pg_num);
-+			if (!uuid_data_page) {
-+				fs_info = ERR_PTR(-ENOMEM);
-+				break;
-+			}
++			if (!uuid_data_page)
++				continue;
 +			uuid_data = page_address(uuid_data_page);
 +		}
 +
 +		last_uuid_pg_num = uuid_pg_num;
 +		memcpy(&fs_info->uuid, &uuid_data[uuid_pg_off], 16);
++		fs_info->dev_t = bdev->bd_dev;
 +
 +no_uuid:
 +		PRINT_HEX_DUMP(KERN_EMERG, "fs_info_from_block_dev "
@@ -3313,6 +3280,31 @@
  #else
  static inline void bd_forget(struct inode *inode) {}
  static inline int sync_blockdev(struct block_device *bdev) { return 0; }
+diff --git a/include/linux/fs_uuid.h b/include/linux/fs_uuid.h
+new file mode 100644
+index 0000000..3234135
+--- /dev/null
++++ b/include/linux/fs_uuid.h
+@@ -0,0 +1,19 @@
++#include <linux/device.h>
++
++struct hd_struct;
++struct block_device;
++
++struct fs_info {
++	char uuid[16];
++	dev_t dev_t;
++	char *last_mount;
++	int last_mount_size;
++};
++
++int part_matches_fs_info(struct hd_struct *part, struct fs_info *seek);
++dev_t blk_lookup_fs_info(struct fs_info *seek);
++struct fs_info *fs_info_from_block_dev(struct block_device *bdev);
++void free_fs_info(struct fs_info *fs_info);
++int bdev_matches_key(struct block_device *bdev, const char *key);
++struct block_device *next_bdev_of_type(struct block_device *last,
++	const char *key);
 diff --git a/include/linux/mm.h b/include/linux/mm.h
 index 462acaf..cd1c705 100644
 --- a/include/linux/mm.h
@@ -3453,30 +3445,6 @@
  extern int reuse_swap_page(struct page *);
  extern int try_to_free_swap(struct page *);
  struct backing_dev_info;
-diff --git a/include/linux/uuid.h b/include/linux/uuid.h
-new file mode 100644
-index 0000000..a968f0f
---- /dev/null
-+++ b/include/linux/uuid.h
-@@ -0,0 +1,18 @@
-+#include <linux/device.h>
-+
-+struct hd_struct;
-+struct block_device;
-+
-+struct fs_info {
-+	char uuid[16];
-+	char *last_mount;
-+	int last_mount_size;
-+};
-+
-+int part_matches_uuid(struct hd_struct *part, const char *uuid);
-+dev_t blk_lookup_uuid(const char *uuid);
-+struct fs_info *fs_info_from_block_dev(struct block_device *bdev);
-+void free_fs_info(struct fs_info *fs_info);
-+int bdev_matches_key(struct block_device *bdev, const char *key);
-+struct block_device *next_bdev_of_type(struct block_device *last,
-+	const char *key);
 diff --git a/init/do_mounts.c b/init/do_mounts.c
 index 02e3ca4..5af8c3e 100644
 --- a/init/do_mounts.c
@@ -4799,7 +4767,7 @@
   *	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..e7bc111
+index 0000000..537291e
 --- /dev/null
 +++ b/kernel/power/tuxonice.h
 @@ -0,0 +1,211 @@
@@ -4826,8 +4794,8 @@
 +#include "tuxonice_pageflags.h"
 +#include "power.h"
 +
-+#define TOI_CORE_VERSION "3.1"
-+#define	TOI_HEADER_VERSION 2
++#define TOI_CORE_VERSION "3.1.1.1"
++#define	TOI_HEADER_VERSION 3
 +#define MY_BOOT_KERNEL_DATA_VERSION 3
 +
 +struct toi_boot_kernel_data {
@@ -6976,10 +6944,10 @@
 +}
 diff --git a/kernel/power/tuxonice_bio_core.c b/kernel/power/tuxonice_bio_core.c
 new file mode 100644
-index 0000000..225aa49
+index 0000000..414d249
 --- /dev/null
 +++ b/kernel/power/tuxonice_bio_core.c
-@@ -0,0 +1,1809 @@
+@@ -0,0 +1,1822 @@
 +/*
 + * kernel/power/tuxonice_bio.c
 + *
@@ -6997,7 +6965,7 @@
 +#include <linux/syscalls.h>
 +#include <linux/suspend.h>
 +#include <linux/ctype.h>
-+#include <linux/uuid.h>
++#include <linux/fs_uuid.h>
 +#include <scsi/scsi_scan.h>
 +
 +#include "tuxonice.h"
@@ -7130,7 +7098,11 @@
 +	char buf[32];
 +
 +	if (uuid) {
-+		device = blk_lookup_uuid(uuid);
++		struct fs_info seek;
++		strncpy((char *) &seek.uuid, uuid, 16);
++		seek.dev_t = 0;
++		seek.last_mount_size = 0;
++		device = blk_lookup_fs_info(&seek);
 +		if (!device) {
 +			device = default_device;
 +			printk(KERN_DEBUG "Unable to resolve uuid. Falling back"
@@ -8412,10 +8384,15 @@
 +	toi_message(TOI_IO, TOI_VERBOSE, 0, "Header dev_t is %lx.",
 +			toi_sig_data->header_dev_t);
 +	if (toi_sig_data->have_uuid) {
++		struct fs_info seek;
 +		dev_t device;
-+		device = blk_lookup_uuid(toi_sig_data->header_uuid);
++
++		strncpy((char *) seek.uuid, toi_sig_data->header_uuid, 16);
++		seek.dev_t = toi_sig_data->header_dev_t;
++		seek.last_mount_size = 0;
++		device = blk_lookup_fs_info(&seek);
 +		if (device) {
-+			printk("Using dev_t %s, returned by blk_lookup_uuid.\n",
++			printk("Using dev_t %s, returned by blk_lookup_fs_info.\n",
 +					format_dev_t(buf, device));
 +			toi_sig_data->header_dev_t = device;
 +		}
@@ -8547,7 +8524,11 @@
 +		retry_if_fails(toi_bio_scan_for_image(quiet));
 +
 +	if (uuid) {
-+		retry_if_fails(resume_dev_t = blk_lookup_uuid(uuid));
++		struct fs_info seek;
++		strncpy((char *) &seek.uuid, uuid, 16);
++		seek.dev_t = resume_dev_t;
++		seek.last_mount_size = 0;
++		retry_if_fails(resume_dev_t = blk_lookup_fs_info(&seek));
 +		kfree(uuid);
 +	}
 +
@@ -8883,7 +8864,7 @@
 +int open_resume_dev_t(int force, int quiet);
 diff --git a/kernel/power/tuxonice_bio_signature.c b/kernel/power/tuxonice_bio_signature.c
 new file mode 100644
-index 0000000..7913c12
+index 0000000..2ebee7e
 --- /dev/null
 +++ b/kernel/power/tuxonice_bio_signature.c
 @@ -0,0 +1,404 @@
@@ -8896,7 +8877,7 @@
 + *
 + */
 +
-+#include <linux/uuid.h>
++#include <linux/fs_uuid.h>
 +
 +#include "tuxonice.h"
 +#include "tuxonice_sysfs.h"
@@ -9293,10 +9274,10 @@
 +}
 diff --git a/kernel/power/tuxonice_builtin.c b/kernel/power/tuxonice_builtin.c
 new file mode 100644
-index 0000000..d9704f2
+index 0000000..bc967d6
 --- /dev/null
 +++ b/kernel/power/tuxonice_builtin.c
-@@ -0,0 +1,360 @@
+@@ -0,0 +1,372 @@
 +/*
 + * Copyright (C) 2004-2010 Nigel Cunningham (nigel at tuxonice net)
 + *
@@ -9596,6 +9577,18 @@
 +__nosavedata struct pbe *restore_highmem_pblist;
 +EXPORT_SYMBOL_GPL(restore_highmem_pblist);
 +
++void toi_read_lock_tasklist(void)
++{
++	read_lock(&tasklist_lock);
++}
++EXPORT_SYMBOL_GPL(toi_read_lock_tasklist);
++
++void toi_read_unlock_tasklist(void)
++{
++	read_unlock(&tasklist_lock);
++}
++EXPORT_SYMBOL_GPL(toi_read_unlock_tasklist);
++
 +static int __init toi_wait_setup(char *str)
 +{
 +	int value;
@@ -9659,10 +9652,10 @@
 +__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..56ede35
+index 0000000..ab67d31
 --- /dev/null
 +++ b/kernel/power/tuxonice_builtin.h
-@@ -0,0 +1,30 @@
+@@ -0,0 +1,32 @@
 +/*
 + * Copyright (C) 2004-2010 Nigel Cunningham (nigel at tuxonice net)
 + *
@@ -9693,6 +9686,8 @@
 +extern int toi_wait;
 +extern int toi_translate_err_default;
 +extern int toi_force_no_multithreaded;
++extern void toi_read_lock_tasklist(void);
++extern void toi_read_unlock_tasklist(void);
 diff --git a/kernel/power/tuxonice_checksum.c b/kernel/power/tuxonice_checksum.c
 new file mode 100644
 index 0000000..3ec2c76
@@ -11896,7 +11891,7 @@
 +#endif
 diff --git a/kernel/power/tuxonice_file.c b/kernel/power/tuxonice_file.c
 new file mode 100644
-index 0000000..e40f5d8
+index 0000000..7a4614a
 --- /dev/null
 +++ b/kernel/power/tuxonice_file.c
 @@ -0,0 +1,496 @@
@@ -11934,7 +11929,7 @@
 +#include <linux/blkdev.h>
 +#include <linux/mount.h>
 +#include <linux/fs.h>
-+#include <linux/uuid.h>
++#include <linux/fs_uuid.h>
 +
 +#include "tuxonice.h"
 +#include "tuxonice_modules.h"
@@ -13717,10 +13712,10 @@
 +#endif
 diff --git a/kernel/power/tuxonice_io.c b/kernel/power/tuxonice_io.c
 new file mode 100644
-index 0000000..94c8b88
+index 0000000..6030dc6
 --- /dev/null
 +++ b/kernel/power/tuxonice_io.c
-@@ -0,0 +1,1822 @@
+@@ -0,0 +1,1836 @@
 +/*
 + * kernel/power/tuxonice_io.c
 + *
@@ -13744,7 +13739,7 @@
 +#include <linux/cpu.h>
 +#include <linux/fs_struct.h>
 +#include <linux/bio.h>
-+#include <linux/uuid.h>
++#include <linux/fs_uuid.h>
 +#include <asm/tlbflush.h>
 +
 +#include "tuxonice.h"
@@ -13764,12 +13759,12 @@
 +/* Version read from image header at resume */
 +static int toi_image_header_version;
 +
-+#define read_if_version(VERS, VAR, DESC) do {					\
++#define read_if_version(VERS, VAR, DESC, ERR_ACT) do {					\
 +	if (likely(toi_image_header_version >= VERS))				\
 +		if (toiActiveAllocator->rw_header_chunk(READ, NULL,		\
 +					(char *) &VAR, sizeof(VAR))) {		\
 +			abort_hibernate(TOI_FAILED_IO, "Failed to read DESC.");	\
-+			goto out_remove_image;					\
++			ERR_ACT;					\
 +		}								\
 +} while(0)									\
 +
@@ -14870,7 +14865,8 @@
 +
 +		fs = fs_info_from_block_dev(sb->s_bdev);
 +		if (save_fs_info(fs, sb->s_bdev))
-+			result += 16 + sizeof(int) + fs->last_mount_size;
++			result += 16 + sizeof(dev_t) + sizeof(int) +
++				fs->last_mount_size;
 +		free_fs_info(fs);
 +	}
 +	return result;
@@ -14923,6 +14919,12 @@
<<Diff was trimmed, longer than 597 lines>>

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/kernel/kernel-tuxonice.patch?r1=1.13&r2=1.14&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/kernel/kernel.spec?r1=1.792&r2=1.793&f=u



More information about the pld-cvs-commit mailing list