This repository has been archived by the owner on Jan 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
block_range.h
140 lines (126 loc) · 4.21 KB
/
block_range.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* Copyright (C) 2015-2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "block_device.h" /* for data_block_t */
/**
* struct block_range - Struct describing a range of blocks
* @start: First block in range.
* @end: Last block in range plus one.
*/
struct block_range {
data_block_t start;
data_block_t end;
};
#define BLOCK_RANGE_INITIAL_VALUE(block_range) {0,0}
/**
* block_range_empty - Check if block range is empty
* @range: Block range to check.
*
* Return: %true if @range is empty, %false otherwise.
*/
static inline bool block_range_empty(const struct block_range range)
{
assert(range.end >= range.start);
return range.start == range.end;
}
/*
* block_in_range - Check if block is in range
* @range: Block range to check.
* @block: Block to check.
*
* Return: %true if @block is in @range, %false otherwise.
*/
static inline bool block_in_range(const struct block_range range,
data_block_t block)
{
assert(range.end >= range.start);
return (block >= range.start && block < range.end);
}
/**
* block_in_range - Check if two block ranges have any overlap
* @a: Block range to check.
* @b: Block range to check.
*
* Return: %true if @a and @b share any blocks, %false otherwise.
*/
static inline bool block_range_overlap(const struct block_range a,
const struct block_range b)
{
return block_in_range(a, b.start) || block_in_range(b, a.start);
}
/**
* block_range_before - Check if a block range start before another block range
* @a: Block range to check.
* @b: Block range to check.
*
* Return: %true if @a starts at a lower block number than @b where the start
* block number of an empty block range is considered infinite, %false
* otherwise.
*/
static inline bool block_range_before(const struct block_range a,
const struct block_range b)
{
return !block_range_empty(a) && (block_range_empty(b) || a.start < b.start);
}
/**
* block_range_is_sub_range - Check if a block range is a subset of another range
* @range: Block range to check.
* @sub_range: Block range to check.
*
* Return: %true if every block in @sub_range is also in @range, %false
* otherwise. @sub_range is not allowed to be be empty.
*/
static inline bool block_range_is_sub_range(const struct block_range range,
const struct block_range sub_range)
{
assert(!block_range_empty(sub_range));
return block_in_range(range, sub_range.start) &&
block_in_range(range, sub_range.end - 1);
}
/**
* block_range_eq - Check if two block ranges are identical
* @a: Block range to check.
* @b: Block range to check.
*
* Return: %true if @a and @b are identical, %false otherwise.
*/
static inline bool block_range_eq(const struct block_range a,
const struct block_range b)
{
assert(a.end >= a.start);
assert(b.end >= b.start);
return a.start == b.start && a.end == b.end;
}
/**
* block_range_init_single - Initialize a block range containing a single block
* @range: Block range object to initialize.
* @block: Block that should be in @range.
*/
static inline void block_range_init_single(struct block_range *range,
data_block_t block)
{
range->start = block;
range->end = block + 1;
}
/**
* block_range_clear - Remove all blocks from a block range
* @range: Block range object to clear.
*/
static inline void block_range_clear(struct block_range *range)
{
range->start = 0;
range->end = 0;
}