projects
/
project
/
fstools.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
libfstools: support file paths longer than 255 chars
[project/fstools.git]
/
libfstools
/
ubi.c
diff --git
a/libfstools/ubi.c
b/libfstools/ubi.c
index
a281729
..
f9d6e0a
100644
(file)
--- a/
libfstools/ubi.c
+++ b/
libfstools/ubi.c
@@
-19,22
+19,26
@@
#include "libfstools.h"
#include "volume.h"
#include "libfstools.h"
#include "volume.h"
+/* fit for UBI_MAX_VOLUME_NAME and sysfs path lengths */
+#define BUFLEN 128
+
/* could use libubi-tiny instead, but already had the code directly reading
* from sysfs */
/* could use libubi-tiny instead, but already had the code directly reading
* from sysfs */
-c
har *
ubi_dir_name = "/sys/devices/virtual/ubi";
+c
onst char *const
ubi_dir_name = "/sys/devices/virtual/ubi";
-struct ubi_priv {
+struct ubi_volume {
+ struct volume v;
int ubi_num;
int ubi_num;
- int ubi_volid
x
;
+ int ubi_volid;
};
static struct driver ubi_driver;
};
static struct driver ubi_driver;
-static
unsigned
int
+static int
read_uint_from_file(char *dirname, char *filename, unsigned int *i)
{
FILE *f;
read_uint_from_file(char *dirname, char *filename, unsigned int *i)
{
FILE *f;
- char fname[
128
];
+ char fname[
BUFLEN
];
int ret = -1;
snprintf(fname, sizeof(fname), "%s/%s", dirname, filename);
int ret = -1;
snprintf(fname, sizeof(fname), "%s/%s", dirname, filename);
@@
-54,10
+58,9
@@
static char
*read_string_from_file(char *dirname, char *filename)
{
FILE *f;
*read_string_from_file(char *dirname, char *filename)
{
FILE *f;
- char fname[
128
];
- char buf[
128
];
+ char fname[
BUFLEN
];
+ char buf[
BUFLEN
];
int i;
int i;
- char *str;
snprintf(fname, sizeof(fname), "%s/%s", dirname, filename);
snprintf(fname, sizeof(fname), "%s/%s", dirname, filename);
@@
-65,17
+68,20
@@
static char
if (!f)
return NULL;
if (!f)
return NULL;
- if (fgets(buf,
128
, f) == NULL)
+ if (fgets(buf,
sizeof(buf)
, f) == NULL)
return NULL;
return NULL;
- i = strlen(buf);
- do
- buf[i--]='\0';
- while (buf[i] == '\n');
-
- str = strdup(buf);
fclose(f);
fclose(f);
- return str;
+
+ /* make sure the string is \0 terminated */
+ buf[sizeof(buf) - 1] = '\0';
+
+ /* remove trailing whitespace */
+ i = strlen(buf) - 1;
+ while (i > 0 && buf[i] <= ' ')
+ buf[i--] = '\0';
+
+ return strdup(buf);
}
static unsigned int
}
static unsigned int
@@
-93,17
+99,15
@@
test_open(char *filename)
static int ubi_volume_init(struct volume *v)
{
static int ubi_volume_init(struct volume *v)
{
-
char voldir[40], voldev[32], *volname
;
-
struct ubi_priv *p
;
+
struct ubi_volume *p = container_of(v, struct ubi_volume, v)
;
+
char voldir[BUFLEN], voldev[BUFLEN], *volname
;
unsigned int volsize;
unsigned int volsize;
- p = (struct ubi_priv*)v->priv;
-
snprintf(voldir, sizeof(voldir), "%s/ubi%u/ubi%u_%u",
snprintf(voldir, sizeof(voldir), "%s/ubi%u/ubi%u_%u",
- ubi_dir_name, p->ubi_num, p->ubi_num, p->ubi_volid
x
);
+ ubi_dir_name, p->ubi_num, p->ubi_num, p->ubi_volid);
snprintf(voldev, sizeof(voldev), "/dev/ubi%u_%u",
snprintf(voldev, sizeof(voldev), "/dev/ubi%u_%u",
- p->ubi_num, p->ubi_volid
x
);
+ p->ubi_num, p->ubi_volid);
volname = read_string_from_file(voldir, "name");
if (!volname)
volname = read_string_from_file(voldir, "name");
if (!volname)
@@
-120,65
+124,83
@@
static int ubi_volume_init(struct volume *v)
return 0;
}
return 0;
}
-
-static int ubi_volume_match(struct volume *v, char *name, int ubi_num, int volidx)
+static struct volume *ubi_volume_match(char *name, int ubi_num, int volid)
{
{
- char voldir[
40], volblkdev[40
], *volname;
- struct ubi_
priv
*p;
+ char voldir[
BUFLEN], volblkdev[BUFLEN
], *volname;
+ struct ubi_
volume
*p;
snprintf(voldir, sizeof(voldir), "%s/ubi%u/ubi%u_%u",
snprintf(voldir, sizeof(voldir), "%s/ubi%u/ubi%u_%u",
- ubi_dir_name, ubi_num, ubi_num, volid
x
);
+ ubi_dir_name, ubi_num, ubi_num, volid);
snprintf(volblkdev, sizeof(volblkdev), "/dev/ubiblock%u_%u",
snprintf(volblkdev, sizeof(volblkdev), "/dev/ubiblock%u_%u",
- ubi_num, volid
x
);
+ ubi_num, volid);
/* skip if ubiblock device exists */
if (test_open(volblkdev))
/* 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");
volname = read_string_from_file(voldir, "name");
+ if (!volname) {
+ ULOG_ERR("Couldn't read %s/name\n", voldir);
+ return NULL;
+ }
- if (strncmp(name, volname, strlen(volname)))
- return
-1
;
+ if (strncmp(name, volname, strlen(volname)
+ 1
))
+ return
NULL
;
- p = calloc(1, sizeof(struct ubi_
priv
));
+ p = calloc(1, sizeof(struct ubi_
volume
));
if (!p)
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_num = ubi_num;
- p->ubi_volid
x = volidx
;
+ p->ubi_volid
= volid
;
- return
ubi_volume_init(v)
;
+ 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)
{
{
- unsigned int i, volumes_count;
- char devdir[80];
+ DIR *ubi_dir;
+ struct dirent *ubi_dirent;
+ unsigned int volid;
+ char devdir[BUFLEN];
+ struct volume *ret = NULL;
snprintf(devdir, sizeof(devdir), "%s/ubi%u",
ubi_dir_name, ubi_num);
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;
+
+ while ((ubi_dirent = readdir(ubi_dir)) != NULL) {
+ if (strncmp(ubi_dirent->d_name, "ubi", 3))
+ continue;
- for (i=0;i<volumes_count;i++) {
- if (!ubi_volume_match(v, name, ubi_num, i)) {
- return 0;
- }
+ if (sscanf(ubi_dirent->d_name, "ubi%*u_%u", &volid) != 1)
+ continue;
+
+ ret = ubi_volume_match(name, ubi_num, volid);
+ if (ret)
+ break;
}
}
+ closedir(ubi_dir);
- return
-1
;
+ 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;
DIR *ubi_dir;
struct dirent *ubi_dirent;
unsigned int ubi_num;
- int ret = -1;
+
+ if (find_filesystem("ubifs"))
+ return ret;
ubi_dir = opendir(ubi_dir_name);
/* check for os ubi support */
ubi_dir = opendir(ubi_dir_name);
/* check for os ubi support */
@@
-191,10
+213,9
@@
static int ubi_volume_find(struct volume *v, char *name)
continue;
sscanf(ubi_dirent->d_name, "ubi%u", &ubi_num);
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;
break;
- };
}
closedir(ubi_dir);
return ret;
}
closedir(ubi_dir);
return ret;
@@
-202,6
+223,7
@@
static int ubi_volume_find(struct volume *v, char *name)
static int ubi_volume_identify(struct volume *v)
{
static int ubi_volume_identify(struct volume *v)
{
+ /* Todo: use libblkid-tiny on the ubi chardev */
return FS_UBIFS;
}
return FS_UBIFS;
}