-
Notifications
You must be signed in to change notification settings - Fork 96
Expand file tree
/
Copy pathltfs.h
More file actions
723 lines (630 loc) · 31.9 KB
/
ltfs.h
File metadata and controls
723 lines (630 loc) · 31.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
/*
**
** OO_Copyright_BEGIN
**
**
** Copyright 2010, 2025 IBM Corp. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. Neither the name of the copyright holder nor the names of its
** contributors may be used to endorse or promote products derived from
** this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
**
** OO_Copyright_END
**
*************************************************************************************
**
** COMPONENT NAME: IBM Linear Tape File System
**
** FILE NAME: ltfs.h
**
** DESCRIPTION: Defines LTFS data structures and prototypes for libltfs.
**
** AUTHORS: Brian Biskeborn
** IBM Almaden Research Center
** bbiskebo@us.ibm.com
**
** Lucas C. Villa Real
** IBM Almaden Research Center
** lucasvr@us.ibm.com
**
*************************************************************************************
*/
#ifndef __ltfs_h__
#define __ltfs_h__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef mingw_PLATFORM
#include "arch/win/win_util.h"
#include <time.h>
#else
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#ifndef __FreeBSD__
#include <sys/xattr.h>
#endif
#ifdef __APPLE_MAKEFILE__
#include <ICU/unicode/utypes.h>
#else
#include <unicode/utypes.h>
#endif
#endif
/* O_BINARY is defined only in MinGW */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ltfs_fuse_version.h"
#include "libltfs/arch/signal_internal.h"
#include "libltfs/arch/arch_info.h"
#include "libltfs/ltfs_error.h"
#include "libltfs/ltfslogging.h"
#include "libltfs/ltfstrace.h"
#include "libltfs/ltfs_types.h"
#include "libltfs/ltfs_thread.h"
#include "libltfs/ltfs_locking.h"
#include "libltfs/queue.h"
#include "libltfs/uthash.h"
#include "libltfs/arch/time_internal.h"
#include "libltfs/arch/ltfs_arch_ops.h"
#include "tape_ops.h"
/* forward declarations from tape.h, tape_ops.h */
struct tape_ops;
struct device_data;
#ifndef LTFS_DEFAULT_WORK_DIR
#ifdef mingw_PLATFORM
#define LTFS_DEFAULT_WORK_DIR "c:/tmp/ltfs"
#include <io.h>
#else
#define LTFS_DEFAULT_WORK_DIR "/tmp/ltfs"
#endif
#endif
#define LTFS_MIN_CACHE_SIZE_DEFAULT 25 /* Default minimum cache size (MiB) */
#define LTFS_MAX_CACHE_SIZE_DEFAULT 50 /* Default maximum cache size (MiB) */
#define LTFS_SYNC_PERIOD_DEFAULT (5 * 60) /* default sync period (5 minutes) */
#define LTFS_NUM_PARTITIONS 2
#define LTFS_FILENAME_MAX 255
#define LTFS_MAX_XATTR_SIZE 4096
#define LTFS_SUPER_MAGIC 0x7af3
#ifdef __NetBSD__
#define LTFS_DEFAULT_BLOCKSIZE MAXPHYS
#else
#define LTFS_DEFAULT_BLOCKSIZE (512*1024)
#endif
#define LTFS_MIN_BLOCKSIZE 4096
#define LTFS_LABEL_MAX 4096
#define LTFS_CRC_SIZE (4)
#define MAKE_LTFS_VERSION(x,y,z) (10000*(x) + 100*(y) + (z))
#define LTFS_FORMAT_MAJOR(v) (v / 10000)
#define LTFS_FORMAT_MINOR(v) ((v - ((v / 10000) * 10000))/100)
#define LTFS_FORMAT_REVISION(v) (v % 100)
#define LTFS_LABEL_VERSION_MIN MAKE_LTFS_VERSION(1,0,0) /* Min supported label version */
#define LTFS_LABEL_VERSION_MAX MAKE_LTFS_VERSION(2,99,99) /* Max supported label version */
#define LTFS_LABEL_VERSION MAKE_LTFS_VERSION(2,4,0) /* Written label version */
#define LTFS_LABEL_VERSION_STR "2.4.0" /* Label version string */
#define LTFS_INDEX_VERSION_MIN MAKE_LTFS_VERSION(1,0,0) /* Min supported index version */
#define LTFS_INDEX_VERSION_MAX MAKE_LTFS_VERSION(2,99,99) /* Max supported index version */
#define LTFS_INDEX_VERSION MAKE_LTFS_VERSION(2,4,0) /* Written index version */
#define LTFS_INDEX_VERSION_STR "2.4.0" /* Index version string */
#define INDEX_MAX_COMMENT_LEN 65536 /* Maximum comment field length (per LTFS Format) */
#define LTFS_NO_BARCODE "NO_BARCODE"
#ifndef __APPLE_CONFIG__
#include "config.h"
#endif
#define LTFS_LOSTANDFOUND_DIR "_ltfs_lostandfound"
#define LTFS_VENDOR_NAME "IBM"
#define LTFS_LIVELINK_EA_NAME "ltfs.vendor.IBM.prefixLength"
/* rao parameters */
#define LTFS_OUT_FILE_EXTENSION ".out"
#define RAO_MAX_FILENUM 2700 /* Maximum file number allowed for RAO */
#define LTFS_GEOMETORY_OFF (0x00)
#define LTFS_GEOMETORY_ON (0x01)
/* Maximum size allowed that is returned from RAO */
#define RAO_MAX_RET_SIZE ((RAO_MAX_FILENUM * (32 + (LTFS_GEOMETORY_OFF * 20))) + 8)
#define INTERRUPTED_GOTO(rc, label) \
do{ \
if (ltfs_is_interrupted()) { \
ltfsmsg(LTFS_INFO, 17159I); \
rc = -LTFS_INTERRUPTED; \
goto label; \
} \
}while (0)
#define INTERRUPTED_RETURN() \
do{ \
if (ltfs_is_interrupted()) { \
ltfsmsg(LTFS_INFO, 17159I); \
return -LTFS_INTERRUPTED; \
} \
}while (0)
/* Never returns from this macro. Send abort signal and wait to abort */
#define KILL_MYSELF() \
do{ \
kill(getpid(), SIGABRT); \
do {sleep(1);}while(1); \
}while(0)
#define NO_BARCODE " "
#define HAVE_BARCODE(v) strcmp(v->label->barcode, NO_BARCODE)
/* Callback prototype used to list directories. The function must return 0 on success
* or a negative value on error. */
typedef int (*ltfs_dir_filler) (void *buf, const char *name, void *priv);
/**
* All capacities are relative to filesystem block size.
*/
struct device_param {
/* Parameters for tape drive*/
unsigned int max_blksize; /* Maximum block size */
/* Parameters for current loaded tape */
unsigned char cart_type; /* Cartridge type in CM like TC_MP_JB */
unsigned char density; /* Current density code */
unsigned int write_protected; /* Write protect status of the tape (use bit field of volumelock_status) */
bool is_encrypted; /* Is encrypted tape ? */
bool is_worm; /* Is worm tape? */
};
struct device_capacity {
unsigned long remaining_ip; /**< Remaining capacity of index partition */
unsigned long remaining_dp; /**< Remaining capacity of data partition */
unsigned long total_ip; /**< Total capacity of index partition */
unsigned long total_dp; /**< Total capacity of data partition */
};
struct tape_offset {
tape_block_t block;
char partition;
};
/**
* Extent information
*/
struct extent_info {
TAILQ_ENTRY(extent_info) list;
struct tape_offset start;
uint32_t byteoffset;
uint64_t bytecount;
uint64_t fileoffset;
};
/**
* Structure to handle nametype in the LTFS format spec
*/
struct ltfs_name {
bool percent_encode; /**< True if name shall be percent encoded at index writing */
char *name; /**< Name which is percent decoded if required */
};
/**
* Extended attributes
*/
struct xattr_info {
TAILQ_ENTRY(xattr_info) list;
struct ltfs_name key;
char *value;
size_t size;
};
/**
* Hash table structure to child node in a directory
*/
struct name_list {
struct dentry *d;
char *name;
uint64_t uid;
UT_hash_handle hh;
};
struct dentry {
/* When more than one of these locks is needed, take them in the order of
* iosched_lock, contents_lock, meta_lock. If the tape device lock is needed, take it
* before meta_lock. If locks are needed on a dentry's parent, take all parent locks before
* any dentry locks. */
MultiReaderSingleWriter contents_lock; /**< Lock for 'extentlist' and 'list' */
MultiReaderSingleWriter meta_lock; /**< Lock for metadata */
ltfs_mutex_t iosched_lock; /**< Lock for use by the I/O scheduler */
/* Immutable fields. No locks are needed to access these. */
ino_t ino; /**< Per-session inode number, unique across all LTFS volumes in this process */
uint64_t uid; /**< Persistent unique id. In single drive mode, this id is also used as inode number. */
bool isdir; /**< True if this is a directory, false if it's a file */
bool isslink; /**< True if this is a symlink, false if it's a file or directory */
struct ltfs_name target; /**< Target name of symbolic link */
bool out_of_sync; /**< This object was failed to sync */
TAILQ_ENTRY(dentry) list; /**< To be tail q entry to manage out of sync dentry list */
struct ltfs_volume *vol; /**< Volume to which this dentry belongs */
size_t tag_count; /**< Number of unknown tags */
unsigned char **preserved_tags; /**< Unknown tags to be preserved on tape */
/* Take the contents_lock before accessing these fields. */
TAILQ_HEAD(extent_struct, extent_info) extentlist; /**< List of extents (file only) */
/* Take the contents_lock and the meta_lock before writing to these fields. Take either of
* those locks before reading these fields. */
uint64_t realsize; /**< Size, not counting sparse tail */
uint64_t size; /**< File size (logical EOF position) */
bool extents_dirty; /**< Dirty flag of extents */
uint64_t used_blocks; /**< number of used block on tape */
bool dirty; /**< Dirty flag of the file will clear when this dentry written to sync file list */
/* Take the meta_lock and parent's contents_lock before writing to these fields.
* Take either of those locks before reading these fields. */
struct ltfs_name name; /**< File or directory name */
char *platform_safe_name; /**< File or directory name after file name mangling */
struct dentry *parent; /**< Pointer to parent dentry */
/* Take the meta_lock before accessing these fields. */
TAILQ_HEAD(xattr_struct, xattr_info) xattrlist; /**< List of extended attributes */
bool readonly; /**< True if file is marked read-only */
struct ltfs_timespec creation_time; /**< Time of creation */
struct ltfs_timespec modify_time; /**< Time of last modification */
struct ltfs_timespec access_time; /**< Time of last access */
struct ltfs_timespec change_time; /**< Time of last status change */
struct ltfs_timespec backup_time; /**< Time of last backup */
uint32_t numhandles; /**< Reference count */
uint32_t link_count; /**< Number of file system links to this dentry */
bool deleted; /**< True if dentry is unlinked from the file system */
bool matches_name_criteria; /**< True if file name matches the name criteria rules */
void *dentry_proxy; /**< dentry proxy corresponding to this dentry */
bool need_update_time; /**< True if write api has come from Windows side */
bool is_immutable; /**< True if dentry is set to Immutable */
bool is_appendonly; /**< True if dentry is set to Append Only */
/* Take the iosched_lock before accessing iosched_priv. */
void *iosched_priv; /**< I/O scheduler private data. */
struct name_list *child_list; /* for hash search */
};
struct tape_attr {
char vender[TC_MAM_APP_VENDER_SIZE + 1];
char app_name[TC_MAM_APP_NAME_SIZE + 1];
char app_ver[TC_MAM_APP_VERSION_SIZE + 1];
char medium_label[TC_MAM_USER_MEDIUM_LABEL_SIZE + 1];
unsigned char tli;
char barcode[TC_MAM_BARCODE_SIZE + 1];
char app_format_ver[TC_MAM_APP_FORMAT_VERSION_SIZE + 1];
unsigned char vollock;
char media_pool[TC_MAM_MEDIA_POOL_SIZE + 1];
};
typedef enum mam_advisory_lock_status {
UNLOCKED_MAM = 0,
LOCKED_MAM = 1, /* Advisory locked (Set VOL_LOCKED) */
PWE_MAM = 2, /* Single write perm (Set VOL_PERM_WRITE_ERR) */
PERMLOCKED_MAM = 3, /* Advisory perm locked (Set VOL_PERM_LOCKED) */
PWE_MAM_DP = 4, /* Single write perm on DP (Set VOL_DP_PERM_ERR) */
PWE_MAM_IP = 5, /* Single write perm on IP (Set VOL_IP_PERM__ERR) */
PWE_MAM_BOTH = 6, /* Double write perm (Set both VOL_DP_PERM_ERR and VOL_IP_PERM_ERR) */
NOLOCK_MAM = 128, /* From HPE */
} mam_lockval;
#define IS_SINGLE_WRITE_PERM(stat) (stat == PWE_MAM || (stat == PWE_MAM_DP || stat == PWE_MAM_IP) )
#define IS_DOUBLE_WRITE_PERM(stat) (stat == PWE_MAM_BOTH)
enum volumelock_status {
VOL_UNLOCKED = 0x00000000,
VOL_LOCKED = 0x00000001, /**< Advisory locked on the LTFS format*/
VOL_PERM_LOCKED = 0x00000002, /**< Advisory perm locked on the LTFS format */
VOL_PHYSICAL_WP = 0x00000004, /**< Physical write protect on tape */
VOL_PERM_WP = 0x00000008, /**< Permanent write protect on tape */
VOL_PERS_WP = 0x00000010, /**< Persistent write protect on tape */
VOL_PERM_WRITE_ERR = 0x00000020, /**< Permanent write error on the LTFS format */
VOL_DP_PERM_ERR = 0x00000040, /**< Permanent write error on DP on the LTFS format */
VOL_IP_PERM_ERR = 0x00000080, /**< Permanent write error on IP on the LTFS format */
/*
* TODO: May be need 64-bit integer to handle following definition
* Please consider to move to #define
*/
VOL_FORCE_READ_ONLY = 0x100000000, /**< Force read only */
};
enum volume_mount_type {
MOUNT_NORMAL = 0, /**< Normal mount */
MOUNT_ROLLBACK, /**< Roll back mount */
MOUNT_ERR_TAPE, /**< Mount write perm tape */
};
#define VOL_WRITE_PERM_MASK (0xE0)
#define VOL_ADV_LOCK_MASK (0x03)
struct ltfs_volume {
/* acquire this lock for read before using the volume in any way. acquire it for write before
* writing the index to tape or performing other exclusive operations. */
MultiReaderSingleWriter lock; /**< Controls access to volume metadata */
/* LTFS format data */
struct tc_coherency ip_coh; /**< Index partition coherency info */
struct tc_coherency dp_coh; /**< Data partition coherency info */
struct ltfs_label *label; /**< Information from the partition labels */
struct ltfs_index *index; /**< Current cartridge index */
char *index_cache_path; /**< File name of on-disk index cache */
/* Opaque handles to higher-level structures */
void *iosched_handle; /**< Handle to the I/O scheduler state */
void *changer_handle; /**< Handle to changer controller state */
void *dcache_handle; /**< Handle to the Dentry cache manager state */
void *periodic_sync_handle; /**< Handle to the periodic sync state */
void *kmi_handle; /**< Handle to the key manager interface state */
/* Internal state variables */
struct device_data *device; /**< Device-specific data */
bool ip_index_file_end; /**< Does the index partition end in an index file? */
bool dp_index_file_end; /**< Does the data partition end in an index file? */
enum volume_mount_type mount_type; /**< Mount type defined by enum */
int traverse_mode; /**< Traverse strategy (rollback, list index, rollback mount) */
bool skip_eod_check; /**< Skip EOD existance check? */
bool ignore_wrong_version; /**< Ignore wrong index version while seeking index? */
/* A 1-block read cache, used to prevent reading the same block from tape over and over.
* You MUST hold the tape device lock before accessing this buffer. */
struct tape_offset last_pos; /**< Position of last block read from the tape. */
unsigned long last_size; /**< Size of last block read from the tape. */
char *last_block; /**< Contents of last block read from the tape. */
/* Caches of cartridge health and capacity data. Take the device lock before using these. */
cartridge_health_info health_cache;
uint64_t tape_alert;
struct device_capacity capacity_cache;
/* User-controlled parameters */
char *creator; /**< Creator string to use when writing labels, index files */
void *opt_args; /**< FUSE command-line arguments */
size_t cache_size_min; /**< Starting scheduler cache size in MiB */
size_t cache_size_max; /**< Maximum scheduler cache size in MiB */
bool reset_capacity; /**< Force to reset tape capacity when formatting tape */
/* Revalidation control. If the cartridge in the drive changes externally, e.g. after
* a drive power cycle, it needs to be revalidated. During the revalidation, operations
* need to be blocked, and if the revalidation fails, operations need to be permanently
* blocked (apart from unmount). */
ltfs_thread_mutex_t reval_lock;
ltfs_thread_cond_t reval_cond;
int reval; /**< One of 0, -LTFS_REVAL_RUNNING, -LTFS_REVAL_FAILED */
bool append_only_mode; /**< Use append-only mode */
bool set_pew; /**< Set PEW value */
bool livelink; /**< Live Link enabled? (SDE) */
char *mountpoint; /**< Store mount point for Live Link (SDE) */
size_t mountpoint_len; /**< Store mount point path length (SDE) */
struct tape_attr *t_attr; /**< Tape Attribute data */
mam_lockval lock_status; /**< Total volume lock status from t_attr->vollock and index->vollock */
struct ltfs_timespec first_locate; /**< Time to first locate */
int file_open_count; /**< Number of opened files */
const char *work_directory;
};
struct ltfs_label {
char *creator; /**< Program that wrote this label */
int version; /**< Label format version, as formatted by MAKE_LTFS_VERSION */
char barcode[7]; /**< Tape barcode number read from the ANSI label */
char vol_uuid[37]; /**< LTFS volume UUID */
struct ltfs_timespec format_time; /**< time when this volume was formatted */
unsigned long blocksize; /**< Preferred tape blocksize */
bool enable_compression; /**< Enable data compression on tape */
/* physical <-> logical partition mapping */
char this_partition; /**< Logical ID of this partition (used on read) */
char partid_dp; /**< Logical ID of data partition */
char partid_ip; /**< Logical ID of index partition */
char part_num2id[LTFS_NUM_PARTITIONS]; /**< Mapping physical partition -> logical ID */
};
/**
* Index partition criteria.
*
* The high and low water mark define how many objects of size @max_filesize_criteria
* to allocate at initialization and at most for a given session. The filename_criteria
* array defines glob patterns that are looked at by the file creation routines so that
* the I/O scheduler can know if the new file is a candidate to go to the index partition
* or not.
*
* Please note that when @max_filesize_criteria is 0 then no caching is performed by
* LTFS and all files go straight to the data partition. The index partition only use
* in this case is to store indices.
*/
struct index_criteria {
bool have_criteria; /**< Does this struct actually specify criteria? */
uint64_t max_filesize_criteria; /**< Maximum file size that goes into the index partition */
struct ltfs_name *glob_patterns; /**< NULL-terminated list of file name criteria */
UChar **glob_cache; /**< Cache of glob patterns in comparison-ready form */
};
struct ltfs_index {
char *creator; /**< Program that wrote this index */
char vol_uuid[37]; /**< LTFS volume UUID */
struct ltfs_name volume_name; /**< human-readable volume name */
unsigned int generation; /**< last generation number written to tape */
struct ltfs_timespec mod_time; /**< time of last modification */
struct tape_offset selfptr; /**< self-pointer (where this index was recovered from tape) */
struct tape_offset backptr; /**< back pointer (to prior generation on data partition) */
/* NOTE: index criteria are accessed without locking, so updates are not thread-safe */
bool criteria_allow_update; /**< Can the index criteria be changed? */
struct index_criteria original_criteria; /**< Index partition criteria from the medium */
struct index_criteria index_criteria; /**< Active index criteria */
struct dentry *root; /**< The directory tree */
ltfs_mutex_t rename_lock; /**< Controls name tree access during renames */
/* Update tracking */
ltfs_mutex_t dirty_lock; /**< Controls access to the update tracking bits */
bool dirty; /**< Set on metadata update, cleared on write to tape */
bool atime_dirty; /**< Set on atime update, cleared on write to tape */
bool use_atime; /**< Set if atime updates should make the index dirty */
uint64_t file_count; /**< Number of files in the file system */
uint64_t uid_number; /**< File/directory's most recently reserved uid number */
uint64_t valid_blocks; /**< Numbert of valid blocks on tape */
char *commit_message; /**< Commit message specified by the "user.ltfs.sync" xattr */
int version; /**< Index format version, as formatted by MAKE_LTFS_VERSION */
/* Reference counts */
ltfs_mutex_t refcount_lock; /**< Controls access to the refcount */
uint64_t refcount; /**< Reference count */
size_t tag_count; /**< Number of unrecognized tags */
unsigned char **preserved_tags; /**< Unrecognized tags, will be preserved when writing tape */
size_t symerr_count; /**< Number of conflicted symlink dentries */
struct dentry **symlink_conflict; /**< symlink/extent conflicted dentries */
mam_lockval vollock; /**< volume lock status on index */
};
struct ltfs_direntry {
struct ltfs_timespec creation_time; /**< Time of creation */
struct ltfs_timespec access_time; /**< Time of last access */
struct ltfs_timespec modify_time; /**< Time of last modification */
struct ltfs_timespec change_time; /**< Time of last status change */
bool isdir; /**< True if this is a directory, false if it's a file */
bool readonly; /**< True if file is marked read-only */
bool isslink; /**< True if file is symbolic link */
uint64_t realsize; /**< Size, not counting sparse tail */
uint64_t size; /**< File size (logical EOF position) */
char *name; /**< File or directory name */
char *platform_safe_name; /**< File or directory name after file name mangling */
};
/* Definitions for sync */
typedef enum {
LTFS_SYNC_NONE,
LTFS_SYNC_TIME,
LTFS_SYNC_CLOSE,
LTFS_SYNC_UNMOUNT
} ltfs_sync_type_t;
/* Reasons of index write */
#define SYNC_EXPLICIT "Explicit Sync"
#define SYNC_PERIODIC "Periodic Sync"
#define SYNC_EA "Sync by EA"
#define SYNC_CLOSE "Sync on close"
#define SYNC_DNO_SPACE "Dcache no space"
#define SYNC_UNMOUNT "Unmount"
#define SYNC_UNMOUNT_NOMEM "Unmount - no memory"
#define SYNC_MOVE "Unmount - %" PRIu64
#define SYNC_CHECK "Check"
#define SYNC_ROLLBACK "Rollback"
#define SYNC_FORMAT "Format"
#define SYNC_RECOVERY "Recovery"
#define SYNC_CASCHE_PRESSURE "Cache Pressure"
#define SYNC_SCAN_TAPE "Scan Tape"
#define SYNC_OOB "Sync via adminchannel"
#define SYNC_WRITE_PERM "Write perm"
#define SYNC_RE_SELECTION "Re-select drive"
#define SYNC_ADV_LOCK "Set advisory lock"
/* Traverse strategy for index */
enum {
TRAVERSE_UNKNOWN,
TRAVERSE_FORWARD,
TRAVERSE_BACKWARD,
};
/* Call back function when index is valid */
typedef int (*f_index_found)(struct ltfs_volume *vol, unsigned int gen, void **list, void *priv);
const char *ltfs_version();
const char *ltfs_format_version();
int ltfs_init(int log_level, bool use_syslog, bool print_thread_id);
int ltfs_fs_init(void);
void ltfs_set_log_level(int log_level);
void ltfs_set_syslog_level(int syslog_level);
bool ltfs_is_interrupted(void);
int ltfs_set_signal_handlers(void);
int ltfs_unset_signal_handlers(void);
int ltfs_finish();
/* Public wrappers for tape_* functions */
const char *ltfs_default_device_name(struct tape_ops *ops);
int ltfs_device_open(const char *devname, struct tape_ops *ops, struct ltfs_volume *vol);
int ltfs_device_reopen(const char *devname, struct ltfs_volume *vol);
void ltfs_device_close(struct ltfs_volume *vol);
void ltfs_device_close_skip_append_only_mode(struct ltfs_volume *vol);
int ltfs_setup_device(struct ltfs_volume *vol);
int ltfs_test_unit_ready(struct ltfs_volume *vol);
int ltfs_get_tape_readonly(struct ltfs_volume *vol);
int ltfs_get_partition_readonly(char partition, struct ltfs_volume *vol);
int ltfs_get_cartridge_health(cartridge_health_info *h, struct ltfs_volume *vol);
int ltfs_get_tape_alert(uint64_t *tape_alert, struct ltfs_volume *vol);
int ltfs_get_tape_alert_unlocked(uint64_t *tape_alert, struct ltfs_volume *vol);
int ltfs_clear_tape_alert(uint64_t tape_alert, struct ltfs_volume *vol);
int ltfs_get_params_unlocked(struct device_param *params, struct ltfs_volume *vol);
int ltfs_get_append_position(uint64_t *pos, struct ltfs_volume *vol);
int ltfs_get_vendorunique_xattr(const char *name, char **buf, struct ltfs_volume *vol);
int ltfs_set_vendorunique_xattr(const char *name, const char *value, size_t size, struct ltfs_volume *vol);
tape_partition_t ltfs_part_id2num(char id, struct ltfs_volume *vol);
int ltfs_volume_alloc(const char *execname, struct ltfs_volume **volume);
void _ltfs_volume_free(bool force, struct ltfs_volume **volume);
#define ltfs_volume_free(vol) \
_ltfs_volume_free(false, vol)
#define ltfs_volume_free_force(vol) \
_ltfs_volume_free(true, vol)
int ltfs_capacity_data(struct device_capacity *cap, struct ltfs_volume *vol);
int ltfs_capacity_data_unlocked(struct device_capacity *cap, struct ltfs_volume *vol);
unsigned long ltfs_get_blocksize(struct ltfs_volume *vol);
bool ltfs_get_compression(struct ltfs_volume *vol);
struct ltfs_timespec ltfs_get_format_time(struct ltfs_volume *vol);
uint64_t ltfs_get_file_count(struct ltfs_volume *vol);
uint64_t ltfs_get_valid_block_count(struct ltfs_volume *vol);
uint64_t ltfs_get_valid_block_count_unlocked(struct ltfs_volume *vol);
int ltfs_update_valid_block_count(struct ltfs_volume *vol, int64_t c);
int ltfs_update_valid_block_count_unlocked(struct ltfs_volume *vol, int64_t c);
unsigned int ltfs_get_index_generation(struct ltfs_volume *vol);
struct ltfs_timespec ltfs_get_index_time(struct ltfs_volume *vol);
struct tape_offset ltfs_get_index_selfpointer(struct ltfs_volume *vol);
struct tape_offset ltfs_get_index_backpointer(struct ltfs_volume *vol);
int ltfs_get_index_commit_message(char **msg, struct ltfs_volume *vol);
int ltfs_get_index_creator(char **msg, struct ltfs_volume *vol);
int ltfs_get_volume_name(char **msg, struct ltfs_volume *vol);
int ltfs_get_index_version(struct ltfs_volume *vol);
const char *ltfs_get_barcode(struct ltfs_volume *vol);
const struct index_criteria *ltfs_get_index_criteria(struct ltfs_volume *vol);
bool ltfs_get_criteria_allow_update(struct ltfs_volume *vol);
int ltfs_start_mount(bool trial, struct ltfs_volume *vol);
int ltfs_mount(bool force_full, bool deep_recovery, bool recover_extra, bool recover_symlink,
unsigned short gen, struct ltfs_volume *vol);
int ltfs_unmount(char *reason, struct ltfs_volume *vol);
void ltfs_dump_tree_unlocked(struct ltfs_index *index);
void ltfs_dump_tree(struct ltfs_volume *vol);
int ltfs_load_tape(struct ltfs_volume *vol);
int ltfs_eject_tape(bool keep_on_drive, struct ltfs_volume *vol);
int ltfs_set_blocksize(unsigned long blocksize, struct ltfs_volume *vol);
int ltfs_set_compression(bool enable_compression, struct ltfs_volume *vol);
int ltfs_set_barcode(const char *barcode, struct ltfs_volume *vol);
int ltfs_set_volume_name(const char *volname, struct ltfs_volume *vol);
int ltfs_set_partition_map(char dp, char ip, int dp_num, int ip_num, struct ltfs_volume *vol);
int ltfs_reset_capacity(bool reset, struct ltfs_volume *vol);
int ltfs_write_label(tape_partition_t partition, struct ltfs_volume *vol);
int ltfs_format_tape(struct ltfs_volume *vol, int density_code, bool destructive);
int ltfs_unformat_tape(struct ltfs_volume *vol, bool long_erase, bool destructive);
bool ltfs_is_dirty(struct ltfs_volume *vol);
int ltfs_load_all_attributes(struct ltfs_volume *vol);
int ltfs_wait_revalidation(struct ltfs_volume *vol);
int ltfs_get_volume_lock(bool exclusive, struct ltfs_volume *vol);
int ltfs_revalidate(bool reacquire, struct ltfs_volume *vol);
void ltfs_use_atime(bool use_atime, struct ltfs_volume *vol);
void ltfs_set_work_dir(const char *dir, struct ltfs_volume *vol);
void ltfs_set_eod_check(bool use, struct ltfs_volume *vol);
void ltfs_set_traverse_mode(int mode, struct ltfs_volume *vol);
int ltfs_override_policy(const char *rules, bool permanent, struct ltfs_volume *vol);
int ltfs_set_scheduler_cache(size_t min_size, size_t max_size, struct ltfs_volume *vol);
size_t ltfs_min_cache_size(struct ltfs_volume *vol);
size_t ltfs_max_cache_size(struct ltfs_volume *vol);
int ltfs_parse_tape_backend_opts(void *opt_args, struct ltfs_volume *vol);
int ltfs_parse_kmi_backend_opts(void *opt_args, struct ltfs_volume *vol);
int ltfs_parse_library_backend_opts(void *opt_args, void *opts);
void ltfs_set_index_dirty(bool locking, bool atime, struct ltfs_index *idx);
void ltfs_unset_index_dirty(bool update_version, struct ltfs_index *idx);
int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol);
int ltfs_save_index_to_disk(const char *work_dir, char * reason, bool need_gen, struct ltfs_volume *vol);
char ltfs_dp_id(struct ltfs_volume *vol);
char ltfs_ip_id(struct ltfs_volume *vol);
const char *ltfs_get_volume_uuid(struct ltfs_volume *vol);
int ltfs_sync_index(char *reason, bool index_locking, struct ltfs_volume *vol);
int ltfs_traverse_index_forward(struct ltfs_volume *vol, char partition, unsigned int gen,
f_index_found func, void **list, void *priv);
int ltfs_traverse_index_backward(struct ltfs_volume *vol, char partition, unsigned int gen,
f_index_found func, void **list, void *priv);
int ltfs_traverse_index_no_eod(struct ltfs_volume *vol, char partition, unsigned int gen,
f_index_found func, void **list, void *priv);
int ltfs_check_eod_status(struct ltfs_volume *vol);
int ltfs_recover_eod(struct ltfs_volume *vol);
int ltfs_release_medium(struct ltfs_volume *vol);
int ltfs_logpage(const uint8_t page, const uint8_t subpage, unsigned char *buf,
const size_t size, struct ltfs_volume *vol);
int ltfs_mam(const tape_partition_t part, unsigned char *buf,
const size_t size, struct ltfs_volume *vol);
int ltfs_wait_device_ready(struct ltfs_volume *vol);
void ltfs_recover_eod_simple(struct ltfs_volume *vol);
int ltfs_print_device_list(struct tape_ops *ops);
void ltfs_enable_livelink_mode(struct ltfs_volume *vol);
int ltfs_profiler_set(uint64_t source, struct ltfs_volume *vol);
int ltfs_get_rao_list(char *path, struct ltfs_volume *vol);
#ifdef __cplusplus
}
#endif
#endif /* __ltfs_h__ */