Whamcloud - gitweb
Merge branch 'maint' into next
authorTheodore Ts'o <tytso@mit.edu>
Tue, 10 Sep 2013 00:49:49 +0000 (20:49 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 10 Sep 2013 00:49:49 +0000 (20:49 -0400)
20 files changed:
debian/changelog
debian/e2fsck-static.preinst [new file with mode: 0644]
debian/e2fsprogs.preinst [new file with mode: 0644]
debugfs/debugfs.c
e2fsck/pass1.c
e2fsck/pass2.c
e2fsck/util.c
lib/ext2fs/dupfs.c
lib/ext2fs/ext2_err.et.in
lib/ext2fs/extent.c
lib/ext2fs/ismounted.c
resize/resize2fs.c
tests/f_invalid_extent_symlink/expect.1 [new file with mode: 0644]
tests/f_invalid_extent_symlink/expect.2 [new file with mode: 0644]
tests/f_invalid_extent_symlink/image.gz [new file with mode: 0644]
tests/f_invalid_extent_symlink/name [new file with mode: 0644]
tests/f_toobig_extent_dir/expect.1 [new file with mode: 0644]
tests/f_toobig_extent_dir/expect.2 [new file with mode: 0644]
tests/f_toobig_extent_dir/image.gz [new file with mode: 0644]
tests/f_toobig_extent_dir/name [new file with mode: 0644]

index 060e148..12a5d8c 100644 (file)
@@ -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 (file)
index 0000000..e756ade
--- /dev/null
@@ -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 (file)
index 0000000..bfa9f6b
--- /dev/null
@@ -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
index dcf16e2..2660218 100644 (file)
@@ -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;
index ba6025b..24b2e16 100644 (file)
@@ -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;
index 85ce982..3c0bf49 100644 (file)
@@ -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");
 }
 
 /*
index 9eaf557..18005f4 100644 (file)
@@ -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);
index 64d3124..02721e1 100644 (file)
@@ -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:
index d20c6b7..de1b05b 100644 (file)
@@ -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,
index 65bb099..fbb0a74 100644 (file)
@@ -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;
 
index 9bccc74..2c1bd75 100644 (file)
@@ -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;
        }
index 3610e7b..76d7aa6 100644 (file)
@@ -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 (file)
index 0000000..7bda0b7
--- /dev/null
@@ -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 (file)
index 0000000..41ceefb
--- /dev/null
@@ -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 (file)
index 0000000..d4a6eef
Binary files /dev/null and b/tests/f_invalid_extent_symlink/image.gz differ
diff --git a/tests/f_invalid_extent_symlink/name b/tests/f_invalid_extent_symlink/name
new file mode 100644 (file)
index 0000000..3792aac
--- /dev/null
@@ -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 (file)
index 0000000..610ca3f
--- /dev/null
@@ -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 (file)
index 0000000..c025645
--- /dev/null
@@ -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 (file)
index 0000000..622f65a
Binary files /dev/null and b/tests/f_toobig_extent_dir/image.gz differ
diff --git a/tests/f_toobig_extent_dir/name b/tests/f_toobig_extent_dir/name
new file mode 100644 (file)
index 0000000..d7453ad
--- /dev/null
@@ -0,0 +1 @@
+directory with a very large lblk in extent