Blame SOURCES/0075-lib-loopdev-retry-LOOP_SET_STATUS64-and-LOOP_SET_BLO.patch

25f9c8
From 97a5abd36eeab4e07a31b27f6a2c2078d42e2e33 Mon Sep 17 00:00:00 2001
25f9c8
From: Karel Zak <kzak@redhat.com>
25f9c8
Date: Tue, 8 Mar 2022 11:40:58 +0100
25f9c8
Subject: lib/loopdev: retry LOOP_SET_STATUS64 and LOOP_SET_BLOCK_SIZE on
25f9c8
 EAGAIN
25f9c8
25f9c8
Upstream: http://github.com/util-linux/util-linux/commit/0ae7bb11c29aa11c8ef25b1ef2f82ee4701b856d
25f9c8
Upstream: http://github.com/util-linux/util-linux/commit/eab90ef8d4f66394285e0cff1dfc0a27242c05aa
25f9c8
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=2058176
25f9c8
Signed-off-by: Karel Zak <kzak@redhat.com>
25f9c8
---
25f9c8
 lib/loopdev.c | 42 +++++++++++++++++++++++++++++++++++++-----
25f9c8
 1 file changed, 37 insertions(+), 5 deletions(-)
25f9c8
25f9c8
diff --git a/lib/loopdev.c b/lib/loopdev.c
25f9c8
index 54d337ea3..48af82aef 100644
25f9c8
--- a/lib/loopdev.c
25f9c8
+++ b/lib/loopdev.c
25f9c8
@@ -42,6 +42,8 @@
25f9c8
 #include "blkdev.h"
25f9c8
 #include "debug.h"
25f9c8
 
25f9c8
+#define LOOPDEV_MAX_TRIES       10
25f9c8
+
25f9c8
 /*
25f9c8
  * Debug stuff (based on include/debug.h)
25f9c8
  */
25f9c8
@@ -1260,6 +1262,7 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
25f9c8
 {
25f9c8
 	int file_fd, dev_fd, mode = O_RDWR, rc = -1, cnt = 0;
25f9c8
 	int errsv = 0;
25f9c8
+	int err, again;
25f9c8
 
25f9c8
 	if (!lc || !*lc->device || !lc->filename)
25f9c8
 		return -EINVAL;
25f9c8
@@ -1331,7 +1334,17 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
25f9c8
 
25f9c8
 	DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD: OK"));
25f9c8
 
25f9c8
-	if (ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info)) {
25f9c8
+	cnt = 0;
25f9c8
+	do {
25f9c8
+		err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info);
25f9c8
+		again = err && errno == EAGAIN;
25f9c8
+		if (again) {
25f9c8
+			xusleep(250000);
25f9c8
+			cnt++;
25f9c8
+		}
25f9c8
+	} while (again && cnt <= LOOPDEV_MAX_TRIES);
25f9c8
+
25f9c8
+	if (err) {
25f9c8
 		rc = -errno;
25f9c8
 		errsv = errno;
25f9c8
 		DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m"));
25f9c8
@@ -1376,7 +1389,7 @@ err:
25f9c8
  */
25f9c8
 int loopcxt_set_status(struct loopdev_cxt *lc)
25f9c8
 {
25f9c8
-	int dev_fd, rc = -1;
25f9c8
+	int dev_fd, rc = -1, err, again, tries = 0;
25f9c8
 
25f9c8
 	errno = 0;
25f9c8
 	dev_fd = loopcxt_get_fd(lc);
25f9c8
@@ -1387,7 +1400,16 @@ int loopcxt_set_status(struct loopdev_cxt *lc)
25f9c8
 	}
25f9c8
 	DBG(SETUP, ul_debugobj(lc, "device open: OK"));
25f9c8
 
25f9c8
-	if (ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info)) {
25f9c8
+	do {
25f9c8
+		err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info);
25f9c8
+		again = err && errno == EAGAIN;
25f9c8
+		if (again) {
25f9c8
+			xusleep(250000);
25f9c8
+			tries++;
25f9c8
+		}
25f9c8
+	} while (again && tries <= LOOPDEV_MAX_TRIES);
25f9c8
+
25f9c8
+	if (err) {
25f9c8
 		rc = -errno;
25f9c8
 		DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m"));
25f9c8
 		return rc;
25f9c8
@@ -1440,12 +1462,22 @@ int loopcxt_set_dio(struct loopdev_cxt *lc, unsigned long use_dio)
25f9c8
 int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
25f9c8
 {
25f9c8
 	int fd = loopcxt_get_fd(lc);
25f9c8
+	int err, again, tries = 0;
25f9c8
 
25f9c8
 	if (fd < 0)
25f9c8
 		return -EINVAL;
25f9c8
 
25f9c8
-	/* Kernels prior to v4.14 don't support this ioctl */
25f9c8
-	if (ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) blocksize) < 0) {
25f9c8
+	do {
25f9c8
+		/* Kernels prior to v4.14 don't support this ioctl */
25f9c8
+		err = ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) blocksize);
25f9c8
+		again = err && errno == EAGAIN;
25f9c8
+		if (again) {
25f9c8
+			xusleep(250000);
25f9c8
+			tries++;
25f9c8
+		}
25f9c8
+	} while (again && tries <= LOOPDEV_MAX_TRIES);
25f9c8
+
25f9c8
+	if (err) {
25f9c8
 		int rc = -errno;
25f9c8
 		DBG(CXT, ul_debugobj(lc, "LOOP_SET_BLOCK_SIZE failed: %m"));
25f9c8
 		return rc;
25f9c8
-- 
25f9c8
2.34.1
25f9c8