diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2015-04-28 13:44:22 +0200 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2015-04-28 15:13:37 +0200 |
commit | 6273ca1f791e254e9f15c8830ea0e56b5561d502 (patch) | |
tree | cc14749572d752e19d8a714f00b87af0180938ed /src | |
parent | f327ec4a34fd787050bddbe6426c452a4c6b7c83 (diff) | |
download | dt-utils-6273ca1f791e254e9f15c8830ea0e56b5561d502.tar.gz dt-utils-6273ca1f791e254e9f15c8830ea0e56b5561d502.tar.xz |
barebox-state: state_backend_raw_file: factor out get_size() into separate function
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/barebox-state.c | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/src/barebox-state.c b/src/barebox-state.c index 3e3cb41..fd4f165 100644 --- a/src/barebox-state.c +++ b/src/barebox-state.c @@ -29,6 +29,7 @@ #include <sys/stat.h> #include <sys/types.h> +#include <linux/fs.h> #include <mtd/mtd-abi.h> #include <common.h> @@ -1156,6 +1157,54 @@ out_free: return ret; } +#ifdef __BAREBOX__ +#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode) || S_ISCHR(s.st_mode)) +#else +#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode)) +#endif + +int get_size(const char *path, size_t *out_size) +{ + struct mtd_info_user meminfo; + struct stat s; + int ret; + int fd; + + ret = stat(path, &s); + if (ret) + return -errno; + + /* + * under Linux, stat() gives the size only on regular files + * under barebox, it works on char dev, too + */ + if (STAT_GIVES_SIZE(s)) { + *out_size = s.st_size; + return 0; + } + + /* this works under Linux on block devs */ + if (S_ISBLK(s.st_mode)) { + fd = open(path, O_RDONLY); + if (fd < 0) + return -errno; + + ret = ioctl(fd, BLKGETSIZE64, out_size); + close(fd); + if (!ret) + return 0; + } + + /* try mtd next */ + ret = mtd_get_meminfo(path, &meminfo); + if (!ret) { + *out_size = meminfo.size; + return 0; + } + + return ret; +} + /* * state_backend_raw_file - create a raw file backend store for a state instance * @@ -1179,20 +1228,21 @@ int state_backend_raw_file(struct state *state, const char *path, off_t offset, struct state_backend_raw *backend_raw; struct state_backend *backend; struct state_variable *sv; - int ret; - struct stat s; struct mtd_info_user meminfo; + size_t path_size; + int ret; if (state->backend) return -EBUSY; - ret = stat(path, &s); - if (!ret && S_ISCHR(s.st_mode)) { - if (size == 0) - size = s.st_size; - else if (offset + size > s.st_size) - return -EINVAL; - } + ret = get_size(path, &path_size); + if (ret) + return ret; + + if (size == 0) + size = path_size; + else if (offset + size > path_size) + return -EINVAL; backend_raw = xzalloc(sizeof(*backend_raw)); backend = &backend_raw->backend; |