diff options
author | Timofey Titovets <nefelim4ag@gmail.com> | 2017-09-28 10:33:39 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2017-11-01 15:45:36 -0400 |
commit | 1fe4f6fa5ae7dd1e63145e1ced7b9b38854da9f4 (patch) | |
tree | dbe0f0b44b9814655e5b64e8b0cc72db375227b9 | |
parent | a440d48c7f93af5bae86af676cc6cd4e9fd6015f (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.c | 15 |
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 | ||
1225 | static 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 | |||
1225 | static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end, | 1233 | static 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 | ||
1324 | out: | ||
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 | ||