1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
24 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
25 * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
26 * Copyright (c) 2014 Integros [integros.com]
27 */
28
29/* Portions Copyright 2010 Robert Milkowski */
30
31#ifndef	_SYS_DMU_OBJSET_H
32#define	_SYS_DMU_OBJSET_H
33
34#include <sys/spa.h>
35#include <sys/arc.h>
36#include <sys/txg.h>
37#include <sys/zfs_context.h>
38#include <sys/dnode.h>
39#include <sys/zio.h>
40#include <sys/zil.h>
41#include <sys/sa.h>
42#include <sys/zfs_ioctl.h>
43
44#ifdef	__cplusplus
45extern "C" {
46#endif
47
48extern krwlock_t os_lock;
49
50struct dsl_pool;
51struct dsl_dataset;
52struct dmu_tx;
53
54#define	OBJSET_PHYS_SIZE_V1	1024
55#define	OBJSET_PHYS_SIZE_V2	2048
56#define	OBJSET_PHYS_SIZE_V3	4096
57
58#define	OBJSET_BUF_HAS_USERUSED(buf) \
59	(arc_buf_size(buf) >= OBJSET_PHYS_SIZE_V2)
60#define	OBJSET_BUF_HAS_PROJECTUSED(buf) \
61	(arc_buf_size(buf) >= OBJSET_PHYS_SIZE_V3)
62
63#define	OBJSET_FLAG_USERACCOUNTING_COMPLETE	(1ULL << 0)
64#define	OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE	(1ULL << 1)
65#define	OBJSET_FLAG_PROJECTQUOTA_COMPLETE	(1ULL << 2)
66
67/* all flags are currently non-portable */
68#define	OBJSET_CRYPT_PORTABLE_FLAGS_MASK	(0)
69
70typedef struct objset_phys {
71	dnode_phys_t os_meta_dnode;
72	zil_header_t os_zil_header;
73	uint64_t os_type;
74	uint64_t os_flags;
75	uint8_t os_portable_mac[ZIO_OBJSET_MAC_LEN];
76	uint8_t os_local_mac[ZIO_OBJSET_MAC_LEN];
77	char os_pad0[OBJSET_PHYS_SIZE_V2 - sizeof (dnode_phys_t)*3 -
78	    sizeof (zil_header_t) - sizeof (uint64_t)*2 -
79	    2*ZIO_OBJSET_MAC_LEN];
80	dnode_phys_t os_userused_dnode;
81	dnode_phys_t os_groupused_dnode;
82	dnode_phys_t os_projectused_dnode;
83	char os_pad1[OBJSET_PHYS_SIZE_V3 - OBJSET_PHYS_SIZE_V2 -
84	    sizeof (dnode_phys_t)];
85} objset_phys_t;
86
87typedef int (*dmu_objset_upgrade_cb_t)(objset_t *);
88
89#define	OBJSET_PROP_UNINITIALIZED	((uint64_t)-1)
90struct objset {
91	/* Immutable: */
92	struct dsl_dataset *os_dsl_dataset;
93	spa_t *os_spa;
94	arc_buf_t *os_phys_buf;
95	objset_phys_t *os_phys;
96	boolean_t os_encrypted;
97
98	/*
99	 * The following "special" dnodes have no parent, are exempt
100	 * from dnode_move(), and are not recorded in os_dnodes, but they
101	 * root their descendents in this objset using handles anyway, so
102	 * that all access to dnodes from dbufs consistently uses handles.
103	 */
104	dnode_handle_t os_meta_dnode;
105	dnode_handle_t os_userused_dnode;
106	dnode_handle_t os_groupused_dnode;
107	dnode_handle_t os_projectused_dnode;
108	zilog_t *os_zil;
109
110	list_node_t os_evicting_node;
111
112	/* can change, under dsl_dir's locks: */
113	uint64_t os_dnodesize; /* default dnode size for new objects */
114	enum zio_checksum os_checksum;
115	enum zio_compress os_compress;
116	uint8_t os_copies;
117	enum zio_checksum os_dedup_checksum;
118	boolean_t os_dedup_verify;
119	zfs_logbias_op_t os_logbias;
120	zfs_cache_type_t os_primary_cache;
121	zfs_cache_type_t os_secondary_cache;
122	zfs_sync_type_t os_sync;
123	zfs_redundant_metadata_type_t os_redundant_metadata;
124	int os_recordsize;
125	/*
126	 * The next four values are used as a cache of whatever's on disk, and
127	 * are initialized the first time these properties are queried. Before
128	 * being initialized with their real values, their values are
129	 * OBJSET_PROP_UNINITIALIZED.
130	 */
131	uint64_t os_version;
132	uint64_t os_normalization;
133	uint64_t os_utf8only;
134	uint64_t os_casesensitivity;
135	/*
136	 * The largest zpl file block allowed in special class.
137	 * cached here instead of zfsvfs for easier access.
138	 */
139	int os_zpl_special_smallblock;
140
141	/*
142	 * Pointer is constant; the blkptr it points to is protected by
143	 * os_dsl_dataset->ds_bp_rwlock
144	 */
145	blkptr_t *os_rootbp;
146
147	/* no lock needed: */
148	struct dmu_tx *os_synctx; /* XXX sketchy */
149	zil_header_t os_zil_header;
150	multilist_t *os_synced_dnodes;
151	uint64_t os_flags;
152	uint64_t os_freed_dnodes;
153	boolean_t os_rescan_dnodes;
154	boolean_t os_raw_receive;
155
156	/* os_phys_buf should be written raw next txg */
157	boolean_t os_next_write_raw[TXG_SIZE];
158
159	/* Protected by os_obj_lock */
160	kmutex_t os_obj_lock;
161	uint64_t os_obj_next_chunk;
162
163	/* Per-CPU next object to allocate, protected by atomic ops. */
164	uint64_t *os_obj_next_percpu;
165	int os_obj_next_percpu_len;
166
167	/* Protected by os_lock */
168	kmutex_t os_lock;
169	multilist_t *os_dirty_dnodes[TXG_SIZE];
170	list_t os_dnodes;
171	list_t os_downgraded_dbufs;
172
173	/* Protects changes to DMU_{USER,GROUP,PROJECT}USED_OBJECT */
174	kmutex_t os_userused_lock;
175
176	/* stuff we store for the user */
177	kmutex_t os_user_ptr_lock;
178	void *os_user_ptr;
179	sa_os_t *os_sa;
180
181	/* kernel thread to upgrade this dataset */
182	kmutex_t os_upgrade_lock;
183	taskqid_t os_upgrade_id;
184	dmu_objset_upgrade_cb_t os_upgrade_cb;
185	boolean_t os_upgrade_exit;
186	int os_upgrade_status;
187};
188
189#define	DMU_META_OBJSET		0
190#define	DMU_META_DNODE_OBJECT	0
191#define	DMU_OBJECT_IS_SPECIAL(obj) ((int64_t)(obj) <= 0)
192#define	DMU_META_DNODE(os)	((os)->os_meta_dnode.dnh_dnode)
193#define	DMU_USERUSED_DNODE(os)	((os)->os_userused_dnode.dnh_dnode)
194#define	DMU_GROUPUSED_DNODE(os)	((os)->os_groupused_dnode.dnh_dnode)
195#define	DMU_PROJECTUSED_DNODE(os) ((os)->os_projectused_dnode.dnh_dnode)
196
197#define	DMU_OS_IS_L2CACHEABLE(os)				\
198	((os)->os_secondary_cache == ZFS_CACHE_ALL ||		\
199	(os)->os_secondary_cache == ZFS_CACHE_METADATA)
200
201#define	DMU_OS_IS_L2COMPRESSIBLE(os)	(zfs_mdcomp_disable == B_FALSE)
202
203/* called from zpl */
204int dmu_objset_hold(const char *name, void *tag, objset_t **osp);
205int dmu_objset_hold_flags(const char *name, boolean_t decrypt, void *tag,
206    objset_t **osp);
207int dmu_objset_own(const char *name, dmu_objset_type_t type,
208    boolean_t readonly, boolean_t decrypt, void *tag, objset_t **osp);
209int dmu_objset_own_obj(struct dsl_pool *dp, uint64_t obj,
210    dmu_objset_type_t type, boolean_t readonly, boolean_t decrypt,
211    void *tag, objset_t **osp);
212void dmu_objset_refresh_ownership(struct dsl_dataset *ds,
213    struct dsl_dataset **newds, boolean_t key_needed, void *tag);
214void dmu_objset_rele(objset_t *os, void *tag);
215void dmu_objset_rele_flags(objset_t *os, boolean_t decrypt, void *tag);
216void dmu_objset_disown(objset_t *os, boolean_t decrypt, void *tag);
217int dmu_objset_from_ds(struct dsl_dataset *ds, objset_t **osp);
218
219void dmu_objset_stats(objset_t *os, nvlist_t *nv);
220void dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat);
221void dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp,
222    uint64_t *usedobjsp, uint64_t *availobjsp);
223uint64_t dmu_objset_fsid_guid(objset_t *os);
224int dmu_objset_find_dp(struct dsl_pool *dp, uint64_t ddobj,
225    int func(struct dsl_pool *, struct dsl_dataset *, void *),
226    void *arg, int flags);
227int dmu_objset_prefetch(const char *name, void *arg);
228void dmu_objset_evict_dbufs(objset_t *os);
229timestruc_t dmu_objset_snap_cmtime(objset_t *os);
230
231/* called from dsl */
232void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx);
233boolean_t dmu_objset_is_dirty(objset_t *os, uint64_t txg);
234objset_t *dmu_objset_create_impl_dnstats(spa_t *spa, struct dsl_dataset *ds,
235    blkptr_t *bp, dmu_objset_type_t type, int levels, int blksz, int ibs,
236    dmu_tx_t *tx);
237objset_t *dmu_objset_create_impl(spa_t *spa, struct dsl_dataset *ds,
238    blkptr_t *bp, dmu_objset_type_t type, dmu_tx_t *tx);
239int dmu_objset_open_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp,
240    objset_t **osp);
241void dmu_objset_evict(objset_t *os);
242void dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx);
243void dmu_objset_userquota_get_ids(dnode_t *dn, boolean_t before, dmu_tx_t *tx);
244boolean_t dmu_objset_userused_enabled(objset_t *os);
245int dmu_objset_userspace_upgrade(objset_t *os);
246boolean_t dmu_objset_userspace_present(objset_t *os);
247boolean_t dmu_objset_userobjspace_upgradable(objset_t *os);
248boolean_t dmu_objset_userobjused_enabled(objset_t *os);
249boolean_t dmu_objset_userobjspace_present(objset_t *os);
250boolean_t dmu_objset_projectquota_enabled(objset_t *os);
251boolean_t dmu_objset_projectquota_present(objset_t *os);
252boolean_t dmu_objset_projectquota_upgradable(objset_t *os);
253void dmu_objset_id_quota_upgrade(objset_t *os);
254
255boolean_t dmu_objset_incompatible_encryption_version(objset_t *os);
256int dmu_fsname(const char *snapname, char *buf);
257
258void dmu_objset_evict_done(objset_t *os);
259void dmu_objset_willuse_space(objset_t *os, int64_t space, dmu_tx_t *tx);
260
261void dmu_objset_init(void);
262void dmu_objset_fini(void);
263
264#ifdef	__cplusplus
265}
266#endif
267
268#endif /* _SYS_DMU_OBJSET_H */
269