Skip to content

Commit 4c8ff70

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: support data compression
This patch tries to support compression in f2fs. - New term named cluster is defined as basic unit of compression, file can be divided into multiple clusters logically. One cluster includes 4 << n (n >= 0) logical pages, compression size is also cluster size, each of cluster can be compressed or not. - In cluster metadata layout, one special flag is used to indicate cluster is compressed one or normal one, for compressed cluster, following metadata maps cluster to [1, 4 << n - 1] physical blocks, in where f2fs stores data including compress header and compressed data. - In order to eliminate write amplification during overwrite, F2FS only support compression on write-once file, data can be compressed only when all logical blocks in file are valid and cluster compress ratio is lower than specified threshold. - To enable compression on regular inode, there are three ways: * chattr +c file * chattr +c dir; touch dir/file * mount w/ -o compress_extension=ext; touch file.ext Compress metadata layout: [Dnode Structure] +-----------------------------------------------+ | cluster 1 | cluster 2 | ......... | cluster N | +-----------------------------------------------+ . . . . . . . . . Compressed Cluster . . Normal Cluster . +----------+---------+---------+---------+ +---------+---------+---------+---------+ |compr flag| block 1 | block 2 | block 3 | | block 1 | block 2 | block 3 | block 4 | +----------+---------+---------+---------+ +---------+---------+---------+---------+ . . . . . . +-------------+-------------+----------+----------------------------+ | data length | data chksum | reserved | compressed data | +-------------+-------------+----------+----------------------------+ Changelog: 20190326: - fix error handling of read_end_io(). - remove unneeded comments in f2fs_encrypt_one_page(). 20190327: - fix wrong use of f2fs_cluster_is_full() in f2fs_mpage_readpages(). - don't jump into loop directly to avoid uninitialized variables. - add TODO tag in error path of f2fs_write_cache_pages(). 20190328: - fix wrong merge condition in f2fs_read_multi_pages(). - check compressed file in f2fs_post_read_required(). 20190401 - allow overwrite on non-compressed cluster. - check cluster meta before writing compressed data. 20190402 - don't preallocate blocks for compressed file. - add lz4 compress algorithm - process multiple post read works in one workqueue Now f2fs supports processing post read work in multiple workqueue, it shows low performance due to schedule overhead of multiple workqueue executing orderly. 20190921 - compress: support buffered overwrite C: compress cluster flag V: valid block address N: NEW_ADDR One cluster contain 4 blocks before overwrite after overwrite - VVVV -> CVNN - CVNN -> VVVV - CVNN -> CVNN - CVNN -> CVVV - CVVV -> CVNN - CVVV -> CVVV 20191029 - add kconfig F2FS_FS_COMPRESSION to isolate compression related codes, add kconfig F2FS_FS_{LZO,LZ4} to cover backend algorithm. note that: will remove lzo backend if Jaegeuk agreed that too. - update codes according to Eric's comments. 20191101 - apply fixes from Jaegeuk 20191113 - apply fixes from Jaegeuk - split workqueue for fsverity 20191216 - apply fixes from Jaegeuk 20200117 - fix to avoid NULL pointer dereference [Jaegeuk Kim] - add tracepoint for f2fs_{,de}compress_pages() - fix many bugs and add some compression stats - fix overwrite/mmap bugs - address 32bit build error, reported by Geert. - bug fixes when handling errors and i_compressed_blocks Reported-by: <noreply@ellerman.id.au> Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 820d366 commit 4c8ff70

File tree

16 files changed

+2566
-117
lines changed

16 files changed

+2566
-117
lines changed

Documentation/filesystems/f2fs.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,17 @@ checkpoint=%s[:%u[%]] Set to "disable" to turn off checkpointing. Set to "en
235235
hide up to all remaining free space. The actual space that
236236
would be unusable can be viewed at /sys/fs/f2fs/<disk>/unusable
237237
This space is reclaimed once checkpoint=enable.
238+
compress_algorithm=%s Control compress algorithm, currently f2fs supports "lzo"
239+
and "lz4" algorithm.
240+
compress_log_size=%u Support configuring compress cluster size, the size will
241+
be 4KB * (1 << %u), 16KB is minimum size, also it's
242+
default size.
243+
compress_extension=%s Support adding specified extension, so that f2fs can enable
244+
compression on those corresponding files, e.g. if all files
245+
with '.ext' has high compression rate, we can set the '.ext'
246+
on compression extension list and enable compression on
247+
these file by default rather than to enable it via ioctl.
248+
For other files, we can still enable compression via ioctl.
238249

239250
================================================================================
240251
DEBUGFS ENTRIES
@@ -840,3 +851,44 @@ zero or random data, which is useful to the below scenario where:
840851
4. address = fibmap(fd, offset)
841852
5. open(blkdev)
842853
6. write(blkdev, address)
854+
855+
Compression implementation
856+
--------------------------
857+
858+
- New term named cluster is defined as basic unit of compression, file can
859+
be divided into multiple clusters logically. One cluster includes 4 << n
860+
(n >= 0) logical pages, compression size is also cluster size, each of
861+
cluster can be compressed or not.
862+
863+
- In cluster metadata layout, one special block address is used to indicate
864+
cluster is compressed one or normal one, for compressed cluster, following
865+
metadata maps cluster to [1, 4 << n - 1] physical blocks, in where f2fs
866+
stores data including compress header and compressed data.
867+
868+
- In order to eliminate write amplification during overwrite, F2FS only
869+
support compression on write-once file, data can be compressed only when
870+
all logical blocks in file are valid and cluster compress ratio is lower
871+
than specified threshold.
872+
873+
- To enable compression on regular inode, there are three ways:
874+
* chattr +c file
875+
* chattr +c dir; touch dir/file
876+
* mount w/ -o compress_extension=ext; touch file.ext
877+
878+
Compress metadata layout:
879+
[Dnode Structure]
880+
+-----------------------------------------------+
881+
| cluster 1 | cluster 2 | ......... | cluster N |
882+
+-----------------------------------------------+
883+
. . . .
884+
. . . .
885+
. Compressed Cluster . . Normal Cluster .
886+
+----------+---------+---------+---------+ +---------+---------+---------+---------+
887+
|compr flag| block 1 | block 2 | block 3 | | block 1 | block 2 | block 3 | block 4 |
888+
+----------+---------+---------+---------+ +---------+---------+---------+---------+
889+
. .
890+
. .
891+
. .
892+
+-------------+-------------+----------+----------------------------+
893+
| data length | data chksum | reserved | compressed data |
894+
+-------------+-------------+----------+----------------------------+

fs/f2fs/Kconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,28 @@ config F2FS_FAULT_INJECTION
9292
Test F2FS to inject faults such as ENOMEM, ENOSPC, and so on.
9393

9494
If unsure, say N.
95+
96+
config F2FS_FS_COMPRESSION
97+
bool "F2FS compression feature"
98+
depends on F2FS_FS
99+
help
100+
Enable filesystem-level compression on f2fs regular files,
101+
multiple back-end compression algorithms are supported.
102+
103+
config F2FS_FS_LZO
104+
bool "LZO compression support"
105+
depends on F2FS_FS_COMPRESSION
106+
select LZO_COMPRESS
107+
select LZO_DECOMPRESS
108+
default y
109+
help
110+
Support LZO compress algorithm, if unsure, say Y.
111+
112+
config F2FS_FS_LZ4
113+
bool "LZ4 compression support"
114+
depends on F2FS_FS_COMPRESSION
115+
select LZ4_COMPRESS
116+
select LZ4_DECOMPRESS
117+
default y
118+
help
119+
Support LZ4 compress algorithm, if unsure, say Y.

fs/f2fs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o
99
f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o
1010
f2fs-$(CONFIG_F2FS_IO_TRACE) += trace.o
1111
f2fs-$(CONFIG_FS_VERITY) += verity.o
12+
f2fs-$(CONFIG_F2FS_FS_COMPRESSION) += compress.o

0 commit comments

Comments
 (0)