]> sourceware.org Git - lvm2.git/commitdiff
bcache: sync io fixes
authorDavid Teigland <teigland@redhat.com>
Fri, 16 Nov 2018 19:09:29 +0000 (13:09 -0600)
committerDavid Teigland <teigland@redhat.com>
Tue, 20 Nov 2018 15:19:18 +0000 (09:19 -0600)
fix lseek error check
fix read/write error checks
handle zero return from read and write
don't return an error for short io
fix partial read/write loop

lib/device/bcache.c

index 7e640a43189f35c18711f3ee24d08195b2b1ec6f..18ffcf058b8305518b74b4e60ba1cec7538a4c1c 100644 (file)
@@ -329,7 +329,7 @@ struct io_engine *create_async_io_engine(void)
        e->aio_context = 0;
        r = io_setup(MAX_IO, &e->aio_context);
        if (r < 0) {
-               log_warn("io_setup failed");
+               log_debug("io_setup failed %d", r);
                free(e);
                return NULL;
        }
@@ -372,8 +372,11 @@ static void _sync_destroy(struct io_engine *ioe)
 static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
                         sector_t sb, sector_t se, void *data, void *context)
 {
-        int r;
-        uint64_t len = (se - sb) * 512, where;
+       int rv;
+       off_t off;
+       uint64_t where;
+       uint64_t pos = 0;
+       uint64_t len = (se - sb) * 512;
        struct sync_engine *e = _to_sync(ioe);
        struct sync_io *io = malloc(sizeof(*io));
        if (!io) {
@@ -382,11 +385,16 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
        }
 
        where = sb * 512;
-       r = lseek(fd, where, SEEK_SET);
-       if (r < 0) {
-               log_warn("unable to seek to position %llu", (unsigned long long) where);
+       off = lseek(fd, where, SEEK_SET);
+       if (off == (off_t) -1) {
+               log_warn("Device seek error %d for offset %llu", errno, (unsigned long long)where);
                free(io);
-               return false;
+               return false;
+       }
+       if (off != (off_t) where) {
+               log_warn("Device seek failed for offset %llu", (unsigned long long)where);
+               free(io);
+               return false;
        }
 
        /*
@@ -431,28 +439,44 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
                len = nbytes;
        }
 
-       while (len) {
-               do {
-                       if (d == DIR_READ)
-                                r = read(fd, data, len);
-                        else
-                                r = write(fd, data, len);
+       while (pos < len) {
+               if (d == DIR_READ)
+                       rv = read(fd, (char *)data + pos, len - pos);
+               else
+                       rv = write(fd, (char *)data + pos, len - pos);
+
+               if (rv == -1 && errno == EINTR)
+                       continue;
+               if (rv == -1 && errno == EAGAIN)
+                       continue;
 
-               } while ((r < 0) && ((r == EINTR) || (r == EAGAIN)));
+               if (!rv)
+                       break;
 
-               if (r < 0) {
-                       log_warn("io failed %d", r);
+               if (rv < 0) {
+                       if (d == DIR_READ)
+                               log_debug("Device read error %d offset %llu len %llu", errno,
+                                         (unsigned long long)(where + pos),
+                                         (unsigned long long)(len - pos));
+                       else
+                               log_debug("Device write error %d offset %llu len %llu", errno,
+                                         (unsigned long long)(where + pos),
+                                         (unsigned long long)(len - pos));
                        free(io);
-                       return false;
-               }
-
-                len -= r;
+                       return false;
+               }
+               pos += rv;
        }
 
-       if (len) {
-               log_warn("short io %u bytes remaining", (unsigned) len);
-               free(io);
+       if (pos < len) {
+               if (d == DIR_READ)
+                       log_warn("Device read short %u bytes remaining", (unsigned)(len - pos));
+               else
+                       log_warn("Device write short %u bytes remaining", (unsigned)(len - pos));
+               /*
+               free(io);
                return false;
+               */
        }
 
 
This page took 0.067472 seconds and 5 git commands to generate.