block: support builtin fstab config
[project/fstools.git] / libfstools / ubi.c
index dbd9a1e..0f6e37a 100644 (file)
 
 /* could use libubi-tiny instead, but already had the code directly reading
  * from sysfs */
-const char const *ubi_dir_name = "/sys/devices/virtual/ubi";
+const char *const ubi_dir_name = "/sys/devices/virtual/ubi";
 
 struct ubi_priv {
        int             ubi_num;
-       int             ubi_volidx;
+       int             ubi_volid;
 };
 
 static struct driver ubi_driver;
@@ -105,10 +105,10 @@ static int ubi_volume_init(struct volume *v)
        p = (struct ubi_priv*)v->priv;
 
        snprintf(voldir, sizeof(voldir), "%s/ubi%u/ubi%u_%u",
-               ubi_dir_name, p->ubi_num, p->ubi_num, p->ubi_volidx);
+               ubi_dir_name, p->ubi_num, p->ubi_num, p->ubi_volid);
 
        snprintf(voldev, sizeof(voldev), "/dev/ubi%u_%u",
-               p->ubi_num, p->ubi_volidx);
+               p->ubi_num, p->ubi_volid);
 
        volname = read_string_from_file(voldir, "name");
        if (!volname)
@@ -125,16 +125,16 @@ static int ubi_volume_init(struct volume *v)
        return 0;
 }
 
-static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volidx)
+static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volid)
 {
        char voldir[BUFLEN], volblkdev[BUFLEN], *volname;
        struct ubi_priv *p;
 
        snprintf(voldir, sizeof(voldir), "%s/ubi%u/ubi%u_%u",
-               ubi_dir_name, ubi_num, ubi_num, volidx);
+               ubi_dir_name, ubi_num, ubi_num, volid);
 
        snprintf(volblkdev, sizeof(volblkdev), "/dev/ubiblock%u_%u",
-               ubi_num, volidx);
+               ubi_num, volid);
 
        /* skip if ubiblock device exists */
        if (test_open(volblkdev))
@@ -143,6 +143,10 @@ static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volid
        /* todo: skip existing gluebi device for legacy support */
 
        volname = read_string_from_file(voldir, "name");
+       if (!volname) {
+               fprintf(stderr, "Couldn't read %s/name\n", voldir);
+               return -1;
+       }
 
        if (strncmp(name, volname, strlen(volname) + 1))
                return -1;
@@ -154,29 +158,41 @@ static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volid
        v->priv = p;
        v->drv = &ubi_driver;
        p->ubi_num = ubi_num;
-       p->ubi_volidx = volidx;
+       p->ubi_volid = volid;
 
        return ubi_volume_init(v);
 }
 
 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)