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
37extern 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
52extern 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
70extern 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 */
101typedef 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 */
137struct 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 */
152typedef 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
160typedef 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 */
169struct 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 */
177typedef 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 */
184struct 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 */
201typedef 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
278extern size_t journal_tag_bytes(journal_t *journal);
279extern int journal_has_csum_v2or3(journal_t *journal);
280extern int tid_gt(tid_t x, tid_t y) EXT2FS_ATTR((unused));
281extern 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) \
369extern int jfs_has_feature_##name(journal_t *j); \
370extern void jfs_set_feature_##name(journal_t *j); \
371extern void jfs_clear_feature_##name(journal_t *j);
372
373#define JFS_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
374extern int jfs_has_feature_##name(journal_t *j); \
375extern void jfs_set_feature_##name(journal_t *j); \
376extern void jfs_clear_feature_##name(journal_t *j);
377
378#define JFS_FEATURE_INCOMPAT_FUNCS(name, flagname) \
379extern int jfs_has_feature_##name(journal_t *j); \
380extern void jfs_set_feature_##name(journal_t *j); \
381extern void jfs_clear_feature_##name(journal_t *j);
382
383#endif /* (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS)) */
384
385JFS_FEATURE_COMPAT_FUNCS(checksum,		CHECKSUM)
386
387JFS_FEATURE_INCOMPAT_FUNCS(revoke,		REVOKE)
388JFS_FEATURE_INCOMPAT_FUNCS(64bit,		64BIT)
389JFS_FEATURE_INCOMPAT_FUNCS(async_commit,	ASYNC_COMMIT)
390JFS_FEATURE_INCOMPAT_FUNCS(csum2,		CSUM_V2)
391JFS_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
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
426_INLINE_ int tid_gt(tid_t x, tid_t y)
427{
428	int difference = (x - y);
429	return (difference > 0);
430}
431
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
441extern 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
459extern int jbd_blocks_per_page(struct inode *inode);
460
461#endif	/* _LINUX_JBD_H */
462