Message ID | 20241210082801.4104194-1-weilongping@oppo.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [f2fs-dev,1/2] f2fs-tools: use pread and pwrite when they are available. | expand |
On 2024/12/10 16:28, LongPing Wei wrote: > This patch want to reduce the number of system calls to improve performance. > pread and pwrite will only be used when the target platform support them. > > Signed-off-by: LongPing Wei <weilongping@oppo.com> > --- > configure.ac | 4 +++- > lib/libf2fs_io.c | 29 +++++++++++++++++++++++++++++ > 2 files changed, 32 insertions(+), 1 deletion(-) > > diff --git a/configure.ac b/configure.ac > index 2053a65..439b97f 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -182,6 +182,7 @@ AC_TYPE_SIZE_T > AC_FUNC_GETMNTENT > AC_CHECK_FUNCS_ONCE([ > add_key > + clock_gettime > fallocate > fsetxattr > fstat > @@ -193,7 +194,8 @@ AC_CHECK_FUNCS_ONCE([ > keyctl > memset > setmntent > - clock_gettime > + pread > + pwrite > ]) > > AS_IF([test "$ac_cv_header_byteswap_h" = "yes"], > diff --git a/lib/libf2fs_io.c b/lib/libf2fs_io.c > index 520ae03..a8430c9 100644 > --- a/lib/libf2fs_io.c > +++ b/lib/libf2fs_io.c > @@ -279,6 +279,12 @@ static int dcache_io_read(long entry, __u64 offset, off_t blk) > if (fd < 0) > return fd; > > +#ifdef HAVE_PREAD > + if (pread(fd, dcache_buf + entry * F2FS_BLKSIZE, F2FS_BLKSIZE, offset) < 0) { > + MSG(0, "\n pread() fail.\n"); > + return -1; > + } > +#else > if (lseek(fd, offset, SEEK_SET) < 0) { > MSG(0, "\n lseek fail.\n"); > return -1; > @@ -287,6 +293,7 @@ static int dcache_io_read(long entry, __u64 offset, off_t blk) > MSG(0, "\n read() fail.\n"); > return -1; > } > +#endif > dcache_lastused[entry] = ++dcache_usetick; > dcache_valid[entry] = true; > dcache_blk[entry] = blk; > @@ -393,10 +400,15 @@ int dev_read_version(void *buf, __u64 offset, size_t len) > { > if (c.sparse_mode) > return 0; > +#ifdef HAVE_RPEAD > + if (pread(c.kd, buf, len, (off_t)offset) < 0) > + return -1; > +#else > if (lseek(c.kd, (off_t)offset, SEEK_SET) < 0) > return -1; > if (read(c.kd, buf, len) < 0) > return -1; > +#endif > return 0; > } > > @@ -535,10 +547,15 @@ int dev_read(void *buf, __u64 offset, size_t len) > fd = __get_device_fd(&offset); > if (fd < 0) > return fd; > +#ifdef HAVE_PREAD > + if (pread(fd, buf, len, (off_t)offset) < 0) > + return -1; > +#else > if (lseek(fd, (off_t)offset, SEEK_SET) < 0) > return -1; > if (read(fd, buf, len) < 0) > return -1; > +#endif > return 0; > } > > @@ -615,8 +632,10 @@ static int __dev_write(void *buf, __u64 offset, size_t len, enum rw_hint whint) > if (fd < 0) > return fd; > > +#ifndef HAVE_PWRITE > if (lseek(fd, (off_t)offset, SEEK_SET) < 0) > return -1; > +#endif Hi, LongPing, Can we move lseek and the following write together after writehint operation? I think there is no need to place writehint between lseek and write, because writehint affects the inode and does not affects the pos in struct file. However, I am wondering if writehint here works as expected when fd is not opened with O_SYNC or O_DSYN, especially if multiple writes occur in a short period of time. Please correct me if I miss something. thanks, shengyong > > #if ! defined(__MINGW32__) > if (c.need_whint && (c.whint != whint)) { > @@ -629,8 +648,13 @@ static int __dev_write(void *buf, __u64 offset, size_t len, enum rw_hint whint) > } > #endif > > +#ifdef HAVE_PWRITE > + if (pwrite(fd, buf, len, (off_t)offset) < 0) > + return -1; > +#else > if (write(fd, buf, len) < 0) > return -1; > +#endif > > c.need_fsync = true; > > @@ -663,10 +687,15 @@ int dev_write_block(void *buf, __u64 blk_addr, enum rw_hint whint) > > int dev_write_dump(void *buf, __u64 offset, size_t len) > { > +#ifdef HAVE_PWRITE > + if (pwrite(c.dump_fd, buf, len, (off_t)offset) < 0) > + return -1; > +#else > if (lseek(c.dump_fd, (off_t)offset, SEEK_SET) < 0) > return -1; > if (write(c.dump_fd, buf, len) < 0) > return -1; > +#endif > return 0; > } >
diff --git a/configure.ac b/configure.ac index 2053a65..439b97f 100644 --- a/configure.ac +++ b/configure.ac @@ -182,6 +182,7 @@ AC_TYPE_SIZE_T AC_FUNC_GETMNTENT AC_CHECK_FUNCS_ONCE([ add_key + clock_gettime fallocate fsetxattr fstat @@ -193,7 +194,8 @@ AC_CHECK_FUNCS_ONCE([ keyctl memset setmntent - clock_gettime + pread + pwrite ]) AS_IF([test "$ac_cv_header_byteswap_h" = "yes"], diff --git a/lib/libf2fs_io.c b/lib/libf2fs_io.c index 520ae03..a8430c9 100644 --- a/lib/libf2fs_io.c +++ b/lib/libf2fs_io.c @@ -279,6 +279,12 @@ static int dcache_io_read(long entry, __u64 offset, off_t blk) if (fd < 0) return fd; +#ifdef HAVE_PREAD + if (pread(fd, dcache_buf + entry * F2FS_BLKSIZE, F2FS_BLKSIZE, offset) < 0) { + MSG(0, "\n pread() fail.\n"); + return -1; + } +#else if (lseek(fd, offset, SEEK_SET) < 0) { MSG(0, "\n lseek fail.\n"); return -1; @@ -287,6 +293,7 @@ static int dcache_io_read(long entry, __u64 offset, off_t blk) MSG(0, "\n read() fail.\n"); return -1; } +#endif dcache_lastused[entry] = ++dcache_usetick; dcache_valid[entry] = true; dcache_blk[entry] = blk; @@ -393,10 +400,15 @@ int dev_read_version(void *buf, __u64 offset, size_t len) { if (c.sparse_mode) return 0; +#ifdef HAVE_RPEAD + if (pread(c.kd, buf, len, (off_t)offset) < 0) + return -1; +#else if (lseek(c.kd, (off_t)offset, SEEK_SET) < 0) return -1; if (read(c.kd, buf, len) < 0) return -1; +#endif return 0; } @@ -535,10 +547,15 @@ int dev_read(void *buf, __u64 offset, size_t len) fd = __get_device_fd(&offset); if (fd < 0) return fd; +#ifdef HAVE_PREAD + if (pread(fd, buf, len, (off_t)offset) < 0) + return -1; +#else if (lseek(fd, (off_t)offset, SEEK_SET) < 0) return -1; if (read(fd, buf, len) < 0) return -1; +#endif return 0; } @@ -615,8 +632,10 @@ static int __dev_write(void *buf, __u64 offset, size_t len, enum rw_hint whint) if (fd < 0) return fd; +#ifndef HAVE_PWRITE if (lseek(fd, (off_t)offset, SEEK_SET) < 0) return -1; +#endif #if ! defined(__MINGW32__) if (c.need_whint && (c.whint != whint)) { @@ -629,8 +648,13 @@ static int __dev_write(void *buf, __u64 offset, size_t len, enum rw_hint whint) } #endif +#ifdef HAVE_PWRITE + if (pwrite(fd, buf, len, (off_t)offset) < 0) + return -1; +#else if (write(fd, buf, len) < 0) return -1; +#endif c.need_fsync = true; @@ -663,10 +687,15 @@ int dev_write_block(void *buf, __u64 blk_addr, enum rw_hint whint) int dev_write_dump(void *buf, __u64 offset, size_t len) { +#ifdef HAVE_PWRITE + if (pwrite(c.dump_fd, buf, len, (off_t)offset) < 0) + return -1; +#else if (lseek(c.dump_fd, (off_t)offset, SEEK_SET) < 0) return -1; if (write(c.dump_fd, buf, len) < 0) return -1; +#endif return 0; }
This patch want to reduce the number of system calls to improve performance. pread and pwrite will only be used when the target platform support them. Signed-off-by: LongPing Wei <weilongping@oppo.com> --- configure.ac | 4 +++- lib/libf2fs_io.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-)