]> git.neil.brown.name Git - LaFS.git/blob - layout.h
fed1473127e572ff9644ebb40e544926298a6782
[LaFS.git] / layout.h
1 /*
2  * fs/lafs/layout.h
3  * Copyright (C) 2005-2009
4  * Neil Brown <neilb@suse.de>
5  * Released under the GPL, version 2
6  *
7  * layout of device superblock
8  * and array state block
9  */
10
11 /* All multibyte numerical values are in little-endian order
12  */
13
14 /* The "superblock" describes a particular device in the filesystem.
15  * different devices have different superblocks.
16  */
17 struct lafs_dev {
18         char    idtag[16];      /* LaFS-DeviceBlock */
19         char    version[16];    /* number space options */
20         u8      uuid[16];
21         u32     checksum;
22         u32     seq;
23
24         u64     ctime;
25         u64     start, size;    /* in array address space (array block)*/
26         u64     devaddr[2];     /* (device byte) one at each "end" */
27         u64     stateaddr[4];   /* (device byte) 4 state blocks, two at each end */
28
29         u8      statebits;      /* log of size of stateblock - normally 10-14 */
30         u8      blockbits;      /* bits in fs block (byte)- 9 - 16 */
31         u16     width;          /* devices in array - 1 to a few hundred */
32         u32     stride;         /* Blocks in a stride - 1 to a very large number */
33         u32     segment_size;   /* blocks in a segment (block) */
34         u32     segment_offset; /* offset of first segment (device byte) */
35         u32     segment_count;
36         u32     usage_inum;     /* inum of segment usage file */
37         u32     level;
38 }  __attribute__((packed));
39 #define  LAFS_DEVBLK_SIZE       1024
40
41 struct lafs_state {
42         char    idtag[16];      /* LaFS-State-Block */
43         char    version[16];    /* number space options */
44         u32     checksum;
45         u32     seq;
46         u8      uuid[16];
47         u32     levels;
48         u32     devices;
49         u32     nonlog_segment; /* segment number and */
50         u16     nonlog_dev;     /* device number of active non-logged segment */
51         u16     nonlog_offset;  /* offset into above segment of next non-logged
52                                  * block to allocate
53                                  */
54         u32     maxsnapshot;
55         u16     nextyouth;
56         u16     pad0;
57
58         u64     checkpointcluster;      /* (array block) */
59         u64     root_inodes[0]; /* (array block) */
60 } __attribute__((packed));
61
62 struct descriptor {
63         u32     block_num;      /* (file block) */
64         u16     block_cnt;      /* int */
65         u16     block_bytes;    /* 0..blocksize - 0 means 'punch a hole',
66                                  * 1..blocksize means advance EOF to there
67                                  */
68 } __attribute__((packed));
69 #define DescHole        0
70 #define DescIndex       0xffff
71 #define DescMiniOffset  0x8000
72
73 #define ROUND_UP(x)  (((x)+3)&~3)
74
75 struct miniblock {
76         u32     block_num;      /* (file block) */
77         u16     block_offset;   /* (byte) */
78         u16     length;         /* (bytes) + 0x8000 */
79         u8      data[0];
80 } __attribute__((packed));
81
82 struct group_head {
83         u32     inum;
84         u32     fsnum;
85         u16     truncatenum_and_flag;
86         u16     group_size_words;       /* 4byte words */
87         union {
88                 struct descriptor desc[0];
89                 struct miniblock mb[0];
90         } u;
91 }  __attribute__((packed));
92
93 struct cluster_head {
94         char    idtag[8];       /* LaFSHead */
95         u8      uuid[16];
96         u64     seq;
97         u32     flags;
98         u16     Hlength;        /* header length - (bytes) */
99         u16     Clength;        /* cluster length including header - (blocks) */
100         u32     checksum;       /* over Hlength bytes */
101         u16     verify_type;
102         u16     pad0;
103         u8      verify_data[16];
104         u64     next_addr;      /* (Array block) */
105         u64     this_addr;      /* (array block) */
106         u64     prev_addr;      /* (array block) */
107         struct group_head groups[0];
108 }  __attribute__((packed));
109
110 #define CH_Checkpoint           1
111 #define CH_CheckpointStart      2
112 #define CH_CheckpointEnd        4
113
114 /* values for verify_type */
115 #define VerifyNull      0       /* if you found me, I'm valid */
116 #define VerifyNext      1       /* if next head is valid, this cluster is */
117 #define VerifyNext2     2       /* if next 2 heads are valid, this cluster is */
118 #define VerifySum       3       /* maybe some sort of MIC is in _data */
119
120 struct la_inode {
121         /* 16 bytes is constant */
122         u32     data_blocks;    /* (blocks) */
123         u32     index_blocks;   /* (blocks) */
124         u16     generation;
125         u16     metadata_size;  /* (bytes) */
126         u8      depth;
127         u8      trunc_gen;
128         u8      filetype;
129         u8      flags;
130 #define File_nonlogged  1
131         union {
132                 struct fs_metadata {
133                         /* 52 bytes plus name. */
134                         u64     update_time;
135                         u64     blocks_used; /* data+index */
136                         u64     blocks_allowed;
137                         u64     creation_age;
138                         u32     inodes_used;
139                         u32     quota_inodes[3];
140                         u16     snapshot_usage_table;
141                         u16     pad;
142                         char    name[0]; /* variable size, nul padded, but
143                                           * not necessarily nul terminated */
144                 } fs;
145                 struct inodemap_metadata {
146                         u32     size;
147                 } inodemap;
148                 struct su_metadata {
149                         u32     table_size;     /* (blocks) */
150                 } segmentusage;
151                 struct file_metadata {
152                         u16     flags;
153                         u16     mode;
154                         u32     userid;
155                         u32     groupid;
156                         u32     treeid;
157                         u64     creationtime;
158                         u64     modifytime;
159                         u64     ctime;
160                         u64     accesstime;
161                         u64     size;
162                         u32     parent;
163                         u32     linkcount;
164                         u32     attrinode;
165                         u32     attributes[0];
166                 } __attribute__((packed)) file;
167                 struct dir_metadata {
168                         struct file_metadata h;
169                         u32     hash_seed;
170                         u32     attributes[0];
171                 } dir;
172                 struct special_metadata {
173                         struct file_metadata h;
174                         u32     major;
175                         u32     minor;
176                         u32     attributes[0];
177                 } special;
178                 struct quota_metadata {
179                         u32     gracetime; /* typically '7' */
180                         u32     graceunits; /* typically 24*60*60 */
181                 } quota;
182         } metadata[0];
183 } __attribute__((packed));
184
185 #define LAFS_INODE_LOG_START offsetof(struct la_inode, metadata[0].file.flags)
186 #define LAFS_INODE_LOG_END offsetof(struct la_inode, metadata[0].file.size)
187 #define LAFS_INODE_LOG_SIZE (LAFS_INODE_LOG_END - LAFS_INODE_LOG_START)
188
189 #define TypeInodeFile   1
190 #define TypeInodeMap    2
191 #define TypeSegmentMap  3
192 #define TypeQuota       4
193 #define TypeOrphanList  5
194 #define TypeAccessTime  6
195
196 #define TypeBase        16
197
198 #define TypeFile        16
199 #define TypeDir         17
200 #define TypeSymlink     18
201 #define TypeSpecial     19 /* char or block, or pipe or socket */
202 #define TypeAttr        20
203
204 #define LAFS_MAX_LINKS ((1UL<<31)-1)
205
206 struct index {
207         u32     logical;
208         u32     phys_lo;
209         u16     phys_hi;
210 } __attribute__((packed));
211
212 struct extent {
213         u32     phys_lo;
214         u16     phys_hi;
215         u16     size;
216         u32     logical;
217 }  __attribute__((packed));
218 #define IBLK_INDEX (0)
219 #define IBLK_INDIRECT (1)
220 #define IBLK_EXTENT (2)
221
222 #define MaxDirHash 0x7fffffffUL
223 struct dirpiece {
224         u32     target; /* inode number */
225         u8      next[2]; /* back, fore */
226         u8      type:4, chain_info:2, longer:2;
227 /* 'longer' is 3 if fore and back the same length
228  *   0  if back (next[0]) is longer
229  *   1  if fore (next[1]) is longer
230  * 'chain_info' is
231  *   0,1: add that number to the hash of filename
232  *   2  : add one trailing byte to hash
233  *   3  : add 4 trailing bytes (little-endian) to hash
234  */
235 #define Neither 3
236         u8      length;
237         char    name[0];
238 }  __attribute__((packed));
239
240 #define NoBlock (0xFFFFFFFF)
241 struct dirheader {
242         u8      root;
243         u8      lastpiece;
244         u8      freepieces;
245         u8      pad;
246 } __attribute__((packed));
247
248 /*
249  * Miniblock for directory updates record the operation type
250  * in the block_offset
251  */
252 #define DIROP_LINK              0
253 #define DIROP_UNLINK            1
254 #define DIROP_REN_SOURCE        2
255 #define DIROP_REN_TARGET        3
256
257 /*
258  * The orphan file has a very simple structure with
259  * 16 byte records identifying blocks in files that
260  * might be orphans
261  */
262 struct orphan {
263         u32     type;   /* 0 if free */
264         u32     filesys;
265         u32     inum;
266         u32     addr;
267 } __attribute__((packed));
268
269 /* Youth values are decayed when nextyouth gets too big */
270 static int inline decay_youth(int y)
271 {
272         if (y < 8)
273                 return y;
274         if (y < 32768+8)
275                 y = (y-8)/2 + 8;
276         else
277                 y -= 16384;
278         return y;
279 }
280 /* This is only called on large youth values */
281 static int inline decay_undo(int y)
282 {
283         return y + 16384;
284 }