aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimofey Titovets <nefelim4ag@gmail.com>2017-09-28 10:33:39 -0400
committerDavid Sterba <dsterba@suse.com>2017-11-01 15:45:36 -0400
commit1fe4f6fa5ae7dd1e63145e1ced7b9b38854da9f4 (patch)
treedbe0f0b44b9814655e5b64e8b0cc72db375227b9
parenta440d48c7f93af5bae86af676cc6cd4e9fd6015f (diff)
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>
-rw-r--r--fs/btrfs/compression.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 0e1561cc9578..0d445c815ca2 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -1222,6 +1222,14 @@ int btrfs_decompress_buf2page(const char *buf, unsigned long buf_start,
1222 return 1; 1222 return 1;
1223} 1223}
1224 1224
1225static bool sample_repeated_patterns(struct heuristic_ws *ws)
1226{
1227 const u32 half_of_sample = ws->sample_size / 2;
1228 const u8 *data = ws->sample;
1229
1230 return memcmp(&data[0], &data[half_of_sample], half_of_sample) == 0;
1231}
1232
1225static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end, 1233static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end,
1226 struct heuristic_ws *ws) 1234 struct heuristic_ws *ws)
1227{ 1235{
@@ -1301,6 +1309,11 @@ int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end)
1301 1309
1302 heuristic_collect_sample(inode, start, end, ws); 1310 heuristic_collect_sample(inode, start, end, ws);
1303 1311
1312 if (sample_repeated_patterns(ws)) {
1313 ret = 1;
1314 goto out;
1315 }
1316
1304 memset(ws->bucket, 0, sizeof(*ws->bucket)*BUCKET_SIZE); 1317 memset(ws->bucket, 0, sizeof(*ws->bucket)*BUCKET_SIZE);
1305 1318
1306 for (i = 0; i < ws->sample_size; i++) { 1319 for (i = 0; i < ws->sample_size; i++) {
@@ -1308,8 +1321,8 @@ int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end)
1308 ws->bucket[byte].count++; 1321 ws->bucket[byte].count++;
1309 } 1322 }
1310 1323
1324out:
1311 __free_workspace(0, ws_list, true); 1325 __free_workspace(0, ws_list, true);
1312
1313 return ret; 1326 return ret;
1314} 1327}
1315 1328