mrc0mmand / rpms / lvm2

Forked from rpms/lvm2 2 years ago
Clone

Blame SOURCES/lvm2-2_02_183-bcache-sync-io-fixes.patch

3a5d46
 lib/device/bcache.c | 69 ++++++++++++++++++++++++++++++++++++-----------------
3a5d46
 1 file changed, 47 insertions(+), 22 deletions(-)
3a5d46
3a5d46
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
3a5d46
index 1cb1b2f..6886b74 100644
3a5d46
--- a/lib/device/bcache.c
3a5d46
+++ b/lib/device/bcache.c
3a5d46
@@ -320,7 +320,7 @@ struct io_engine *create_async_io_engine(void)
3a5d46
 	e->aio_context = 0;
3a5d46
 	r = io_setup(MAX_IO, &e->aio_context);
3a5d46
 	if (r < 0) {
3a5d46
-		log_warn("io_setup failed");
3a5d46
+		log_debug("io_setup failed %d", r);
3a5d46
 		dm_free(e);
3a5d46
 		return NULL;
3a5d46
 	}
3a5d46
@@ -363,8 +363,11 @@ static void _sync_destroy(struct io_engine *ioe)
3a5d46
 static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
3a5d46
                         sector_t sb, sector_t se, void *data, void *context)
3a5d46
 {
3a5d46
-        int r;
3a5d46
-        uint64_t len = (se - sb) * 512, where;
3a5d46
+	int rv;
3a5d46
+	off_t off;
3a5d46
+	uint64_t where;
3a5d46
+	uint64_t pos = 0;
3a5d46
+	uint64_t len = (se - sb) * 512;
3a5d46
 	struct sync_engine *e = _to_sync(ioe);
3a5d46
 	struct sync_io *io = malloc(sizeof(*io));
3a5d46
 	if (!io) {
3a5d46
@@ -373,11 +376,17 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
3a5d46
 	}
3a5d46
 
3a5d46
 	where = sb * 512;
3a5d46
-	r = lseek(fd, where, SEEK_SET);
3a5d46
-	if (r < 0) {
3a5d46
-        	log_warn("unable to seek to position %llu", (unsigned long long) where);
3a5d46
-        	free(io);
3a5d46
-        	return false;
3a5d46
+
3a5d46
+	off = lseek(fd, where, SEEK_SET);
3a5d46
+	if (off == (off_t) -1) {
3a5d46
+		log_warn("Device seek error %d for offset %llu", errno, (unsigned long long)where);
3a5d46
+		free(io);
3a5d46
+		return false;
3a5d46
+	}
3a5d46
+	if (off != (off_t) where) {
3a5d46
+		log_warn("Device seek failed for offset %llu", (unsigned long long)where);
3a5d46
+		free(io);
3a5d46
+		return false;
3a5d46
 	}
3a5d46
 
3a5d46
 	/*
3a5d46
@@ -422,28 +431,44 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
3a5d46
 		len = nbytes;
3a5d46
 	}
3a5d46
 
3a5d46
-	while (len) {
3a5d46
-        	do {
3a5d46
-                	if (d == DIR_READ)
3a5d46
-                                r = read(fd, data, len);
3a5d46
-                        else
3a5d46
-                                r = write(fd, data, len);
3a5d46
+	while (pos < len) {
3a5d46
+		if (d == DIR_READ)
3a5d46
+			rv = read(fd, (char *)data + pos, len - pos);
3a5d46
+		else
3a5d46
+			rv = write(fd, (char *)data + pos, len - pos);
3a5d46
 
3a5d46
-        	} while ((r < 0) && ((r == EINTR) || (r == EAGAIN)));
3a5d46
+		if (rv == -1 && errno == EINTR)
3a5d46
+			continue;
3a5d46
+		if (rv == -1 && errno == EAGAIN)
3a5d46
+			continue;
3a5d46
+
3a5d46
+		if (!rv)
3a5d46
+			break;
3a5d46
 
3a5d46
-        	if (r < 0) {
3a5d46
-                	log_warn("io failed %d", r);
3a5d46
+		if (rv < 0) {
3a5d46
+			if (d == DIR_READ)
3a5d46
+				log_debug("Device read error %d offset %llu len %llu", errno,
3a5d46
+					  (unsigned long long)(where + pos),
3a5d46
+					  (unsigned long long)(len - pos));
3a5d46
+			else
3a5d46
+				log_debug("Device write error %d offset %llu len %llu", errno,
3a5d46
+					  (unsigned long long)(where + pos),
3a5d46
+					  (unsigned long long)(len - pos));
3a5d46
                 	free(io);
3a5d46
                 	return false;
3a5d46
-        	}
3a5d46
-
3a5d46
-                len -= r;
3a5d46
+		}
3a5d46
+		pos += rv;
3a5d46
 	}
3a5d46
 
3a5d46
-	if (len) {
3a5d46
-        	log_warn("short io %u bytes remaining", (unsigned) len);
3a5d46
+	if (pos < len) {
3a5d46
+		if (d == DIR_READ)
3a5d46
+			log_warn("Device read short %u bytes remaining", (unsigned)(len - pos));
3a5d46
+		else
3a5d46
+			log_warn("Device write short %u bytes remaining", (unsigned)(len - pos));
3a5d46
+		/*
3a5d46
         	free(io);
3a5d46
         	return false;
3a5d46
+		*/
3a5d46
 	}
3a5d46
 
3a5d46