Trước hết bạn không đơn độc trong việc đánh đố về các loại vấn đề này.
Điều này không chỉ giới hạn tmpfs
mà còn là mối quan tâm được trích dẫn với
NFSv4 .
Nếu một ứng dụng đọc 'lỗ' trong một tệp thưa thớt, hệ thống tệp sẽ chuyển đổi các khối trống thành các khối "thực" chứa đầy số không và trả chúng về ứng dụng.
Khi md5sum
cố gắng quét một tệp, nó rõ ràng chọn thực hiện việc này
theo thứ tự tuần tự , điều này rất có ý nghĩa dựa trên những gì md5sum đang cố gắng thực hiện.
Vì có những "lỗ hổng" cơ bản trong tệp, việc đọc tuần tự này sẽ xảy ra (trong một số trường hợp) gây ra một bản sao trên thao tác ghi giống như điền vào tệp. Điều này sau đó đi vào một vấn đề sâu hơn xung quanh việc có được fallocate()
triển khai trong hệ thống tập tin hay khôngFALLOC_FL_PUNCH_HOLE
.
May mắn thay, không chỉ tmpfs
hỗ trợ điều này mà còn có một cơ chế để "đào" các lỗ hổng ra ngoài.
Sử dụng tiện ích CLI, fallocate
chúng ta có thể phát hiện và đào lại những lỗ hổng này thành công.
Theo man 1 fallocate
:
-d, --dig-holes
Detect and dig holes. This makes the file sparse in-place, without
using extra disk space. The minimum size of the hole depends on
filesystem I/O block size (usually 4096 bytes). Also, when using
this option, --keep-size is implied. If no range is specified by
--offset and --length, then the entire file is analyzed for holes.
You can think of this option as doing a "cp --sparse" and then
renaming the destination file to the original, without the need for
extra disk space.
See --punch-hole for a list of supported filesystems.
fallocate
hoạt động ở cấp độ tập tin mặc dù và khi bạn đang chạy md5sum
trên một thiết bị khối (yêu cầu đọc tuần tự) bạn đang vấp vào khoảng cách chính xác giữa cách tòa nhà fallocate()
nên hoạt động. Chúng ta có thể thấy điều này trong hành động:
Trong thực tế, sử dụng ví dụ của bạn, chúng tôi thấy như sau:
$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ONTGAS8L06
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ONTGAS8L06/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ sudo md5sum /dev/loop0
2f282b84e7e608d5852449ed940bfc51 /dev/loop0
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 102400 /tmp/tmp.ONTGAS8L06/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ONTGAS8L06/sparse100M
Bây giờ ... đó là câu trả lời cho câu hỏi cơ bản của bạn. Phương châm chung của tôi là "trở nên kỳ lạ" vì vậy tôi đã đào sâu thêm ...
$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ZcAxvW32GY
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 516 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 512 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
Bạn thấy rằng chỉ đơn thuần là hành động thực hiện các losetup
thay đổi kích thước của tập tin thưa thớt. Vì vậy, điều này trở thành một sự kết hợp thú vị của nơi tmpfs
, cơ chế HOLE_PUNCH fallocate
và các thiết bị khối giao nhau.