We need to do an accounting of duplicate clusters on a per-cluster
instead of a per-block basis so we know when we've correctly accounted
for all of the multiply claimed blocks in a particular inode.
Thanks to Robin Dong for reporting this bug.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The ext2fs_file_acl_block() and ext2fs_set_file_acl_block() needs to
only check i_file_acl_high if the 64-bit flag is set. This is needed
because otherwise we will run into problems on Hurd systems which
actually use that field for h_i_mode_high.
This involves an ABI change since we need to pass ext2_filsys to these
functions. Fortunately these functions were first included in the
1.42-WIP series, so it's OK for us to change them now. (This is why
we have 1.42-WIP releases. :-)
Addresses-Sourceforge-Bug: #3379227
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Multi-mount protection is feature that allows mke2fs, e2fsck, and
others to detect if the filesystem is mounted on a remote node (on
SAN disks) and avoid corrupting the filesystem. For e2fsprogs this
means that it checks the MMP block to see if the filesystem is in use,
and marks the filesystem busy while e2fsck is running on the system.
This is useful on SAN disks that are shared between high-availability
servers, or accessible by multiple nodes that aren't in HA pairs. MMP
isn't intended to serve as a primary HA exclusion mechanism, but as a
failsafe to protect against user, software, or hardware errors.
There is no requirement that e2fsck updates the MMP block at regular
intervals, but e2fsck does this occasionally to provide useful
information to the sysadmin in case of a detected conflict.
For the kernel (since Linux 3.0) MMP adds a "heartbeat" mechanism to
periodically write to disk (every few seconds by default) to notify
other nodes that the filesystem is still in use and unsafe to modify.
Originally-by: Kalpak Shah <kalpak@clusterfs.com>
Signed-off-by: Johann Lombardi <johann@whamcloud.com>
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
The DEFS line in MCONFIG had gotten so long that it exceeded 4k, and
this was starting to cause some tools heartburn. It also made "make
V=1" almost useless, since trying to following the individual commands
run by make was lost in the noise of all of the defines.
So fix this by putting the configure-generated defines in lib/config.h
and the directory pathnames to lib/dirpaths.h.
In addition, clean up some vestigal defines in configure.in and in the
Makefiles to further shorten the cc command lines.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This patch adds support for doing quota accounting during full
e2fsck scan if the 'quota' feature was set on the superblock.
If user-visible quota inodes are in use, they will be hidden
and converted to the reserved quota inodes.
Signed-off-by: Aditya Kali <adityakali@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
I had an extremely corrupted customer filesystem which, after thousands
of lines of e2fsck output, found one more problem on an immediately
subsequent e2fsck. In short, a file had had its i_file_acl block
cloned due to being a duplicate. That ultimately got cleared
because the fs did not have the xattr feature, and the inode
was subsequently removed due to invalid mode.
The 2nd e2fsck pass found the cloned xattr block as in use, but
not owned by any file, and had to fix up the block bitmaps.
Simply skipping the processing of duplicate xattr blocks on a
non-xattr filesystem seems reasonable, since they will be cleared
later in any case.
(also fix existing brace misalignment)
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
in the case of ! defined RESOURCE_TRACK, so that we can clean up #ifdef
throughout e2fsck source.
Signed-off-by: Ken Chen <kenchen@google.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
On ext2, time tracking for pass1 includes both error detection and
specific type of fs fix-up phase (e.g. block referenced by multiple
inodes). The multi-reference fix-up phase some time take significant
amount of time to complete. We would like to track time spent in sub
component of pass1 by having a finer granularity during pass1b through
pass1d phase.
Signed-off-by: Ken Chen <kenchen@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Factor out code to clear a bogus inode and update e2fsck's internal
data structures accordingly into a common routine,
e2fsck_clear_inode(). This saves about 200 bytes in the compiled x86
e2fsck executable, and makes the code more maintainable in the
long-term.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Another small bug I think: if the root directory contains shared
blocks, e2fsck pass1c search_dirent_proc() will be looking for
one more containing directory than it will ever find, and thus
loses an opportunity to terminate early.
Signed-off-by: Jim Garlick <garlick@llnl.gov>
I think this is a small buglet in e2fsck: if a file has multiple hard
links, e2fsck pass1c search_dirent_proc() doesn't maintain its count
properly and may return DIRENT_ABORT before it has found containing
directories for all inodes sharing blocks.
Signed-off-by: Jim Garlick <garlick@llnl.gov>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The dict_lookup() function can potentially return a NULL dnode_t. It is
not checked in two places in the clone_file() function. Looks to be
safe to continue if n is NULL, so just print a warning message and
continue.
Coverity ID: 9: Null Returns
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
For loops iterating over all group descriptors, consistently define
first_block and last_block in a way that they are inclusive of the
range, and do not overflow.
Previously on the last block group we did a test of <= first +
dec_blocks; this would actually wrap back to 0 for a total block count
of 2^32-1
Also add handling of last block group which may be smaller.
Signed-off-by: Eric Sandeen <esandeen@redhat.com>
This fixes some (but not all) of the compatibility bugs which prevented
e2fsprogs from being compiled on a Linux 2.0.35 system. There are still
some unprotected use of long long's, and apparently some type problems
with the uuid library, but these can be fixed up later.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Change the format string(%d, %ld) for a block number and inode number
to %u or %lu.
Signed-off-by: Takashi Sato <sho@tnes.nec.co.jp>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
autoconf 2.13 version of AC_CHECK_TYPE. Otherwise, on some platforms
intptr_t might get erroneously #define'd to be long. (Addresses
Debian Bug #289133)
field calculation so that it only counts EA block entries
as a single multiply claimed block (since once we clone
the EA blocks for one inode, we fix the problem for all of
the other inodes). Also, I moved the num_bad calculation
from process_pass1b_block to the end of pass1b. This
fixes a *significant* performance bug in pass1b which hit
people who had to had a lot of multiply claimed blocks.
(Can you say O(n**3) boys and girls? I knew you could...
Fortunately, this case didn't happen that much in actual practice.)
blocks. Moved free of block_buf to after the code which clones the
extattr block, and fixed logic for changing pointers to the extended
attribute field in the inodes which were affected.
(decrement_badcount): New function which is used whenever we need to
decrement the number of files which claim a particular bad block.
Fixed bug where delete_file wasn't checking check_if_fs_block() before
clearing the entry in block_dup_map. This could cause a block which
was claimed by multiple files as well as the filesystem metadata to
not be completely fixed.
pass1.c (pass1_get_blocks, pass1_read_inode, pass1_write_inode,
pass1_check_directory): Add a safety check to make sure
ctx->stashed_inode is non-zero.
pass1b.c (pass1b): Use e2fsck_use_inode_shortcuts() to disable the
inode shortcut processing, instead of manually clearing only half of
the function pointers that needed to be NULL'ed out. This caused
nasty bugs if the last inode in the filesystem needed dup block
processing.
pass1b.c (clone_file_block): When cloning a directory's metadata
block, don't try to update the directory block list database, since
indirect blocks aren't stored in the database and the resulting error
will abort the file clone operation.
journal.c, pass1.c, pass1b.c, pass3.c, recovery.c, revoke.c, super.c,
unix.c, util.c: Fix random gcc -Wall complaints.
jfs_user.h: Use more sophisticated inline handling to allow building
with --enable-gcc-wall
pass1b.c: Change routines to use PR_1B_BLOCK_ITERATE when reporting
problems rather than using com_err directly.
problem.c, problem.h (PR_1B_BLOCK_ITERATE): Add new problem code.
message.c (expand_percent_expression): Add safety check. If ctx->str
is NULL, print "NULL" instead of dereferencing the null pointer.
pass1b.c, pass2.c, pass3.c: Change calls to ext2fs_block_iterate to
ext2fs_block_iterate2, to support 64-bit filesizes and to speed things
up slightly by avoiding the use of the ext2fs_block_iterate's
compatibility shim layer.
version.h:
Update for WIP release.
unix.c (main): If compression is enabled on the filesystem, print a
warning message (for now).
message.c: Add new compression shortcut: @c == compress
problem.c, problem.h (PR_1_COMPR_SET): Add new error code.
pass1.c (check_blocks): If the inode has EXT2_COMPRBLK_FL flag set,
check to see if the filesystem supports compression. If it does pass
this information down to process_block() so it can treat the
compressed block flag words correctly. If not, offer to clear the
flag, since it shouldn't be set.
(process_block): If an inode has the compressed inode flag set, allow
EXT2FS_COMPRESSED_BLKADDR.
pass1b.c (process_pass1b_block, delete_file_block, clone_file_block):
pass2.c (deallocate_inode_block): Use HOLE_BLKADDR to check to see if
the block can be skipped.
ChangeLog, Makefile.in:
Makefile.in: Exclude the internationalization files from being
distributed.
ChangeLog, configure, configure.in:
configure.in: Add support for --enable-compression. This is
experimental code only for now, which is why it's under --enable test.
Once it's stable, it will always be compiled in.
TODO:
Commit additional TODO items.
e2fsck.h:
pass1.c (mark_table_blocks, e2fsck_pass1): Remove
ctx->block_illegal_map, since it's not needed by pass1, and pass1b has
been modified to calculate it manually if needed. This reduces the
memory footprint needed by e2fsck.
pass1b.c (check_if_fs_block): New static function which returns
whether or not a block overlaps with filesystem metadata. This
replaces consulting the block_illegal_map bitmap.
util.c:
Make resource tracking message more concise.
pass1b.c (clone_file_block): Don't clear the dup_map flag if the block
also shares data with the fs metadata when the count drops to 1, since
the block should still be cloned, as fs metadata isn't included in the
count.
ChangeLog, pass3.c:
pass3.c (adjust_inode_count): Fix bug where we didn't keep the
internal and external inode counts in sync when we decremented an
inode whose link count was already zero. Now we skip incrementing or
decrementing both link counts if we would cause an overflow condition.
(expand_dir, expand_dir_proc): Change where we update the inode block
count and size files so that the block count field is updated
correctly when we create an indirect block.
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.