ubik: positional io for db reads and writes 72/12272/5
authorMichael Meffie <mmeffie@sinenomine.net>
Wed, 20 Apr 2016 00:46:33 +0000 (20:46 -0400)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 21 Sep 2018 12:08:22 +0000 (08:08 -0400)
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 <adeason@sinenomine.net>
Reviewed-by: Marcio Brito Barbosa <mbarbosa@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/ubik/phys.c

index 62063bb..b35ae4a 100644 (file)
@@ -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)) {