diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-08 17:01:45 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-09 04:31:10 +0900 |
commit | bb273a5145977844a8cb0314b1a03c3361dd3ede (patch) | |
tree | a25206e2b7d5e8cf6c56a11c08d56c55b0b849be /src/shared/loop-util.c | |
parent | 54ba7daf23e7e4fe3564cf4ea1e0f7cdf99b2558 (diff) | |
download | systemd-bb273a5145977844a8cb0314b1a03c3361dd3ede.tar.gz |
loop-util: save the flag about if LOOP_CONFIGURE ioctl works or not in loop_configure()
When LOOP_CONFIGURE fail, then it is not necessary to call it on any
later call of loop_configure(). Let's save the flag in a static variable
in the function.
Diffstat (limited to 'src/shared/loop-util.c')
-rw-r--r-- | src/shared/loop-util.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 8c71f2cf4e..f1debc6d95 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -221,11 +221,12 @@ static int loop_configure( int fd, int nr, const struct loop_config *c, - bool *try_loop_configure, uint64_t *ret_seqnum_not_before, usec_t *ret_timestamp_not_before, int *ret_lock_fd) { + static bool loop_configure_broken = false; + _cleanup_close_ int lock_fd = -1; uint64_t seqnum; usec_t timestamp; @@ -234,7 +235,6 @@ static int loop_configure( assert(fd >= 0); assert(nr >= 0); assert(c); - assert(try_loop_configure); /* Let's lock the device before we do anything. We take the BSD lock on a second, separately opened * fd for the device. udev after all watches for close() events (specifically IN_CLOSE_WRITE) on @@ -272,7 +272,7 @@ static int loop_configure( return -EUCLEAN; } - if (*try_loop_configure) { + if (!loop_configure_broken) { /* Acquire uevent seqnum immediately before attaching the loopback device. This allows * callers to ignore all uevents with a seqnum before this one, if they need to associate * uevent with this attachment. Doing so isn't race-free though, as uevents that happen in @@ -293,14 +293,14 @@ static int loop_configure( if (!ERRNO_IS_NOT_SUPPORTED(errno) && errno != EINVAL) return -errno; - *try_loop_configure = false; + loop_configure_broken = true; } else { r = loop_configure_verify(fd, c); if (r < 0) goto fail; if (r == 0) { /* LOOP_CONFIGURE doesn't work. Remember that. */ - *try_loop_configure = false; + loop_configure_broken = true; /* We return EBUSY here instead of retrying immediately with LOOP_SET_FD, * because LOOP_CLR_FD is async: if the operation cannot be executed right @@ -311,26 +311,25 @@ static int loop_configure( r = -EBUSY; goto fail; } - - goto success; } } - /* Let's read the seqnum again, to shorten the window. */ - r = get_current_uevent_seqnum(&seqnum); - if (r < 0) - return r; + if (loop_configure_broken) { + /* Let's read the seqnum again, to shorten the window. */ + r = get_current_uevent_seqnum(&seqnum); + if (r < 0) + return r; - timestamp = now(CLOCK_MONOTONIC); + timestamp = now(CLOCK_MONOTONIC); - if (ioctl(fd, LOOP_SET_FD, c->fd) < 0) - return -errno; + if (ioctl(fd, LOOP_SET_FD, c->fd) < 0) + return -errno; - r = loop_configure_fallback(fd, c); - if (r < 0) - goto fail; + r = loop_configure_fallback(fd, c); + if (r < 0) + goto fail; + } -success: if (ret_seqnum_not_before) *ret_seqnum_not_before = seqnum; if (ret_timestamp_not_before) @@ -361,7 +360,6 @@ static int loop_device_make_internal( _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int direct_io_fd = -1; _cleanup_free_ char *node = NULL, *backing_file = NULL; - bool try_loop_configure = true; struct loop_config config; LoopDevice *d; uint64_t seqnum = UINT64_MAX; @@ -482,7 +480,7 @@ static int loop_device_make_internal( if (!ERRNO_IS_DEVICE_ABSENT(errno)) return -errno; } else { - r = loop_configure(dev, loop, nr, &config, &try_loop_configure, &seqnum, ×tamp, &lock_fd); + r = loop_configure(dev, loop, nr, &config, &seqnum, ×tamp, &lock_fd); if (r >= 0) { loop_with_fd = TAKE_FD(loop); break; |