是否可以将动态增大的文件系统作为文件?

Jay*_*Jay 4 filesystems

我想做一些类似的事情

mkfs -t btrfs filedrive
mount filedrive /media/fuse
Run Code Online (Sandbox Code Playgroud)

在不指定特定大小的情况下,我希望能够在将文件写入已安装的文件系统时使文件增大,并在删除文件时缩小。

这有什么机制吗?


我也看到了这个问题,我知道理论上可以手动管理它,但我的问题与 ecryptfs 无关,而是侧重于自动方面。我并不特别关心文件中的文件系统类型。

我也知道现有系统会做类似的事情:特别是 VirtualBox 的动态磁盘。如果有某种方法可以在不实际运行虚拟机的情况下使用它们 - 或类似于它们的东西 - 我也会对此感到满意。

tel*_*coM 8

实际上,类似的事情已经成为可能

文件系统需要有一个定义的最大大小。但是由于 filesystem-as-file 可以是sparse,因此该大小可以是任意数字,这与 filesystem-as-file 在底层文件系统上占用多少空间没有太大关系。

如果您可以接受为 filesystem-as-file 设置任意最大大小限制(可能比底层文件系统的实际大小大得多),您可以立即在其上创建一个稀疏文件和一个文件系统:

/tmp# df -h .
Filesystem                Size  Used Avail Use% Mounted on
<current filesystem>       20G   16G  3.0G  84% /

/tmp# dd if=/dev/null bs=1 seek=1024000000000 of=testdummy
0+0 records in
0+0 records out
0 bytes copied, 0.000159622 s, 0.0 kB/s
/tmp# ll testdummy
-rw-r--r-- 1 root root 1024000000000 Feb 19 08:24 testdummy
/tmp# ll -h testdummy
-rw-r--r-- 1 root root 954G Feb 19 08:24 testdummy
Run Code Online (Sandbox Code Playgroud)

在这里,我创建了一个文件,它看起来比它存储的文件系统大得多......

/tmp# du -k testdummy
0       testdummy
Run Code Online (Sandbox Code Playgroud)

...但到目前为止,它实际上根本不占用任何磁盘空间(除了 inode 和其他一些元数据)。

完全有可能,在losetup它上面创建一个文件系统并开始使用它。每次将数据实际写入文件的写入操作都会导致文件的空间需求增加。换句话说,虽然报告的文件大小ls -l将始终保持在任意大的数字,但报告的文件在磁盘上占用的实际空间du会增加。

如果您使用discard挂载选项挂载 filesystem-as-file ,收缩也可以自动进行:

/tmp# losetup /dev/loop0 testdummy
/tmp# mkfs.ext4 /dev/loop0
/tmp# mount -o discard /dev/loop0 /mnt
/tmp# du -k testdummy 
1063940 testdummy
/tmp# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0      938G   77M  890G   1% /mnt

/tmp# cp /boot/initrd.img /mnt
/tmp# du -k testdummy 
1093732 testdummy

/tmp# rm /mnt/initrd.img
/tmp# du -k testdummy
1063944 testdummy
Run Code Online (Sandbox Code Playgroud)

自动收缩需要:

1.) filesystem-as-file 的文件系统类型支持discard挂载选项(以便文件系统驱动程序可以告诉底层系统哪些块可以被释放)

2.) 并且底层文件系统的文件系统类型支持“打孔”,即fallocate(2)带有FALLOC_FL_PUNCH_HOLE选项的系统调用(这样底层文件系统可以被告知将文件系统的一些先前分配的块标记为文件再次作为稀疏块)

3.) 并且您正在使用内核版本 3.2 或更高版本,以便循环设备支持具有必要的基础结构。

https://outflux.net/blog/archives/2012/02/15/discard-hole-punching-and-trim/

如果您对较少的立即收缩没有问题,您可以定期fstrim在文件系统作为文件上运行,而不是使用discard挂载选项。如果底层文件系统非常繁忙,避免立即收缩可能有助于最小化底层文件系统的碎片。

这种方法的问题在于,如果底层文件系统已满,就不会得到很好的处理。如果底层文件系统中不再有空间,则文件系统即文件在尝试用实际数据替换稀疏“漏洞”时将开始接收错误,即使文件系统即文件似乎还有一些未使用的容量.