summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2015-04-28 13:44:22 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2015-04-28 15:13:37 +0200
commit6273ca1f791e254e9f15c8830ea0e56b5561d502 (patch)
treecc14749572d752e19d8a714f00b87af0180938ed /src
parentf327ec4a34fd787050bddbe6426c452a4c6b7c83 (diff)
downloaddt-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.c68
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;