Home | History | Annotate | Download | only in ext2fs
      1 /*
      2  * linux/include/linux/jbd.h
      3  *
      4  * Written by Stephen C. Tweedie <sct (at) 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 
    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 
    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 
    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