--- /dev/null	2012-10-26 17:09:25.000000000 +0200
+++ new/usr/src/uts/common/fs/zfs/sys/far_impl.h	2012-10-26 17:09:25.598689000 +0200
@@ -0,0 +1,237 @@
+/*
+ * 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_FAR_IMPL_H
+#define	_SYS_FAR_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>
+#include <sys/avl.h>
+#include <sys/dmu_impl.h>
+
+#define	FAR_NO_INO	0
+
+enum pass {
+	PASS_LINK,
+	PASS_UNLINK
+};
+
+typedef struct _far_count_elem {
+	avl_node_t	fce_avl_node;
+	uint64_t	fce_ino;
+	uint64_t	fce_count;
+	uint64_t	fce_aux;
+} far_count_elem_t;
+
+typedef struct _far_counter {
+	avl_tree_t fc_avl;
+	char *fc_name;
+} far_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 _far {
+	enum pass f_pass;
+	struct _far_ops	*f_ops;
+	far_counter_t f_del_dir_cnt;
+	far_counter_t f_put_back_cnt;
+	far_counter_t f_link_add_cnt;
+	uint64_t f_current_ino;
+	struct _far_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;
+	dmu_sendarg_t	f_dmu_sendarg;
+} far_t;
+
+typedef struct _far_ops {
+	int (*far_dir_add)(far_t *f, uint64_t ino);
+	int (*far_dir_del)(far_t *f, uint64_t ino);
+	int (*far_dir_mod)(far_t *f, uint64_t ino);
+	int (*far_dirent_add)(void *far_enump, char *name, uint64_t ino);
+	int (*far_dirent_del)(void *far_enump, char *name, uint64_t ino);
+	int (*far_dirent_mod)(void *far_enump, char *name,
+	    uint64_t ino_old, uint64_t ino_new);
+	int (*far_dirent_unmod)(void *far_enump, char *name, uint64_t ino);
+	int (*far_file_add)(far_t *f, uint64_t ino);
+	int (*far_file_del)(far_t *f, uint64_t ino);
+	int (*far_file_mod)(far_t *f, uint64_t ino);
+	int (*far_file_data)(void *far_filep, void *data, uint64_t off,
+	    uint64_t len);
+} far_ops_t;
+
+typedef struct _far_path {
+	struct _far_path *fp_next;
+	int fp_len;
+	int fp_total_len;
+	char fp_buf[0];
+} far_path_t;
+
+typedef struct _far_dirent {
+	char *fd_name;
+	uint64_t fd_parent_ino;
+	struct _far_dirent *fd_prev;
+} far_dirent_t;
+
+typedef enum _far_which {
+	FAR_UNDEF,
+	FAR_OLD,
+	FAR_NEW
+} far_which_t;
+
+typedef struct _far_time {
+	uint64_t	st_sec;
+	uint64_t	st_nsec;
+} far_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 _far_info {
+	uint64_t	si_nlinks;
+	uint64_t	si_parent;
+	union {
+		uint64_t	si_nentries;
+		uint64_t	si_size;
+	};
+	far_time_t	si_atime;
+	far_time_t	si_mtime;
+	far_time_t	si_ctime;
+	far_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;
+} far_info_t;
+
+int far_start(far_t *f, far_ops_t **);
+int far_start2(far_t *f, far_ops_t **);
+int far_abort(far_t *f);
+int far_end(far_t *f);
+
+int far_dirent_add_file(far_t *f, far_dirent_t *dirent,
+    uint64_t ino, uint64_t mode, int exists);
+void far_path_free(far_path_t *fp);
+
+int far_get_info(far_t *f, uint64_t dnobj, far_which_t which,
+    far_info_t *sp, uint64_t flags);
+
+typedef int (*far_file_cb_t)(void *ctx, void *data, int len);
+int far_file_contents(far_t *f, uint64_t dnobj, void *ctx);
+int far_dir_contents(far_t *f, uint64_t dnobj, void *ctx);
+int far_find_entry(far_t *f, uint64_t dirobj, uint64_t dnobj,
+    far_which_t which, char **name);
+void far_free_name(char *name);
+int far_lookup_entry(far_t *f, uint64_t dirobj, char *name,
+    far_which_t which, uint64_t *dnobj);
+int far_write(far_t *f, const uint8_t *data, int len);
+int far_get_uuid(far_t *f, far_which_t which, uint8_t data[16]);
+int far_get_ctransid(far_t *f, far_which_t which,
+    uint64_t *ctransid);
+int far_get_snapname(far_t *f, far_which_t which,
+    char **name, int *len);
+int far_read_symlink(far_t *f, uint64_t dnobj, far_which_t which,
+    char **target, int *plen);
+
+int far_send_start(far_t *f);
+int far_send_create_file(far_t *f, far_dirent_t *dirent, uint64_t ino,
+int devise_tempname, far_path_t **path_ret);
+int far_send_link(far_t *f, far_dirent_t *new_dirent, uint64_t ino,
+    uint64_t old_parent_ino, far_which_t which,
+int devise_tempname);
+int far_send_mkdir(far_t *f, far_dirent_t *dirent, uint64_t ino,
+int devise_tempname);
+int far_send_rename(far_t *f, far_dirent_t *dirent, uint64_t ino,
+    uint64_t old_parent_ino, int devise_tempname);
+int far_send_rename_from_tempname(far_t *f, far_dirent_t *dirent,
+    uint64_t ino, uint64_t old);
+int far_send_unlink(far_t *f, far_dirent_t *dirent, uint64_t ino);
+int far_send_rmdir(far_t *f, far_dirent_t *dirent, uint64_t ino);
+/* TODO: make **path *path or do we really still alloc it? */
+int far_send_file_data(far_t *f,
+    far_path_t **path, far_dirent_t *dirent,
+    uint64_t ino, uint64_t off, uint64_t len, void *data);
+int far_send_mtime_update(far_t *f, far_dirent_t *dirent, uint64_t ino);
+int far_send_truncate(far_t *f, far_dirent_t *dirent, uint64_t ino,
+    uint64_t new_size);
+int far_send_chown(far_t *f, far_dirent_t *dirent, uint64_t ino,
+    uint64_t new_uid, uint64_t new_gid);
+int far_send_chmod(far_t *f, far_dirent_t *dirent, uint64_t ino,
+    uint64_t new_mode);
+int far_send_end(far_t *f);
+int far_count_init(far_counter_t *fc, char *name);
+void far_count_destroy(far_counter_t *fc);
+int far_add_count(far_counter_t *fc, uint64_t ino, uint64_t inc,
+    uint64_t aux, uint64_t *new_count, uint64_t *old_aux);
+void far_free_count(far_counter_t *fc, uint64_t ino);
+int far_get_count(far_counter_t *fc, uint64_t ino, uint64_t *new_count,
+    uint64_t *old_aux);
+int far_count_fini(far_counter_t *fc);
+
+void far_send_init(far_t *f);
+void far_send_fini(far_t *f);
+
+#endif /* _SYS_FAR_IMPL_H */
