--- /dev/null	2012-10-17 21:48:39.000000000 +0200
+++ new/usr/src/uts/common/fs/zfs/sys/fits_impl.h	2012-10-17 21:48:39.881016000 +0200
@@ -0,0 +1,232 @@
+/*
+ * 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) 2012 STRATO AG. All rights reserved.
+ */
+
+#ifndef	_SYS_FITS_IMPL_H
+#define	_SYS_FITS_IMPL_H
+
+#include <sys/inttypes.h>
+#include <sys/types.h>
+#include <sys/cmn_err.h>
+#include <sys/spa.h>
+#include <sys/arc.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dnode.h>
+#include <sys/sa.h>
+
+#define	FITS_NO_INO	0
+
+enum pass {
+	PASS_LINK,
+	PASS_UNLINK
+};
+
+typedef struct _fits_count_elem {
+	struct _fits_count_elem *fce_next;
+	uint64_t fce_ino;
+	uint64_t fce_count;
+	uint64_t fce_aux;
+} fits_count_elem_t;
+
+typedef struct _fits_counter {
+	fits_count_elem_t *fc_head;
+	const char *fc_name;
+} fits_counter_t;
+
+typedef struct blklevel {
+	uint64_t	bl_blk;
+	int		bl_nslots;
+	blkptr_t	*bl_bp;
+	arc_buf_t	*bl_buf;
+} blklevel_t;
+
+typedef struct _fits {
+	enum pass f_pass;
+	struct _fits_ops	*f_ops;
+	fits_counter_t f_del_dir_cnt;
+	fits_counter_t f_put_back_cnt;
+	fits_counter_t f_link_add_cnt;
+	uint64_t f_current_ino;
+	struct _fits_path *f_current_path;
+	int		f_alloc_len;
+	uint8_t		*f_buf;
+	int		f_size;
+	struct vnode	*f_vp;		/* file to which we are reporting */
+	offset_t	*f_offp;
+	int		f_err;		/* error that stopped diff search */
+	dsl_dataset_t	*f_fromds;
+	dsl_dataset_t	*f_tods;
+	objset_t	*f_fromsnap;
+	objset_t	*f_tosnap;
+	dnode_phys_t	*f_dnp;
+	blklevel_t	*f_bl;
+	blklevel_t	*f_filebl;
+	uint64_t	f_fromtxg;
+	sa_attr_type_t	*f_from_sa_table;
+	sa_attr_type_t	*f_to_sa_table;
+	uint64_t	f_shares_dir;
+} fits_t;
+
+typedef struct _fits_ops {
+	int (*fits_dir_add)(fits_t *f, uint64_t ino);
+	int (*fits_dir_del)(fits_t *f, uint64_t ino);
+	int (*fits_dir_mod)(fits_t *f, uint64_t ino);
+	int (*fits_dirent_add)(void *fits_enump, char *name, uint64_t ino);
+	int (*fits_dirent_del)(void *fits_enump, char *name, uint64_t ino);
+	int (*fits_dirent_mod)(void *fits_enump, char *name,
+	    uint64_t ino_old, uint64_t ino_new);
+	int (*fits_dirent_unmod)(void *fits_enump, char *name, uint64_t ino);
+	int (*fits_file_add)(fits_t *f, uint64_t ino);
+	int (*fits_file_del)(fits_t *f, uint64_t ino);
+	int (*fits_file_mod)(fits_t *f, uint64_t ino);
+	int (*fits_file_data)(void *fits_filep, void *data, uint64_t off,
+	    uint64_t len);
+} fits_ops_t;
+
+typedef struct _fits_path {
+	struct _fits_path *fp_next;
+	int fp_len;
+	int fp_total_len;
+	char fp_buf[0];
+} fits_path_t;
+
+typedef struct _fits_dirent {
+	char *fd_name;
+	uint64_t fd_parent_ino;
+	struct _fits_dirent *fd_prev;
+} fits_dirent_t;
+
+typedef enum _fits_which {
+	FITS_UNDEF,
+	FITS_OLD,
+	FITS_NEW
+} fits_which_t;
+
+typedef struct _fits_time {
+	uint64_t	st_sec;
+	uint64_t	st_nsec;
+} fits_time_t;
+
+#define	FI_ATTR_ATIME		(1 <<  0)
+#define	FI_ATTR_MTIME		(1 <<  1)
+#define	FI_ATTR_CTIME		(1 <<  2)
+#define	FI_ATTR_OTIME		(1 <<  3)
+#define	FI_ATTR_MODE		(1 <<  4)
+#define	FI_ATTR_SIZE		(1 <<  5)
+#define	FI_ATTR_NENTRIES	(1 <<  5)
+#define	FI_ATTR_PARENT		(1 <<  6)
+#define	FI_ATTR_LINKS		(1 <<  7)
+#define	FI_ATTR_RDEV		(1 <<  8)
+#define	FI_ATTR_UID		(1 <<  9)
+#define	FI_ATTR_GID		(1 << 10)
+#define	FI_ATTR_GEN		(1 << 11)
+/* XXX TODO xattr, acl, dacl */
+
+#undef si_uid	/* XXX defined in siginfo.h */
+#undef si_gid	/* XXX defined in siginfo.h */
+typedef struct _fits_info {
+	uint64_t	si_nlinks;
+	uint64_t	si_parent;
+	union {
+		uint64_t	si_nentries;
+		uint64_t	si_size;
+	};
+	fits_time_t	si_atime;
+	fits_time_t	si_mtime;
+	fits_time_t	si_ctime;
+	fits_time_t	si_otime;
+	uint64_t	si_mode;
+	/* XXX TODO xattr */
+	uint64_t	si_rdev;
+	uint64_t	si_uid;
+	uint64_t	si_gid;
+	uint64_t	si_gen;
+} fits_info_t;
+
+int fits_start(fits_t *f, fits_ops_t **);
+int fits_start2(fits_t *f, fits_ops_t **);
+int fits_abort(fits_t *f);
+int fits_end(fits_t *f);
+
+int fits_dirent_add_file(fits_t *f, fits_dirent_t *dirent,
+    uint64_t ino, uint64_t mode, int exists);
+void fits_path_free(fits_path_t *fp);
+
+int fits_get_info(fits_t *f, uint64_t dnobj, fits_which_t which,
+    fits_info_t *sp, uint64_t flags);
+
+typedef int (*fits_file_cb_t)(void *ctx, void *data, int len);
+int fits_file_contents(fits_t *f, uint64_t dnobj, void *ctx);
+int fits_dir_contents(fits_t *f, uint64_t dnobj, void *ctx);
+int fits_find_entry(fits_t *f, uint64_t dirobj, uint64_t dnobj,
+    fits_which_t which, char **name);
+void fits_free_name(char *name);
+int fits_lookup_entry(fits_t *f, uint64_t dirobj, char *name,
+    fits_which_t which, uint64_t *dnobj);
+int fits_write(fits_t *f, const uint8_t *data, int len);
+int fits_get_uuid(fits_t *f, fits_which_t which, uint8_t data[16]);
+int fits_get_ctransid(fits_t *f, fits_which_t which,
+    uint64_t *ctransid);
+int fits_get_snapname(fits_t *f, fits_which_t which,
+    char **name, int *len);
+int fits_read_symlink(fits_t *f, uint64_t dnobj, fits_which_t which,
+    char **target, int *plen);
+
+int fits_send_start(fits_t *f);
+int fits_send_create_file(fits_t *f, fits_dirent_t *dirent, uint64_t ino,
+int devise_tempname, fits_path_t **path_ret);
+int fits_send_link(fits_t *f, fits_dirent_t *new_dirent, uint64_t ino,
+    uint64_t old_parent_ino, fits_which_t which,
+int devise_tempname);
+int fits_send_mkdir(fits_t *f, fits_dirent_t *dirent, uint64_t ino,
+int devise_tempname);
+int fits_send_rename(fits_t *f, fits_dirent_t *dirent, uint64_t ino,
+    uint64_t old_parent_ino, int devise_tempname);
+int fits_send_rename_from_tempname(fits_t *f, fits_dirent_t *dirent,
+    uint64_t ino, uint64_t old);
+int fits_send_unlink(fits_t *f, fits_dirent_t *dirent, uint64_t ino);
+int fits_send_rmdir(fits_t *f, fits_dirent_t *dirent, uint64_t ino);
+/* TODO: make **path *path or do we really still alloc it? */
+int fits_send_file_data(fits_t *f,
+    fits_path_t **path, fits_dirent_t *dirent,
+    uint64_t ino, uint64_t off, uint64_t len, void *data);
+int fits_send_mtime_update(fits_t *f, fits_dirent_t *dirent, uint64_t ino);
+int fits_send_truncate(fits_t *f, fits_dirent_t *dirent, uint64_t ino,
+    uint64_t new_size);
+int fits_send_chown(fits_t *f, fits_dirent_t *dirent, uint64_t ino,
+    uint64_t new_uid, uint64_t new_gid);
+int fits_send_chmod(fits_t *f, fits_dirent_t *dirent, uint64_t ino,
+    uint64_t new_mode);
+int fits_send_end(fits_t *f);
+int fits_add_count(fits_counter_t *fc, uint64_t ino, uint64_t inc,
+    uint64_t aux, uint64_t *new_count, uint64_t *old_aux);
+void fits_free_count(fits_counter_t *fc, uint64_t ino);
+int fits_get_count(fits_counter_t *fc, uint64_t ino, uint64_t *new_count,
+    uint64_t *old_aux);
+int fits_assert_count_empty(fits_counter_t *fc);
+
+void fits_send_init(fits_t *f);
+void fits_send_fini(fits_t *f);
+
+#endif /* _SYS_FITS_IMPL_H */
