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