blob: 4e570846aefa2432ae820d2587a2efac236a7a80 [file] [edit]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2024-2026, SUSE LLC
*
* Authors: Enzo Matsumiya <ematsumiya@suse.de>
*
* Implementation of the LZ77 "plain" compression algorithm, as per MS-XCA spec.
*/
#ifndef _SMB_COMPRESS_LZ77_H
#define _SMB_COMPRESS_LZ77_H
#include <linux/kernel.h>
/**
* lz77_compressed_alloc_size() - Compute compressed buffer size.
* @size: uncompressed (src) size
*
* Compute allocation size for the compressed buffer based on uncompressed size.
* Accounts for metadata and overprovision for the worst case scenario.
*
* LZ77 metadata is a 4-byte flag that is written:
* - on dst begin (pos 0)
* - every 32 literals or matches
* - on end-of-stream (possibly, if last write was another flag)
*
* Worst case scenario is an all-literal compression, which means:
* metadata bytes = 4 + ((@size / 32) * 4) + 4, or, simplified, (@size >> 3) + 8
*
* The worst case scenario rarely happens, but such overprovisioning also allows lz77_compress()
* main loop to run without ever bound checking dst, which is a huge perf improvement, while also
* being safe when compression goes bad.
*
* Return: required (*) allocation size for compressed buffer.
*
* (*) checked once in the beginning of lz77_compress()
*/
static __always_inline u32 lz77_compressed_alloc_size(const u32 size)
{
return size + (size >> 3) + 8;
}
int lz77_compress(const void *src, const u32 slen, void *dst, u32 *dlen);
#endif /* _SMB_COMPRESS_LZ77_H */