libfstools: use container_of for volume private data
[project/fstools.git] / libfstools / mtd.c
index 60326fed12a6c0cf20249a1678ff3ce372dcc394..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;
 
@@ -86,13 +85,13 @@ static int mtd_volume_load(struct volume *v)
        p->fd = mtd_open(p->chr, 0);
        if (p->fd < 0) {
                p->fd = 0;
-               fprintf(stderr, "Could not open mtd device: %s\n", p->chr);
+               ULOG_ERR("Could not open mtd device: %s\n", p->chr);
                return -1;
        }
 
        if (ioctl(p->fd, MEMGETINFO, &mtdInfo)) {
-               mtd_volume_close(v);
-               fprintf(stderr, "Could not get MTD device info from %s\n", p->chr);
+               mtd_volume_close(p);
+               ULOG_ERR("Could not get MTD device info from %s\n", p->chr);
                return -1;
        }
 
@@ -130,7 +129,9 @@ static char* mtd_find_index(char *name)
                return index;
 
        while (!index && fgets(line, sizeof(line), fp)) {
-               if (strstr(line, name)) {
+               char *ret;
+
+               if ((ret = strstr(line, name)) && (ret[strlen(name)] == '"')) {
                        char *eol = strstr(line, ":");
 
                        if (!eol)
@@ -146,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);
@@ -170,64 +172,65 @@ static int mtd_volume_find(struct volume *v, char *name)
        snprintf(buffer, sizeof(buffer), "/dev/mtd%s", idx);
        p->chr = strdup(buffer);
 
-       return 0;
+       if (mtd_volume_load(p)) {
+               ULOG_ERR("reading %s failed\n", v->name);
+               free(p);
+               return NULL;
+       }
+
+       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)) {
-               fprintf(stderr, "reading %s failed\n", v->name);
+       if (mtd_volume_load(p)) {
+               ULOG_ERR("reading %s failed\n", v->name);
                return -1;
        }
 
        sz = read(p->fd, &deadc0de, sizeof(deadc0de));
 
        if (sz != sizeof(deadc0de)) {
-               fprintf(stderr, "reading %s failed: %s\n", v->name, strerror(errno));
+               ULOG_ERR("reading %s failed: %s\n", v->name, strerror(errno));
                return -1;
        }
 
-       if (deadc0de == 0x4f575254)
+       if (deadc0de == __be32_to_cpu(0x4f575254))
                return FS_SNAPSHOT;
 
        deadc0de = __be32_to_cpu(deadc0de);
        if (deadc0de == 0xdeadc0de) {
-               fprintf(stderr, "jffs2 is not ready - marker found\n");
                return FS_DEADCODE;
        }
 
        jffs2 = __be16_to_cpu(deadc0de >> 16);
        if (jffs2 == 0x1985) {
-               fprintf(stderr, "jffs2 is ready\n");
                return FS_JFFS2;
        }
 
        if (v->type == UBIVOLUME && deadc0de == 0xffffffff) {
-               fprintf(stderr, "jffs2 is ready\n");
                return FS_JFFS2;
        }
 
-       fprintf(stderr, "No jffs2 marker was found\n");
-
        return FS_NONE;
 }
 
 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) {
-               fprintf(stderr, "mtd erase needs to be block aligned\n");
+               ULOG_ERR("mtd erase needs to be block aligned\n");
                return -1;
        }
 
@@ -238,37 +241,39 @@ static int mtd_volume_erase(struct volume *v, int offset, int len)
        for (eiu.start = first_block * v->block_size;
                        eiu.start < v->size && eiu.start < (first_block + num_blocks) * v->block_size;
                        eiu.start += v->block_size) {
-               fprintf(stderr, "erasing %x %x\n", eiu.start, v->block_size);
+               ULOG_INFO("erasing %x %x\n", eiu.start, v->block_size);
                ioctl(p->fd, MEMUNLOCK, &eiu);
                if (ioctl(p->fd, MEMERASE, &eiu))
-                       fprintf(stderr, "Failed to erase block at 0x%x\n", eiu.start);
+                       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);
        if (ret) {
-               fprintf(stderr, "ioctl(%d, MEMGETINFO) failed: %s\n", p->fd, strerror(errno));
+               ULOG_ERR("ioctl(%d, MEMGETINFO) failed: %s\n", p->fd, strerror(errno));
        } else {
                struct erase_info_user mtdlock;
 
@@ -282,18 +287,18 @@ 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) {
-               fprintf(stderr, "lseek/read failed\n");
+               ULOG_ERR("lseek/read failed\n");
                return -1;
        }
 
        if (read(p->fd, buf, length) == -1) {
-               fprintf(stderr, "read failed\n");
+               ULOG_ERR("read failed\n");
                return -1;
        }
 
@@ -302,19 +307,19 @@ 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) {
-               fprintf(stderr, "lseek/write failed at offset %d\n", offset);
+               ULOG_ERR("lseek/write failed at offset %d\n", offset);
                perror("lseek");
                return -1;
        }
 
        if (write(p->fd, buf, length) == -1) {
-               fprintf(stderr, "write failed\n");
+               ULOG_ERR("write failed\n");
                return -1;
        }