summaryrefslogtreecommitdiff
path: root/fs/btrfs/compression.c
diff options
context:
space:
mode:
authorTimofey Titovets <nefelim4ag@gmail.com>2017-07-17 16:52:58 +0300
committerDavid Sterba <dsterba@suse.com>2017-08-16 16:12:04 +0200
commitc2fcdcdf36bba08c5d2fbf4f17c2d8a944bfd4df (patch)
tree3d7ef1596b198197daa7039ee50fd6ee98321e81 /fs/btrfs/compression.c
parent131ce4367a8f37c6609148117a051d86cd55a5d9 (diff)
Btrfs: add skeleton code for compression heuristic
Add skeleton code for compresison heuristics. Now it iterates over all the pages, but in the end always says "yes, compress please", ie it does not change the current behaviour. In the future we're going to add various heuristics to analyze the data. This patch can be used as a baseline for measuring if the effectivness and performance. Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com> Reviewed-by: David Sterba <dsterba@suse.com> [ enhanced changelog, modified comments ] Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r--fs/btrfs/compression.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 3896bd0175ec..883ecc58fd0d 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -1047,3 +1047,36 @@ int btrfs_decompress_buf2page(const char *buf, unsigned long buf_start,
return 1;
}
+
+/*
+ * Compression heuristic.
+ *
+ * For now is's a naive and optimistic 'return true', we'll extend the logic to
+ * quickly (compared to direct compression) detect data characteristics
+ * (compressible/uncompressible) to avoid wasting CPU time on uncompressible
+ * data.
+ *
+ * The following types of analysis can be performed:
+ * - detect mostly zero data
+ * - detect data with low "byte set" size (text, etc)
+ * - detect data with low/high "core byte" set
+ *
+ * Return non-zero if the compression should be done, 0 otherwise.
+ */
+int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end)
+{
+ u64 index = start >> PAGE_SHIFT;
+ u64 end_index = end >> PAGE_SHIFT;
+ struct page *page;
+ int ret = 1;
+
+ while (index <= end_index) {
+ page = find_get_page(inode->i_mapping, index);
+ kmap(page);
+ kunmap(page);
+ put_page(page);
+ index++;
+ }
+
+ return ret;
+}