implied_cluster_alloc() is written such that if the the user passes in
a logical block that is the zeroth block in a logical cluster (lblk %
cluster_ratio == 0), then it will assume that there is no physical
cluster mapped to any other part of the logical cluster.
This is not true if we happen to be allocating logical blocks in
reverse order. Therefore, search the whole cluster, except for the
lblk that we passed in.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
When told to truncate a file, ext2fs_file_set_size2() should start with
the first block past the end of the file. The current calculation
jumps one more block ahead, with the result that it fails to hack off
the last block. Adding blocksize-1 and dividing is sufficient to find
the last block.
Reviewed-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
ext2fs_file_write() needs to update i_size on successful write,
otherwise, ext2fs_file_read() in same open/close cycle will not
be able to read the just written data.
This fixes a bug which results in the the problem of quotacheck
triggered on 'tune2fs -O quota' failed to write back multiple
users/groups accounting information.
Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The inode and block relocation functions aren't currently compiled in
(so we don't need to worry about breaking ABI compatibility). They
were originally intended for use by resize2fs, but we never ended up
using them, so (wisely) they weren't ever included in libext2fs as an
exported interface (they're not even compiled by the Makefile).
Fix them so that in case we ever use them, so that in places where raw
data types (int, long, etc.) stood in for blk_t and blk64_t. Also fix
some sites where we should probably be using blk64_t.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Fix all the places where we should be using a blk64_t instead of a
blk_t. These fixes are more severe because 64bit values could be
truncated silently.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
When we're iterating the main loop in ind_punch(), "offset" tracks how
far we've progressed into the block map, "start" tells us where to
start punching, and "count" tells us how many blocks we are to punch
after "start". Therefore, we would like to break out of the loop once
the "offset" that we're looking at has progressed past the end of the
punch range. Unfortunately, if start !=0, the if-break clause in the
loop causes us to break out of the loop early.
Therefore, change the breakout test to terminate the loop at the
correct time.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The range of blocks to punch is treated as an inclusive range on both
ends, i.e. if start=1 and end=2, both blocks 1 and 2 are punched out.
Thus, start == end means that the caller wishes to punch a single
block. Remove the check that prevents us from punching a single
block.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
During a punch operation, if we decide to delete an extent out of the
extent tree, the subsequent extents are moved on top of the current
extent (that is to say, they're memmmove'd down one slot). Therefore
it is not correct to advance to the next leaf because that means we
miss half the extents in the range! Rereading the current pointer
should be fine.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
If someone tries to write a file that is larger than 2GB, we need to
set the large_file feature flag to affirm that i_size_hi can hold
meaningful contents.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
The ext2fs_link helper function link_proc does not check the value of
ls->done, which means that if the function finds multiple empty spaces
that will fit the new directory entry, it will create a directory
entry in each of the spaces. Instead of doing that, check the done
value and don't do anything more if we've already added the directory
entry.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
When we define an error in lib/ext2fs/ext2_err.et.in, we will always use
EXT2_ET_* prefix for a new error. But EXT2_NO_MTAB_FILE doesn't obey
this rule. So fix it.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
If we have an extent tree like this (from debuge2fs's "ex" command):
Level Entries Logical Physical Length Flags
...
2/ 2 60/ 63 13096 - 13117 650024 - 650045 22
2/ 2 61/ 63 13134 - 13142 650062 - 650070 9
2/ 2 62/ 63 13193 - 13194 650121 - 650122 2
2/ 2 63/ 63 13227 - 13227 650155 - 650155 1 A)
1/ 2 4/ 14 13228 - 17108 655367 3881 B)
2/ 2 1/117 13228 - 13251 650156 - 650179 24 C)
2/ 2 2/117 13275 - 13287 650203 - 650215 13
2/ 2 3/117 13348 - 13353 650276 - 650281 6
...
and we resize the fs in such a way that all of those blocks must
be moved down, we do them one at a time. Eventually we move 1-block
extent A) to a lower block, and then follow it with the other
blocks in the next logical offsets from extent C) in the next
interior node B).
The userspace extent code tries to merge, so when it finds that
logical 13228 can be merged with logical 13227 into a single extent,
it does. And so on, all through extent C), up to block 13250 (why
not 13251? [1]), and eventually move the node block as well.
So we end up with this when all the blocks are moved post-resize:
Level Entries Logical Physical Length Flags
...
2/ 2 120/122 13193 - 13193 33220 - 33220 1
2/ 2 121/122 13194 - 13194 33221 - 33221 1
2/ 2 122/122 13227 - 13250 33222 - 33245 24 D)
1/ 2 5/ 19 13228 - 17108 34676 3881 E) ***
2/ 2 1/222 13251 - 13251 33246 - 33246 1 F)
2/ 2 2/222 13275 - 13286 33247 - 33258 12
...
All those adjacent blocks got moved into extent D), which is nice -
but the next interior node E) was never updated to reflect its new
starting point - it says the leaf extents beneath it start at 13228,
when in fact they start at 13251.
So as we move blocks one by one out of original extent C) above, we
need to keep updating C)'s parent node B) for a proper starting point.
fix_parents() does this.
Once the tree is corrupted like this, more corruption can
ensue post-resize, because we traverse the tree by interior nodes,
relying on their start block to know where we are in the tree.
If it gets off, we'll end up inserting blocks into the wrong part
of the tree, etc.
I have a testcase using fsx to create a complex extent tree which
is then moved during resize; it hit this corruption quite easily,
and with this fix, it succeeds.
Note the first hunk in the commit is for going the other way,
moving the last block of an extent to the extent after it; this
needs the same sort of fix-up, although I haven't seen it in
practice.
[1] We leave the last block because a single-block extent is its
own case, and there is no merging code in that case. \o/
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
It turns out that resize2fs uses ext2fs_dup_handle to duplicate fs handles. If
MMP is enabled, this causes both handles to share MMP buffers, which is bad
news when it comes time to free both handles. Change the code to (we hope) fix
this. This prevents resize2fs from failing with a double-free error when
handed a MMP filesystem.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The environment variable EXT2FS_NO_MTAB_OK will suppress the error
code EXT2_NO_MTAB_FILE when the /etc/mtab file can not be found. This
allows the e2fsprogs regression test suite to be run in chroots which
might not have an /etc/mtab file.
By default will still want to complain if the /etc/mtab file is
missing, since we really don't want to discourage distributions and
purveyors of embedded systems from running without an /etc/mtab file.
But if it's missing it only results in a missing sanity check that
might cause file system corruption if the file system is mounted when
programs such as e2fsck, tune2fs, or resize2fs is running, so there is
no potential security problems that might result if this environment
variable is set inappropriately.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Avoid compatibility problems by using the byte swapping functions
defined by e2fsprogs, instead of the ones defined in the system header
files. We use them everywhere else, so we should use them in
kernel-jbd.h too.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Add a test to see if the backtrace() function requires linking in a
library in /usr/lib.
Addresses-Debian-Bug: #708307
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
If secure_getenv() use it in preference to __secure_getenv().
Starting with (e)glibc version 2.17, secure_getenv() exists, while
__secure_getenv() only works with shared library links (where it is a
weak symbol), but not for static links with /lib/libc.a
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This file was never getting compiled, and there is no user of
ext2fs_list_backups() in the e2fsprogs sources. So remove it as a
clean up.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The ext2fs_read_inode_full() function should not use fs->read_inode()
if the caller has requested more than the base 128 byte inode
structure and the inode size is greater than 128 bytes. Otherwise the
caller won't get all of the bytes that they were asking for, since
there's no way for the fs->read_inode override function can know what
the size of the buffer passed to ext2fs_read_inode_full().
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This prevents from SIGSEGV when -s options is used.
Signed-off-by: Tomas Racek <tracek@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Lukas Czerner <lczerner@redhat.com>
New function ext2fs_symlink() doesn't have a prototype in ext2fs.h and
thus debugfs compilation gives warning:
debugfs.c:2219:2: warning: implicit declaration of function 'ext2fs_symlink'
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
parse_num_blocks2() wrongly did:
num << 1;
when log_block_size < 0. That is obviously wrong as such statement has
no effect (and the compiler properly warns about it). Callers expect
returned value to be in bytes when log_block_size < 0 so fix the
statement accordingly.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
ext2fs_llseek() was using lseek instead of lseek64. The
only time it would use lseek64 is if passed an offset that
overflowed 32 bits. This works for SEEK_SET, but not
SEEK_CUR, which can apply a small offset to move the file
pointer past the 32 bit limit.
The code has been changed to instead try lseek64 first, and
fall back to lseek if that fails. It also was doing a
runtime check of the size of off_t. This has been moved to
compile time.
This fixes a problem which would cause e2image when built for
x86-32 to bomb out when used with large file systems.
Signed-off-by: Phillip Susi <psusi@ubuntu.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The ext2fs_{mark,unmark,test}_block_bitmap2() functions understand
about clusters, and will take block numbers and convert them to
clusters before checking the bitmap. The
ext2fs_*_block_bitmap_range2() functions did not do this, which made
them inconsistent. Fortunately, nothing has depended on this
incorrect behavior, and in fact most of the usage of these functions
have only recently been added, and only for optimizations that were
only enabled for non-bigalloc file systems.
So this is a change in previously exported functions, but (a) it
doesn't change the behavior at all for non-bigalloc file systems, and
(b) the change is more likely to fix bugs for bigalloc file systems.
For example, this change fixes a problem with resize2fs and bigalloc
file systems.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Creating symlinks is a complex affair when accounting for slowlinks.
Create a new function, ext2fs_symlink(), modeled after ext2fs_mkdir().
Like ext2fs_mkdir(), ext2fs_symlink() takes on the task of allocating a
new inode and block (for slowlinks), setting up sane default values in
the inode, copying the target path to either the inode (for fastlinks)
or to the first block (for slowlinks), and accounting for the inode and
block stats. Disallow link targets longer than blocksize as the Linux
kernel prevents this.
It does not attempt to expand the parent directory, instead returning
EXT2_ET_DIR_NO_SPACE and leaving it to the caller to expand just as
ext2fs_mkdir() does. Ideally, I think both of these functions should
make a single attempt to expand the directory.
[ Fixed a few bugs discovered when creating a test case for ext2fs_symlink() ]
Signed-off-by: Darren Hart <dvhart@infradead.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Andreas Dilger <adilger@dilger.ca>
To maintain the error codes numbering, we need to pull in the changes
from the 1.43.x development branch for the libext2's error table.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
If the user attemps to create a 512MB cluster, we need to adjust the
defaults to avoid a 32-bit overflow of s_blocks_per_group. Also check
to make sure that the caller of ext2fs_initialize() has not given a
value of s_clusters_per_group that would result in an overflow of
s_blocks_per_group.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
Previously the behavior of parse_num_block2 was undefined if
log_block_size was less than zero. It will now return a number in
units of bytes.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
The addition of MMP code was added in the wrong place, so ret_fs could
get set (and EXT2_FLAG_NOFREE_ON_ERROR was cleared as well, which
could confuse e2fsck which depends on this flag being cleared if
ext2fs_open2() succeeded.)
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
There are a number of places where we multiply a dgrp_t with
s_blocks_per_group expecting that we will get a blk64_t. This
requires a cast, or using the convenience function
ext2fs_group_first_block2().
This audit was suggested by Eric Sandeen.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Use ext2fs_[un]mark_block_range2() functions to reduce the CPU
overhead of resizing large file systems by 45%, primarily by
reducing the time spent in fix_uninit_block_bitmaps().
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Fix up the com_err.texinfo file so it will produce a valid printed
output, by cleaning up some errors in the texinfo file, and updating
texinfo.tex to be consistent with the version in the doc subdirectory.
Also add rules so we can generate pdf and ps files from
com_err.texinfo and libext2fs.texinfo.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The macro for log_err() was written so that it needed to always
have an argument, but GCC was unhappy to have an argument when
none was specified in the format string. Use the CPP "##" to
eat the preceeding comma if no argument is specified.
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Quiet a number of simple compiler warnings:
- pointers not initialized by ext2fs_get_mem()
- return without value in non-void function
- dereferencing type-punned pointers
- unused variables
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
In a number of places, the output format from "make check" is
incorrectly interpreted as compiler warning output (triggered by
the presence of colons and parenthesis in the output). Convert
these lines to similar output that does not trigger false build
warnings.
In the case of the tst_uuid.c program, the "ctime()" output was
difficult to change, but in fact it is better to actually compare
the time-based UUID against wallclock time instead of just printing
the formatted time as a string, so this test is improved.
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Force the use of the static libraries when linking the test program so
that "make check" works when the shared libraries have not been
installed, and so that we test against the version of the libraries in
the source tree.
Reported-by: g.esp@free.fr
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit adds the functionality which had previously only been in
the tst_extents command to debugfs. The debugfs command extent_open
will open extent tree of a particular inode, and enables a series of
commands which will allow the user to interact with the extent tree
directly. Once the extent tree is closed via extent_open(), these
additional commands will be disabled again.
This commit exports two new functions from lib/ext2fs/extent.c which
had previously been statically defined: ext2fs_extent_node_split() and
ext2fs_extent_goto2().
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Previously, ext2fs_extent_fix_parents() would only avoid modifying the
cursor location associated with the extent handle the cursor was
pointed at a leaf node in the extent tree. This is because it saved
the starting logical block number of the current extent, but not the
"level" of the extent (where level 0 is the leaf node, level 1 is the
interior node which points at blocks containing leaf nodes, etc.)
Fix ext2fs_extent_fix_parents() so it is guaranteed to not change the
current extent in the handle even if the current extent is not at the
bottom of the tree.
Also add a fix_extent command to the tst_extents program to make it
easier to test this function.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
An index node's logical start (ei_block) should
match the logical start of the first node (index
or leaf) below it. If we find a node whose start
does not match its parent, fix all of its parents
accordingly.
If it finds such a problem, we'll see:
Pass 1: Checking inodes, blocks, and sizes
Interior extent node level 0 of inode 274258:
Logical start 3666 does not match logical start 4093 at next level. Fix<y>?
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
The current m68k code was buggy for multiple reasons; first the bfset,
et. al commands interpret the bit number as a signed number, not an
unsigned number. Secondly, there were missing memory clobbers. Since
there is no real benefit in using explicit asm's at this point (gcc is
smart enough to optimize the generic C code to use the set/clear/test
bit m68k instruction) fix this bug by removing the m68k specific asm
versions of these functions.
Tested on m68k-linux with e2fsprogs-1.42.6 and gcc-4.6.3 as before.
All tests pass and the debug output looks sane.
I compared the e2fsck binaries from the previous build with this
one. They had identical .text sizes, and almost the same number
of bit field instructions (obviously compiler-generated), so this
change should have no serious performance implications.
Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Schwab <schwab@linux-m68k.org>
Fix a potential memory leak reported by Li Xi. In addition, there
were possible error cases where the file descriptor would not be
properly closed, so fix those as well while we're at it.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reported-by: Li Xi <pkuelelixi@gmail.com>