From: Theodore Ts'o Date: Tue, 29 Jul 2014 14:53:49 +0000 (-0400) Subject: Merge branch 'maint' into next X-Git-Tag: v1.43-WIP-2015-05-18~268^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=643fd7e7aac21f02e61f0fcbe58b4433d67c862c;p=thirdparty%2Fe2fsprogs.git Merge branch 'maint' into next --- 643fd7e7aac21f02e61f0fcbe58b4433d67c862c diff --cc lib/ext2fs/kernel-jbd.h index 130c3a2ba,2baae7355..a9cdc3054 --- a/lib/ext2fs/kernel-jbd.h +++ b/lib/ext2fs/kernel-jbd.h @@@ -227,13 -208,11 +230,14 @@@ typedef struct journal_superblock_ __u32 s_max_trans_data; /* Limit of data blocks per trans. */ /* 0x0050 */ - __u32 s_padding[44]; + __u8 s_checksum_type; /* checksum type */ + __u8 s_padding2[3]; + __u32 s_padding[42]; + __u32 s_checksum; /* crc32c(superblock) */ /* 0x0100 */ - __u8 s_users[16*48]; /* ids of all fs'es sharing the log */ + __u8 s_users[JFS_USERS_SIZE]; /* ids of all fs'es sharing the log */ + /* 0x0400 */ } journal_superblock_t; diff --cc misc/tune2fs.c index 601a6c85e,0c1feb1ee..5aaea5eac --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@@ -177,9 -172,53 +177,53 @@@ static __u32 clear_ok_features[3] = #ifdef CONFIG_QUOTA EXT4_FEATURE_RO_COMPAT_QUOTA | #endif - EXT4_FEATURE_RO_COMPAT_GDT_CSUM + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM }; + /** + * Try to get journal super block if any + */ + static int get_journal_sb(ext2_filsys jfs, char buf[SUPERBLOCK_SIZE]) + { + int retval; + int start; + journal_superblock_t *jsb; + + if (!(jfs->super->s_feature_incompat & + EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { + return EXT2_ET_UNSUPP_FEATURE; + } + + /* Get the journal superblock */ + if ((retval = io_channel_read_blk64(jfs->io, + ext2fs_journal_sb_start(jfs->blocksize), -SUPERBLOCK_SIZE, buf))) { + com_err(program_name, retval, "%s", + _("while reading journal superblock")); + return retval; + } + + jsb = (journal_superblock_t *) buf; + if ((jsb->s_header.h_magic != (unsigned)ntohl(JFS_MAGIC_NUMBER)) || + (jsb->s_header.h_blocktype != (unsigned)ntohl(JFS_SUPERBLOCK_V2))) { + fputs(_("Journal superblock not found!\n"), stderr); + return EXT2_ET_BAD_MAGIC; + } + + return 0; + } + + static void * + journal_user(char uuid[UUID_SIZE], char s_users[JFS_USERS_SIZE], int nr_users) + { + int i; + for (i = 0; i < nr_users; i++) { + if (memcmp(uuid, &s_users[i * UUID_SIZE], UUID_SIZE) == 0) + return &s_users[i * UUID_SIZE]; + } + + return NULL; + } + /* * Remove an external journal from the filesystem */ @@@ -2691,8 -2273,11 +2784,10 @@@ retry_open if (U_flag) { int set_csum = 0; dgrp_t i; + char buf[SUPERBLOCK_SIZE]; + char old_uuid[UUID_SIZE]; - if (sb->s_feature_ro_compat & - EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { + if (ext2fs_has_group_desc_csum(fs)) { /* * Changing the UUID requires rewriting all metadata, * which can race with a mounted fs. Don't allow that. @@@ -2736,13 -2322,31 +2833,36 @@@ ext2fs_group_desc_csum_set(fs, i); fs->flags &= ~EXT2_FLAG_SUPER_ONLY; } + + /* If this is a journal dev, we need to copy UUID into jsb */ + if (!(rc = get_journal_sb(fs, buf))) { + journal_superblock_t *jsb; + + jsb = (journal_superblock_t *) buf; + fputs(_("Need to update journal superblock.\n"), stdout); + memcpy(jsb->s_uuid, sb->s_uuid, sizeof(sb->s_uuid)); + + /* Writeback the journal superblock */ + if ((rc = io_channel_write_blk64(fs->io, + ext2fs_journal_sb_start(fs->blocksize), + -SUPERBLOCK_SIZE, buf))) + goto closefs; + } else if (rc != EXT2_ET_UNSUPP_FEATURE) + goto closefs; + else { + rc = 0; /** Reset rc to avoid ext2fs_mmp_stop() */ + + if ((rc = fs_update_journal_user(sb, old_uuid))) + goto closefs; + } + ext2fs_mark_super_dirty(fs); + if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) + rewrite_checksums = 1; } + if (rewrite_checksums) + rewrite_metadata_checksums(fs); if (I_flag) { if (mount_flags & EXT2_MF_MOUNTED) { fputs(_("The inode size may only be "