Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
loopdev: add retries on EAGAIN
* add limit to number of attempts for LOOP_SET_STATUS64

* use the same for LOOP_SET_BLOCK_SIZE ioctl

Addresses: #1582
Signed-off-by: Karel Zak <kzak@redhat.com>
  • Loading branch information
karelzak committed Mar 1, 2022
1 parent 36bbb18 commit 0ae7bb1
Showing 1 changed file with 23 additions and 9 deletions.
32 changes: 23 additions & 9 deletions lib/loopdev.c
Expand Up @@ -43,6 +43,9 @@
#include "debug.h"
#include "fileutils.h"


#define LOOPDEV_MAX_TRIES 10

/*
* Debug stuff (based on include/debug.h)
*/
Expand Down Expand Up @@ -1454,7 +1457,7 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
*/
int loopcxt_ioctl_status(struct loopdev_cxt *lc)
{
int dev_fd, rc = -1, err, again;
int dev_fd, rc = -1, err, again, tries = 0;

errno = 0;
dev_fd = loopcxt_get_fd(lc);
Expand All @@ -1468,9 +1471,12 @@ int loopcxt_ioctl_status(struct loopdev_cxt *lc)
do {
err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->config.info);
again = err && errno == EAGAIN;
if (again)
if (again) {
xusleep(250000);
} while (again);
tries++;
}
} while (again && tries <= LOOPDEV_MAX_TRIES);

if (err) {
rc = -errno;
DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m"));
Expand Down Expand Up @@ -1524,16 +1530,24 @@ int loopcxt_ioctl_dio(struct loopdev_cxt *lc, unsigned long use_dio)
int loopcxt_ioctl_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
{
int fd = loopcxt_get_fd(lc);
int err, again, tries = 0;

if (fd < 0)
return -EINVAL;

/* Kernels prior to v4.14 don't support this ioctl */
if (ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) blocksize) < 0) {
int rc = -errno;
DBG(CXT, ul_debugobj(lc, "LOOP_SET_BLOCK_SIZE failed: %m"));
return rc;
}
do {
/* Kernels prior to v4.14 don't support this ioctl */
err = ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) blocksize);
again = err && errno == EAGAIN;
if (again) {
xusleep(250000);
tries++;
} else if (err) {
int rc = -errno;
DBG(CXT, ul_debugobj(lc, "LOOP_SET_BLOCK_SIZE failed: %m"));
return rc;
}
} while (again && tries <= LOOPDEV_MAX_TRIES);

DBG(CXT, ul_debugobj(lc, "logical block size set"));
return 0;
Expand Down

0 comments on commit 0ae7bb1

Please sign in to comment.