AquilaOS documentation
How it works, and its code
Toggle main menu visibility
Loading...
Searching...
No Matches
flock.c
Go to the documentation of this file.
1
7
8
#include <
core/system.h
>
9
#include <
fs/vfs.h
>
10
#include <
net/socket.h
>
11
#include <
sys/sched.h
>
12
#include <
ds/queue.h
>
13
14
#include <aquila/fcntl.h>
15
#include <aquila/errno.h>
16
17
MALLOC_DEFINE
(M_FILE_LOCK,
"file-lock"
,
"flock() lock"
);
18
20
struct
file_lock
{
21
struct
vnode
*
vnode
;
/* the file it locks */
22
int
type
;
/* LOCK_SH, LOCK_EX, or 0 while not locked */
23
};
24
25
/* the locks held, and the threads waiting for one to be released */
26
static
struct
queue
locks
= {0};
27
static
struct
waitq
waiters
= {0};
28
31
static
int
lock_conflicts
(
struct
file_lock
*lock,
int
type)
32
{
33
queue_for
(node, &
locks
) {
34
struct
file_lock
*held = node->value;
35
36
if
(held != lock && held->
vnode
== lock->
vnode
&&
37
(
type
== LOCK_EX || held->
type
== LOCK_EX))
38
return
1;
39
}
40
41
return
0;
42
}
43
45
static
void
lock_unlock
(
struct
file_lock
*lock)
46
{
47
if
(!lock->
type
)
48
return
;
49
50
queue_remove(&
locks
, lock);
51
lock->
type
= 0;
52
waitq_wakeup
(&
waiters
);
53
}
54
67
int
vfs_file_flock
(
struct
file
*
file
,
int
op)
68
{
69
int
type
= op & ~LOCK_NB;
70
71
if
(
type
!= LOCK_SH &&
type
!= LOCK_EX &&
type
!= LOCK_UN)
72
return
-EINVAL;
73
74
if
(
file
->
flags
&
FILE_SOCKET
)
75
return
-EINVAL;
76
77
struct
file_lock
*lock =
file
->
lock
;
78
79
if
(
type
== LOCK_UN) {
80
if
(lock)
81
lock_unlock
(lock);
82
return
0;
83
}
84
85
if
(!lock) {
86
lock =
kmalloc
(
sizeof
(*lock), &M_FILE_LOCK,
M_ZERO
);
87
if
(!lock)
return
-ENOMEM;
88
89
lock->
vnode
=
file
->vnode;
90
file
->
lock
= lock;
91
}
92
93
while
(
lock_conflicts
(lock,
type
)) {
94
if
(op & LOCK_NB)
95
return
-EWOULDBLOCK;
96
97
int
err =
waitq_sleep
(&
waiters
);
98
99
if
(err)
100
return
err;
101
}
102
103
if
(!lock->
type
)
104
enqueue(&
locks
, lock);
105
106
/* changing an exclusive lock to a shared one may let others in */
107
if
(lock->
type
== LOCK_EX &&
type
== LOCK_SH)
108
waitq_wakeup
(&
waiters
);
109
110
lock->
type
=
type
;
111
return
0;
112
}
113
119
void
vfs_file_lock_release
(
struct
file
*
file
)
120
{
121
struct
file_lock
*lock =
file
->
lock
;
122
123
if
(!lock)
124
return
;
125
126
file
->
lock
=
NULL
;
127
lock_unlock
(lock);
128
kfree
(lock);
129
}
vfs_file_flock
int vfs_file_flock(struct file *file, int op)
Takes, changes or releases an open file's lock.
Definition
flock.c:67
waiters
static struct waitq waiters
Definition
flock.c:27
locks
static struct queue locks
Definition
flock.c:26
vfs_file_lock_release
void vfs_file_lock_release(struct file *file)
Releases an open file's lock when the file is closed.
Definition
flock.c:119
lock_conflicts
static int lock_conflicts(struct file_lock *lock, int type)
Says whether taking a lock of type conflicts with a lock that another open file holds on the same fil...
Definition
flock.c:31
lock_unlock
static void lock_unlock(struct file_lock *lock)
Releases a lock, and wakes up the threads waiting for one.
Definition
flock.c:45
system.h
MALLOC_DEFINE
#define MALLOC_DEFINE(type, _name, _desc)
Definition
kvmem.h:30
kmalloc
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition
kvmem.c:123
M_ZERO
#define M_ZERO
Definition
kvmem.h:26
kfree
void kfree(void *)
Frees an object that kmalloc() gave.
Definition
kvmem.c:146
queue.h
queue_for
#define queue_for(n, q)
Definition
queue.h:37
sched.h
socket.h
FILE_SOCKET
#define FILE_SOCKET
Definition
socket.h:70
NULL
#define NULL
Definition
stddef.h:27
file_lock
An open file's lock.
Definition
flock.c:20
file_lock::vnode
struct vnode * vnode
Definition
flock.c:21
file_lock::type
int type
Definition
flock.c:22
file
An open file (POSIX's "open file description", fs/file.c).
Definition
vfs.h:157
file::lock
struct file_lock * lock
Definition
vfs.h:167
file::flags
int flags
Definition
vfs.h:164
queue
A queue.
Definition
queue.h:29
waitq
Definition
waitq.h:19
vfs.h
waitq_wakeup
void waitq_wakeup(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, and every thread polling it.
Definition
waitq.c:178
waitq_sleep
int waitq_sleep(struct waitq *waitq)
Puts the current thread to sleep on a wait queue until it is woken up.
Definition
waitq.c:50
kernel
fs
flock.c
Generated by
1.18.0