Skip to main content

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

9
  • 2
    Thanks for your answer. I'm aware tmpfs supports sparse files and punch_hole. That's what makes it so confusing - tmpfs supports this, so why go and fill the sparse holes when reading through a loop device? losetup doesn't change the file size, but it creates a block device, which on most systems is then scanned for content like: is there a partition table? is there a filesystem with UUID? should I create a /dev/disk/by-uuid/ symlink then? And those reads already cause parts of the sparse file to be allocated, because for some mysterious reason, tmpfs fills holes on (some) reads. Commented Sep 20, 2018 at 18:12
  • 2
    Can you clarify "sequential reading is going to (in some situations) cause a copy on write like operation", please? I'm curious to understand how a read operation would trigger a copy on write action. Thanks! Commented Sep 20, 2018 at 18:12
  • This is odd. On my system I followed the same steps, though manually and not in a script. First I did a 100M file just like the OP. Then I repeated the steps with only a 10MB file. First result : ls -s sparse100M was 102400. But ls -s on the 10MB file was only 328 blocks. ?? Commented Sep 21, 2018 at 5:16
  • 1
    @PatrickTaylor ~328K is about what's used after the UUID scanners came by, but you didn't cat / md5sum the loop device for a full read. Commented Sep 21, 2018 at 10:53
  • 1
    I was digging through the source for the loop kernel module (in loop.c) and saw that there are two relevant functions: lo_read_simple & lo_read_transfer. There are some minor differences in how they do low level memory allocation... lo_read_transfer is actually requesting non-blocking io from slab.h (GFP_NOIO) while performing a alloc_page() call. lo_read_simple() on the other hand is not performing alloc_page(). Commented Sep 21, 2018 at 19:23