// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2008 Oracle.  All rights reserved.
 */

#include <linux/kernel.h>
#include <linux/bio.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/highmem.h>
#include <linux/kthread.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/backing-dev.h>
#include <linux/writeback.h>
#include <linux/psi.h>
#include <linux/slab.h>
#include <linux/sched/mm.h>
#include <linux/log2.h>
#include <linux/shrinker.h>
#include "misc.h"
#include "ctree.h"
#include "fs.h"
#include "btrfs_inode.h"
#include "bio.h"
#include "ordered-data.h"
#include "compression.h"
#include "extent_io.h"
#include "extent_map.h"
#include "subpage.h"
#include "messages.h"
#include "super.h"

static struct bio_set btrfs_compressed_bioset;

static const char* const btrfs_compress_types[] = { "", "zlib", "lzo", "zstd" };

const char* btrfs_compress_type2str(enum btrfs_compression_type type)
{
	switch (type) {
	case BTRFS_COMPRESS_ZLIB:
	case BTRFS_COMPRESS_LZO:
	case BTRFS_COMPRESS_ZSTD:
	case BTRFS_COMPRESS_NONE:
		return btrfs_compress_types[type];
	default:
		break;
	}

	return NULL;
}

static inline struct compressed_bio *to_compressed_bio(struct btrfs_bio *bbio)
{
	return container_of(bbio, struct compressed_bio, bbio);
}

static struct compressed_bio *alloc_compressed_bio(struct btrfs_inode *inode,
						   u64 start, blk_opf_t op,
						   btrfs_bio_end_io_t end_io)
{
	struct btrfs_bio *bbio;

	bbio = btrfs_bio(bio_alloc_bioset(NULL, BTRFS_MAX_COMPRESSED_PAGES, op,
					  GFP_NOFS, &btrfs_compressed_bioset));
	btrfs_bio_init(bbio, inode, start, end_io, NULL);
	return to_compressed_bio(bbio);
}

bool btrfs_compress_is_valid_type(const char *str, size_t len)
{
	int i;

	for (i = 1; i < ARRAY_SIZE(btrfs_compress_types); i++) {
		size_t comp_len = strlen(btrfs_compress_types[i]);

		if (len < comp_len)
			continue;

		if (!strncmp(btrfs_compress_types[i], str, comp_len))
			return true;
	}
	return false;
}

static int compression_decompress_bio(struct list_head *ws,
				      struct compressed_bio *cb)
{
	switch (cb->compress_type) {
	case BTRFS_COMPRESS_ZLIB: return zlib_decompress_bio(ws, cb);
	case BTRFS_COMPRESS_LZO:  return lzo_decompress_bio(ws, cb);
	case BTRFS_COMPRESS_ZSTD: return zstd_decompress_bio(ws, cb);
	case BTRFS_COMPRESS_NONE:
	default:
		/*
		 * This can't happen, the type is validated several times
		 * before we get here.
		 */
		BUG();
	}
}

static int compression_decompress(int type, struct list_head *ws,
		const u8 *data_in, struct folio *dest_folio,
		unsigned long dest_pgoff, size_t srclen, size_t destlen)
{
	switch (type) {
	case BTRFS_COMPRESS_ZLIB: return zlib_decompress(ws, data_in, dest_folio,
						dest_pgoff, srclen, destlen);
	case BTRFS_COMPRESS_LZO:  return lzo_decompress(ws, data_in, dest_folio,
						dest_pgoff, srclen, destlen);
	case BTRFS_COMPRESS_ZSTD: return zstd_decompress(ws, data_in, dest_folio,
						dest_pgoff, srclen, destlen);
	case BTRFS_COMPRESS_NONE:
	default:
		/*
		 * This can't happen, the type is validated several times
		 * before we get here.
		 */
		BUG();
	}
}

static int btrfs_decompress_bio(struct compressed_bio *cb);

/*
 * Global cache of last unused pages for compression/decompression.
 */
static struct btrfs_compr_pool {
	struct shrinker *shrinker;
	spinlock_t lock;
	struct list_head list;
	int count;
	int thresh;
} compr_pool;

static unsigned long btrfs_compr_pool_count(struct shrinker *sh, struct shrink_control *sc)
{
	int ret;

	/*
	 * We must not read the values more than once if 'ret' gets expanded in
	 * the return statement so we don't accidentally return a negative
	 * number, even if the first condition finds it positive.
	 */
	ret = READ_ONCE(compr_pool.count) - READ_ONCE(compr_pool.thresh);

	return ret > 0 ? ret : 0;
}

static unsigned long btrfs_compr_pool_scan(struct shrinker *sh, struct shrink_control *sc)
{
	LIST_HEAD(remove);
	struct list_head *tmp, *next;
	int freed;

	if (compr_pool.count == 0)
		return SHRINK_STOP;

	/* For now, just simply drain the whole list. */
	spin_lock(&compr_pool.lock);
	list_splice_init(&compr_pool.list, &remove);
	freed = compr_pool.count;
	compr_pool.count = 0;
	spin_unlock(&compr_pool.lock);

	list_for_each_safe(tmp, next, &remove) {
		struct page *page = list_entry(tmp, struct page, lru);

		ASSERT(page_ref_count(page) == 1);
		put_page(page);
	}

	return freed;
}

/*
 * Common wrappers for page allocation from compression wrappers
 */
struct folio *btrfs_alloc_compr_folio(struct btrfs_fs_info *fs_info)
{
	struct folio *folio = NULL;

	/* For bs > ps cases, no cached folio pool for now. */
	if (fs_info->block_min_order)
		goto alloc;

	spin_lock(&compr_pool.lock);
	if (compr_pool.count > 0) {
		folio = list_first_entry(&compr_pool.list, struct folio, lru);
		list_del_init(&folio->lru);
		compr_pool.count--;
	}
	spin_unlock(&compr_pool.lock);

	if (folio)
		return folio;

alloc:
	return folio_alloc(GFP_NOFS, fs_info->block_min_order);
}

void btrfs_free_compr_folio(struct folio *folio)
{
	bool do_free = false;

	/* The folio is from bs > ps fs, no cached pool for now. */
	if (folio_order(folio))
		goto free;

	spin_lock(&compr_pool.lock);
	if (compr_pool.count > compr_pool.thresh) {
		do_free = true;
	} else {
		list_add(&folio->lru, &compr_pool.list);
		compr_pool.count++;
	}
	spin_unlock(&compr_pool.lock);

	if (!do_free)
		return;

free:
	ASSERT(folio_ref_count(folio) == 1);
	folio_put(folio);
}

static void end_bbio_compressed_read(struct btrfs_bio *bbio)
{
	struct compressed_bio *cb = to_compressed_bio(bbio);
	blk_status_t status = bbio->bio.bi_status;
	struct folio_iter fi;

	if (!status)
		status = errno_to_blk_status(btrfs_decompress_bio(cb));

	btrfs_bio_end_io(cb->orig_bbio, status);
	bio_for_each_folio_all(fi, &bbio->bio)
		btrfs_free_compr_folio(fi.folio);
	bio_put(&bbio->bio);
}

/*
 * Clear the writeback bits on all of the file
 * pages for a compressed write
 */
static noinline void end_compressed_writeback(const struct compressed_bio *cb)
{
	struct inode *inode = &cb->bbio.inode->vfs_inode;
	struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
	pgoff_t index = cb->start >> PAGE_SHIFT;
	const pgoff_t end_index = (cb->start + cb->len - 1) >> PAGE_SHIFT;
	struct folio_batch fbatch;
	int i;
	int ret;

	ret = blk_status_to_errno(cb->bbio.bio.bi_status);
	if (ret)
		mapping_set_error(inode->i_mapping, ret);

	folio_batch_init(&fbatch);
	while (index <= end_index) {
		ret = filemap_get_folios(inode->i_mapping, &index, end_index,
				&fbatch);

		if (ret == 0)
			return;

		for (i = 0; i < ret; i++) {
			struct folio *folio = fbatch.folios[i];

			btrfs_folio_clamp_clear_writeback(fs_info, folio,
							  cb->start, cb->len);
		}
		folio_batch_release(&fbatch);
	}
	/* the inode may be gone now */
}

/*
 * Do the cleanup once all the compressed pages hit the disk.  This will clear
 * writeback on the file pages and free the compressed pages.
 *
 * This also calls the writeback end hooks for the file pages so that metadata
 * and checksums can be updated in the file.
 */
static void end_bbio_compressed_write(struct btrfs_bio *bbio)
{
	struct compressed_bio *cb = to_compressed_bio(bbio);
	struct folio_iter fi;

	btrfs_finish_ordered_extent(cb->bbio.ordered, NULL, cb->start, cb->len,
				    cb->bbio.bio.bi_status == BLK_STS_OK);

	if (cb->writeback)
		end_compressed_writeback(cb);
	/* Note, our inode could be gone now. */
	bio_for_each_folio_all(fi, &bbio->bio)
		btrfs_free_compr_folio(fi.folio);
	bio_put(&cb->bbio.bio);
}

/*
 * worker function to build and submit bios for previously compressed pages.
 * The corresponding pages in the inode should be marked for writeback
 * and the compressed pages should have a reference on them for dropping
 * when the IO is complete.
 *
 * This also checksums the file bytes and gets things ready for
 * the end io hooks.
 */
void btrfs_submit_compressed_write(struct btrfs_ordered_extent *ordered,
				   struct compressed_bio *cb)
{
	struct btrfs_inode *inode = ordered->inode;
	struct btrfs_fs_info *fs_info = inode->root->fs_info;

	ASSERT(IS_ALIGNED(ordered->file_offset, fs_info->sectorsize));
	ASSERT(IS_ALIGNED(ordered->num_bytes, fs_info->sectorsize));
	/*
	 * This flag determines if we should clear the writeback flag from the
	 * page cache. But this function is only utilized by encoded writes, it
	 * never goes through the page cache.
	 */
	ASSERT(!cb->writeback);

	cb->start = ordered->file_offset;
	cb->len = ordered->num_bytes;
	ASSERT(cb->bbio.bio.bi_iter.bi_size == ordered->disk_num_bytes);
	cb->compressed_len = ordered->disk_num_bytes;
	cb->bbio.bio.bi_iter.bi_sector = ordered->disk_bytenr >> SECTOR_SHIFT;
	cb->bbio.ordered = ordered;

	btrfs_submit_bbio(&cb->bbio, 0);
}

/*
 * Allocate a compressed write bio for @inode file offset @start length @len.
 *
 * The caller still needs to properly queue all folios and populate involved
 * members.
 */
struct compressed_bio *btrfs_alloc_compressed_write(struct btrfs_inode *inode,
						    u64 start, u64 len)
{
	struct compressed_bio *cb;

	cb = alloc_compressed_bio(inode, start, REQ_OP_WRITE, end_bbio_compressed_write);
	cb->start = start;
	cb->len = len;
	cb->writeback = false;
	return cb;
}

/*
 * Add extra pages in the same compressed file extent so that we don't need to
 * re-read the same extent again and again.
 *
 * NOTE: this won't work well for subpage, as for subpage read, we lock the
 * full page then submit bio for each compressed/regular extents.
 *
 * This means, if we have several sectors in the same page points to the same
 * on-disk compressed data, we will re-read the same extent many times and
 * this function can only help for the next page.
 */
static noinline int add_ra_bio_pages(struct inode *inode,
				     u64 compressed_end,
				     struct compressed_bio *cb,
				     int *memstall, unsigned long *pflags)
{
	struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
	pgoff_t end_index;
	struct bio *orig_bio = &cb->orig_bbio->bio;
	u64 cur = cb->orig_bbio->file_offset + orig_bio->bi_iter.bi_size;
	u64 isize = i_size_read(inode);
	int ret;
	struct folio *folio;
	struct extent_map *em;
	struct address_space *mapping = inode->i_mapping;
	struct extent_map_tree *em_tree;
	struct extent_io_tree *tree;
	int sectors_missed = 0;

	em_tree = &BTRFS_I(inode)->extent_tree;
	tree = &BTRFS_I(inode)->io_tree;

	if (isize == 0)
		return 0;

	/*
	 * For current subpage support, we only support 64K page size,
	 * which means maximum compressed extent size (128K) is just 2x page
	 * size.
	 * This makes readahead less effective, so here disable readahead for
	 * subpage for now, until full compressed write is supported.
	 */
	if (fs_info->sectorsize < PAGE_SIZE)
		return 0;

	/* For bs > ps cases, we don't support readahead for compressed folios for now. */
	if (fs_info->block_min_order)
		return 0;

	end_index = (i_size_read(inode) - 1) >> PAGE_SHIFT;

	while (cur < compressed_end) {
		pgoff_t page_end;
		pgoff_t pg_index = cur >> PAGE_SHIFT;
		u32 add_size;

		if (pg_index > end_index)
			break;

		folio = filemap_get_folio(mapping, pg_index);
		if (!IS_ERR(folio)) {
			u64 folio_sz = folio_size(folio);
			u64 offset = offset_in_folio(folio, cur);

			folio_put(folio);
			sectors_missed += (folio_sz - offset) >>
					  fs_info->sectorsize_bits;

			/* Beyond threshold, no need to continue */
			if (sectors_missed > 4)
				break;

			/*
			 * Jump to next page start as we already have page for
			 * current offset.
			 */
			cur += (folio_sz - offset);
			continue;
		}

		folio = filemap_alloc_folio(mapping_gfp_constraint(mapping, ~__GFP_FS),
					    0, NULL);
		if (!folio)
			break;

		if (filemap_add_folio(mapping, folio, pg_index, GFP_NOFS)) {
			/* There is already a page, skip to page end */
			cur += folio_size(folio);
			folio_put(folio);
			continue;
		}

		if (!*memstall && folio_test_workingset(folio)) {
			psi_memstall_enter(pflags);
			*memstall = 1;
		}

		ret = set_folio_extent_mapped(folio);
		if (ret < 0) {
			folio_unlock(folio);
			folio_put(folio);
			break;
		}

		page_end = (pg_index << PAGE_SHIFT) + folio_size(folio) - 1;
		btrfs_lock_extent(tree, cur, page_end, NULL);
		read_lock(&em_tree->lock);
		em = btrfs_lookup_extent_mapping(em_tree, cur, page_end + 1 - cur);
		read_unlock(&em_tree->lock);

		/*
		 * At this point, we have a locked page in the page cache for
		 * these bytes in the file.  But, we have to make sure they map
		 * to this compressed extent on disk.
		 */
		if (!em || cur < em->start ||
		    (cur + fs_info->sectorsize > btrfs_extent_map_end(em)) ||
		    (btrfs_extent_map_block_start(em) >> SECTOR_SHIFT) !=
		    orig_bio->bi_iter.bi_sector) {
			btrfs_free_extent_map(em);
			btrfs_unlock_extent(tree, cur, page_end, NULL);
			folio_unlock(folio);
			folio_put(folio);
			break;
		}
		add_size = min(btrfs_extent_map_end(em), page_end + 1) - cur;
		btrfs_free_extent_map(em);
		btrfs_unlock_extent(tree, cur, page_end, NULL);

		if (folio_contains(folio, end_index)) {
			size_t zero_offset = offset_in_folio(folio, isize);

			if (zero_offset) {
				int zeros;
				zeros = folio_size(folio) - zero_offset;
				folio_zero_range(folio, zero_offset, zeros);
			}
		}

		if (!bio_add_folio(orig_bio, folio, add_size,
				   offset_in_folio(folio, cur))) {
			folio_unlock(folio);
			folio_put(folio);
			break;
		}
		/*
		 * If it's subpage, we also need to increase its
		 * subpage::readers number, as at endio we will decrease
		 * subpage::readers and to unlock the page.
		 */
		if (fs_info->sectorsize < PAGE_SIZE)
			btrfs_folio_set_lock(fs_info, folio, cur, add_size);
		folio_put(folio);
		cur += add_size;
	}
	return 0;
}

/*
 * for a compressed read, the bio we get passed has all the inode pages
 * in it.  We don't actually do IO on those pages but allocate new ones
 * to hold the compressed pages on disk.
 *
 * bio->bi_iter.bi_sector points to the compressed extent on disk
 * bio->bi_io_vec points to all of the inode pages
 *
 * After the compressed pages are read, we copy the bytes into the
 * bio we were passed and then call the bio end_io calls
 */
void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
{
	struct btrfs_inode *inode = bbio->inode;
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	struct extent_map_tree *em_tree = &inode->extent_tree;
	struct compressed_bio *cb;
	unsigned int compressed_len;
	const u32 min_folio_size = btrfs_min_folio_size(fs_info);
	u64 file_offset = bbio->file_offset;
	u64 em_len;
	u64 em_start;
	struct extent_map *em;
	unsigned long pflags;
	int memstall = 0;
	int ret;

	/* we need the actual starting offset of this extent in the file */
	read_lock(&em_tree->lock);
	em = btrfs_lookup_extent_mapping(em_tree, file_offset, fs_info->sectorsize);
	read_unlock(&em_tree->lock);
	if (!em) {
		ret = -EIO;
		goto out;
	}

	ASSERT(btrfs_extent_map_is_compressed(em));
	compressed_len = em->disk_num_bytes;

	cb = alloc_compressed_bio(inode, file_offset, REQ_OP_READ,
				  end_bbio_compressed_read);

	cb->start = em->start - em->offset;
	em_len = em->len;
	em_start = em->start;

	cb->len = bbio->bio.bi_iter.bi_size;
	cb->compressed_len = compressed_len;
	cb->compress_type = btrfs_extent_map_compression(em);
	cb->orig_bbio = bbio;
	cb->bbio.csum_search_commit_root = bbio->csum_search_commit_root;

	btrfs_free_extent_map(em);

	for (int i = 0; i * min_folio_size < compressed_len; i++) {
		struct folio *folio;
		u32 cur_len = min(compressed_len - i * min_folio_size, min_folio_size);

		folio = btrfs_alloc_compr_folio(fs_info);
		if (!folio) {
			ret = -ENOMEM;
			goto out_free_bio;
		}

		ret = bio_add_folio(&cb->bbio.bio, folio, cur_len, 0);
		if (unlikely(!ret)) {
			folio_put(folio);
			ret = -EINVAL;
			goto out_free_bio;
		}
	}
	ASSERT(cb->bbio.bio.bi_iter.bi_size == compressed_len);

	add_ra_bio_pages(&inode->vfs_inode, em_start + em_len, cb, &memstall,
			 &pflags);

	cb->len = bbio->bio.bi_iter.bi_size;
	cb->bbio.bio.bi_iter.bi_sector = bbio->bio.bi_iter.bi_sector;

	if (memstall)
		psi_memstall_leave(&pflags);

	btrfs_submit_bbio(&cb->bbio, 0);
	return;

out_free_bio:
	cleanup_compressed_bio(cb);
out:
	btrfs_bio_end_io(bbio, errno_to_blk_status(ret));
}

/*
 * Heuristic uses systematic sampling to collect data from the input data
 * range, the logic can be tuned by the following constants:
 *
 * @SAMPLING_READ_SIZE - how many bytes will be copied from for each sample
 * @SAMPLING_INTERVAL  - range from which the sampled data can be collected
 */
#define SAMPLING_READ_SIZE	(16)
#define SAMPLING_INTERVAL	(256)

/*
 * For statistical analysis of the input data we consider bytes that form a
 * Galois Field of 256 objects. Each object has an attribute count, ie. how
 * many times the object appeared in the sample.
 */
#define BUCKET_SIZE		(256)

/*
 * The size of the sample is based on a statistical sampling rule of thumb.
 * The common way is to perform sampling tests as long as the number of
 * elements in each cell is at least 5.
 *
 * Instead of 5, we choose 32 to obtain more accurate results.
 * If the data contain the maximum number of symbols, which is 256, we obtain a
 * sample size bound by 8192.
 *
 * For a sample of at most 8KB of data per data range: 16 consecutive bytes
 * from up to 512 locations.
 */
#define MAX_SAMPLE_SIZE		(BTRFS_MAX_UNCOMPRESSED *		\
				 SAMPLING_READ_SIZE / SAMPLING_INTERVAL)

struct bucket_item {
	u32 count;
};

struct heuristic_ws {
	/* Partial copy of input data */
	u8 *sample;
	u32 sample_size;
	/* Buckets store counters for each byte value */
	struct bucket_item *bucket;
	/* Sorting buffer */
	struct bucket_item *bucket_b;
	struct list_head list;
};

static void free_heuristic_ws(struct list_head *ws)
{
	struct heuristic_ws *workspace;

	workspace = list_entry(ws, struct heuristic_ws, list);

	kvfree(workspace->sample);
	kfree(workspace->bucket);
	kfree(workspace->bucket_b);
	kfree(workspace);
}

static struct list_head *alloc_heuristic_ws(struct btrfs_fs_info *fs_info)
{
	struct heuristic_ws *ws;

	ws = kzalloc_obj(*ws);
	if (!ws)
		return ERR_PTR(-ENOMEM);

	ws->sample = kvmalloc(MAX_SAMPLE_SIZE, GFP_KERNEL);
	if (!ws->sample)
		goto fail;

	ws->bucket = kzalloc_objs(*ws->bucket, BUCKET_SIZE);
	if (!ws->bucket)
		goto fail;

	ws->bucket_b = kzalloc_objs(*ws->bucket_b, BUCKET_SIZE);
	if (!ws->bucket_b)
		goto fail;

	INIT_LIST_HEAD(&ws->list);
	return &ws->list;
fail:
	free_heuristic_ws(&ws->list);
	return ERR_PTR(-ENOMEM);
}

const struct btrfs_compress_levels btrfs_heuristic_compress = { 0 };

static const struct btrfs_compress_levels * const btrfs_compress_levels[] = {
	/* The heuristic is represented as compression type 0 */
	&btrfs_heuristic_compress,
	&btrfs_zlib_compress,
	&btrfs_lzo_compress,
	&btrfs_zstd_compress,
};

static struct list_head *alloc_workspace(struct btrfs_fs_info *fs_info, int type, int level)
{
	switch (type) {
	case BTRFS_COMPRESS_NONE: return alloc_heuristic_ws(fs_info);
	case BTRFS_COMPRESS_ZLIB: return zlib_alloc_workspace(fs_info, level);
	case BTRFS_COMPRESS_LZO:  return lzo_alloc_workspace(fs_info);
	case BTRFS_COMPRESS_ZSTD: return zstd_alloc_workspace(fs_info, level);
	default:
		/*
		 * This can't happen, the type is validated several times
		 * before we get here.
		 */
		BUG();
	}
}

static void free_workspace(int type, struct list_head *ws)
{
	switch (type) {
	case BTRFS_COMPRESS_NONE: return free_heuristic_ws(ws);
	case BTRFS_COMPRESS_ZLIB: return zlib_free_workspace(ws);
	case BTRFS_COMPRESS_LZO:  return lzo_free_workspace(ws);
	case BTRFS_COMPRESS_ZSTD: return zstd_free_workspace(ws);
	default:
		/*
		 * This can't happen, the type is validated several times
		 * before we get here.
		 */
		BUG();
	}
}

static int alloc_workspace_manager(struct btrfs_fs_info *fs_info,
				   enum btrfs_compression_type type)
{
	struct workspace_manager *gwsm;
	struct list_head *workspace;

	ASSERT(fs_info->compr_wsm[type] == NULL);
	gwsm = kzalloc_obj(*gwsm);
	if (!gwsm)
		return -ENOMEM;

	INIT_LIST_HEAD(&gwsm->idle_ws);
	spin_lock_init(&gwsm->ws_lock);
	atomic_set(&gwsm->total_ws, 0);
	init_waitqueue_head(&gwsm->ws_wait);
	fs_info->compr_wsm[type] = gwsm;

	/*
	 * Preallocate one workspace for each compression type so we can
	 * guarantee forward progress in the worst case
	 */
	workspace = alloc_workspace(fs_info, type, 0);
	if (IS_ERR(workspace)) {
		btrfs_warn(fs_info,
	"cannot preallocate compression workspace for %s, will try later",
			   btrfs_compress_type2str(type));
	} else {
		atomic_set(&gwsm->total_ws, 1);
		gwsm->free_ws = 1;
		list_add(workspace, &gwsm->idle_ws);
	}
	return 0;
}

static void free_workspace_manager(struct btrfs_fs_info *fs_info,
				   enum btrfs_compression_type type)
{
	struct list_head *ws;
	struct workspace_manager *gwsm = fs_info->compr_wsm[type];

	/* ZSTD uses its own workspace manager, should enter here. */
	ASSERT(type != BTRFS_COMPRESS_ZSTD && type < BTRFS_NR_COMPRESS_TYPES);
	if (!gwsm)
		return;
	fs_info->compr_wsm[type] = NULL;
	while (!list_empty(&gwsm->idle_ws)) {
		ws = gwsm->idle_ws.next;
		list_del(ws);
		free_workspace(type, ws);
		atomic_dec(&gwsm->total_ws);
	}
	kfree(gwsm);
}

/*
 * This finds an available workspace or allocates a new one.
 * If it's not possible to allocate a new one, waits until there's one.
 * Preallocation makes a forward progress guarantees and we do not return
 * errors.
 */
struct list_head *btrfs_get_workspace(struct btrfs_fs_info *fs_info, int type, int level)
{
	struct workspace_manager *wsm = fs_info->compr_wsm[type];
	struct list_head *workspace;
	int cpus = num_online_cpus();
	unsigned nofs_flag;
	struct list_head *idle_ws;
	spinlock_t *ws_lock;
	atomic_t *total_ws;
	wait_queue_head_t *ws_wait;
	int *free_ws;

	ASSERT(wsm);
	idle_ws	 = &wsm->idle_ws;
	ws_lock	 = &wsm->ws_lock;
	total_ws = &wsm->total_ws;
	ws_wait	 = &wsm->ws_wait;
	free_ws	 = &wsm->free_ws;

again:
	spin_lock(ws_lock);
	if (!list_empty(idle_ws)) {
		workspace = idle_ws->next;
		list_del(workspace);
		(*free_ws)--;
		spin_unlock(ws_lock);
		return workspace;

	}
	if (atomic_read(total_ws) > cpus) {
		DEFINE_WAIT(wait);

		spin_unlock(ws_lock);
		prepare_to_wait(ws_wait, &wait, TASK_UNINTERRUPTIBLE);
		if (atomic_read(total_ws) > cpus && !*free_ws)
			schedule();
		finish_wait(ws_wait, &wait);
		goto again;
	}
	atomic_inc(total_ws);
	spin_unlock(ws_lock);

	/*
	 * Allocation helpers call vmalloc that can't use GFP_NOFS, so we have
	 * to turn it off here because we might get called from the restricted
	 * context of btrfs_compress_bio/btrfs_compress_pages
	 */
	nofs_flag = memalloc_nofs_save();
	workspace = alloc_workspace(fs_info, type, level);
	memalloc_nofs_restore(nofs_flag);

	if (IS_ERR(workspace)) {
		atomic_dec(total_ws);
		wake_up(ws_wait);

		/*
		 * Do not return the error but go back to waiting. There's a
		 * workspace preallocated for each type and the compression
		 * time is bounded so we get to a workspace eventually. This
		 * makes our caller's life easier.
		 *
		 * To prevent silent and low-probability deadlocks (when the
		 * initial preallocation fails), check if there are any
		 * workspaces at all.
		 */
		if (atomic_read(total_ws) == 0) {
			static DEFINE_RATELIMIT_STATE(_rs,
					/* once per minute */ 60 * HZ,
					/* no burst */ 1);

			if (__ratelimit(&_rs))
				btrfs_warn(fs_info,
				"no compression workspaces, low memory, retrying");
		}
		goto again;
	}
	return workspace;
}

static struct list_head *get_workspace(struct btrfs_fs_info *fs_info, int type, int level)
{
	switch (type) {
	case BTRFS_COMPRESS_NONE: return btrfs_get_workspace(fs_info, type, level);
	case BTRFS_COMPRESS_ZLIB: return zlib_get_workspace(fs_info, level);
	case BTRFS_COMPRESS_LZO:  return btrfs_get_workspace(fs_info, type, level);
	case BTRFS_COMPRESS_ZSTD: return zstd_get_workspace(fs_info, level);
	default:
		/*
		 * This can't happen, the type is validated several times
		 * before we get here.
		 */
		BUG();
	}
}

/*
 * put a workspace struct back on the list or free it if we have enough
 * idle ones sitting around
 */
void btrfs_put_workspace(struct btrfs_fs_info *fs_info, int type, struct list_head *ws)
{
	struct workspace_manager *gwsm = fs_info->compr_wsm[type];
	struct list_head *idle_ws;
	spinlock_t *ws_lock;
	atomic_t *total_ws;
	wait_queue_head_t *ws_wait;
	int *free_ws;

	ASSERT(gwsm);
	idle_ws	 = &gwsm->idle_ws;
	ws_lock	 = &gwsm->ws_lock;
	total_ws = &gwsm->total_ws;
	ws_wait	 = &gwsm->ws_wait;
	free_ws	 = &gwsm->free_ws;

	spin_lock(ws_lock);
	if (*free_ws <= num_online_cpus()) {
		list_add(ws, idle_ws);
		(*free_ws)++;
		spin_unlock(ws_lock);
		goto wake;
	}
	spin_unlock(ws_lock);

	free_workspace(type, ws);
	atomic_dec(total_ws);
wake:
	cond_wake_up(ws_wait);
}

static void put_workspace(struct btrfs_fs_info *fs_info, int type, struct list_head *ws)
{
	switch (type) {
	case BTRFS_COMPRESS_NONE: return btrfs_put_workspace(fs_info, type, ws);
	case BTRFS_COMPRESS_ZLIB: return btrfs_put_workspace(fs_info, type, ws);
	case BTRFS_COMPRESS_LZO:  return btrfs_put_workspace(fs_info, type, ws);
	case BTRFS_COMPRESS_ZSTD: return zstd_put_workspace(fs_info, ws);
	default:
		/*
		 * This can't happen, the type is validated several times
		 * before we get here.
		 */
		BUG();
	}
}

/*
 * Adjust @level according to the limits of the compression algorithm or
 * fallback to default
 */
static int btrfs_compress_set_level(unsigned int type, int level)
{
	const struct btrfs_compress_levels *levels = btrfs_compress_levels[type];

	if (level == 0)
		level = levels->default_level;
	else
		level = clamp(level, levels->min_level, levels->max_level);

	return level;
}

/*
 * Check whether the @level is within the valid range for the given type.
 */
bool btrfs_compress_level_valid(unsigned int type, int level)
{
	const struct btrfs_compress_levels *levels = btrfs_compress_levels[type];

	return levels->min_level <= level && level <= levels->max_level;
}

/* Wrapper around find_get_page(), with extra error message. */
int btrfs_compress_filemap_get_folio(struct address_space *mapping, u64 start,
				     struct folio **in_folio_ret)
{
	struct folio *in_folio;

	/*
	 * The compressed write path should have the folio locked already, thus
	 * we only need to grab one reference.
	 */
	in_folio = filemap_get_folio(mapping, start >> PAGE_SHIFT);
	if (IS_ERR(in_folio)) {
		struct btrfs_inode *inode = BTRFS_I(mapping->host);

		btrfs_crit(inode->root->fs_info,
		"failed to get page cache, root %lld ino %llu file offset %llu",
			   btrfs_root_id(inode->root), btrfs_ino(inode), start);
		return -ENOENT;
	}
	*in_folio_ret = in_folio;
	return 0;
}

/*
 * Given an address space and start and length, compress the page cache
 * contents into @cb.
 *
 * @type_level:      is encoded algorithm and level, where level 0 means whatever
 *                   default the algorithm chooses and is opaque here;
 *                   - compression algo are 0-3
 *                   - the level are bits 4-7
 *
 * @cb->bbio.bio.bi_iter.bi_size will indicate the compressed data size.
 * The bi_size may not be sectorsize aligned, thus the caller still need
 * to do the round up before submission.
 *
 * This function will allocate compressed folios with btrfs_alloc_compr_folio(),
 * thus callers must make sure the endio function and error handling are using
 * btrfs_free_compr_folio() to release those folios.
 * This is already done in end_bbio_compressed_write() and cleanup_compressed_bio().
 */
struct compressed_bio *btrfs_compress_bio(struct btrfs_inode *inode,
					  u64 start, u32 len, unsigned int type,
					  int level, blk_opf_t write_flags)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	struct list_head *workspace;
	struct compressed_bio *cb;
	int ret;

	cb = alloc_compressed_bio(inode, start, REQ_OP_WRITE | write_flags,
				  end_bbio_compressed_write);
	cb->start = start;
	cb->len = len;
	cb->writeback = true;
	cb->compress_type = type;

	level = btrfs_compress_set_level(type, level);
	workspace = get_workspace(fs_info, type, level);
	switch (type) {
	case BTRFS_COMPRESS_ZLIB:
		ret = zlib_compress_bio(workspace, cb);
		break;
	case BTRFS_COMPRESS_LZO:
		ret = lzo_compress_bio(workspace, cb);
		break;
	case BTRFS_COMPRESS_ZSTD:
		ret = zstd_compress_bio(workspace, cb);
		break;
	case BTRFS_COMPRESS_NONE:
	default:
		/*
		 * This can happen when compression races with remount setting
		 * it to 'no compress', while caller doesn't call
		 * inode_need_compress() to check if we really need to
		 * compress.
		 *
		 * Not a big deal, just need to inform caller that we
		 * haven't allocated any pages yet.
		 */
		ret = -E2BIG;
	}

	put_workspace(fs_info, type, workspace);
	if (ret < 0) {
		cleanup_compressed_bio(cb);
		return ERR_PTR(ret);
	}
	return cb;
}

static int btrfs_decompress_bio(struct compressed_bio *cb)
{
	struct btrfs_fs_info *fs_info = cb_to_fs_info(cb);
	struct list_head *workspace;
	int ret;
	int type = cb->compress_type;

	workspace = get_workspace(fs_info, type, 0);
	ret = compression_decompress_bio(workspace, cb);
	put_workspace(fs_info, type, workspace);

	if (!ret)
		zero_fill_bio(&cb->orig_bbio->bio);
	return ret;
}

/*
 * a less complex decompression routine.  Our compressed data fits in a
 * single page, and we want to read a single page out of it.
 * dest_pgoff tells us the offset into the destination folio where we write the
 * decompressed data.
 */
int btrfs_decompress(int type, const u8 *data_in, struct folio *dest_folio,
		     unsigned long dest_pgoff, size_t srclen, size_t destlen)
{
	struct btrfs_fs_info *fs_info = folio_to_fs_info(dest_folio);
	struct list_head *workspace;
	const u32 sectorsize = fs_info->sectorsize;
	int ret;

	/*
	 * The full destination folio range should not exceed the folio size.
	 * And the @destlen should not exceed sectorsize, as this is only called for
	 * inline file extents, which should not exceed sectorsize.
	 */
	ASSERT(dest_pgoff + destlen <= folio_size(dest_folio) && destlen <= sectorsize);

	workspace = get_workspace(fs_info, type, 0);
	ret = compression_decompress(type, workspace, data_in, dest_folio,
				     dest_pgoff, srclen, destlen);
	put_workspace(fs_info, type, workspace);

	return ret;
}

int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info)
{
	int ret;

	ret = alloc_workspace_manager(fs_info, BTRFS_COMPRESS_NONE);
	if (ret < 0)
		goto error;
	ret = alloc_workspace_manager(fs_info, BTRFS_COMPRESS_ZLIB);
	if (ret < 0)
		goto error;
	ret = alloc_workspace_manager(fs_info, BTRFS_COMPRESS_LZO);
	if (ret < 0)
		goto error;
	ret = zstd_alloc_workspace_manager(fs_info);
	if (ret < 0)
		goto error;
	return 0;
error:
	btrfs_free_compress_wsm(fs_info);
	return ret;
}

void btrfs_free_compress_wsm(struct btrfs_fs_info *fs_info)
{
	free_workspace_manager(fs_info, BTRFS_COMPRESS_NONE);
	free_workspace_manager(fs_info, BTRFS_COMPRESS_ZLIB);
	free_workspace_manager(fs_info, BTRFS_COMPRESS_LZO);
	zstd_free_workspace_manager(fs_info);
}

int __init btrfs_init_compress(void)
{
	if (bioset_init(&btrfs_compressed_bioset, BIO_POOL_SIZE,
			offsetof(struct compressed_bio, bbio.bio),
			BIOSET_NEED_BVECS))
		return -ENOMEM;

	compr_pool.shrinker = shrinker_alloc(SHRINKER_NONSLAB, "btrfs-compr-pages");
	if (!compr_pool.shrinker)
		return -ENOMEM;

	spin_lock_init(&compr_pool.lock);
	INIT_LIST_HEAD(&compr_pool.list);
	compr_pool.count = 0;
	/* 128K / 4K = 32, for 8 threads is 256 pages. */
	compr_pool.thresh = BTRFS_MAX_COMPRESSED / PAGE_SIZE * 8;
	compr_pool.shrinker->count_objects = btrfs_compr_pool_count;
	compr_pool.shrinker->scan_objects = btrfs_compr_pool_scan;
	compr_pool.shrinker->batch = 32;
	compr_pool.shrinker->seeks = DEFAULT_SEEKS;
	shrinker_register(compr_pool.shrinker);

	return 0;
}

void __cold btrfs_exit_compress(void)
{
	/* For now scan drains all pages and does not touch the parameters. */
	btrfs_compr_pool_scan(NULL, NULL);
	shrinker_free(compr_pool.shrinker);

	bioset_exit(&btrfs_compressed_bioset);
}

/*
 * The bvec is a single page bvec from a bio that contains folios from a filemap.
 *
 * Since the folio may be a large one, and if the bv_page is not a head page of
 * a large folio, then page->index is unreliable.
 *
 * Thus we need this helper to grab the proper file offset.
 */
static u64 file_offset_from_bvec(const struct bio_vec *bvec)
{
	const struct page *page = bvec->bv_page;
	const struct folio *folio = page_folio(page);

	return (page_pgoff(folio, page) << PAGE_SHIFT) + bvec->bv_offset;
}

/*
 * Copy decompressed data from working buffer to pages.
 *
 * @buf:		The decompressed data buffer
 * @buf_len:		The decompressed data length
 * @decompressed:	Number of bytes that are already decompressed inside the
 * 			compressed extent
 * @cb:			The compressed extent descriptor
 * @orig_bio:		The original bio that the caller wants to read for
 *
 * An easier to understand graph is like below:
 *
 * 		|<- orig_bio ->|     |<- orig_bio->|
 * 	|<-------      full decompressed extent      ----->|
 * 	|<-----------    @cb range   ---->|
 * 	|			|<-- @buf_len -->|
 * 	|<--- @decompressed --->|
 *
 * Note that, @cb can be a subpage of the full decompressed extent, but
 * @cb->start always has the same as the orig_file_offset value of the full
 * decompressed extent.
 *
 * When reading compressed extent, we have to read the full compressed extent,
 * while @orig_bio may only want part of the range.
 * Thus this function will ensure only data covered by @orig_bio will be copied
 * to.
 *
 * Return 0 if we have copied all needed contents for @orig_bio.
 * Return >0 if we need continue decompress.
 */
int btrfs_decompress_buf2page(const char *buf, u32 buf_len,
			      struct compressed_bio *cb, u32 decompressed)
{
	struct bio *orig_bio = &cb->orig_bbio->bio;
	/* Offset inside the full decompressed extent */
	u32 cur_offset;

	cur_offset = decompressed;
	/* The main loop to do the copy */
	while (cur_offset < decompressed + buf_len) {
		struct bio_vec bvec;
		size_t copy_len;
		u32 copy_start;
		/* Offset inside the full decompressed extent */
		u32 bvec_offset;
		void *kaddr;

		bvec = bio_iter_iovec(orig_bio, orig_bio->bi_iter);
		/*
		 * cb->start may underflow, but subtracting that value can still
		 * give us correct offset inside the full decompressed extent.
		 */
		bvec_offset = file_offset_from_bvec(&bvec) - cb->start;

		/* Haven't reached the bvec range, exit */
		if (decompressed + buf_len <= bvec_offset)
			return 1;

		copy_start = max(cur_offset, bvec_offset);
		copy_len = min(bvec_offset + bvec.bv_len,
			       decompressed + buf_len) - copy_start;
		ASSERT(copy_len);

		/*
		 * Extra range check to ensure we didn't go beyond
		 * @buf + @buf_len.
		 */
		ASSERT(copy_start - decompressed < buf_len);

		kaddr = bvec_kmap_local(&bvec);
		memcpy(kaddr, buf + copy_start - decompressed, copy_len);
		kunmap_local(kaddr);

		cur_offset += copy_len;
		bio_advance(orig_bio, copy_len);
		/* Finished the bio */
		if (!orig_bio->bi_iter.bi_size)
			return 0;
	}
	return 1;
}

/*
 * Shannon Entropy calculation
 *
 * Pure byte distribution analysis fails to determine compressibility of data.
 * Try calculating entropy to estimate the average minimum number of bits
 * needed to encode the sampled data.
 *
 * For convenience, return the percentage of needed bits, instead of amount of
 * bits directly.
 *
 * @ENTROPY_LVL_ACEPTABLE - below that threshold, sample has low byte entropy
 *			    and can be compressible with high probability
 *
 * @ENTROPY_LVL_HIGH - data are not compressible with high probability
 *
 * Use of ilog2() decreases precision, we lower the LVL to 5 to compensate.
 */
#define ENTROPY_LVL_ACEPTABLE		(65)
#define ENTROPY_LVL_HIGH		(80)

/*
 * For increased precision in shannon_entropy calculation,
 * let's do pow(n, M) to save more digits after comma:
 *
 * - maximum int bit length is 64
 * - ilog2(MAX_SAMPLE_SIZE)	-> 13
 * - 13 * 4 = 52 < 64		-> M = 4
 *
 * So use pow(n, 4).
 */
static inline u32 ilog2_w(u64 n)
{
	return ilog2(n * n * n * n);
}

static u32 shannon_entropy(struct heuristic_ws *ws)
{
	const u32 entropy_max = 8 * ilog2_w(2);
	u32 entropy_sum = 0;
	u32 p, p_base, sz_base;
	u32 i;

	sz_base = ilog2_w(ws->sample_size);
	for (i = 0; i < BUCKET_SIZE && ws->bucket[i].count > 0; i++) {
		p = ws->bucket[i].count;
		p_base = ilog2_w(p);
		entropy_sum += p * (sz_base - p_base);
	}

	entropy_sum /= ws->sample_size;
	return entropy_sum * 100 / entropy_max;
}

#define RADIX_BASE		4U
#define COUNTERS_SIZE		(1U << RADIX_BASE)

static u8 get4bits(u64 num, int shift) {
	u8 low4bits;

	num >>= shift;
	/* Reverse order */
	low4bits = (COUNTERS_SIZE - 1) - (num % COUNTERS_SIZE);
	return low4bits;
}

/*
 * Use 4 bits as radix base
 * Use 16 u32 counters for calculating new position in buf array
 *
 * @array     - array that will be sorted
 * @array_buf - buffer array to store sorting results
 *              must be equal in size to @array
 * @num       - array size
 */
static void radix_sort(struct bucket_item *array, struct bucket_item *array_buf,
		       int num)
{
	u64 max_num;
	u64 buf_num;
	u32 counters[COUNTERS_SIZE];
	u32 new_addr;
	u32 addr;
	int bitlen;
	int shift;
	int i;

	/*
	 * Try avoid useless loop iterations for small numbers stored in big
	 * counters.  Example: 48 33 4 ... in 64bit array
	 */
	max_num = array[0].count;
	for (i = 1; i < num; i++) {
		buf_num = array[i].count;
		if (buf_num > max_num)
			max_num = buf_num;
	}

	buf_num = ilog2(max_num);
	bitlen = ALIGN(buf_num, RADIX_BASE * 2);

	shift = 0;
	while (shift < bitlen) {
		memset(counters, 0, sizeof(counters));

		for (i = 0; i < num; i++) {
			buf_num = array[i].count;
			addr = get4bits(buf_num, shift);
			counters[addr]++;
		}

		for (i = 1; i < COUNTERS_SIZE; i++)
			counters[i] += counters[i - 1];

		for (i = num - 1; i >= 0; i--) {
			buf_num = array[i].count;
			addr = get4bits(buf_num, shift);
			counters[addr]--;
			new_addr = counters[addr];
			array_buf[new_addr] = array[i];
		}

		shift += RADIX_BASE;

		/*
		 * Normal radix expects to move data from a temporary array, to
		 * the main one.  But that requires some CPU time. Avoid that
		 * by doing another sort iteration to original array instead of
		 * memcpy()
		 */
		memset(counters, 0, sizeof(counters));

		for (i = 0; i < num; i ++) {
			buf_num = array_buf[i].count;
			addr = get4bits(buf_num, shift);
			counters[addr]++;
		}

		for (i = 1; i < COUNTERS_SIZE; i++)
			counters[i] += counters[i - 1];

		for (i = num - 1; i >= 0; i--) {
			buf_num = array_buf[i].count;
			addr = get4bits(buf_num, shift);
			counters[addr]--;
			new_addr = counters[addr];
			array[new_addr] = array_buf[i];
		}

		shift += RADIX_BASE;
	}
}

/*
 * Size of the core byte set - how many bytes cover 90% of the sample
 *
 * There are several types of structured binary data that use nearly all byte
 * values. The distribution can be uniform and counts in all buckets will be
 * nearly the same (eg. encrypted data). Unlikely to be compressible.
 *
 * Other possibility is normal (Gaussian) distribution, where the data could
 * be potentially compressible, but we have to take a few more steps to decide
 * how much.
 *
 * @BYTE_CORE_SET_LOW  - main part of byte values repeated frequently,
 *                       compression algo can easy fix that
 * @BYTE_CORE_SET_HIGH - data have uniform distribution and with high
 *                       probability is not compressible
 */
#define BYTE_CORE_SET_LOW		(64)
#define BYTE_CORE_SET_HIGH		(200)

static int byte_core_set_size(struct heuristic_ws *ws)
{
	u32 i;
	u32 coreset_sum = 0;
	const u32 core_set_threshold = ws->sample_size * 90 / 100;
	struct bucket_item *bucket = ws->bucket;

	/* Sort in reverse order */
	radix_sort(ws->bucket, ws->bucket_b, BUCKET_SIZE);

	for (i = 0; i < BYTE_CORE_SET_LOW; i++)
		coreset_sum += bucket[i].count;

	if (coreset_sum > core_set_threshold)
		return i;

	for (; i < BYTE_CORE_SET_HIGH && bucket[i].count > 0; i++) {
		coreset_sum += bucket[i].count;
		if (coreset_sum > core_set_threshold)
			break;
	}

	return i;
}

/*
 * Count byte values in buckets.
 * This heuristic can detect textual data (configs, xml, json, html, etc).
 * Because in most text-like data byte set is restricted to limited number of
 * possible characters, and that restriction in most cases makes data easy to
 * compress.
 *
 * @BYTE_SET_THRESHOLD - consider all data within this byte set size:
 *	less - compressible
 *	more - need additional analysis
 */
#define BYTE_SET_THRESHOLD		(64)

static u32 byte_set_size(const struct heuristic_ws *ws)
{
	u32 i;
	u32 byte_set_size = 0;

	for (i = 0; i < BYTE_SET_THRESHOLD; i++) {
		if (ws->bucket[i].count > 0)
			byte_set_size++;
	}

	/*
	 * Continue collecting count of byte values in buckets.  If the byte
	 * set size is bigger then the threshold, it's pointless to continue,
	 * the detection technique would fail for this type of data.
	 */
	for (; i < BUCKET_SIZE; i++) {
		if (ws->bucket[i].count > 0) {
			byte_set_size++;
			if (byte_set_size > BYTE_SET_THRESHOLD)
				return byte_set_size;
		}
	}

	return byte_set_size;
}

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)
{
	struct page *page;
	pgoff_t index, index_end;
	u32 i, curr_sample_pos;
	u8 *in_data;

	/*
	 * Compression handles the input data by chunks of 128KiB
	 * (defined by BTRFS_MAX_UNCOMPRESSED)
	 *
	 * We do the same for the heuristic and loop over the whole range.
	 *
	 * MAX_SAMPLE_SIZE - calculated under assumption that heuristic will
	 * process no more than BTRFS_MAX_UNCOMPRESSED at a time.
	 */
	if (end - start > BTRFS_MAX_UNCOMPRESSED)
		end = start + BTRFS_MAX_UNCOMPRESSED;

	index = start >> PAGE_SHIFT;
	index_end = end >> PAGE_SHIFT;

	/* Don't miss unaligned end */
	if (!PAGE_ALIGNED(end))
		index_end++;

	curr_sample_pos = 0;
	while (index < index_end) {
		page = find_get_page(inode->i_mapping, index);
		in_data = kmap_local_page(page);
		/* Handle case where the start is not aligned to PAGE_SIZE */
		i = start % PAGE_SIZE;
		while (i < PAGE_SIZE - SAMPLING_READ_SIZE) {
			/* Don't sample any garbage from the last page */
			if (start > end - SAMPLING_READ_SIZE)
				break;
			memcpy(&ws->sample[curr_sample_pos], &in_data[i],
					SAMPLING_READ_SIZE);
			i += SAMPLING_INTERVAL;
			start += SAMPLING_INTERVAL;
			curr_sample_pos += SAMPLING_READ_SIZE;
		}
		kunmap_local(in_data);
		put_page(page);

		index++;
	}

	ws->sample_size = curr_sample_pos;
}

/*
 * Compression heuristic.
 *
 * The following types of analysis can be performed:
 * - detect mostly zero data
 * - detect data with low "byte set" size (text, etc)
 * - detect data with low/high "core byte" set
 *
 * Return non-zero if the compression should be done, 0 otherwise.
 */
int btrfs_compress_heuristic(struct btrfs_inode *inode, u64 start, u64 end)
{
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	struct list_head *ws_list = get_workspace(fs_info, 0, 0);
	struct heuristic_ws *ws;
	u32 i;
	u8 byte;
	int ret = 0;

	ws = list_entry(ws_list, struct heuristic_ws, list);

	heuristic_collect_sample(&inode->vfs_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++) {
		byte = ws->sample[i];
		ws->bucket[byte].count++;
	}

	i = byte_set_size(ws);
	if (i < BYTE_SET_THRESHOLD) {
		ret = 2;
		goto out;
	}

	i = byte_core_set_size(ws);
	if (i <= BYTE_CORE_SET_LOW) {
		ret = 3;
		goto out;
	}

	if (i >= BYTE_CORE_SET_HIGH) {
		ret = 0;
		goto out;
	}

	i = shannon_entropy(ws);
	if (i <= ENTROPY_LVL_ACEPTABLE) {
		ret = 4;
		goto out;
	}

	/*
	 * For the levels below ENTROPY_LVL_HIGH, additional analysis would be
	 * needed to give green light to compression.
	 *
	 * For now just assume that compression at that level is not worth the
	 * resources because:
	 *
	 * 1. it is possible to defrag the data later
	 *
	 * 2. the data would turn out to be hardly compressible, eg. 150 byte
	 * values, every bucket has counter at level ~54. The heuristic would
	 * be confused. This can happen when data have some internal repeated
	 * patterns like "abbacbbc...". This can be detected by analyzing
	 * pairs of bytes, which is too costly.
	 */
	if (i < ENTROPY_LVL_HIGH) {
		ret = 5;
		goto out;
	} else {
		ret = 0;
		goto out;
	}

out:
	put_workspace(fs_info, 0, ws_list);
	return ret;
}

/*
 * Convert the compression suffix (eg. after "zlib" starting with ":") to level.
 *
 * If the resulting level exceeds the algo's supported levels, it will be clamped.
 *
 * Return <0 if no valid string can be found.
 * Return 0 if everything is fine.
 */
int btrfs_compress_str2level(unsigned int type, const char *str, int *level_ret)
{
	int level = 0;
	int ret;

	if (!type) {
		*level_ret = btrfs_compress_set_level(type, level);
		return 0;
	}

	if (str[0] == ':') {
		ret = kstrtoint(str + 1, 10, &level);
		if (ret)
			return ret;
	}

	*level_ret = btrfs_compress_set_level(type, level);
	return 0;
}
