env: increment redund flag on read fail
authorBrandon Maier <brandon.maier@rockwellcollins.com>
Thu, 17 Dec 2020 23:19:18 +0000 (17:19 -0600)
committerTom Rini <trini@konsulko.com>
Fri, 16 Apr 2021 15:55:55 +0000 (11:55 -0400)
If one of the reads fails when importing redundant environments (a
single read failure), the env_flags wouldn't get initialized in
env_import_redund(). If a user then calls saveenv, the new environment
will have the wrong flags value. So on the next load the new environment
will be ignored.

While debugging this, I also noticed that env/sf.c was not correctly
handling a single read failure, as it would not check the crc before
assigning it to gd->env_addr.

Having a special error path for when there is a single read failure
seems unnecessary and may lead to future bugs. Instead collapse the
'single read failure' error to be the same as a 'single crc failure'.
That way env_check_redund() either passes or fails, and if it passes we
are guaranteed to have checked the CRC.

Signed-off-by: Brandon Maier <brandon.maier@rockwellcollins.com>
CC: Joe Hershberger <joe.hershberger@ni.com>
CC: Wolfgang Denk <wd@denx.de>
CC: Heiko Schocher <hs@denx.de>
Reviewed-by: Tom Rini <trini@konsulko.com>
env/common.c
env/sf.c
include/env.h

index 2ee423b..49bbb05 100644 (file)
@@ -145,7 +145,7 @@ static unsigned char env_flags;
 int env_check_redund(const char *buf1, int buf1_read_fail,
                     const char *buf2, int buf2_read_fail)
 {
-       int crc1_ok, crc2_ok;
+       int crc1_ok = 0, crc2_ok = 0;
        env_t *tmp_env1, *tmp_env2;
 
        tmp_env1 = (env_t *)buf1;
@@ -153,25 +153,18 @@ int env_check_redund(const char *buf1, int buf1_read_fail,
 
        if (buf1_read_fail && buf2_read_fail) {
                puts("*** Error - No Valid Environment Area found\n");
+               return -EIO;
        } else if (buf1_read_fail || buf2_read_fail) {
                puts("*** Warning - some problems detected ");
                puts("reading environment; recovered successfully\n");
        }
 
-       if (buf1_read_fail && buf2_read_fail) {
-               return -EIO;
-       } else if (!buf1_read_fail && buf2_read_fail) {
-               gd->env_valid = ENV_VALID;
-               return -EINVAL;
-       } else if (buf1_read_fail && !buf2_read_fail) {
-               gd->env_valid = ENV_REDUND;
-               return -ENOENT;
-       }
-
-       crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) ==
-                       tmp_env1->crc;
-       crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) ==
-                       tmp_env2->crc;
+       if (!buf1_read_fail)
+               crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) ==
+                               tmp_env1->crc;
+       if (!buf2_read_fail)
+               crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) ==
+                               tmp_env2->crc;
 
        if (!crc1_ok && !crc2_ok) {
                return -ENOMSG; /* needed for env_load() */
@@ -208,10 +201,6 @@ int env_import_redund(const char *buf1, int buf1_read_fail,
        if (ret == -EIO) {
                env_set_default("bad env area", 0);
                return -EIO;
-       } else if (ret == -EINVAL) {
-               return env_import((char *)buf1, 1, flags);
-       } else if (ret == -ENOENT) {
-               return env_import((char *)buf2, 1, flags);
        } else if (ret == -ENOMSG) {
                env_set_default("bad CRC", 0);
                return -ENOMSG;
index 06cc62e..e13d414 100644 (file)
--- a/env/sf.c
+++ b/env/sf.c
@@ -359,7 +359,7 @@ static int env_sf_init_early(void)
                ret = env_check_redund((char *)tmp_env1, read1_fail,
                                       (char *)tmp_env2, read2_fail);
 
-               if (ret == -EIO || ret == -ENOMSG)
+               if (ret < 0)
                        goto err_read;
 
                if (gd->env_valid == ENV_VALID)
index c15339a..b5731e4 100644 (file)
@@ -328,8 +328,6 @@ int env_export(struct environment_s *env_out);
  * @buf2_read_fail: 0 if buf2 is valid, non-zero if invalid
  * @return 0 if OK,
  *     -EIO if no environment is valid,
- *     -EINVAL if read of second entry is good
- *     -ENOENT if read of first entry is good
  *     -ENOMSG if the CRC was bad
  */