2 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <sys/mount.h>
19 #include <sys/types.h>
22 #include <asm/byteorder.h>
26 #include <mtd/mtd-user.h>
29 #include "libfstools.h"
33 #define ext4_sysfs_path "/sys/block/mmcblk*/mmcblk*/uevent"
36 #define EXT_SB_OFF 0x400
37 #define EXT_SB_KBOFF (EXT_SB_OFF >> 10)
38 #define EXT_SB_MAGIC "\123\357"
39 #define EXT_MAG_OFF 0x38
46 static struct driver ext4_driver;
48 static int ext4_volume_init(struct volume *v)
53 p = (struct ext4_priv*)v->priv;
54 snprintf(buf, sizeof(buf), "/dev/%s",p->devname);
56 v->name = strdup(p->name);
63 ext4_part_match(char *dev, char *name, char *filename)
67 char devname[MAX_SIZE];
71 fp = fopen(filename, "r");
75 while (fgets(buf, sizeof(buf), fp)) {
76 if (strstr(buf, "DEVNAME")) {
77 strcpy(devname, buf + strlen("DEVNAME="));
80 /* Match partition name */
81 if (strstr(buf, name)) {
89 /* make sure the string is \0 terminated */
90 devname[sizeof(devname) - 1] = '\0';
92 /* remove trailing whitespace */
93 i = strlen(devname) - 1;
94 while (i > 0 && devname[i] <= ' ')
101 static int ext4_find_devname(char *dev, char *name)
106 if (glob(ext4_sysfs_path, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl) < 0)
109 for (i = 0; i < gl.gl_pathc; i++) {
110 if (!ext4_part_match(dev, name, gl.gl_pathv[i])) {
120 static int check_for_mtd(const char *mtd)
125 if ((fp = fopen("/proc/mtd", "r"))) {
126 while (fgets(dev, sizeof(dev), fp)) {
127 if (strstr(dev, mtd)) {
137 static int ext4_volume_find(struct volume *v, char *name)
142 if (find_filesystem("ext4"))
145 if (check_for_mtd(name))
148 if (ext4_find_devname(buf, name))
151 p = calloc(1, sizeof(struct ext4_priv));
156 v->drv = &ext4_driver;
158 p->devname = strdup(buf);
159 p->name = strdup(name);
160 return ext4_volume_init(v);
163 static int ext4_volume_identify(struct volume *v)
165 char magic[32] = { 0 };
166 int off = (EXT_SB_KBOFF * 1024) + EXT_MAG_OFF;
169 fd = open(v->blk, O_RDONLY);
173 lseek(fd, off, SEEK_SET);
174 read(fd, magic, sizeof(EXT_SB_MAGIC) - 1);
177 if (v->type == EXT4VOLUME &&
178 !memcmp(EXT_SB_MAGIC, magic, sizeof(EXT_SB_MAGIC) - 1)) {
182 ULOG_ERR("ext4 is not ready - marker found\n");
186 static struct driver ext4_driver = {
188 .find = ext4_volume_find,
189 .init = ext4_volume_init,
190 .identify = ext4_volume_identify,