diff options
author | Alexander Aring <alex.aring@gmail.com> | 2013-02-17 22:05:01 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-02-20 08:22:42 +0100 |
commit | 9d8a20592fdc55be56add1639606b65e3cc523d1 (patch) | |
tree | b00eca00c6930954f213443fb990631dd2dd1110 | |
parent | e48b1440715f7f25d664faf98f5afe0a787f7c68 (diff) | |
download | barebox-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.c | 36 | ||||
-rw-r--r-- | fs/fs.c | 88 | ||||
-rw-r--r-- | include/fs.h | 2 |
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 */ @@ -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 |