Commit 602a16d5 authored by Daeho Jeong's avatar Daeho Jeong Committed by Jaegeuk Kim
Browse files

f2fs: add compress_mode mount option



We will add a new "compress_mode" mount option to control file
compression mode. This supports "fs" and "user". In "fs" mode (default),
f2fs does automatic compression on the compression enabled files.
In "user" mode, f2fs disables the automaic compression and gives the
user discretion of choosing the target file and the timing. It means
the user can do manual compression/decompression on the compression
enabled files using ioctls.

Signed-off-by: default avatarDaeho Jeong <daehojeong@google.com>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent db489652
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -261,6 +261,13 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
			 Note that, there is one reserved special extension '*', it
			 can be set to enable compression for all files.
compress_chksum		 Support verifying chksum of raw data in compressed cluster.
compress_mode=%s	 Control file compression mode. This supports "fs" and "user"
			 modes. In "fs" mode (default), f2fs does automatic compression
			 on the compression enabled files. In "user" mode, f2fs disables
			 the automaic compression and gives the user discretion of
			 choosing the target file and the timing. The user can do manual
			 compression/decompression on the compression enabled files using
			 ioctls.
inlinecrypt		 When possible, encrypt/decrypt the contents of encrypted
			 files using the blk-crypto framework rather than
			 filesystem-layer encryption. This allows the use of
@@ -811,6 +818,34 @@ Compress metadata layout::
	| data length | data chksum | reserved |      compressed data       |
	+-------------+-------------+----------+----------------------------+

Compression mode
--------------------------

f2fs supports "fs" and "user" compression modes with "compression_mode" mount option.
With this option, f2fs provides a choice to select the way how to compress the
compression enabled files (refer to "Compression implementation" section for how to
enable compression on a regular inode).

1) compress_mode=fs
This is the default option. f2fs does automatic compression in the writeback of the
compression enabled files.

2) compress_mode=user
This disables the automaic compression and gives the user discretion of choosing the
target file and the timing. The user can do manual compression/decompression on the
compression enabled files using F2FS_IOC_DECOMPRESS_FILE and F2FS_IOC_COMPRESS_FILE
ioctls like the below.

To decompress a file,

fd = open(filename, O_WRONLY, 0);
ret = ioctl(fd, F2FS_IOC_DECOMPRESS_FILE);

To compress a file,

fd = open(filename, O_WRONLY, 0);
ret = ioctl(fd, F2FS_IOC_COMPRESS_FILE);

NVMe Zoned Namespace devices
----------------------------

+1 −1
Original line number Diff line number Diff line
@@ -944,7 +944,7 @@ int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)

static bool cluster_may_compress(struct compress_ctx *cc)
{
	if (!f2fs_compressed_file(cc->inode))
	if (!f2fs_need_compress_data(cc->inode))
		return false;
	if (f2fs_is_atomic_file(cc->inode))
		return false;
+1 −1
Original line number Diff line number Diff line
@@ -3147,7 +3147,7 @@ static inline bool __should_serialize_io(struct inode *inode,
	if (IS_NOQUOTA(inode))
		return false;

	if (f2fs_compressed_file(inode))
	if (f2fs_need_compress_data(inode))
		return true;
	if (wbc->sync_mode != WB_SYNC_ALL)
		return true;
+30 −0
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ struct f2fs_mount_info {
	unsigned char compress_log_size;	/* cluster log size */
	bool compress_chksum;			/* compressed data chksum */
	unsigned char compress_ext_cnt;		/* extension count */
	int compress_mode;			/* compression mode */
	unsigned char extensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN];	/* extensions */
};

@@ -677,6 +678,7 @@ enum {
	FI_COMPRESSED_FILE,	/* indicate file's data can be compressed */
	FI_COMPRESS_CORRUPT,	/* indicate compressed cluster is corrupted */
	FI_MMAP_FILE,		/* indicate file was mmapped */
	FI_ENABLE_COMPRESS,	/* enable compression in "user" compression mode */
	FI_MAX,			/* max flag, never be used */
};

@@ -1244,6 +1246,18 @@ enum fsync_mode {
	FSYNC_MODE_NOBARRIER,	/* fsync behaves nobarrier based on posix */
};

enum {
	COMPR_MODE_FS,		/*
				 * automatically compress compression
				 * enabled files
				 */
	COMPR_MODE_USER,	/*
				 * automatical compression is disabled.
				 * user can control the file compression
				 * using ioctls
				 */
};

/*
 * this value is set in page as a private data which indicate that
 * the page is atomically written, and it is in inmem_pages list.
@@ -2759,6 +2773,22 @@ static inline int f2fs_compressed_file(struct inode *inode)
		is_inode_flag_set(inode, FI_COMPRESSED_FILE);
}

static inline bool f2fs_need_compress_data(struct inode *inode)
{
	int compress_mode = F2FS_OPTION(F2FS_I_SB(inode)).compress_mode;

	if (!f2fs_compressed_file(inode))
		return false;

	if (compress_mode == COMPR_MODE_FS)
		return true;
	else if (compress_mode == COMPR_MODE_USER &&
			is_inode_flag_set(inode, FI_ENABLE_COMPRESS))
		return true;

	return false;
}

static inline unsigned int addrs_per_inode(struct inode *inode)
{
	unsigned int addrs = CUR_ADDRS_PER_INODE(inode) -
+1 −1
Original line number Diff line number Diff line
@@ -3261,7 +3261,7 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
			else
				return CURSEG_COLD_DATA;
		}
		if (file_is_cold(inode) || f2fs_compressed_file(inode))
		if (file_is_cold(inode) || f2fs_need_compress_data(inode))
			return CURSEG_COLD_DATA;
		if (file_is_hot(inode) ||
				is_inode_flag_set(inode, FI_HOT_DATA) ||
Loading