libfstools: ubi: rework reading volumes
authorRafał Miłecki <zajec5@gmail.com>
Tue, 23 Dec 2014 21:20:13 +0000 (22:20 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Tue, 6 Jan 2015 11:09:16 +0000 (12:09 +0100)
UBI volume IDs don't have to be contiguous, this may happen if there
were few and the not last one was removed. In such case we may have
e.g. ubi0_0, ubi0_2.
It means we can't simply read value from "volumes_count" and iterate
from 0 to the count - 1.

This patch rewrites ubi_part_match to read whole directory and look
for ubi%d_%d entries in it.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
libfstools/ubi.c

index ac9eb1b976851e1e4322edace5018cd44265d488..0f6e37a2e66b58b8cdf18f8bf91bf1d53a118f31 100644 (file)
@@ -165,22 +165,34 @@ static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volid
 
 static int ubi_part_match(struct volume *v, char *name, unsigned int ubi_num)
 {
-       unsigned int i, volumes_count;
+       DIR *ubi_dir;
+       struct dirent *ubi_dirent;
+       unsigned int volid;
        char devdir[BUFLEN];
+       int ret = -1;
 
        snprintf(devdir, sizeof(devdir), "%s/ubi%u",
                ubi_dir_name, ubi_num);
 
-       if (read_uint_from_file(devdir, "volumes_count", &volumes_count))
-               return -1;
+       ubi_dir = opendir(devdir);
+       if (!ubi_dir)
+               return ret;
 
-       for (i=0;i<volumes_count;i++) {
-               if (!ubi_volume_match(v, name, ubi_num, i)) {
-                       return 0;
+       while ((ubi_dirent = readdir(ubi_dir)) != NULL) {
+               if (strncmp(ubi_dirent->d_name, "ubi", 3))
+                       continue;
+
+               if (sscanf(ubi_dirent->d_name, "ubi%*u_%u", &volid) != 1)
+                       continue;
+
+               if (!ubi_volume_match(v, name, ubi_num, volid)) {
+                       ret = 0;
+                       break;
                }
        }
+       closedir(ubi_dir);
 
-       return -1;
+       return ret;
 }
 
 static int ubi_volume_find(struct volume *v, char *name)