Btrfs: heuristic: add detection of repeated data patterns

Walk over data sample and use memcmp to detect repeated patterns, like
zeros, but a bit more general.

Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ minor coding style fixes ]
Signed-off-by: David Sterba <dsterba@suse.com>
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 0e1561cc..0d445c8 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -1222,6 +1222,14 @@
 	return 1;
 }
 
+static bool sample_repeated_patterns(struct heuristic_ws *ws)
+{
+	const u32 half_of_sample = ws->sample_size / 2;
+	const u8 *data = ws->sample;
+
+	return memcmp(&data[0], &data[half_of_sample], half_of_sample) == 0;
+}
+
 static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end,
 				     struct heuristic_ws *ws)
 {
@@ -1301,6 +1309,11 @@
 
 	heuristic_collect_sample(inode, start, end, ws);
 
+	if (sample_repeated_patterns(ws)) {
+		ret = 1;
+		goto out;
+	}
+
 	memset(ws->bucket, 0, sizeof(*ws->bucket)*BUCKET_SIZE);
 
 	for (i = 0; i < ws->sample_size; i++) {
@@ -1308,8 +1321,8 @@
 		ws->bucket[byte].count++;
 	}
 
+out:
 	__free_workspace(0, ws_list, true);
-
 	return ret;
 }