1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * This file and its contents are supplied under the terms of the 6 * Common Development and Distribution License ("CDDL"), version 1.0. 7 * You may only use this file in accordance with the terms of version 8 * 1.0 of the CDDL. 9 * 10 * A full copy of the text of the CDDL should have accompanied this 11 * source. A copy of the CDDL is also available via the Internet at 12 * http://www.illumos.org/license/CDDL. 13 * 14 * CDDL HEADER END 15 */ 16 /* 17 * Copyright (c) 2013, 2018 by Delphix. All rights reserved. 18 */ 19 20 #ifndef _SYS_DSL_BOOKMARK_H 21 #define _SYS_DSL_BOOKMARK_H 22 23 #include <sys/zfs_context.h> 24 #include <sys/zfs_refcount.h> 25 #include <sys/dsl_dataset.h> 26 #include <sys/dsl_pool.h> 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /* 33 * On disk zap object. 34 */ 35 typedef struct zfs_bookmark_phys { 36 uint64_t zbm_guid; /* guid of bookmarked dataset */ 37 uint64_t zbm_creation_txg; /* birth transaction group */ 38 uint64_t zbm_creation_time; /* bookmark creation time */ 39 40 /* fields used for redacted send / recv */ 41 uint64_t zbm_redaction_obj; /* redaction list object */ 42 uint64_t zbm_flags; /* ZBM_FLAG_* */ 43 44 /* fields used for bookmark written size */ 45 uint64_t zbm_referenced_bytes_refd; 46 uint64_t zbm_compressed_bytes_refd; 47 uint64_t zbm_uncompressed_bytes_refd; 48 uint64_t zbm_referenced_freed_before_next_snap; 49 uint64_t zbm_compressed_freed_before_next_snap; 50 uint64_t zbm_uncompressed_freed_before_next_snap; 51 52 /* fields used for raw sends */ 53 uint64_t zbm_ivset_guid; 54 } zfs_bookmark_phys_t; 55 56 57 #define BOOKMARK_PHYS_SIZE_V1 (3 * sizeof (uint64_t)) 58 #define BOOKMARK_PHYS_SIZE_V2 (12 * sizeof (uint64_t)) 59 60 typedef enum zbm_flags { 61 ZBM_FLAG_HAS_FBN = (1 << 0), 62 ZBM_FLAG_SNAPSHOT_EXISTS = (1 << 1), 63 } zbm_flags_t; 64 65 typedef struct redaction_list_phys { 66 uint64_t rlp_last_object; 67 uint64_t rlp_last_blkid; 68 uint64_t rlp_num_entries; 69 uint64_t rlp_num_snaps; 70 uint64_t rlp_snaps[]; /* variable length */ 71 } redaction_list_phys_t; 72 73 typedef struct redaction_list { 74 dmu_buf_user_t rl_dbu; 75 redaction_list_phys_t *rl_phys; 76 dmu_buf_t *rl_bonus; 77 dmu_buf_t *rl_dbuf; 78 uint64_t rl_object; 79 zfs_refcount_t rl_longholds; 80 objset_t *rl_mos; 81 } redaction_list_t; 82 83 /* node in ds_bookmarks */ 84 typedef struct dsl_bookmark_node { 85 char *dbn_name; /* free with strfree() */ 86 kmutex_t dbn_lock; /* protects dirty/phys in block_killed */ 87 boolean_t dbn_dirty; /* in currently syncing txg */ 88 zfs_bookmark_phys_t dbn_phys; 89 avl_node_t dbn_node; 90 } dsl_bookmark_node_t; 91 92 typedef struct redact_block_phys { 93 uint64_t rbp_object; 94 uint64_t rbp_blkid; 95 /* 96 * The top 16 bits of this field represent the block size in sectors of 97 * the blocks in question; the bottom 48 bits are used to store the 98 * number of consecutive blocks that are in the redaction list. They 99 * should be accessed using the inline functions below. 100 */ 101 uint64_t rbp_size_count; 102 uint64_t rbp_padding; 103 } redact_block_phys_t; 104 105 typedef int (*rl_traverse_callback_t)(redact_block_phys_t *, void *); 106 107 108 typedef struct dsl_bookmark_create_arg { 109 nvlist_t *dbca_bmarks; 110 nvlist_t *dbca_errors; 111 } dsl_bookmark_create_arg_t; 112 113 typedef struct dsl_bookmark_create_redacted_arg { 114 const char *dbcra_bmark; 115 const char *dbcra_snap; 116 redaction_list_t **dbcra_rl; 117 uint64_t dbcra_numsnaps; 118 uint64_t *dbcra_snaps; 119 const void *dbcra_tag; 120 } dsl_bookmark_create_redacted_arg_t; 121 122 int dsl_bookmark_create(nvlist_t *, nvlist_t *); 123 int dsl_bookmark_create_nvl_validate(nvlist_t *); 124 int dsl_bookmark_create_check(void *arg, dmu_tx_t *tx); 125 void dsl_bookmark_create_sync(void *arg, dmu_tx_t *tx); 126 int dsl_bookmark_create_redacted(const char *, const char *, uint64_t, 127 uint64_t *, const void *, redaction_list_t **); 128 int dsl_get_bookmarks(const char *, nvlist_t *, nvlist_t *); 129 int dsl_get_bookmarks_impl(dsl_dataset_t *, nvlist_t *, nvlist_t *); 130 int dsl_get_bookmark_props(const char *, const char *, nvlist_t *); 131 int dsl_bookmark_destroy(nvlist_t *, nvlist_t *); 132 int dsl_bookmark_lookup(struct dsl_pool *, const char *, 133 struct dsl_dataset *, zfs_bookmark_phys_t *); 134 int dsl_bookmark_lookup_impl(dsl_dataset_t *, const char *, 135 zfs_bookmark_phys_t *); 136 int dsl_redaction_list_hold_obj(struct dsl_pool *, uint64_t, const void *, 137 redaction_list_t **); 138 void dsl_redaction_list_rele(redaction_list_t *, const void *); 139 void dsl_redaction_list_long_hold(struct dsl_pool *, redaction_list_t *, 140 const void *); 141 void dsl_redaction_list_long_rele(redaction_list_t *, const void *); 142 boolean_t dsl_redaction_list_long_held(redaction_list_t *); 143 int dsl_bookmark_init_ds(dsl_dataset_t *); 144 void dsl_bookmark_fini_ds(dsl_dataset_t *); 145 boolean_t dsl_bookmark_ds_destroyed(dsl_dataset_t *, dmu_tx_t *); 146 void dsl_bookmark_snapshotted(dsl_dataset_t *, dmu_tx_t *); 147 void dsl_bookmark_block_killed(dsl_dataset_t *, const blkptr_t *, dmu_tx_t *); 148 void dsl_bookmark_sync_done(dsl_dataset_t *, dmu_tx_t *); 149 void dsl_bookmark_node_add(dsl_dataset_t *, dsl_bookmark_node_t *, dmu_tx_t *); 150 uint64_t dsl_bookmark_latest_txg(dsl_dataset_t *); 151 int dsl_redaction_list_traverse(redaction_list_t *, zbookmark_phys_t *, 152 rl_traverse_callback_t, void *); 153 void dsl_bookmark_next_changed(dsl_dataset_t *, dsl_dataset_t *, dmu_tx_t *); 154 155 #ifdef __cplusplus 156 } 157 #endif 158 159 #endif /* _SYS_DSL_BOOKMARK_H */ 160