mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 07:04:28 +00:00
fw_setenv: avoid writing environment when nothing has changed
In the case where one deletes an already-non-existing variable, or sets a variable to the value it already has, there is no point in writing the environment back, thus reducing wear on the underlying storage device. In the case of redundant environments, if the two environments differ (e.g. because one is corrupt), make sure that any call of fw_setenv causes the two to become synchronized, even if the fw_setenv call does not change anything in the good copy. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
parent
1785d8c3a5
commit
c62e6142b9
1 changed files with 19 additions and 1 deletions
20
tools/env/fw_env.c
vendored
20
tools/env/fw_env.c
vendored
|
@ -112,6 +112,7 @@ struct environment {
|
|||
unsigned char *flags;
|
||||
char *data;
|
||||
enum flag_scheme flag_scheme;
|
||||
int dirty;
|
||||
};
|
||||
|
||||
static struct environment environment = {
|
||||
|
@ -506,6 +507,9 @@ int fw_env_flush(struct env_opts *opts)
|
|||
if (!opts)
|
||||
opts = &default_opts;
|
||||
|
||||
if (!environment.dirty)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Update CRC
|
||||
*/
|
||||
|
@ -551,7 +555,8 @@ int fw_env_write(char *name, char *value)
|
|||
|
||||
deleting = (oldval && !(value && strlen(value)));
|
||||
creating = (!oldval && (value && strlen(value)));
|
||||
overwriting = (oldval && (value && strlen(value)));
|
||||
overwriting = (oldval && (value && strlen(value) &&
|
||||
strcmp(oldval, value)));
|
||||
|
||||
/* check for permission */
|
||||
if (deleting) {
|
||||
|
@ -591,6 +596,7 @@ int fw_env_write(char *name, char *value)
|
|||
/* Nothing to do */
|
||||
return 0;
|
||||
|
||||
environment.dirty = 1;
|
||||
if (deleting || overwriting) {
|
||||
if (*++nxt == '\0') {
|
||||
*env = '\0';
|
||||
|
@ -1440,6 +1446,7 @@ int fw_env_open(struct env_opts *opts)
|
|||
"Warning: Bad CRC, using default environment\n");
|
||||
memcpy(environment.data, default_environment,
|
||||
sizeof(default_environment));
|
||||
environment.dirty = 1;
|
||||
}
|
||||
} else {
|
||||
flag0 = *environment.flags;
|
||||
|
@ -1493,6 +1500,16 @@ int fw_env_open(struct env_opts *opts)
|
|||
crc1_ok = (crc1 == redundant->crc);
|
||||
flag1 = redundant->flags;
|
||||
|
||||
/*
|
||||
* environment.data still points to ((struct
|
||||
* env_image_redundant *)addr0)->data. If the two
|
||||
* environments differ, or one has bad crc, force a
|
||||
* write-out by marking the environment dirty.
|
||||
*/
|
||||
if (memcmp(environment.data, redundant->data, ENV_SIZE) ||
|
||||
!crc0_ok || !crc1_ok)
|
||||
environment.dirty = 1;
|
||||
|
||||
if (crc0_ok && !crc1_ok) {
|
||||
dev_current = 0;
|
||||
} else if (!crc0_ok && crc1_ok) {
|
||||
|
@ -1502,6 +1519,7 @@ int fw_env_open(struct env_opts *opts)
|
|||
"Warning: Bad CRC, using default environment\n");
|
||||
memcpy(environment.data, default_environment,
|
||||
sizeof(default_environment));
|
||||
environment.dirty = 1;
|
||||
dev_current = 0;
|
||||
} else {
|
||||
switch (environment.flag_scheme) {
|
||||
|
|
Loading…
Reference in a new issue