diff options
| author | Tom Rini <[email protected]> | 2026-07-09 08:02:23 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-07-09 08:02:23 -0600 |
| commit | 964a26cc6d1002343ceba393d86ee4a0cd447385 (patch) | |
| tree | 5306b4b0d6857feba92558f6756e2882dd24bb67 | |
| parent | c991faf4f7a010cae56a9065b69fc23b6ca9ddf4 (diff) | |
| parent | 93ae75361f12fb621c425dd2509f321b6b26c4b6 (diff) | |
Merge tag 'ubi-updates-for-2026.10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-ubi
ubi updates for 2026.10-rc1
- fs: ubifs: fix ubifs_finddir() from Patrick
Fixes: 0cab29ff467e ("fs: ubifs: Fix and rework error handling in ubifs_finddir")
fix test -e
- cmd: ubi: rework from Weijie
- env: ubi: add support to create environment volume if it does not exist
- cmd: ubi: allow creating volume with all free spaces in ubi_create_vol
- cmd: ubi: export more APIs to public
- cmd: ubi: reorganize command messages
- cmd: ubi: change all positive error return value to negative
- cmd: ubi: change the type of parameter dynamic to bool
- cmd: ubifs: mark string parameters with const
- cmd: ubi: use void * for buf parameter in ubi_volume_read
- cmd: ubi: mark read-only function parameters with const
- ubi: remove unnecessary extern directive from function prototypes
| -rw-r--r-- | cmd/ubi.c | 272 | ||||
| -rw-r--r-- | cmd/ubifs.c | 2 | ||||
| -rw-r--r-- | env/Kconfig | 20 | ||||
| -rw-r--r-- | env/ubi.c | 65 | ||||
| -rw-r--r-- | fs/ubifs/super.c | 2 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.c | 4 | ||||
| -rw-r--r-- | include/ubi_uboot.h | 106 | ||||
| -rw-r--r-- | include/ubifs_uboot.h | 4 |
8 files changed, 352 insertions, 123 deletions
diff --git a/cmd/ubi.c b/cmd/ubi.c index 93de6f3aea2..2b206141a21 100644 --- a/cmd/ubi.c +++ b/cmd/ubi.c @@ -39,7 +39,7 @@ static struct ubi_device *ubi; #include <ubifs_uboot.h> #endif -static void display_volume_info(struct ubi_device *ubi) +static void display_volume_info(const struct ubi_device *ubi) { int i; @@ -50,7 +50,7 @@ static void display_volume_info(struct ubi_device *ubi) } } -static void display_ubi_info(struct ubi_device *ubi) +static void display_ubi_info(const struct ubi_device *ubi) { ubi_msg("MTD device name: \"%s\"", ubi->mtd->name); ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); @@ -149,12 +149,12 @@ static int ubi_list(const char *var, int numeric) return 0; } -static int ubi_check_volumename(const struct ubi_volume *vol, char *name) +static int ubi_check_volumename(const struct ubi_volume *vol, const char *name) { return strcmp(vol->name, name); } -static int ubi_check(char *name) +static int ubi_check(const char *name) { int i; @@ -172,7 +172,7 @@ static int ubi_check(char *name) static int verify_mkvol_req(const struct ubi_device *ubi, const struct ubi_mkvol_req *req) { - int n, err = EINVAL; + int n, err = -EINVAL; if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 || req->name_len < 0) @@ -187,7 +187,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi, if (req->bytes == 0) { printf("No space left in UBI device!\n"); - err = ENOMEM; + err = -ENOMEM; goto bad; } @@ -204,7 +204,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi, if (req->name_len > UBI_VOL_NAME_MAX) { printf("Name too long!\n"); - err = ENAMETOOLONG; + err = -ENAMETOOLONG; goto bad; } @@ -213,8 +213,8 @@ bad: return err; } -static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id, - bool skipcheck) +int ubi_create_vol(const char *volume, int64_t size, bool dynamic, int vol_id, + bool skipcheck) { struct ubi_mkvol_req req; int err; @@ -226,7 +226,11 @@ static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id, req.vol_id = vol_id; req.alignment = 1; - req.bytes = size; + + if (size < 0) + req.bytes = ubi->avail_pebs * ubi->leb_size; + else + req.bytes = size; strcpy(req.name, volume); req.name_len = strlen(volume); @@ -241,13 +245,12 @@ static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id, printf("verify_mkvol_req failed %d\n", err); return err; } - printf("Creating %s volume %s of size %lld\n", - dynamic ? "dynamic" : "static", volume, size); + /* Call real ubi create volume */ return ubi_create_volume(ubi, &req); } -static struct ubi_volume *ubi_find_volume(char *volume) +struct ubi_volume *ubi_find_volume(const char *volume) { struct ubi_volume *vol; int i; @@ -258,24 +261,26 @@ static struct ubi_volume *ubi_find_volume(char *volume) return vol; } - printf("Volume %s not found!\n", volume); return NULL; } -static int ubi_remove_vol(char *volume) +static struct ubi_volume *ubi_require_volume(const char *volume) { - int err, reserved_pebs, i; - struct ubi_volume *vol; + struct ubi_volume *vol = ubi_find_volume(volume); - vol = ubi_find_volume(volume); - if (vol == NULL) - return ENODEV; + if (!vol) + printf("Volume %s not found!\n", volume); + + return vol; +} - printf("Remove UBI volume %s (id %d)\n", vol->name, vol->vol_id); +static int __ubi_remove_vol(struct ubi_volume *vol) +{ + int err, reserved_pebs, i; if (ubi->ro_mode) { printf("It's read-only mode\n"); - err = EROFS; + err = -EROFS; goto out_err; } @@ -310,35 +315,40 @@ static int ubi_remove_vol(char *volume) return 0; out_err: - ubi_err(ubi, "cannot remove volume %s, error %d", volume, err); - if (err < 0) - err = -err; + ubi_err(ubi, "cannot remove volume %s, error %d", vol->name, err); return err; } -static int ubi_rename_vol(char *oldname, char *newname) +int ubi_remove_vol(const char *volume) +{ + struct ubi_volume *vol; + + vol = ubi_require_volume(volume); + if (!vol) + return -ENODEV; + + return __ubi_remove_vol(vol); +} + +static int ubi_rename_vol(const char *oldname, const char *newname) { struct ubi_volume *vol; struct ubi_rename_entry rename; struct ubi_volume_desc desc; struct list_head list; - vol = ubi_find_volume(oldname); - if (!vol) { - printf("%s: volume %s doesn't exist\n", __func__, oldname); - return ENODEV; - } + vol = ubi_require_volume(oldname); + if (!vol) + return -ENODEV; if (!ubi_check(newname)) { printf("%s: volume %s already exist\n", __func__, newname); - return EINVAL; + return -EINVAL; } - printf("Rename UBI volume %s to %s\n", oldname, newname); - if (ubi->ro_mode) { printf("%s: ubi device is in read-only mode\n", __func__); - return EROFS; + return -EROFS; } rename.new_name_len = strlen(newname); @@ -354,24 +364,25 @@ static int ubi_rename_vol(char *oldname, char *newname) return ubi_rename_volumes(ubi, &list); } -static int ubi_volume_continue_write(char *volume, void *buf, size_t size) +static int ubi_volume_continue_write(const char *volume, const void *buf, + size_t size) { int err; struct ubi_volume *vol; - vol = ubi_find_volume(volume); + vol = ubi_require_volume(volume); if (vol == NULL) - return ENODEV; + return -ENODEV; if (!vol->updating) { printf("UBI volume update was not initiated\n"); - return EINVAL; + return -EINVAL; } err = ubi_more_update_data(ubi, vol, buf, size); if (err < 0) { printf("Couldnt or partially wrote data\n"); - return -err; + return err; } if (err) { @@ -379,7 +390,7 @@ static int ubi_volume_continue_write(char *volume, void *buf, size_t size) err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) - return -err; + return err; if (err) { ubi_warn(ubi, "volume %d on UBI device %d is corrupt", @@ -394,27 +405,27 @@ static int ubi_volume_continue_write(char *volume, void *buf, size_t size) return 0; } -int ubi_volume_begin_write(char *volume, void *buf, size_t size, - size_t full_size) +int ubi_volume_begin_write(const char *volume, const void *buf, size_t size, + size_t full_size) { int err; int rsvd_bytes; struct ubi_volume *vol; - vol = ubi_find_volume(volume); + vol = ubi_require_volume(volume); if (vol == NULL) - return ENODEV; + return -ENODEV; rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad); if (size > rsvd_bytes) { printf("size > volume size! Aborting!\n"); - return EINVAL; + return -EINVAL; } err = ubi_start_update(ubi, vol, full_size); if (err < 0) { printf("Cannot start volume update\n"); - return -err; + return err; } /* The volume is just wiped out */ @@ -424,8 +435,8 @@ int ubi_volume_begin_write(char *volume, void *buf, size_t size, return ubi_volume_continue_write(volume, buf, size); } -static int ubi_volume_offset_write(char *volume, void *buf, loff_t offset, - size_t size) +static int ubi_volume_offset_write(const char *volume, const void *buf, + loff_t offset, size_t size) { int len, tbuf_size, ret; u64 lnum; @@ -433,7 +444,7 @@ static int ubi_volume_offset_write(char *volume, void *buf, loff_t offset, loff_t off = offset; void *tbuf; - vol = ubi_find_volume(volume); + vol = ubi_require_volume(volume); if (!vol) return -ENODEV; @@ -487,7 +498,8 @@ exit: return ret; } -int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size) +int ubi_volume_write(const char *volume, const void *buf, loff_t offset, + size_t size) { int ret; @@ -503,36 +515,28 @@ int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size) return ret; } -int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size) +static int __ubi_volume_read(struct ubi_volume *vol, void *buf, loff_t offset, + size_t size) { int err, lnum, off, len, tbuf_size; void *tbuf; unsigned long long tmp; - struct ubi_volume *vol; loff_t offp = offset; size_t len_read; - vol = ubi_find_volume(volume); - if (vol == NULL) - return ENODEV; - if (vol->updating) { printf("updating"); - return EBUSY; + return -EBUSY; } if (vol->upd_marker) { printf("damaged volume, update marker is set"); - return EBADF; + return -EBADF; } if (offp == vol->used_bytes) return 0; - if (size == 0) { - printf("No size specified -> Using max size (%lld)\n", vol->used_bytes); + if (size == 0) size = vol->used_bytes; - } - - printf("Read %zu bytes from volume %s to %p\n", size, volume, buf); if (vol->corrupted) printf("read from corrupted volume %d", vol->vol_id); @@ -545,7 +549,7 @@ int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size) tbuf = malloc_cache_aligned(tbuf_size); if (!tbuf) { printf("NO MEM\n"); - return ENOMEM; + return -ENOMEM; } len = size > tbuf_size ? tbuf_size : size; @@ -561,7 +565,6 @@ int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size) err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0); if (err) { printf("read err %x\n", err); - err = -err; break; } off += len; @@ -587,7 +590,19 @@ int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size) return err; } -static int ubi_dev_scan(struct mtd_info *info, const char *vid_header_offset) +int ubi_volume_read(const char *volume, void *buf, loff_t offset, size_t size) +{ + struct ubi_volume *vol; + + vol = ubi_require_volume(volume); + if (!vol) + return -ENODEV; + + return __ubi_volume_read(vol, buf, offset, size); +} + +static int ubi_dev_scan(const struct mtd_info *info, + const char *vid_header_offset) { char ubi_mtd_param_buffer[80]; int err; @@ -600,28 +615,25 @@ static int ubi_dev_scan(struct mtd_info *info, const char *vid_header_offset) err = ubi_mtd_param_parse(ubi_mtd_param_buffer, NULL); if (err) - return -err; + return err; led_activity_blink(); err = ubi_init(); led_activity_off(); if (err) - return -err; + return err; return 0; } -static int ubi_set_skip_check(char *volume, bool skip_check) +static int ubi_set_skip_check(const char *volume, bool skip_check) { struct ubi_vtbl_record vtbl_rec; struct ubi_volume *vol; - vol = ubi_find_volume(volume); + vol = ubi_require_volume(volume); if (!vol) - return ENODEV; - - printf("%sing skip_check on volume %s\n", - skip_check ? "Sett" : "Clear", volume); + return -ENODEV; vtbl_rec = ubi->vtbl[vol->vol_id]; if (skip_check) { @@ -635,7 +647,7 @@ static int ubi_set_skip_check(char *volume, bool skip_check) return ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec); } -static int ubi_detach(void) +int ubi_detach(void) { #ifdef CONFIG_CMD_UBIFS /* @@ -658,7 +670,7 @@ static int ubi_detach(void) return 0; } -int ubi_part(char *part_name, const char *vid_header_offset) +int ubi_part(const char *part_name, const char *vid_header_offset) { struct mtd_info *mtd; int err; @@ -674,7 +686,7 @@ int ubi_part(char *part_name, const char *vid_header_offset) mtd = get_mtd_device_nm(part_name); if (IS_ERR(mtd)) { printf("Partition %s not found!\n", part_name); - return 1; + return -ENODEV; } put_mtd_device(mtd); @@ -695,6 +707,8 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int64_t size; ulong addr = 0; bool skipcheck = false; + struct ubi_volume *vol; + int ret; if (argc < 2) return CMD_RET_USAGE; @@ -709,7 +723,7 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc == 2) { if (!ubi) { printf("Error, no UBI device selected!\n"); - return 1; + return CMD_RET_FAILURE; } printf("Device %d: %s, MTD partition %s\n", @@ -723,12 +737,13 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc > 3) vid_header_offset = argv[3]; - return ubi_part(argv[2], vid_header_offset); + ret = ubi_part(argv[2], vid_header_offset); + return ret ? CMD_RET_FAILURE : 0; } if ((strcmp(argv[1], "part") != 0) && !ubi) { printf("Error, no UBI device selected!\n"); - return 1; + return CMD_RET_FAILURE; } if (strcmp(argv[1], "info") == 0) { @@ -758,11 +773,11 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return ubi_check(argv[2]); printf("Error, no volume name passed\n"); - return 1; + return CMD_RET_USAGE; } if (strncmp(argv[1], "create", 6) == 0) { - int dynamic = 1; /* default: dynamic volume */ + bool dynamic = true; /* default: dynamic volume */ int id = UBI_VOL_NUM_AUTO; /* Use maximum available size */ @@ -783,10 +798,10 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* E.g., create volume size type */ if (argc == 5) { if (strncmp(argv[4], "s", 1) == 0) - dynamic = 0; + dynamic = false; else if (strncmp(argv[4], "d", 1) != 0) { printf("Incorrect type\n"); - return 1; + return CMD_RET_USAGE; } argc--; } @@ -799,38 +814,80 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* Use maximum available size */ if (!size) { size = (int64_t)ubi->avail_pebs * ubi->leb_size; - printf("No size specified -> Using max size (%lld)\n", size); + if (size) + printf("No size specified -> Using max size (%lld)\n", + size); } /* E.g., create volume */ if (argc == 3) { - return ubi_create_vol(argv[2], size, dynamic, id, - skipcheck); + ret = ubi_create_vol(argv[2], size, dynamic, id, + skipcheck); + if (ret) + return CMD_RET_FAILURE; + + printf("Created %s volume %s of size %lld\n", + dynamic ? "dynamic" : "static", argv[2], size); + + return 0; } } if (strncmp(argv[1], "remove", 6) == 0) { /* E.g., remove volume */ - if (argc == 3) - return ubi_remove_vol(argv[2]); + if (argc == 3) { + int vol_id; + + vol = ubi_require_volume(argv[2]); + if (!vol) + return CMD_RET_FAILURE; + + vol_id = vol->vol_id; + + ret = __ubi_remove_vol(vol); + if (ret) + return CMD_RET_FAILURE; + + printf("Removed UBI volume %s (id %d)\n", argv[2], + vol_id); + + return 0; + } } - if (IS_ENABLED(CONFIG_CMD_UBI_RENAME) && !strncmp(argv[1], "rename", 6)) - return ubi_rename_vol(argv[2], argv[3]); + if (IS_ENABLED(CONFIG_CMD_UBI_RENAME) && !strncmp(argv[1], "rename", 6)) { + if (argc < 4) { + printf("Please see usage\n"); + return CMD_RET_USAGE; + } + + ret = ubi_rename_vol(argv[2], argv[3]); + if (ret) + return CMD_RET_FAILURE; + + printf("UBI volume %s renamed to %s\n", argv[2], argv[3]); + + return 0; + } if (strncmp(argv[1], "skipcheck", 9) == 0) { /* E.g., change skip_check flag */ if (argc == 4) { skipcheck = strncmp(argv[3], "on", 2) == 0; - return ubi_set_skip_check(argv[2], skipcheck); + ret = ubi_set_skip_check(argv[2], skipcheck); + if (ret) + return CMD_RET_FAILURE; + + printf("%s skip_check on volume %s\n", + skipcheck ? "Set" : "Cleared", argv[2]); + + return 0; } } if (strncmp(argv[1], "write", 5) == 0) { - int ret; - if (argc < 5) { printf("Please see usage\n"); - return 1; + return CMD_RET_USAGE; } addr = hextoul(argv[2], NULL); @@ -855,7 +912,7 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) argv[3]); } - return ret; + return ret ? CMD_RET_FAILURE : 0; } if (strncmp(argv[1], "read", 4) == 0) { @@ -874,12 +931,29 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } if (argc == 3) { - return ubi_volume_read(argv[3], (char *)addr, 0, size); + vol = ubi_require_volume(argv[3]); + if (!vol) + return CMD_RET_FAILURE; + + if (!size) { + printf("No size specified -> Using max size (%lld)\n", + vol->used_bytes); + size = vol->used_bytes; + } + + ret = __ubi_volume_read(vol, (void *)addr, 0, size); + if (ret) + return CMD_RET_FAILURE; + + printf("%lld bytes read from volume %s to 0x%lx\n", + size, argv[3], addr); + + return 0; } } printf("Please see usage\n"); - return 1; + return CMD_RET_USAGE; } U_BOOT_CMD( diff --git a/cmd/ubifs.c b/cmd/ubifs.c index 22e95db8ca5..81f2d37fc7b 100644 --- a/cmd/ubifs.c +++ b/cmd/ubifs.c @@ -19,7 +19,7 @@ static int ubifs_initialized; static int ubifs_mounted; -int cmd_ubifs_mount(char *vol_name) +int cmd_ubifs_mount(const char *vol_name) { int ret; diff --git a/env/Kconfig b/env/Kconfig index 3c9aaeb1f16..bbd657682d7 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -739,6 +739,26 @@ config ENV_UBI_VOLUME_REDUND help Name of the redundant volume that you want to store the environment in. +config ENV_UBI_VOLUME_CREATE + bool "Create UBI volume if it does not exist" + depends on ENV_IS_IN_UBI + help + This option is useful if U-Boot will be booted from a fresh device + where the environment volume has not been created. + This is a common case where factory UBI image contains only volumes + with valid data. + By enabling this option, any missing environment volumes will be + created before loading. + If ENV_UBI_VOLUME_REDUND is also enabled, both volumes will be + created. + +config ENV_UBI_VOLUME_STATIC + bool "Create static UBI volume" + depends on ENV_UBI_VOLUME_CREATE + help + By default environment volume will be dynamic. + Enable this option to create static volume. + config ENV_UBI_VID_OFFSET int "ubi environment VID offset" depends on ENV_IS_IN_UBI diff --git a/env/ubi.c b/env/ubi.c index e9865b45ebc..810faaf7744 100644 --- a/env/ubi.c +++ b/env/ubi.c @@ -103,12 +103,30 @@ static int env_ubi_save(void) } #endif /* CONFIG_ENV_REDUNDANT */ +static int env_ubi_volume_create(const char *volume) +{ + bool dynamic = !IS_ENABLED(CONFIG_ENV_UBI_VOLUME_STATIC); + struct ubi_volume *vol; + int ret; + + vol = ubi_find_volume(volume); + if (vol) + return 0; + + ret = ubi_create_vol(volume, CONFIG_ENV_SIZE, dynamic, UBI_VOL_NUM_AUTO, + false); + if (ret) + printf("Failed to create environment volume '%s'\n", volume); + + return ret; +} + #ifdef CONFIG_ENV_REDUNDANT static int env_ubi_load(void) { ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE); ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE); - int read1_fail, read2_fail; + int read1_fail, read2_fail, create1_fail = 0, create2_fail = 0; env_t *tmp_env1, *tmp_env2; /* @@ -132,17 +150,35 @@ static int env_ubi_load(void) return -EIO; } - read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, 0, - CONFIG_ENV_SIZE); - if (read1_fail) - printf("\n** Unable to read env from %s:%s **\n", - CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); + if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE)) { + create1_fail = env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME); + create2_fail = env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME_REDUND); + if (create1_fail && create2_fail) { + env_set_default(NULL, 0); + return -ENODEV; + } + } - read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, - (void *)tmp_env2, 0, CONFIG_ENV_SIZE); - if (read2_fail) - printf("\n** Unable to read redundant env from %s:%s **\n", - CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND); + if (!create1_fail) { + read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, tmp_env1, 0, + CONFIG_ENV_SIZE); + if (read1_fail) + printf("\n** Unable to read env from %s:%s **\n", + CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); + } else { + read1_fail = create1_fail; + } + + if (!create2_fail) { + read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, + tmp_env2, 0, CONFIG_ENV_SIZE); + if (read2_fail) + printf("\n** Unable to read redundant env from %s:%s **\n", + CONFIG_ENV_UBI_PART, + CONFIG_ENV_UBI_VOLUME_REDUND); + } else { + read2_fail = create2_fail; + } return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2, read2_fail, H_EXTERNAL); @@ -169,6 +205,13 @@ static int env_ubi_load(void) return -EIO; } + if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE)) { + if (env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME)) { + env_set_default(NULL, 0); + return -ENODEV; + } + } + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, 0, CONFIG_ENV_SIZE)) { printf("\n** Unable to read env from %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index b6004b88f4e..9c8974a97a5 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -2694,7 +2694,7 @@ MODULE_VERSION(__stringify(UBIFS_VERSION)); MODULE_AUTHOR("Artem Bityutskiy, Adrian Hunter"); MODULE_DESCRIPTION("UBIFS - UBI File System"); #else -int uboot_ubifs_mount(char *vol_name) +int uboot_ubifs_mount(const char *vol_name) { struct dentry *ret; int flags; diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 3f2e2037745..6121fb0b135 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -544,7 +544,7 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename) *(next++) = '\0'; } ret = ubifs_finddir(sb, name, root_inum, &inum); - if (!ret) { + if (ret <= 0) { kfree(buf); return 0; } @@ -991,7 +991,7 @@ void ubifs_close(void) } /* Compat wrappers for common/cmd_ubifs.c */ -int ubifs_load(char *filename, unsigned long addr, u32 size) +int ubifs_load(const char *filename, unsigned long addr, u32 size) { loff_t actread; int err; diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index ea0db69c72a..bdf5645de3d 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -44,15 +44,107 @@ #endif /* functions */ -extern int ubi_mtd_param_parse(const char *val, struct kernel_param *kp); -extern int ubi_init(void); -extern void ubi_exit(void); -extern int ubi_part(char *part_name, const char *vid_header_offset); -extern int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size); -extern int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size); +int ubi_mtd_param_parse(const char *val, struct kernel_param *kp); +int ubi_init(void); +void ubi_exit(void); + +/** + * ubi_detach() - detach UBI from MTD partition + * + * This function performs the cleanup of the UBI subsystem to make sure the + * MTD partition can be safely used for another purpose, or be attached again + * with ubi_part(). + * + * Any mounted UBIFS will be unmounted automatically. + * + * Return: 0 + */ +int ubi_detach(void); + +/** + * ubi_part() - attach UBI to MTD partition + * @part_name: name of the MTD partition to attach + * @vid_header_offset: VID header offset (string) + * + * This function detaches any existing UBI device, then probes for the + * specified MTD partition, and then scans it to initialize UBI. + * + * @vid_header_offset is optional and is usually set to NULL. + * + * Return: 0 on success, or -ve on error. + */ +int ubi_part(const char *part_name, const char *vid_header_offset); + +/** + * ubi_volume_write() - write data to UBI volume + * @volume: name of the volume to write to + * @buf: data buffer to be written + * @offset: start offset for writing + * @size: number of bytes to write + * + * This function writes data to the specific UBI volume. If the offset is zero, + * it initiates a full volume update. Otherwise, it performs an offset-based + * write using LEB changes. + * + * Return: 0 on success, or -ve on error. + */ +int ubi_volume_write(const char *volume, const void *buf, loff_t offset, + size_t size); + +/** + * ubi_volume_read() - read data from UBI volume + * @volume: name of the volume to read from + * @buf: buffer to hold the read data + * @offset: start offset for reading + * @size: number of bytes to read + * + * This function reads data from the specified UBI volume. If @size is zero, + * the function reads the entire volume content starting from @offset. + * + * Return: 0 on success, or -ve on error. + */ +int ubi_volume_read(const char *volume, void *buf, loff_t offset, size_t size); + +/** + * ubi_create_vol() - create UBI volume + * @volume: name of the volume to create + * @size: size of the volume in bytes + * @dynamic: create dynamic volume if set to true + * @vol_id: volume ID + * @skipcheck: skip CRC check on this volume if set to true + * + * This function creates a new UBI volume with the specified parameters. + * If @size is negative, all available space will be used. + * For volume ID auto assignment, pass %UBI_VOL_NUM_AUTO to @vol_id. + * + * Return: 0 on success, or -ve on error. + */ +int ubi_create_vol(const char *volume, int64_t size, bool dynamic, int vol_id, + bool skipcheck); + +/** + * ubi_find_volume() - find UBI volume by name + * @volume: name of the volume to find + * + * This function searches for a UBI volume with the specified name in the + * current UBI device. + * + * Return: pointer to the UBI volume structure, or %NULL if not found. + */ +struct ubi_volume *ubi_find_volume(const char *volume); + +/** + * ubi_remove_vol() - remove UBI volume + * @volume: name of the volume to remove + * + * This function removes an existing UBI volume from the current UBI device. + * + * Return: 0 on success, or -ve on error. + */ +int ubi_remove_vol(const char *volume); extern struct ubi_device *ubi_devices[]; -int cmd_ubifs_mount(char *vol_name); +int cmd_ubifs_mount(const char *vol_name); int cmd_ubifs_umount(void); #if IS_ENABLED(CONFIG_UBI_BLOCK) diff --git a/include/ubifs_uboot.h b/include/ubifs_uboot.h index db8a29e9bbd..0877dd84f99 100644 --- a/include/ubifs_uboot.h +++ b/include/ubifs_uboot.h @@ -18,10 +18,10 @@ struct blk_desc; struct disk_partition; int ubifs_init(void); -int uboot_ubifs_mount(char *vol_name); +int uboot_ubifs_mount(const char *vol_name); void uboot_ubifs_umount(void); int ubifs_is_mounted(void); -int ubifs_load(char *filename, unsigned long addr, u32 size); +int ubifs_load(const char *filename, unsigned long addr, u32 size); int ubifs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info); int ubifs_ls(const char *dir_name); |
