From f62fb17b3cf1c886f8cfc2fabe9984070dd3eec4 Mon Sep 17 00:00:00 2001 From: Michael Meffie Date: Tue, 19 Apr 2016 20:46:33 -0400 Subject: [PATCH] ubik: positional io for db reads and writes The ubik library was written before positional i/o was available and issues an lseek system call for each database file read and write. This change converts the ubik database accesses to use positional i/o on platforms where pread and pwrite are available, in order to reduce system call load. The new inline uphys_pread and uphys_pwrite functions are supplied on platforms which do not supply pread and pwrite. These functions fall back to non-positional i/o. If these symbols are present in the database server binary then the server process will continue to call lseek before each read and write access of the database file. This change does not affect the whole-file database synchronization done by ubik during database recovery (via the DISK_SendFile and DISK_GetFile RPCs), which still uses non-positional i/o. However, that code does not share file descriptors with the phys.c code, so there is no possibility of mixing positional and non-positional i/o on the same FDs. Change-Id: I28accd24f7f27b5e8a4f1dd0e3e08bab033c16e0 Reviewed-on: https://gerrit.openafs.org/12272 Reviewed-by: Andrew Deason Reviewed-by: Marcio Brito Barbosa Reviewed-by: Michael Meffie Reviewed-by: Mark Vitale Reviewed-by: Benjamin Kaduk Tested-by: BuildBot --- src/ubik/phys.c | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/ubik/phys.c b/src/ubik/phys.c index 62063bb..b35ae4a 100644 --- a/src/ubik/phys.c +++ b/src/ubik/phys.c @@ -46,6 +46,29 @@ static char pbuffer[1024]; static int uphys_buf_flush(struct ubik_dbase *adbase, afs_int32 afid); +#ifdef HAVE_PIO +# define uphys_pread pread +# define uphys_pwrite pwrite +#else /* HAVE_PIO */ +static_inline ssize_t +uphys_pread(int fd, void *buf, size_t nbyte, off_t offset) +{ + if (lseek(fd, offset, 0) < 0) { + return -1; + } + return read(fd, buf, nbyte); +} + +static_inline ssize_t +uphys_pwrite(int fd, void *buf, size_t nbyte, off_t offset) +{ + if (lseek(fd, offset, 0) < 0) { + return -1; + } + return write(fd, buf, nbyte); +} +#endif /* !HAVE_PIO */ + /*! * \warning Beware, when using this function, of the header in front of most files. */ @@ -186,12 +209,7 @@ uphys_read(struct ubik_dbase *adbase, afs_int32 afile, fd = uphys_open(adbase, afile); if (fd < 0) return -1; - code = lseek(fd, apos + HDRSIZE, 0); - if (code < 0) { - uphys_close(fd); - return -1; - } - code = read(fd, abuffer, alength); + code = uphys_pread(fd, abuffer, alength, apos + HDRSIZE); uphys_close(fd); return code; } @@ -207,12 +225,7 @@ uphys_write(struct ubik_dbase *adbase, afs_int32 afile, fd = uphys_open(adbase, afile); if (fd < 0) return -1; - code = lseek(fd, apos + HDRSIZE, 0); - if (code < 0) { - uphys_close(fd); - return -1; - } - length = write(fd, abuffer, alength); + length = uphys_pwrite(fd, abuffer, alength, apos + HDRSIZE); code = uphys_close(fd); if (code) return -1; @@ -265,11 +278,7 @@ uphys_getlabel(struct ubik_dbase *adbase, afs_int32 afile, fd = uphys_open(adbase, afile); if (fd < 0) return UNOENT; - if (lseek(fd, 0, 0) < 0) { - uphys_close(fd); - return EIO; - } - code = read(fd, &thdr, sizeof(thdr)); + code = uphys_pread(fd, &thdr, sizeof(thdr), 0); if (code != sizeof(thdr)) { uphys_close(fd); return EIO; @@ -300,11 +309,7 @@ uphys_setlabel(struct ubik_dbase *adbase, afs_int32 afile, thdr.version.counter = htonl(aversion->counter); thdr.magic = htonl(UBIK_MAGIC); thdr.size = htons(HDRSIZE); - if (lseek(fd, 0, 0) < 0) { - uphys_close(fd); - return EIO; - } - code = write(fd, &thdr, sizeof(thdr)); + code = uphys_pwrite(fd, &thdr, sizeof(thdr), 0); fsync(fd); /* preserve over crash */ uphys_close(fd); if (code != sizeof(thdr)) { -- 1.9.4