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
;
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 JFS_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_maxlen
= 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
)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(READ
, 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_maxlen
= (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(READ
, 1, &jbh
);
561 jsb
= journal
->j_superblock
;
562 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
563 if (jsb
->s_header
.h_magic
!= htonl(JFS_MAGIC_NUMBER
))
564 return ext2fs_journal_fix_bad_inode(fs
);
566 switch (ntohl(jsb
->s_header
.h_blocktype
)) {
567 case JFS_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 JFS_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 JFS_DESCRIPTOR_BLOCK
:
590 case JFS_COMMIT_BLOCK
:
591 case JFS_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 (JFS_HAS_INCOMPAT_FEATURE(journal
, ~JFS_KNOWN_INCOMPAT_FEATURES
))
602 return EXT2_ET_UNSUPP_FEATURE
;
604 if (JFS_HAS_RO_COMPAT_FEATURE(journal
, ~JFS_KNOWN_ROCOMPAT_FEATURES
))
605 return EXT2_ET_RO_UNSUPP_FEATURE
;
607 /* Checksum v1-3 are mutually exclusive features. */
608 if (jfs_has_feature_csum2(journal
) && jfs_has_feature_csum3(journal
))
609 return EXT2_ET_CORRUPT_JOURNAL_SB
;
611 if (journal_has_csum_v2or3(journal
) &&
612 jfs_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 (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_maxlen
)
630 journal
->j_maxlen
= ntohl(jsb
->s_maxlen
);
631 else if (ntohl(jsb
->s_maxlen
) > journal
->j_maxlen
)
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 journal_init_revoke_caches();
744 retval
= ext2fs_get_journal(fs
, &journal
);
748 retval
= ext2fs_journal_load(journal
);
752 retval
= journal_init_revoke(journal
, 1024);
756 retval
= -journal_recover(journal
);
760 if (journal
->j_failed_commit
) {
761 journal
->j_superblock
->s_errno
= -EINVAL
;
762 mark_buffer_dirty(journal
->j_sb_buffer
);
766 journal_destroy_revoke(journal
);
767 journal_destroy_revoke_caches();
768 ext2fs_journal_release(fs
, journal
, 1, 0);
772 errcode_t
ext2fs_run_ext3_journal(ext2_filsys
*fsp
)
774 ext2_filsys fs
= *fsp
;
775 io_manager io_ptr
= fs
->io
->manager
;
776 errcode_t retval
, recover_retval
;
778 unsigned long long kbytes_written
= 0;
783 if (!(fs
->flags
& EXT2_FLAG_RW
))
784 return EXT2_ET_FILE_RO
;
786 if (fs
->flags
& EXT2_FLAG_DIRTY
)
787 ext2fs_flush(fs
); /* Force out any modifications */
789 recover_retval
= recover_ext3_journal(fs
);
792 * Reload the filesystem context to get up-to-date data from disk
793 * because journal recovery will change the filesystem under us.
795 if (fs
->super
->s_kbytes_written
&&
796 fs
->io
->manager
->get_stats
)
797 fs
->io
->manager
->get_stats(fs
->io
, &stats
);
798 if (stats
&& stats
->bytes_written
)
799 kbytes_written
= stats
->bytes_written
>> 10;
802 fsname
= fs
->device_name
;
803 fs
->device_name
= NULL
;
805 fsblocksize
= fs
->blocksize
;
808 retval
= ext2fs_open(fsname
, fsflags
, 0, fsblocksize
, io_ptr
, fsp
);
809 ext2fs_free_mem(&fsname
);
814 fs
->flags
|= EXT2_FLAG_MASTER_SB_ONLY
;
815 fs
->super
->s_kbytes_written
+= kbytes_written
;
817 /* Set the superblock flags */
818 ext2fs_clear_recover(fs
, recover_retval
!= 0);
821 * Do one last sanity check, and propagate journal->s_errno to
822 * the EXT2_ERROR_FS flag in the fs superblock if needed.
824 retval
= ext2fs_check_ext3_journal(fs
);
825 return retval
? retval
: recover_retval
;
828 errcode_t
ext2fs_open_journal(ext2_filsys fs
, journal_t
**j
)
833 journal_init_revoke_caches();
834 retval
= ext2fs_get_journal(fs
, &journal
);
838 retval
= ext2fs_journal_load(journal
);
842 retval
= journal_init_revoke(journal
, 1024);
846 if (journal
->j_failed_commit
) {
847 journal
->j_superblock
->s_errno
= -EINVAL
;
848 mark_buffer_dirty(journal
->j_sb_buffer
);
855 journal_destroy_revoke(journal
);
856 journal_destroy_revoke_caches();
857 ext2fs_journal_release(fs
, journal
, 1, 0);
861 errcode_t
ext2fs_close_journal(ext2_filsys fs
, journal_t
**j
)
863 journal_t
*journal
= *j
;
865 journal_destroy_revoke(journal
);
866 journal_destroy_revoke_caches();
867 ext2fs_journal_release(fs
, journal
, 0, 0);
873 void jbd2_commit_block_csum_set(journal_t
*j
, struct buffer_head
*bh
)
875 struct commit_header
*h
;
878 if (!journal_has_csum_v2or3(j
))
881 h
= (struct commit_header
*)(bh
->b_data
);
882 h
->h_chksum_type
= 0;
883 h
->h_chksum_size
= 0;
885 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
886 h
->h_chksum
[0] = ext2fs_cpu_to_be32(csum
);
889 void jbd2_revoke_csum_set(journal_t
*j
, struct buffer_head
*bh
)
891 struct journal_revoke_tail
*tail
;
894 if (!journal_has_csum_v2or3(j
))
897 tail
= (struct journal_revoke_tail
*)(bh
->b_data
+ j
->j_blocksize
-
898 sizeof(struct journal_revoke_tail
));
899 tail
->r_checksum
= 0;
900 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
901 tail
->r_checksum
= ext2fs_cpu_to_be32(csum
);
904 void jbd2_descr_block_csum_set(journal_t
*j
, struct buffer_head
*bh
)
906 struct journal_block_tail
*tail
;
909 if (!journal_has_csum_v2or3(j
))
912 tail
= (struct journal_block_tail
*)(bh
->b_data
+ j
->j_blocksize
-
913 sizeof(struct journal_block_tail
));
914 tail
->t_checksum
= 0;
915 csum
= jbd2_chksum(j
, j
->j_csum_seed
, bh
->b_data
, j
->j_blocksize
);
916 tail
->t_checksum
= ext2fs_cpu_to_be32(csum
);
919 void jbd2_block_tag_csum_set(journal_t
*j
, journal_block_tag_t
*tag
,
920 struct buffer_head
*bh
, __u32 sequence
)
922 journal_block_tag3_t
*tag3
= (journal_block_tag3_t
*)tag
;
926 if (!journal_has_csum_v2or3(j
))
929 seq
= ext2fs_cpu_to_be32(sequence
);
930 csum32
= jbd2_chksum(j
, j
->j_csum_seed
, (__u8
*)&seq
, sizeof(seq
));
931 csum32
= jbd2_chksum(j
, csum32
, bh
->b_data
, bh
->b_size
);
933 if (jfs_has_feature_csum3(j
))
934 tag3
->t_checksum
= ext2fs_cpu_to_be32(csum32
);
936 tag
->t_checksum
= ext2fs_cpu_to_be16(csum32
);