1 /*
2 * linux/include/linux/jbd.h
3 *
4 * Written by Stephen C. Tweedie <sct@redhat.com>
5 *
6 * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
7 *
8 * This file is part of the Linux kernel and is made available under
9 * the terms of the GNU General Public License, version 2, or at your
10 * option, any later version, incorporated herein by reference.
11 *
12 * Definitions for transaction data structures for the buffer cache
13 * filesystem journaling support.
14 */
15
16 #ifndef _LINUX_JBD_H
17 #define _LINUX_JBD_H
18
19 #include "jfs_compat.h"
20 #define JFS_DEBUG
21 #define jfs_debug jbd_debug
22
23 #ifndef __GNUC__
24 #define __FUNCTION__ ""
25 #endif
26
27 #define journal_oom_retry 0
28
29 #ifdef CONFIG_JBD_DEBUG
30 /*
31 * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
32 * consistency checks. By default we don't do this unless
33 * CONFIG_JBD_DEBUG is on.
34 */
35 #define JBD_EXPENSIVE_CHECKING
36 extern int journal_enable_debug;
37 #else
38 #define journal_enable_debug (-1)
39 #endif /* !CONFIG_JBD_DEBUG */
40
41 #ifdef __STDC__
42 #define jbd_debug(n, f, a...) \
43 do { \
44 if ((n) <= journal_enable_debug) { \
45 printk (KERN_DEBUG "(%s, %d): %s: ", \
46 __FILE__, __LINE__, __FUNCTION__); \
47 printk (f, ## a); \
48 } \
49 } while (0)
50 #else
51 #define jbd_debug(x) /* AIX doesn't do STDC */
52 #endif /* !__STDC__ */
53
54 extern void * __jbd_kmalloc (char *where, size_t size, int flags, int retry);
55 #define jbd_kmalloc(size, flags) \
56 __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
57 #define jbd_rep_kmalloc(size, flags) \
58 __jbd_kmalloc(__FUNCTION__, (size), (flags), 1)
59
60 #define JBD2_MIN_JOURNAL_BLOCKS 1024
61 #define JBD2_DEFAULT_FAST_COMMIT_BLOCKS 256
62
63 /*
64 * Internal structures used by the logging mechanism:
65 */
66
67 #define JBD2_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
68
69 /*
70 * On-disk structures
71 */
72
73 /*
74 * Descriptor block types:
75 */
76
77 #define JBD2_DESCRIPTOR_BLOCK 1
78 #define JBD2_COMMIT_BLOCK 2
79 #define JBD2_SUPERBLOCK_V1 3
80 #define JBD2_SUPERBLOCK_V2 4
81 #define JBD2_REVOKE_BLOCK 5
82 #define JBD2_FC_BLOCK 6
83
84 /*
85 * Standard header for all descriptor blocks:
86 */
87 typedef struct journal_header_s
88 {
89 __be32 h_magic;
90 __be32 h_blocktype;
91 __be32 h_sequence;
92 } journal_header_t;
93
94 /*
95 * Checksum types.
96 */
97 #define JBD2_CRC32_CHKSUM 1
98 #define JBD2_MD5_CHKSUM 2
99 #define JBD2_SHA1_CHKSUM 3
100 #define JBD2_CRC32C_CHKSUM 4
101
102 #define JBD2_CRC32_CHKSUM_SIZE 4
103
104 #define JBD2_CHECKSUM_BYTES (32 / sizeof(__u32))
105 /*
106 * Commit block header for storing transactional checksums:
107 *
108 * NOTE: If FEATURE_COMPAT_CHECKSUM (checksum v1) is set, the h_chksum*
109 * fields are used to store a checksum of the descriptor and data blocks.
110 *
111 * If FEATURE_INCOMPAT_CSUM_V2 (checksum v2) is set, then the h_chksum
112 * field is used to store crc32c(uuid+commit_block). Each journal metadata
113 * block gets its own checksum, and data block checksums are stored in
114 * journal_block_tag (in the descriptor). The other h_chksum* fields are
115 * not used.
116 *
117 * If FEATURE_INCOMPAT_CSUM_V3 is set, the descriptor block uses
118 * journal_block_tag3_t to store a full 32-bit checksum. Everything else
119 * is the same as v2.
120 *
121 * Checksum v1, v2, and v3 are mutually exclusive features.
122 */
123 struct commit_header {
124 __be32 h_magic;
125 __be32 h_blocktype;
126 __be32 h_sequence;
127 unsigned char h_chksum_type;
128 unsigned char h_chksum_size;
129 unsigned char h_padding[2];
130 __be32 h_chksum[JBD2_CHECKSUM_BYTES];
131 __be64 h_commit_sec;
132 __be32 h_commit_nsec;
133 };
134
135 /*
136 * The block tag: used to describe a single buffer in the journal
137 */
138 typedef struct journal_block_tag3_s
139 {
140 __be32 t_blocknr; /* The on-disk block number */
141 __be32 t_flags; /* See below */
142 __be32 t_blocknr_high; /* most-significant high 32bits. */
143 __be32 t_checksum; /* crc32c(uuid+seq+block) */
144 } journal_block_tag3_t;
145
146 typedef struct journal_block_tag_s
147 {
148 __be32 t_blocknr; /* The on-disk block number */
149 __be16 t_checksum; /* truncated crc32c(uuid+seq+block) */
150 __be16 t_flags; /* See below */
151 __be32 t_blocknr_high; /* most-significant high 32bits. */
152 } journal_block_tag_t;
153
154 /* Tail of descriptor or revoke block, for checksumming */
155 struct jbd2_journal_block_tail {
156 __be32 t_checksum;
157 };
158
159 /*
160 * The revoke descriptor: used on disk to describe a series of blocks to
161 * be revoked from the log
162 */
163 typedef struct journal_revoke_header_s
164 {
165 journal_header_t r_header;
166 __be32 r_count; /* Count of bytes used in the block */
167 } jbd2_journal_revoke_header_t;
168
169 /* Definitions for the journal tag flags word: */
170 #define JBD2_FLAG_ESCAPE 1 /* on-disk block is escaped */
171 #define JBD2_FLAG_SAME_UUID 2 /* block has same uuid as previous */
172 #define JBD2_FLAG_DELETED 4 /* block deleted by this transaction */
173 #define JBD2_FLAG_LAST_TAG 8 /* last tag in this descriptor block */
174
175
176 #define UUID_SIZE 16
177 #define JBD2_USERS_MAX 48
178 #define JBD2_USERS_SIZE (UUID_SIZE * JBD2_USERS_MAX)
179 /*
180 * The journal superblock. All fields are in big-endian byte order.
181 */
182 typedef struct journal_superblock_s
183 {
184 /* 0x0000 */
185 journal_header_t s_header;
186
187 /* 0x000C */
188 /* Static information describing the journal */
189 __be32 s_blocksize; /* journal device blocksize */
190 __be32 s_maxlen; /* total blocks in journal file */
191 __be32 s_first; /* first block of log information */
192
193 /* 0x0018 */
194 /* Dynamic information describing the current state of the log */
195 __be32 s_sequence; /* first commit ID expected in log */
196 __be32 s_start; /* blocknr of start of log */
197
198 /* 0x0020 */
199 /* Error value, as set by journal_abort(). */
200 __s32 s_errno;
201
202 /* 0x0024 */
203 /* Remaining fields are only valid in a version-2 superblock */
204 __be32 s_feature_compat; /* compatible feature set */
205 __be32 s_feature_incompat; /* incompatible feature set */
206 __be32 s_feature_ro_compat; /* readonly-compatible feature set */
207 /* 0x0030 */
208 __u8 s_uuid[16]; /* 128-bit uuid for journal */
209
210 /* 0x0040 */
211 __be32 s_nr_users; /* Nr of filesystems sharing log */
212
213 __be32 s_dynsuper; /* Blocknr of dynamic superblock copy*/
214
215 /* 0x0048 */
216 __be32 s_max_transaction; /* Limit of journal blocks per trans.*/
217 __be32 s_max_trans_data; /* Limit of data blocks per trans. */
218
219 /* 0x0050 */
220 __u8 s_checksum_type; /* checksum type */
221 __u8 s_padding2[3];
222 /* 0x0054 */
223 __be32 s_num_fc_blks; /* Number of fast commit blocks */
224 /* 0x0058 */
225 __be32 s_padding[41];
226 __be32 s_checksum; /* crc32c(superblock) */
227
228 /* 0x0100 */
229 __u8 s_users[JBD2_USERS_SIZE]; /* ids of all fs'es sharing the log */
230
231 /* 0x0400 */
232 } journal_superblock_t;
233
234 #define JBD2_HAS_COMPAT_FEATURE(j,mask) \
235 ((j)->j_format_version >= 2 && \
236 ((j)->j_superblock->s_feature_compat & ext2fs_cpu_to_be32((mask))))
237 #define JBD2_HAS_RO_COMPAT_FEATURE(j,mask) \
238 ((j)->j_format_version >= 2 && \
239 ((j)->j_superblock->s_feature_ro_compat & ext2fs_cpu_to_be32((mask))))
240 #define JBD2_HAS_INCOMPAT_FEATURE(j,mask) \
241 ((j)->j_format_version >= 2 && \
242 ((j)->j_superblock->s_feature_incompat & ext2fs_cpu_to_be32((mask))))
243
244 #define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001
245
246 #define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001
247 #define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002
248 #define JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT 0x00000004
249 #define JBD2_FEATURE_INCOMPAT_CSUM_V2 0x00000008
250 #define JBD2_FEATURE_INCOMPAT_CSUM_V3 0x00000010
251 #define JBD2_FEATURE_INCOMPAT_FAST_COMMIT 0x00000020
252
253 /* Features known to this kernel version: */
254 #define JBD2_KNOWN_COMPAT_FEATURES 0
255 #define JBD2_KNOWN_ROCOMPAT_FEATURES 0
256 #define JBD2_KNOWN_INCOMPAT_FEATURES (JBD2_FEATURE_INCOMPAT_REVOKE|\
257 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT| \
258 JBD2_FEATURE_INCOMPAT_64BIT|\
259 JBD2_FEATURE_INCOMPAT_CSUM_V2| \
260 JBD2_FEATURE_INCOMPAT_CSUM_V3 | \
261 JBD2_FEATURE_INCOMPAT_FAST_COMMIT)
262
263 #ifdef NO_INLINE_FUNCS
264 extern size_t journal_tag_bytes(journal_t *journal);
265 extern int jbd2_journal_has_csum_v2or3(journal_t *journal);
266 extern int tid_gt(tid_t x, tid_t y) EXT2FS_ATTR((unused));
267 extern int tid_geq(tid_t x, tid_t y) EXT2FS_ATTR((unused));
268 #endif
269
270 #if (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
271 #ifdef E2FSCK_INCLUDE_INLINE_FUNCS
272 #if (__STDC_VERSION__ >= 199901L)
273 #define _INLINE_ extern inline
274 #else
275 #define _INLINE_ inline
276 #endif
277 #else /* !E2FSCK_INCLUDE_INLINE FUNCS */
278 #if (__STDC_VERSION__ >= 199901L)
279 #define _INLINE_ inline
280 #else /* not C99 */
281 #ifdef __GNUC__
282 #define _INLINE_ extern __inline__
283 #else /* For Watcom C */
284 #define _INLINE_ extern inline
285 #endif /* __GNUC__ */
286 #endif /* __STDC_VERSION__ >= 199901L */
287 #endif /* INCLUDE_INLINE_FUNCS */
288
289 /* journal feature predicate functions */
290 #define JBD2_FEATURE_COMPAT_FUNCS(name, flagname) \
291 _INLINE_ int jbd2_has_feature_##name(journal_t *j); \
292 _INLINE_ int jbd2_has_feature_##name(journal_t *j) \
293 { \
294 return ((j)->j_format_version >= 2 && \
295 ((j)->j_superblock->s_feature_compat & \
296 ext2fs_cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname)) != 0); \
297 } \
298 _INLINE_ void jbd2_set_feature_##name(journal_t *j); \
299 _INLINE_ void jbd2_set_feature_##name(journal_t *j) \
300 { \
301 (j)->j_superblock->s_feature_compat |= \
302 ext2fs_cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname); \
303 } \
304 _INLINE_ void jbd2_clear_feature_##name(journal_t *j); \
305 _INLINE_ void jbd2_clear_feature_##name(journal_t *j) \
306 { \
307 (j)->j_superblock->s_feature_compat &= \
308 ~ext2fs_cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname); \
309 }
310
311 #define JBD2_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
312 _INLINE_ int jbd2_has_feature_##name(journal_t *j); \
313 _INLINE_ int jbd2_has_feature_##name(journal_t *j) \
314 { \
315 return ((j)->j_format_version >= 2 && \
316 ((j)->j_superblock->s_feature_ro_compat & \
317 ext2fs_cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname)) != 0); \
318 } \
319 _INLINE_ void jbd2_set_feature_##name(journal_t *j); \
320 _INLINE_ void jbd2_set_feature_##name(journal_t *j) \
321 { \
322 (j)->j_superblock->s_feature_ro_compat |= \
323 ext2fs_cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname); \
324 } \
325 _INLINE_ void jbd2_clear_feature_##name(journal_t *j); \
326 _INLINE_ void jbd2_clear_feature_##name(journal_t *j) \
327 { \
328 (j)->j_superblock->s_feature_ro_compat &= \
329 ~ext2fs_cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname); \
330 }
331
332 #define JBD2_FEATURE_INCOMPAT_FUNCS(name, flagname) \
333 _INLINE_ int jbd2_has_feature_##name(journal_t *j); \
334 _INLINE_ int jbd2_has_feature_##name(journal_t *j) \
335 { \
336 return ((j)->j_format_version >= 2 && \
337 ((j)->j_superblock->s_feature_incompat & \
338 ext2fs_cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname)) != 0); \
339 } \
340 _INLINE_ void jbd2_set_feature_##name(journal_t *j); \
341 _INLINE_ void jbd2_set_feature_##name(journal_t *j) \
342 { \
343 (j)->j_superblock->s_feature_incompat |= \
344 ext2fs_cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname); \
345 } \
346 _INLINE_ void jbd2_clear_feature_##name(journal_t *j); \
347 _INLINE_ void jbd2_clear_feature_##name(journal_t *j) \
348 { \
349 (j)->j_superblock->s_feature_incompat &= \
350 ~ext2fs_cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname); \
351 }
352
353 #else
354 #define JBD2_FEATURE_COMPAT_FUNCS(name, flagname) \
355 extern int jbd2_has_feature_##name(journal_t *j); \
356 extern void jbd2_set_feature_##name(journal_t *j); \
357 extern void jbd2_clear_feature_##name(journal_t *j);
358
359 #define JBD2_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
360 extern int jbd2_has_feature_##name(journal_t *j); \
361 extern void jbd2_set_feature_##name(journal_t *j); \
362 extern void jbd2_clear_feature_##name(journal_t *j);
363
364 #define JBD2_FEATURE_INCOMPAT_FUNCS(name, flagname) \
365 extern int jbd2_has_feature_##name(journal_t *j); \
366 extern void jbd2_set_feature_##name(journal_t *j); \
367 extern void jbd2_clear_feature_##name(journal_t *j);
368
369 #endif /* (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS)) */
370
JBD2_FEATURE_COMPAT_FUNCS(checksum,CHECKSUM)371 JBD2_FEATURE_COMPAT_FUNCS(checksum, CHECKSUM)
372
373 JBD2_FEATURE_INCOMPAT_FUNCS(revoke, REVOKE)
374 JBD2_FEATURE_INCOMPAT_FUNCS(64bit, 64BIT)
375 JBD2_FEATURE_INCOMPAT_FUNCS(async_commit, ASYNC_COMMIT)
376 JBD2_FEATURE_INCOMPAT_FUNCS(csum2, CSUM_V2)
377 JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3)
378 JBD2_FEATURE_INCOMPAT_FUNCS(fast_commit, FAST_COMMIT)
379
380 #if (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
381 /*
382 * helper functions to deal with 32 or 64bit block numbers.
383 */
384 _INLINE_ size_t journal_tag_bytes(journal_t *journal)
385 {
386 size_t sz;
387
388 if (jbd2_has_feature_csum3(journal))
389 return sizeof(journal_block_tag3_t);
390
391 sz = sizeof(journal_block_tag_t);
392
393 if (jbd2_has_feature_csum2(journal))
394 sz += sizeof(__u16);
395
396 if (jbd2_has_feature_64bit(journal))
397 return sz;
398
399 return sz - sizeof(__u32);
400 }
401
jbd2_journal_has_csum_v2or3(journal_t * journal)402 _INLINE_ int jbd2_journal_has_csum_v2or3(journal_t *journal)
403 {
404 if (jbd2_has_feature_csum2(journal) || jbd2_has_feature_csum3(journal))
405 return 1;
406
407 return 0;
408 }
409
jbd2_journal_get_num_fc_blks(journal_superblock_t * jsb)410 _INLINE_ int jbd2_journal_get_num_fc_blks(journal_superblock_t *jsb)
411 {
412 int num_fc_blocks = be32_to_cpu(jsb->s_num_fc_blks);
413
414 return num_fc_blocks ? num_fc_blocks : JBD2_DEFAULT_FAST_COMMIT_BLOCKS;
415 }
416
417 /* Comparison functions for transaction IDs: perform comparisons using
418 * modulo arithmetic so that they work over sequence number wraps. */
419
tid_gt(tid_t x,tid_t y)420 _INLINE_ int tid_gt(tid_t x, tid_t y)
421 {
422 int difference = (x - y);
423 return (difference > 0);
424 }
425
tid_geq(tid_t x,tid_t y)426 _INLINE_ int tid_geq(tid_t x, tid_t y)
427 {
428 int difference = (x - y);
429 return (difference >= 0);
430 }
431 #endif /* (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS)) */
432
433 #undef _INLINE_
434
435 extern int journal_blocks_per_page(struct inode *inode);
436
437 /*
438 * Definitions which augment the buffer_head layer
439 */
440
441 /* journaling buffer types */
442 #define BJ_None 0 /* Not journaled */
443 #define BJ_SyncData 1 /* Normal data: flush before commit */
444 #define BJ_AsyncData 2 /* writepage data: wait on it before commit */
445 #define BJ_Metadata 3 /* Normal journaled metadata */
446 #define BJ_Forget 4 /* Buffer superceded by this transaction */
447 #define BJ_IO 5 /* Buffer is for temporary IO use */
448 #define BJ_Shadow 6 /* Buffer contents being shadowed to the log */
449 #define BJ_LogCtl 7 /* Buffer contains log descriptors */
450 #define BJ_Reserved 8 /* Buffer is reserved for access by journal */
451 #define BJ_Types 9
452
453 extern int jbd_blocks_per_page(struct inode *inode);
454
455 #endif /* _LINUX_JBD_H */
456