libfstools: use container_of for volume private data
authorFelix Fietkau <nbd@nbd.name>
Tue, 6 Sep 2016 14:14:35 +0000 (16:14 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 8 Sep 2016 11:05:57 +0000 (13:05 +0200)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
libfstools/libfstools.h
libfstools/mtd.c
libfstools/ubi.c
libfstools/volume.c
libfstools/volume.h

index 31d9f9e0364ebc2782dce118eea404dbe2ec06e9..ec760f4a33b72ae8f861d1d04cf39bdb435f6cb9 100644 (file)
@@ -17,6 +17,7 @@
 #include <libubox/list.h>
 #include <libubox/blob.h>
 #include <libubox/ulog.h>
+#include <libubox/utils.h>
 
 struct volume;
 
index 156d166b5a2cc92f124852180782e5c2826be881..a1811c315e8332e4f810865d6960a24ad9edcf19 100644 (file)
@@ -27,7 +27,8 @@
 
 #define PATH_MAX               256
 
-struct mtd_priv {
+struct mtd_volume {
+       struct volume v;
        int     fd;
        int     idx;
        char    *chr;
@@ -60,10 +61,8 @@ static int mtd_open(const char *mtd, int block)
        return open(mtd, flags);
 }
 
-static void mtd_volume_close(struct volume *v)
+static void mtd_volume_close(struct mtd_volume *p)
 {
-       struct mtd_priv *p = (struct mtd_priv*) v->priv;
-
        if (!p->fd)
                return;
 
@@ -71,9 +70,9 @@ static void mtd_volume_close(struct volume *v)
        p->fd = 0;
 }
 
-static int mtd_volume_load(struct volume *v)
+static int mtd_volume_load(struct mtd_volume *p)
 {
-       struct mtd_priv *p = (struct mtd_priv*) v->priv;
+       struct volume *v = &p->v;
        struct mtd_info_user mtdInfo;
        struct erase_info_user mtdLockInfo;
 
@@ -91,7 +90,7 @@ static int mtd_volume_load(struct volume *v)
        }
 
        if (ioctl(p->fd, MEMGETINFO, &mtdInfo)) {
-               mtd_volume_close(v);
+               mtd_volume_close(p);
                ULOG_ERR("Could not get MTD device info from %s\n", p->chr);
                return -1;
        }
@@ -148,20 +147,21 @@ static char* mtd_find_index(char *name)
        return index;
 }
 
-static int mtd_volume_find(struct volume *v, char *name)
+static struct volume *mtd_volume_find(char *name)
 {
        char *idx = mtd_find_index(name);
-       struct mtd_priv *p;
+       struct mtd_volume *p;
+       struct volume *v;
        char buffer[32];
 
        if (!idx)
-               return -1;
+               return NULL;
 
-       p = calloc(1, sizeof(struct mtd_priv));
+       p = calloc(1, sizeof(struct mtd_volume));
        if (!p)
-               return -1;
+               return NULL;
 
-       v->priv = p;
+       v = &p->v;
        v->name = strdup(name);
        v->drv = &mtd_driver;
        p->idx = atoi(idx);
@@ -172,22 +172,23 @@ static int mtd_volume_find(struct volume *v, char *name)
        snprintf(buffer, sizeof(buffer), "/dev/mtd%s", idx);
        p->chr = strdup(buffer);
 
-       if (mtd_volume_load(v)) {
+       if (mtd_volume_load(p)) {
                ULOG_ERR("reading %s failed\n", v->name);
-               return -1;
+               free(p);
+               return NULL;
        }
 
-       return 0;
+       return v;
 }
 
 static int mtd_volume_identify(struct volume *v)
 {
-       struct mtd_priv *p = (struct mtd_priv*) v->priv;
+       struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
        __u32 deadc0de;
        __u16 jffs2;
        size_t sz;
 
-       if (mtd_volume_load(v)) {
+       if (mtd_volume_load(p)) {
                ULOG_ERR("reading %s failed\n", v->name);
                return -1;
        }
@@ -221,11 +222,11 @@ static int mtd_volume_identify(struct volume *v)
 
 static int mtd_volume_erase(struct volume *v, int offset, int len)
 {
-       struct mtd_priv *p = (struct mtd_priv*) v->priv;
+       struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
        struct erase_info_user eiu;
        int first_block, num_blocks;
 
-       if (mtd_volume_load(v))
+       if (mtd_volume_load(p))
                return -1;
 
        if (offset % v->block_size || len % v->block_size) {
@@ -246,26 +247,28 @@ static int mtd_volume_erase(struct volume *v, int offset, int len)
                        ULOG_ERR("Failed to erase block at 0x%x\n", eiu.start);
        }
 
-       mtd_volume_close(v);
+       mtd_volume_close(p);
 
        return 0;
 }
 
 static int mtd_volume_erase_all(struct volume *v)
 {
+       struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
+
        mtd_volume_erase(v, 0, v->size);
-       mtd_volume_close(v);
+       mtd_volume_close(p);
 
        return 0;
 }
 
 static int mtd_volume_init(struct volume *v)
 {
-       struct mtd_priv *p = (struct mtd_priv*) v->priv;
+       struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
        struct mtd_info_user mtdinfo;
        int ret;
 
-       if (mtd_volume_load(v))
+       if (mtd_volume_load(p))
                return -1;
 
        ret = ioctl(p->fd, MEMGETINFO, &mtdinfo);
@@ -284,9 +287,9 @@ static int mtd_volume_init(struct volume *v)
 
 static int mtd_volume_read(struct volume *v, void *buf, int offset, int length)
 {
-       struct mtd_priv *p = (struct mtd_priv*) v->priv;
+       struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
 
-       if (mtd_volume_load(v))
+       if (mtd_volume_load(p))
                return -1;
 
        if (lseek(p->fd, offset, SEEK_SET) == (off_t) -1) {
@@ -304,9 +307,9 @@ static int mtd_volume_read(struct volume *v, void *buf, int offset, int length)
 
 static int mtd_volume_write(struct volume *v, void *buf, int offset, int length)
 {
-       struct mtd_priv *p = (struct mtd_priv*) v->priv;
+       struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
 
-       if (mtd_volume_load(v))
+       if (mtd_volume_load(p))
                return -1;
 
        if (lseek(p->fd, offset, SEEK_SET) == (off_t) -1) {
index c1dce46417fea39e96703429d0c40e0c35fb3d22..f9d6e0aaa718ef941862297cae84afaebf7440c8 100644 (file)
@@ -26,7 +26,8 @@
  * from sysfs */
 const char *const ubi_dir_name = "/sys/devices/virtual/ubi";
 
-struct ubi_priv {
+struct ubi_volume {
+       struct volume v;
        int             ubi_num;
        int             ubi_volid;
 };
@@ -98,12 +99,10 @@ test_open(char *filename)
 
 static int ubi_volume_init(struct volume *v)
 {
+       struct ubi_volume *p = container_of(v, struct ubi_volume, v);
        char voldir[BUFLEN], voldev[BUFLEN], *volname;
-       struct ubi_priv *p;
        unsigned int volsize;
 
-       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_volid);
 
@@ -125,10 +124,10 @@ static int ubi_volume_init(struct volume *v)
        return 0;
 }
 
-static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volid)
+static struct volume *ubi_volume_match(char *name, int ubi_num, int volid)
 {
        char voldir[BUFLEN], volblkdev[BUFLEN], *volname;
-       struct ubi_priv *p;
+       struct ubi_volume *p;
 
        snprintf(voldir, sizeof(voldir), "%s/ubi%u/ubi%u_%u",
                ubi_dir_name, ubi_num, ubi_num, volid);
@@ -138,38 +137,37 @@ static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volid
 
        /* skip if ubiblock device exists */
        if (test_open(volblkdev))
-               return -1;
+               return NULL;
 
        /* todo: skip existing gluebi device for legacy support */
 
        volname = read_string_from_file(voldir, "name");
        if (!volname) {
                ULOG_ERR("Couldn't read %s/name\n", voldir);
-               return -1;
+               return NULL;
        }
 
        if (strncmp(name, volname, strlen(volname) + 1))
-               return -1;
+               return NULL;
 
-       p = calloc(1, sizeof(struct ubi_priv));
+       p = calloc(1, sizeof(struct ubi_volume));
        if (!p)
-               return -1;
+               return NULL;
 
-       v->priv = p;
-       v->drv = &ubi_driver;
+       p->v.drv = &ubi_driver;
        p->ubi_num = ubi_num;
        p->ubi_volid = volid;
 
-       return 0;
+       return &p->v;
 }
 
-static int ubi_part_match(struct volume *v, char *name, unsigned int ubi_num)
+static struct volume *ubi_part_match(char *name, unsigned int ubi_num)
 {
        DIR *ubi_dir;
        struct dirent *ubi_dirent;
        unsigned int volid;
        char devdir[BUFLEN];
-       int ret = -1;
+       struct volume *ret = NULL;
 
        snprintf(devdir, sizeof(devdir), "%s/ubi%u",
                ubi_dir_name, ubi_num);
@@ -185,22 +183,21 @@ static int ubi_part_match(struct volume *v, char *name, unsigned int ubi_num)
                if (sscanf(ubi_dirent->d_name, "ubi%*u_%u", &volid) != 1)
                        continue;
 
-               if (!ubi_volume_match(v, name, ubi_num, volid)) {
-                       ret = 0;
+               ret = ubi_volume_match(name, ubi_num, volid);
+               if (ret)
                        break;
-               }
        }
        closedir(ubi_dir);
 
        return ret;
 }
 
-static int ubi_volume_find(struct volume *v, char *name)
+static struct volume *ubi_volume_find(char *name)
 {
+       struct volume *ret = NULL;
        DIR *ubi_dir;
        struct dirent *ubi_dirent;
        unsigned int ubi_num;
-       int ret = -1;
 
        if (find_filesystem("ubifs"))
                return ret;
@@ -216,10 +213,9 @@ static int ubi_volume_find(struct volume *v, char *name)
                        continue;
 
                sscanf(ubi_dirent->d_name, "ubi%u", &ubi_num);
-               if (!ubi_part_match(v, name, ubi_num)) {
-                       ret = 0;
+               ret = ubi_part_match(name, ubi_num);
+               if (ret)
                        break;
-               };
        }
        closedir(ubi_dir);
        return ret;
index 8f920e0d06c1b172166ea043144abc60221e9a35..0d293d54ea738acc9f308eaddcfe297ca94b3d7f 100644 (file)
@@ -28,20 +28,16 @@ volume_register_driver(struct driver *d)
 
 struct volume* volume_find(char *name)
 {
-       struct volume *v = malloc(sizeof(struct volume));
+       struct volume *v;
        struct driver *d;
 
-       if (!v)
-               return NULL;
-
        list_for_each_entry(d, &drivers, list) {
-               memset(v, 0, sizeof(struct volume));
-
-               if (d->find && !d->find(v, name))
-                       return v;
+               if (d->find) {
+                       v = d->find(name);
+                       if (v)
+                               return v;
+               }
        }
 
-       free(v);
-
        return NULL;
 }
index 9c679f7fb126665886d59e9399d0930ddca30768..fdd97d16457e07b1a2613f41f375382e3678fbbc 100644 (file)
@@ -21,7 +21,7 @@ struct volume;
 typedef int (*volume_probe_t)(void);
 typedef int (*volume_init_t)(struct volume *v);
 typedef void (*volume_stop_t)(struct volume *v);
-typedef int (*volume_find_t)(struct volume *v, char *name);
+typedef struct volume *(*volume_find_t)(char *name);
 typedef int (*volume_identify_t)(struct volume *v);
 typedef int (*volume_read_t)(struct volume *v, void *buf, int offset, int length);
 typedef int (*volume_write_t)(struct volume *v, void *buf, int offset, int length);
@@ -51,7 +51,6 @@ enum {
 
 struct volume {
        struct driver   *drv;
-       void            *priv;
        char            *name;
        char            *blk;