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 static int bh_count
= 0;
31 #if EXT2_FLAT_INCLUDES
34 #include "blkid/blkid.h"
38 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
39 * This creates a larger static binary, and a smaller binary using
40 * shared libraries. It's also probably slightly less CPU-efficient,
41 * which is why it's not on by default. But, it's a good way of
42 * testing the functions in inode_io.c and fileio.c.
46 /* Checksumming functions */
47 static int ext2fs_journal_verify_csum_type(journal_t
*j
,
48 journal_superblock_t
*jsb
)
50 if (!jbd2_journal_has_csum_v2or3(j
))
53 return jsb
->s_checksum_type
== JBD2_CRC32C_CHKSUM
;
56 static __u32
ext2fs_journal_sb_csum(journal_superblock_t
*jsb
)
60 old_crc
= jsb
->s_checksum
;
62 crc
= ext2fs_crc32c_le(~0, (unsigned char *)jsb
,
63 sizeof(journal_superblock_t
));
64 jsb
->s_checksum
= old_crc
;
69 static int ext2fs_journal_sb_csum_verify(journal_t
*j
,
70 journal_superblock_t
*jsb
)
72 __u32 provided
, calculated
;
74 if (!jbd2_journal_has_csum_v2or3(j
))
77 provided
= ext2fs_be32_to_cpu(jsb
->s_checksum
);
78 calculated
= ext2fs_journal_sb_csum(jsb
);
80 return provided
== calculated
;
83 static errcode_t
ext2fs_journal_sb_csum_set(journal_t
*j
,
84 journal_superblock_t
*jsb
)
88 if (!jbd2_journal_has_csum_v2or3(j
))
91 crc
= ext2fs_journal_sb_csum(jsb
);
92 jsb
->s_checksum
= ext2fs_cpu_to_be32(crc
);
96 /* Kernel compatibility functions for handling the journal. These allow us
97 * to use the recovery.c file virtually unchanged from the kernel, so we
98 * don't have to do much to keep kernel and user recovery in sync.
100 int jbd2_journal_bmap(journal_t
*journal
, unsigned long block
,
101 unsigned long long *phys
)
107 struct inode
*inode
= journal
->j_inode
;
116 retval
= ext2fs_bmap2(inode
->i_fs
, inode
->i_ino
,
117 &inode
->i_ext2
, NULL
, 0, (blk64_t
) block
,
124 struct buffer_head
*getblk(kdev_t kdev
, unsigned long long blocknr
,
127 struct buffer_head
*bh
;
128 int bufsize
= sizeof(*bh
) + kdev
->k_fs
->blocksize
-
132 retval
= ext2fs_get_memzero(bufsize
, &bh
);
136 if (journal_enable_debug
>= 3)
138 jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
139 blocknr
, blocksize
, bh_count
);
141 bh
->b_fs
= kdev
->k_fs
;
142 if (kdev
->k_dev
== K_DEV_FS
)
143 bh
->b_io
= kdev
->k_fs
->io
;
145 bh
->b_io
= kdev
->k_fs
->journal_io
;
146 bh
->b_size
= blocksize
;
147 bh
->b_blocknr
= blocknr
;
152 int sync_blockdev(kdev_t kdev
)
156 if (kdev
->k_dev
== K_DEV_FS
)
159 io
= kdev
->k_fs
->journal_io
;
161 return io_channel_flush(io
) ? EIO
: 0;
164 void ll_rw_block(int rw
, int op_flags
EXT2FS_ATTR((unused
)), int nr
,
165 struct buffer_head
*bhp
[])
168 struct buffer_head
*bh
;
170 for (; nr
> 0; --nr
) {
172 if (rw
== REQ_OP_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
== REQ_OP_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
== REQ_OP_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(REQ_OP_WRITE
, 0, 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(REQ_OP_READ
, 0, 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
;
254 * If we replayed the journal by definition the file system
255 * was mounted since the last time it was checked
257 if (fs
->super
->s_lastcheck
>= fs
->super
->s_mtime
)
258 fs
->super
->s_lastcheck
= fs
->super
->s_mtime
- 1;
259 ext2fs_mark_super_dirty(fs
);
263 * This is a helper function to check the validity of the journal.
265 struct process_block_struct
{
266 e2_blkcnt_t last_block
;
269 static int process_journal_block(ext2_filsys fs
,
271 e2_blkcnt_t blockcnt
,
272 blk64_t ref_block
EXT2FS_ATTR((unused
)),
273 int ref_offset
EXT2FS_ATTR((unused
)),
276 struct process_block_struct
*p
;
277 blk64_t blk
= *block_nr
;
279 p
= (struct process_block_struct
*) priv_data
;
281 if (!blk
|| blk
< fs
->super
->s_first_data_block
||
282 blk
>= ext2fs_blocks_count(fs
->super
))
286 p
->last_block
= blockcnt
;
290 static errcode_t
ext2fs_get_journal(ext2_filsys fs
, journal_t
**ret_journal
)
292 struct process_block_struct pb
;
293 struct ext2_super_block
*sb
= fs
->super
;
294 struct ext2_super_block jsuper
;
295 struct buffer_head
*bh
;
296 struct inode
*j_inode
= NULL
;
297 struct kdev_s
*dev_fs
= NULL
, *dev_journal
;
298 const char *journal_name
= 0;
299 journal_t
*journal
= NULL
;
300 errcode_t retval
= 0;
301 io_manager io_ptr
= 0;
302 unsigned long long start
= 0;
304 int tried_backup_jnl
= 0;
306 retval
= ext2fs_get_memzero(sizeof(journal_t
), &journal
);
310 retval
= ext2fs_get_memzero(2 * sizeof(struct kdev_s
), &dev_fs
);
313 dev_journal
= dev_fs
+1;
315 dev_fs
->k_fs
= dev_journal
->k_fs
= fs
;
316 dev_fs
->k_dev
= K_DEV_FS
;
317 dev_journal
->k_dev
= K_DEV_JOURNAL
;
319 journal
->j_dev
= dev_journal
;
320 journal
->j_fs_dev
= dev_fs
;
321 journal
->j_inode
= NULL
;
322 journal
->j_blocksize
= fs
->blocksize
;
324 if (uuid_is_null(sb
->s_journal_uuid
)) {
325 if (!sb
->s_journal_inum
) {
326 retval
= EXT2_ET_BAD_INODE_NUM
;
329 retval
= ext2fs_get_memzero(sizeof(*j_inode
), &j_inode
);
334 j_inode
->i_ino
= sb
->s_journal_inum
;
336 retval
= ext2fs_read_inode(fs
, sb
->s_journal_inum
,
340 if (sb
->s_jnl_backup_type
!= EXT3_JNL_BACKUP_BLOCKS
||
343 memset(&j_inode
->i_ext2
, 0, sizeof(struct ext2_inode
));
344 memcpy(&j_inode
->i_ext2
.i_block
[0], sb
->s_jnl_blocks
,
346 j_inode
->i_ext2
.i_size_high
= sb
->s_jnl_blocks
[15];
347 j_inode
->i_ext2
.i_size
= sb
->s_jnl_blocks
[16];
348 j_inode
->i_ext2
.i_links_count
= 1;
349 j_inode
->i_ext2
.i_mode
= LINUX_S_IFREG
| 0600;
352 if (!j_inode
->i_ext2
.i_links_count
||
353 !LINUX_S_ISREG(j_inode
->i_ext2
.i_mode
)) {
354 retval
= EXT2_ET_NO_JOURNAL
;
355 goto try_backup_journal
;
357 if (EXT2_I_SIZE(&j_inode
->i_ext2
) / journal
->j_blocksize
<
358 JBD2_MIN_JOURNAL_BLOCKS
) {
359 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
360 goto try_backup_journal
;
363 retval
= ext2fs_block_iterate3(fs
, j_inode
->i_ino
,
365 process_journal_block
, &pb
);
366 if ((pb
.last_block
+ 1) * fs
->blocksize
<
367 (int) EXT2_I_SIZE(&j_inode
->i_ext2
)) {
368 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
369 goto try_backup_journal
;
371 if (tried_backup_jnl
&& (fs
->flags
& EXT2_FLAG_RW
)) {
372 retval
= ext2fs_write_inode(fs
, sb
->s_journal_inum
,
378 journal
->j_total_len
= EXT2_I_SIZE(&j_inode
->i_ext2
) /
379 journal
->j_blocksize
;
382 retval
= ext2fs_inode_io_intern2(fs
, sb
->s_journal_inum
,
388 io_ptr
= inode_io_manager
;
390 journal
->j_inode
= j_inode
;
391 fs
->journal_io
= fs
->io
;
392 retval
= (errcode_t
) jbd2_journal_bmap(journal
, 0, &start
);
398 if (!fs
->journal_name
) {
402 blkid_get_cache(&blkid
, NULL
);
403 uuid_unparse(sb
->s_journal_uuid
, uuid
);
404 fs
->journal_name
= blkid_get_devname(blkid
,
406 if (!fs
->journal_name
)
407 fs
->journal_name
= blkid_devno_to_devname(sb
->s_journal_dev
);
408 blkid_put_cache(blkid
);
410 journal_name
= fs
->journal_name
;
413 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
417 jfs_debug(1, "Using journal file %s\n", journal_name
);
418 io_ptr
= unix_io_manager
;
422 test_io_backing_manager
= io_ptr
;
423 io_ptr
= test_io_manager
;
429 retval
= io_ptr
->open(journal_name
, fs
->flags
& EXT2_FLAG_RW
,
435 io_channel_set_blksize(fs
->journal_io
, fs
->blocksize
);
440 start
= ext2fs_journal_sb_start(fs
->blocksize
) - 1;
441 bh
= getblk(dev_journal
, start
, fs
->blocksize
);
443 retval
= EXT2_ET_NO_MEMORY
;
446 ll_rw_block(REQ_OP_READ
, 0, 1, &bh
);
452 memcpy(&jsuper
, start
? bh
->b_data
:
453 bh
->b_data
+ SUPERBLOCK_OFFSET
,
455 #ifdef WORDS_BIGENDIAN
456 if (jsuper
.s_magic
== ext2fs_swab16(EXT2_SUPER_MAGIC
))
457 ext2fs_swap_super(&jsuper
);
459 if (jsuper
.s_magic
!= EXT2_SUPER_MAGIC
||
460 !ext2fs_has_feature_journal_dev(&jsuper
)) {
461 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
465 /* Make sure the journal UUID is correct */
466 if (memcmp(jsuper
.s_uuid
, fs
->super
->s_journal_uuid
,
467 sizeof(jsuper
.s_uuid
))) {
468 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
473 /* Check the superblock checksum */
474 if (ext2fs_has_feature_metadata_csum(&jsuper
)) {
475 struct struct_ext2_filsys fsx
;
476 struct ext2_super_block superx
;
479 p
= start
? bh
->b_data
: bh
->b_data
+ SUPERBLOCK_OFFSET
;
480 memcpy(&fsx
, fs
, sizeof(fsx
));
481 memcpy(&superx
, fs
->super
, sizeof(superx
));
483 ext2fs_set_feature_metadata_csum(fsx
.super
);
484 if (!ext2fs_superblock_csum_verify(&fsx
, p
)) {
485 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
492 maxlen
= ext2fs_blocks_count(&jsuper
);
493 journal
->j_total_len
= (maxlen
< 1ULL << 32) ? maxlen
:
498 bh
= getblk(dev_journal
, start
, journal
->j_blocksize
);
500 retval
= EXT2_ET_NO_MEMORY
;
504 journal
->j_sb_buffer
= bh
;
505 journal
->j_superblock
= (journal_superblock_t
*)bh
->b_data
;
509 ext2fs_free_mem(&j_inode
);
512 *ret_journal
= journal
;
517 ext2fs_free_mem(&dev_fs
);
519 ext2fs_free_mem(&j_inode
);
521 ext2fs_free_mem(&journal
);
525 static errcode_t
ext2fs_journal_fix_bad_inode(ext2_filsys fs
)
527 struct ext2_super_block
*sb
= fs
->super
;
528 int recover
= ext2fs_has_feature_journal_needs_recovery(fs
->super
);
529 int has_journal
= ext2fs_has_feature_journal(fs
->super
);
531 if (has_journal
|| sb
->s_journal_inum
) {
532 /* The journal inode is bogus, remove and force full fsck */
533 return EXT2_ET_BAD_INODE_NUM
;
534 } else if (recover
) {
535 return EXT2_ET_UNSUPP_FEATURE
;
540 #define V1_SB_SIZE 0x0024
541 static void clear_v2_journal_fields(journal_t
*journal
)
543 ext2_filsys fs
= journal
->j_dev
->k_fs
;
545 memset(((char *) journal
->j_superblock
) + V1_SB_SIZE
, 0,
546 fs
->blocksize
-V1_SB_SIZE
);
547 mark_buffer_dirty(journal
->j_sb_buffer
);
551 static errcode_t
ext2fs_journal_load(journal_t
*journal
)
553 ext2_filsys fs
= journal
->j_dev
->k_fs
;
554 journal_superblock_t
*jsb
;
555 struct buffer_head
*jbh
= journal
->j_sb_buffer
;
557 ll_rw_block(REQ_OP_READ
, 0, 1, &jbh
);
561 jsb
= journal
->j_superblock
;
562 /* If we don't even have JBD2_MAGIC, we probably have a wrong inode */
563 if (jsb
->s_header
.h_magic
!= htonl(JBD2_MAGIC_NUMBER
))
564 return ext2fs_journal_fix_bad_inode(fs
);
566 switch (ntohl(jsb
->s_header
.h_blocktype
)) {
567 case JBD2_SUPERBLOCK_V1
:
568 journal
->j_format_version
= 1;
569 if (jsb
->s_feature_compat
||
570 jsb
->s_feature_incompat
||
571 jsb
->s_feature_ro_compat
||
573 clear_v2_journal_fields(journal
);
576 case JBD2_SUPERBLOCK_V2
:
577 journal
->j_format_version
= 2;
578 if (ntohl(jsb
->s_nr_users
) > 1 &&
579 uuid_is_null(fs
->super
->s_journal_uuid
))
580 clear_v2_journal_fields(journal
);
581 if (ntohl(jsb
->s_nr_users
) > 1)
582 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
586 * These should never appear in a journal super block, so if
587 * they do, the journal is badly corrupted.
589 case JBD2_DESCRIPTOR_BLOCK
:
590 case JBD2_COMMIT_BLOCK
:
591 case JBD2_REVOKE_BLOCK
:
592 return EXT2_ET_CORRUPT_JOURNAL_SB
;
594 /* If we don't understand the superblock major type, but there
595 * is a magic number, then it is likely to be a new format we
596 * just don't understand, so leave it alone. */
598 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
601 if (JBD2_HAS_INCOMPAT_FEATURE(journal
, ~JBD2_KNOWN_INCOMPAT_FEATURES
))
602 return EXT2_ET_UNSUPP_FEATURE
;
604 if (JBD2_HAS_RO_COMPAT_FEATURE(journal
, ~JBD2_KNOWN_ROCOMPAT_FEATURES
))
605 return EXT2_ET_RO_UNSUPP_FEATURE
;
607 /* Checksum v1-3 are mutually exclusive features. */
608 if (jbd2_has_feature_csum2(journal
) && jbd2_has_feature_csum3(journal
))
609 return EXT2_ET_CORRUPT_JOURNAL_SB
;
611 if (jbd2_journal_has_csum_v2or3(journal
) &&
612 jbd2_has_feature_checksum(journal
))
613 return EXT2_ET_CORRUPT_JOURNAL_SB
;
615 if (!ext2fs_journal_verify_csum_type(journal
, jsb
) ||
616 !ext2fs_journal_sb_csum_verify(journal
, jsb
))
617 return EXT2_ET_CORRUPT_JOURNAL_SB
;
619 if (jbd2_journal_has_csum_v2or3(journal
))
620 journal
->j_csum_seed
= jbd2_chksum(journal
, ~0, jsb
->s_uuid
,
621 sizeof(jsb
->s_uuid
));
623 /* We have now checked whether we know enough about the journal
624 * format to be able to proceed safely, so any other checks that
625 * fail we should attempt to recover from. */
626 if (jsb
->s_blocksize
!= htonl(journal
->j_blocksize
))
627 return EXT2_ET_CORRUPT_JOURNAL_SB
;
629 if (ntohl(jsb
->s_maxlen
) < journal
->j_total_len
)
630 journal
->j_total_len
= ntohl(jsb
->s_maxlen
);
631 else if (ntohl(jsb
->s_maxlen
) > journal
->j_total_len
)
632 return EXT2_ET_CORRUPT_JOURNAL_SB
;
634 journal
->j_tail_sequence
= ntohl(jsb
->s_sequence
);
635 journal
->j_transaction_sequence
= journal
->j_tail_sequence
;
636 journal
->j_tail
= ntohl(jsb
->s_start
);
637 journal
->j_first
= ntohl(jsb
->s_first
);
638 journal
->j_last
= ntohl(jsb
->s_maxlen
);
643 static void ext2fs_journal_release(ext2_filsys fs
, journal_t
*journal
,
646 journal_superblock_t
*jsb
;
649 mark_buffer_clean(journal
->j_sb_buffer
);
650 else if (fs
->flags
& EXT2_FLAG_RW
) {
651 jsb
= journal
->j_superblock
;
652 jsb
->s_sequence
= htonl(journal
->j_tail_sequence
);
654 jsb
->s_start
= 0; /* this marks the journal as empty */
655 ext2fs_journal_sb_csum_set(journal
, jsb
);
656 mark_buffer_dirty(journal
->j_sb_buffer
);
658 brelse(journal
->j_sb_buffer
);
660 if (fs
&& fs
->journal_io
) {
661 if (fs
->io
!= fs
->journal_io
)
662 io_channel_close(fs
->journal_io
);
663 fs
->journal_io
= NULL
;
664 free(fs
->journal_name
);
665 fs
->journal_name
= NULL
;
669 if (journal
->j_inode
)
670 ext2fs_free_mem(&journal
->j_inode
);
672 if (journal
->j_fs_dev
)
673 ext2fs_free_mem(&journal
->j_fs_dev
);
674 ext2fs_free_mem(&journal
);
678 * This function makes sure that the superblock fields regarding the
679 * journal are consistent.
681 static errcode_t
ext2fs_check_ext3_journal(ext2_filsys fs
)
683 struct ext2_super_block
*sb
= fs
->super
;
685 int recover
= ext2fs_has_feature_journal_needs_recovery(fs
->super
);
688 /* If we don't have any journal features, don't do anything more */
689 if (!ext2fs_has_feature_journal(sb
) &&
690 !recover
&& sb
->s_journal_inum
== 0 && sb
->s_journal_dev
== 0 &&
691 uuid_is_null(sb
->s_journal_uuid
))
694 retval
= ext2fs_get_journal(fs
, &journal
);
698 retval
= ext2fs_journal_load(journal
);
703 * We want to make the flags consistent here. We will not leave with
704 * needs_recovery set but has_journal clear. We can't get in a loop
705 * with -y, -n, or -p, only if a user isn't making up their mind.
707 if (!ext2fs_has_feature_journal(sb
)) {
708 retval
= EXT2_ET_JOURNAL_FLAGS_WRONG
;
712 if (ext2fs_has_feature_journal(sb
) &&
713 !ext2fs_has_feature_journal_needs_recovery(sb
) &&
714 journal
->j_superblock
->s_start
!= 0) {
715 retval
= EXT2_ET_JOURNAL_FLAGS_WRONG
;
720 * If we don't need to do replay the journal, check to see if
721 * the journal's errno is set; if so, we need to mark the file
722 * system as being corrupt and clear the journal's s_errno.
724 if (!ext2fs_has_feature_journal_needs_recovery(sb
) &&
725 journal
->j_superblock
->s_errno
) {
726 fs
->super
->s_state
|= EXT2_ERROR_FS
;
727 ext2fs_mark_super_dirty(fs
);
728 journal
->j_superblock
->s_errno
= 0;
729 ext2fs_journal_sb_csum_set(journal
, journal
->j_superblock
);
730 mark_buffer_dirty(journal
->j_sb_buffer
);
734 ext2fs_journal_release(fs
, journal
, 0, retval
? 1 : 0);
738 static errcode_t
recover_ext3_journal(ext2_filsys fs
)
743 retval
= jbd2_journal_init_revoke_record_cache();
747 retval
= jbd2_journal_init_revoke_table_cache();
751 retval
= ext2fs_get_journal(fs
, &journal
);
755 retval
= ext2fs_journal_load(journal
);
759 retval
= jbd2_journal_init_revoke(journal
, 1024);
763 retval
= -jbd2_journal_recover(journal
);
767 if (journal
->j_failed_commit
) {
768 journal
->j_superblock
->s_errno
= -EINVAL
;
769 mark_buffer_dirty(journal
->j_sb_buffer
);
772 journal
->j_tail_sequence
= journal
->j_transaction_sequence
;
775 jbd2_journal_destroy_revoke(journal
);
776 jbd2_journal_destroy_revoke_record_cache();
777 jbd2_journal_destroy_revoke_table_cache();
778 ext2fs_journal_release(fs
, journal
, 1, 0);
782 errcode_t
ext2fs_run_ext3_journal(ext2_filsys
*fsp
)
784 ext2_filsys fs
= *fsp
;
785 io_manager io_ptr
= fs
->io
->manager
;
786 errcode_t retval
, recover_retval
;
788 unsigned long long kbytes_written
= 0;
793 if (!(fs
->flags
& EXT2_FLAG_RW
))
794 return EXT2_ET_FILE_RO
;
796 if (fs
->flags
& EXT2_FLAG_DIRTY
)
797 ext2fs_flush(fs
); /* Force out any modifications */
799 recover_retval
= recover_ext3_journal(fs
);
802 * Reload the filesystem context to get up-to-date data from disk
803 * because journal recovery will change the filesystem under us.
805 if (fs
->super
->s_kbytes_written
&&
806 fs
->io
->manager
->get_stats
)
807 fs
->io
->manager
->get_stats(fs
->io
, &stats
);
808 if (stats
&& stats
->bytes_written
)
809 kbytes_written
= stats
->bytes_written
>> 10;
812 fsname
= fs
->device_name
;
813 fs
->device_name
= NULL
;
815 fsblocksize
= fs
->blocksize
;
818 retval
= ext2fs_open(fsname
, fsflags
, 0, fsblocksize
, io_ptr
, fsp
);
819 ext2fs_free_mem(&fsname
);
824 fs
->flags
|= EXT2_FLAG_MASTER_SB_ONLY
;
825 fs
->super
->s_kbytes_written
+= kbytes_written
;
827 /* Set the superblock flags */
828 ext2fs_clear_recover(fs
, recover_retval
!= 0);
831 * Do one last sanity check, and propagate journal->s_errno to
832 * the EXT2_ERROR_FS flag in the fs superblock if needed.
834 retval
= ext2fs_check_ext3_journal(fs
);
835 return retval
? retval
: recover_retval
;
838 errcode_t
ext2fs_open_journal(ext2_filsys fs
, journal_t
**j
)
843 retval
= jbd2_journal_init_revoke_record_cache();
847 retval
= jbd2_journal_init_revoke_table_cache();
851 retval
= ext2fs_get_journal(fs
, &journal
);
855 retval
= ext2fs_journal_load(journal
);
859 retval
= jbd2_journal_init_revoke(journal
, 1024);
863 if (journal
->j_failed_commit
) {
864 journal
->j_superblock
->s_errno
= -EINVAL
;
865 mark_buffer_dirty(journal
->j_sb_buffer
);
872 jbd2_journal_destroy_revoke(journal
);
873 jbd2_journal_destroy_revoke_record_cache();
874 jbd2_journal_destroy_revoke_table_cache();
875 ext2fs_journal_release(fs
, journal
, 1, 0);
879 errcode_t
ext2fs_close_journal(ext2_filsys fs
, journal_t
**j
)
881 journal_t
*journal
= *j
;
883 jbd2_journal_destroy_revoke(journal
);
884 jbd2_journal_destroy_revoke_record_cache();
885 jbd2_journal_destroy_revoke_table_cache();
886 ext2fs_journal_release(fs
, journal
, 0, 0);
892 void jbd2_commit_block_csum_set(journal_t
*j
, struct buffer_head
*bh
)
894 struct commit_header
*h
;
897 if (!jbd2_journal_has_csum_v2or3(j
))
900 h
= (struct commit_header
*)(bh
->b_data
);
901 h
->h_chksum_type
= 0;
902 h
->h_chksum_size
= 0;
904 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
905 h
->h_chksum
[0] = ext2fs_cpu_to_be32(csum
);
908 void jbd2_revoke_csum_set(journal_t
*j
, struct buffer_head
*bh
)
910 jbd2_descr_block_csum_set(j
, bh
);
913 void jbd2_descr_block_csum_set(journal_t
*j
, struct buffer_head
*bh
)
915 struct jbd2_journal_block_tail
*tail
;
918 if (!jbd2_journal_has_csum_v2or3(j
))
921 tail
= (struct jbd2_journal_block_tail
*)(bh
->b_data
+ j
->j_blocksize
-
922 sizeof(struct jbd2_journal_block_tail
));
923 tail
->t_checksum
= 0;
924 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
925 tail
->t_checksum
= ext2fs_cpu_to_be32(csum
);
928 void jbd2_block_tag_csum_set(journal_t
*j
, journal_block_tag_t
*tag
,
929 struct buffer_head
*bh
, __u32 sequence
)
931 journal_block_tag3_t
*tag3
= (journal_block_tag3_t
*)tag
;
935 if (!jbd2_journal_has_csum_v2or3(j
))
938 seq
= ext2fs_cpu_to_be32(sequence
);
939 csum32
= jbd2_chksum(j
, j
->j_csum_seed
, (__u8
*)&seq
, sizeof(seq
));
940 csum32
= jbd2_chksum(j
, csum32
, bh
->b_data
, bh
->b_size
);
942 if (jbd2_has_feature_csum3(j
))
943 tag3
->t_checksum
= ext2fs_cpu_to_be32(csum32
);
945 tag
->t_checksum
= ext2fs_cpu_to_be16(csum32
);