1104e2ed7Sperrin /* 2104e2ed7Sperrin * CDDL HEADER START 3104e2ed7Sperrin * 4104e2ed7Sperrin * The contents of this file are subject to the terms of the 5104e2ed7Sperrin * Common Development and Distribution License (the "License"). 6104e2ed7Sperrin * You may not use this file except in compliance with the License. 7104e2ed7Sperrin * 8104e2ed7Sperrin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9104e2ed7Sperrin * or http://www.opensolaris.org/os/licensing. 10104e2ed7Sperrin * See the License for the specific language governing permissions 11104e2ed7Sperrin * and limitations under the License. 12104e2ed7Sperrin * 13104e2ed7Sperrin * When distributing Covered Code, include this CDDL HEADER in each 14104e2ed7Sperrin * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15104e2ed7Sperrin * If applicable, add the following below this CDDL HEADER, with the 16104e2ed7Sperrin * fields enclosed by brackets "[]" replaced with your own identifying 17104e2ed7Sperrin * information: Portions Copyright [yyyy] [name of copyright owner] 18104e2ed7Sperrin * 19104e2ed7Sperrin * CDDL HEADER END 20104e2ed7Sperrin */ 21104e2ed7Sperrin /* 22104e2ed7Sperrin * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23104e2ed7Sperrin * Use is subject to license terms. 24104e2ed7Sperrin */ 25*79315247SMatthew Ahrens /* 26*79315247SMatthew Ahrens * Copyright (c) 2018 by Delphix. All rights reserved. 27*79315247SMatthew Ahrens */ 28104e2ed7Sperrin 29104e2ed7Sperrin #ifndef _SYS_FS_ZFS_RLOCK_H 30104e2ed7Sperrin #define _SYS_FS_ZFS_RLOCK_H 31104e2ed7Sperrin 32104e2ed7Sperrin #ifdef __cplusplus 33104e2ed7Sperrin extern "C" { 34104e2ed7Sperrin #endif 35104e2ed7Sperrin 36104e2ed7Sperrin typedef enum { 37104e2ed7Sperrin RL_READER, 38104e2ed7Sperrin RL_WRITER, 39104e2ed7Sperrin RL_APPEND 40*79315247SMatthew Ahrens } rangelock_type_t; 41104e2ed7Sperrin 42*79315247SMatthew Ahrens struct locked_range; 43104e2ed7Sperrin 44*79315247SMatthew Ahrens typedef void (rangelock_cb_t)(struct locked_range *, void *); 45104e2ed7Sperrin 46*79315247SMatthew Ahrens typedef struct rangelock { 47*79315247SMatthew Ahrens avl_tree_t rl_tree; /* contains locked_range_t */ 48*79315247SMatthew Ahrens kmutex_t rl_lock; 49*79315247SMatthew Ahrens rangelock_cb_t *rl_cb; 50*79315247SMatthew Ahrens void *rl_arg; 51*79315247SMatthew Ahrens } rangelock_t; 52104e2ed7Sperrin 53*79315247SMatthew Ahrens typedef struct locked_range { 54*79315247SMatthew Ahrens rangelock_t *lr_rangelock; /* rangelock that this lock applies to */ 55*79315247SMatthew Ahrens avl_node_t lr_node; /* avl node link */ 56*79315247SMatthew Ahrens uint64_t lr_offset; /* file range offset */ 57*79315247SMatthew Ahrens uint64_t lr_length; /* file range length */ 58*79315247SMatthew Ahrens uint_t lr_count; /* range reference count in tree */ 59*79315247SMatthew Ahrens rangelock_type_t lr_type; /* range type */ 60*79315247SMatthew Ahrens kcondvar_t lr_write_cv; /* cv for waiting writers */ 61*79315247SMatthew Ahrens kcondvar_t lr_read_cv; /* cv for waiting readers */ 62*79315247SMatthew Ahrens uint8_t lr_proxy; /* acting for original range */ 63*79315247SMatthew Ahrens uint8_t lr_write_wanted; /* writer wants to lock this range */ 64*79315247SMatthew Ahrens uint8_t lr_read_wanted; /* reader wants to lock this range */ 65*79315247SMatthew Ahrens } locked_range_t; 66104e2ed7Sperrin 67*79315247SMatthew Ahrens void rangelock_init(rangelock_t *, rangelock_cb_t *, void *); 68*79315247SMatthew Ahrens void rangelock_fini(rangelock_t *); 69104e2ed7Sperrin 70*79315247SMatthew Ahrens locked_range_t *rangelock_enter(rangelock_t *, 71*79315247SMatthew Ahrens uint64_t, uint64_t, rangelock_type_t); 72*79315247SMatthew Ahrens void rangelock_exit(locked_range_t *); 73*79315247SMatthew Ahrens void rangelock_reduce(locked_range_t *, uint64_t, uint64_t); 74104e2ed7Sperrin 75104e2ed7Sperrin #ifdef __cplusplus 76104e2ed7Sperrin } 77104e2ed7Sperrin #endif 78104e2ed7Sperrin 79104e2ed7Sperrin #endif /* _SYS_FS_ZFS_RLOCK_H */ 80