diff --git a/e2fsprogs-1.41.4-extent-open-leak.patch b/e2fsprogs-1.41.4-extent-open-leak.patch new file mode 100644 index 0000000..8d4112b --- /dev/null +++ b/e2fsprogs-1.41.4-extent-open-leak.patch @@ -0,0 +1,28 @@ +Each time an extent handle is opened and closed, if the inode has an +extent tree which does not fit in the inode's i_block structure, a +filesystem block buffer was not getting released. Since e2fsck opens +an extent handle for every inode using extents, this can translate to +a very large amount of memory getting lost. + +Thanks to Henrik 'Mauritz' Johnson for discovering and pointing out +this leak, which he ran into while running the "rdump" command in +debugfs. + +Signed-off-by: "Theodore Ts'o" +--- + lib/ext2fs/extent.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c +index b7eb617..2b88739 100644 +--- a/lib/ext2fs/extent.c ++++ b/lib/ext2fs/extent.c +@@ -168,7 +168,7 @@ extern void ext2fs_extent_free(ext2_extent_handle_t handle) + if (handle->inode) + ext2fs_free_mem(&handle->inode); + if (handle->path) { +- for (i=1; i < handle->max_depth; i++) { ++ for (i=1; i <= handle->max_depth; i++) { + if (handle->path[i].buf) + ext2fs_free_mem(&handle->path[i].buf); + } diff --git a/e2fsprogs-1.41.4-no-full-inode-write-in-extentcode.patch b/e2fsprogs-1.41.4-no-full-inode-write-in-extentcode.patch new file mode 100644 index 0000000..20ec2e2 --- /dev/null +++ b/e2fsprogs-1.41.4-no-full-inode-write-in-extentcode.patch @@ -0,0 +1,55 @@ +commit 125a36780626cdb0fc4d62fd529486baa8bce54c +Author: Eric Sandeen +Date: Wed Jun 17 18:49:01 2009 -0400 + + libext2fs: write only core inode in update_path() + + The ext2_extent_handle only has a struct ext2_inode allocated on + it, and the same amount copied into it in that same function, + but in update_path() we're possibly writing out more than that - + for example 256 bytes, from that address. This causes uninitialized + memory to get written to disk, overwriting the parts of the + inode past the osd2 member (the end of the smaller structure). + + Signed-off-by: Eric Sandeen + Signed-off-by: "Theodore Ts'o" + +diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c +index 2b88739..35b080e 100644 +--- a/lib/ext2fs/extent.c ++++ b/lib/ext2fs/extent.c +@@ -546,8 +546,8 @@ static errcode_t update_path(ext2_extent_handle_t handle) + struct ext3_extent_idx *ix; + + if (handle->level == 0) { +- retval = ext2fs_write_inode_full(handle->fs, handle->ino, +- handle->inode, EXT2_INODE_SIZE(handle->fs->super)); ++ retval = ext2fs_write_inode(handle->fs, handle->ino, ++ handle->inode); + } else { + ix = handle->path[handle->level - 1].curr; + blk = ext2fs_le32_to_cpu(ix->ei_leaf) + +@@ -1011,8 +1011,8 @@ static errcode_t extent_node_split(ext2_extent_handle_t handle) + + /* new node hooked in, so update inode block count (do this here?) */ + handle->inode->i_blocks += handle->fs->blocksize / 512; +- retval = ext2fs_write_inode_full(handle->fs, handle->ino, +- handle->inode, EXT2_INODE_SIZE(handle->fs->super)); ++ retval = ext2fs_write_inode(handle->fs, handle->ino, ++ handle->inode); + if (retval) + goto done; + +@@ -1370,9 +1370,8 @@ errcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags) + + retval = ext2fs_extent_delete(handle, flags); + handle->inode->i_blocks -= handle->fs->blocksize / 512; +- retval = ext2fs_write_inode_full(handle->fs, +- handle->ino, handle->inode, +- EXT2_INODE_SIZE(handle->fs->super)); ++ retval = ext2fs_write_inode(handle->fs, handle->ino, ++ handle->inode); + ext2fs_block_alloc_stats(handle->fs, extent.e_pblk, -1); + } + } else { + diff --git a/e2fsprogs-1.41.4-update-sb-journal-backup.patch b/e2fsprogs-1.41.4-update-sb-journal-backup.patch new file mode 100644 index 0000000..1f26210 --- /dev/null +++ b/e2fsprogs-1.41.4-update-sb-journal-backup.patch @@ -0,0 +1,89 @@ +This was reported in Fedora, since the livecd creator does +a lot of resizing. + +If we've moved the journal blocks during resize (more likely now, +due to the journal being in the middle) the backup blocks in the +superblock don't get updated, and a subsequent e2fsck will find +issues: + +e2fsck 1.41.6 (30-May-2009) +Backing up journal inode block information. + +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information + +/mnt/test/img: ***** FILE SYSTEM WAS MODIFIED ***** +/mnt/test/img: 11/16000 files (0.0% non-contiguous), 17789/38400 blocks + +This can be shown in a simple test: + +# dd if=/dev/zero of=img bs=1 count=0 seek=3000M +# mke2fs -t ext4 -F img +# resize2fs img 150M +# e2fsck -f img + +(thanks to the Fedora reporter Mads Kiilerich for the testcase! +https://bugzilla.redhat.com/show_bug.cgi?id=506105#c2) + +So, update the backup journal in the superblock before resize2fs exits. + +Signed-off-by: Eric Sandeen +Resolves-RH-Bugzilla: 505339 +--- + +diff --git a/resize/resize2fs.c b/resize/resize2fs.c +index 0d5dc81..63c469f 100644 +--- a/resize/resize2fs.c ++++ b/resize/resize2fs.c +@@ -49,6 +49,7 @@ static errcode_t inode_ref_fix(ext2_resize_t rfs); + static errcode_t move_itables(ext2_resize_t rfs); + static errcode_t fix_resize_inode(ext2_filsys fs); + static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs); ++static errcode_t fix_sb_journal_backup(ext2_filsys fs); + + /* + * Some helper CPP macros +@@ -148,6 +149,10 @@ errcode_t resize_fs(ext2_filsys fs, blk_t *new_size, int flags, + if (retval) + goto errout; + ++ retval = fix_sb_journal_backup(rfs->new_fs); ++ if (retval) ++ goto errout; ++ + rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; + retval = ext2fs_close(rfs->new_fs); + if (retval) +@@ -1857,6 +1862,28 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) + } + + /* ++ * Journal may have been relocated; update the backup journal blocks ++ * in the superblock. ++ */ ++static errcode_t fix_sb_journal_backup(ext2_filsys fs) ++{ ++ errcode_t retval; ++ struct ext2_inode inode; ++ ++ if (!(fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) ++ return 0; ++ ++ retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode); ++ if (retval) ++ return retval; ++ memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4); ++ fs->super->s_jnl_blocks[16] = inode.i_size; ++ fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; ++ ext2fs_mark_super_dirty(fs); ++ return 0; ++} ++ ++/* + * calcluate the minimum number of blocks the given fs can be resized to + */ + blk_t calculate_minimum_resize_size(ext2_filsys fs) + diff --git a/e2fsprogs.spec b/e2fsprogs.spec index 98cd991..d7ae869 100644 --- a/e2fsprogs.spec +++ b/e2fsprogs.spec @@ -4,7 +4,7 @@ Summary: Utilities for managing ext2, ext3, and ext4 filesystems Name: e2fsprogs Version: 1.41.6 -Release: 4%{?dist} +Release: 5%{?dist} # License based on upstream-modified COPYING file, # which clearly states "V2" intent. License: GPLv2 @@ -14,6 +14,11 @@ Source1: ext2_types-wrapper.h Source3: uuidd.init Patch2: e2fsprogs-1.40.4-sb_feature_check_ignore.patch +# Upstream or soon to be: +Patch3: e2fsprogs-1.41.4-update-sb-journal-backup.patch +Patch4: e2fsprogs-1.41.4-extent-open-leak.patch +Patch5: e2fsprogs-1.41.4-no-full-inode-write-in-extentcode.patch + Url: http://e2fsprogs.sourceforge.net/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: e2fsprogs-libs = %{version}-%{release}, device-mapper @@ -89,6 +94,9 @@ SMP systems. # mildly unsafe but 'til I get something better, avoid full fsck # after an selinux install... %patch2 -p1 -b .featurecheck +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 %build %configure --enable-elf-shlibs --enable-nls \ @@ -270,6 +278,11 @@ fi %dir %attr(2775, uuidd, uuidd) /var/lib/libuuid %changelog +* Thu Jun 18 2009 Eric Sandeen 1.41.6-5 +- Update journal backup blocks in sb after resize (#505339) +- Fix memory leak in extent handling functions +- Fix bug in inode writing in extent code, clobbered i_extra_isize etc + * Mon Jun 8 2009 Karel Zak 1.41.6-4 - set BuildRequires: libblkid-devel (from util-linux-ng) diff --git a/uuidd.init b/uuidd.init index e269da8..9aca1da 100755 --- a/uuidd.init +++ b/uuidd.init @@ -65,7 +65,7 @@ case "$1" in ;; status) status -p /var/lib/libuuid/uuidd.pid uuidd uuidd - REVAL=$? + RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"