aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/util-linux/util-linux/0001-lib-loopdev-fix-loopcxt_check_size-to-work-with-blkd.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/util-linux/util-linux/0001-lib-loopdev-fix-loopcxt_check_size-to-work-with-blkd.patch')
-rw-r--r--meta/recipes-core/util-linux/util-linux/0001-lib-loopdev-fix-loopcxt_check_size-to-work-with-blkd.patch60
1 files changed, 60 insertions, 0 deletions
diff --git a/meta/recipes-core/util-linux/util-linux/0001-lib-loopdev-fix-loopcxt_check_size-to-work-with-blkd.patch b/meta/recipes-core/util-linux/util-linux/0001-lib-loopdev-fix-loopcxt_check_size-to-work-with-blkd.patch
new file mode 100644
index 0000000000..d1093f21ef
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/0001-lib-loopdev-fix-loopcxt_check_size-to-work-with-blkd.patch
@@ -0,0 +1,60 @@
+Upstream-Status: Backport
+Signed-off-by: Jonathan Liu <net147@gmail.com>
+
+From e3b6cb87e0ba1304fa07ec316784de1c6243b28e Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Mon, 13 May 2013 10:54:41 +0200
+Subject: [PATCH] lib/loopdev: fix loopcxt_check_size() to work with blkdevs
+
+The loopcxt_check_size() is workaround for kernels < v3.9, kernel has
+been fixed by commit 541c742a7559eb65f0e36d3e2338c2ca532a3e61.
+
+The function sets loopdev size according to backing file size. The
+problem is that the backing file could be a block device where
+stat.st_size is zero, so we have to use blkdev_get_size() for block
+devices.
+
+Addresses: https://bugs.archlinux.org/task/35193
+Reported-by: Dave Reisner <d@falconindy.com>
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+ lib/loopdev.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/lib/loopdev.c b/lib/loopdev.c
+index c35e306..3b65b5d 100644
+--- a/lib/loopdev.c
++++ b/lib/loopdev.c
+@@ -1097,7 +1097,17 @@ static int loopcxt_check_size(struct loopdev_cxt *lc, int file_fd)
+ if (fstat(file_fd, &st))
+ return -errno;
+
+- expected_size = st.st_size;
++ if (S_ISBLK(st.st_mode)) {
++ if (blkdev_get_size(file_fd,
++ (unsigned long long *) &expected_size))
++ return -errno;
++ } else
++ expected_size = st.st_size;
++
++ if (expected_size == 0 || expected_size <= lc->info.lo_offset) {
++ DBG(lc, loopdev_debug("failed to determine expected size"));
++ return 0; /* ignore this error */
++ }
+
+ if (lc->info.lo_offset > 0)
+ expected_size -= lc->info.lo_offset;
+@@ -1113,6 +1123,10 @@ static int loopcxt_check_size(struct loopdev_cxt *lc, int file_fd)
+ return -errno;
+
+ if (expected_size != size) {
++ DBG(lc, loopdev_debug("warning: loopdev and expected "
++ "size dismatch (%ju/%ju)",
++ size, expected_size));
++
+ if (loopcxt_set_capacity(lc)) {
+ /* ioctl not available */
+ if (errno == ENOTTY || errno == EINVAL)
+--
+1.8.2.3
+