1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* 27 * Copyright (c) 2018 by Delphix. All rights reserved. 28 */ 29 30 #ifndef _SYS_FS_ZFS_RLOCK_H 31 #define _SYS_FS_ZFS_RLOCK_H 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #include <sys/avl.h> 38 39 typedef enum { 40 RL_READER, 41 RL_WRITER, 42 RL_APPEND 43 } zfs_rangelock_type_t; 44 45 struct zfs_locked_range; 46 47 typedef void (zfs_rangelock_cb_t)(struct zfs_locked_range *, void *); 48 49 typedef struct zfs_rangelock { 50 avl_tree_t rl_tree; /* contains locked_range_t */ 51 kmutex_t rl_lock; 52 zfs_rangelock_cb_t *rl_cb; 53 void *rl_arg; 54 } zfs_rangelock_t; 55 56 typedef struct zfs_locked_range { 57 zfs_rangelock_t *lr_rangelock; /* rangelock that this lock applies to */ 58 avl_node_t lr_node; /* avl node link */ 59 uint64_t lr_offset; /* file range offset */ 60 uint64_t lr_length; /* file range length */ 61 uint_t lr_count; /* range reference count in tree */ 62 zfs_rangelock_type_t lr_type; /* range type */ 63 kcondvar_t lr_write_cv; /* cv for waiting writers */ 64 kcondvar_t lr_read_cv; /* cv for waiting readers */ 65 uint8_t lr_proxy; /* acting for original range */ 66 uint8_t lr_write_wanted; /* writer wants to lock this range */ 67 uint8_t lr_read_wanted; /* reader wants to lock this range */ 68 } zfs_locked_range_t; 69 70 void zfs_rangelock_init(zfs_rangelock_t *, zfs_rangelock_cb_t *, void *); 71 void zfs_rangelock_fini(zfs_rangelock_t *); 72 73 zfs_locked_range_t *zfs_rangelock_enter(zfs_rangelock_t *, 74 uint64_t, uint64_t, zfs_rangelock_type_t); 75 zfs_locked_range_t *zfs_rangelock_tryenter(zfs_rangelock_t *, 76 uint64_t, uint64_t, zfs_rangelock_type_t); 77 void zfs_rangelock_exit(zfs_locked_range_t *); 78 void zfs_rangelock_reduce(zfs_locked_range_t *, uint64_t, uint64_t); 79 80 #ifdef __cplusplus 81 } 82 #endif 83 84 #endif /* _SYS_FS_ZFS_RLOCK_H */ 85