ubi: provide a way to skip CRC checks
authorQuentin Schulz <quentin.schulz@bootlin.com>
Mon, 2 Jul 2018 09:43:50 +0000 (11:43 +0200)
committerRichard Weinberger <richard@nod.at>
Tue, 14 Aug 2018 22:25:20 +0000 (00:25 +0200)
Some users of static UBI volumes implement their own integrity check,
thus making the volume CRC check done at open time useless. For
instance, this is the case when one use the ubiblock + dm-verity +
squashfs combination, where dm-verity already checks integrity of the
block device but this time at the block granularity instead of verifying
the whole volume.

Skipping this test drastically improves the boot-time.

Suggested-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
drivers/mtd/ubi/kapi.c
drivers/mtd/ubi/ubi-media.h
drivers/mtd/ubi/ubi.h
drivers/mtd/ubi/vmt.c
drivers/mtd/ubi/vtbl.c

index d4b2e874449869629437828e6e8f8b01cce1ee74..e9e9ecbcedcc384aee39a7b3e08f9d23cffd39aa 100644 (file)
@@ -202,7 +202,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
        desc->mode = mode;
 
        mutex_lock(&ubi->ckvol_mutex);
-       if (!vol->checked) {
+       if (!vol->checked && !vol->skip_check) {
                /* This is the first open - check the volume */
                err = ubi_check_volume(ubi, vol_id);
                if (err < 0) {
index 195ff8ca821175eab37079cbc66e1f02ed35913a..b5fe8f82281b8f5884bad6250512d3cb90682227 100644 (file)
@@ -45,6 +45,11 @@ enum {
  * Volume flags used in the volume table record.
  *
  * @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
+ * @UBI_VTBL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
+ *                              open time. Should only be set on volumes that
+ *                              are used by upper layers doing this kind of
+ *                              check. Main use-case for this flag is
+ *                              boot-time reduction
  *
  * %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
  * table. UBI automatically re-sizes the volume which has this flag and makes
@@ -76,6 +81,7 @@ enum {
  */
 enum {
        UBI_VTBL_AUTORESIZE_FLG = 0x01,
+       UBI_VTBL_SKIP_CRC_CHECK_FLG = 0x02,
 };
 
 /*
index f5ba97c46160ac18ba73e46d7277b64ebddbf41e..d47b9e436e6730af38e414821c0348f1e5ac7550 100644 (file)
@@ -327,6 +327,9 @@ struct ubi_eba_leb_desc {
  *           atomic LEB change
  *
  * @eba_tbl: EBA table of this volume (LEB->PEB mapping)
+ * @skip_check: %1 if CRC check of this static volume should be skipped.
+ *             Directly reflects the presence of the
+ *             %UBI_VTBL_SKIP_CRC_CHECK_FLG flag in the vtbl entry
  * @checked: %1 if this static volume was checked
  * @corrupted: %1 if the volume is corrupted (static volumes only)
  * @upd_marker: %1 if the update marker is set for this volume
@@ -374,6 +377,7 @@ struct ubi_volume {
        void *upd_buf;
 
        struct ubi_eba_table *eba_tbl;
+       unsigned int skip_check:1;
        unsigned int checked:1;
        unsigned int corrupted:1;
        unsigned int upd_marker:1;
index 0be516780e929daa3ff31c9d73c30bbd38493da4..e2606a4e1c9e97177ec7580c04fd98d424505aaa 100644 (file)
@@ -299,6 +299,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
                vtbl_rec.vol_type = UBI_VID_DYNAMIC;
        else
                vtbl_rec.vol_type = UBI_VID_STATIC;
+
+       if (vol->skip_check)
+               vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;
+
        memcpy(vtbl_rec.name, vol->name, vol->name_len);
 
        err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
@@ -733,6 +737,11 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
                        ubi_err(ubi, "bad used_bytes");
                        goto fail;
                }
+
+               if (vol->skip_check) {
+                       ubi_err(ubi, "bad skip_check");
+                       goto fail;
+               }
        } else {
                if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
                        ubi_err(ubi, "bad used_ebs");
index 7504f430c011baed9c4239f9ee281e614ea2ca87..1bc82154bb18f6b3e03df72d725778d7dea12227 100644 (file)
@@ -560,6 +560,9 @@ static int init_volumes(struct ubi_device *ubi,
                vol->name[vol->name_len] = '\0';
                vol->vol_id = i;
 
+               if (vtbl[i].flags & UBI_VTBL_SKIP_CRC_CHECK_FLG)
+                       vol->skip_check = 1;
+
                if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
                        /* Auto re-size flag may be set only for one volume */
                        if (ubi->autoresize_vol_id != -1) {