Commit 386f20cade50ed36674e3e5827cb282eb1da95c2

Authored by Quentin Schulz
Committed by Heiko Schocher
1 parent 6891152a45

ubi: provide a way to skip CRC checks

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.

Adapted to U-Boot by Stefan Roese.

Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Signed-off-by: Stefan Roese <sr@denx.de>
Reviewed-by: Heiko Schocher <hs@denx.de>
Cc: Quentin Schulz <quentin.schulz@bootlin.com>
Cc: Boris Brezillon <boris.brezillon@bootlin.com>

Showing 7 changed files with 61 additions and 9 deletions Side-by-side Diff

... ... @@ -146,7 +146,8 @@
146 146 return err;
147 147 }
148 148  
149   -static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id)
  149 +static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
  150 + bool skipcheck)
150 151 {
151 152 struct ubi_mkvol_req req;
152 153 int err;
... ... @@ -163,7 +164,10 @@
163 164 strcpy(req.name, volume);
164 165 req.name_len = strlen(volume);
165 166 req.name[req.name_len] = '\0';
166   - req.padding1 = 0;
  167 + req.flags = 0;
  168 + if (skipcheck)
  169 + req.flags |= UBI_VOL_SKIP_CRC_CHECK_FLG;
  170 +
167 171 /* It's duplicated at drivers/mtd/ubi/cdev.c */
168 172 err = verify_mkvol_req(ubi, &req);
169 173 if (err) {
... ... @@ -469,6 +473,7 @@
469 473 {
470 474 int64_t size = 0;
471 475 ulong addr = 0;
  476 + bool skipcheck = false;
472 477  
473 478 if (argc < 2)
474 479 return CMD_RET_USAGE;
... ... @@ -527,6 +532,12 @@
527 532 /* Use maximum available size */
528 533 size = 0;
529 534  
  535 + /* E.g., create volume with "skipcheck" bit set */
  536 + if (argc == 7) {
  537 + skipcheck = strncmp(argv[6], "--skipcheck", 11) == 0;
  538 + argc--;
  539 + }
  540 +
530 541 /* E.g., create volume size type vol_id */
531 542 if (argc == 6) {
532 543 id = simple_strtoull(argv[5], NULL, 16);
... ... @@ -555,8 +566,10 @@
555 566 printf("No size specified -> Using max size (%lld)\n", size);
556 567 }
557 568 /* E.g., create volume */
558   - if (argc == 3)
559   - return ubi_create_vol(argv[2], size, dynamic, id);
  569 + if (argc == 3) {
  570 + return ubi_create_vol(argv[2], size, dynamic, id,
  571 + skipcheck);
  572 + }
560 573 }
561 574  
562 575 if (strncmp(argv[1], "remove", 6) == 0) {
... ... @@ -623,7 +636,7 @@
623 636 }
624 637  
625 638 U_BOOT_CMD(
626   - ubi, 6, 1, do_ubi,
  639 + ubi, 7, 1, do_ubi,
627 640 "ubi commands",
628 641 "detach"
629 642 " - detach ubi from a mtd partition\n"
... ... @@ -634,7 +647,7 @@
634 647 " - Display volume and ubi layout information\n"
635 648 "ubi check volumename"
636 649 " - check if volumename exists\n"
637   - "ubi create[vol] volume [size] [type] [id]\n"
  650 + "ubi create[vol] volume [size] [type] [id] [--skipcheck]\n"
638 651 " - create volume name with size ('-' for maximum"
639 652 " available size)\n"
640 653 "ubi write[vol] address volume size"
drivers/mtd/ubi/kapi.c
... ... @@ -196,7 +196,7 @@
196 196 desc->mode = mode;
197 197  
198 198 mutex_lock(&ubi->ckvol_mutex);
199   - if (!vol->checked) {
  199 + if (!vol->checked && !vol->skip_check) {
200 200 /* This is the first open - check the volume */
201 201 err = ubi_check_volume(ubi, vol_id);
202 202 if (err < 0) {
drivers/mtd/ubi/ubi-media.h
... ... @@ -48,6 +48,11 @@
48 48 * Volume flags used in the volume table record.
49 49 *
50 50 * @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
  51 + * @UBI_VTBL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
  52 + * open time. Should only be set on volumes that
  53 + * are used by upper layers doing this kind of
  54 + * check. Main use-case for this flag is
  55 + * boot-time reduction
51 56 *
52 57 * %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
53 58 * table. UBI automatically re-sizes the volume which has this flag and makes
... ... @@ -79,6 +84,7 @@
79 84 */
80 85 enum {
81 86 UBI_VTBL_AUTORESIZE_FLG = 0x01,
  87 + UBI_VTBL_SKIP_CRC_CHECK_FLG = 0x02,
82 88 };
83 89  
84 90 /*
drivers/mtd/ubi/ubi.h
... ... @@ -293,6 +293,9 @@
293 293 * atomic LEB change
294 294 *
295 295 * @eba_tbl: EBA table of this volume (LEB->PEB mapping)
  296 + * @skip_check: %1 if CRC check of this static volume should be skipped.
  297 + * Directly reflects the presence of the
  298 + * %UBI_VTBL_SKIP_CRC_CHECK_FLG flag in the vtbl entry
296 299 * @checked: %1 if this static volume was checked
297 300 * @corrupted: %1 if the volume is corrupted (static volumes only)
298 301 * @upd_marker: %1 if the update marker is set for this volume
... ... @@ -341,6 +344,7 @@
341 344 void *upd_buf;
342 345  
343 346 int *eba_tbl;
  347 + unsigned int skip_check:1;
344 348 unsigned int checked:1;
345 349 unsigned int corrupted:1;
346 350 unsigned int upd_marker:1;
drivers/mtd/ubi/vmt.c
... ... @@ -162,6 +162,9 @@
162 162 if (!vol)
163 163 return -ENOMEM;
164 164  
  165 + if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG)
  166 + vol->skip_check = 1;
  167 +
165 168 spin_lock(&ubi->volumes_lock);
166 169 if (vol_id == UBI_VOL_NUM_AUTO) {
167 170 /* Find unused volume ID */
... ... @@ -295,6 +298,10 @@
295 298 vtbl_rec.vol_type = UBI_VID_DYNAMIC;
296 299 else
297 300 vtbl_rec.vol_type = UBI_VID_STATIC;
  301 +
  302 + if (vol->skip_check)
  303 + vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;
  304 +
298 305 memcpy(vtbl_rec.name, vol->name, vol->name_len);
299 306  
300 307 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
... ... @@ -736,6 +743,11 @@
736 743 }
737 744 if (vol->used_bytes != n) {
738 745 ubi_err(ubi, "bad used_bytes");
  746 + goto fail;
  747 + }
  748 +
  749 + if (vol->skip_check) {
  750 + ubi_err(ubi, "bad skip_check");
739 751 goto fail;
740 752 }
741 753 } else {
drivers/mtd/ubi/vtbl.c
... ... @@ -554,6 +554,9 @@
554 554 vol->name[vol->name_len] = '\0';
555 555 vol->vol_id = i;
556 556  
  557 + if (vtbl[i].flags & UBI_VTBL_SKIP_CRC_CHECK_FLG)
  558 + vol->skip_check = 1;
  559 +
557 560 if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
558 561 /* Auto re-size flag may be set only for one volume */
559 562 if (ubi->autoresize_vol_id != -1) {
include/mtd/ubi-user.h
... ... @@ -271,6 +271,20 @@
271 271 __s8 padding[10];
272 272 };
273 273  
  274 +/*
  275 + * UBI volume flags.
  276 + *
  277 + * @UBI_VOL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
  278 + * open time. Only valid for static volumes and
  279 + * should only be used if the volume user has a
  280 + * way to verify data integrity
  281 + */
  282 +enum {
  283 + UBI_VOL_SKIP_CRC_CHECK_FLG = 0x1,
  284 +};
  285 +
  286 +#define UBI_VOL_VALID_FLGS (UBI_VOL_SKIP_CRC_CHECK_FLG)
  287 +
274 288 /**
275 289 * struct ubi_mkvol_req - volume description data structure used in
276 290 * volume creation requests.
... ... @@ -278,7 +292,7 @@
278 292 * @alignment: volume alignment
279 293 * @bytes: volume size in bytes
280 294 * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
281   - * @padding1: reserved for future, not used, has to be zeroed
  295 + * @flags: volume flags (%UBI_VOL_SKIP_CRC_CHECK_FLG)
282 296 * @name_len: volume name length
283 297 * @padding2: reserved for future, not used, has to be zeroed
284 298 * @name: volume name
... ... @@ -307,7 +321,7 @@
307 321 __s32 alignment;
308 322 __s64 bytes;
309 323 __s8 vol_type;
310   - __s8 padding1;
  324 + __u8 flags;
311 325 __s16 name_len;
312 326 __s8 padding2[4];
313 327 char name[UBI_MAX_VOLUME_NAME + 1];