Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sbin/hastd/rangelock.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2010 The FreeBSD Foundation
5
*
6
* This software was developed by Pawel Jakub Dawidek under sponsorship from
7
* the FreeBSD Foundation.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
22
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
* SUCH DAMAGE.
29
*/
30
31
#include <sys/cdefs.h>
32
#include <sys/queue.h>
33
34
#include <stdbool.h>
35
#include <stdlib.h>
36
#include <unistd.h>
37
38
#include <pjdlog.h>
39
40
#include "rangelock.h"
41
42
#ifndef PJDLOG_ASSERT
43
#include <assert.h>
44
#define PJDLOG_ASSERT(...) assert(__VA_ARGS__)
45
#endif
46
47
#define RANGELOCKS_MAGIC 0x94310c
48
struct rangelocks {
49
int rls_magic; /* Magic value. */
50
TAILQ_HEAD(, rlock) rls_locks; /* List of locked ranges. */
51
};
52
53
struct rlock {
54
off_t rl_start;
55
off_t rl_end;
56
TAILQ_ENTRY(rlock) rl_next;
57
};
58
59
int
60
rangelock_init(struct rangelocks **rlsp)
61
{
62
struct rangelocks *rls;
63
64
PJDLOG_ASSERT(rlsp != NULL);
65
66
rls = malloc(sizeof(*rls));
67
if (rls == NULL)
68
return (-1);
69
70
TAILQ_INIT(&rls->rls_locks);
71
72
rls->rls_magic = RANGELOCKS_MAGIC;
73
*rlsp = rls;
74
75
return (0);
76
}
77
78
void
79
rangelock_free(struct rangelocks *rls)
80
{
81
struct rlock *rl;
82
83
PJDLOG_ASSERT(rls->rls_magic == RANGELOCKS_MAGIC);
84
85
rls->rls_magic = 0;
86
87
while ((rl = TAILQ_FIRST(&rls->rls_locks)) != NULL) {
88
TAILQ_REMOVE(&rls->rls_locks, rl, rl_next);
89
free(rl);
90
}
91
free(rls);
92
}
93
94
int
95
rangelock_add(struct rangelocks *rls, off_t offset, off_t length)
96
{
97
struct rlock *rl;
98
99
PJDLOG_ASSERT(rls->rls_magic == RANGELOCKS_MAGIC);
100
101
rl = malloc(sizeof(*rl));
102
if (rl == NULL)
103
return (-1);
104
rl->rl_start = offset;
105
rl->rl_end = offset + length;
106
TAILQ_INSERT_TAIL(&rls->rls_locks, rl, rl_next);
107
return (0);
108
}
109
110
void
111
rangelock_del(struct rangelocks *rls, off_t offset, off_t length)
112
{
113
struct rlock *rl;
114
115
PJDLOG_ASSERT(rls->rls_magic == RANGELOCKS_MAGIC);
116
117
TAILQ_FOREACH(rl, &rls->rls_locks, rl_next) {
118
if (rl->rl_start == offset && rl->rl_end == offset + length)
119
break;
120
}
121
PJDLOG_ASSERT(rl != NULL);
122
TAILQ_REMOVE(&rls->rls_locks, rl, rl_next);
123
free(rl);
124
}
125
126
bool
127
rangelock_islocked(struct rangelocks *rls, off_t offset, off_t length)
128
{
129
struct rlock *rl;
130
off_t end;
131
132
PJDLOG_ASSERT(rls->rls_magic == RANGELOCKS_MAGIC);
133
134
end = offset + length;
135
TAILQ_FOREACH(rl, &rls->rls_locks, rl_next) {
136
if (rl->rl_start < end && rl->rl_end > offset)
137
break;
138
}
139
return (rl != NULL);
140
}
141
142