diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2015-05-26 13:37:50 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-05-26 14:33:18 +0200 |
commit | a44ccc57daaed8b72364d50109f5d3d04373fa4f (patch) | |
tree | 5eff046b1b20450bced949b9b3713d1800429d95 /common | |
parent | 8fba554f888493103d104c1acceca449a0a105ed (diff) | |
download | barebox-a44ccc57daaed8b72364d50109f5d3d04373fa4f.tar.gz barebox-a44ccc57daaed8b72364d50109f5d3d04373fa4f.tar.xz |
state: backend_raw: factor out state_backend_raw_file_get_size() into separate function
This patch factors out the state_backend_raw_file_get_size() into a separate
function and adds some ifdefs to make this code work under Linux aswell.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common')
-rw-r--r-- | common/state.c | 73 |
1 files changed, 64 insertions, 9 deletions
diff --git a/common/state.c b/common/state.c index dd921e7c56..dae4a84cde 100644 --- a/common/state.c +++ b/common/state.c @@ -1216,6 +1216,60 @@ out_free: return ret; } +#ifdef __BAREBOX__ +#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode) || S_ISCHR(s.st_mode)) +#define BLKGET_GIVES_SIZE(s) 0 +#ifndef BLKGETSIZE64 +#define BLKGETSIZE64 -1 +#endif +#else +#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode)) +#define BLKGET_GIVES_SIZE(s) (S_ISBLK(s.st_mode)) +#endif + +static int state_backend_raw_file_get_size(const char *path, size_t *out_size) +{ + struct mtd_info_user meminfo; + struct stat s; + int ret; + + 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 (BLKGET_GIVES_SIZE(s)) { + int fd; + + 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 * @@ -1239,20 +1293,21 @@ int state_backend_raw_file(struct state *state, const char *of_path, 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 = 0; + 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 = state_backend_raw_file_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; |