]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
loop-util: work around cache invalidation bug in older kernels 21044/head
authorLennart Poettering <lennart@poettering.net>
Mon, 18 Oct 2021 20:34:54 +0000 (22:34 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 19 Oct 2021 13:38:21 +0000 (15:38 +0200)
Inspired by the discussions in #21003.

Inspired in particular by what Android apexd does:

https://android.googlesource.com/platform/system/apex/+/refs/heads/master/apexd/apexd_loop.cpp

src/shared/loop-util.c

index dbd02663901ef2bf954597a02248de5b4b96f282..072acc8c4735733707312c0c947d7dc06ecafbea 100644 (file)
@@ -326,6 +326,21 @@ static int loop_configure(
                               random_u64_range(UINT64_C(240) * USEC_PER_MSEC * n_attempts/64));
         }
 
+        /* Work around a kernel bug, where changing offset/size of the loopback device doesn't correctly
+         * invalidate the buffer cache. For details see:
+         *
+         *     https://android.googlesource.com/platform/system/apex/+/bef74542fbbb4cd629793f4efee8e0053b360570
+         *
+         * This was fixed in kernel 5.0, see:
+         *
+         *     https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5db470e229e22b7eda6e23b5566e532c96fb5bc3
+         *
+         * We'll run the work-around here in the legacy LOOP_SET_STATUS64 codepath. In the LOOP_CONFIGURE
+         * codepath above it should not be necessary. */
+        if (c->info.lo_offset != 0 || c->info.lo_sizelimit != 0)
+                if (ioctl(fd, BLKFLSBUF, 0) < 0)
+                        log_debug_errno(errno, "Failed to issue BLKFLSBUF ioctl, ignoring: %m");
+
         /* LO_FLAGS_DIRECT_IO is a flags we need to configure via explicit ioctls. */
         if (FLAGS_SET(c->info.lo_flags, LO_FLAGS_DIRECT_IO)) {
                 unsigned long b = 1;