Re: filesystem inside a file using loop device.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Hi Sergei,
>      Thank you for ur explanation.. Please find my doubts inline...
> 
> 2009/1/4 Sergei Trofimovich <slyfox@xxxxxxxx>:
> > On Sun, 4 Jan 2009 18:39:10 +0530
> > "Paraneetharan Chandrasekaran" <paraneetharanc@xxxxxxxxx> wrote:
> >
> >> Hi All,
> >>          I created a file of 10 MB from /dev/zero using dd command.
> >> Then i associated /dev/loop0 to that file using losetup command. Then
> >> i created an ext2 filesystem above /dev/loop0 using mke2fs command.
> >> Then i mounted the that loop device in a mount point. I entered the
> >> monted directiry and created on file and entered some contents to that
> >> file. Then i came out of the directory. Then i deleted the file i
> >> associated. Then If i go inside the mounted directory, i was able
> >> change the directory and the file was there with the contents i put.
> >>
> >> how is that possible when deleted the file itself inside which i
> >> created the ext2 filesystem..?  I was previously thinking that the VFS
> >> reads from the file itself for files and directory info. is it not
> >> like that..? I have even cleared the buffers after i deleted the
> >> file(using sync).
> >

To clarify:
All the stuff below is about deleting image file (loopback backend)

> > When you unlink file - directory entry(dentry) is deleted from directory
> > structure immediately (metadata operation). So you can't open deleted file by it's old _name_.
> >
> > Inode (structure, holding info about physical blocks belonging to associated file) is
> > deleted when there is no more references to it.
> >
> > References can be:
> >  * on disk (hard links)
> >  * in-memory descriptors (files currently opened by process(es))
> >
> > Thus you can safely use code like this:
> > ...
> >    char tmpl[] = "/tmp/tmp.XXXXXXXX"
> >    int fd = mkstemp (tmpl); /* create inode and dentry */
> >    (assert fd != -1);
> >    unlink(tmpl);                   /* delete dentry */
> >
> >    /*
> >      * Do something with fd: read/write
> >      */
> >
> >      close(fd);                     /* delete inode */
> > ...
> >
> > Moreover, you can get access to this (deleted) file until process exits or closes file.
> >
> > You could play with it (prompt 1 emulates losetup, prompt 2 emulates your actions):
> > prompt1$ cat > /tmp/z
> >               FOO
> >               BAR
> >             <leave it running>
> > prompt2$ rm /tmp/z
> >             $ls -l /proc/*/fd/* 2>/dev/null | grep /tmp/z
> >               l-wx------ 1 slyfox slyfox 64 Янв  4 18:39 /proc/22665/fd/1 -> /tmp/z (deleted)
> >             $ cat /proc/22665/fd/1
> >               FOO
> >               BAR
> >
> > But!.
> >
> > My examples are userspace reference holders and they are visible via /proc/*/fd,
> > losetup (or mount -o loop), in contrast,  increments reference count
> > to associated file differently - via ioctl() call.
>           Does this mean loop device driver is holding another
> reference in kernel space..?

We can always have a look at kernel source:
We are interested in LOOP_SET_FD ioctl command.
Source is in linux/drivers/block/loop.c : loop_set_fd() function

There we see 'file * file', which stores info about our image backend file.
start of loop_set_fd() contains:
file = fget(arg); // acquires one more reference to file

    fget() source is in linux/fs/file_table.c.
        It looks up file structure by supplied into IOCTL file descriptor and increments reference counter.

  Then 'file * f' is stored into 'loop_device * lo' (associates file with /dev/loop) and 
_setups_file_as_real_block_device_source_(we will need to know it :]) ... we don't care :]

So yes, You are absolutely right. Kernel increments reference counter in loop driver.

> >
> > You can observe dark magic by `strace'ing losetup command:
> >
> > # strace losetup /dev/loop0 /etc/fstab
> > ....
> > open("/etc/fstab", O_RDWR|O_LARGEFILE)  = 3
> > open("/dev/loop0", O_RDWR|O_LARGEFILE)  = 4
> > ....
> > ioctl(4, 0x4c00, 0x3)                   = 0 // ahha, that's it! We ask kernel to do something nasty with this descriptor
> > close(3)                                = 0
> > ioctl(4, 0x4c04, 0xbf9c0624)            = 0 // and here too
> > close(4)                                = 0
> > ....
> > /usr/include/linux/loop.h:#define LOOP_SET_FD            0x4C00
> > /usr/include/linux/loop.h:#define LOOP_SET_STATUS64      0x4C04
> >
> > So, your ext image file will be deleted right after you supply losetup -d /dev/loop0 (or umount)
> > Before this action you can play with /dev/loop .
> >
>         I found an another observation too. Now i dint delete the
> image file.. I opened the image file and searched for the contents i
> put in that newly created file.. It was there in some corner.. Then i
> closed the image file by ":q".. Then i added some more data in the
> newly created file... Then i came back to the image file and searched
> whether the newly added contents have reflected here or not.. Of
> course, the newly added contents and old contents were in that image
> file.. Then i was  happy and closed by the image file by ":wq"..
> 
> Then i entered into the mounted directory and opened the file i
> created.. I again entered some other contents. Then i came back to the
> image file and opened it.. The changes are no longer there.. I again
> and again added new contents in the file inside mount point.. The
> changes were no longer in the image file.. But all the newly added
> contents were not go into the air as i was able to see them in the
> file inside the mounted directory forever..
> 
> summary: When the image file is closed with ":wq", the chages made in
> the file inside mounted dir are no longer reflected. But the changes
> and new additions are retained in the file inside mountpoint. where do
> the contents are coming from..? and why this loop association goes
> away when i close it with ":wq" ( writing in the iamge file des)?

When you deal with filesystems on slow and latent block devices, you need some sort of cache
in operating system. This cache holds recently used and soon-to-be-used (detected by IO
scheduler heuristics) parts of block device in memory and sometimes (not right after users
have made something on stacked filesystem) _reads_ and _writes_ new blocks  to satisfy user's needs
(I suspect pdflush kernel thread in this). Cache is also flushed to block dev(our image) when You try
to free block device (losetup -d).

There is yet fsync program to write changes from cache to block device (almost) instantly.
I think You could observe Your later changes by running fsync after each file modifications.

> Thanks,
> Paraneetharan C

-- 

  Sergei

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux