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