Whamcloud - gitweb
Merge branch 'maint' into next
authorTheodore Ts'o <tytso@mit.edu>
Tue, 29 Jul 2014 14:53:49 +0000 (10:53 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 29 Jul 2014 14:53:49 +0000 (10:53 -0400)
1  2 
e2fsck/journal.c
lib/ext2fs/ext2fs.h
lib/ext2fs/kernel-jbd.h
misc/tune2fs.c

Simple merge
Simple merge
@@@ -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
@@@ -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.
                                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 "