platform: msm_shared: Turn off the space-fixup in the flashed image

When using UBI aware flasher there is no need to have the space-fixup performed
on first boot since it's done by the flasher. If the flashed image was created with
the space-fixup flag, turn it off in order to expedite the first boot after flashing the
image.

Change-Id: I7b4467bffc26033841f5d987a5bcea6b16473d4b
diff --git a/include/dev/flash-ubi.h b/include/dev/flash-ubi.h
index b758352..50577cc 100644
--- a/include/dev/flash-ubi.h
+++ b/include/dev/flash-ubi.h
@@ -33,6 +33,48 @@
 #include <lib/ptable.h>
 #include <stdint.h>
 
+struct __attribute__ ((packed)) ubifs_ch {
+	uint32_t magic;
+	uint32_t crc;
+	uint64_t sqnum;
+	uint32_t len;
+#define UBIFS_SB_NODE	6
+	uint8_t node_type;
+	uint8_t group_type;
+	uint8_t padding[2];
+};
+
+/* UBIFS superblock node */
+struct __attribute__ ((packed)) ubifs_sb_node {
+	struct ubifs_ch ch;
+	uint8_t padding[2];
+	uint8_t key_hash;
+	uint8_t key_fmt;
+#define UBIFS_FLG_SPACE_FIXUP  0x04
+	uint32_t flags;
+	uint32_t min_io_size;
+	uint32_t leb_size;
+	uint32_t leb_cnt;
+	uint32_t max_leb_cnt;
+	uint64_t max_bud_bytes;
+	uint32_t log_lebs;
+	uint32_t lpt_lebs;
+	uint32_t orph_lebs;
+	uint32_t jhead_cnt;
+	uint32_t fanout;
+	uint32_t lsave_cnt;
+	uint32_t fmt_version;
+	uint16_t default_compr;
+	uint8_t padding1[2];
+	uint32_t rp_uid;
+	uint32_t rp_gid;
+	uint64_t rp_size;
+	uint32_t time_gran;
+	uint8_t uuid[16];
+	uint32_t ro_compat_version;
+	uint8_t padding2[3968];
+};
+
 /* Erase counter header magic number (ASCII "UBI#") */
 #define UBI_EC_HDR_MAGIC  0x55424923
 
@@ -44,6 +86,7 @@
 #define UBI_IMAGE_SEQ_BASE 0x12345678
 #define UBI_DEF_ERACE_COUNTER 0
 #define UBI_CRC32_INIT 0xFFFFFFFFU
+#define UBIFS_CRC32_INIT 0xFFFFFFFFU
 
 /* Erase counter header fields */
 struct __attribute__ ((packed)) ubi_ec_hdr {
@@ -83,7 +126,11 @@
 #define UBI_EC_HDR_SIZE_CRC  (UBI_EC_HDR_SIZE  - sizeof(uint32_t))
 #define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(uint32_t))
 
-#define UBI_FM_SB_VOLUME_ID	(0x7FFFFFFF - 4096 + 1)
+#define UBI_MAX_VOLUMES 128
+#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096)
+#define UBI_LAYOUT_VOLUME_ID     UBI_INTERNAL_VOL_START
+#define UBI_FM_SB_VOLUME_ID	(UBI_INTERNAL_VOL_START + 1)
+
 /**
  * struct ubi_scan_info - UBI scanning information.
  * @ec: erase counters or eraseblock status for all eraseblocks
diff --git a/platform/msm_shared/flash-ubi.c b/platform/msm_shared/flash-ubi.c
index 13f24f0..0051a3a 100644
--- a/platform/msm_shared/flash-ubi.c
+++ b/platform/msm_shared/flash-ubi.c
@@ -465,6 +465,46 @@
 	}
 	return 0;
 }
+
+/**
+ * remove_F_flag() - Turn off space-fixup flag in the ubifs superblock
+ * @data: pointer to the peb to check in the flashed image
+ *
+ * The UBIFS Superblock will be located at LEB 0 of the image. LEB 0 will be
+ * mapped as follows:
+ * If the image contains Fastmap superblock:
+ * - LEB 0 will be at PEB3
+ * else:
+ * - LEB 0 will be at PEB2
+ */
+static void remove_F_flag(const void *leb_data)
+{
+	struct ubifs_ch *ch;
+	struct ubifs_sb_node *ubifs_sb;
+	struct ubi_ec_hdr *ech;
+	struct ubi_vid_hdr *vidh;
+	int vol_id;
+
+	ech = (struct ubi_ec_hdr *)leb_data;
+	vidh = (struct ubi_vid_hdr *)(leb_data + BE32(ech->vid_hdr_offset));
+	vol_id = BE32(vidh->vol_id);
+
+	if (vol_id > UBI_MAX_VOLUMES &&
+			vol_id != UBI_LAYOUT_VOLUME_ID &&
+			vol_id != UBI_FM_SB_VOLUME_ID)
+		return;
+
+	ubifs_sb = (struct ubifs_sb_node *)(leb_data + BE32(ech->data_offset));
+	ch = (struct ubifs_ch *)ubifs_sb;
+	if (ch->node_type != UBIFS_SB_NODE)
+		return;
+	if (ubifs_sb->flags & UBIFS_FLG_SPACE_FIXUP) {
+		ubifs_sb->flags &= (~UBIFS_FLG_SPACE_FIXUP);
+		ch->crc = mtd_crc32(UBIFS_CRC32_INIT, (void *)ubifs_sb + 8,
+				sizeof(struct ubifs_sb_node) - 8);
+	}
+}
+
 /**
  * flash_ubi_img() - Write the provided (UBI) image to given partition
  * @ptn: partition to write the image to
@@ -516,7 +556,7 @@
 			curr_peb++;
 			continue;
 		}
-
+		remove_F_flag(img_peb);
 		/* Update the ec_header in the image */
 		old_ech = (struct ubi_ec_hdr *)img_peb;
 		update_ec_header(old_ech, si, curr_peb - ptn->start, false);