1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (C) 2024-2026, SUSE LLC 4 * 5 * Authors: Enzo Matsumiya <ematsumiya@suse.de> 6 * 7 * Implementation of the LZ77 "plain" compression algorithm, as per MS-XCA spec. 8 */ 9 #ifndef _SMB_COMPRESS_LZ77_H 10 #define _SMB_COMPRESS_LZ77_H 11 12 #include <linux/kernel.h> 13 14 /** 15 * smb_lz77_compressed_alloc_size() - Compute compressed buffer size. 16 * @size: uncompressed (src) size 17 * 18 * Compute allocation size for the compressed buffer based on uncompressed size. 19 * Accounts for metadata and overprovision for the worst case scenario. 20 * 21 * LZ77 metadata is a 4-byte flag that is written: 22 * - on dst begin (pos 0) 23 * - every 32 literals or matches 24 * - on end-of-stream (possibly, if last write was another flag) 25 * 26 * Worst case scenario is an all-literal compression, which means: 27 * metadata bytes = 4 + ((@size / 32) * 4) + 4, or, simplified, (@size >> 3) + 8 28 * 29 * The worst case scenario rarely happens, but such overprovisioning also 30 * allows smb_lz77_compress() main loop to run without ever bound checking dst, 31 * which is a huge perf improvement, while also being safe when compression goes 32 * bad. 33 * 34 * Return: required (*) allocation size for compressed buffer. 35 * 36 * (*) checked once in the beginning of smb_lz77_compress() 37 */ 38 static __always_inline u32 smb_lz77_compressed_alloc_size(const u32 size) 39 { 40 return size + (size >> 3) + 8; 41 } 42 43 int smb_lz77_compress(const void *src, const u32 slen, void *dst, u32 *dlen); 44 int smb_lz77_decompress(const void *src, const u32 slen, void *dst, 45 const u32 dlen); 46 #endif /* _SMB_COMPRESS_LZ77_H */ 47