From: Jeff Mahoney <jeffm@suse.com>
To: util-linux@vger.kernel.org
Subject: [PATCH] loopdev: sync capacity after setting it
Date: Fri, 15 Mar 2013 17:04:57 -0400 [thread overview]
Message-ID: <51438CF9.7020707@suse.com> (raw)
I recently tried to mount an hfsplus file system from an image file with
a partition table by using the loop offset and sizelimit options to specify
the location of the file system.
hfsplus stores some metadata at a set offset from the end of the partition,
so it's sensitive to the device size reported by the kernel.
It worked with this:
# losetup -r -o 32k --sizelimit=102400000 <loopdev> <imagefile>
# mount -r -t hfsplus <loopdev> <mountpoint>
But failed with this:
# mount -r -oloop,offset=32k,sizelimit=102400000 <imagefile> <mountpoint>
# losetup -a
/dev/loop0: [0089]:2 (<imagefile>), offset 32768, sizelimit 102400000
/dev/loop1: [0089]:2 (<imagefile>), offset 32768, sizelimit 102400000
/proc/partitions shows the correct number of blocks to match the sizelimit.
But if I set a breakpoint in mount before the mount syscall, I could see:
# blockdev --getsize64 /dev/loop[01]
102400000
102432768
The kernel loop driver will set the gendisk capacity of the device at
LOOP_SET_STATUS64 but won't sync it to the block device until one of two
conditions are met: All open file descriptors referring to the device are
closed (and it will sync when re-opened) or if the LOOP_SET_CAPACITY ioctl
is called to sync it. Since mount opens the device and passes it directly
to the mount syscall after LOOP_SET_STATUS64 without closing and reopening
it, the sizelimit argument is effectively ignroed. The capacity needs to
be synced immediately for it to work as expected.
This patch adds the LOOP_SET_CAPACITY call to loopctx_setup_device since
the device isn't yet released to the user, so it's safe to sync the capacity
immediately.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
lib/loopdev.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/lib/loopdev.c
+++ b/lib/loopdev.c
@@ -1105,6 +1105,18 @@ int loopcxt_setup_device(struct loopdev_
goto err;
}
+ /*
+ * mount passes the file descriptor without closing it, so
+ * the capacity isn't updated automatically. File systems
+ * won't see the new size if it's not the full size of
+ * the backing file.
+ */
+ if ((lc->info.lo_offset || lc->info.lo_sizelimit) &&
+ ioctl(dev_fd, LOOP_SET_CAPACITY, 0)) {
+ DBG(lc, loopdev_debug("LOOP_SET_CAPACITY failed: %m"));
+ goto err;
+ }
+
DBG(lc, loopdev_debug("setup: LOOP_SET_STATUS64: OK"));
memset(&lc->info, 0, sizeof(lc->info));
--
Jeff Mahoney
SUSE Labs
next reply other threads:[~2013-03-15 21:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-15 21:04 Jeff Mahoney [this message]
2013-03-17 14:18 ` [PATCH] loopdev: sync capacity after setting it Jeff Mahoney
2013-03-18 9:27 ` Karel Zak
2013-03-18 13:05 ` Jeff Mahoney
2013-03-18 13:18 ` Karel Zak
2013-03-27 20:45 ` [PATCH v2] " Jeff Mahoney
2013-04-09 12:39 ` Karel Zak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51438CF9.7020707@suse.com \
--to=jeffm@suse.com \
--cc=util-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.