summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2013-02-17 22:05:01 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2013-02-20 08:22:42 +0100
commit9d8a20592fdc55be56add1639606b65e3cc523d1 (patch)
treeb00eca00c6930954f213443fb990631dd2dd1110
parente48b1440715f7f25d664faf98f5afe0a787f7c68 (diff)
downloadbarebox-9d8a20592fdc55be56add1639606b65e3cc523d1.tar.gz
barebox-9d8a20592fdc55be56add1639606b65e3cc523d1.tar.xz
fs: add pread and pwrite functions
Add pread and pwrite functions. Split read and write functions to save some space. The functions pread and pwrite saves and sets the file position to a given offset and restore them afterwards. This also makes the nandtest command use these function which is necessary to not break compilation for the nandtest command. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--commands/nandtest.c36
-rw-r--r--fs/fs.c88
-rw-r--r--include/fs.h2
3 files changed, 82 insertions, 44 deletions
diff --git a/commands/nandtest.c b/commands/nandtest.c
index f08f8eb886..4e6024b0c5 100644
--- a/commands/nandtest.c
+++ b/commands/nandtest.c
@@ -43,41 +43,17 @@ static unsigned int ecc_stats_over;
static unsigned int ecc_failed_cnt;
/*
- * Implementation of pread with lseek and read.
- */
-static ssize_t pread(int fd, void *buf, size_t count, loff_t offset)
-{
- int ret;
-
- /* Seek to offset */
- ret = lseek(fd, offset, SEEK_SET);
- if (ret < 0)
- perror("lseek");
-
- /* Read from flash and put it into buf */
- ret = read(fd, buf, count);
- if (ret < 0)
- perror("read");
-
- return 0;
-}
-
-/*
* Implementation of pwrite with lseek and write.
*/
-static ssize_t pwrite(int fd, const void *buf,
+static ssize_t __pwrite(int fd, const void *buf,
size_t count, loff_t offset, loff_t length)
{
- int ret;
-
- ret = lseek(fd, offset, SEEK_SET);
- if (ret < 0)
- perror("lseek");
+ ssize_t ret;
/* Write buf to flash */
- ret = write(fd, buf, count);
+ ret = pwrite(fd, buf, count, offset);
if (ret < 0) {
- perror("write");
+ perror("pwrite");
if (markbad) {
printf("\nMark block bad at 0x%08llx\n",
offset + memregion.offset);
@@ -88,7 +64,7 @@ static ssize_t pwrite(int fd, const void *buf,
}
flush(fd);
- return 0;
+ return ret;
}
/*
@@ -119,7 +95,7 @@ static int erase_and_write(loff_t ofs, unsigned char *data,
for (i = 0; i < meminfo.erasesize;
i += meminfo.writesize) {
/* Write data to given offset */
- pwrite(fd, data + i, meminfo.writesize,
+ __pwrite(fd, data + i, meminfo.writesize,
ofs + i, length);
/* Read data from offset */
diff --git a/fs/fs.c b/fs/fs.c
index 48d1c89a85..6346112e52 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -754,17 +754,12 @@ int ioctl(int fd, int request, void *buf)
return ret;
}
-ssize_t read(int fd, void *buf, size_t count)
+static ssize_t __read(FILE *f, void *buf, size_t count)
{
struct device_d *dev;
struct fs_driver_d *fsdrv;
- FILE *f;
int ret;
- if (check_fd(fd))
- return -errno;
-
- f = &files[fd];
dev = f->dev;
fsdrv = dev_to_fs_driver(dev);
@@ -777,18 +772,33 @@ ssize_t read(int fd, void *buf, size_t count)
ret = fsdrv->read(dev, f, buf, count);
- if (ret > 0)
- f->pos += ret;
if (ret < 0)
errno = -ret;
return ret;
}
-EXPORT_SYMBOL(read);
-ssize_t write(int fd, const void *buf, size_t count)
+ssize_t pread(int fd, void *buf, size_t count, loff_t offset)
+{
+ loff_t pos;
+ FILE *f;
+ int ret;
+
+ if (check_fd(fd))
+ return -errno;
+
+ f = &files[fd];
+
+ pos = f->pos;
+ f->pos = offset;
+ ret = __read(f, buf, count);
+ f->pos = pos;
+
+ return ret;
+}
+EXPORT_SYMBOL(pread);
+
+ssize_t read(int fd, void *buf, size_t count)
{
- struct device_d *dev;
- struct fs_driver_d *fsdrv;
FILE *f;
int ret;
@@ -796,6 +806,21 @@ ssize_t write(int fd, const void *buf, size_t count)
return -errno;
f = &files[fd];
+
+ ret = __read(f, buf, count);
+
+ if (ret > 0)
+ f->pos += ret;
+ return ret;
+}
+EXPORT_SYMBOL(read);
+
+static ssize_t __write(FILE *f, const void *buf, size_t count)
+{
+ struct device_d *dev;
+ struct fs_driver_d *fsdrv;
+ int ret;
+
dev = f->dev;
fsdrv = dev_to_fs_driver(dev);
@@ -812,13 +837,48 @@ ssize_t write(int fd, const void *buf, size_t count)
}
}
ret = fsdrv->write(dev, f, buf, count);
- if (ret > 0)
- f->pos += ret;
out:
if (ret < 0)
errno = -ret;
return ret;
}
+
+ssize_t pwrite(int fd, const void *buf, size_t count, loff_t offset)
+{
+ loff_t pos;
+ FILE *f;
+ int ret;
+
+ if (check_fd(fd))
+ return -errno;
+
+ f = &files[fd];
+
+ pos = f->pos;
+ f->pos = offset;
+ ret = __write(f, buf, count);
+ f->pos = pos;
+
+ return ret;
+}
+EXPORT_SYMBOL(pwrite);
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+ FILE *f;
+ int ret;
+
+ if (check_fd(fd))
+ return -errno;
+
+ f = &files[fd];
+
+ ret = __write(f, buf, count);
+
+ if (ret > 0)
+ f->pos += ret;
+ return ret;
+}
EXPORT_SYMBOL(write);
int flush(int fd)
diff --git a/include/fs.h b/include/fs.h
index d6b22f71f1..7c4e46175a 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -114,8 +114,10 @@ int flush(int fd);
int lstat(const char *filename, struct stat *s);
int stat(const char *filename, struct stat *s);
ssize_t read(int fd, void *buf, size_t count);
+ssize_t pread(int fd, void *buf, size_t count, loff_t offset);
int ioctl(int fd, int request, void *buf);
ssize_t write(int fd, const void *buf, size_t count);
+ssize_t pwrite(int fd, const void *buf, size_t count, loff_t offset);
#define SEEK_SET 1
#define SEEK_CUR 2