File: content_inode.h

package info (click to toggle)
xfsdump 3.1.9%2B0
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 3,932 kB
  • sloc: ansic: 45,863; sh: 3,227; makefile: 545
file content (410 lines) | stat: -rw-r--r-- 12,801 bytes parent folder | download | duplicates (3)
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
/*
 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#ifndef CONTENT_INODE_H
#define CONTENT_INODE_H

/* content_inode.h - inode-style content strategy-specific header structure
 */

/* dump startpoint: identifies dump stream boundaries
 * NOTE: sp_offset is not a position within a file; it is a quantity of
 * bytes to skip. holes do not count.
 */
struct startpt {
	xfs_ino_t sp_ino;		/* first inode to dump */
	off64_t sp_offset;	/* bytes to skip in file data fork */
	int32_t sp_flags;
	int32_t sp_pad1;
};

typedef struct startpt startpt_t;

#define STARTPT_FLAGS_END		(1 << 0)
		/* this startpt indicates that all extents of all files in
		 * the stream were completely dumped. the other fields
		 * are meaningless. this will appear only once per dump
		 * stream, even if the stream spans multiple media files.
		 *
		 * also used in the strategy-specific portion of the
		 * content header to qualify the ending point.
		 */
#define STARTPT_FLAGS_NULL		(1 << 1)
		/* used to detect if the null file header makes it onto
		 * media. only necessary after the last file in the stream,
		 * to allow the end-of-stream flag in the null header to
		 * be seen.
		 */


/* drange_t - describes a range of ino/offset values
 */
struct drange {
	startpt_t dr_begin;
	startpt_t dr_end;
};

typedef struct drange drange_t;


/* inode-style specific media file header section
 */
#define CONTENT_INODE_HDR_SZ  sizeofmember(content_hdr_t, ch_specific)

struct content_inode_hdr {
	int32_t cih_mediafiletype;			/*   4   4 */
		/* dump media file type: see #defines below */
	int32_t cih_dumpattr;				/*   4   8 */
		/* dump attributes: see #defines below */
	int32_t cih_level;				/*   4   c */
		/* dump level */
	char pad1[4];					/*   4  10 */
		/* alignment */
	time32_t cih_last_time;				/*   4  14 */
		/* if an incremental, time of previous dump at a lesser level */
	time32_t cih_resume_time;			/*   4  18 */
		/* if a resumed dump, time of interrupted dump */
	xfs_ino_t cih_rootino;				/*   8  20 */
		/* root inode number */
	uuid_t cih_last_id;				/*  10  30 */
		/* if an incremental, uuid of prev dump */
	uuid_t cih_resume_id;				/*  10  40 */
		/* if a resumed dump, uuid of interrupted dump */
	startpt_t cih_startpt;				/*  18  58 */
		/* starting point of media file contents */
	startpt_t cih_endpt;				/*  18  70 */
		/* starting point of next stream */
	uint64_t cih_inomap_hnkcnt;			/*   8  78 */

	uint64_t cih_inomap_segcnt;			/*   8  80 */

	uint64_t cih_inomap_dircnt;			/*   8  88 */

	uint64_t cih_inomap_nondircnt;			/*   8  90 */

	xfs_ino_t cih_inomap_firstino;			/*   8  98 */

	xfs_ino_t cih_inomap_lastino;			/*   8  a0 */

	uint64_t cih_inomap_datasz;			/*   8  a8 */
		/* bytes of non-metadata dumped */
	char cih_pad2[CONTENT_INODE_HDR_SZ - 0xa8];	/*  18  c0 */
		/* padding */
};

typedef struct content_inode_hdr content_inode_hdr_t;

/* media file types
 */
#define CIH_MEDIAFILETYPE_DATA		0
#define CIH_MEDIAFILETYPE_INVENTORY	1
#define CIH_MEDIAFILETYPE_INDEX		2

/* dump attributes
 */
#define	CIH_DUMPATTR_SUBTREE			(1 <<  0)
#define	CIH_DUMPATTR_INDEX			(1 <<  1)
#define CIH_DUMPATTR_INVENTORY			(1 <<  2)
#define CIH_DUMPATTR_INCREMENTAL		(1 <<  3)
#define CIH_DUMPATTR_RETRY			(1 <<  4)
#define CIH_DUMPATTR_RESUME			(1 <<  5)
#define CIH_DUMPATTR_INOMAP			(1 <<  6)
#define CIH_DUMPATTR_DIRDUMP			(1 <<  7)
#define CIH_DUMPATTR_FILEHDR_CHECKSUM		(1 <<  8)
#define CIH_DUMPATTR_EXTENTHDR_CHECKSUM		(1 <<  9)
#define CIH_DUMPATTR_DIRENTHDR_CHECKSUM		(1 << 10)
#define CIH_DUMPATTR_DIRENTHDR_GEN		(1 << 11)
#define CIH_DUMPATTR_EXTATTR			(1 << 12)
#define CIH_DUMPATTR_EXTATTRHDR_CHECKSUM	(1 << 13)
#define CIH_DUMPATTR_NOTSELFCONTAINED		(1 << 14)


/* timestruct_t - time structure
 *
 * used in bstat_t below. derived from timestruc_t, to achieve independence
 * from changes to timestruc_t.
 */
#define TIMESTRUCT_SZ	8

struct timestruct {			/*		     bytes accum */
	int32_t		tv_sec;		/* seconds		 4     4 */
	int32_t		tv_nsec;	/* and nanoseconds	 4     8 */
};

typedef struct timestruct timestruct_t;


/* bstat_t - bulk stat structure
 *
 * used in filehdr_t below. derived from struct xfs_bstat, to achieve independence
 * from changes to struct xfs_bstat.
 */
#define BSTAT_SZ	128
#define MODE_SZ		4

struct bstat {				/*		     bytes accum */
	xfs_ino_t	bs_ino;		/* inode number		 8     8 */
	uint32_t	bs_mode;	/* type and mode	 4     c */
	uint32_t	bs_nlink;	/* number of links	 4    10 */
	int32_t		bs_uid;		/* user id		 4    14 */
	int32_t		bs_gid;		/* group id		 4    18 */
	uint32_t	bs_rdev;	/* device value		 4    1c */
	int32_t		bs_blksize;	/* block size		 4    20 */
	off64_t		bs_size;	/* file size		 8    28 */
	timestruct_t	bs_atime;	/* access time		 8    30 */
	timestruct_t	bs_mtime;	/* modify time		 8    38 */
	timestruct_t	bs_ctime;	/* inode change time	 8    40 */
	int64_t		bs_blocks;	/* number of blocks	 8    48 */
	uint32_t	bs_xflags;	/* extended flags	 4    4c */
	int32_t		bs_extsize;	/* extent size		 4    50 */
	int32_t		bs_extents;	/* number of extents	 4    54 */
	uint32_t	bs_gen;		/* generation count	 4    58 */
	uint16_t	bs_projid_lo;	/* low 16 of project id	 2    5a */
	uint16_t	bs_forkoff;	/* inode fork offset	 2    5c */
	uint16_t	bs_projid_hi;	/* hi 16 of project id	 2    5e */
	char		bs_pad[10];	/* for expansion	 e    68 */
	uint32_t	bs_dmevmask;	/* DMI event mask        4    6c */
	uint16_t	bs_dmstate;	/* DMI state info        2    6e */
	char		bs_pad1[18];	/* for expansion        12    80 */
					/* NOTE: old dumps didn't always
					 * zero first 2 bytes of bs_pad1 */
};

typedef struct bstat bstat_t;

/*
 * Project quota id helpers (previously projid was 16bit only
 * and using two 16bit values to hold new 32bit projid was choosen
 * to retain compatibility with "old" filesystems).
 */
static inline uint32_t
bstat_projid(struct bstat *bs)
{
        return (uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo;
}


/* extended inode flags that can only be set after all data
 * has been restored to a file.
 */
#define	POST_DATA_XFLAGS	(XFS_XFLAG_IMMUTABLE |		\
				  XFS_XFLAG_APPEND |		\
				  XFS_XFLAG_SYNC)

/* filehdr_t - header placed at the beginning of every dumped file.
 *
 * each fs file placed on dump media begins with a FILEHDR_SZ-byte header.
 * following that are one or more variable-length content extents.
 * the content extents contain the actual data associated with the fs file.
 */
#define FILEHDR_SZ	256

struct filehdr {
	int64_t fh_offset;
	int32_t fh_flags;
	uint32_t fh_checksum;
	bstat_t fh_stat;
	char fh_pad2[FILEHDR_SZ
		      - sizeof(int64_t)
		      - sizeof(int32_t)
		      - sizeof(uint32_t)
		      - sizeof(bstat_t)];
};

typedef struct filehdr filehdr_t;

#define FILEHDR_FLAGS_NULL	(1 << 0)
		/* identifies a dummy file header. every media file
		 * is terminated with a dummy file header, unless
		 * terminated by end of media.
		 */
#define FILEHDR_FLAGS_CHECKSUM	(1 << 1)
		/* indicates the header checksum is valid
		 */
#define FILEHDR_FLAGS_END	(1 << 2)
		/* the last media file in the stream is always terminated by
		 * a dummy file header, with this flag set.
		 */
#define FILEHDR_FLAGS_EXTATTR	(1 << 3)
		/* special file header followed by one file's (dir or nondir)
		 * extended attributes.
		 */


/* extenthdr_t - a header placed at the beginning of every dumped
 * content extent.
 *
 * a dumped file consists of a filehdr_t followed by zero or more
 * extents. for regular files the last extent is always of type LAST.
 * for symbolic link files, only one extent is dumped, and it contains the
 * symlink path.
 */
#define EXTENTHDR_SZ	32

struct extenthdr {
	off64_t eh_sz; /* length of extent, NOT including header, in bytes */
	off64_t eh_offset;
	int32_t eh_type;
	int32_t eh_flags;
	uint32_t eh_checksum;
	char eh_pad[4];
};

typedef struct extenthdr extenthdr_t;

#define EXTENTHDR_TYPE_LAST	0
		/* always the last extent. sz is always 0
		 */
#define EXTENTHDR_TYPE_ALIGN	1
		/* used for alignment. sz is the number of bytes to skip,
		 * in addition to the hdr
		 */
#define EXTENTHDR_TYPE_DATA	4
		/* heads an extent of ordinary file data. sz is the data
		 * extent length in bytes, NOT including the hdr. offset
		 * indicates the byte position of the extent within the file.
		 * also heads the path in a symlink dump.
		 */
#define EXTENTHDR_TYPE_HOLE	8
		/* used to encode a hole extent. Offset indicates the byte
		 * position of the hole within the file and sz is the
		 * hole extent length.
		 */

#define EXTENTHDR_FLAGS_CHECKSUM	(1 << 0)


/* direnthdr_t - placed at the beginning of every dumped directory entry.
 * a directory entry consists of the fixed size header followed by a variable
 * length NULL-terminated name string, followed by enough padding to make the
 * overall record size a multiple of 8 bytes. the name string begins
 * at the dh_name field. the total number of bytes occupied by
 * each directory entry on media is dh_sz.
 *
 * a sequence of directory entries is always terminated with a null direnthdr_t.
 * this is detected by looking for a zero ino.
 */
typedef uint32_t gen_t;

#define DIRENTHDR_ALIGN	8

#define DIRENTHDR_SZ	24

struct direnthdr {
	xfs_ino_t dh_ino;
	gen_t dh_gen;
	uint32_t dh_checksum;
	uint16_t dh_sz; /* overall size of record */
	char dh_name[6];
};

typedef struct direnthdr direnthdr_t;

/* the old direnthdr truncated the inode generation number
 * to the low 12 bits.
 */

struct direnthdr_v1 {
	xfs_ino_t dh_ino;
	uint16_t dh_gen; /* generation count & DENTGENMASK of ref'ed inode */
	uint16_t dh_sz; /* overall size of record */
	uint32_t dh_checksum;
	char dh_name[8];
};

typedef struct direnthdr_v1 direnthdr_v1_t;

/* truncated generation count
 */
#define DENTGENSZ		12	/* leave 4 bits for future flags */
#define DENTGENMASK		((1 << DENTGENSZ) - 1)
#define BIGGEN2GEN(bg)	((gen_t)(bg & DENTGENMASK))



/* symbolic links will be dumped using an extent header. the extent
 * will always be a multiple of SYMLINK_ALIGN bytes. the symlink character
 * string will always be null-terminated.
 */
#define SYMLINK_ALIGN	8

/* extattr_hdr_t - hdr for an extended attribute. the first byte of the
 * attribute name immediately follows the header. the name is terminated
 * with a NULL byte. Each extattr record will be aligned; there may
 * be padding at the end of each record to achieve this. NOTE: ah_sz
 * includes the hdr sz; adding ah_sz to the offset of one extattr
 * gives the offset of the next.
 */
#define EXTATTRHDR_SZ		16
#define EXTATTRHDR_ALIGN	8

struct extattrhdr {
	uint32_t ah_sz; /* overall size of extended attribute record */
	uint16_t ah_valoff; /* byte offset within record of value */
	uint16_t ah_flags; /* see EXTATTRHDR_FLAGS_... below */
	uint32_t ah_valsz; /* size of value */
	uint32_t ah_checksum; /* hdr checksum */
};

typedef struct extattrhdr extattrhdr_t;

#define EXTATTRHDR_FLAGS_ROOT		(1 << 0)
	/* a "root" mode attribute
	 */
#define EXTATTRHDR_FLAGS_NULL		(1 << 1)
	/* marks the end of the attributes associated with the leading filehdr_t
	 */
#define EXTATTRHDR_FLAGS_OLD_CHECKSUM	(1 << 2)
	/* old xfsdumps used this flag to indicate a checksum is present,
	 * but the checksum was not calculated properly. the presence of
	 * this flag now indicates a checksum that cannot be verified.
	 */
#define EXTATTRHDR_FLAGS_SECURE		(1 << 3)
	/* a linux "secure" mode attribute
	 */
#define EXTATTRHDR_FLAGS_CHECKSUM	(1 << 4)
	/* checksum is present.
	 */

/* Routines for calculating and validating checksums on xfsdump headers.
 * The header length must be an integral number of uint32_t's.
 */
static inline uint32_t
calc_checksum(void *bufp, size_t len)
{
	uint32_t sum = 0;
	uint32_t *sump = bufp;
	uint32_t *endp = sump + len / sizeof(uint32_t);
	assert(len % sizeof(uint32_t) == 0);
	while (sump < endp)
		sum += *sump++;
	return ~sum + 1;
}

static inline bool_t
is_checksum_valid(void *bufp, size_t len)
{
	uint32_t sum = 0;
	uint32_t *sump = bufp;
	uint32_t *endp = sump + len / sizeof(uint32_t);
	assert(len % sizeof(uint32_t) == 0);
	while (sump < endp)
		sum += *sump++;
	return sum == 0 ? BOOL_TRUE : BOOL_FALSE;
}

#endif /* CONTENT_INODE_H */