• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef NO_INLINE_FUNCS
278 extern size_t journal_tag_bytes(journal_t *journal);
279 extern int journal_has_csum_v2or3(journal_t *journal);
280 extern int tid_gt(tid_t x, tid_t y) EXT2FS_ATTR((unused));
281 extern int tid_geq(tid_t x, tid_t y) EXT2FS_ATTR((unused));
282 #endif
283 
284 #if (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
285 #ifdef E2FSCK_INCLUDE_INLINE_FUNCS
286 #if (__STDC_VERSION__ >= 199901L)
287 #define _INLINE_ extern inline
288 #else
289 #define _INLINE_ inline
290 #endif
291 #else /* !E2FSCK_INCLUDE_INLINE FUNCS */
292 #if (__STDC_VERSION__ >= 199901L)
293 #define _INLINE_ inline
294 #else /* not C99 */
295 #ifdef __GNUC__
296 #define _INLINE_ extern __inline__
297 #else				/* For Watcom C */
298 #define _INLINE_ extern inline
299 #endif /* __GNUC__ */
300 #endif /* __STDC_VERSION__ >= 199901L */
301 #endif /* INCLUDE_INLINE_FUNCS */
302 
303 /* journal feature predicate functions */
304 #define JFS_FEATURE_COMPAT_FUNCS(name, flagname) \
305 _INLINE_ int jfs_has_feature_##name(journal_t *j); \
306 _INLINE_ int jfs_has_feature_##name(journal_t *j) \
307 { \
308 	return ((j)->j_format_version >= 2 && \
309 		((j)->j_superblock->s_feature_compat & \
310 		 ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_##flagname)) != 0); \
311 } \
312 _INLINE_ void jfs_set_feature_##name(journal_t *j); \
313 _INLINE_ void jfs_set_feature_##name(journal_t *j) \
314 { \
315 	(j)->j_superblock->s_feature_compat |= \
316 		ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_##flagname); \
317 } \
318 _INLINE_ void jfs_clear_feature_##name(journal_t *j); \
319 _INLINE_ void jfs_clear_feature_##name(journal_t *j) \
320 { \
321 	(j)->j_superblock->s_feature_compat &= \
322 		~ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_##flagname); \
323 }
324 
325 #define JFS_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
326 _INLINE_ int jfs_has_feature_##name(journal_t *j);	\
327 _INLINE_ int jfs_has_feature_##name(journal_t *j) \
328 { \
329 	return ((j)->j_format_version >= 2 && \
330 		((j)->j_superblock->s_feature_ro_compat & \
331 		 ext2fs_cpu_to_be32(JFS_FEATURE_RO_COMPAT_##flagname)) != 0); \
332 } \
333 _INLINE_ void jfs_set_feature_##name(journal_t *j); \
334 _INLINE_ void jfs_set_feature_##name(journal_t *j) \
335 { \
336 	(j)->j_superblock->s_feature_ro_compat |= \
337 		ext2fs_cpu_to_be32(JFS_FEATURE_RO_COMPAT_##flagname); \
338 } \
339 _INLINE_ void jfs_clear_feature_##name(journal_t *j); \
340 _INLINE_ void jfs_clear_feature_##name(journal_t *j) \
341 { \
342 	(j)->j_superblock->s_feature_ro_compat &= \
343 		~ext2fs_cpu_to_be32(JFS_FEATURE_RO_COMPAT_##flagname); \
344 }
345 
346 #define JFS_FEATURE_INCOMPAT_FUNCS(name, flagname) \
347 _INLINE_ int jfs_has_feature_##name(journal_t *j); \
348 _INLINE_ int jfs_has_feature_##name(journal_t *j) \
349 { \
350 	return ((j)->j_format_version >= 2 && \
351 		((j)->j_superblock->s_feature_incompat & \
352 		 ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_##flagname)) != 0); \
353 } \
354 _INLINE_ void jfs_set_feature_##name(journal_t *j); \
355 _INLINE_ void jfs_set_feature_##name(journal_t *j) \
356 { \
357 	(j)->j_superblock->s_feature_incompat |= \
358 		ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_##flagname); \
359 } \
360 _INLINE_ void jfs_clear_feature_##name(journal_t *j); \
361 _INLINE_ void jfs_clear_feature_##name(journal_t *j) \
362 { \
363 	(j)->j_superblock->s_feature_incompat &= \
364 		~ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_##flagname); \
365 }
366 
367 #else
368 #define JFS_FEATURE_COMPAT_FUNCS(name, flagname) \
369 extern int jfs_has_feature_##name(journal_t *j); \
370 extern void jfs_set_feature_##name(journal_t *j); \
371 extern void jfs_clear_feature_##name(journal_t *j);
372 
373 #define JFS_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
374 extern int jfs_has_feature_##name(journal_t *j); \
375 extern void jfs_set_feature_##name(journal_t *j); \
376 extern void jfs_clear_feature_##name(journal_t *j);
377 
378 #define JFS_FEATURE_INCOMPAT_FUNCS(name, flagname) \
379 extern int jfs_has_feature_##name(journal_t *j); \
380 extern void jfs_set_feature_##name(journal_t *j); \
381 extern void jfs_clear_feature_##name(journal_t *j);
382 
383 #endif /* (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS)) */
384 
JFS_FEATURE_COMPAT_FUNCS(checksum,CHECKSUM)385 JFS_FEATURE_COMPAT_FUNCS(checksum,		CHECKSUM)
386 
387 JFS_FEATURE_INCOMPAT_FUNCS(revoke,		REVOKE)
388 JFS_FEATURE_INCOMPAT_FUNCS(64bit,		64BIT)
389 JFS_FEATURE_INCOMPAT_FUNCS(async_commit,	ASYNC_COMMIT)
390 JFS_FEATURE_INCOMPAT_FUNCS(csum2,		CSUM_V2)
391 JFS_FEATURE_INCOMPAT_FUNCS(csum3,		CSUM_V3)
392 
393 #if (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
394 /*
395  * helper functions to deal with 32 or 64bit block numbers.
396  */
397 _INLINE_ size_t journal_tag_bytes(journal_t *journal)
398 {
399 	size_t sz;
400 
401 	if (jfs_has_feature_csum3(journal))
402 		return sizeof(journal_block_tag3_t);
403 
404 	sz = sizeof(journal_block_tag_t);
405 
406 	if (jfs_has_feature_csum2(journal))
407 		sz += sizeof(__u16);
408 
409 	if (jfs_has_feature_64bit(journal))
410 		return sz;
411 
412 	return sz - sizeof(__u32);
413 }
414 
journal_has_csum_v2or3(journal_t * journal)415 _INLINE_ int journal_has_csum_v2or3(journal_t *journal)
416 {
417 	if (jfs_has_feature_csum2(journal) || jfs_has_feature_csum3(journal))
418 		return 1;
419 
420 	return 0;
421 }
422 
423 /* Comparison functions for transaction IDs: perform comparisons using
424  * modulo arithmetic so that they work over sequence number wraps. */
425 
tid_gt(tid_t x,tid_t y)426 _INLINE_ int tid_gt(tid_t x, tid_t y)
427 {
428 	int difference = (x - y);
429 	return (difference > 0);
430 }
431 
tid_geq(tid_t x,tid_t y)432 _INLINE_ int tid_geq(tid_t x, tid_t y)
433 {
434 	int difference = (x - y);
435 	return (difference >= 0);
436 }
437 #endif /* (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS)) */
438 
439 #undef _INLINE_
440 
441 extern int journal_blocks_per_page(struct inode *inode);
442 
443 /*
444  * Definitions which augment the buffer_head layer
445  */
446 
447 /* journaling buffer types */
448 #define BJ_None		0	/* Not journaled */
449 #define BJ_SyncData	1	/* Normal data: flush before commit */
450 #define BJ_AsyncData	2	/* writepage data: wait on it before commit */
451 #define BJ_Metadata	3	/* Normal journaled metadata */
452 #define BJ_Forget	4	/* Buffer superceded by this transaction */
453 #define BJ_IO		5	/* Buffer is for temporary IO use */
454 #define BJ_Shadow	6	/* Buffer contents being shadowed to the log */
455 #define BJ_LogCtl	7	/* Buffer contains log descriptors */
456 #define BJ_Reserved	8	/* Buffer is reserved for access by journal */
457 #define BJ_Types	9
458 
459 extern int jbd_blocks_per_page(struct inode *inode);
460 
461 #endif	/* _LINUX_JBD_H */
462