loop-util: LOOP_CONFIGURE ignores lo_sizelimit
It appears LOOP_CONFIGURE in 5.8 is even more broken than initially thought: it doesn't properly propgate lo_sizelimit to the block device layer. :-( Let's hence check the block device size immediately after issuing LOOP_CONFIGURE, and if it doesn't match what we just set let's fallback to the old ioctls. This means LOOP_CONFIGURE currently works correctly only for the most simply case: no partition table logic and no size limit. Sad! (Kernel people should really be told about the concepts of tests and even CI, one day!)
This commit is contained in:
parent
c2f418d595
commit
bb2551bdcb
|
@ -47,18 +47,42 @@ static int loop_configure(int fd, const struct loop_config *c) {
|
|||
if (!ERRNO_IS_NOT_SUPPORTED(errno) && errno != EINVAL)
|
||||
return -errno;
|
||||
} else {
|
||||
if (!FLAGS_SET(c->info.lo_flags, LO_FLAGS_PARTSCAN))
|
||||
bool good = true;
|
||||
|
||||
if (c->info.lo_sizelimit != 0) {
|
||||
/* Kernel 5.8 vanilla doesn't properly propagate the size limit into the block
|
||||
* device. If it's used, let's immediately check if it had the desired effect
|
||||
* hence. And if not use classic LOOP_SET_STATUS64. */
|
||||
uint64_t z;
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, &z) < 0) {
|
||||
r = -errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (z != c->info.lo_sizelimit) {
|
||||
log_debug("LOOP_CONFIGURE is broken, doesn't honour .lo_sizelimit. Falling back to LOOP_SET_STATUS64.");
|
||||
good = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAGS_SET(c->info.lo_flags, LO_FLAGS_PARTSCAN)) {
|
||||
/* Kernel 5.8 vanilla doesn't properly propagate the partition scanning flag into the
|
||||
* block device. Let's hence verify if things work correctly here before
|
||||
* returning. */
|
||||
|
||||
r = blockdev_partscan_enabled(fd);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (r == 0) {
|
||||
log_debug("LOOP_CONFIGURE is broken, doesn't honour LO_FLAGS_PARTSCAN. Falling back to LOOP_SET_STATUS64.");
|
||||
good = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (good)
|
||||
return 0;
|
||||
|
||||
/* Kernel 5.8 vanilla doesn't properly propagate the partition scanning flag into the
|
||||
* block device. Let's hence verify if things work correctly here before returning. */
|
||||
|
||||
r = blockdev_partscan_enabled(fd);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (r > 0)
|
||||
return 0; /* All is good. */
|
||||
|
||||
/* Otherwise, undo the attachment and use the old APIs */
|
||||
(void) ioctl(fd, LOOP_CLR_FD);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue