diff options
Diffstat (limited to 'include')
30 files changed, 386 insertions, 228 deletions
diff --git a/include/libzfs.h b/include/libzfs.h index d51a71d75..3826c2cc8 100644 --- a/include/libzfs.h +++ b/include/libzfs.h @@ -563,7 +563,7 @@ extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t, extern int zfs_create_ancestors(libzfs_handle_t *, const char *); extern int zfs_destroy(zfs_handle_t *, boolean_t); extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t); -extern int zfs_destroy_snaps_nvl(zfs_handle_t *, nvlist_t *, boolean_t); +extern int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t); extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *); extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *); extern int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, @@ -606,8 +606,8 @@ extern int zfs_send(zfs_handle_t *, const char *, const char *, sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **); extern int zfs_promote(zfs_handle_t *); -extern int zfs_hold(zfs_handle_t *, const char *, const char *, boolean_t, - boolean_t, boolean_t, int, uint64_t, uint64_t); +extern int zfs_hold(zfs_handle_t *, const char *, const char *, + boolean_t, boolean_t, int); extern int zfs_release(zfs_handle_t *, const char *, const char *, boolean_t); extern int zfs_get_holds(zfs_handle_t *, nvlist_t **); extern uint64_t zvol_volsize_to_reservation(uint64_t, nvlist_t *); diff --git a/include/libzfs_core.h b/include/libzfs_core.h index 9edc884a1..f5fd6cda9 100644 --- a/include/libzfs_core.h +++ b/include/libzfs_core.h @@ -46,6 +46,10 @@ int lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist); int lzc_snaprange_space(const char *firstsnap, const char *lastsnap, uint64_t *usedp); +int lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist); +int lzc_release(nvlist_t *holds, nvlist_t **errlist); +int lzc_get_holds(const char *snapname, nvlist_t **holdsp); + int lzc_send(const char *snapname, const char *fromsnap, int fd); int lzc_receive(const char *snapname, nvlist_t *props, const char *origin, boolean_t force, int fd); diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index 2245ff445..34c715101 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -12,6 +12,7 @@ COMMON_H = \ $(top_srcdir)/include/sys/dmu.h \ $(top_srcdir)/include/sys/dmu_impl.h \ $(top_srcdir)/include/sys/dmu_objset.h \ + $(top_srcdir)/include/sys/dmu_send.h \ $(top_srcdir)/include/sys/dmu_traverse.h \ $(top_srcdir)/include/sys/dmu_tx.h \ $(top_srcdir)/include/sys/dmu_zfetch.h \ @@ -19,11 +20,13 @@ COMMON_H = \ $(top_srcdir)/include/sys/dsl_dataset.h \ $(top_srcdir)/include/sys/dsl_deadlist.h \ $(top_srcdir)/include/sys/dsl_deleg.h \ + $(top_srcdir)/include/sys/dsl_destroy.h \ $(top_srcdir)/include/sys/dsl_dir.h \ $(top_srcdir)/include/sys/dsl_pool.h \ $(top_srcdir)/include/sys/dsl_prop.h \ $(top_srcdir)/include/sys/dsl_scan.h \ $(top_srcdir)/include/sys/dsl_synctask.h \ + $(top_srcdir)/include/sys/dsl_userhold.h \ $(top_srcdir)/include/sys/efi_partition.h \ $(top_srcdir)/include/sys/metaslab.h \ $(top_srcdir)/include/sys/metaslab_impl.h \ @@ -65,8 +68,8 @@ COMMON_H = \ $(top_srcdir)/include/sys/zfs_sa.h \ $(top_srcdir)/include/sys/zfs_stat.h \ $(top_srcdir)/include/sys/zfs_vfsops.h \ - $(top_srcdir)/include/sys/zfs_znode.h \ $(top_srcdir)/include/sys/zfs_vnops.h \ + $(top_srcdir)/include/sys/zfs_znode.h \ $(top_srcdir)/include/sys/zil.h \ $(top_srcdir)/include/sys/zil_impl.h \ $(top_srcdir)/include/sys/zio_checksum.h \ diff --git a/include/sys/arc.h b/include/sys/arc.h index 67882197a..8c10d947c 100644 --- a/include/sys/arc.h +++ b/include/sys/arc.h @@ -100,7 +100,7 @@ arc_buf_t *arc_loan_buf(spa_t *spa, int size); void arc_return_buf(arc_buf_t *buf, void *tag); void arc_loan_inuse_buf(arc_buf_t *buf, void *tag); void arc_buf_add_ref(arc_buf_t *buf, void *tag); -int arc_buf_remove_ref(arc_buf_t *buf, void *tag); +boolean_t arc_buf_remove_ref(arc_buf_t *buf, void *tag); int arc_buf_size(arc_buf_t *buf); void arc_release(arc_buf_t *buf, void *tag); int arc_released(arc_buf_t *buf); diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h index 394fdfb15..8cd1fde01 100644 --- a/include/sys/dbuf.h +++ b/include/sys/dbuf.h @@ -307,20 +307,17 @@ void dbuf_fini(void); boolean_t dbuf_is_metadata(dmu_buf_impl_t *db); -#define DBUF_IS_METADATA(_db) \ - (dbuf_is_metadata(_db)) - #define DBUF_GET_BUFC_TYPE(_db) \ - (DBUF_IS_METADATA(_db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA) + (dbuf_is_metadata(_db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA) #define DBUF_IS_CACHEABLE(_db) \ ((_db)->db_objset->os_primary_cache == ZFS_CACHE_ALL || \ - (DBUF_IS_METADATA(_db) && \ + (dbuf_is_metadata(_db) && \ ((_db)->db_objset->os_primary_cache == ZFS_CACHE_METADATA))) #define DBUF_IS_L2CACHEABLE(_db) \ ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_ALL || \ - (DBUF_IS_METADATA(_db) && \ + (dbuf_is_metadata(_db) && \ ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_METADATA))) #define DBUF_IS_L2COMPRESSIBLE(_db) \ diff --git a/include/sys/dmu.h b/include/sys/dmu.h index c50df391e..b0db7604d 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -214,6 +214,11 @@ typedef enum dmu_object_type { DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE), } dmu_object_type_t; +typedef enum txg_how { + TXG_WAIT = 1, + TXG_NOWAIT, +} txg_how_t; + void byteswap_uint64_array(void *buf, size_t size); void byteswap_uint32_array(void *buf, size_t size); void byteswap_uint16_array(void *buf, size_t size); @@ -252,22 +257,19 @@ void dmu_objset_rele(objset_t *os, void *tag); void dmu_objset_disown(objset_t *os, void *tag); int dmu_objset_open_ds(struct dsl_dataset *ds, objset_t **osp); -int dmu_objset_evict_dbufs(objset_t *os); +void dmu_objset_evict_dbufs(objset_t *os); int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags, void (*func)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx), void *arg); -int dmu_objset_clone(const char *name, struct dsl_dataset *clone_origin, - uint64_t flags); -int dmu_objset_destroy(const char *name, boolean_t defer); -int dmu_snapshots_destroy_nvl(struct nvlist *snaps, boolean_t defer, +int dmu_objset_clone(const char *name, const char *origin); +int dsl_destroy_snapshots_nvl(struct nvlist *snaps, boolean_t defer, struct nvlist *errlist); -int dmu_objset_snapshot(struct nvlist *snaps, struct nvlist *, struct nvlist *); int dmu_objset_snapshot_one(const char *fsname, const char *snapname); int dmu_objset_snapshot_tmp(const char *, const char *, int); -int dmu_objset_rename(const char *name, const char *newname, - boolean_t recursive); int dmu_objset_find(char *name, int func(const char *, void *), void *arg, int flags); void dmu_objset_byteswap(void *buf, size_t size); +int dsl_dataset_rename_snapshot(const char *fsname, + const char *oldsnapname, const char *newsnapname, boolean_t recursive); typedef struct dmu_buf { uint64_t db_object; /* object that this buffer is part of */ @@ -537,7 +539,7 @@ void dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t object); void dmu_tx_hold_sa(dmu_tx_t *tx, struct sa_handle *hdl, boolean_t may_grow); void dmu_tx_hold_sa_create(dmu_tx_t *tx, int total_size); void dmu_tx_abort(dmu_tx_t *tx); -int dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how); +int dmu_tx_assign(dmu_tx_t *tx, enum txg_how txg_how); void dmu_tx_wait(dmu_tx_t *tx); void dmu_tx_commit(dmu_tx_t *tx); @@ -785,36 +787,8 @@ typedef void (*dmu_traverse_cb_t)(objset_t *os, void *arg, struct blkptr *bp, void dmu_traverse_objset(objset_t *os, uint64_t txg_start, dmu_traverse_cb_t cb, void *arg); -int dmu_send(objset_t *tosnap, objset_t *fromsnap, - int outfd, struct vnode *vp, offset_t *off); -int dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, uint64_t *sizep); - -typedef struct dmu_recv_cookie { - /* - * This structure is opaque! - * - * If logical and real are different, we are recving the stream - * into the "real" temporary clone, and then switching it with - * the "logical" target. - */ - struct dsl_dataset *drc_logical_ds; - struct dsl_dataset *drc_real_ds; - struct drr_begin *drc_drrb; - char *drc_tosnap; - char *drc_top_ds; - boolean_t drc_newfs; - boolean_t drc_force; - struct avl_tree *drc_guid_to_ds_map; -} dmu_recv_cookie_t; - -int dmu_recv_begin(char *tofs, char *tosnap, char *topds, struct drr_begin *, - boolean_t force, objset_t *origin, dmu_recv_cookie_t *); -int dmu_recv_stream(dmu_recv_cookie_t *drc, struct vnode *vp, offset_t *voffp, - int cleanup_fd, uint64_t *action_handlep); -int dmu_recv_end(dmu_recv_cookie_t *drc); - -int dmu_diff(objset_t *tosnap, objset_t *fromsnap, struct vnode *vp, - offset_t *off); +int dmu_diff(const char *tosnap_name, const char *fromsnap_name, + struct vnode *vp, offset_t *offp); /* CRC64 table */ #define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */ diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index 79d3a6bc0..7fe91bebe 100644 --- a/include/sys/dmu_objset.h +++ b/include/sys/dmu_objset.h @@ -44,6 +44,7 @@ extern "C" { extern krwlock_t os_lock; +struct dsl_pool; struct dsl_dataset; struct dmu_tx; @@ -115,8 +116,6 @@ struct objset { /* stuff we store for the user */ kmutex_t os_user_ptr_lock; void *os_user_ptr; - - /* SA layout/attribute registration */ sa_os_t *os_sa; }; @@ -146,10 +145,10 @@ void dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat); void dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp, uint64_t *usedobjsp, uint64_t *availobjsp); uint64_t dmu_objset_fsid_guid(objset_t *os); -int dmu_objset_find_spa(spa_t *spa, const char *name, - int func(spa_t *, uint64_t, const char *, void *), void *arg, int flags); -int dmu_objset_prefetch(const char *name, void *arg); -int dmu_objset_evict_dbufs(objset_t *os); +int dmu_objset_find_dp(struct dsl_pool *dp, uint64_t ddobj, + int func(struct dsl_pool *, struct dsl_dataset *, void *), + void *arg, int flags); +void dmu_objset_evict_dbufs(objset_t *os); timestruc_t dmu_objset_snap_cmtime(objset_t *os); /* called from dsl */ @@ -165,6 +164,7 @@ void dmu_objset_userquota_get_ids(dnode_t *dn, boolean_t before, dmu_tx_t *tx); boolean_t dmu_objset_userused_enabled(objset_t *os); int dmu_objset_userspace_upgrade(objset_t *os); boolean_t dmu_objset_userspace_present(objset_t *os); +int dmu_fsname(const char *snapname, char *buf); void dmu_objset_init(void); void dmu_objset_fini(void); diff --git a/include/sys/dmu_send.h b/include/sys/dmu_send.h new file mode 100644 index 000000000..ee0885a60 --- /dev/null +++ b/include/sys/dmu_send.h @@ -0,0 +1,66 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _DMU_SEND_H +#define _DMU_SEND_H + +#include <sys/inttypes.h> +#include <sys/spa.h> + +struct vnode; +struct dsl_dataset; +struct drr_begin; +struct avl_tree; + +int dmu_send(const char *tosnap, const char *fromsnap, int outfd, + struct vnode *vp, offset_t *off); +int dmu_send_estimate(struct dsl_dataset *ds, struct dsl_dataset *fromds, + uint64_t *sizep); +int dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap, + int outfd, struct vnode *vp, offset_t *off); + +typedef struct dmu_recv_cookie { + struct dsl_dataset *drc_ds; + struct drr_begin *drc_drrb; + const char *drc_tofs; + const char *drc_tosnap; + boolean_t drc_newfs; + boolean_t drc_byteswap; + boolean_t drc_force; + struct avl_tree *drc_guid_to_ds_map; + zio_cksum_t drc_cksum; + uint64_t drc_newsnapobj; +} dmu_recv_cookie_t; + +int dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, + boolean_t force, char *origin, dmu_recv_cookie_t *drc); +int dmu_recv_stream(dmu_recv_cookie_t *drc, struct vnode *vp, offset_t *voffp, + int cleanup_fd, uint64_t *action_handlep); +int dmu_recv_end(dmu_recv_cookie_t *drc); + +#endif /* _DMU_SEND_H */ diff --git a/include/sys/dmu_tx.h b/include/sys/dmu_tx.h index 40c1ded5d..48a507e34 100644 --- a/include/sys/dmu_tx.h +++ b/include/sys/dmu_tx.h @@ -22,6 +22,9 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ #ifndef _SYS_DMU_TX_H #define _SYS_DMU_TX_H @@ -133,10 +136,11 @@ extern dmu_tx_stats_t dmu_tx_stats; * These routines are defined in dmu.h, and are called by the user. */ dmu_tx_t *dmu_tx_create(objset_t *dd); -int dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how); +int dmu_tx_assign(dmu_tx_t *tx, txg_how_t txg_how); void dmu_tx_commit(dmu_tx_t *tx); void dmu_tx_abort(dmu_tx_t *tx); uint64_t dmu_tx_get_txg(dmu_tx_t *tx); +struct dsl_pool *dmu_tx_pool(dmu_tx_t *tx); void dmu_tx_wait(dmu_tx_t *tx); void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func, diff --git a/include/sys/dsl_dataset.h b/include/sys/dsl_dataset.h index 735ccbbd3..494f11b90 100644 --- a/include/sys/dsl_dataset.h +++ b/include/sys/dsl_dataset.h @@ -35,6 +35,7 @@ #include <sys/dsl_synctask.h> #include <sys/zfs_context.h> #include <sys/dsl_deadlist.h> +#include <sys/refcount.h> #ifdef __cplusplus extern "C" { @@ -48,10 +49,8 @@ struct dsl_pool; #define DS_IS_INCONSISTENT(ds) \ ((ds)->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) /* - * NB: nopromote can not yet be set, but we want support for it in this - * on-disk version, so that we don't need to upgrade for it later. It - * will be needed when we implement 'zfs split' (where the split off - * clone should not be promoted). + * Note: nopromote can not yet be set, but we want support for it in this + * on-disk version, so that we don't need to upgrade for it later. */ #define DS_FLAG_NOPROMOTE (1ULL<<1) @@ -76,6 +75,8 @@ struct dsl_pool; */ #define DS_FLAG_CI_DATASET (1ULL<<16) +#define DS_CREATE_FLAG_NODIRTY (1ULL<<24) + typedef struct dsl_dataset_phys { uint64_t ds_dir_obj; /* DMU_OT_DSL_DIR */ uint64_t ds_prev_snap_obj; /* DMU_OT_DSL_DATASET */ @@ -125,9 +126,6 @@ typedef struct dsl_dataset { dsl_deadlist_t ds_deadlist; bplist_t ds_pending_deadlist; - /* to protect against multiple concurrent incremental recv */ - kmutex_t ds_recvlock; - /* protected by lock on pool's dp_dirty_datasets list */ txg_node_t ds_dirty_link; list_node_t ds_synced_link; @@ -139,13 +137,15 @@ typedef struct dsl_dataset { kmutex_t ds_lock; objset_t *ds_objset; uint64_t ds_userrefs; + void *ds_owner; /* - * ds_owner is protected by the ds_rwlock and the ds_lock + * Long holds prevent the ds from being destroyed; they allow the + * ds to remain held even after dropping the dp_config_rwlock. + * Owning counts as a long hold. See the comments above + * dsl_pool_hold() for details. */ - krwlock_t ds_rwlock; - kcondvar_t ds_exclusive_cv; - void *ds_owner; + refcount_t ds_longholds; /* no locking; only for making guesses */ uint64_t ds_trysnap_txg; @@ -163,76 +163,42 @@ typedef struct dsl_dataset { char ds_snapname[MAXNAMELEN]; } dsl_dataset_t; -struct dsl_ds_destroyarg { - dsl_dataset_t *ds; /* ds to destroy */ - dsl_dataset_t *rm_origin; /* also remove our origin? */ - boolean_t is_origin_rm; /* set if removing origin snap */ - boolean_t defer; /* destroy -d requested? */ - boolean_t releasing; /* destroying due to release? */ - boolean_t need_prep; /* do we need to retry due to EBUSY? */ -}; - /* * The max length of a temporary tag prefix is the number of hex digits * required to express UINT64_MAX plus one for the hyphen. */ #define MAX_TAG_PREFIX_LEN 17 -struct dsl_ds_holdarg { - dsl_sync_task_group_t *dstg; - const char *htag; - char *snapname; - boolean_t recursive; - boolean_t gotone; - boolean_t temphold; - char failed[MAXPATHLEN]; -}; - #define dsl_dataset_is_snapshot(ds) \ ((ds)->ds_phys->ds_num_children != 0) #define DS_UNIQUE_IS_ACCURATE(ds) \ (((ds)->ds_phys->ds_flags & DS_FLAG_UNIQUE_ACCURATE) != 0) -int dsl_dataset_hold(const char *name, void *tag, dsl_dataset_t **dsp); -int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, - void *tag, dsl_dataset_t **); -int dsl_dataset_own(const char *name, boolean_t inconsistentok, +int dsl_dataset_hold(struct dsl_pool *dp, const char *name, void *tag, + dsl_dataset_t **dsp); +int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, void *tag, + dsl_dataset_t **); +void dsl_dataset_rele(dsl_dataset_t *ds, void *tag); +int dsl_dataset_own(struct dsl_pool *dp, const char *name, void *tag, dsl_dataset_t **dsp); int dsl_dataset_own_obj(struct dsl_pool *dp, uint64_t dsobj, - boolean_t inconsistentok, void *tag, dsl_dataset_t **dsp); -void dsl_dataset_name(dsl_dataset_t *ds, char *name); -void dsl_dataset_rele(dsl_dataset_t *ds, void *tag); + void *tag, dsl_dataset_t **dsp); void dsl_dataset_disown(dsl_dataset_t *ds, void *tag); -void dsl_dataset_drop_ref(dsl_dataset_t *ds, void *tag); -boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, boolean_t inconsistentok, - void *tag); -void dsl_dataset_make_exclusive(dsl_dataset_t *ds, void *tag); +void dsl_dataset_name(dsl_dataset_t *ds, char *name); +boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, void *tag); void dsl_register_onexit_hold_cleanup(dsl_dataset_t *ds, const char *htag, minor_t minor); uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname, dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *); uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, uint64_t flags, dmu_tx_t *tx); -int dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer); -dsl_checkfunc_t dsl_dataset_destroy_check; -dsl_syncfunc_t dsl_dataset_destroy_sync; -dsl_syncfunc_t dsl_dataset_user_hold_sync; -int dsl_dataset_snapshot_check(dsl_dataset_t *ds, const char *, dmu_tx_t *tx); -void dsl_dataset_snapshot_sync(dsl_dataset_t *ds, const char *, dmu_tx_t *tx); -int dsl_dataset_rename(char *name, const char *newname, boolean_t recursive); +int dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors); int dsl_dataset_promote(const char *name, char *conflsnap); -int dsl_dataset_clone_swap(dsl_dataset_t *clone, dsl_dataset_t *origin_head, - boolean_t force); -int dsl_dataset_user_hold(char *dsname, char *snapname, char *htag, - boolean_t recursive, boolean_t temphold, int cleanup_fd); -int dsl_dataset_user_hold_for_send(dsl_dataset_t *ds, char *htag, - boolean_t temphold); -int dsl_dataset_user_release(char *dsname, char *snapname, char *htag, - boolean_t recursive); -int dsl_dataset_user_release_tmp(struct dsl_pool *dp, uint64_t dsobj, - char *htag, boolean_t retry); -int dsl_dataset_get_holds(const char *dsname, nvlist_t **nvp); +int dsl_dataset_rename_snapshot(const char *fsname, + const char *oldsnapname, const char *newsnapname, boolean_t recursive); +int dsl_dataset_snapshot_tmp(const char *fsname, const char *snapname, + minor_t cleanup_minor, const char *htag); blkptr_t *dsl_dataset_get_blkptr(dsl_dataset_t *ds); void dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx); @@ -271,13 +237,35 @@ int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf); int dsl_dataset_check_quota(dsl_dataset_t *ds, boolean_t check_quota, uint64_t asize, uint64_t inflight, uint64_t *used, uint64_t *ref_rsrv); -int dsl_dataset_set_quota(const char *dsname, zprop_source_t source, +int dsl_dataset_set_refquota(const char *dsname, zprop_source_t source, uint64_t quota); -dsl_syncfunc_t dsl_dataset_set_quota_sync; -int dsl_dataset_set_reservation(const char *dsname, zprop_source_t source, +int dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source, uint64_t reservation); -int dsl_destroy_inconsistent(const char *dsname, void *arg); +boolean_t dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier); +void dsl_dataset_long_hold(dsl_dataset_t *ds, void *tag); +void dsl_dataset_long_rele(dsl_dataset_t *ds, void *tag); +boolean_t dsl_dataset_long_held(dsl_dataset_t *ds); + +int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone, + dsl_dataset_t *origin_head, boolean_t force); +void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone, + dsl_dataset_t *origin_head, dmu_tx_t *tx); +int dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname, + dmu_tx_t *tx); +void dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, + dmu_tx_t *tx); + +void dsl_dataset_remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj, + dmu_tx_t *tx); +void dsl_dataset_recalc_head_uniq(dsl_dataset_t *ds); +int dsl_dataset_get_snapname(dsl_dataset_t *ds); +int dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name, + uint64_t *value); +int dsl_dataset_snap_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx); +void dsl_dataset_set_refreservation_sync_impl(dsl_dataset_t *ds, + zprop_source_t source, uint64_t value, dmu_tx_t *tx); +int dsl_dataset_rollback(const char *fsname); #ifdef ZFS_DEBUG #define dprintf_ds(ds, fmt, ...) do { \ diff --git a/include/sys/dsl_destroy.h b/include/sys/dsl_destroy.h new file mode 100644 index 000000000..c5a70bb90 --- /dev/null +++ b/include/sys/dsl_destroy.h @@ -0,0 +1,52 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_DSL_DESTROY_H +#define _SYS_DSL_DESTROY_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct nvlist; +struct dsl_dataset; +struct dmu_tx; + +int dsl_destroy_snapshots_nvl(struct nvlist *snaps, boolean_t defer, + struct nvlist *errlist); +int dsl_destroy_snapshot(const char *name, boolean_t defer); +int dsl_destroy_head(const char *name); +int dsl_destroy_head_check_impl(struct dsl_dataset *ds, int expected_holds); +void dsl_destroy_head_sync_impl(struct dsl_dataset *ds, struct dmu_tx *tx); +int dsl_destroy_inconsistent(const char *dsname, void *arg); +void dsl_destroy_snapshot_sync_impl(struct dsl_dataset *ds, + boolean_t defer, struct dmu_tx *tx); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_DSL_DESTROY_H */ diff --git a/include/sys/dsl_dir.h b/include/sys/dsl_dir.h index 65ad202bb..2477e89af 100644 --- a/include/sys/dsl_dir.h +++ b/include/sys/dsl_dir.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_DSL_DIR_H @@ -101,18 +102,15 @@ struct dsl_dir { char dd_myname[MAXNAMELEN]; }; -void dsl_dir_close(dsl_dir_t *dd, void *tag); -int dsl_dir_open(const char *name, void *tag, dsl_dir_t **, const char **tail); -int dsl_dir_open_spa(spa_t *spa, const char *name, void *tag, dsl_dir_t **, - const char **tailp); -int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, +void dsl_dir_rele(dsl_dir_t *dd, void *tag); +int dsl_dir_hold(dsl_pool_t *dp, const char *name, void *tag, + dsl_dir_t **, const char **tail); +int dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj, const char *tail, void *tag, dsl_dir_t **); void dsl_dir_name(dsl_dir_t *dd, char *buf); int dsl_dir_namelen(dsl_dir_t *dd); uint64_t dsl_dir_create_sync(dsl_pool_t *dp, dsl_dir_t *pds, const char *name, dmu_tx_t *tx); -dsl_checkfunc_t dsl_dir_destroy_check; -dsl_syncfunc_t dsl_dir_destroy_sync; void dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv); uint64_t dsl_dir_space_available(dsl_dir_t *dd, dsl_dir_t *ancestor, int64_t delta, int ondiskonly); @@ -131,14 +129,15 @@ int dsl_dir_set_quota(const char *ddname, zprop_source_t source, uint64_t quota); int dsl_dir_set_reservation(const char *ddname, zprop_source_t source, uint64_t reservation); -int dsl_dir_rename(dsl_dir_t *dd, const char *newname); +int dsl_dir_rename(const char *oldname, const char *newname); int dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd, uint64_t space); -int dsl_dir_set_reservation_check(void *arg1, void *arg2, dmu_tx_t *tx); boolean_t dsl_dir_is_clone(dsl_dir_t *dd); void dsl_dir_new_refreservation(dsl_dir_t *dd, struct dsl_dataset *ds, uint64_t reservation, cred_t *cr, dmu_tx_t *tx); void dsl_dir_snap_cmtime_update(dsl_dir_t *dd); timestruc_t dsl_dir_snap_cmtime(dsl_dir_t *dd); +void dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value, + dmu_tx_t *tx); /* internal reserved dir name */ #define MOS_DIR_NAME "$MOS" diff --git a/include/sys/dsl_pool.h b/include/sys/dsl_pool.h index 4a4bf76ef..51b588e6a 100644 --- a/include/sys/dsl_pool.h +++ b/include/sys/dsl_pool.h @@ -36,6 +36,7 @@ #include <sys/arc.h> #include <sys/bpobj.h> #include <sys/bptree.h> +#include <sys/rrwlock.h> #ifdef __cplusplus extern "C" { @@ -129,7 +130,7 @@ typedef struct dsl_pool { * syncing context does not need to ever have it for read, since * nobody else could possibly have it for write. */ - krwlock_t dp_config_rwlock; + rrwlock_t dp_config_rwlock; zfs_all_blkstats_t *dp_blkstats; } dsl_pool_t; @@ -155,15 +156,20 @@ void dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx); void dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx); void dsl_pool_mos_diduse_space(dsl_pool_t *dp, int64_t used, int64_t comp, int64_t uncomp); +void dsl_pool_config_enter(dsl_pool_t *dp, void *tag); +void dsl_pool_config_exit(dsl_pool_t *dp, void *tag); +boolean_t dsl_pool_config_held(dsl_pool_t *dp); taskq_t *dsl_pool_iput_taskq(dsl_pool_t *dp); -extern int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, - const char *tag, uint64_t *now, dmu_tx_t *tx); -extern int dsl_pool_user_release(dsl_pool_t *dp, uint64_t dsobj, +int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, + const char *tag, uint64_t now, dmu_tx_t *tx); +int dsl_pool_user_release(dsl_pool_t *dp, uint64_t dsobj, const char *tag, dmu_tx_t *tx); -extern void dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp); +void dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp); int dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **); +int dsl_pool_hold(const char *name, void *tag, dsl_pool_t **dp); +void dsl_pool_rele(dsl_pool_t *dp, void *tag); void dsl_pool_tx_assign_add_usecs(dsl_pool_t *dp, uint64_t usecs); diff --git a/include/sys/dsl_prop.h b/include/sys/dsl_prop.h index b0d9a52cd..5fe18d6a7 100644 --- a/include/sys/dsl_prop.h +++ b/include/sys/dsl_prop.h @@ -54,58 +54,47 @@ typedef struct dsl_props_arg { zprop_source_t pa_source; } dsl_props_arg_t; -typedef struct dsl_prop_set_arg { - const char *psa_name; - zprop_source_t psa_source; - int psa_intsz; - int psa_numints; - const void *psa_value; - - /* - * Used to handle the special requirements of the quota and reservation - * properties. - */ - uint64_t psa_effective_value; -} dsl_prop_setarg_t; - int dsl_prop_register(struct dsl_dataset *ds, const char *propname, dsl_prop_changed_cb_t *callback, void *cbarg); int dsl_prop_unregister(struct dsl_dataset *ds, const char *propname, dsl_prop_changed_cb_t *callback, void *cbarg); -int dsl_prop_numcb(struct dsl_dataset *ds); +void dsl_prop_notify_all(struct dsl_dir *dd); +boolean_t dsl_prop_hascb(struct dsl_dataset *ds); int dsl_prop_get(const char *ddname, const char *propname, int intsz, int numints, void *buf, char *setpoint); int dsl_prop_get_integer(const char *ddname, const char *propname, uint64_t *valuep, char *setpoint); int dsl_prop_get_all(objset_t *os, nvlist_t **nvp); -int dsl_prop_get_received(objset_t *os, nvlist_t **nvp); +int dsl_prop_get_received(const char *dsname, nvlist_t **nvp); int dsl_prop_get_ds(struct dsl_dataset *ds, const char *propname, int intsz, int numints, void *buf, char *setpoint); +int dsl_prop_get_int_ds(struct dsl_dataset *ds, const char *propname, + uint64_t *valuep); int dsl_prop_get_dd(struct dsl_dir *dd, const char *propname, int intsz, int numints, void *buf, char *setpoint, boolean_t snapshot); -dsl_syncfunc_t dsl_props_set_sync; -int dsl_prop_set(const char *ddname, const char *propname, - zprop_source_t source, int intsz, int numints, const void *buf); +void dsl_props_set_sync_impl(struct dsl_dataset *ds, zprop_source_t source, + nvlist_t *props, dmu_tx_t *tx); +void dsl_prop_set_sync_impl(struct dsl_dataset *ds, const char *propname, + zprop_source_t source, int intsz, int numints, const void *value, + dmu_tx_t *tx); int dsl_props_set(const char *dsname, zprop_source_t source, nvlist_t *nvl); +int dsl_prop_set_int(const char *dsname, const char *propname, + zprop_source_t source, uint64_t value); +int dsl_prop_set_string(const char *dsname, const char *propname, + zprop_source_t source, const char *value); +int dsl_prop_inherit(const char *dsname, const char *propname, + zprop_source_t source); -void dsl_prop_setarg_init_uint64(dsl_prop_setarg_t *psa, const char *propname, - zprop_source_t source, uint64_t *value); -int dsl_prop_predict_sync(dsl_dir_t *dd, dsl_prop_setarg_t *psa); -#ifdef ZFS_DEBUG -void dsl_prop_check_prediction(dsl_dir_t *dd, dsl_prop_setarg_t *psa); -#define DSL_PROP_CHECK_PREDICTION(dd, psa) \ - dsl_prop_check_prediction((dd), (psa)) -#else -#define DSL_PROP_CHECK_PREDICTION(dd, psa) /* nothing */ -#endif +int dsl_prop_predict(dsl_dir_t *dd, const char *propname, + zprop_source_t source, uint64_t value, uint64_t *newvalp); /* flag first receive on or after SPA_VERSION_RECVD_PROPS */ -boolean_t dsl_prop_get_hasrecvd(objset_t *os); -void dsl_prop_set_hasrecvd(objset_t *os); -void dsl_prop_unset_hasrecvd(objset_t *os); +boolean_t dsl_prop_get_hasrecvd(const char *dsname); +int dsl_prop_set_hasrecvd(const char *dsname); +void dsl_prop_unset_hasrecvd(const char *dsname); void dsl_prop_nvlist_add_uint64(nvlist_t *nv, zfs_prop_t prop, uint64_t value); void dsl_prop_nvlist_add_string(nvlist_t *nv, diff --git a/include/sys/dsl_synctask.h b/include/sys/dsl_synctask.h index 9126290cd..ef86fb64c 100644 --- a/include/sys/dsl_synctask.h +++ b/include/sys/dsl_synctask.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_DSL_SYNCTASK_H @@ -34,43 +35,26 @@ extern "C" { struct dsl_pool; -typedef int (dsl_checkfunc_t)(void *, void *, dmu_tx_t *); -typedef void (dsl_syncfunc_t)(void *, void *, dmu_tx_t *); +typedef int (dsl_checkfunc_t)(void *, dmu_tx_t *); +typedef void (dsl_syncfunc_t)(void *, dmu_tx_t *); typedef struct dsl_sync_task { - list_node_t dst_node; + txg_node_t dst_node; + struct dsl_pool *dst_pool; + uint64_t dst_txg; + int dst_space; dsl_checkfunc_t *dst_checkfunc; dsl_syncfunc_t *dst_syncfunc; - void *dst_arg1; - void *dst_arg2; - int dst_err; + void *dst_arg; + int dst_error; + boolean_t dst_nowaiter; } dsl_sync_task_t; -typedef struct dsl_sync_task_group { - txg_node_t dstg_node; - list_t dstg_tasks; - struct dsl_pool *dstg_pool; - uint64_t dstg_txg; - int dstg_err; - int dstg_space; - boolean_t dstg_nowaiter; -} dsl_sync_task_group_t; - -dsl_sync_task_group_t *dsl_sync_task_group_create(struct dsl_pool *dp); -void dsl_sync_task_create(dsl_sync_task_group_t *dstg, - dsl_checkfunc_t *, dsl_syncfunc_t *, - void *arg1, void *arg2, int blocks_modified); -int dsl_sync_task_group_wait(dsl_sync_task_group_t *dstg); -void dsl_sync_task_group_nowait(dsl_sync_task_group_t *dstg, dmu_tx_t *tx); -void dsl_sync_task_group_destroy(dsl_sync_task_group_t *dstg); -void dsl_sync_task_group_sync(dsl_sync_task_group_t *dstg, dmu_tx_t *tx); - -int dsl_sync_task_do(struct dsl_pool *dp, - dsl_checkfunc_t *checkfunc, dsl_syncfunc_t *syncfunc, - void *arg1, void *arg2, int blocks_modified); -void dsl_sync_task_do_nowait(struct dsl_pool *dp, - dsl_checkfunc_t *checkfunc, dsl_syncfunc_t *syncfunc, - void *arg1, void *arg2, int blocks_modified, dmu_tx_t *tx); +void dsl_sync_task_sync(dsl_sync_task_t *dst, dmu_tx_t *tx); +int dsl_sync_task(const char *pool, dsl_checkfunc_t *checkfunc, + dsl_syncfunc_t *syncfunc, void *arg, int blocks_modified); +void dsl_sync_task_nowait(struct dsl_pool *dp, dsl_syncfunc_t *syncfunc, + void *arg, int blocks_modified, dmu_tx_t *tx); #ifdef __cplusplus } diff --git a/include/sys/dsl_userhold.h b/include/sys/dsl_userhold.h new file mode 100644 index 000000000..56c6c8f47 --- /dev/null +++ b/include/sys/dsl_userhold.h @@ -0,0 +1,57 @@ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_DSL_USERHOLD_H +#define _SYS_DSL_USERHOLD_H + +#include <sys/nvpair.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct dsl_pool; +struct dsl_dataset; +struct dmu_tx; + +int dsl_dataset_user_hold(nvlist_t *holds, minor_t cleanup_minor, + nvlist_t *errlist); +int dsl_dataset_user_release(nvlist_t *holds, nvlist_t *errlist); +int dsl_dataset_get_holds(const char *dsname, nvlist_t *nvl); +void dsl_dataset_user_release_tmp(struct dsl_pool *dp, uint64_t dsobj, + const char *htag); +int dsl_dataset_user_hold_check_one(struct dsl_dataset *ds, const char *htag, + boolean_t temphold, struct dmu_tx *tx); +void dsl_dataset_user_hold_sync_one(struct dsl_dataset *ds, const char *htag, + minor_t minor, uint64_t now, struct dmu_tx *tx); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_DSL_USERHOLD_H */ diff --git a/include/sys/metaslab.h b/include/sys/metaslab.h index 99912424b..70f7af0a5 100644 --- a/include/sys/metaslab.h +++ b/include/sys/metaslab.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_METASLAB_H @@ -57,6 +57,7 @@ extern int metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, extern void metaslab_free(spa_t *spa, const blkptr_t *bp, uint64_t txg, boolean_t now); extern int metaslab_claim(spa_t *spa, const blkptr_t *bp, uint64_t txg); +extern void metaslab_check_free(spa_t *spa, const blkptr_t *bp); extern void metaslab_fastwrite_mark(spa_t *spa, const blkptr_t *bp); extern void metaslab_fastwrite_unmark(spa_t *spa, const blkptr_t *bp); diff --git a/include/sys/nvpair.h b/include/sys/nvpair.h index c502568a6..7a6787045 100644 --- a/include/sys/nvpair.h +++ b/include/sys/nvpair.h @@ -285,6 +285,7 @@ void fnvlist_pack_free(char *, size_t); nvlist_t *fnvlist_unpack(char *, size_t); nvlist_t *fnvlist_dup(nvlist_t *); void fnvlist_merge(nvlist_t *, nvlist_t *); +size_t fnvlist_num_pairs(nvlist_t *); void fnvlist_add_boolean(nvlist_t *, const char *); void fnvlist_add_boolean_value(nvlist_t *, const char *, boolean_t); diff --git a/include/sys/refcount.h b/include/sys/refcount.h index 1752c64e3..e767a2389 100644 --- a/include/sys/refcount.h +++ b/include/sys/refcount.h @@ -50,15 +50,17 @@ typedef struct reference { typedef struct refcount { kmutex_t rc_mtx; + boolean_t rc_tracked; list_t rc_list; list_t rc_removed; int64_t rc_count; int64_t rc_removed_count; } refcount_t; -/* Note: refcount_t must be initialized with refcount_create() */ +/* Note: refcount_t must be initialized with refcount_create[_untracked]() */ void refcount_create(refcount_t *rc); +void refcount_create_untracked(refcount_t *rc); void refcount_destroy(refcount_t *rc); void refcount_destroy_many(refcount_t *rc, uint64_t number); int refcount_is_zero(refcount_t *rc); @@ -79,6 +81,7 @@ typedef struct refcount { } refcount_t; #define refcount_create(rc) ((rc)->rc_count = 0) +#define refcount_create_untracked(rc) ((rc)->rc_count = 0) #define refcount_destroy(rc) ((rc)->rc_count = 0) #define refcount_destroy_many(rc, number) ((rc)->rc_count = 0) #define refcount_is_zero(rc) ((rc)->rc_count == 0) diff --git a/include/sys/rrwlock.h b/include/sys/rrwlock.h index 8fde3a3be..25c8a5246 100644 --- a/include/sys/rrwlock.h +++ b/include/sys/rrwlock.h @@ -60,6 +60,7 @@ typedef struct rrwlock { refcount_t rr_anon_rcount; refcount_t rr_linked_rcount; boolean_t rr_writer_wanted; + boolean_t rr_track_all; } rrwlock_t; /* @@ -67,15 +68,19 @@ typedef struct rrwlock { * 'tag' must be the same in a rrw_enter() as in its * corresponding rrw_exit(). */ -void rrw_init(rrwlock_t *rrl); +void rrw_init(rrwlock_t *rrl, boolean_t track_all); void rrw_destroy(rrwlock_t *rrl); void rrw_enter(rrwlock_t *rrl, krw_t rw, void *tag); +void rrw_enter_read(rrwlock_t *rrl, void *tag); +void rrw_enter_write(rrwlock_t *rrl); void rrw_exit(rrwlock_t *rrl, void *tag); boolean_t rrw_held(rrwlock_t *rrl, krw_t rw); void rrw_tsd_destroy(void *arg); #define RRW_READ_HELD(x) rrw_held(x, RW_READER) #define RRW_WRITE_HELD(x) rrw_held(x, RW_WRITER) +#define RRW_LOCK_HELD(x) \ + (rrw_held(x, RW_WRITER) || rrw_held(x, RW_READER)) #ifdef __cplusplus } diff --git a/include/sys/spa.h b/include/sys/spa.h index 1af9137f8..401ae8343 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -422,7 +422,7 @@ extern int spa_get_stats(const char *pool, nvlist_t **config, char *altroot, extern int spa_create(const char *pool, nvlist_t *config, nvlist_t *props, nvlist_t *zplprops); extern int spa_import_rootpool(char *devpath, char *devid); -extern int spa_import(const char *pool, nvlist_t *config, nvlist_t *props, +extern int spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags); extern nvlist_t *spa_tryimport(nvlist_t *tryconfig); extern int spa_destroy(char *pool); diff --git a/include/sys/space_map.h b/include/sys/space_map.h index 2da80d29b..c53074a00 100644 --- a/include/sys/space_map.h +++ b/include/sys/space_map.h @@ -149,6 +149,8 @@ extern void space_map_add(space_map_t *sm, uint64_t start, uint64_t size); extern void space_map_remove(space_map_t *sm, uint64_t start, uint64_t size); extern boolean_t space_map_contains(space_map_t *sm, uint64_t start, uint64_t size); +extern space_seg_t *space_map_find(space_map_t *sm, uint64_t start, + uint64_t size, avl_index_t *wherep); extern void space_map_swap(space_map_t **msrc, space_map_t **mdest); extern void space_map_vacate(space_map_t *sm, space_map_func_t *func, space_map_t *mdest); diff --git a/include/sys/txg.h b/include/sys/txg.h index f9d6dd421..b9bbba8be 100644 --- a/include/sys/txg.h +++ b/include/sys/txg.h @@ -45,9 +45,6 @@ extern "C" { /* Number of txgs worth of frees we defer adding to in-core spacemaps */ #define TXG_DEFER_SIZE 2 -#define TXG_WAIT 1ULL -#define TXG_NOWAIT 2ULL - typedef struct tx_cpu tx_cpu_t; typedef struct txg_handle { @@ -125,11 +122,11 @@ extern void txg_wait_callbacks(struct dsl_pool *dp); extern void txg_list_create(txg_list_t *tl, size_t offset); extern void txg_list_destroy(txg_list_t *tl); extern boolean_t txg_list_empty(txg_list_t *tl, uint64_t txg); -extern int txg_list_add(txg_list_t *tl, void *p, uint64_t txg); -extern int txg_list_add_tail(txg_list_t *tl, void *p, uint64_t txg); +extern boolean_t txg_list_add(txg_list_t *tl, void *p, uint64_t txg); +extern boolean_t txg_list_add_tail(txg_list_t *tl, void *p, uint64_t txg); extern void *txg_list_remove(txg_list_t *tl, uint64_t txg); extern void *txg_list_remove_this(txg_list_t *tl, void *p, uint64_t txg); -extern int txg_list_member(txg_list_t *tl, void *p, uint64_t txg); +extern boolean_t txg_list_member(txg_list_t *tl, void *p, uint64_t txg); extern void *txg_list_head(txg_list_t *tl, uint64_t txg); extern void *txg_list_next(txg_list_t *tl, void *p, uint64_t txg); diff --git a/include/sys/zfeature.h b/include/sys/zfeature.h index 481e85b1b..1a081e422 100644 --- a/include/sys/zfeature.h +++ b/include/sys/zfeature.h @@ -26,7 +26,6 @@ #ifndef _SYS_ZFEATURE_H #define _SYS_ZFEATURE_H -#include <sys/dmu.h> #include <sys/nvpair.h> #include "zfeature_common.h" @@ -34,14 +33,18 @@ extern "C" { #endif -extern boolean_t feature_is_supported(objset_t *os, uint64_t obj, +struct spa; +struct dmu_tx; +struct objset; + +extern boolean_t feature_is_supported(struct objset *os, uint64_t obj, uint64_t desc_obj, nvlist_t *unsup_feat, nvlist_t *enabled_feat); -struct spa; -extern void spa_feature_create_zap_objects(struct spa *, dmu_tx_t *); -extern void spa_feature_enable(struct spa *, zfeature_info_t *, dmu_tx_t *); -extern void spa_feature_incr(struct spa *, zfeature_info_t *, dmu_tx_t *); -extern void spa_feature_decr(struct spa *, zfeature_info_t *, dmu_tx_t *); +extern void spa_feature_create_zap_objects(struct spa *, struct dmu_tx *); +extern void spa_feature_enable(struct spa *, zfeature_info_t *, + struct dmu_tx *); +extern void spa_feature_incr(struct spa *, zfeature_info_t *, struct dmu_tx *); +extern void spa_feature_decr(struct spa *, zfeature_info_t *, struct dmu_tx *); extern boolean_t spa_feature_is_enabled(struct spa *, zfeature_info_t *); extern boolean_t spa_feature_is_active(struct spa *, zfeature_info_t *); diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 599b97a9b..a126c058e 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -209,8 +209,6 @@ typedef struct kthread { void * t_arg; } kthread_t; -#define tsd_get(key) pthread_getspecific(key) -#define tsd_set(key, val) pthread_setspecific(key, val) #define curthread zk_thread_current() #define thread_exit zk_thread_exit #define thread_create(stk, stksize, func, arg, len, pp, state, pri) \ @@ -284,6 +282,12 @@ typedef int krw_t; #define RW_WRITE_HELD(x) ((x)->rw_wr_owner == curthread) #define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x)) +#undef RW_LOCK_HELD +#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x)) + +#undef RW_LOCK_HELD +#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x)) + extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg); extern void rw_destroy(krwlock_t *rwlp); extern void rw_enter(krwlock_t *rwlp, krw_t rw); @@ -321,6 +325,22 @@ extern void cv_broadcast(kcondvar_t *cv); #define cv_wait_io(cv, mp) cv_wait(cv, mp) /* + * Thread-specific data + */ +#define tsd_get(k) pthread_getspecific(k) +#define tsd_set(k, v) pthread_setspecific(k, v) +#define tsd_create(kp, d) pthread_key_create(kp, d) +#define tsd_destroy(kp) /* nothing */ + +/* + * Thread-specific data + */ +#define tsd_get(k) pthread_getspecific(k) +#define tsd_set(k, v) pthread_setspecific(k, v) +#define tsd_create(kp, d) pthread_key_create(kp, d) +#define tsd_destroy(kp) /* nothing */ + +/* * kstat creation, installation and deletion */ extern kstat_t *kstat_create(char *, int, @@ -592,7 +612,7 @@ typedef struct callb_cpr { extern char *kmem_vasprintf(const char *fmt, va_list adx); extern char *kmem_asprintf(const char *fmt, ...); -#define strfree(str) kmem_free((str), strlen(str)+1) +#define strfree(str) kmem_free((str), strlen(str) + 1) /* * Hostname information diff --git a/include/sys/zfs_debug.h b/include/sys/zfs_debug.h index 591d0df8f..7632d7420 100644 --- a/include/sys/zfs_debug.h +++ b/include/sys/zfs_debug.h @@ -43,11 +43,13 @@ extern int zfs_flags; extern int zfs_recover; -#define ZFS_DEBUG_DPRINTF 0x0001 -#define ZFS_DEBUG_DBUF_VERIFY 0x0002 -#define ZFS_DEBUG_DNODE_VERIFY 0x0004 -#define ZFS_DEBUG_SNAPNAMES 0x0008 -#define ZFS_DEBUG_MODIFY 0x0010 +#define ZFS_DEBUG_DPRINTF (1<<0) +#define ZFS_DEBUG_DBUF_VERIFY (1<<1) +#define ZFS_DEBUG_DNODE_VERIFY (1<<2) +#define ZFS_DEBUG_SNAPNAMES (1<<3) +#define ZFS_DEBUG_MODIFY (1<<4) +#define ZFS_DEBUG_SPA (1<<5) +#define ZFS_DEBUG_ZIO_FREE (1<<6) /* * Always log zfs debug messages to the spl debug subsystem as SS_USER1. diff --git a/include/sys/zfs_ioctl.h b/include/sys/zfs_ioctl.h index 21bfe2b8f..8838322a9 100644 --- a/include/sys/zfs_ioctl.h +++ b/include/sys/zfs_ioctl.h @@ -302,7 +302,6 @@ typedef struct zfs_cmd { uint64_t zc_history; /* really (char *) */ char zc_value[MAXPATHLEN * 2]; char zc_string[MAXNAMELEN]; - char zc_top_ds[MAXPATHLEN]; uint64_t zc_guid; uint64_t zc_nvlist_conf; /* really (char *) */ uint64_t zc_nvlist_conf_size; @@ -352,7 +351,8 @@ extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr); extern int zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr); extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr); -extern int zfs_unmount_snap(const char *, void *); +extern void zfs_unmount_snap(const char *); +extern void zfs_destroy_unmount_origin(const char *); enum zfsdev_state_type { ZST_ONEXIT, diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index bdddcc366..aa9d9d288 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_FS_ZFS_ZNODE_H @@ -254,7 +255,7 @@ typedef struct znode { */ #define ZFS_ENTER(zsb) \ { \ - rrw_enter(&(zsb)->z_teardown_lock, RW_READER, FTAG); \ + rrw_enter_read(&(zsb)->z_teardown_lock, FTAG); \ if ((zsb)->z_unmounted) { \ ZFS_EXIT(zsb); \ return (EIO); \ diff --git a/include/sys/zil.h b/include/sys/zil.h index 589e28f83..f3e00101b 100644 --- a/include/sys/zil.h +++ b/include/sys/zil.h @@ -470,8 +470,8 @@ extern int zil_check_log_chain(const char *osname, void *txarg); extern void zil_sync(zilog_t *zilog, dmu_tx_t *tx); extern void zil_clean(zilog_t *zilog, uint64_t synced_txg); -extern int zil_suspend(zilog_t *zilog); -extern void zil_resume(zilog_t *zilog); +extern int zil_suspend(const char *osname, void **cookiep); +extern void zil_resume(void *cookie); extern void zil_add_block(zilog_t *zilog, const blkptr_t *bp); extern int zil_bp_tree_add(zilog_t *zilog, const blkptr_t *bp); diff --git a/include/sys/zvol.h b/include/sys/zvol.h index c05f81a5f..640538c2c 100644 --- a/include/sys/zvol.h +++ b/include/sys/zvol.h @@ -39,7 +39,7 @@ extern int zvol_get_stats(objset_t *os, nvlist_t *nv); extern boolean_t zvol_is_zvol(const char *); extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx); extern int zvol_create_minor(const char *); -extern int zvol_create_minors(const char *); +extern int zvol_create_minors(char *); extern int zvol_remove_minor(const char *); extern void zvol_remove_minors(const char *); extern int zvol_set_volsize(const char *, uint64_t); |