aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-09-09 20:49:49 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-09-09 20:49:49 -0400
commitfc9f162eea8ade980b6347a70a020d43ba215540 (patch)
tree6b0bca15941cac1b9bb6c414b57f9a8d9a37da8e
parent97ba11e8da0cedd783db109fe5b97bb609754fd6 (diff)
parent085757fcc22a86168ee6793dfad9a95d88fb09db (diff)
downloade2fsprogs-fc9f162eea8ade980b6347a70a020d43ba215540.tar.gz
e2fsprogs-fc9f162eea8ade980b6347a70a020d43ba215540.tar.xz
e2fsprogs-fc9f162eea8ade980b6347a70a020d43ba215540.zip
Merge branch 'maint' into next
-rw-r--r--debian/changelog9
-rw-r--r--debian/e2fsck-static.preinst19
-rw-r--r--debian/e2fsprogs.preinst19
-rw-r--r--debugfs/debugfs.c13
-rw-r--r--e2fsck/pass1.c17
-rw-r--r--e2fsck/pass2.c7
-rw-r--r--e2fsck/util.c2
-rw-r--r--lib/ext2fs/dupfs.c25
-rw-r--r--lib/ext2fs/ext2_err.et.in2
-rw-r--r--lib/ext2fs/extent.c6
-rw-r--r--lib/ext2fs/ismounted.c2
-rw-r--r--resize/resize2fs.c41
-rw-r--r--tests/f_invalid_extent_symlink/expect.112
-rw-r--r--tests/f_invalid_extent_symlink/expect.27
-rw-r--r--tests/f_invalid_extent_symlink/image.gzbin0 -> 1115 bytes
-rw-r--r--tests/f_invalid_extent_symlink/name1
-rw-r--r--tests/f_toobig_extent_dir/expect.112
-rw-r--r--tests/f_toobig_extent_dir/expect.27
-rw-r--r--tests/f_toobig_extent_dir/image.gzbin0 -> 822 bytes
-rw-r--r--tests/f_toobig_extent_dir/name1
20 files changed, 172 insertions, 30 deletions
diff --git a/debian/changelog b/debian/changelog
index 060e148f..12a5d8ca 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -123,6 +123,15 @@ e2fsprogs (1.42.6-1) unstable; urgency=low
-- Theodore Y. Ts'o <tytso@mit.edu> Fri, 21 Sep 2012 12:14:41 -0400
+e2fsprogs (1.42.5-1.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * e2fsck-static, e2fsprogs: let preinst remove a symbolic link in
+ /usr/share/doc, that should have been replaced with a directory since
+ 1.39+1.40-WIP-2006.10.02+dfsg-1. (Closes: #698879).
+
+ -- Nicolas Boulenguez <nicolas@debian.org> Fri, 22 Feb 2013 23:14:59 +0100
+
e2fsprogs (1.42.5-1) unstable; urgency=low
* New upstream version
diff --git a/debian/e2fsck-static.preinst b/debian/e2fsck-static.preinst
new file mode 100644
index 00000000..e756adea
--- /dev/null
+++ b/debian/e2fsck-static.preinst
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# Abort on error.
+set -e
+
+PKG=e2fsck-static
+DOCLNK=/usr/share/doc/$PKG
+if test "$1" = upgrade \
+ -a -L $DOCLNK
+then
+ rm $DOCLNK
+fi
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/e2fsprogs.preinst b/debian/e2fsprogs.preinst
new file mode 100644
index 00000000..bfa9f6b0
--- /dev/null
+++ b/debian/e2fsprogs.preinst
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# Abort on error.
+set -e
+
+PKG=e2fsprogs
+DOCLNK=/usr/share/doc/$PKG
+if test "$1" = upgrade \
+ -a -L $DOCLNK
+then
+ rm $DOCLNK
+fi
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index dcf16e28..26602189 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -1677,8 +1677,19 @@ void do_write(int argc, char *argv[])
inode.i_links_count = 1;
inode.i_size = statbuf.st_size;
if (current_fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_EXTENTS)
+ EXT3_FEATURE_INCOMPAT_EXTENTS) {
+ int i;
+ struct ext3_extent_header *eh;
+
+ eh = (struct ext3_extent_header *) &inode.i_block[0];
+ eh->eh_depth = 0;
+ eh->eh_entries = 0;
+ eh->eh_magic = EXT3_EXT_MAGIC;
+ i = (sizeof(inode.i_block) - sizeof(*eh)) /
+ sizeof(struct ext3_extent);
+ eh->eh_max = ext2fs_cpu_to_le16(i);
inode.i_flags |= EXT4_EXTENTS_FL;
+ }
if (debugfs_write_new_inode(newfile, &inode, argv[0])) {
close(fd);
return;
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index ba6025b8..24b2e16d 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1849,6 +1849,7 @@ void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
struct process_block_struct *pb,
blk64_t start_block, blk64_t end_block,
+ blk64_t eof_block,
ext2_extent_handle_t ehandle)
{
struct ext2fs_extent extent;
@@ -1892,7 +1893,9 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
problem = PR_1_EXTENT_BAD_START_BLK;
else if (extent.e_lblk < start_block)
problem = PR_1_OUT_OF_ORDER_EXTENTS;
- else if (end_block && last_lblk > end_block)
+ else if ((end_block && last_lblk > end_block) &&
+ (!(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT &&
+ last_lblk > eof_block)))
problem = PR_1_EXTENT_END_OUT_OF_BOUNDS;
else if (is_leaf && extent.e_len == 0)
problem = PR_1_EXTENT_LENGTH_ZERO;
@@ -1900,6 +1903,10 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
(extent.e_pblk + extent.e_len) >
ext2fs_blocks_count(ctx->fs->super))
problem = PR_1_EXTENT_ENDS_BEYOND;
+ else if (is_leaf && is_dir &&
+ ((extent.e_lblk + extent.e_len) >
+ (1 << (21 - ctx->fs->super->s_log_block_size))))
+ problem = PR_1_TOOBIG_DIR;
/* Corrupt but passes checks? Ask to fix checksum. */
if (failed_csum) {
@@ -1917,6 +1924,7 @@ report_problem:
pctx->blk = extent.e_pblk;
pctx->blk2 = extent.e_lblk;
pctx->num = extent.e_len;
+ pctx->blkcount = extent.e_lblk + extent.e_len;
if (fix_problem(ctx, problem, pctx)) {
fix_problem_now:
e2fsck_read_bitmaps(ctx);
@@ -1968,7 +1976,7 @@ fix_problem_now:
ext2fs_extent_fix_parents(ehandle);
}
scan_extent_node(ctx, pctx, pb, extent.e_lblk,
- last_lblk, ehandle);
+ last_lblk, eof_block, ehandle);
if (pctx->errcode)
return;
pctx->errcode = ext2fs_extent_get(ehandle,
@@ -2071,6 +2079,7 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
ext2_filsys fs = ctx->fs;
ext2_ino_t ino = pctx->ino;
errcode_t retval;
+ blk64_t eof_lblk;
pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
if (pctx->errcode) {
@@ -2088,7 +2097,9 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
ctx->extent_depth_count[info.max_depth]++;
}
- scan_extent_node(ctx, pctx, pb, 0, 0, ehandle);
+ eof_lblk = ((EXT2_I_SIZE(inode) + fs->blocksize - 1) >>
+ EXT2_BLOCK_SIZE_BITS(fs->super)) - 1;
+ scan_extent_node(ctx, pctx, pb, 0, 0, eof_lblk, ehandle);
if (pctx->errcode &&
fix_problem(ctx, PR_1_EXTENT_ITERATE_FAILURE, pctx)) {
pb->num_blocks = 0;
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 85ce9821..3c0bf498 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1282,7 +1282,6 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
struct del_block del_block;
e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
- e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode");
clear_problem_context(&pctx);
pctx.ino = ino;
@@ -1317,7 +1316,7 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
}
if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
- return;
+ goto clear_inode;
if (LINUX_S_ISREG(inode.i_mode) && EXT2_I_SIZE(&inode) >= 0x80000000UL)
ctx->large_files--;
@@ -1332,6 +1331,10 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
ctx->flags |= E2F_FLAG_ABORT;
return;
}
+clear_inode:
+ /* Inode may have changed by block_iterate, so reread it */
+ e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
+ e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode");
}
/*
diff --git a/e2fsck/util.c b/e2fsck/util.c
index 9eaf5574..18005f40 100644
--- a/e2fsck/util.c
+++ b/e2fsck/util.c
@@ -55,7 +55,7 @@ void fatal_error(e2fsck_t ctx, const char *msg)
fprintf (stderr, "e2fsck: %s\n", msg);
if (!fs)
goto out;
- if (fs->io) {
+ if (fs->io && fs->super) {
ext2fs_mmp_stop(ctx->fs);
if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
io_channel_flush(ctx->fs->io);
diff --git a/lib/ext2fs/dupfs.c b/lib/ext2fs/dupfs.c
index 64d31248..02721e1a 100644
--- a/lib/ext2fs/dupfs.c
+++ b/lib/ext2fs/dupfs.c
@@ -40,6 +40,9 @@ errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
fs->block_map = 0;
fs->badblocks = 0;
fs->dblist = 0;
+ fs->mmp_buf = 0;
+ fs->mmp_cmp = 0;
+ fs->mmp_fd = -1;
io_channel_bumpcount(fs->io);
if (fs->icache)
@@ -87,6 +90,28 @@ errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
if (retval)
goto errout;
}
+ if (src->mmp_buf) {
+ retval = ext2fs_get_mem(src->blocksize, &fs->mmp_buf);
+ if (retval)
+ goto errout;
+ memcpy(fs->mmp_buf, src->mmp_buf, src->blocksize);
+ }
+ if (src->mmp_fd >= 0) {
+ fs->mmp_fd = dup(src->mmp_fd);
+ if (fs->mmp_fd < 0) {
+ retval = EXT2_ET_MMP_OPEN_DIRECT;
+ goto errout;
+ }
+ }
+ if (src->mmp_cmp) {
+ int align = ext2fs_get_dio_alignment(src->mmp_fd);
+
+ retval = ext2fs_get_memalign(src->blocksize, align,
+ &fs->mmp_cmp);
+ if (retval)
+ goto errout;
+ memcpy(fs->mmp_cmp, src->mmp_cmp, src->blocksize);
+ }
*dest = fs;
return 0;
errout:
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index d20c6b73..de1b05bb 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -416,7 +416,7 @@ ec EXT2_ET_EXTENT_INVALID_LENGTH,
ec EXT2_ET_IO_CHANNEL_NO_SUPPORT_64,
"I/O Channel does not support 64-bit block numbers"
-ec EXT2_NO_MTAB_FILE,
+ec EXT2_ET_NO_MTAB_FILE,
"Can't check if filesystem is mounted due to missing mtab file"
ec EXT2_ET_CANT_USE_LEGACY_BITMAPS,
diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
index 65bb0996..fbb0a74a 100644
--- a/lib/ext2fs/extent.c
+++ b/lib/ext2fs/extent.c
@@ -1378,6 +1378,9 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
&next_extent);
if (retval)
goto done;
+ retval = ext2fs_extent_fix_parents(handle);
+ if (retval)
+ goto done;
} else
retval = ext2fs_extent_insert(handle,
EXT2_EXTENT_INSERT_AFTER, &newextent);
@@ -1430,6 +1433,9 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
retval = ext2fs_extent_replace(handle, 0, &extent);
if (retval)
goto done;
+ retval = ext2fs_extent_fix_parents(handle);
+ if (retval)
+ goto done;
} else {
__u32 orig_length;
diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c
index 9bccc74d..2c1bd752 100644
--- a/lib/ext2fs/ismounted.c
+++ b/lib/ext2fs/ismounted.c
@@ -58,7 +58,7 @@ static errcode_t check_mntent_file(const char *mtab_file, const char *file,
if (getenv("EXT2FS_NO_MTAB_OK"))
return 0;
else
- return EXT2_NO_MTAB_FILE;
+ return EXT2_ET_NO_MTAB_FILE;
}
return errno;
}
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 3610e7bf..76d7aa6f 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -272,34 +272,36 @@ static void fix_uninit_block_bitmaps(ext2_filsys fs)
*/
static void free_gdp_blocks(ext2_filsys fs,
ext2fs_block_bitmap reserve_blocks,
- struct ext2_group_desc *gdp)
+ ext2_filsys old_fs,
+ dgrp_t group)
{
- blk_t blk;
+ blk64_t blk;
int j;
- if (gdp->bg_block_bitmap &&
- (gdp->bg_block_bitmap < ext2fs_blocks_count(fs->super))) {
- ext2fs_block_alloc_stats(fs, gdp->bg_block_bitmap, -1);
- ext2fs_mark_block_bitmap2(reserve_blocks,
- gdp->bg_block_bitmap);
+ blk = ext2fs_block_bitmap_loc(old_fs, group);
+ if (blk &&
+ (blk < ext2fs_blocks_count(fs->super))) {
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ ext2fs_mark_block_bitmap2(reserve_blocks, blk);
}
- if (gdp->bg_inode_bitmap &&
- (gdp->bg_inode_bitmap < ext2fs_blocks_count(fs->super))) {
- ext2fs_block_alloc_stats(fs, gdp->bg_inode_bitmap, -1);
- ext2fs_mark_block_bitmap2(reserve_blocks,
- gdp->bg_inode_bitmap);
+ blk = ext2fs_inode_bitmap_loc(old_fs, group);
+ if (blk &&
+ (blk < ext2fs_blocks_count(fs->super))) {
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ ext2fs_mark_block_bitmap2(reserve_blocks, blk);
}
- if (gdp->bg_inode_table == 0 ||
- (gdp->bg_inode_table >= ext2fs_blocks_count(fs->super)))
+ blk = ext2fs_inode_table_loc(old_fs, group);
+ if (blk == 0 ||
+ (blk >= ext2fs_blocks_count(fs->super)))
return;
- for (blk = gdp->bg_inode_table, j = 0;
+ for (j = 0;
j < fs->inode_blocks_per_group; j++, blk++) {
if (blk >= ext2fs_blocks_count(fs->super))
break;
- ext2fs_block_alloc_stats(fs, blk, -1);
+ ext2fs_block_alloc_stats2(fs, blk, -1);
ext2fs_mark_block_bitmap2(reserve_blocks, blk);
}
}
@@ -466,11 +468,8 @@ retry:
* and free any blocks associated with their metadata
*/
for (i = fs->group_desc_count;
- i < old_fs->group_desc_count; i++) {
- free_gdp_blocks(fs, reserve_blocks,
- ext2fs_group_desc(old_fs,
- old_fs->group_desc, i));
- }
+ i < old_fs->group_desc_count; i++)
+ free_gdp_blocks(fs, reserve_blocks, old_fs, i);
retval = 0;
goto errout;
}
diff --git a/tests/f_invalid_extent_symlink/expect.1 b/tests/f_invalid_extent_symlink/expect.1
new file mode 100644
index 00000000..7bda0b73
--- /dev/null
+++ b/tests/f_invalid_extent_symlink/expect.1
@@ -0,0 +1,12 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Symlink /a (inode #12) is invalid.
+Clear? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 11/16 files (9.1% non-contiguous), 21/100 blocks
+Exit status is 1
diff --git a/tests/f_invalid_extent_symlink/expect.2 b/tests/f_invalid_extent_symlink/expect.2
new file mode 100644
index 00000000..41ceefb4
--- /dev/null
+++ b/tests/f_invalid_extent_symlink/expect.2
@@ -0,0 +1,7 @@
+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
+test_filesys: 11/16 files (0.0% non-contiguous), 21/100 blocks
+Exit status is 0
diff --git a/tests/f_invalid_extent_symlink/image.gz b/tests/f_invalid_extent_symlink/image.gz
new file mode 100644
index 00000000..d4a6eef7
--- /dev/null
+++ b/tests/f_invalid_extent_symlink/image.gz
Binary files differ
diff --git a/tests/f_invalid_extent_symlink/name b/tests/f_invalid_extent_symlink/name
new file mode 100644
index 00000000..3792aac7
--- /dev/null
+++ b/tests/f_invalid_extent_symlink/name
@@ -0,0 +1 @@
+extent-mapped symlink with two blocks
diff --git a/tests/f_toobig_extent_dir/expect.1 b/tests/f_toobig_extent_dir/expect.1
new file mode 100644
index 00000000..610ca3f0
--- /dev/null
+++ b/tests/f_toobig_extent_dir/expect.1
@@ -0,0 +1,12 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 is too big. Truncate? yes
+
+Block #4294967281 (90) causes directory to be too big. CLEARED.
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 12/56 files (0.0% non-contiguous), 28/400 blocks
+Exit status is 1
diff --git a/tests/f_toobig_extent_dir/expect.2 b/tests/f_toobig_extent_dir/expect.2
new file mode 100644
index 00000000..c0256452
--- /dev/null
+++ b/tests/f_toobig_extent_dir/expect.2
@@ -0,0 +1,7 @@
+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
+test_filesys: 12/56 files (0.0% non-contiguous), 28/400 blocks
+Exit status is 0
diff --git a/tests/f_toobig_extent_dir/image.gz b/tests/f_toobig_extent_dir/image.gz
new file mode 100644
index 00000000..622f65a0
--- /dev/null
+++ b/tests/f_toobig_extent_dir/image.gz
Binary files differ
diff --git a/tests/f_toobig_extent_dir/name b/tests/f_toobig_extent_dir/name
new file mode 100644
index 00000000..d7453ad3
--- /dev/null
+++ b/tests/f_toobig_extent_dir/name
@@ -0,0 +1 @@
+directory with a very large lblk in extent