Bug 730266 - losetup -a does not show devices in use if backing file is < 512 bytes
Summary: losetup -a does not show devices in use if backing file is < 512 bytes
Keywords:
Status: CLOSED NEXTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: util-linux
Version: 15
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Karel Zak
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 730272
TreeView+ depends on / blocked
 
Reported: 2011-08-12 10:21 UTC by Daniel Berrangé
Modified: 2012-06-12 13:51 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 730272 (view as bug list)
Environment:
Last Closed: 2012-06-12 13:51:44 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Daniel Berrangé 2011-08-12 10:21:32 UTC
Description of problem:

If you attach a loop device to a backing file which is less than 512 bytes in length, then losetup -a will not show the loop device as being in use. It certainly *is* in use, however, since attempting to attach to the invisible devices results in EBUSY

Create some files of various sizes:

# touch one
# dd if=/dev/zero of=two count=1 bs=511
1+0 records in
1+0 records out
511 bytes (511 B) copied, 8.128e-05 s, 6.3 MB/s
# dd if=/dev/zero of=three count=1 bs=512
1+0 records in
1+0 records out
512 bytes (512 B) copied, 6.9564e-05 s, 7.4 MB/s

Attach them to loop devices:

# for i in one two three ; do losetup -f  $i ; done

See what is claimed to be in use

# losetup -a
/dev/loop2: [fd00]:3174665 (/root/three)


Test what is actually in use:

# dd if=/dev/zero of=four count=1 bs=512
1+0 records in
1+0 records out
512 bytes (512 B) copied, 9.1725e-05 s, 5.6 MB/s

# losetup /dev/loop0 four
losetup: /dev/loop0: device is busy

# losetup /dev/loop1 four
losetup: /dev/loop1: device is busy


Release the devices that losetup claims are not actually in use

# losetup -d /dev/loop0
# losetup -d /dev/loop1


Version-Release number of selected component (if applicable):
util-linux-2.19.1-1.fc15.x86_64

How reproducible:
Always for files < 512 bytes in length

Steps to Reproduce:
See above

Comment 1 Karel Zak 2011-08-12 19:07:22 UTC
I know about this problem.

The losetup(8) uses the /proc/partitions file to get list of the devices, unfortunately this file contains only devices bigger than 1KiB... yeah, kernel sucks.

The solution is to scan /sys/block/loopN.

Comment 2 Kay Sievers 2011-08-12 19:55:10 UTC
I suspect that:
  bd_set_size(bdev, size << 9);
in:
  drivers/block/loop.c
should round up to the next sector.

I guess a 600 bytes big loop device is only 512 bytes in size too?

Comment 3 Kay Sievers 2011-08-13 15:17:32 UTC
The kernel needs to round down to the next full 512 bytes block. If the
entire file is smaller than 512, the size of the volume will be 0, which
is expected behavior. If the kernel wouldn't do that, it would need to
pad stuff with \0 on read and write on the last unaligned block.

Talked to Tejun, we think that losetup should always truncate the size
at 512 bytes boundaries. And possibly even warn if the filesize is not
aligned to sector boundaries, as the trailing bytes that are smaller than
a sector will be ignored by the kernel. Even when the loop device is zeroed
out, the file might still contain garbage at the end after that.

Loop has blockdevice semantics, so there is nothing really the kernel can
do with the last bytes of the files that don't fit into a 512 bytes sector.
So losetup should probably inform the user that the remainder of the file
is ignored by the kernel, and that this might not be what it was asked for.

Having a file < 512 bytes makes no sense for a blockdevice mapping. The loop
device can not be read or write, we can only handle full blocks. That the
kernel allows that is questionable, but we think that losetup should
already check these values at device setup.

Comment 4 Daniel Berrangé 2011-08-14 03:46:27 UTC
If losetup wants to warn, or even refuse, to attach files < 512 bytes in size that'd be fine. I didn't intentionally want a < 512 byte file - it was a total mistake :-)

In the particular scenario I originally encountered this problem with though, I was doing the ioctl()s to attach the (mistakenly zero length) file to the loop device directly from libvirt, and then wondering why 'losetup -a' didn't show them. So it would still be desirable to find a way to get 'losetup -a' to report such files, or for the kernel itself to refuse to allow it.

Comment 5 Karel Zak 2011-08-15 08:41:07 UTC
(In reply to comment #3)
> Having a file < 512 bytes makes no sense for a blockdevice mapping. The loop
> device can not be read or write, we can only handle full blocks. That the
> kernel allows that is questionable

There is possible to modify the device capacity. I can imagine scenario when you associate an empty file (or set sizelimit=0) and later modify the size by LOOP_SET_CAPACITY ioctl.

> but we think that losetup should
> already check these values at device setup.

I'll add the warning about misaligned or too small sizes to losetup(1). The stupid thing is that the empty loopdev is not in /proc/partitions, so if we want to support this crazy feature then we have to _scan_ /sys/block/ :-(

Comment 6 Karel Zak 2012-06-12 13:51:44 UTC
Fixed by upstream commit e4062c72d1733b0b99ed1c6269c996d6194e869b (new version scans /sys/block). 

Not urgen issue, Fedora package will be updated after upgrade to the new upstream version.


Note You need to log in before you can comment on or make changes to this bug.