2020-11-17 04:04:21

by Daeho Jeong

[permalink] [raw]
Subject: [PATCH 1/2] f2fs: add disable_auto_compr mount option

From: Daeho Jeong <[email protected]>

We will add a new disable_auto_compr mount option to turn off the
automaic compression on the compression enabled file, in order to
give discretion of choosing the target file and the timing of
compression to the user.

Signed-off-by: Daeho Jeong <[email protected]>
---
Documentation/filesystems/f2fs.rst | 4 ++++
fs/f2fs/data.c | 10 +++++-----
fs/f2fs/f2fs.h | 8 ++++++++
fs/f2fs/segment.c | 2 +-
fs/f2fs/super.c | 9 +++++++++
5 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
index b8ee761c9922..c36ca1e0f7ab 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -260,6 +260,10 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
For other files, we can still enable compression via ioctl.
Note that, there is one reserved special extension '*', it
can be set to enable compression for all files.
+disable_auto_compr Even if compression feature is enabled, this option can
+ disable automaic compression on the compression enabled
+ file to give discretion of choosing the target file and
+ the timing of compression to the user.
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
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index c31ec408bd4f..414c8370ab7e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2896,7 +2896,7 @@ static int f2fs_write_data_page(struct page *page,
if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
goto out;

- if (f2fs_compressed_file(inode)) {
+ if (f2fs_need_compress_write(inode)) {
if (f2fs_is_compressed_cluster(inode, page->index)) {
redirty_page_for_writepage(wbc, page);
return AOP_WRITEPAGE_ACTIVATE;
@@ -2988,7 +2988,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
readd:
need_readd = false;
#ifdef CONFIG_F2FS_FS_COMPRESSION
- if (f2fs_compressed_file(inode)) {
+ if (f2fs_need_compress_write(inode)) {
ret = f2fs_init_compress_ctx(&cc);
if (ret) {
done = 1;
@@ -3067,7 +3067,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
goto continue_unlock;

#ifdef CONFIG_F2FS_FS_COMPRESSION
- if (f2fs_compressed_file(inode)) {
+ if (f2fs_need_compress_write(inode)) {
get_page(page);
f2fs_compress_ctx_add_page(&cc, page);
continue;
@@ -3120,7 +3120,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
}
#ifdef CONFIG_F2FS_FS_COMPRESSION
/* flush remained pages in compress cluster */
- if (f2fs_compressed_file(inode) && !f2fs_cluster_is_empty(&cc)) {
+ if (f2fs_need_compress_write(inode) && !f2fs_cluster_is_empty(&cc)) {
ret = f2fs_write_multi_pages(&cc, &submitted, wbc, io_type);
nwritten += submitted;
wbc->nr_to_write -= submitted;
@@ -3162,7 +3162,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_write(inode))
return true;
if (wbc->sync_mode != WB_SYNC_ALL)
return true;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index a33c90cf979b..c473c78699bc 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -99,6 +99,7 @@ extern const char *f2fs_fault_name[FAULT_MAX];
#define F2FS_MOUNT_DISABLE_CHECKPOINT 0x02000000
#define F2FS_MOUNT_NORECOVERY 0x04000000
#define F2FS_MOUNT_ATGC 0x08000000
+#define F2FS_MOUNT_DISABLE_AUTO_COMPR 0x10000000

#define F2FS_OPTION(sbi) ((sbi)->mount_opt)
#define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
@@ -2838,6 +2839,13 @@ static inline int f2fs_compressed_file(struct inode *inode)
is_inode_flag_set(inode, FI_COMPRESSED_FILE);
}

+static inline int f2fs_need_compress_write(struct inode *inode)
+{
+ if (test_opt(F2FS_I_SB(inode), DISABLE_AUTO_COMPR))
+ return 0;
+ return f2fs_compressed_file(inode);
+}
+
static inline unsigned int addrs_per_inode(struct inode *inode)
{
unsigned int addrs = CUR_ADDRS_PER_INODE(inode) -
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index a0d7a7e04bc7..f56a8b6bbee7 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3245,7 +3245,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_write(inode))
return CURSEG_COLD_DATA;
if (file_is_hot(inode) ||
is_inode_flag_set(inode, FI_HOT_DATA) ||
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 5bb523bf32a6..909c1543b282 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -146,6 +146,7 @@ enum {
Opt_compress_algorithm,
Opt_compress_log_size,
Opt_compress_extension,
+ Opt_disable_auto_compr,
Opt_atgc,
Opt_err,
};
@@ -214,6 +215,7 @@ static match_table_t f2fs_tokens = {
{Opt_compress_algorithm, "compress_algorithm=%s"},
{Opt_compress_log_size, "compress_log_size=%u"},
{Opt_compress_extension, "compress_extension=%s"},
+ {Opt_disable_auto_compr, "disable_auto_compr"},
{Opt_atgc, "atgc"},
{Opt_err, NULL},
};
@@ -934,10 +936,14 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
F2FS_OPTION(sbi).compress_ext_cnt++;
kfree(name);
break;
+ case Opt_disable_auto_compr:
+ set_opt(sbi, DISABLE_AUTO_COMPR);
+ break;
#else
case Opt_compress_algorithm:
case Opt_compress_log_size:
case Opt_compress_extension:
+ case Opt_disable_auto_compr:
f2fs_info(sbi, "compression options not supported");
break;
#endif
@@ -1511,6 +1517,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
seq_printf(seq, ",compress_extension=%s",
F2FS_OPTION(sbi).extensions[i]);
}
+
+ if (test_opt(sbi, DISABLE_AUTO_COMPR))
+ seq_puts(seq, ",disable_auto_compr");
}

static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
--
2.29.2.299.gdc1121823c-goog


2020-11-17 04:06:03

by Daeho Jeong

[permalink] [raw]
Subject: [PATCH 2/2] f2fs: add F2FS_IOC_DECOMPRESS_FILE and F2FS_IOC_COMPRESS_FILE

From: Daeho Jeong <[email protected]>

Added two ioctl to decompress/compress explicitly the compression
enabled file in disable_auto_compr mount option.

Using these two ioctls, the users can make a control of compression
and decompression of their files.

Signed-off-by: Daeho Jeong <[email protected]>
---
fs/f2fs/f2fs.h | 10 ++-
fs/f2fs/file.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index c473c78699bc..0dd3be63ac66 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -436,6 +436,8 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal,
struct f2fs_sectrim_range)
#define F2FS_IOC_GET_COMPRESS_OPTION _IOR(F2FS_IOCTL_MAGIC, 21, \
struct f2fs_comp_option)
+#define F2FS_IOC_DECOMPRESS_FILE _IO(F2FS_IOCTL_MAGIC, 23)
+#define F2FS_IOC_COMPRESS_FILE _IO(F2FS_IOCTL_MAGIC, 24)

/*
* should be same as XFS_IOC_GOINGDOWN.
@@ -762,6 +764,8 @@ enum {
FI_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
FI_COMPRESSED_FILE, /* indicate file's data can be compressed */
FI_MMAP_FILE, /* indicate file was mmapped */
+ FI_FORCE_UNCOMPRESS, /* indicate forcing to disable file compression */
+ FI_FORCE_COMPRESS, /* indicate forcing file compression */
FI_MAX, /* max flag, never be used */
};

@@ -2841,7 +2845,11 @@ static inline int f2fs_compressed_file(struct inode *inode)

static inline int f2fs_need_compress_write(struct inode *inode)
{
- if (test_opt(F2FS_I_SB(inode), DISABLE_AUTO_COMPR))
+ if (is_inode_flag_set(inode, FI_FORCE_UNCOMPRESS))
+ return 0;
+ else if (is_inode_flag_set(inode, FI_FORCE_COMPRESS))
+ return 1;
+ else if (test_opt(F2FS_I_SB(inode), DISABLE_AUTO_COMPR))
return 0;
return f2fs_compressed_file(inode);
}
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index bd52df84219d..1e7ff96d7c6e 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -3963,6 +3963,182 @@ static int f2fs_ioc_get_compress_option(struct file *filp, unsigned long arg)
return 0;
}

+static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page;
+ pgoff_t redirty_idx = page_idx;
+ int i, page_len = 0, ret = 0;
+
+ page_cache_readahead_unbounded(mapping, NULL, page_idx, len, 0);
+
+ for (i = 0; i < len; i++, page_idx++) {
+ page = read_cache_page(mapping, page_idx, NULL, NULL);
+ if (IS_ERR(page)) {
+ ret = PTR_ERR(page);
+ f2fs_warn(sbi, "%s: inode (%lu) : page_index (%lu) "
+ "couldn't be read (errno:%d).\n",
+ __func__, inode->i_ino, page_idx, ret);
+ break;
+ }
+ page_len++;
+ }
+
+ for (i = 0; i < page_len; i++, redirty_idx++) {
+ page = find_lock_page(mapping, redirty_idx);
+ if (!page) {
+ ret = -ENOENT;
+ f2fs_warn(sbi, "%s: inode (%lu) : page_index (%lu) "
+ "couldn't be found (errno:%d).\n",
+ __func__, inode->i_ino, redirty_idx, ret);
+ }
+ set_page_dirty(page);
+ f2fs_put_page(page, 1);
+ f2fs_put_page(page, 0);
+ }
+
+ return ret;
+}
+
+static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
+{
+ struct inode *inode = file_inode(filp);
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ pgoff_t page_idx = 0, last_idx;
+ int cluster_size = F2FS_I(inode)->i_cluster_size;
+ int count, ret;
+
+ if (!f2fs_sb_has_compression(sbi))
+ return -EOPNOTSUPP;
+
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EBADF;
+
+ if (!f2fs_compressed_file(inode))
+ return -EINVAL;
+
+ f2fs_balance_fs(F2FS_I_SB(inode), true);
+
+ file_start_write(filp);
+ inode_lock(inode);
+
+ if (f2fs_is_mmap_file(inode)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ if (ret)
+ goto out;
+
+ if (!F2FS_I(inode)->i_compr_blocks)
+ goto out;
+
+ set_inode_flag(inode, FI_FORCE_UNCOMPRESS);
+
+ last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+
+ count = last_idx - page_idx;
+ while (count) {
+ int len = min(cluster_size, count);
+
+ ret = redirty_blocks(inode, page_idx, len);
+
+ if (ret < 0)
+ break;
+
+ page_idx += len;
+ count -= len;
+ }
+
+ if (!ret)
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0,
+ LLONG_MAX);
+
+ clear_inode_flag(inode, FI_FORCE_UNCOMPRESS);
+
+ if (!ret) {
+ stat_sub_compr_blocks(inode, F2FS_I(inode)->i_compr_blocks);
+ F2FS_I(inode)->i_compr_blocks = 0;
+ f2fs_mark_inode_dirty_sync(inode, true);
+ } else {
+ f2fs_warn(sbi, "%s: The file might be partially decompressed "
+ "(errno=%d). Please delete the file.\n",
+ __func__, ret);
+ }
+out:
+ inode_unlock(inode);
+ file_end_write(filp);
+
+ return ret;
+}
+
+static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
+{
+ struct inode *inode = file_inode(filp);
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ pgoff_t page_idx = 0, last_idx;
+ int cluster_size = F2FS_I(inode)->i_cluster_size;
+ int count, ret;
+
+ if (!f2fs_sb_has_compression(sbi))
+ return -EOPNOTSUPP;
+
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EBADF;
+
+ if (!f2fs_compressed_file(inode))
+ return -EINVAL;
+
+ f2fs_balance_fs(F2FS_I_SB(inode), true);
+
+ file_start_write(filp);
+ inode_lock(inode);
+
+ if (f2fs_is_mmap_file(inode)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ if (ret)
+ goto out;
+
+ set_inode_flag(inode, FI_FORCE_COMPRESS);
+
+ last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+
+ count = last_idx - page_idx;
+ while (count) {
+ int len = min(cluster_size, count);
+
+ ret = redirty_blocks(inode, page_idx, len);
+
+ if (ret < 0)
+ break;
+
+ page_idx += len;
+ count -= len;
+ }
+
+ if (!ret)
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0,
+ LLONG_MAX);
+
+ clear_inode_flag(inode, FI_FORCE_COMPRESS);
+
+ if (ret)
+ f2fs_warn(sbi, "%s: The file might be partially compressed "
+ "(errno=%d). Please delete the file.\n",
+ __func__, ret);
+out:
+ inode_unlock(inode);
+ file_end_write(filp);
+
+ return ret;
+}
+
long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp)))))
@@ -4053,6 +4229,10 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return f2fs_sec_trim_file(filp, arg);
case F2FS_IOC_GET_COMPRESS_OPTION:
return f2fs_ioc_get_compress_option(filp, arg);
+ case F2FS_IOC_DECOMPRESS_FILE:
+ return f2fs_ioc_decompress_file(filp, arg);
+ case F2FS_IOC_COMPRESS_FILE:
+ return f2fs_ioc_compress_file(filp, arg);
default:
return -ENOTTY;
}
@@ -4224,6 +4404,8 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case F2FS_IOC_RESERVE_COMPRESS_BLOCKS:
case F2FS_IOC_SEC_TRIM_FILE:
case F2FS_IOC_GET_COMPRESS_OPTION:
+ case F2FS_IOC_DECOMPRESS_FILE:
+ case F2FS_IOC_COMPRESS_FILE:
break;
default:
return -ENOIOCTLCMD;
--
2.29.2.299.gdc1121823c-goog

2020-11-17 04:18:40

by Eric Biggers

[permalink] [raw]
Subject: Re: [f2fs-dev] [PATCH 1/2] f2fs: add disable_auto_compr mount option

This patchset doesn't have a cover letter, and it doesn't apply to f2fs/dev, so
I'm not sure what its purpose is.

On Tue, Nov 17, 2020 at 01:02:22PM +0900, Daeho Jeong wrote:
> From: Daeho Jeong <[email protected]>
>
> We will add a new disable_auto_compr mount option to turn off the
> automaic compression on the compression enabled file, in order to
> give discretion of choosing the target file and the timing of
> compression to the user.
>
> Signed-off-by: Daeho Jeong <[email protected]>
> ---
> Documentation/filesystems/f2fs.rst | 4 ++++
> fs/f2fs/data.c | 10 +++++-----
> fs/f2fs/f2fs.h | 8 ++++++++
> fs/f2fs/segment.c | 2 +-
> fs/f2fs/super.c | 9 +++++++++
> 5 files changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
> index b8ee761c9922..c36ca1e0f7ab 100644
> --- a/Documentation/filesystems/f2fs.rst
> +++ b/Documentation/filesystems/f2fs.rst
> @@ -260,6 +260,10 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
> For other files, we can still enable compression via ioctl.
> Note that, there is one reserved special extension '*', it
> can be set to enable compression for all files.
> +disable_auto_compr Even if compression feature is enabled, this option can
> + disable automaic compression on the compression enabled
> + file to give discretion of choosing the target file and
> + the timing of compression to the user.

I don't understand. How is this different from just not specifying the
compress_extension mount option? And how can a file have compression both
enabled and disabled at the same time?

- Eric

2020-11-17 17:17:11

by Jaegeuk Kim

[permalink] [raw]
Subject: Re: [PATCH 1/2] f2fs: add disable_auto_compr mount option

On 11/17, Daeho Jeong wrote:
> From: Daeho Jeong <[email protected]>
>
> We will add a new disable_auto_compr mount option to turn off the
> automaic compression on the compression enabled file, in order to
> give discretion of choosing the target file and the timing of
> compression to the user.

The aim would be getting compressed inode format but having no compressed
blocks in file contents which will be done by coming ioctls manually by user.

>
> Signed-off-by: Daeho Jeong <[email protected]>
> ---
> Documentation/filesystems/f2fs.rst | 4 ++++
> fs/f2fs/data.c | 10 +++++-----
> fs/f2fs/f2fs.h | 8 ++++++++
> fs/f2fs/segment.c | 2 +-
> fs/f2fs/super.c | 9 +++++++++
> 5 files changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
> index b8ee761c9922..c36ca1e0f7ab 100644
> --- a/Documentation/filesystems/f2fs.rst
> +++ b/Documentation/filesystems/f2fs.rst
> @@ -260,6 +260,10 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
> For other files, we can still enable compression via ioctl.
> Note that, there is one reserved special extension '*', it
> can be set to enable compression for all files.
> +disable_auto_compr Even if compression feature is enabled, this option can
> + disable automaic compression on the compression enabled
> + file to give discretion of choosing the target file and
> + the timing of compression to the user.
> 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
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index c31ec408bd4f..414c8370ab7e 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -2896,7 +2896,7 @@ static int f2fs_write_data_page(struct page *page,
> if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
> goto out;
>
> - if (f2fs_compressed_file(inode)) {
> + if (f2fs_need_compress_write(inode)) {
> if (f2fs_is_compressed_cluster(inode, page->index)) {
> redirty_page_for_writepage(wbc, page);
> return AOP_WRITEPAGE_ACTIVATE;
> @@ -2988,7 +2988,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
> readd:
> need_readd = false;
> #ifdef CONFIG_F2FS_FS_COMPRESSION
> - if (f2fs_compressed_file(inode)) {
> + if (f2fs_need_compress_write(inode)) {
> ret = f2fs_init_compress_ctx(&cc);
> if (ret) {
> done = 1;
> @@ -3067,7 +3067,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
> goto continue_unlock;
>
> #ifdef CONFIG_F2FS_FS_COMPRESSION
> - if (f2fs_compressed_file(inode)) {
> + if (f2fs_need_compress_write(inode)) {
> get_page(page);
> f2fs_compress_ctx_add_page(&cc, page);
> continue;
> @@ -3120,7 +3120,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
> }
> #ifdef CONFIG_F2FS_FS_COMPRESSION
> /* flush remained pages in compress cluster */
> - if (f2fs_compressed_file(inode) && !f2fs_cluster_is_empty(&cc)) {
> + if (f2fs_need_compress_write(inode) && !f2fs_cluster_is_empty(&cc)) {
> ret = f2fs_write_multi_pages(&cc, &submitted, wbc, io_type);
> nwritten += submitted;
> wbc->nr_to_write -= submitted;
> @@ -3162,7 +3162,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_write(inode))
> return true;
> if (wbc->sync_mode != WB_SYNC_ALL)
> return true;
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index a33c90cf979b..c473c78699bc 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -99,6 +99,7 @@ extern const char *f2fs_fault_name[FAULT_MAX];
> #define F2FS_MOUNT_DISABLE_CHECKPOINT 0x02000000
> #define F2FS_MOUNT_NORECOVERY 0x04000000
> #define F2FS_MOUNT_ATGC 0x08000000
> +#define F2FS_MOUNT_DISABLE_AUTO_COMPR 0x10000000
>
> #define F2FS_OPTION(sbi) ((sbi)->mount_opt)
> #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
> @@ -2838,6 +2839,13 @@ static inline int f2fs_compressed_file(struct inode *inode)
> is_inode_flag_set(inode, FI_COMPRESSED_FILE);
> }
>
> +static inline int f2fs_need_compress_write(struct inode *inode)
> +{
> + if (test_opt(F2FS_I_SB(inode), DISABLE_AUTO_COMPR))
> + return 0;
> + return f2fs_compressed_file(inode);
> +}
> +
> static inline unsigned int addrs_per_inode(struct inode *inode)
> {
> unsigned int addrs = CUR_ADDRS_PER_INODE(inode) -
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index a0d7a7e04bc7..f56a8b6bbee7 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3245,7 +3245,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_write(inode))
> return CURSEG_COLD_DATA;
> if (file_is_hot(inode) ||
> is_inode_flag_set(inode, FI_HOT_DATA) ||
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 5bb523bf32a6..909c1543b282 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -146,6 +146,7 @@ enum {
> Opt_compress_algorithm,
> Opt_compress_log_size,
> Opt_compress_extension,
> + Opt_disable_auto_compr,
> Opt_atgc,
> Opt_err,
> };
> @@ -214,6 +215,7 @@ static match_table_t f2fs_tokens = {
> {Opt_compress_algorithm, "compress_algorithm=%s"},
> {Opt_compress_log_size, "compress_log_size=%u"},
> {Opt_compress_extension, "compress_extension=%s"},
> + {Opt_disable_auto_compr, "disable_auto_compr"},
> {Opt_atgc, "atgc"},
> {Opt_err, NULL},
> };
> @@ -934,10 +936,14 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
> F2FS_OPTION(sbi).compress_ext_cnt++;
> kfree(name);
> break;
> + case Opt_disable_auto_compr:
> + set_opt(sbi, DISABLE_AUTO_COMPR);
> + break;
> #else
> case Opt_compress_algorithm:
> case Opt_compress_log_size:
> case Opt_compress_extension:
> + case Opt_disable_auto_compr:
> f2fs_info(sbi, "compression options not supported");
> break;
> #endif
> @@ -1511,6 +1517,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
> seq_printf(seq, ",compress_extension=%s",
> F2FS_OPTION(sbi).extensions[i]);
> }
> +
> + if (test_opt(sbi, DISABLE_AUTO_COMPR))
> + seq_puts(seq, ",disable_auto_compr");
> }
>
> static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
> --
> 2.29.2.299.gdc1121823c-goog