xref: /freebsd/sys/contrib/openzfs/include/sys/zfs_rlock.h (revision 22649d4dba730d46244fd2dff4fd174903c8379f)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * This file and its contents are supplied under the terms of the
4  * Common Development and Distribution License ("CDDL"), version 1.0.
5  * You may only use this file in accordance with the terms of version
6  * 1.0 of the CDDL.
7  *
8  * A full copy of the text of the CDDL should have accompanied this
9  * source.  A copy of the CDDL is also available via the Internet at
10  * https://opensource.org/license/CDDL-1.0.
11  */
12 /*
13  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
14  * Use is subject to license terms.
15  */
16 /*
17  * Copyright (c) 2018 by Delphix. All rights reserved.
18  */
19 
20 #ifndef	_SYS_FS_ZFS_RLOCK_H
21 #define	_SYS_FS_ZFS_RLOCK_H
22 
23 #ifdef	__cplusplus
24 extern "C" {
25 #endif
26 
27 #include <sys/avl.h>
28 
29 typedef enum {
30 	RL_READER,
31 	RL_WRITER,
32 	RL_APPEND
33 } zfs_rangelock_type_t;
34 
35 struct zfs_locked_range;
36 
37 typedef void (zfs_rangelock_cb_t)(struct zfs_locked_range *, void *);
38 
39 typedef struct zfs_rangelock {
40 	avl_tree_t rl_tree; /* contains locked_range_t */
41 	kmutex_t rl_lock;
42 	zfs_rangelock_cb_t *rl_cb;
43 	void *rl_arg;
44 } zfs_rangelock_t;
45 
46 typedef struct zfs_locked_range {
47 	zfs_rangelock_t *lr_rangelock; /* rangelock that this lock applies to */
48 	avl_node_t lr_node;	/* avl node link */
49 	uint64_t lr_offset;	/* file range offset */
50 	uint64_t lr_length;	/* file range length */
51 	uint_t lr_count;	/* range reference count in tree */
52 	zfs_rangelock_type_t lr_type; /* range type */
53 	kcondvar_t lr_write_cv;	/* cv for waiting writers */
54 	kcondvar_t lr_read_cv;	/* cv for waiting readers */
55 	uint8_t lr_proxy;	/* acting for original range */
56 	uint8_t lr_write_wanted; /* writer wants to lock this range */
57 	uint8_t lr_read_wanted;	/* reader wants to lock this range */
58 } zfs_locked_range_t;
59 
60 void zfs_rangelock_init(zfs_rangelock_t *, zfs_rangelock_cb_t *, void *);
61 void zfs_rangelock_fini(zfs_rangelock_t *);
62 
63 zfs_locked_range_t *zfs_rangelock_enter(zfs_rangelock_t *,
64     uint64_t, uint64_t, zfs_rangelock_type_t);
65 zfs_locked_range_t *zfs_rangelock_tryenter(zfs_rangelock_t *,
66     uint64_t, uint64_t, zfs_rangelock_type_t);
67 void zfs_rangelock_exit(zfs_locked_range_t *);
68 void zfs_rangelock_reduce(zfs_locked_range_t *, uint64_t, uint64_t);
69 
70 #ifdef	__cplusplus
71 }
72 #endif
73 
74 #endif	/* _SYS_FS_ZFS_RLOCK_H */
75