@@ -1507,6 +1507,7 @@ enum {
#define BTRFS_INODE_NOATIME (1U << 9)
#define BTRFS_INODE_DIRSYNC (1U << 10)
#define BTRFS_INODE_COMPRESS (1U << 11)
+#define BTRFS_INODE_HEURISTIC_NOCOMPRESS (1U << 12)
#define BTRFS_INODE_ROOT_ITEM_INIT (1U << 31)
@@ -1523,7 +1524,17 @@ enum {
BTRFS_INODE_NOATIME | \
BTRFS_INODE_DIRSYNC | \
BTRFS_INODE_COMPRESS | \
- BTRFS_INODE_ROOT_ITEM_INIT)
+ BTRFS_INODE_ROOT_ITEM_INIT | \
+ BTRFS_INODE_HEURISTIC_NOCOMPRESS )
+
+/*
+ * Inode only memory flags
+ */
+
+#define BTRFS_INODE_ONLY_MEM_FLAG_MASK \
+ (BTRFS_INODE_HEURISTIC_NOCOMPRESS)
+
+
#define BTRFS_INODE_RO_VERITY (1U << 0)
@@ -550,7 +550,8 @@ static inline int inode_need_compress(struct btrfs_inode *inode, u64 start,
if (inode->defrag_compress)
return 1;
/* bad compression ratios */
- if (inode->flags & BTRFS_INODE_NOCOMPRESS)
+ if (inode->flags & BTRFS_INODE_NOCOMPRESS ||
+ inode->flags & BTRFS_INODE_HEURISTIC_NOCOMPRESS)
return 0;
if (btrfs_test_opt(fs_info, COMPRESS) ||
inode->flags & BTRFS_INODE_COMPRESS ||
@@ -838,7 +839,7 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
/* flag the file so we don't compress in the future */
if (!btrfs_test_opt(fs_info, FORCE_COMPRESS) &&
!(BTRFS_I(inode)->prop_compress)) {
- BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
+ BTRFS_I(inode)->flags |= BTRFS_INODE_HEURISTIC_NOCOMPRESS;
}
}
cleanup_and_bail_uncompressed:
@@ -3970,8 +3971,12 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
btrfs_set_token_inode_sequence(&token, item, inode_peek_iversion(inode));
btrfs_set_token_inode_transid(&token, item, trans->transid);
btrfs_set_token_inode_rdev(&token, item, inode->i_rdev);
- flags = btrfs_inode_combine_flags(BTRFS_I(inode)->flags,
- BTRFS_I(inode)->ro_flags);
+ /*
+ * get rid of memory only flag
+ */
+ flags = btrfs_inode_combine_flags(
+ BTRFS_I(inode)->flags & ~BTRFS_INODE_ONLY_MEM_FLAG_MASK,
+ BTRFS_I(inode)->ro_flags);
btrfs_set_token_inode_flags(&token, item, flags);
btrfs_set_token_inode_block_group(&token, item, 0);
}
@@ -4165,8 +4165,12 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
btrfs_set_token_inode_sequence(&token, item, inode_peek_iversion(inode));
btrfs_set_token_inode_transid(&token, item, trans->transid);
btrfs_set_token_inode_rdev(&token, item, inode->i_rdev);
- flags = btrfs_inode_combine_flags(BTRFS_I(inode)->flags,
- BTRFS_I(inode)->ro_flags);
+ /*
+ * clear memory only flag
+ */
+ flags = btrfs_inode_combine_flags(
+ BTRFS_I(inode)->flags & ~BTRFS_INODE_ONLY_MEM_FLAG_MASK,
+ BTRFS_I(inode)->ro_flags);
btrfs_set_token_inode_flags(&token, item, flags);
btrfs_set_token_inode_block_group(&token, item, 0);
}
Introduce the memory flag BTRFS_INODE_HEURISTIC_NOCOMPRESS which is kept in memory only. This flag should be unset every time the filesystem writes to disk. 1. If the compressed file is larger than the original size, BTRFS_INODE_HEURISTIC_NOCOMPRESS will be set. 2. If the btrfs file system wants to write the btrfs_inode flag to the disk or journal tree, the btrfs_inode flag should be and with ~BTRFS_INODE_ONLY_MEM_FLAG_MASK to filter the memory-only flag. 3. In the inode_need_compress function, if btrfs_info is set to BTRFS_INODE_HEURISTIC_NOCOMPRESS, it returns 0, which means that the file is not compressed as much as possible. Signed-off-by: Li Zhang <zhanglikernel@gmail.com> --- fs/btrfs/ctree.h | 13 ++++++++++++- fs/btrfs/inode.c | 13 +++++++++---- fs/btrfs/tree-log.c | 8 ++++++-- 3 files changed, 27 insertions(+), 7 deletions(-)