From ea8b0bd66f82ee88fb7472b392db46c2c6c1e072 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 31 May 2012 14:15:24 -0500 Subject: > 16T fixes from upstream --- e2fsprogs-1.42.2-64-bit-fixes.patch | 320 ++++++++++++++++++++++++++++++++++++ e2fsprogs.spec | 9 +- 2 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 e2fsprogs-1.42.2-64-bit-fixes.patch diff --git a/e2fsprogs-1.42.2-64-bit-fixes.patch b/e2fsprogs-1.42.2-64-bit-fixes.patch new file mode 100644 index 0000000..bc6c33c --- /dev/null +++ b/e2fsprogs-1.42.2-64-bit-fixes.patch @@ -0,0 +1,320 @@ +commit 8c778b3acd885c79d76d94b4ba0b7fad7b031607 +Author: Theodore Ts'o +Date: Mon May 21 10:59:01 2012 -0400 + + libe2p: teach e2p_jrnl_feature2string() about the 64-bit journal feature + + This will allow dumpe2fs to correctly display the 64-bit journal + feature, if it is enabled. + + Signed-off-by: "Theodore Ts'o" + +diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c +index db85365..9691263 100644 +--- a/lib/e2p/feature.c ++++ b/lib/e2p/feature.c +@@ -104,6 +104,8 @@ static struct feature jrnl_feature_list[] = { + + { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_REVOKE, + "journal_incompat_revoke" }, ++ { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_64BIT, ++ "journal_64bit" }, + { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_ASYNC_COMMIT, + "journal_async_commit" }, + { 0, 0, 0 }, + +commit 3b693d0b03569795d04920a04a0a21e5f64ffedc +Author: Theodore Ts'o +Date: Mon May 21 21:30:45 2012 -0400 + + e2fsck: fix 64-bit journal support + + 64-bit journal support was broken; we weren't using the high bits from + the journal descriptor blocks! We were also using "unsigned long" for + the journal block numbers, which would be a problem on 32-bit systems. + + Signed-off-by: "Theodore Ts'o" + +diff --git a/e2fsck/jfs_user.h b/e2fsck/jfs_user.h +index 9e33306..92f8ae2 100644 +--- a/e2fsck/jfs_user.h ++++ b/e2fsck/jfs_user.h +@@ -18,7 +18,7 @@ struct buffer_head { + e2fsck_t b_ctx; + io_channel b_io; + int b_size; +- blk_t b_blocknr; ++ unsigned long long b_blocknr; + int b_dirty; + int b_uptodate; + int b_err; +@@ -121,7 +121,7 @@ _INLINE_ size_t journal_tag_bytes(journal_t *journal) + /* + * Kernel compatibility functions are defined in journal.c + */ +-int journal_bmap(journal_t *journal, blk64_t block, unsigned long *phys); ++int journal_bmap(journal_t *journal, blk64_t block, unsigned long long *phys); + struct buffer_head *getblk(kdev_t ctx, blk64_t blocknr, int blocksize); + void sync_blockdev(kdev_t kdev); + void ll_rw_block(int rw, int dummy, struct buffer_head *bh[]); +diff --git a/e2fsck/journal.c b/e2fsck/journal.c +index 915b8bb..bada028 100644 +--- a/e2fsck/journal.c ++++ b/e2fsck/journal.c +@@ -44,7 +44,7 @@ static int bh_count = 0; + * to use the recovery.c file virtually unchanged from the kernel, so we + * don't have to do much to keep kernel and user recovery in sync. + */ +-int journal_bmap(journal_t *journal, blk64_t block, unsigned long *phys) ++int journal_bmap(journal_t *journal, blk64_t block, unsigned long long *phys) + { + #ifdef USE_INODE_IO + *phys = block; +@@ -80,8 +80,8 @@ struct buffer_head *getblk(kdev_t kdev, blk64_t blocknr, int blocksize) + if (journal_enable_debug >= 3) + bh_count++; + #endif +- jfs_debug(4, "getblk for block %lu (%d bytes)(total %d)\n", +- (unsigned long) blocknr, blocksize, bh_count); ++ jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n", ++ (unsigned long long) blocknr, blocksize, bh_count); + + bh->b_ctx = kdev->k_ctx; + if (kdev->k_dev == K_DEV_FS) +@@ -114,38 +114,39 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) + for (; nr > 0; --nr) { + bh = *bhp++; + if (rw == READ && !bh->b_uptodate) { +- jfs_debug(3, "reading block %lu/%p\n", +- (unsigned long) bh->b_blocknr, (void *) bh); ++ jfs_debug(3, "reading block %llu/%p\n", ++ bh->b_blocknr, (void *) bh); + retval = io_channel_read_blk64(bh->b_io, + bh->b_blocknr, + 1, bh->b_data); + if (retval) { + com_err(bh->b_ctx->device_name, retval, +- "while reading block %lu\n", +- (unsigned long) bh->b_blocknr); ++ "while reading block %llu\n", ++ bh->b_blocknr); + bh->b_err = retval; + continue; + } + bh->b_uptodate = 1; + } else if (rw == WRITE && bh->b_dirty) { +- jfs_debug(3, "writing block %lu/%p\n", +- (unsigned long) bh->b_blocknr, (void *) bh); ++ jfs_debug(3, "writing block %llu/%p\n", ++ bh->b_blocknr, ++ (void *) bh); + retval = io_channel_write_blk64(bh->b_io, + bh->b_blocknr, + 1, bh->b_data); + if (retval) { + com_err(bh->b_ctx->device_name, retval, +- "while writing block %lu\n", +- (unsigned long) bh->b_blocknr); ++ "while writing block %llu\n", ++ bh->b_blocknr); + bh->b_err = retval; + continue; + } + bh->b_dirty = 0; + bh->b_uptodate = 1; + } else { +- jfs_debug(3, "no-op %s for block %lu\n", ++ jfs_debug(3, "no-op %s for block %llu\n", + rw == READ ? "read" : "write", +- (unsigned long) bh->b_blocknr); ++ bh->b_blocknr); + } + } + } +@@ -164,8 +165,8 @@ void brelse(struct buffer_head *bh) + { + if (bh->b_dirty) + ll_rw_block(WRITE, 1, &bh); +- jfs_debug(3, "freeing block %lu/%p (total %d)\n", +- (unsigned long) bh->b_blocknr, (void *) bh, --bh_count); ++ jfs_debug(3, "freeing block %llu/%p (total %d)\n", ++ bh->b_blocknr, (void *) bh, --bh_count); + ext2fs_free_mem(&bh); + } + +@@ -237,7 +238,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal) + journal_t *journal = NULL; + errcode_t retval = 0; + io_manager io_ptr = 0; +- unsigned long start = 0; ++ unsigned long long start = 0; + int ext_journal = 0; + int tried_backup_jnl = 0; + +diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c +index b669941..e94ef4e 100644 +--- a/e2fsck/recovery.c ++++ b/e2fsck/recovery.c +@@ -71,7 +71,7 @@ static int do_readahead(journal_t *journal, unsigned int start) + { + int err; + unsigned int max, nbufs, next; +- unsigned long blocknr; ++ unsigned long long blocknr; + struct buffer_head *bh; + + struct buffer_head * bufs[MAXBUF]; +@@ -133,7 +133,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal, + unsigned int offset) + { + int err; +- unsigned long blocknr; ++ unsigned long long blocknr; + struct buffer_head *bh; + + *bhp = NULL; +@@ -309,7 +309,6 @@ int journal_skip_recovery(journal_t *journal) + return err; + } + +-#if 0 + static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag) + { + unsigned long long block = be32_to_cpu(tag->t_blocknr); +@@ -317,17 +316,16 @@ static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag + block |= (__u64)be32_to_cpu(tag->t_blocknr_high) << 32; + return block; + } +-#endif + + /* + * calc_chksums calculates the checksums for the blocks described in the + * descriptor block. + */ + static int calc_chksums(journal_t *journal, struct buffer_head *bh, +- unsigned long *next_log_block, __u32 *crc32_sum) ++ unsigned long long *next_log_block, __u32 *crc32_sum) + { + int i, num_blks, err; +- unsigned long io_block; ++ unsigned long long io_block; + struct buffer_head *obh; + + num_blks = count_tags(journal, bh); +@@ -340,7 +338,7 @@ static int calc_chksums(journal_t *journal, struct buffer_head *bh, + err = jread(&obh, journal, io_block); + if (err) { + printk(KERN_ERR "JBD: IO error %d recovering block " +- "%lu in log\n", err, io_block); ++ "%llu in log\n", err, io_block); + return 1; + } else { + *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data, +@@ -355,7 +353,7 @@ static int do_one_pass(journal_t *journal, + struct recovery_info *info, enum passtype pass) + { + unsigned int first_commit_ID, next_commit_ID; +- unsigned long next_log_block; ++ unsigned long long next_log_block; + int err, success = 0; + journal_superblock_t * sb; + journal_header_t * tmp; +@@ -485,7 +483,7 @@ static int do_one_pass(journal_t *journal, + tagp = &bh->b_data[sizeof(journal_header_t)]; + while ((tagp - bh->b_data + tag_bytes) + <= journal->j_blocksize) { +- unsigned long io_block; ++ unsigned long long io_block; + + tag = (journal_block_tag_t *) tagp; + flags = be32_to_cpu(tag->t_flags); +@@ -499,13 +497,14 @@ static int do_one_pass(journal_t *journal, + success = err; + printk (KERN_ERR + "JBD: IO error %d recovering " +- "block %ld in log\n", ++ "block %llu in log\n", + err, io_block); + } else { +- unsigned long blocknr; ++ unsigned long long blocknr; + + J_ASSERT(obh != NULL); +- blocknr = be32_to_cpu(tag->t_blocknr); ++ blocknr = read_tag_block(tag_bytes, ++ tag); + + /* If the block has been + * revoked, then we're all done +@@ -733,7 +732,7 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, + record_len = 8; + + while (offset < max) { +- unsigned long blocknr; ++ unsigned long long blocknr; + int err; + + if (record_len == 4) + +commit 97a67c40dc36a4cfc50192fe96ed12689718af94 +Author: Eric Sandeen +Date: Sun May 27 22:11:58 2012 -0400 + + debugfs: fix strtoblk for 64bit block numbers + + Affects icheck, freeb, setb, testb... + + Signed-off-by: Eric Sandeen + Signed-off-by: Theodore Ts'o + +diff --git a/debugfs/util.c b/debugfs/util.c +index f43b470..b07a8cc 100644 +--- a/debugfs/util.c ++++ b/debugfs/util.c +@@ -298,7 +298,7 @@ unsigned long long parse_ulonglong(const char *str, const char *cmd, + */ + int strtoblk(const char *cmd, const char *str, blk64_t *ret) + { +- blk_t blk; ++ blk64_t blk; + int err; + + blk = parse_ulonglong(str, cmd, "block number", &err); + +commit 918eeb32e9bd1d053bafc9d3c70ef420c21eeda9 +Author: Eric Sandeen +Date: Sun May 27 22:13:39 2012 -0400 + + libext2fs: fix rbtree backend for extent lengths greater than 2^32 + + For a completely full filesystem with more than 2^32 blocks, the + rbtree bitmap backend can assemble an extent of used blocks which is + longer than 2^32. If it does, it will overflow ->count, and corrupt + the rbtree for the bitmaps. + + Discovered by completely filling a 32T filesystem using fallocate, and + then observing debugfs, dumpe2fs, and e2fsck all behaving badly. + + (Note that filling with only 31 x 1T files did not show the problem, + because freespace was fragmented enough that there was no sufficiently + long range of used blocks.) + + Reviewed-by: Andreas Dilger + Signed-off-by: Eric Sandeen + Signed-off-by: Theodore Ts'o + +diff --git a/lib/ext2fs/blkmap64_rb.c b/lib/ext2fs/blkmap64_rb.c +index 7ab72f4..a83f8ac 100644 +--- a/lib/ext2fs/blkmap64_rb.c ++++ b/lib/ext2fs/blkmap64_rb.c +@@ -33,7 +33,7 @@ + struct bmap_rb_extent { + struct rb_node node; + __u64 start; +- __u32 count; ++ __u64 count; + }; + + struct ext2fs_rb_private { + + diff --git a/e2fsprogs.spec b/e2fsprogs.spec index dc4fddd..d2a9e10 100644 --- a/e2fsprogs.spec +++ b/e2fsprogs.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing ext2, ext3, and ext4 filesystems Name: e2fsprogs Version: 1.42.3 -Release: 1%{?dist} +Release: 2%{?dist} # License tags based on COPYING file distinctions for various components License: GPLv2 @@ -11,6 +11,7 @@ Source1: ext2_types-wrapper.h Source2: e2fsck.conf Patch1: e2fsprogs-1.40.4-sb_feature_check_ignore.patch +Patch2: e2fsprogs-1.42.2-64-bit-fixes.patch Url: http://e2fsprogs.sourceforge.net/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -147,6 +148,9 @@ It was originally inspired by the Multics SubSystem library. # after an selinux install... %patch1 -p1 -b .featurecheck +# 64 bit fixes +%patch2 -p1 + %build %configure --enable-elf-shlibs --enable-nls --disable-uuidd --disable-fsck \ --disable-e2initrd-helper --disable-libblkid --disable-libuuid \ @@ -320,6 +324,9 @@ exit 0 %{_libdir}/pkgconfig/ss.pc %changelog +* Thu May 31 2013 Eric Sandeen 1.42.3-2 +- Fixes for > 16T filesystems + * Mon May 14 2013 Eric Sandeen 1.42.3-1 - New upstream release -- cgit