162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#ifndef BTRFS_MISC_H
462306a36Sopenharmony_ci#define BTRFS_MISC_H
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/sched.h>
762306a36Sopenharmony_ci#include <linux/wait.h>
862306a36Sopenharmony_ci#include <linux/math64.h>
962306a36Sopenharmony_ci#include <linux/rbtree.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/*
1262306a36Sopenharmony_ci * Enumerate bits using enum autoincrement. Define the @name as the n-th bit.
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci#define ENUM_BIT(name)                                  \
1562306a36Sopenharmony_ci	__ ## name ## _BIT,                             \
1662306a36Sopenharmony_ci	name = (1U << __ ## name ## _BIT),              \
1762306a36Sopenharmony_ci	__ ## name ## _SEQ = __ ## name ## _BIT
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic inline void cond_wake_up(struct wait_queue_head *wq)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	/*
2262306a36Sopenharmony_ci	 * This implies a full smp_mb barrier, see comments for
2362306a36Sopenharmony_ci	 * waitqueue_active why.
2462306a36Sopenharmony_ci	 */
2562306a36Sopenharmony_ci	if (wq_has_sleeper(wq))
2662306a36Sopenharmony_ci		wake_up(wq);
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic inline void cond_wake_up_nomb(struct wait_queue_head *wq)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	/*
3262306a36Sopenharmony_ci	 * Special case for conditional wakeup where the barrier required for
3362306a36Sopenharmony_ci	 * waitqueue_active is implied by some of the preceding code. Eg. one
3462306a36Sopenharmony_ci	 * of such atomic operations (atomic_dec_and_return, ...), or a
3562306a36Sopenharmony_ci	 * unlock/lock sequence, etc.
3662306a36Sopenharmony_ci	 */
3762306a36Sopenharmony_ci	if (waitqueue_active(wq))
3862306a36Sopenharmony_ci		wake_up(wq);
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic inline u64 mult_perc(u64 num, u32 percent)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	return div_u64(num * percent, 100);
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci/* Copy of is_power_of_two that is 64bit safe */
4662306a36Sopenharmony_cistatic inline bool is_power_of_two_u64(u64 n)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	return n != 0 && (n & (n - 1)) == 0;
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic inline bool has_single_bit_set(u64 n)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	return is_power_of_two_u64(n);
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/*
5762306a36Sopenharmony_ci * Simple bytenr based rb_tree relate structures
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * Any structure wants to use bytenr as single search index should have their
6062306a36Sopenharmony_ci * structure start with these members.
6162306a36Sopenharmony_ci */
6262306a36Sopenharmony_cistruct rb_simple_node {
6362306a36Sopenharmony_ci	struct rb_node rb_node;
6462306a36Sopenharmony_ci	u64 bytenr;
6562306a36Sopenharmony_ci};
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic inline struct rb_node *rb_simple_search(struct rb_root *root, u64 bytenr)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	struct rb_node *node = root->rb_node;
7062306a36Sopenharmony_ci	struct rb_simple_node *entry;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	while (node) {
7362306a36Sopenharmony_ci		entry = rb_entry(node, struct rb_simple_node, rb_node);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci		if (bytenr < entry->bytenr)
7662306a36Sopenharmony_ci			node = node->rb_left;
7762306a36Sopenharmony_ci		else if (bytenr > entry->bytenr)
7862306a36Sopenharmony_ci			node = node->rb_right;
7962306a36Sopenharmony_ci		else
8062306a36Sopenharmony_ci			return node;
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci	return NULL;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/*
8662306a36Sopenharmony_ci * Search @root from an entry that starts or comes after @bytenr.
8762306a36Sopenharmony_ci *
8862306a36Sopenharmony_ci * @root:	the root to search.
8962306a36Sopenharmony_ci * @bytenr:	bytenr to search from.
9062306a36Sopenharmony_ci *
9162306a36Sopenharmony_ci * Return the rb_node that start at or after @bytenr.  If there is no entry at
9262306a36Sopenharmony_ci * or after @bytner return NULL.
9362306a36Sopenharmony_ci */
9462306a36Sopenharmony_cistatic inline struct rb_node *rb_simple_search_first(struct rb_root *root,
9562306a36Sopenharmony_ci						     u64 bytenr)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	struct rb_node *node = root->rb_node, *ret = NULL;
9862306a36Sopenharmony_ci	struct rb_simple_node *entry, *ret_entry = NULL;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	while (node) {
10162306a36Sopenharmony_ci		entry = rb_entry(node, struct rb_simple_node, rb_node);
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci		if (bytenr < entry->bytenr) {
10462306a36Sopenharmony_ci			if (!ret || entry->bytenr < ret_entry->bytenr) {
10562306a36Sopenharmony_ci				ret = node;
10662306a36Sopenharmony_ci				ret_entry = entry;
10762306a36Sopenharmony_ci			}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci			node = node->rb_left;
11062306a36Sopenharmony_ci		} else if (bytenr > entry->bytenr) {
11162306a36Sopenharmony_ci			node = node->rb_right;
11262306a36Sopenharmony_ci		} else {
11362306a36Sopenharmony_ci			return node;
11462306a36Sopenharmony_ci		}
11562306a36Sopenharmony_ci	}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	return ret;
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistatic inline struct rb_node *rb_simple_insert(struct rb_root *root, u64 bytenr,
12162306a36Sopenharmony_ci					       struct rb_node *node)
12262306a36Sopenharmony_ci{
12362306a36Sopenharmony_ci	struct rb_node **p = &root->rb_node;
12462306a36Sopenharmony_ci	struct rb_node *parent = NULL;
12562306a36Sopenharmony_ci	struct rb_simple_node *entry;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	while (*p) {
12862306a36Sopenharmony_ci		parent = *p;
12962306a36Sopenharmony_ci		entry = rb_entry(parent, struct rb_simple_node, rb_node);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci		if (bytenr < entry->bytenr)
13262306a36Sopenharmony_ci			p = &(*p)->rb_left;
13362306a36Sopenharmony_ci		else if (bytenr > entry->bytenr)
13462306a36Sopenharmony_ci			p = &(*p)->rb_right;
13562306a36Sopenharmony_ci		else
13662306a36Sopenharmony_ci			return parent;
13762306a36Sopenharmony_ci	}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	rb_link_node(node, parent, p);
14062306a36Sopenharmony_ci	rb_insert_color(node, root);
14162306a36Sopenharmony_ci	return NULL;
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistatic inline bool bitmap_test_range_all_set(const unsigned long *addr,
14562306a36Sopenharmony_ci					     unsigned long start,
14662306a36Sopenharmony_ci					     unsigned long nbits)
14762306a36Sopenharmony_ci{
14862306a36Sopenharmony_ci	unsigned long found_zero;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	found_zero = find_next_zero_bit(addr, start + nbits, start);
15162306a36Sopenharmony_ci	return (found_zero == start + nbits);
15262306a36Sopenharmony_ci}
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistatic inline bool bitmap_test_range_all_zero(const unsigned long *addr,
15562306a36Sopenharmony_ci					      unsigned long start,
15662306a36Sopenharmony_ci					      unsigned long nbits)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	unsigned long found_set;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	found_set = find_next_bit(addr, start + nbits, start);
16162306a36Sopenharmony_ci	return (found_set == start + nbits);
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#endif
165