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