2 * journal.c --- code for handling the "ext3" journal
4 * Copyright (C) 2000 Andreas Dilger
5 * Copyright (C) 2000 Theodore Ts'o
7 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
8 * Copyright (C) 1999 Red Hat Software
10 * This file may be redistributed under the terms of the
11 * GNU General Public License version 2 or at your discretion
16 #ifdef HAVE_SYS_MOUNT_H
17 #include <sys/param.h>
18 #include <sys/mount.h>
19 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
21 #ifdef HAVE_SYS_STAT_H
25 #define E2FSCK_INCLUDE_INLINE_FUNCS
26 #include "uuid/uuid.h"
29 #ifdef CONFIG_JBD_DEBUG /* Enabled by configure --enable-jfs-debug */
30 static int bh_count
= 0;
33 #if EXT2_FLAT_INCLUDES
36 #include "blkid/blkid.h"
40 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
41 * This creates a larger static binary, and a smaller binary using
42 * shared libraries. It's also probably slightly less CPU-efficient,
43 * which is why it's not on by default. But, it's a good way of
44 * testing the functions in inode_io.c and fileio.c.
48 /* Checksumming functions */
49 static int ext2fs_journal_verify_csum_type(journal_t
*j
,
50 journal_superblock_t
*jsb
)
52 if (!journal_has_csum_v2or3(j
))
55 return jsb
->s_checksum_type
== JBD2_CRC32C_CHKSUM
;
58 static __u32
ext2fs_journal_sb_csum(journal_superblock_t
*jsb
)
62 old_crc
= jsb
->s_checksum
;
64 crc
= ext2fs_crc32c_le(~0, (unsigned char *)jsb
,
65 sizeof(journal_superblock_t
));
66 jsb
->s_checksum
= old_crc
;
71 static int ext2fs_journal_sb_csum_verify(journal_t
*j
,
72 journal_superblock_t
*jsb
)
74 __u32 provided
, calculated
;
76 if (!journal_has_csum_v2or3(j
))
79 provided
= ext2fs_be32_to_cpu(jsb
->s_checksum
);
80 calculated
= ext2fs_journal_sb_csum(jsb
);
82 return provided
== calculated
;
85 static errcode_t
ext2fs_journal_sb_csum_set(journal_t
*j
,
86 journal_superblock_t
*jsb
)
90 if (!journal_has_csum_v2or3(j
))
93 crc
= ext2fs_journal_sb_csum(jsb
);
94 jsb
->s_checksum
= ext2fs_cpu_to_be32(crc
);
98 /* Kernel compatibility functions for handling the journal. These allow us
99 * to use the recovery.c file virtually unchanged from the kernel, so we
100 * don't have to do much to keep kernel and user recovery in sync.
102 int journal_bmap(journal_t
*journal
, blk64_t block
, unsigned long long *phys
)
108 struct inode
*inode
= journal
->j_inode
;
117 retval
= ext2fs_bmap2(inode
->i_fs
, inode
->i_ino
,
118 &inode
->i_ext2
, NULL
, 0, block
, 0, &pblk
);
124 struct buffer_head
*getblk(kdev_t kdev
, blk64_t blocknr
, int blocksize
)
126 struct buffer_head
*bh
;
127 int bufsize
= sizeof(*bh
) + kdev
->k_fs
->blocksize
-
131 retval
= ext2fs_get_memzero(bufsize
, &bh
);
135 #ifdef CONFIG_JBD_DEBUG
136 if (journal_enable_debug
>= 3)
139 jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
140 (unsigned long long) blocknr
, blocksize
, bh_count
);
142 bh
->b_fs
= kdev
->k_fs
;
143 if (kdev
->k_dev
== K_DEV_FS
)
144 bh
->b_io
= kdev
->k_fs
->io
;
146 bh
->b_io
= kdev
->k_fs
->journal_io
;
147 bh
->b_size
= blocksize
;
148 bh
->b_blocknr
= blocknr
;
153 int sync_blockdev(kdev_t kdev
)
157 if (kdev
->k_dev
== K_DEV_FS
)
160 io
= kdev
->k_fs
->journal_io
;
162 return io_channel_flush(io
) ? EIO
: 0;
165 void ll_rw_block(int rw
, int nr
, struct buffer_head
*bhp
[])
168 struct buffer_head
*bh
;
170 for (; nr
> 0; --nr
) {
172 if (rw
== READ
&& !bh
->b_uptodate
) {
173 jfs_debug(3, "reading block %llu/%p\n",
174 bh
->b_blocknr
, (void *) bh
);
175 retval
= io_channel_read_blk64(bh
->b_io
,
179 com_err(bh
->b_fs
->device_name
, retval
,
180 "while reading block %llu\n",
182 bh
->b_err
= (int) retval
;
186 } else if (rw
== WRITE
&& bh
->b_dirty
) {
187 jfs_debug(3, "writing block %llu/%p\n",
190 retval
= io_channel_write_blk64(bh
->b_io
,
194 com_err(bh
->b_fs
->device_name
, retval
,
195 "while writing block %llu\n",
197 bh
->b_err
= (int) retval
;
203 jfs_debug(3, "no-op %s for block %llu\n",
204 rw
== READ
? "read" : "write",
210 void mark_buffer_dirty(struct buffer_head
*bh
)
215 static void mark_buffer_clean(struct buffer_head
*bh
)
220 void brelse(struct buffer_head
*bh
)
223 ll_rw_block(WRITE
, 1, &bh
);
224 jfs_debug(3, "freeing block %llu/%p (total %d)\n",
225 bh
->b_blocknr
, (void *) bh
, --bh_count
);
226 ext2fs_free_mem(&bh
);
229 int buffer_uptodate(struct buffer_head
*bh
)
231 return bh
->b_uptodate
;
234 void mark_buffer_uptodate(struct buffer_head
*bh
, int val
)
236 bh
->b_uptodate
= val
;
239 void wait_on_buffer(struct buffer_head
*bh
)
242 ll_rw_block(READ
, 1, &bh
);
246 static void ext2fs_clear_recover(ext2_filsys fs
, int error
)
248 ext2fs_clear_feature_journal_needs_recovery(fs
->super
);
250 /* if we had an error doing journal recovery, we need a full fsck */
252 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
253 ext2fs_mark_super_dirty(fs
);
257 * This is a helper function to check the validity of the journal.
259 struct process_block_struct
{
260 e2_blkcnt_t last_block
;
263 static int process_journal_block(ext2_filsys fs
,
265 e2_blkcnt_t blockcnt
,
266 blk64_t ref_block
EXT2FS_ATTR((unused
)),
267 int ref_offset
EXT2FS_ATTR((unused
)),
270 struct process_block_struct
*p
;
271 blk64_t blk
= *block_nr
;
273 p
= (struct process_block_struct
*) priv_data
;
275 if (!blk
|| blk
< fs
->super
->s_first_data_block
||
276 blk
>= ext2fs_blocks_count(fs
->super
))
280 p
->last_block
= blockcnt
;
284 static errcode_t
ext2fs_get_journal(ext2_filsys fs
, journal_t
**ret_journal
)
286 struct process_block_struct pb
;
287 struct ext2_super_block
*sb
= fs
->super
;
288 struct ext2_super_block jsuper
;
289 struct buffer_head
*bh
;
290 struct inode
*j_inode
= NULL
;
291 struct kdev_s
*dev_fs
= NULL
, *dev_journal
;
292 const char *journal_name
= 0;
293 journal_t
*journal
= NULL
;
294 errcode_t retval
= 0;
295 io_manager io_ptr
= 0;
296 unsigned long long start
= 0;
298 int tried_backup_jnl
= 0;
300 retval
= ext2fs_get_memzero(sizeof(journal_t
), &journal
);
304 retval
= ext2fs_get_memzero(2 * sizeof(struct kdev_s
), &dev_fs
);
307 dev_journal
= dev_fs
+1;
309 dev_fs
->k_fs
= dev_journal
->k_fs
= fs
;
310 dev_fs
->k_dev
= K_DEV_FS
;
311 dev_journal
->k_dev
= K_DEV_JOURNAL
;
313 journal
->j_dev
= dev_journal
;
314 journal
->j_fs_dev
= dev_fs
;
315 journal
->j_inode
= NULL
;
316 journal
->j_blocksize
= fs
->blocksize
;
318 if (uuid_is_null(sb
->s_journal_uuid
)) {
319 if (!sb
->s_journal_inum
) {
320 retval
= EXT2_ET_BAD_INODE_NUM
;
323 retval
= ext2fs_get_memzero(sizeof(*j_inode
), &j_inode
);
328 j_inode
->i_ino
= sb
->s_journal_inum
;
330 retval
= ext2fs_read_inode(fs
, sb
->s_journal_inum
,
334 if (sb
->s_jnl_backup_type
!= EXT3_JNL_BACKUP_BLOCKS
||
337 memset(&j_inode
->i_ext2
, 0, sizeof(struct ext2_inode
));
338 memcpy(&j_inode
->i_ext2
.i_block
[0], sb
->s_jnl_blocks
,
340 j_inode
->i_ext2
.i_size_high
= sb
->s_jnl_blocks
[15];
341 j_inode
->i_ext2
.i_size
= sb
->s_jnl_blocks
[16];
342 j_inode
->i_ext2
.i_links_count
= 1;
343 j_inode
->i_ext2
.i_mode
= LINUX_S_IFREG
| 0600;
346 if (!j_inode
->i_ext2
.i_links_count
||
347 !LINUX_S_ISREG(j_inode
->i_ext2
.i_mode
)) {
348 retval
= EXT2_ET_NO_JOURNAL
;
349 goto try_backup_journal
;
351 if (EXT2_I_SIZE(&j_inode
->i_ext2
) / journal
->j_blocksize
<
352 JFS_MIN_JOURNAL_BLOCKS
) {
353 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
354 goto try_backup_journal
;
357 retval
= ext2fs_block_iterate3(fs
, j_inode
->i_ino
,
359 process_journal_block
, &pb
);
360 if ((pb
.last_block
+ 1) * fs
->blocksize
<
361 (int) EXT2_I_SIZE(&j_inode
->i_ext2
)) {
362 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
363 goto try_backup_journal
;
365 if (tried_backup_jnl
&& (fs
->flags
& EXT2_FLAG_RW
)) {
366 retval
= ext2fs_write_inode(fs
, sb
->s_journal_inum
,
372 journal
->j_maxlen
= EXT2_I_SIZE(&j_inode
->i_ext2
) /
373 journal
->j_blocksize
;
376 retval
= ext2fs_inode_io_intern2(fs
, sb
->s_journal_inum
,
382 io_ptr
= inode_io_manager
;
384 journal
->j_inode
= j_inode
;
385 fs
->journal_io
= fs
->io
;
386 retval
= (errcode_t
)journal_bmap(journal
, 0, &start
);
392 if (!fs
->journal_name
) {
396 blkid_get_cache(&blkid
, NULL
);
397 uuid_unparse(sb
->s_journal_uuid
, uuid
);
398 fs
->journal_name
= blkid_get_devname(blkid
,
400 if (!fs
->journal_name
)
401 fs
->journal_name
= blkid_devno_to_devname(sb
->s_journal_dev
);
402 blkid_put_cache(blkid
);
404 journal_name
= fs
->journal_name
;
407 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
411 jfs_debug(1, "Using journal file %s\n", journal_name
);
412 io_ptr
= unix_io_manager
;
416 test_io_backing_manager
= io_ptr
;
417 io_ptr
= test_io_manager
;
423 retval
= io_ptr
->open(journal_name
, fs
->flags
& EXT2_FLAG_RW
,
429 io_channel_set_blksize(fs
->journal_io
, fs
->blocksize
);
434 start
= ext2fs_journal_sb_start(fs
->blocksize
) - 1;
435 bh
= getblk(dev_journal
, start
, fs
->blocksize
);
437 retval
= EXT2_ET_NO_MEMORY
;
440 ll_rw_block(READ
, 1, &bh
);
446 memcpy(&jsuper
, start
? bh
->b_data
:
447 bh
->b_data
+ SUPERBLOCK_OFFSET
,
449 #ifdef WORDS_BIGENDIAN
450 if (jsuper
.s_magic
== ext2fs_swab16(EXT2_SUPER_MAGIC
))
451 ext2fs_swap_super(&jsuper
);
453 if (jsuper
.s_magic
!= EXT2_SUPER_MAGIC
||
454 !ext2fs_has_feature_journal_dev(&jsuper
)) {
455 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
459 /* Make sure the journal UUID is correct */
460 if (memcmp(jsuper
.s_uuid
, fs
->super
->s_journal_uuid
,
461 sizeof(jsuper
.s_uuid
))) {
462 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
467 /* Check the superblock checksum */
468 if (ext2fs_has_feature_metadata_csum(&jsuper
)) {
469 struct struct_ext2_filsys fsx
;
470 struct ext2_super_block superx
;
473 p
= start
? bh
->b_data
: bh
->b_data
+ SUPERBLOCK_OFFSET
;
474 memcpy(&fsx
, fs
, sizeof(fsx
));
475 memcpy(&superx
, fs
->super
, sizeof(superx
));
477 ext2fs_set_feature_metadata_csum(fsx
.super
);
478 if (!ext2fs_superblock_csum_verify(&fsx
, p
)) {
479 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
486 maxlen
= ext2fs_blocks_count(&jsuper
);
487 journal
->j_maxlen
= (maxlen
< 1ULL << 32) ? maxlen
:
492 bh
= getblk(dev_journal
, start
, journal
->j_blocksize
);
494 retval
= EXT2_ET_NO_MEMORY
;
498 journal
->j_sb_buffer
= bh
;
499 journal
->j_superblock
= (journal_superblock_t
*)bh
->b_data
;
503 ext2fs_free_mem(&j_inode
);
506 *ret_journal
= journal
;
511 ext2fs_free_mem(&dev_fs
);
513 ext2fs_free_mem(&j_inode
);
515 ext2fs_free_mem(&journal
);
519 static errcode_t
ext2fs_journal_fix_bad_inode(ext2_filsys fs
)
521 struct ext2_super_block
*sb
= fs
->super
;
522 int recover
= ext2fs_has_feature_journal_needs_recovery(fs
->super
);
523 int has_journal
= ext2fs_has_feature_journal(fs
->super
);
525 if (has_journal
|| sb
->s_journal_inum
) {
526 /* The journal inode is bogus, remove and force full fsck */
527 return EXT2_ET_BAD_INODE_NUM
;
528 } else if (recover
) {
529 return EXT2_ET_UNSUPP_FEATURE
;
534 #define V1_SB_SIZE 0x0024
535 static void clear_v2_journal_fields(journal_t
*journal
)
537 ext2_filsys fs
= journal
->j_dev
->k_fs
;
539 memset(((char *) journal
->j_superblock
) + V1_SB_SIZE
, 0,
540 fs
->blocksize
-V1_SB_SIZE
);
541 mark_buffer_dirty(journal
->j_sb_buffer
);
545 static errcode_t
ext2fs_journal_load(journal_t
*journal
)
547 ext2_filsys fs
= journal
->j_dev
->k_fs
;
548 journal_superblock_t
*jsb
;
549 struct buffer_head
*jbh
= journal
->j_sb_buffer
;
551 ll_rw_block(READ
, 1, &jbh
);
555 jsb
= journal
->j_superblock
;
556 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
557 if (jsb
->s_header
.h_magic
!= htonl(JFS_MAGIC_NUMBER
))
558 return ext2fs_journal_fix_bad_inode(fs
);
560 switch (ntohl(jsb
->s_header
.h_blocktype
)) {
561 case JFS_SUPERBLOCK_V1
:
562 journal
->j_format_version
= 1;
563 if (jsb
->s_feature_compat
||
564 jsb
->s_feature_incompat
||
565 jsb
->s_feature_ro_compat
||
567 clear_v2_journal_fields(journal
);
570 case JFS_SUPERBLOCK_V2
:
571 journal
->j_format_version
= 2;
572 if (ntohl(jsb
->s_nr_users
) > 1 &&
573 uuid_is_null(fs
->super
->s_journal_uuid
))
574 clear_v2_journal_fields(journal
);
575 if (ntohl(jsb
->s_nr_users
) > 1)
576 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
580 * These should never appear in a journal super block, so if
581 * they do, the journal is badly corrupted.
583 case JFS_DESCRIPTOR_BLOCK
:
584 case JFS_COMMIT_BLOCK
:
585 case JFS_REVOKE_BLOCK
:
586 return EXT2_ET_CORRUPT_SUPERBLOCK
;
588 /* If we don't understand the superblock major type, but there
589 * is a magic number, then it is likely to be a new format we
590 * just don't understand, so leave it alone. */
592 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
595 if (JFS_HAS_INCOMPAT_FEATURE(journal
, ~JFS_KNOWN_INCOMPAT_FEATURES
))
596 return EXT2_ET_UNSUPP_FEATURE
;
598 if (JFS_HAS_RO_COMPAT_FEATURE(journal
, ~JFS_KNOWN_ROCOMPAT_FEATURES
))
599 return EXT2_ET_RO_UNSUPP_FEATURE
;
601 /* Checksum v1-3 are mutually exclusive features. */
602 if (jfs_has_feature_csum2(journal
) && jfs_has_feature_csum3(journal
))
603 return EXT2_ET_CORRUPT_SUPERBLOCK
;
605 if (journal_has_csum_v2or3(journal
) &&
606 jfs_has_feature_checksum(journal
))
607 return EXT2_ET_CORRUPT_SUPERBLOCK
;
609 if (!ext2fs_journal_verify_csum_type(journal
, jsb
) ||
610 !ext2fs_journal_sb_csum_verify(journal
, jsb
))
611 return EXT2_ET_CORRUPT_SUPERBLOCK
;
613 if (journal_has_csum_v2or3(journal
))
614 journal
->j_csum_seed
= jbd2_chksum(journal
, ~0, jsb
->s_uuid
,
615 sizeof(jsb
->s_uuid
));
617 /* We have now checked whether we know enough about the journal
618 * format to be able to proceed safely, so any other checks that
619 * fail we should attempt to recover from. */
620 if (jsb
->s_blocksize
!= htonl(journal
->j_blocksize
))
621 return EXT2_ET_CORRUPT_SUPERBLOCK
;
623 if (ntohl(jsb
->s_maxlen
) < journal
->j_maxlen
)
624 journal
->j_maxlen
= ntohl(jsb
->s_maxlen
);
625 else if (ntohl(jsb
->s_maxlen
) > journal
->j_maxlen
)
626 return EXT2_ET_CORRUPT_SUPERBLOCK
;
628 journal
->j_tail_sequence
= ntohl(jsb
->s_sequence
);
629 journal
->j_transaction_sequence
= journal
->j_tail_sequence
;
630 journal
->j_tail
= ntohl(jsb
->s_start
);
631 journal
->j_first
= ntohl(jsb
->s_first
);
632 journal
->j_last
= ntohl(jsb
->s_maxlen
);
637 static void ext2fs_journal_release(ext2_filsys fs
, journal_t
*journal
,
640 journal_superblock_t
*jsb
;
643 mark_buffer_clean(journal
->j_sb_buffer
);
644 else if (fs
->flags
& EXT2_FLAG_RW
) {
645 jsb
= journal
->j_superblock
;
646 jsb
->s_sequence
= htonl(journal
->j_tail_sequence
);
648 jsb
->s_start
= 0; /* this marks the journal as empty */
649 ext2fs_journal_sb_csum_set(journal
, jsb
);
650 mark_buffer_dirty(journal
->j_sb_buffer
);
652 brelse(journal
->j_sb_buffer
);
654 if (fs
&& fs
->journal_io
) {
655 if (fs
->io
!= fs
->journal_io
)
656 io_channel_close(fs
->journal_io
);
657 fs
->journal_io
= NULL
;
661 if (journal
->j_inode
)
662 ext2fs_free_mem(&journal
->j_inode
);
664 if (journal
->j_fs_dev
)
665 ext2fs_free_mem(&journal
->j_fs_dev
);
666 ext2fs_free_mem(&journal
);
670 * This function makes sure that the superblock fields regarding the
671 * journal are consistent.
673 static errcode_t
ext2fs_check_ext3_journal(ext2_filsys fs
)
675 struct ext2_super_block
*sb
= fs
->super
;
677 int recover
= ext2fs_has_feature_journal_needs_recovery(fs
->super
);
680 /* If we don't have any journal features, don't do anything more */
681 if (!ext2fs_has_feature_journal(sb
) &&
682 !recover
&& sb
->s_journal_inum
== 0 && sb
->s_journal_dev
== 0 &&
683 uuid_is_null(sb
->s_journal_uuid
))
686 retval
= ext2fs_get_journal(fs
, &journal
);
690 retval
= ext2fs_journal_load(journal
);
695 * We want to make the flags consistent here. We will not leave with
696 * needs_recovery set but has_journal clear. We can't get in a loop
697 * with -y, -n, or -p, only if a user isn't making up their mind.
699 if (!ext2fs_has_feature_journal(sb
)) {
700 retval
= EXT2_ET_JOURNAL_FLAGS_WRONG
;
704 if (ext2fs_has_feature_journal(sb
) &&
705 !ext2fs_has_feature_journal_needs_recovery(sb
) &&
706 journal
->j_superblock
->s_start
!= 0) {
707 retval
= EXT2_ET_JOURNAL_FLAGS_WRONG
;
712 * If we don't need to do replay the journal, check to see if
713 * the journal's errno is set; if so, we need to mark the file
714 * system as being corrupt and clear the journal's s_errno.
716 if (!ext2fs_has_feature_journal_needs_recovery(sb
) &&
717 journal
->j_superblock
->s_errno
) {
718 fs
->super
->s_state
|= EXT2_ERROR_FS
;
719 ext2fs_mark_super_dirty(fs
);
720 journal
->j_superblock
->s_errno
= 0;
721 ext2fs_journal_sb_csum_set(journal
, journal
->j_superblock
);
722 mark_buffer_dirty(journal
->j_sb_buffer
);
726 ext2fs_journal_release(fs
, journal
, 0, retval
? 1 : 0);
730 static errcode_t
recover_ext3_journal(ext2_filsys fs
)
735 journal_init_revoke_caches();
736 retval
= ext2fs_get_journal(fs
, &journal
);
740 retval
= ext2fs_journal_load(journal
);
744 retval
= journal_init_revoke(journal
, 1024);
748 retval
= -journal_recover(journal
);
752 if (journal
->j_failed_commit
) {
753 journal
->j_superblock
->s_errno
= -EINVAL
;
754 mark_buffer_dirty(journal
->j_sb_buffer
);
758 journal_destroy_revoke(journal
);
759 journal_destroy_revoke_caches();
760 ext2fs_journal_release(fs
, journal
, 1, 0);
764 errcode_t
ext2fs_run_ext3_journal(ext2_filsys
*fsp
)
766 ext2_filsys fs
= *fsp
;
767 io_manager io_ptr
= fs
->io
->manager
;
768 errcode_t retval
, recover_retval
;
770 unsigned long long kbytes_written
= 0;
775 if (!(fs
->flags
& EXT2_FLAG_RW
))
776 return EXT2_ET_FILE_RO
;
778 if (fs
->flags
& EXT2_FLAG_DIRTY
)
779 ext2fs_flush(fs
); /* Force out any modifications */
781 recover_retval
= recover_ext3_journal(fs
);
784 * Reload the filesystem context to get up-to-date data from disk
785 * because journal recovery will change the filesystem under us.
787 if (fs
->super
->s_kbytes_written
&&
788 fs
->io
->manager
->get_stats
)
789 fs
->io
->manager
->get_stats(fs
->io
, &stats
);
790 if (stats
&& stats
->bytes_written
)
791 kbytes_written
= stats
->bytes_written
>> 10;
794 fsname
= strdup(fs
->device_name
);
796 fsblocksize
= fs
->blocksize
;
798 retval
= ext2fs_open(fsname
, fsflags
,
799 0, fsblocksize
, io_ptr
,
806 fs
->flags
|= EXT2_FLAG_MASTER_SB_ONLY
;
807 fs
->super
->s_kbytes_written
+= kbytes_written
;
809 /* Set the superblock flags */
810 ext2fs_clear_recover(fs
, recover_retval
!= 0);
813 * Do one last sanity check, and propagate journal->s_errno to
814 * the EXT2_ERROR_FS flag in the fs superblock if needed.
816 retval
= ext2fs_check_ext3_journal(fs
);
817 return retval
? retval
: recover_retval
;
820 errcode_t
ext2fs_open_journal(ext2_filsys fs
, journal_t
**j
)
825 journal_init_revoke_caches();
826 retval
= ext2fs_get_journal(fs
, &journal
);
830 retval
= ext2fs_journal_load(journal
);
834 retval
= journal_init_revoke(journal
, 1024);
838 if (journal
->j_failed_commit
) {
839 journal
->j_superblock
->s_errno
= -EINVAL
;
840 mark_buffer_dirty(journal
->j_sb_buffer
);
847 journal_destroy_revoke(journal
);
848 journal_destroy_revoke_caches();
849 ext2fs_journal_release(fs
, journal
, 1, 0);
853 errcode_t
ext2fs_close_journal(ext2_filsys fs
, journal_t
**j
)
855 journal_t
*journal
= *j
;
857 journal_destroy_revoke(journal
);
858 journal_destroy_revoke_caches();
859 ext2fs_journal_release(fs
, journal
, 0, 0);
865 void jbd2_commit_block_csum_set(journal_t
*j
, struct buffer_head
*bh
)
867 struct commit_header
*h
;
870 if (!journal_has_csum_v2or3(j
))
873 h
= (struct commit_header
*)(bh
->b_data
);
874 h
->h_chksum_type
= 0;
875 h
->h_chksum_size
= 0;
877 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
878 h
->h_chksum
[0] = ext2fs_cpu_to_be32(csum
);
881 void jbd2_revoke_csum_set(journal_t
*j
, struct buffer_head
*bh
)
883 struct journal_revoke_tail
*tail
;
886 if (!journal_has_csum_v2or3(j
))
889 tail
= (struct journal_revoke_tail
*)(bh
->b_data
+ j
->j_blocksize
-
890 sizeof(struct journal_revoke_tail
));
891 tail
->r_checksum
= 0;
892 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
893 tail
->r_checksum
= ext2fs_cpu_to_be32(csum
);
896 void jbd2_descr_block_csum_set(journal_t
*j
, struct buffer_head
*bh
)
898 struct journal_block_tail
*tail
;
901 if (!journal_has_csum_v2or3(j
))
904 tail
= (struct journal_block_tail
*)(bh
->b_data
+ j
->j_blocksize
-
905 sizeof(struct journal_block_tail
));
906 tail
->t_checksum
= 0;
907 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
908 tail
->t_checksum
= ext2fs_cpu_to_be32(csum
);
911 void jbd2_block_tag_csum_set(journal_t
*j
, journal_block_tag_t
*tag
,
912 struct buffer_head
*bh
, __u32 sequence
)
914 journal_block_tag3_t
*tag3
= (journal_block_tag3_t
*)tag
;
918 if (!journal_has_csum_v2or3(j
))
921 seq
= ext2fs_cpu_to_be32(sequence
);
922 csum32
= jbd2_chksum(j
, j
->j_csum_seed
, (__u8
*)&seq
, sizeof(seq
));
923 csum32
= jbd2_chksum(j
, csum32
, bh
->b_data
, bh
->b_size
);
925 if (jfs_has_feature_csum3(j
))
926 tag3
->t_checksum
= ext2fs_cpu_to_be32(csum32
);
928 tag
->t_checksum
= ext2fs_cpu_to_be16(csum32
);