aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/util-linux/util-linux/0001-lib-loopdev-fix-loopcxt_check_size-to-work-with-blkd.patch
blob: d1093f21eff811144a869b0c2d6d175dd50cdfd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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