Subject: Add Intel Fast Flash(iFFS) partition type support on GPT disk type

From: Max Lin <[email-masked]>
Date: Thu, 05 Sep 2013 12:30:37 +0800

Hello list,

This patch is intend to add Intel Fast Flash(iFFS) partition type 
support on GPT disk type to parted, the GUID code of this type is 
D3BFE2DE-3DAF-11DF-BA40-E3A556D89593, this partition type is a 
requirements of Intel Rapid Start Technology[1].

This patch also contains a test script, and no complain from "make 
distcheck". Could you please review this patch and give me any 
suggestion? Thanks a lot!!

Best regards,
Max

[1] 
http://software.intel.com/en-us/articles/what-is-intel-rapid-start-technology
>From df1788f6297ff16335ed25643d9e26343d10018c Mon Sep 17 00:00:00 2001
From: Max Lin <[email-masked]>
Date: Thu, 22 Aug 2013 11:53:16 +0800
Subject: [PATCH] libparted: Add Intel Fast Flash(iFFS) partition type support
 on gpt disk type

Add Intel Fast Flash(iFFS) flag on gpt disk type, iFFS partition is one
pre-requirements of Intel Rapid Start Technology. The concept of Intel
Rapid Start Technology is, when suspend your computer and the timeout
expires, the firmware just copies the entire contents of RAM to iFFS
partition and turns the computer off, the firmware dumps the contents
back into RAM and resume at next time hit the power button.

* NEWS (Changes in behavior): Mention the feature of iFFS partition.
* libparted/labels/gpt.c: Add this new feature.
* libparted/disk.c: Likewise.
* include/parted/disk.in.h: Add iFFS to _PedPartitionFlag.
* tests/t0260-gpt-iffs.sh: New test against iffs flag.
* tests/Makefile.am: Add it.
---
 NEWS                     |  9 ++++++++
 include/parted/disk.in.h |  3 ++-
 libparted/disk.c         |  2 ++
 libparted/labels/gpt.c   | 59 ++++++++++++++++++++++++++++++++++++++++--------
 tests/Makefile.am        |  1 +
 tests/t0260-gpt-iffs.sh  | 44 ++++++++++++++++++++++++++++++++++++
 6 files changed, 107 insertions(+), 11 deletions(-)
 create mode 100644 tests/t0260-gpt-iffs.sh

diff --git a/NEWS b/NEWS
index 98f7c6e..7dbda21 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,15 @@ GNU parted NEWS                                    -*- outline -*-
   System partitions) or "msftres" (which sets the "Microsoft Reserved" type
   code).
 
+  Added new "iffs" flag on GPT disks.  This flag corresponds to a GPT type
+  code of D3BFE2DE-3DAF-11DF-BA40-E3A556D89593 ("Intel Fast Flash"). This
+  partition type is a pre-requirements of Intel Rapid Start Technology, it is
+  needs to be a partition that's at least the size of your system's physical
+  RAM, and need given a type GUID of D3BFE2DE-3DAF-11DF-BA40-E3A556D89593.
+  The concept of Intel Rapid Start Technology is, when suspend your computer
+  and the timeout expires, the firmware just copies the entire contents of
+  RAM to iFFS partition and turns the computer off, the firmware dumps the
+  contents back into RAM and resume at next time hit the power button.
 
 * Noteworthy changes in release 3.1 (2012-03-02) [stable]
 
diff --git a/include/parted/disk.in.h b/include/parted/disk.in.h
index aa905c5..76f7c82 100644
--- a/include/parted/disk.in.h
+++ b/include/parted/disk.in.h
@@ -73,7 +73,8 @@ enum _PedPartitionFlag {
         PED_PARTITION_APPLE_TV_RECOVERY=13,
         PED_PARTITION_DIAG=14,
         PED_PARTITION_LEGACY_BOOT=15,
-        PED_PARTITION_MSFT_DATA=16
+        PED_PARTITION_IFFS=16,
+        PED_PARTITION_MSFT_DATA=17
 };
 #define PED_PARTITION_FIRST_FLAG        PED_PARTITION_BOOT
 #define PED_PARTITION_LAST_FLAG         PED_PARTITION_MSFT_DATA
diff --git a/libparted/disk.c b/libparted/disk.c
index d3cd5bb..6f033d8 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -2441,6 +2441,8 @@ ped_partition_flag_get_name (PedPartitionFlag flag)
                 return N_("diag");
         case PED_PARTITION_LEGACY_BOOT:
                 return N_("legacy_boot");
+        case PED_PARTITION_IFFS:
+                return N_("iffs");
 
 	default:
 		ped_exception_throw (
diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index 490de70..021f36e 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -146,6 +146,10 @@ typedef struct
     ((efi_guid_t) { PED_CPU_TO_LE32 (0x5265636F), PED_CPU_TO_LE16 (0x7665), \
                     PED_CPU_TO_LE16 (0x11AA), 0xaa, 0x11, \
                     { 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC }})
+#define PARTITION_IFFS_GUID \
+    ((efi_guid_t) { PED_CPU_TO_LE32 (0xD3BFE2DE), PED_CPU_TO_LE16 (0x3DAF), \
+                    PED_CPU_TO_LE16 (0x11DF), 0xBA, 0x40, \
+                    { 0xE3, 0xA5, 0x56, 0xD8, 0x95, 0x93 }})
 
 struct __attribute__ ((packed)) _GuidPartitionTableHeader_t
 {
@@ -288,6 +292,7 @@ typedef struct _GPTPartitionData
   int atvrecv;
   int msftrecv;
   int legacy_boot;
+  int iffs;
 } GPTPartitionData;
 
 static PedDiskType gpt_disk_type;
@@ -796,7 +801,8 @@ _parse_part_entry (PedDisk *disk, GuidPartitionEntry_t *pte)
     = gpt_part_data->msftdata
     = gpt_part_data->msftrecv
     = gpt_part_data->legacy_boot
-    = gpt_part_data->bios_grub = gpt_part_data->atvrecv = 0;
+    = gpt_part_data->bios_grub = gpt_part_data->atvrecv
+    = gpt_part_data->iffs = 0;
 
   if (pte->Attributes.RequiredToFunction & 0x1)
     gpt_part_data->hidden = 1;
@@ -821,6 +827,8 @@ _parse_part_entry (PedDisk *disk, GuidPartitionEntry_t *pte)
     gpt_part_data->msftrecv = 1;
   else if (!guid_cmp (gpt_part_data->type, PARTITION_APPLE_TV_RECOVERY_GUID))
     gpt_part_data->atvrecv = 1;
+  else if (!guid_cmp (gpt_part_data->type, PARTITION_IFFS_GUID))
+    gpt_part_data->iffs = 1;
 
   return part;
 }
@@ -1338,6 +1346,7 @@ gpt_partition_new (const PedDisk *disk,
   gpt_part_data->msftrecv = 0;
   gpt_part_data->atvrecv = 0;
   gpt_part_data->legacy_boot = 0;
+  gpt_part_data->iffs = 0;
   uuid_generate ((unsigned char *) &gpt_part_data->uuid);
   swap_uuid_and_efi_guid ((unsigned char *) (&gpt_part_data->uuid));
   memset (gpt_part_data->name, 0, sizeof gpt_part_data->name);
@@ -1446,6 +1455,11 @@ gpt_partition_set_system (PedPartition *part,
       gpt_part_data->type = PARTITION_APPLE_TV_RECOVERY_GUID;
       return 1;
     }
+  if (gpt_part_data->iffs)
+    {
+      gpt_part_data->type = PARTITION_IFFS_GUID;
+      return 1;
+    }
 
   if (fs_type)
     {
@@ -1587,7 +1601,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->msftres
           = gpt_part_data->msftdata
           = gpt_part_data->msftrecv
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_BIOS_GRUB:
       gpt_part_data->bios_grub = state;
@@ -1599,7 +1614,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->msftres
           = gpt_part_data->msftdata
           = gpt_part_data->msftrecv
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_RAID:
       gpt_part_data->raid = state;
@@ -1611,7 +1627,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->msftres
           = gpt_part_data->msftdata
           = gpt_part_data->msftrecv
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_LVM:
       gpt_part_data->lvm = state;
@@ -1623,7 +1640,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->msftres
           = gpt_part_data->msftdata
           = gpt_part_data->msftrecv
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_HPSERVICE:
       gpt_part_data->hp_service = state;
@@ -1635,7 +1653,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->msftres
           = gpt_part_data->msftdata
           = gpt_part_data->msftrecv
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_MSFT_RESERVED:
       gpt_part_data->msftres = state;
@@ -1647,7 +1666,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->hp_service
           = gpt_part_data->msftdata
           = gpt_part_data->msftrecv
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_MSFT_DATA:
       gpt_part_data->msftres = state;
@@ -1659,7 +1679,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->hp_service
           = gpt_part_data->msftres
           = gpt_part_data->msftrecv
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
         gpt_part_data->msftdata = 1;
       } else {
         gpt_part_data->msftdata = 0;
@@ -1675,7 +1696,8 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->hp_service
           = gpt_part_data->msftdata
           = gpt_part_data->msftres
-          = gpt_part_data->atvrecv = 0;
+          = gpt_part_data->atvrecv
+          = gpt_part_data->iffs = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_APPLE_TV_RECOVERY:
       gpt_part_data->atvrecv = state;
@@ -1687,7 +1709,21 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
           = gpt_part_data->hp_service
           = gpt_part_data->msftres
           = gpt_part_data->msftdata
-          = gpt_part_data->msftrecv = 0;
+          = gpt_part_data->msftrecv
+          = gpt_part_data->iffs = 0;
+      return gpt_partition_set_system (part, part->fs_type);
+    case PED_PARTITION_IFFS:
+      gpt_part_data->iffs = state;
+      if (state)
+        gpt_part_data->boot
+          = gpt_part_data->raid
+          = gpt_part_data->lvm
+          = gpt_part_data->bios_grub
+          = gpt_part_data->hp_service
+          = gpt_part_data->msftres
+          = gpt_part_data->msftdata
+          = gpt_part_data->msftrecv
+          = gpt_part_data->atvrecv = 0;
       return gpt_partition_set_system (part, part->fs_type);
     case PED_PARTITION_HIDDEN:
       gpt_part_data->hidden = state;
@@ -1735,6 +1771,8 @@ gpt_partition_get_flag (const PedPartition *part, PedPartitionFlag flag)
       return gpt_part_data->hidden;
     case PED_PARTITION_LEGACY_BOOT:
       return gpt_part_data->legacy_boot;
+    case PED_PARTITION_IFFS:
+      return gpt_part_data->iffs;
     case PED_PARTITION_SWAP:
     case PED_PARTITION_LBA:
     case PED_PARTITION_ROOT:
@@ -1761,6 +1799,7 @@ gpt_partition_is_flag_available (const PedPartition *part,
     case PED_PARTITION_APPLE_TV_RECOVERY:
     case PED_PARTITION_HIDDEN:
     case PED_PARTITION_LEGACY_BOOT:
+    case PED_PARTITION_IFFS:
       return 1;
     case PED_PARTITION_SWAP:
     case PED_PARTITION_ROOT:
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4ec08da..7df742f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -27,6 +27,7 @@ TESTS = \
   t0212-gpt-many-partitions.sh \
   t0220-gpt-msftres.sh \
   t0250-gpt.sh \
+  t0260-gpt-iffs.sh \
   t0280-gpt-corrupt.sh \
   t0300-dos-on-gpt.sh \
   t0301-overwrite-gpt-pmbr.sh \
diff --git a/tests/t0260-gpt-iffs.sh b/tests/t0260-gpt-iffs.sh
new file mode 100644
index 0000000..cc0a927
--- /dev/null
+++ b/tests/t0260-gpt-iffs.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+# iFFS parition type support on gpt disk type
+
+# Copyright (C) 2012-2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../parted
+
+dev=loop-file
+ss=$sector_size_
+n_sectors=5000
+
+# Create the smallest file that can accommodate a GPT partition table.
+dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || framework_failure
+
+# Create a GPT partition table
+parted -s $dev mklabel gpt > out 2>&1 || fail=1
+# Expect no output
+compare /dev/null out || fail=1
+
+# Create a single partition without fs-type given
+parted -s $dev mkpart primary 1m 2m > out 2>&1 || fail=1
+# Expect no output
+compare /dev/null out || fail=1
+
+# Set the iffs flag
+parted -s $dev set 1 iffs on || fail=1
+# Ensure that setting the "iffs" flag works
+parted -s $dev u s p > out || fail=1
+grep iffs out || { fail=1; cat out; }
+
+Exit $fail
-- 
1.8.1.4