diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/loop-util.c | 13 | ||||
-rw-r--r-- | src/shared/loop-util.h | 4 |
2 files changed, 14 insertions, 3 deletions
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 8be4dbf938..047e213634 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -129,7 +129,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) { if (d->fd >= 0) { - if (d->nr >= 0) { + if (d->nr >= 0 && !d->relinquished) { if (ioctl(d->fd, LOOP_CLR_FD) < 0) log_debug_errno(errno, "Failed to clear loop device: %m"); @@ -138,7 +138,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) { safe_close(d->fd); } - if (d->nr >= 0) { + if (d->nr >= 0 && !d->relinquished) { _cleanup_close_ int control = -1; control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK); @@ -155,3 +155,12 @@ LoopDevice* loop_device_unref(LoopDevice *d) { return NULL; } + +void loop_device_relinquish(LoopDevice *d) { + assert(d); + + /* Don't attempt to clean up the loop device anymore from this point on. Leave the clean-ing up to the kernel + * itself, using the loop device "auto-clear" logic we already turned on when creating the device. */ + + d->relinquished = true; +} diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h index 5c847c4ac3..45fead5f18 100644 --- a/src/shared/loop-util.h +++ b/src/shared/loop-util.h @@ -29,11 +29,13 @@ struct LoopDevice { int fd; int nr; char *node; + bool relinquished; }; int loop_device_make(int fd, int open_flags, LoopDevice **ret); int loop_device_make_by_path(const char *path, int open_flags, LoopDevice **ret); LoopDevice* loop_device_unref(LoopDevice *d); - DEFINE_TRIVIAL_CLEANUP_FUNC(LoopDevice*, loop_device_unref); + +void loop_device_relinquish(LoopDevice *d); |