This patch moves normal subcommand messages into the main command function.
This will allow current and potential api functions being called with clean
output on success.

A new function ubi_require_volume() is added for finding and printing error
message if volume not found. The original ubi_find_volume() will be silent
for being an api function.

To avoid ubi_require_volume() being called twice for volume read/remove,
some changes are required:
- The parameter of ubi_remove_vol() is changed to accept
'struct ubi_volume *' directly.
- The original ubi_volume_read() is renamed to __ubi_volume_read, with its
  first parameter changed to accept also 'struct ubi_volume *' directly.
- A new ubi_volume_read() is added to wraps __ubi_volume_read() to accept
  volume name as its first parameter.

Signed-off-by: Weijie Gao <[email protected]>
---
v4: Make error message always be printed in both command and api calls.
    Avoid duplicated call to ubi_require_volume().
    Add parameter check for "ubi rename" subcommand.
v3: Fix use-after-free and "ubi read" command message displaying error
v2: new
---
 cmd/ubi.c | 118 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 80 insertions(+), 38 deletions(-)

diff --git a/cmd/ubi.c b/cmd/ubi.c
index 23b846f22ce..b0b513cfe53 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -241,8 +241,7 @@ static int ubi_create_vol(const char *volume, int64_t size, 
bool dynamic,
                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);
 }
@@ -258,20 +257,22 @@ static struct ubi_volume *ubi_find_volume(const char 
*volume)
                        return vol;
        }
 
-       printf("Volume %s not found!\n", volume);
        return NULL;
 }
 
-static int ubi_remove_vol(const 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");
@@ -310,7 +311,7 @@ static int ubi_remove_vol(const char *volume)
 
        return 0;
 out_err:
-       ubi_err(ubi, "cannot remove volume %s, error %d", volume, err);
+       ubi_err(ubi, "cannot remove volume %s, error %d", vol->name, err);
        return err;
 }
 
@@ -321,19 +322,15 @@ static int ubi_rename_vol(const char *oldname, const char 
*newname)
        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);
+       vol = ubi_require_volume(oldname);
+       if (!vol)
                return -ENODEV;
-       }
 
        if (!ubi_check(newname)) {
                printf("%s: volume %s already exist\n", __func__, newname);
                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;
@@ -358,7 +355,7 @@ static int ubi_volume_continue_write(const char *volume, 
const void *buf,
        int err;
        struct ubi_volume *vol;
 
-       vol = ubi_find_volume(volume);
+       vol = ubi_require_volume(volume);
        if (vol == NULL)
                return -ENODEV;
 
@@ -400,7 +397,7 @@ int ubi_volume_begin_write(const char *volume, const void 
*buf, size_t size,
        int rsvd_bytes;
        struct ubi_volume *vol;
 
-       vol = ubi_find_volume(volume);
+       vol = ubi_require_volume(volume);
        if (vol == NULL)
                return -ENODEV;
 
@@ -432,7 +429,7 @@ static int ubi_volume_offset_write(const char *volume, 
const void *buf,
        loff_t off = offset;
        void *tbuf;
 
-       vol = ubi_find_volume(volume);
+       vol = ubi_require_volume(volume);
        if (!vol)
                return -ENODEV;
 
@@ -503,19 +500,15 @@ int ubi_volume_write(const char *volume, const void *buf, 
loff_t offset,
        return ret;
 }
 
-int ubi_volume_read(const char *volume, void *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;
@@ -527,12 +520,8 @@ int ubi_volume_read(const char *volume, void *buf, loff_t 
offset, size_t size)
        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);
@@ -586,6 +575,17 @@ int ubi_volume_read(const char *volume, void *buf, loff_t 
offset, size_t size)
        return err;
 }
 
+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)
 {
@@ -616,13 +616,10 @@ 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);
-
        vtbl_rec = ubi->vtbl[vol->vol_id];
        if (skip_check) {
                vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;
@@ -695,6 +692,7 @@ 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)
@@ -803,7 +801,9 @@ 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) {
@@ -811,6 +811,10 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
                                             skipcheck);
                        if (ret)
                                return CMD_RET_FAILURE;
+
+                       printf("Created %s volume %s of size %lld\n",
+                              dynamic ? "dynamic" : "static", argv[2], size);
+
                        return 0;
                }
        }
@@ -818,17 +822,37 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
        if (strncmp(argv[1], "remove", 6) == 0) {
                /* E.g., remove volume */
                if (argc == 3) {
-                       ret = ubi_remove_vol(argv[2]);
+                       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)) {
+               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;
        }
 
@@ -839,6 +863,10 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
                        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;
                }
        }
@@ -892,9 +920,23 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int 
argc, char *const argv[])
                }
 
                if (argc == 3) {
-                       ret = ubi_volume_read(argv[3], (void *)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;
                }
        }
-- 
2.45.2

Reply via email to