Please find attached my modifications to the
libparted/fs/linux_swap/linux_swap.c file. Although it is only the
diff between the 'master' linux_swap.c file and my copy, it is really
big and intrusive. I would have liked to make it available in smaller
parts, but unfortunately it is becoming too cumbersome to do that.
Let me jot down the main aspects of the patch:
1. Support for swsusp image containing partitions. This addresses
http://bugzilla.gnome.org/show_bug.cgi?id=334569
2. Syncronizing the linux-swap structures in accordance with the linux
kernel sources.
3. Code clean-ups here & there.
If you find it really difficult, I will explain the diff in parts.
Happy hacking,
Debarshi
--
After the game the king and the pawn go into the same box.
-- Italian proverb
--- parted/libparted/fs/linux_swap/linux_swap.c 2007-01-14 20:11:51.000000000 +0530
+++ parted-build/libparted/fs/linux_swap/linux_swap.c 2007-01-15 06:24:27.000000000 +0530
@@ -31,8 +31,9 @@
# define _(String) (String)
#endif /* ENABLE_NLS */
-#include <unistd.h>
+#include <stdint.h>
#include <string.h>
+#include <unistd.h>
#define SWAP_SPECIFIC(fs) ((SwapSpecific*) (fs->type_specific))
#define BUFFER_SIZE 128
@@ -46,11 +47,13 @@ typedef struct {
/* ripped from mkswap */
typedef struct {
char bootbits[1024]; /* Space for disklabel etc. */
- unsigned int version;
- unsigned int last_page;
- unsigned int nr_badpages;
- unsigned int padding[125];
- unsigned int badpages[1];
+ uint32_t version;
+ uint32_t last_page;
+ uint32_t nr_badpages;
+ unsigned char sws_uuid[16];
+ unsigned char sws_volume[16];
+ uint32_t padding[117];
+ uint32_t badpages[1];
} SwapNewHeader;
typedef struct {
@@ -68,20 +71,38 @@ typedef struct {
unsigned int max_bad_pages;
} SwapSpecific;
-static PedFileSystemType swap_type;
-
-static PedFileSystem* swap_open (PedGeometry* geom);
+static PedFileSystemType _swap_v1_type;
+static PedFileSystemType _swap_v2_type;
+static PedFileSystemType _swap_swsusp_type;
+
+static PedFileSystem* _swap_v1_open (PedGeometry* geom);
+static PedFileSystem* _swap_v2_open (PedGeometry* geom);
+static PedFileSystem* _swap_swsusp_open (PedGeometry* geom);
static int swap_close (PedFileSystem* fs);
static PedGeometry*
-swap_probe (PedGeometry* geom)
+_generic_swap_probe (PedGeometry* geom, int kind)
{
PedFileSystem* fs;
SwapSpecific* fs_info;
PedGeometry* probed_geom;
PedSector length;
- fs = swap_open (geom);
+ switch (kind) {
+ /* Check for old style swap partitions. */
+ case 0:
+ fs = _swap_v1_open(geom);
+ break;
+ /* Check for new style swap partitions. */
+ case 1:
+ fs = _swap_v2_open(geom);
+ break;
+ /* Check for swap partitions containing swsusp data. */
+ case -1:
+ fs = _swap_swsusp_open(geom);
+ break;
+ }
+
if (!fs)
goto error;
fs_info = SWAP_SPECIFIC (fs);
@@ -89,7 +110,8 @@ swap_probe (PedGeometry* geom)
if (fs_info->version)
length = fs_info->page_sectors * fs_info->page_count;
else
- length = geom->length;
+ length = geom->length;
+
probed_geom = ped_geometry_new (geom->dev, geom->start, length);
if (!probed_geom)
goto error_close_fs;
@@ -104,12 +126,26 @@ error:
#ifndef DISCOVER_ONLY
static int
-swap_clobber (PedGeometry* geom)
+_generic_swap_clobber (PedGeometry* geom, int kind)
{
PedFileSystem* fs;
char buf[512];
- fs = swap_open (geom);
+ switch (kind) {
+ /* Check for old style swap partitions. */
+ case 0:
+ fs = _swap_v1_open(geom);
+ break;
+ /* Check for new style swap partitions. */
+ case 1:
+ fs = _swap_v2_open(geom);
+ break;
+ /* Check for swap partitions containing swsusp data. */
+ case -1:
+ fs = _swap_swsusp_open(geom);
+ break;
+ }
+
if (!fs)
return 1;
@@ -127,7 +163,7 @@ error:
}
#endif /* !DISCOVER_ONLY */
-static void
+static int
swap_init (PedFileSystem* fs, int fresh)
{
SwapSpecific* fs_info = SWAP_SPECIFIC (fs);
@@ -138,11 +174,13 @@ swap_init (PedFileSystem* fs, int fresh)
fs_info->max_bad_pages = (getpagesize()
- sizeof (SwapNewHeader)) / 4;
- if (fresh)
+ if (fresh) {
memset (fs_info->header, 0, getpagesize());
+ return 1;
+ }
else
- ped_geometry_read (fs->geom, fs_info->header,
- 0, fs_info->page_sectors);
+ return ped_geometry_read (fs->geom, fs_info->header,
+ 0, fs_info->page_sectors);
}
static PedFileSystem*
@@ -173,7 +211,7 @@ swap_alloc (PedGeometry* geom)
fs->geom = ped_geometry_duplicate (geom);
if (!fs->geom)
goto error_free_buffer;
- fs->type = &swap_type;
+ fs->type = &_swap_v2_type;
return fs;
error_free_buffer:
@@ -202,7 +240,7 @@ swap_free (PedFileSystem* fs)
}
static PedFileSystem*
-swap_open (PedGeometry* geom)
+_swap_v1_open (PedGeometry* geom)
{
PedFileSystem* fs;
SwapSpecific* fs_info;
@@ -224,7 +262,47 @@ swap_open (PedGeometry* geom)
fs_info->page_count
= PED_MIN (fs->geom->length / fs_info->page_sectors,
8 * (getpagesize() - 10));
- } else if (strncmp (sig, "SWAPSPACE2", 10) == 0) {
+ } else {
+ char _sig [11];
+
+ memcpy (_sig, sig, 10);
+ _sig [10] = 0;
+ ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+ _("Unrecognised old style linux swap signature '%10s'."), _sig);
+ goto error_free_fs;
+ }
+
+ fs->checked = 1;
+ return fs;
+
+error_free_fs:
+ swap_free (fs);
+error:
+ return NULL;
+}
+
+static PedFileSystem*
+_swap_v2_open (PedGeometry* geom)
+{
+ PedFileSystem* fs;
+ SwapSpecific* fs_info;
+ const char* sig;
+
+ fs = swap_alloc (geom);
+ if (!fs)
+ goto error;
+/* swap_init (fs, 0); */
+
+/* fs_info = SWAP_SPECIFIC (fs); */
+/* if (!ped_geometry_read (fs->geom, fs_info->header, 0, */
+/* fs_info->page_sectors)) */
+ if (!swap_init(fs, 0))
+ goto error_free_fs;
+
+ fs_info = SWAP_SPECIFIC (fs);
+
+ sig = ((char*) fs_info->header) + getpagesize() - 10;
+ if (strncmp (sig, "SWAPSPACE2", 10) == 0) {
fs_info->version = 1;
fs_info->page_count = fs_info->header->new.last_page;
} else {
@@ -233,7 +311,47 @@ swap_open (PedGeometry* geom)
memcpy (_sig, sig, 10);
_sig [10] = 0;
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Unrecognised linux swap signature '%10s'."), _sig);
+ _("Unrecognised new style linux swap signature '%10s'."), _sig);
+ goto error_free_fs;
+ }
+
+ fs->checked = 1;
+ return fs;
+
+error_free_fs:
+ swap_free (fs);
+error:
+ return NULL;
+}
+
+static PedFileSystem*
+_swap_swsusp_open (PedGeometry* geom)
+{
+ PedFileSystem* fs;
+ SwapSpecific* fs_info;
+ const char* sig;
+
+ fs = swap_alloc (geom);
+ if (!fs)
+ goto error;
+ fs->type = &_swap_swsusp_type;
+ swap_init (fs, 0);
+
+ fs_info = SWAP_SPECIFIC (fs);
+ if (!ped_geometry_read (fs->geom, fs_info->header, 0,
+ fs_info->page_sectors))
+ goto error_free_fs;
+
+ sig = ((char*) fs_info->header) + getpagesize() - 10;
+ if (strncmp (sig, "S1SUSPEND", 9) == 0) {
+ fs_info->version = -1;
+ } else {
+ char _sig [10];
+
+ memcpy (_sig, sig, 9);
+ _sig [9] = 0;
+ ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+ _("Unrecognised swsusp linux swap signature '%9s'."), _sig);
goto error_free_fs;
}
@@ -436,7 +554,7 @@ error:
static PedFileSystem*
swap_copy (const PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
{
- return ped_file_system_create (geom, &swap_type, timer);
+ return ped_file_system_create (geom, &_swap_v2_type, timer);
}
static int
@@ -472,11 +590,95 @@ swap_get_copy_constraint (const PedFileS
}
#endif /* !DISCOVER_ONLY */
-static PedFileSystemOps swap_ops = {
- probe: swap_probe,
+static PedGeometry*
+_swap_v1_probe (PedGeometry* geom) {
+ return _generic_swap_probe (geom, 0);
+}
+
+static PedGeometry*
+_swap_v2_probe (PedGeometry* geom) {
+ return _generic_swap_probe (geom, 1);
+}
+
+static PedGeometry*
+_swap_swsusp_probe (PedGeometry* geom) {
+ return _generic_swap_probe (geom, -1);
+}
+
+static int
+_swap_v1_clobber (PedGeometry* geom) {
+ return _generic_swap_clobber (geom, 0);
+}
+
+static int
+_swap_v2_clobber (PedGeometry* geom) {
+ return _generic_swap_clobber (geom, 1);
+}
+
+static int
+_swap_swsusp_clobber (PedGeometry* geom) {
+ return _generic_swap_clobber (geom, -1);
+}
+
+static PedFileSystemOps _swap_v1_ops = {
+ probe: _swap_v1_probe,
+#ifndef DISCOVER_ONLY
+ clobber: _swap_v1_clobber,
+ open: _swap_v1_open,
+ create: swap_create,
+ close: swap_close,
+ check: swap_check,
+ copy: swap_copy,
+ resize: swap_resize,
+ get_create_constraint: swap_get_create_constraint,
+ get_resize_constraint: swap_get_resize_constraint,
+ get_copy_constraint: swap_get_copy_constraint
+#else
+ clobber: NULL,
+ open: NULL,
+ create: NULL,
+ close: NULL,
+ check: NULL,
+ copy: NULL,
+ resize: NULL,
+ get_create_constraint: NULL,
+ get_resize_constraint: NULL,
+ get_copy_constraint: NULL
+#endif /* !DISCOVER_ONLY */
+};
+
+static PedFileSystemOps _swap_v2_ops = {
+ probe: _swap_v2_probe,
+#ifndef DISCOVER_ONLY
+ clobber: _swap_v2_clobber,
+ open: _swap_v2_open,
+ create: swap_create,
+ close: swap_close,
+ check: swap_check,
+ copy: swap_copy,
+ resize: swap_resize,
+ get_create_constraint: swap_get_create_constraint,
+ get_resize_constraint: swap_get_resize_constraint,
+ get_copy_constraint: swap_get_copy_constraint
+#else
+ clobber: NULL,
+ open: NULL,
+ create: NULL,
+ close: NULL,
+ check: NULL,
+ copy: NULL,
+ resize: NULL,
+ get_create_constraint: NULL,
+ get_resize_constraint: NULL,
+ get_copy_constraint: NULL
+#endif /* !DISCOVER_ONLY */
+};
+
+static PedFileSystemOps _swap_swsusp_ops = {
+ probe: _swap_swsusp_probe,
#ifndef DISCOVER_ONLY
- clobber: swap_clobber,
- open: swap_open,
+ clobber: _swap_swsusp_clobber,
+ open: _swap_swsusp_open,
create: swap_create,
close: swap_close,
check: swap_check,
@@ -499,22 +701,39 @@ static PedFileSystemOps swap_ops = {
#endif /* !DISCOVER_ONLY */
};
-static PedFileSystemType swap_type = {
+static PedFileSystemType _swap_v1_type = {
next: NULL,
- ops: &swap_ops,
- name: "linux-swap",
+ ops: &_swap_v1_ops,
+ name: "linux-swap(old)",
block_sizes: LINUXSWAP_BLOCK_SIZES
};
+static PedFileSystemType _swap_v2_type = {
+ next: NULL,
+ ops: &_swap_v2_ops,
+ name: "linux-swap(new)",
+ block_sizes: LINUXSWAP_BLOCK_SIZES
+};
+
+static PedFileSystemType _swap_swsusp_type = {
+ next: NULL,
+ ops: &_swap_swsusp_ops,
+ name: "swsusp",
+ block_sizes: LINUXSWAP_BLOCK_SIZES
+};
+
void
ped_file_system_linux_swap_init ()
{
- ped_file_system_type_register (&swap_type);
+ ped_file_system_type_register (&_swap_v1_type);
+ ped_file_system_type_register (&_swap_v2_type);
+ ped_file_system_type_register (&_swap_swsusp_type);
}
void
ped_file_system_linux_swap_done ()
{
- ped_file_system_type_unregister (&swap_type);
+ ped_file_system_type_unregister (&_swap_v1_type);
+ ped_file_system_type_unregister (&_swap_v2_type);
+ ped_file_system_type_unregister (&_swap_swsusp_type);
}
-
_______________________________________________
parted-devel mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/parted-devel