Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*
      7  * BSD 3 Clause License
      8  *
      9  * Copyright (c) 2007, The Storage Networking Industry Association.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 	- Redistributions of source code must retain the above copyright
     15  *	  notice, this list of conditions and the following disclaimer.
     16  *
     17  * 	- Redistributions in binary form must reproduce the above copyright
     18  *	  notice, this list of conditions and the following disclaimer in
     19  *	  the documentation and/or other materials provided with the
     20  *	  distribution.
     21  *
     22  *	- Neither the name of The Storage Networking Industry Association (SNIA)
     23  *	  nor the names of its contributors may be used to endorse or promote
     24  *	  products derived from this software without specific prior written
     25  *	  permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  * POSSIBILITY OF SUCH DAMAGE.
     38  */
     39 #ifndef	_TLM_H_
     40 #define	_TLM_H_
     41 
     42 #include <sys/types.h>
     43 #include <synch.h>
     44 #include <limits.h>
     45 #include <cstack.h>
     46 #include <sys/acl.h>
     47 #include <stdio.h>
     48 #include <errno.h>
     49 #include <fcntl.h>
     50 #include <strings.h>
     51 #include <sys/stat.h>
     52 #include <time.h>
     53 #include <sys/queue.h>
     54 #include <sys/fs/zfs.h>
     55 #include <libzfs.h>
     56 
     57 #define	IS_SET(f, m)	(((f) & (m)) != 0)
     58 
     59 #define	TLM_MAX_BACKUP_JOB_NAME	32	/* max size of a job's name */
     60 #define	TLM_TAPE_BUFFERS	10	/* number of rotating tape buffers */
     61 #define	TLM_LINE_SIZE		128	/* size of text messages */
     62 
     63 
     64 #define	TLM_BACKUP_RUN		0x00000001
     65 #define	TLM_RESTORE_RUN		0x00000002
     66 #define	TLM_STOP		0x00000009	/* graceful stop */
     67 #define	TLM_ABORT		0x99999999	/* abandon the run */
     68 
     69 #define	TLM_EXTRA_SPACE		64
     70 #define	TLM_MAX_PATH_NAME	(PATH_MAX + TLM_EXTRA_SPACE)
     71 
     72 #define	ENTRYTYPELEN	14
     73 #define	PERMS		4
     74 #define	ID_STR_MAX	20
     75 #define	APPENDED_ID_MAX	(ID_STR_MAX + 1)
     76 #define	ACL_ENTRY_SIZE	(ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX)
     77 #define	TLM_MAX_ACL_TXT	MAX_ACL_ENTRIES * ACL_ENTRY_SIZE
     78 
     79 
     80 /* operation flags */
     81 #define	TLM_OP_CHOOSE_ARCHIVE	0x00000001	/* look for archive bit */
     82 
     83 /*
     84  * Synchronization flags used when launching the TLM threads.
     85  */
     86 #define	TLM_TAPE_READER		0x00000001
     87 #define	TLM_TAPE_WRITER		0x00000002
     88 #define	TLM_SOCK_READER		0x00000004
     89 #define	TLM_SOCK_WRITER		0x00000008
     90 #define	TLM_BUF_READER		0x00000010
     91 #define	TLM_BUF_WRITER		0x00000020
     92 #define	TLM_TAR_READER		0x00000040
     93 #define	TLM_TAR_WRITER		0x00000080
     94 
     95 #define	SCSI_SERIAL_PAGE	0x80
     96 #define	SCSI_DEVICE_IDENT_PAGE	0x83
     97 #define	SCMD_READ_ELEMENT_STATUS	0xB8
     98 
     99 #define	OCTAL7CHAR	07777777
    100 #define	SYSATTR_RDONLY	"SUNWattr_ro"
    101 #define	SYSATTR_RW	"SUNWattr_rw"
    102 
    103 typedef	int (*func_t)();
    104 
    105 typedef struct scsi_serial {
    106 	int sr_flags;
    107 	char sr_num[16];
    108 } scsi_serial_t;
    109 
    110 typedef struct fs_fhandle {
    111 	int fh_fid;
    112 	char *fh_fpath;
    113 } fs_fhandle_t;
    114 
    115 typedef struct scsi_link {
    116 	struct scsi_link 	*sl_next;
    117 	struct scsi_link 	*sl_prev;
    118 	struct scsi_adapter 	*sl_sa;
    119 	unsigned int		sl_sid;
    120 	unsigned int		sl_lun;
    121 	unsigned int		sl_requested_max_active;
    122 	unsigned int		sl_granted_max_active;
    123 	unsigned int		sl_n_active;
    124 	unsigned int		sl_type; /* SCSI device type */
    125 } scsi_link_t;
    126 
    127 typedef struct scsi_adapter {
    128 	struct scsi_adapter	*sa_next;
    129 	char			sa_name[16];
    130 	struct scsi_link	sa_link_head;
    131 } scsi_adapter_t;
    132 
    133 typedef struct sasd_drive {
    134 	char		sd_name[256];
    135 	char		sd_vendor[8 + 1];
    136 	char		sd_id[16 + 1];
    137 	char		sd_rev[4 + 1];
    138 	char		sd_serial[16 + 1];
    139 	char		sd_wwn[32 + 1];
    140 } sasd_drive_t;
    141 
    142 typedef struct scsi_sasd_drive {
    143 	sasd_drive_t	ss_sd;
    144 	scsi_link_t	ss_slink;
    145 } scsi_sasd_drive_t;
    146 
    147 
    148 #define	DEFAULT_SLINK_MAX_XFER	(64*1024)
    149 
    150 typedef struct	tlm_info {
    151 	int			ti_init_done;	/* initialization done ? */
    152 	int			ti_library_count; /* number of libraries */
    153 	struct tlm_library	*ti_library;	/* first in chain */
    154 	struct tlm_chain_link	*ti_job_stats;  /* chain of job statistics */
    155 } tlm_info_t;
    156 
    157 typedef struct	tlm_chain_link {
    158 	struct tlm_chain_link	*tc_next;	/* next blob of statistics */
    159 	struct tlm_chain_link	*tc_prev;	/* previous blob in the chain */
    160 	int	tc_ref_count;			/* number of routines */
    161 	void	*tc_data;			/* the data blob */
    162 } tlm_chain_link_t;
    163 
    164 typedef struct	tlm_robot {
    165 	struct tlm_robot	*tr_next;
    166 	struct tlm_library	*tr_library;
    167 	int	tr_number;
    168 } tlm_robot_t;
    169 
    170 typedef struct	tlm_drive {
    171 	struct tlm_drive	*td_next;
    172 	struct tlm_library	*td_library;
    173 	char	td_job_name[TLM_MAX_BACKUP_JOB_NAME];
    174 	int	td_number;		/* number of this tape drive */
    175 	int	td_element;		/* the library's number for the drive */
    176 	struct	scsi_link *td_slink;	/* because the drive may be connected */
    177 					/* to a different SCSI card than the */
    178 					/* library */
    179 	short	td_scsi_id;
    180 	short	td_lun;
    181 	short	td_volume_number;	/* for current job */
    182 					/*  an index into the tape set */
    183 	int	td_fd;			/* I/O file descriptor */
    184 	int	td_errno;		/* system error number */
    185 	long	td_exists	: 1;
    186 
    187 } tlm_drive_t;
    188 
    189 typedef struct	tlm_slot {
    190 	struct tlm_slot		*ts_next;
    191 	struct tlm_library	*ts_library;
    192 	int	ts_number;		/* number of this slot */
    193 	int	ts_element;
    194 	short	ts_use_count;		/* number of times used since loaded */
    195 	long	ts_status_full		: 1;
    196 } tlm_slot_t;
    197 
    198 typedef struct	tlm_library {
    199 	struct tlm_library	*tl_next;
    200 	int	tl_number;		/* number of this tape library */
    201 	long	tl_capability_robot	: 1,
    202 		tl_capability_door	: 1,
    203 		tl_capability_lock	: 1,
    204 		tl_capability_slots	: 1,
    205 		tl_capability_export	: 1,
    206 		tl_capability_drives	: 1,
    207 		tl_capability_barcodes	: 1,
    208 		tl_ghost_drives		: 1;
    209 		/*
    210 		 * "ghost_drives" is used to make sure that
    211 		 * all drives claimed by the library really
    212 		 * exist ... libraries have been known to lie.
    213 		 */
    214 	struct	scsi_link *tl_slink;
    215 
    216 	int		tl_robot_count;
    217 	tlm_robot_t	*tl_robot;
    218 	int		tl_drive_count;
    219 	tlm_drive_t	*tl_drive;
    220 	int		tl_slot_count;
    221 	tlm_slot_t	*tl_slot;
    222 } tlm_library_t;
    223 
    224 typedef struct {
    225 	unsigned char d_name[8];
    226 } device_info_t;
    227 
    228 typedef struct {
    229 	unsigned char p_number[4];
    230 } port_info_t;
    231 
    232 typedef struct {
    233 #ifdef _BIG_ENDIAN
    234 	uint8_t	di_peripheral_qual	: 3,
    235 		di_peripheral_dev_type	: 5;
    236 	uint8_t	di_page_code;
    237 	uint16_t	di_page_length;
    238 #else
    239 	uint8_t	di_peripheral_dev_type	: 5,
    240 		di_peripheral_qual	: 3;
    241 	uint8_t	di_page_code;
    242 	uint16_t	di_page_length;
    243 #endif
    244 } device_ident_header_t;
    245 
    246 typedef struct {
    247 #ifdef _BIG_ENDIAN
    248 	uint8_t	ni_proto_ident	: 4,
    249 		ni_code_set	: 4;
    250 
    251 	uint8_t	ni_PIV		: 1,
    252 				: 1,
    253 		ni_asso		: 2,
    254 		ni_ident_type	: 4;
    255 
    256 	uint8_t	ni_reserved;
    257 	uint8_t	ni_ident_length;
    258 #else
    259 	uint8_t	ni_code_set	: 4,
    260 		ni_proto_ident	: 4;
    261 
    262 	uint8_t	ni_ident_type	: 4,
    263 		ni_asso		: 2,
    264 				: 1,
    265 		ni_PIV		: 1;
    266 	uint8_t	ni_reserved;
    267 	uint8_t	ni_ident_length;
    268 #endif
    269 } name_ident_t;
    270 
    271 typedef struct {
    272 	device_ident_header_t	np_header;
    273 	name_ident_t		np_node;
    274 	device_info_t		np_node_info;
    275 	name_ident_t		np_port;
    276 	device_info_t		np_port_info;
    277 	name_ident_t		np_portno;
    278 	port_info_t		np_portid;
    279 } device_name_page_t;
    280 
    281 #define	TLM_NO_ERRORS			0x00000000
    282 #define	TLM_ERROR_BUSY			0x00000001
    283 #define	TLM_ERROR_INTERNAL		0x00000002
    284 #define	TLM_ERROR_NO_ROBOTS		0x00000003
    285 #define	TLM_TIMEOUT			0x00000004
    286 #define	TLM_ERROR_RANGE			0x00000005
    287 #define	TLM_EMPTY			0x00000006
    288 #define	TLM_DRIVE_NOT_ASSIGNED		0x00000007
    289 #define	TLM_NO_TAPE_NAME		0x00000008
    290 #define	TLM_NO_BACKUP_DIR		0x00000009
    291 #define	TLM_NO_BACKUP_HARDWARE		0x0000000a
    292 #define	TLM_NO_SOURCE_FILE		0x0000000b
    293 #define	TLM_NO_FREE_TAPES		0x0000000c
    294 #define	TLM_EOT				0x0000000d
    295 #define	TLM_SERIAL_NOT_FOUND		0x0000000e
    296 #define	TLM_SMALL_READ			0x0000000f
    297 #define	TLM_NO_RESTORE_FILE		0x00000010
    298 #define	TLM_EOF				0x00000011
    299 #define	TLM_NO_DIRECTORY		0x00000012
    300 #define	TLM_NO_MEMORY			0x00000013
    301 #define	TLM_WRITE_ERROR			0x00000014
    302 #define	TLM_NO_SCRATCH_SPACE		0x00000015
    303 #define	TLM_INVALID			0x00000016
    304 #define	TLM_MOVE			0x00000017
    305 #define	TLM_SKIP			0x00000018
    306 #define	TLM_OPEN_ERR			0x00000019
    307 
    308 
    309 #define	TLM_MAX_TAPE_DRIVES	16
    310 #define	TLM_NAME_SIZE		100
    311 #define	TLM_MAX_TAR_IMAGE	017777777770
    312 
    313 #define	TLM_VOLNAME_MAX_LENGTH	255
    314 #define	NAME_MAX		255
    315 
    316 #define	TLM_MAGIC		"ustar  "
    317 #define	TLM_SNAPSHOT_PREFIX	".zfs"
    318 #define	TLM_SNAPSHOT_DIR	".zfs/snapshot"
    319 
    320 #define	RECORDSIZE	512
    321 #define	NAMSIZ	100
    322 
    323 typedef struct	tlm_tar_hdr {
    324 	char	th_name[TLM_NAME_SIZE];
    325 	char	th_mode[8];
    326 	char	th_uid[8];
    327 	char	th_gid[8];
    328 	char	th_size[12];
    329 	char	th_mtime[12];
    330 	char	th_chksum[8];
    331 	char	th_linkflag;
    332 	char	th_linkname[TLM_NAME_SIZE];
    333 	char	th_magic[8];
    334 	char	th_uname[32];
    335 	char	th_gname[32];
    336 	union {
    337 		struct {
    338 			char	th_devmajor[8];
    339 			char	th_devminor[8];
    340 		} th_dev;
    341 		char	th_hlink_ino[12];
    342 	} th_shared;
    343 } tlm_tar_hdr_t;
    344 
    345 
    346 
    347 /*
    348  * The linkflag defines the type of file
    349  */
    350 #define	LF_OLDNORMAL	'\0'		/* Normal disk file, Unix compat */
    351 #define	LF_NORMAL	'0'		/* Normal disk file */
    352 #define	LF_LINK		'1'		/* Link to previously dumped file */
    353 #define	LF_SYMLINK	'2'		/* Symbolic link */
    354 #define	LF_CHR		'3'		/* Character special file */
    355 #define	LF_BLK		'4'		/* Block special file */
    356 #define	LF_DIR		'5'		/* Directory */
    357 #define	LF_FIFO		'6'		/* FIFO special file */
    358 #define	LF_CONTIG	'7'		/* Contiguous file */
    359 /* Further link types may be defined later. */
    360 
    361 #define	LF_DUMPDIR	'D'
    362 					/*
    363 					 * This is a dir entry that contains
    364 					 * the names of files that were in
    365 					 * the dir at the time the dump
    366 					 * was made
    367 					 */
    368 #define	LF_HUMONGUS	'H'
    369 					/*
    370 					 * Identifies the NEXT file on the tape
    371 					 * as a HUGE file
    372 					 */
    373 #define	LF_LONGLINK	'K'
    374 					/*
    375 					 * Identifies the NEXT file on the tape
    376 					 * as having a long linkname
    377 					 */
    378 #define	LF_LONGNAME	'L'
    379 					/*
    380 					 * Identifies the NEXT file on the tape
    381 					 * as having a long name.
    382 					 */
    383 #define	LF_MULTIVOL	'M'
    384 					/*
    385 					 * This is the continuation
    386 					 * of a file that began on another
    387 					 * volume
    388 					 */
    389 
    390 #define	LF_VOLHDR	'V'		/* This file is a tape/volume header */
    391 					/* Ignore it on extraction */
    392 
    393 #define	LF_ACL		'A'		/* Access Control List */
    394 
    395 #define	LF_XATTR	'E'		/* Extended attribute */
    396 
    397 #define	KILOBYTE	1024
    398 
    399 
    400 /*
    401  * ACL support structure
    402  */
    403 typedef struct sec_attr {
    404 	char attr_type;
    405 	char attr_len[7];
    406 	char attr_info[TLM_MAX_ACL_TXT];
    407 } sec_attr_t;
    408 
    409 typedef struct	tlm_acls {
    410 	int	acl_checkpointed	: 1,	/* are checkpoints active ? */
    411 		acl_clear_archive	: 1,	/* clear archive bit ? */
    412 		acl_overwrite		: 1,	/* always overwrite ? */
    413 		acl_update		: 1,	/* only update ? */
    414 		acl_non_trivial		: 1;	/* real ACLs? */
    415 		/*
    416 		 * The following fields are here to allow
    417 		 * the backup reader to open a file one time
    418 		 * and keep the information for ACL, ATTRs,
    419 		 * and reading the file.
    420 		 */
    421 	sec_attr_t acl_info;
    422 
    423 	char acl_root_dir[TLM_VOLNAME_MAX_LENGTH]; /* name of root filesystem */
    424 	fs_fhandle_t acl_dir_fh;		/* parent dir's info */
    425 	fs_fhandle_t acl_fil_fh;		/* file's info */
    426 	struct stat64 acl_attr;			/* file system attributes */
    427 	char uname[32];
    428 	char gname[32];
    429 } tlm_acls_t;
    430 
    431 
    432 /*
    433  * Tape manager's data archiving ops vector
    434  *
    435  * This vector represents the granular operations for
    436  * performing backup/restore. Each backend should provide
    437  * such a vector interface in order to be invoked by NDMP
    438  * server.
    439  * The reserved callbacks are kept for different backup
    440  * types which are volume-based rather than file-based
    441  * e.g. zfs send.
    442  */
    443 typedef struct tm_ops {
    444 	char *tm_name;
    445 	int (*tm_putfile)();
    446 	int (*tm_putdir)();
    447 	int (*tm_putvol)();	/* Reserved */
    448 	int (*tm_getfile)();
    449 	int (*tm_getdir)();
    450 	int (*tm_getvol)();	/* Reserved */
    451 } tm_ops_t;
    452 
    453 /* The checksum field is filled with this while the checksum is computed. */
    454 #define	CHKBLANKS	"        "	/* 8 blanks, no null */
    455 
    456 #define	LONGNAME_PREFIX	"././_LoNg_NaMe_"
    457 extern void ndmp_log(ulong_t, char *, char *, ...);
    458 char ndmp_log_info[256];
    459 #define	NDMP_LOG(p, ...) { \
    460 				(void) snprintf(ndmp_log_info, \
    461 				    sizeof (ndmp_log_info), \
    462 				    "[%d][%s:%d]", \
    463 				    (int)pthread_self(), __func__, __LINE__); \
    464 				ndmp_log(p, ndmp_log_info, __VA_ARGS__); \
    465 			}
    466 extern void *ndmp_malloc(size_t size);
    467 
    468 /*
    469  * ZFS metadata plug-in module structures
    470  */
    471 #define	ZFS_MAX_PROPS		100
    472 #define	ZFS_META_MAGIC		"ZFSMETA"
    473 #define	ZFS_META_MAGIC_EXT	"ZFSMETA2"
    474 
    475 /* Add new major/minor for header changes */
    476 typedef enum {
    477 	META_HDR_MAJOR_0,	/* Original format */
    478 	META_HDR_MAJOR_1,	/* Extended format */
    479 } ndmp_metadata_header_major_t;
    480 
    481 #define	META_HDR_MAJOR_VERSION	META_HDR_MAJOR_1
    482 
    483 typedef enum {
    484 	META_HDR_MINOR_0,
    485 } ndmp_metadata_header_minor_t;
    486 
    487 #define	META_HDR_MINOR_VERSION	META_HDR_MINOR_0
    488 
    489 /* To support older backups */
    490 typedef struct ndmp_metadata_property {
    491 	char mp_name[NAME_MAX];
    492 	char mp_value[NAME_MAX];
    493 	char mp_source[NAME_MAX];
    494 } ndmp_metadata_property_t;
    495 
    496 typedef struct ndmp_metadata_property_ext {
    497 	char mp_name[ZFS_MAXNAMELEN];
    498 	char mp_value[ZFS_MAXPROPLEN];
    499 	char mp_source[ZFS_MAXPROPLEN];
    500 } ndmp_metadata_property_ext_t;
    501 
    502 typedef struct ndmp_metadata_top_header {
    503 	char th_plname[100];
    504 	uint_t th_plversion;
    505 	char th_magic[10];
    506 	void *th_reserved_1;
    507 	int th_count;
    508 } ndmp_metadata_top_header_t;
    509 
    510 /* Original metadata format */
    511 typedef struct ndmp_metadata_header {
    512 	ndmp_metadata_top_header_t nh_hdr;
    513 	char nh_dataset[NAME_MAX];
    514 	ndmp_metadata_property_t nh_property[1];
    515 } ndmp_metadata_header_t;
    516 
    517 /* Extended metadata format */
    518 typedef struct ndmp_metadata_header_ext {
    519 	ndmp_metadata_top_header_t nh_hdr;
    520 	char nh_dataset[ZFS_MAXNAMELEN];
    521 	int32_t nh_total_bytes;
    522 	int32_t nh_major;
    523 	int32_t nh_minor;
    524 	ndmp_metadata_property_ext_t nh_property[1];
    525 } ndmp_metadata_header_ext_t;
    526 
    527 #define	nh_plname	nh_hdr.th_plname
    528 #define	nh_plversion	nh_hdr.th_plversion
    529 #define	nh_magic	nh_hdr.th_magic
    530 #define	nh_count	nh_hdr.th_count
    531 
    532 typedef struct ndmp_metadata_handle {
    533 	void *ml_handle;
    534 	int32_t ml_quota_prop;
    535 	union {
    536 		ndmp_metadata_header_t *u_hdr;
    537 		ndmp_metadata_header_ext_t *u_xhdr;
    538 	} ml_hdr_u;
    539 } ndmp_metadata_handle_t;
    540 
    541 #define	ml_hdr	ml_hdr_u.u_hdr
    542 #define	ml_xhdr	ml_hdr_u.u_xhdr
    543 
    544 /*
    545  * Node in struct hardlink_q
    546  *
    547  * inode: the inode of the hardlink
    548  * path: the name of the hardlink, used during restore
    549  * offset: tape offset of the data records for the hardlink, used during backup
    550  * is_tmp: indicate whether the file was created temporarily for restoring
    551  * other links during a non-DAR partial restore
    552  */
    553 struct hardlink_node {
    554 	unsigned long inode;
    555 	char *path;
    556 	unsigned long long offset;
    557 	int is_tmp;
    558 	SLIST_ENTRY(hardlink_node) next_hardlink;
    559 };
    560 
    561 /*
    562  * Hardlinks that have been backed up or restored.
    563  *
    564  * During backup, each node represents a file whose
    565  *   (1) inode has multiple links
    566  *   (2) data has been backed up
    567  *
    568  * When we run into a file with multiple links during backup,
    569  * we first check the list to see whether a file with the same inode
    570  * has been backed up.  If yes, we backup an empty record, while
    571  * making the file history of this file contain the data offset
    572  * of the offset of the file that has been backed up.  If no,
    573  * we backup this file, and add an entry to the list.
    574  *
    575  * During restore, each node represents an LF_LINK type record whose
    576  * data has been restored (v.s. a hard link has been created).
    577  *
    578  * During restore, when we run into a record of LF_LINK type, we
    579  * first check the queue to see whether a file with the same inode
    580  * has been restored.  If yes, we create a hardlink to it.
    581  * If no, we restore the data, and add an entry to the list.
    582  */
    583 struct hardlink_q {
    584 	struct hardlink_node *slh_first;
    585 };
    586 
    587 /* Utility functions from handling hardlink */
    588 extern struct hardlink_q *hardlink_q_init();
    589 extern void hardlink_q_cleanup(struct hardlink_q *qhead);
    590 extern int hardlink_q_get(struct hardlink_q *qhead, unsigned long inode,
    591     unsigned long long *offset, char **path);
    592 extern int hardlink_q_add(struct hardlink_q *qhead, unsigned long inode,
    593     unsigned long long offset, char *path, int is_tmp);
    594 
    595 #endif	/* !_TLM_H_ */
    596