mirror of https://github.com/vitalif/e2fsprogs
Compare commits
27 Commits
master
...
debian-1.4
Author | SHA1 | Date |
---|---|---|
Theodore Ts'o | 1944d8c53d | |
Theodore Ts'o | 20cdfde28f | |
Theodore Ts'o | 24c6cf26e5 | |
Theodore Ts'o | 4829ce0958 | |
Theodore Ts'o | 02765bf7d3 | |
Theodore Ts'o | 25c4a206a4 | |
Theodore Ts'o | 023e1d403b | |
Theodore Ts'o | 89351df69d | |
Theodore Ts'o | e6fcb8f09f | |
Theodore Ts'o | 12147857a0 | |
Theodore Ts'o | 39e05c5672 | |
Theodore Ts'o | cdf396a039 | |
Theodore Ts'o | c59935dc92 | |
Theodore Ts'o | 4fa126b596 | |
Theodore Ts'o | 89615d3ad1 | |
Theodore Ts'o | 602432f38c | |
Theodore Ts'o | d04897df10 | |
Theodore Ts'o | 97c76e0f09 | |
Theodore Ts'o | 64f5a8f084 | |
Theodore Ts'o | e31b4e03ee | |
Theodore Ts'o | 8fce6511d9 | |
Theodore Ts'o | c414e897ef | |
Theodore Ts'o | d3a2ca5cde | |
Theodore Ts'o | 3e53f0f427 | |
Theodore Ts'o | 73fb183d03 | |
Theodore Ts'o | 350497fe84 | |
Theodore Ts'o | 79ac4caa77 |
|
@ -5,7 +5,6 @@ build.static
|
||||||
FILES
|
FILES
|
||||||
^core
|
^core
|
||||||
*~
|
*~
|
||||||
patches
|
|
||||||
Makefile
|
Makefile
|
||||||
*.bak
|
*.bak
|
||||||
*.diff
|
*.diff
|
||||||
|
@ -161,8 +160,6 @@ misc/e2initrd_helper
|
||||||
misc/e2label.8
|
misc/e2label.8
|
||||||
misc/e2undo
|
misc/e2undo
|
||||||
misc/e2undo.8
|
misc/e2undo.8
|
||||||
misc/e2patch
|
|
||||||
misc/e2patch.8
|
|
||||||
misc/e4defrag
|
misc/e4defrag
|
||||||
misc/e4defrag.8
|
misc/e4defrag.8
|
||||||
misc/ext4.5
|
misc/ext4.5
|
||||||
|
|
|
@ -68,8 +68,8 @@ pkgconfigdir = $(libdir)/pkgconfig
|
||||||
@ifGNUmake@ endif
|
@ifGNUmake@ endif
|
||||||
@ifGNUmake@ endif
|
@ifGNUmake@ endif
|
||||||
|
|
||||||
@ifNotGNUmake@ CHECK_CMD=true
|
@ifNotGNUmake@ CHECK_CMD=@true
|
||||||
@ifNotGNUmake@ CPPCHECK_CMD=true
|
@ifNotGNUmake@ CPPHECK_CMD=@true
|
||||||
|
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
BUILD_CC = @BUILD_CC@
|
BUILD_CC = @BUILD_CC@
|
||||||
|
|
2
README
2
README
|
@ -1,4 +1,4 @@
|
||||||
This is the new version (1.43.3) of the second extended file
|
This is the new version (1.43.2) of the second extended file
|
||||||
system management programs.
|
system management programs.
|
||||||
|
|
||||||
From time to time, I release new versions of e2fsprogs, to fix
|
From time to time, I release new versions of e2fsprogs, to fix
|
||||||
|
|
|
@ -1,31 +1,3 @@
|
||||||
E2fsprogs 1.43.3 (September 4, 2016)
|
|
||||||
====================================
|
|
||||||
|
|
||||||
Fix e2fsck's handling of timestamps on 32-bit systems.
|
|
||||||
|
|
||||||
E2fsck will now check, and if necessary repair the extra isize fields
|
|
||||||
in the inode and superblock.
|
|
||||||
|
|
||||||
Fix crashes on architectures such as sparc64 that are sensitive to
|
|
||||||
unaligned pointer derferences in the journal recovery code when
|
|
||||||
journal checksums are enabled.
|
|
||||||
|
|
||||||
Programming notes
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Support reproducible builds by not capturing the build directory into
|
|
||||||
the mk_cmds and compile_et scripts. Also fix debian build rules to
|
|
||||||
ensure build reproducibility.
|
|
||||||
|
|
||||||
Fix debian build rules to ensure build reproducibility and to avoid
|
|
||||||
hiding the linker flags for e2fsck.static so the build hardening log
|
|
||||||
scanner can properly audit the build.
|
|
||||||
|
|
||||||
Fix compatibility with FreeBSD's pmake and teach the configure script
|
|
||||||
to force the creation of pmake-compatible Makefiles if the
|
|
||||||
FORCE_NATIVE_MAKE environment variable is set to a non-empty value.
|
|
||||||
|
|
||||||
|
|
||||||
E2fsprogs 1.43.2 (September 1, 2016)
|
E2fsprogs 1.43.2 (September 1, 2016)
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
|
|
|
@ -108,12 +108,7 @@ AC_DEFUN(
|
||||||
[CHECK_GNU_MAKE], [ AC_CACHE_CHECK( for GNU make,_cv_gnu_make_command,
|
[CHECK_GNU_MAKE], [ AC_CACHE_CHECK( for GNU make,_cv_gnu_make_command,
|
||||||
_cv_gnu_make_command='' ;
|
_cv_gnu_make_command='' ;
|
||||||
dnl Search all the common names for GNU make
|
dnl Search all the common names for GNU make
|
||||||
if test -n "$FORCE_NATIVE_MAKE" ; then
|
for a in "$MAKE" make gmake gnumake ; do
|
||||||
MAKES="make"
|
|
||||||
else
|
|
||||||
MAKES="make gmake gnumake"
|
|
||||||
fi
|
|
||||||
for a in "$MAKE" $MAKES ; do
|
|
||||||
if test -z "$a" ; then continue ; fi ;
|
if test -z "$a" ; then continue ; fi ;
|
||||||
if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then
|
if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then
|
||||||
_cv_gnu_make_command=$a ;
|
_cv_gnu_make_command=$a ;
|
||||||
|
|
|
@ -11515,12 +11515,7 @@ if ${_cv_gnu_make_command+:} false; then :
|
||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
else
|
else
|
||||||
_cv_gnu_make_command='' ;
|
_cv_gnu_make_command='' ;
|
||||||
if test -n "$FORCE_NATIVE_MAKE" ; then
|
for a in "$MAKE" make gmake gnumake ; do
|
||||||
MAKES="make"
|
|
||||||
else
|
|
||||||
MAKES="make gmake gnumake"
|
|
||||||
fi
|
|
||||||
for a in "$MAKE" $MAKES ; do
|
|
||||||
if test -z "$a" ; then continue ; fi ;
|
if test -z "$a" ; then continue ; fi ;
|
||||||
if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then
|
if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then
|
||||||
_cv_gnu_make_command=$a ;
|
_cv_gnu_make_command=$a ;
|
||||||
|
|
|
@ -1,13 +1,3 @@
|
||||||
e2fsprogs (1.43.3-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Fix e2fsck's handling of timestamps on 32-bit system (Closes: #836559)
|
|
||||||
* E2fsck will sanity check and repair the extra isize fields in inodes
|
|
||||||
and the superblock.
|
|
||||||
* Fix sparc64 crashes when dereferencing unaligned integers in journal
|
|
||||||
blocks when metdata checksums are enabled.
|
|
||||||
|
|
||||||
-- Theodore Y. Ts'o <tytso@mit.edu> Sun, 04 Sep 2016 20:41:21 -0400
|
|
||||||
|
|
||||||
e2fsprogs (1.43.2-2) unstable; urgency=medium
|
e2fsprogs (1.43.2-2) unstable; urgency=medium
|
||||||
|
|
||||||
* Fix build reproducibility problems
|
* Fix build reproducibility problems
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
Description: Enable metadata_csum by default
|
||||||
|
For debian testing let's be more aggressive about testing the
|
||||||
|
metadata_csum feature.
|
||||||
|
From: Theodore Y. Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
|
--- e2fsprogs-1.43.orig/misc/mke2fs.conf.in
|
||||||
|
+++ e2fsprogs-1.43/misc/mke2fs.conf.in
|
||||||
|
@@ -11,11 +11,11 @@
|
||||||
|
features = has_journal
|
||||||
|
}
|
||||||
|
ext4 = {
|
||||||
|
- features = has_journal,extent,huge_file,flex_bg,64bit,dir_nlink,extra_isize
|
||||||
|
+ features = has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize
|
||||||
|
inode_size = 256
|
||||||
|
}
|
||||||
|
ext4dev = {
|
||||||
|
- features = has_journal,extent,huge_file,flex_bg,inline_data,64bit,dir_nlink,extra_isize
|
||||||
|
+ features = has_journal,extent,huge_file,flex_bg,metadata_csum,inline_data,64bit,dir_nlink,extra_isize
|
||||||
|
inode_size = 256
|
||||||
|
options = test_fs=1
|
||||||
|
}
|
|
@ -0,0 +1,262 @@
|
||||||
|
Description: Fix build reproducibility for mk_cmds and compile_et
|
||||||
|
The mk_cmds and compile_et scripts include the build directory, which
|
||||||
|
breaks the build reproducibility goal of Debian.
|
||||||
|
From: Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index 03e24d1..0ac5dcb 100755
|
||||||
|
--- a/configure
|
||||||
|
+++ b/configure
|
||||||
|
@@ -633,8 +633,6 @@ BUILD_CFLAGS
|
||||||
|
MKINSTALLDIRS
|
||||||
|
INCLUDES
|
||||||
|
DO_TEST_SUITE
|
||||||
|
-ET_DIR
|
||||||
|
-SS_DIR
|
||||||
|
LDFLAGS_STATIC
|
||||||
|
root_sysconfdir
|
||||||
|
root_libdir
|
||||||
|
@@ -13805,10 +13803,6 @@ $as_echo "#define _INTL_REDIRECT_MACROS 1" >>confdefs.h
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
-SS_DIR=`cd ${srcdir}/lib/ss; pwd`
|
||||||
|
-ET_DIR=`cd ${srcdir}/lib/et; pwd`
|
||||||
|
-
|
||||||
|
-
|
||||||
|
if test "$cross_compiling" = yes ; then
|
||||||
|
DO_TEST_SUITE=
|
||||||
|
else
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index a387dfd..1c73301 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -1400,13 +1400,6 @@ darwin*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
dnl
|
||||||
|
-dnl Make the ss and et directories work correctly.
|
||||||
|
-dnl
|
||||||
|
-SS_DIR=`cd ${srcdir}/lib/ss; pwd`
|
||||||
|
-ET_DIR=`cd ${srcdir}/lib/et; pwd`
|
||||||
|
-AC_SUBST(SS_DIR)
|
||||||
|
-AC_SUBST(ET_DIR)
|
||||||
|
-dnl
|
||||||
|
dnl Only try to run the test suite if we're not cross compiling.
|
||||||
|
dnl
|
||||||
|
if test "$cross_compiling" = yes ; then
|
||||||
|
diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
|
||||||
|
index c22b8c0..a3fe13e 100644
|
||||||
|
--- a/debugfs/Makefile.in
|
||||||
|
+++ b/debugfs/Makefile.in
|
||||||
|
@@ -14,7 +14,7 @@ INSTALL = @INSTALL@
|
||||||
|
PROGS= debugfs
|
||||||
|
MANPAGES= debugfs.8
|
||||||
|
|
||||||
|
-MK_CMDS= _SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds
|
||||||
|
+MK_CMDS= _SS_DIR_OVERRIDE=$(srcdir)/../lib/ss ../lib/ss/mk_cmds
|
||||||
|
|
||||||
|
DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
|
||||||
|
lsdel.o dump.o set_fields.o logdump.o htree.o unused.o e2freefrag.o \
|
||||||
|
diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in
|
||||||
|
index 06d9f55..6f626f4 100644
|
||||||
|
--- a/e2fsck/Makefile.in
|
||||||
|
+++ b/e2fsck/Makefile.in
|
||||||
|
@@ -34,7 +34,7 @@ PROFILED_DEPLIBS= $(DEPPROFILED_LIBSUPPORT) $(PROFILED_LIBEXT2FS) \
|
||||||
|
$(DEPPROFILED_LIBCOM_ERR) $(DEPPROFILED_LIBBLKID) \
|
||||||
|
$(DEPPROFILED_LIBUUID) $(DEPPROFILED_LIBE2P)
|
||||||
|
|
||||||
|
-COMPILE_ET=$(top_builddir)/lib/et/compile_et --build-tree
|
||||||
|
+COMPILE_ET= _ET_DIR_OVERRIDE=$(srcdir)/../lib/et/et ../lib/et/compile_et
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(E) " CC $<"
|
||||||
|
diff --git a/lib/et/Makefile.in b/lib/et/Makefile.in
|
||||||
|
index cb75ab8..476f189 100644
|
||||||
|
--- a/lib/et/Makefile.in
|
||||||
|
+++ b/lib/et/Makefile.in
|
||||||
|
@@ -140,7 +140,7 @@ uninstall::
|
||||||
|
check:: compile_et
|
||||||
|
for i in $(srcdir)/test_cases/*.et ; do \
|
||||||
|
t=`basename $$i | sed -e 's/.et//'`; \
|
||||||
|
- ./compile_et --build-tree $$i ; \
|
||||||
|
+ _ET_DIR_OVERRIDE=$(srcdir) ./compile_et $$i ; \
|
||||||
|
diff -c $(srcdir)/test_cases/$$t.c $$t.c > $$t.failed; \
|
||||||
|
if [ $$? -ne 0 ]; then echo Test case $$t failed; exit 1 ; fi ; \
|
||||||
|
diff -c $(srcdir)/test_cases/$$t.h $$t.h >> $$t.failed; \
|
||||||
|
diff --git a/lib/et/compile_et.sh.in b/lib/et/compile_et.sh.in
|
||||||
|
index c2861f4..4c4ba17 100644
|
||||||
|
--- a/lib/et/compile_et.sh.in
|
||||||
|
+++ b/lib/et/compile_et.sh.in
|
||||||
|
@@ -4,8 +4,7 @@
|
||||||
|
|
||||||
|
datarootdir=@datarootdir@
|
||||||
|
AWK=@AWK@
|
||||||
|
-DIR="${DIR-@datadir@/et}"
|
||||||
|
-ET_DIR="${ET_DIR-@ET_DIR@}"
|
||||||
|
+DIR=@datadir@/et
|
||||||
|
|
||||||
|
if test "$1" = "--build-tree" ; then
|
||||||
|
shift;
|
||||||
|
@@ -29,13 +28,13 @@ do
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
+if test -n "$_ET_DIR_OVERRIDE" ; then
|
||||||
|
+ DIR="$_ET_DIR_OVERRIDE";
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
if test ! -f "$DIR/et_h.awk" || test ! -f "$DIR/et_c.awk" ; then
|
||||||
|
- DIR="$ET_DIR"
|
||||||
|
-# echo "Falling back to $DIR..."
|
||||||
|
- if test ! -f "$DIR/et_h.awk" || test ! -f "$DIR/et_c.awk" ; then
|
||||||
|
- echo "compile_et: Couldn't find compile_et's template files."
|
||||||
|
- exit 1
|
||||||
|
- fi
|
||||||
|
+ echo "compile_et: Couldn't find compile_et's template files."
|
||||||
|
+ exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ROOT=`echo $1 | sed -e s/.et$//`
|
||||||
|
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
|
||||||
|
index 461920c..6a3656d 100644
|
||||||
|
--- a/lib/ext2fs/Makefile.in
|
||||||
|
+++ b/lib/ext2fs/Makefile.in
|
||||||
|
@@ -13,7 +13,8 @@ DEBUGFS_CFLAGS = -I$(srcdir)/../../e2fsck $(ALL_CFLAGS) -DDEBUGFS
|
||||||
|
|
||||||
|
@DEBUGFS_CMT@DEBUGFS_LIB_OBJS = bb_compat.o inode_io.o write_bb_file.o
|
||||||
|
|
||||||
|
-MK_CMDS= _SS_DIR_OVERRIDE=../ss ../ss/mk_cmds
|
||||||
|
+MK_CMDS= _SS_DIR_OVERRIDE=$(srcdir)/../ss ../ss/mk_cmds
|
||||||
|
+COMPILE_ET= _ET_DIR_OVERRIDE=$(srcdir)/../et ../et/compile_et
|
||||||
|
|
||||||
|
@RESIZER_CMT@RESIZE_LIB_OBJS = dupfs.o
|
||||||
|
@TEST_IO_CMT@TEST_IO_LIB_OBJS = test_io.o
|
||||||
|
@@ -254,8 +255,6 @@ all:: ext2fs.pc
|
||||||
|
@ELF_CMT@ $(Q) $(CC) $(ALL_CFLAGS_SHLIB) -fPIC -shared -o elfshared/$*.o -c $<
|
||||||
|
@BSDLIB_CMT@ $(Q) $(CC) $(ALL_CFLAGS_SHLIB) $(BSDLIB_PIC_FLAG) -o pic/$*.o -c $<
|
||||||
|
|
||||||
|
-COMPILE_ET=../et/compile_et --build-tree
|
||||||
|
-
|
||||||
|
DISTFILES= Makefile *.c *.h image
|
||||||
|
|
||||||
|
ext2_err.et: $(DEP_SUBSTITUTE) $(srcdir)/ext2_err.et.in
|
||||||
|
diff --git a/lib/ss/Makefile.in b/lib/ss/Makefile.in
|
||||||
|
index 255b58b..f4953f0 100644
|
||||||
|
--- a/lib/ss/Makefile.in
|
||||||
|
+++ b/lib/ss/Makefile.in
|
||||||
|
@@ -28,8 +28,8 @@ BSDLIB_MYDIR = ss
|
||||||
|
BSDLIB_INSTALL_DIR = $(root_libdir)
|
||||||
|
|
||||||
|
TAGS=etags
|
||||||
|
-COMPILE_ET=../et/compile_et --build-tree
|
||||||
|
-MK_CMDS=_SS_DIR_OVERRIDE=. ./mk_cmds
|
||||||
|
+MK_CMDS= _SS_DIR_OVERRIDE=$(srcdir) ./mk_cmds
|
||||||
|
+COMPILE_ET= _ET_DIR_OVERRIDE=$(srcdir)/../et ../et/compile_et
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(E) " CC $<"
|
||||||
|
diff --git a/lib/ss/mk_cmds.sh.in b/lib/ss/mk_cmds.sh.in
|
||||||
|
index a8976a4..0abc19d 100644
|
||||||
|
--- a/lib/ss/mk_cmds.sh.in
|
||||||
|
+++ b/lib/ss/mk_cmds.sh.in
|
||||||
|
@@ -3,8 +3,7 @@
|
||||||
|
#
|
||||||
|
|
||||||
|
datarootdir=@datarootdir@
|
||||||
|
-DIR="${DIR-@datadir@/ss}"
|
||||||
|
-SS_DIR="@SS_DIR@"
|
||||||
|
+DIR=@datadir@/ss
|
||||||
|
AWK=@AWK@
|
||||||
|
SED=@SED@
|
||||||
|
|
||||||
|
@@ -30,12 +29,8 @@ if test -n "$_SS_DIR_OVERRIDE" ; then
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test ! -f $DIR/ct_c.sed || test ! -f $DIR/ct_c.awk ; then
|
||||||
|
- DIR="$SS_DIR"
|
||||||
|
-# echo "Falling back to $DIR..."
|
||||||
|
- if test ! -f "$DIR/ct_c.sed" || test ! -f "$DIR/ct_c.awk" ; then
|
||||||
|
- echo "mk_cmds: Couldn't find mk_cmds's template files."
|
||||||
|
- exit 1
|
||||||
|
- fi
|
||||||
|
+ echo "mk_cmds: Couldn't find mk_cmds's template files."
|
||||||
|
+ exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILE="$1"
|
||||||
|
diff --git a/lib/support/Makefile.in b/lib/support/Makefile.in
|
||||||
|
index 5beaaac..112ba24 100644
|
||||||
|
--- a/lib/support/Makefile.in
|
||||||
|
+++ b/lib/support/Makefile.in
|
||||||
|
@@ -41,7 +41,7 @@ LIBDIR= support
|
||||||
|
@MAKEFILE_LIBRARY@
|
||||||
|
@MAKEFILE_PROFILE@
|
||||||
|
|
||||||
|
-COMPILE_ET=$(top_builddir)/lib/et/compile_et --build-tree
|
||||||
|
+COMPILE_ET= _ET_DIR_OVERRIDE=$(srcdir)/../et ../et/compile_et
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(E) " CC $<"
|
||||||
|
diff --git a/misc/Makefile.in b/misc/Makefile.in
|
||||||
|
index e487692..d6436c2 100644
|
||||||
|
--- a/misc/Makefile.in
|
||||||
|
+++ b/misc/Makefile.in
|
||||||
|
@@ -115,7 +115,7 @@ STATIC_DEPLIBS= $(DEPLIBSUPPORT) $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
|
||||||
|
LIBS_E2P= $(LIBE2P) $(LIBCOM_ERR)
|
||||||
|
DEPLIBS_E2P= $(LIBE2P) $(DEPLIBCOM_ERR)
|
||||||
|
|
||||||
|
-COMPILE_ET=$(top_builddir)/lib/et/compile_et --build-tree
|
||||||
|
+COMPILE_ET= _ET_DIR_OVERRIDE=$(srcdir)/../lib/et/et ../lib/et/compile_et
|
||||||
|
|
||||||
|
# This nastyness is needed because of jfs_user.h hackery; when we finally
|
||||||
|
# clean up this mess, we should be able to drop it
|
||||||
|
diff --git a/tests/progs/Makefile.in b/tests/progs/Makefile.in
|
||||||
|
index 22d9417..f6a31b9 100644
|
||||||
|
--- a/tests/progs/Makefile.in
|
||||||
|
+++ b/tests/progs/Makefile.in
|
||||||
|
@@ -11,7 +11,7 @@ INSTALL = @INSTALL@
|
||||||
|
|
||||||
|
@MCONFIG@
|
||||||
|
|
||||||
|
-MK_CMDS= _SS_DIR_OVERRIDE=../../lib/ss ../../lib/ss/mk_cmds
|
||||||
|
+MK_CMDS= _SS_DIR_OVERRIDE=$(srcdir)/../../lib/ss ../../lib/ss/mk_cmds
|
||||||
|
|
||||||
|
PROGS= test_icount crcsum
|
||||||
|
|
||||||
|
diff --git a/util/gen-android-files b/util/gen-android-files
|
||||||
|
index 994337b..ebd8778 100755
|
||||||
|
--- a/util/gen-android-files
|
||||||
|
+++ b/util/gen-android-files
|
||||||
|
@@ -14,8 +14,8 @@ ANDROID_GENERATED_FILES="lib/ext2fs/ext2_err.c lib/ext2fs/ext2_err.h \
|
||||||
|
SS_DIR=$(pwd)/lib/ss
|
||||||
|
MK_CMDS=/tmp/mk_cmds$$.sh
|
||||||
|
|
||||||
|
-sed -e "s;@SS_DIR@;$SS_DIR;" < $SS_DIR/mk_cmds.sh.in \
|
||||||
|
- | sed -e "s/@AWK@/awk/" | sed -e "s/@SED@/sed/" > $MK_CMDS
|
||||||
|
+sed -e "s/@AWK@/awk/" < $SS_DIR/mk_cmds.sh.in \
|
||||||
|
+ | sed -e "s/@SED@/sed/" > $MK_CMDS
|
||||||
|
|
||||||
|
sed -e "s/@E2FSPROGS_VERSION@/$(git describe)/" < lib/ext2fs/ext2_err.et.in > lib/ext2fs/ext2_err.et
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ done
|
||||||
|
for i in lib/ss/std_rqs debugfs/debug_cmds debugfs/ro_debug_cmds \
|
||||||
|
debugfs/extent_cmds
|
||||||
|
do
|
||||||
|
- /bin/sh $MK_CMDS $i.ct
|
||||||
|
+ _SS_DIR_OVERRIDE=lib/ss /bin/sh $MK_CMDS $i.ct
|
||||||
|
mv -f $(basename $i).c $i.c
|
||||||
|
done
|
||||||
|
|
||||||
|
diff --git a/util/subst.conf.in b/util/subst.conf.in
|
||||||
|
index ada11e7..fbc044d 100644
|
||||||
|
--- a/util/subst.conf.in
|
||||||
|
+++ b/util/subst.conf.in
|
||||||
|
@@ -1,7 +1,5 @@
|
||||||
|
AWK @AWK@
|
||||||
|
SED @SED@
|
||||||
|
-ET_DIR @ET_DIR@
|
||||||
|
-SS_DIR @SS_DIR@
|
||||||
|
E2FSPROGS_MONTH @E2FSPROGS_MONTH@
|
||||||
|
E2FSPROGS_YEAR @E2FSPROGS_YEAR@
|
||||||
|
E2FSPROGS_VERSION @E2FSPROGS_VERSION@
|
|
@ -0,0 +1,2 @@
|
||||||
|
enable-metadata_csum-by-default
|
||||||
|
fix-build-reproducibility-in-mk_cmds-and-compile_et
|
|
@ -1,7 +1,7 @@
|
||||||
\input texinfo @c -*-texinfo-*-
|
\input texinfo @c -*-texinfo-*-
|
||||||
@c %**start of header
|
@c %**start of header
|
||||||
@setfilename libext2fs.info
|
@setfilename libext2fs.info
|
||||||
@settitle The EXT2FS Library (version 1.43.3)
|
@settitle The EXT2FS Library (version 1.43.2)
|
||||||
@synindex tp fn
|
@synindex tp fn
|
||||||
@comment %**end of header
|
@comment %**end of header
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ by the author.
|
||||||
|
|
||||||
@title The EXT2FS Library
|
@title The EXT2FS Library
|
||||||
@subtitle The EXT2FS Library
|
@subtitle The EXT2FS Library
|
||||||
@subtitle Version 1.43.3
|
@subtitle Version 1.43.2
|
||||||
@subtitle September 2016
|
@subtitle September 2016
|
||||||
|
|
||||||
@author by Theodore Ts'o
|
@author by Theodore Ts'o
|
||||||
|
@ -101,7 +101,7 @@ by the Foundation.
|
||||||
|
|
||||||
@top The EXT2FS Library
|
@top The EXT2FS Library
|
||||||
|
|
||||||
This manual documents the EXT2FS Library, version 1.43.3.
|
This manual documents the EXT2FS Library, version 1.43.2.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Introduction to the EXT2FS Library::
|
* Introduction to the EXT2FS Library::
|
||||||
|
|
|
@ -345,12 +345,6 @@ or
|
||||||
.B \-p
|
.B \-p
|
||||||
options.
|
options.
|
||||||
.TP
|
.TP
|
||||||
.BI \-T " patch_file"
|
|
||||||
Do not apply changes to the real filesystem; write updates into a sparse file
|
|
||||||
named 'patch_file' to safely apply them later with e2patch(8) utility.
|
|
||||||
You'll also be able to create a backup before applying patch and safely
|
|
||||||
restore it in case of power outage or system crash.
|
|
||||||
.TP
|
|
||||||
.BI \-z " undo_file"
|
.BI \-z " undo_file"
|
||||||
Before overwriting a file system block, write the old contents of the block to
|
Before overwriting a file system block, write the old contents of the block to
|
||||||
an undo file. This undo file can be used with e2undo(8) to restore the old
|
an undo file. This undo file can be used with e2undo(8) to restore the old
|
||||||
|
|
|
@ -391,9 +391,6 @@ struct e2fsck_struct {
|
||||||
*/
|
*/
|
||||||
ext2fs_inode_bitmap inodes_to_rebuild;
|
ext2fs_inode_bitmap inodes_to_rebuild;
|
||||||
|
|
||||||
/* Patch file */
|
|
||||||
char *patch_file;
|
|
||||||
|
|
||||||
/* Undo file */
|
/* Undo file */
|
||||||
char *undo_file;
|
char *undo_file;
|
||||||
};
|
};
|
||||||
|
|
|
@ -488,14 +488,10 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
|
||||||
* implementations should never allow i_extra_isize to be 0
|
* implementations should never allow i_extra_isize to be 0
|
||||||
*/
|
*/
|
||||||
if (inode->i_extra_isize &&
|
if (inode->i_extra_isize &&
|
||||||
(inode->i_extra_isize < min || inode->i_extra_isize > max ||
|
(inode->i_extra_isize < min || inode->i_extra_isize > max)) {
|
||||||
inode->i_extra_isize & 3)) {
|
|
||||||
if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
|
if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
|
||||||
return;
|
return;
|
||||||
if (inode->i_extra_isize < min || inode->i_extra_isize > max)
|
inode->i_extra_isize = min;
|
||||||
inode->i_extra_isize = sb->s_want_extra_isize;
|
|
||||||
else
|
|
||||||
inode->i_extra_isize = (inode->i_extra_isize + 3) & ~3;
|
|
||||||
e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
|
e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
|
||||||
EXT2_INODE_SIZE(sb), "pass1");
|
EXT2_INODE_SIZE(sb), "pass1");
|
||||||
return;
|
return;
|
||||||
|
@ -516,9 +512,9 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
|
||||||
* If the inode's extended atime (ctime, crtime, mtime) is stored in
|
* If the inode's extended atime (ctime, crtime, mtime) is stored in
|
||||||
* the old, invalid format, repair it.
|
* the old, invalid format, repair it.
|
||||||
*/
|
*/
|
||||||
if (((sizeof(time_t) <= 4) ||
|
if ((sizeof(time_t) <= 4) ||
|
||||||
(((sizeof(time_t) > 4) &&
|
(((sizeof(time_t) > 4) &&
|
||||||
ctx->now < EXT4_EXTRA_NEGATIVE_DATE_CUTOFF))) &&
|
ctx->now < EXT4_EXTRA_NEGATIVE_DATE_CUTOFF)) &&
|
||||||
(CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, atime) ||
|
(CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, atime) ||
|
||||||
CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, ctime) ||
|
CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, ctime) ||
|
||||||
CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, crtime) ||
|
CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, crtime) ||
|
||||||
|
|
|
@ -477,16 +477,6 @@ static struct e2fsck_problem problem_table[] = {
|
||||||
N_("Error initializing quota context in support library: %m\n"),
|
N_("Error initializing quota context in support library: %m\n"),
|
||||||
PROMPT_NULL, PR_FATAL },
|
PROMPT_NULL, PR_FATAL },
|
||||||
|
|
||||||
/* Bad s_min_extra_isize in superblock */
|
|
||||||
{ PR_0_BAD_MIN_EXTRA_ISIZE,
|
|
||||||
N_("Bad required extra isize in @S (%N). "),
|
|
||||||
PROMPT_FIX, 0 },
|
|
||||||
|
|
||||||
/* Bad s_min_extra_isize in superblock */
|
|
||||||
{ PR_0_BAD_WANT_EXTRA_ISIZE,
|
|
||||||
N_("Bad desired extra isize in @S (%N). "),
|
|
||||||
PROMPT_FIX, 0 },
|
|
||||||
|
|
||||||
/* Pass 1 errors */
|
/* Pass 1 errors */
|
||||||
|
|
||||||
/* Pass 1: Checking inodes, blocks, and sizes */
|
/* Pass 1: Checking inodes, blocks, and sizes */
|
||||||
|
|
|
@ -274,12 +274,6 @@ struct problem_context {
|
||||||
/* Error initializing quota context */
|
/* Error initializing quota context */
|
||||||
#define PR_0_QUOTA_INIT_CTX 0x00004C
|
#define PR_0_QUOTA_INIT_CTX 0x00004C
|
||||||
|
|
||||||
/* Bad s_min_extra_isize in superblock */
|
|
||||||
#define PR_0_BAD_MIN_EXTRA_ISIZE 0x00004D
|
|
||||||
|
|
||||||
/* Bad s_want_extra_isize in superblock */
|
|
||||||
#define PR_0_BAD_WANT_EXTRA_ISIZE 0x00004E
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pass 1 errors
|
* Pass 1 errors
|
||||||
|
|
|
@ -338,24 +338,12 @@ int journal_skip_recovery(journal_t *journal)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __u32 get_be32(__be32 *p)
|
|
||||||
{
|
|
||||||
unsigned char *cp = (unsigned char *) p;
|
|
||||||
__u32 ret;
|
|
||||||
|
|
||||||
ret = *cp++;
|
|
||||||
ret = (ret << 8) + *cp++;
|
|
||||||
ret = (ret << 8) + *cp++;
|
|
||||||
ret = (ret << 8) + *cp++;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long long read_tag_block(journal_t *journal,
|
static inline unsigned long long read_tag_block(journal_t *journal,
|
||||||
journal_block_tag_t *tag)
|
journal_block_tag_t *tag)
|
||||||
{
|
{
|
||||||
unsigned long long block = get_be32(&tag->t_blocknr);
|
unsigned long long block = ext2fs_be32_to_cpu(tag->t_blocknr);
|
||||||
if (jfs_has_feature_64bit(journal))
|
if (jfs_has_feature_64bit(journal))
|
||||||
block |= (u64)get_be32(&tag->t_blocknr_high) << 32;
|
block |= (u64)ext2fs_be32_to_cpu(tag->t_blocknr_high) << 32;
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -578,34 +578,6 @@ void check_super_block(e2fsck_t ctx)
|
||||||
ext2fs_mark_super_dirty(fs);
|
ext2fs_mark_super_dirty(fs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (EXT2_INODE_SIZE(sb) > EXT2_GOOD_OLD_INODE_SIZE) {
|
|
||||||
unsigned min =
|
|
||||||
sizeof(((struct ext2_inode_large *) 0)->i_extra_isize) +
|
|
||||||
sizeof(((struct ext2_inode_large *) 0)->i_checksum_hi);
|
|
||||||
unsigned max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
|
|
||||||
pctx.num = sb->s_min_extra_isize;
|
|
||||||
if (sb->s_min_extra_isize &&
|
|
||||||
(sb->s_min_extra_isize < min ||
|
|
||||||
sb->s_min_extra_isize > max ||
|
|
||||||
sb->s_min_extra_isize & 3) &&
|
|
||||||
fix_problem(ctx, PR_0_BAD_MIN_EXTRA_ISIZE, &pctx)) {
|
|
||||||
sb->s_min_extra_isize =
|
|
||||||
(sizeof(struct ext2_inode_large) -
|
|
||||||
EXT2_GOOD_OLD_INODE_SIZE);
|
|
||||||
ext2fs_mark_super_dirty(fs);
|
|
||||||
}
|
|
||||||
pctx.num = sb->s_want_extra_isize;
|
|
||||||
if (sb->s_want_extra_isize &&
|
|
||||||
(sb->s_want_extra_isize < min ||
|
|
||||||
sb->s_want_extra_isize > max ||
|
|
||||||
sb->s_want_extra_isize & 3) &&
|
|
||||||
fix_problem(ctx, PR_0_BAD_WANT_EXTRA_ISIZE, &pctx)) {
|
|
||||||
sb->s_want_extra_isize =
|
|
||||||
(sizeof(struct ext2_inode_large) -
|
|
||||||
EXT2_GOOD_OLD_INODE_SIZE);
|
|
||||||
ext2fs_mark_super_dirty(fs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Are metadata_csum and uninit_bg both set? */
|
/* Are metadata_csum and uninit_bg both set? */
|
||||||
if (ext2fs_has_feature_metadata_csum(fs->super) &&
|
if (ext2fs_has_feature_metadata_csum(fs->super) &&
|
||||||
|
|
|
@ -76,7 +76,7 @@ static void usage(e2fsck_t ctx)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("Usage: %s [-panyrcdfktvDFV] [-b superblock] [-B blocksize]\n"
|
_("Usage: %s [-panyrcdfktvDFV] [-b superblock] [-B blocksize]\n"
|
||||||
"\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\n"
|
"\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\n"
|
||||||
"\t\t[-E extended-options] [-T patch_file] [-z undo_file] device\n"),
|
"\t\t[-E extended-options] [-z undo_file] device\n"),
|
||||||
ctx->program_name);
|
ctx->program_name);
|
||||||
|
|
||||||
fprintf(stderr, "%s", _("\nEmergency help:\n"
|
fprintf(stderr, "%s", _("\nEmergency help:\n"
|
||||||
|
@ -92,7 +92,6 @@ static void usage(e2fsck_t ctx)
|
||||||
" -j external_journal Set location of the external journal\n"
|
" -j external_journal Set location of the external journal\n"
|
||||||
" -l bad_blocks_file Add to badblocks list\n"
|
" -l bad_blocks_file Add to badblocks list\n"
|
||||||
" -L bad_blocks_file Set badblocks list\n"
|
" -L bad_blocks_file Set badblocks list\n"
|
||||||
" -T patch_file Create a patch file instead of applying changes to real FS\n"
|
|
||||||
" -z undo_file Create an undo file\n"
|
" -z undo_file Create an undo file\n"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -805,7 +804,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
||||||
|
|
||||||
phys_mem_kb = get_memory_size() / 1024;
|
phys_mem_kb = get_memory_size() / 1024;
|
||||||
ctx->readahead_kb = ~0ULL;
|
ctx->readahead_kb = ~0ULL;
|
||||||
while ((c = getopt(argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDkT:z:")) != EOF)
|
while ((c = getopt(argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDkz:")) != EOF)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'C':
|
case 'C':
|
||||||
ctx->progress = e2fsck_update_progress;
|
ctx->progress = e2fsck_update_progress;
|
||||||
|
@ -937,9 +936,6 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
||||||
case 'k':
|
case 'k':
|
||||||
keep_bad_blocks++;
|
keep_bad_blocks++;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
|
||||||
ctx->patch_file = optarg;
|
|
||||||
break;
|
|
||||||
case 'z':
|
case 'z':
|
||||||
ctx->undo_file = optarg;
|
ctx->undo_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -1237,19 +1233,6 @@ check_error:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int e2fsck_setup_patch(e2fsck_t ctx, io_manager *io_ptr)
|
|
||||||
{
|
|
||||||
set_patch_io_backing_manager(*io_ptr);
|
|
||||||
set_patch_io_patch_file(ctx->patch_file);
|
|
||||||
*io_ptr = patch_io_manager;
|
|
||||||
printf(_("To make backup before applying changes run:\n"
|
|
||||||
" e2patch backup %s %s %s.backup\n"
|
|
||||||
"Then, to apply the operation to the real filesystem run:\n"
|
|
||||||
" e2patch apply %s %s\n"),
|
|
||||||
ctx->device_name, ctx->patch_file, ctx->patch_file, ctx->device_name, ctx->patch_file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int e2fsck_setup_tdb(e2fsck_t ctx, io_manager *io_ptr)
|
static int e2fsck_setup_tdb(e2fsck_t ctx, io_manager *io_ptr)
|
||||||
{
|
{
|
||||||
errcode_t retval = ENOMEM;
|
errcode_t retval = ENOMEM;
|
||||||
|
@ -1447,11 +1430,7 @@ restart:
|
||||||
flags &= ~EXT2_FLAG_EXCLUSIVE;
|
flags &= ~EXT2_FLAG_EXCLUSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->patch_file) {
|
if (ctx->undo_file) {
|
||||||
retval = e2fsck_setup_patch(ctx, &io_ptr);
|
|
||||||
if (retval)
|
|
||||||
exit(FSCK_ERROR);
|
|
||||||
} else if (ctx->undo_file) {
|
|
||||||
retval = e2fsck_setup_tdb(ctx, &io_ptr);
|
retval = e2fsck_setup_tdb(ctx, &io_ptr);
|
||||||
if (retval)
|
if (retval)
|
||||||
exit(FSCK_ERROR);
|
exit(FSCK_ERROR);
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
Begin3
|
Begin3
|
||||||
Title: EXT2 Filesystem utilities
|
Title: EXT2 Filesystem utilities
|
||||||
Version: 1.43.3
|
Version: 1.43.2
|
||||||
Entered-date: 2016-09-04
|
Entered-date: 2016-09-01
|
||||||
Description: The filesystem utilities for the EXT2, EXT3, and EXT4
|
Description: The filesystem utilities for the EXT2, EXT3, and EXT4
|
||||||
filesystems, including e2fsck, mke2fs, dumpe2fs, and others.
|
filesystems, including e2fsck, mke2fs, dumpe2fs, and others.
|
||||||
Keywords: utilities, filesystem, Ext2fs, ext3, ext4
|
Keywords: utilities, filesystem, Ext2fs, ext3, ext4
|
||||||
Author: tytso@mit.edu (Theodore Tso)
|
Author: tytso@mit.edu (Theodore Tso)
|
||||||
Maintained-by: tytso@mit.edu (Theodore Tso)
|
Maintained-by: tytso@mit.edu (Theodore Tso)
|
||||||
Primary-site: ftp.kernel.org /pub/linux/kernel/people/tytso/e2fsprogs
|
Primary-site: ftp.kernel.org /pub/linux/kernel/people/tytso/e2fsprogs
|
||||||
7224kB e2fsprogs-1.43.3.tar.gz
|
7224kB e2fsprogs-1.43.2.tar.gz
|
||||||
644kB e2fsprogs-libs-1.43.3.tar.gz
|
644kB e2fsprogs-libs-1.43.2.tar.gz
|
||||||
1kB e2fsprogs-1.43.3.lsm
|
1kB e2fsprogs-1.43.2.lsm
|
||||||
Alternate-site: download.sourceforge.net /pub/sourceforge/e2fsprogs
|
Alternate-site: download.sourceforge.net /pub/sourceforge/e2fsprogs
|
||||||
Platforms: linux 1.2.x/1.3.x/2.0.x/2.1.x/2.2.x/2.3.x/2.4.x/2.5.x/2.6.x/3.x/4.x
|
Platforms: linux 1.2.x/1.3.x/2.0.x/2.1.x/2.2.x/2.3.x/2.4.x/2.5.x/2.6.x/3.x/4.x
|
||||||
Copying-policy: GPL-2/LGPL-2
|
Copying-policy: GPL-2/LGPL-2
|
||||||
|
|
|
@ -117,7 +117,6 @@ exit 0
|
||||||
%{_root_sbindir}/e2image
|
%{_root_sbindir}/e2image
|
||||||
%{_root_sbindir}/e2label
|
%{_root_sbindir}/e2label
|
||||||
%{_root_sbindir}/e2undo
|
%{_root_sbindir}/e2undo
|
||||||
%{_root_sbindir}/e2patch
|
|
||||||
%{_root_sbindir}/findfs
|
%{_root_sbindir}/findfs
|
||||||
%{_root_sbindir}/fsck
|
%{_root_sbindir}/fsck
|
||||||
%{_root_sbindir}/fsck.ext2
|
%{_root_sbindir}/fsck.ext2
|
||||||
|
@ -169,7 +168,6 @@ exit 0
|
||||||
%{_mandir}/man8/e2image.8*
|
%{_mandir}/man8/e2image.8*
|
||||||
%{_mandir}/man8/e2label.8*
|
%{_mandir}/man8/e2label.8*
|
||||||
%{_mandir}/man8/e2undo.8*
|
%{_mandir}/man8/e2undo.8*
|
||||||
%{_mandir}/man8/e2patch.8*
|
|
||||||
%{_mandir}/man8/fsck.8*
|
%{_mandir}/man8/fsck.8*
|
||||||
%{_mandir}/man8/logsave.8*
|
%{_mandir}/man8/logsave.8*
|
||||||
%{_mandir}/man8/mke2fs.8*
|
%{_mandir}/man8/mke2fs.8*
|
||||||
|
|
|
@ -75,8 +75,6 @@ libext2fs_src_files := \
|
||||||
swapfs.c \
|
swapfs.c \
|
||||||
symlink.c \
|
symlink.c \
|
||||||
undo_io.c \
|
undo_io.c \
|
||||||
patch.c \
|
|
||||||
patch_io.c \
|
|
||||||
unix_io.c \
|
unix_io.c \
|
||||||
unlink.c \
|
unlink.c \
|
||||||
valid_blk.c \
|
valid_blk.c \
|
||||||
|
|
|
@ -124,8 +124,6 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
|
||||||
symlink.o \
|
symlink.o \
|
||||||
$(TDB_OBJ) \
|
$(TDB_OBJ) \
|
||||||
undo_io.o \
|
undo_io.o \
|
||||||
patch.o \
|
|
||||||
patch_io.o \
|
|
||||||
unix_io.o \
|
unix_io.o \
|
||||||
unlink.o \
|
unlink.o \
|
||||||
valid_blk.o \
|
valid_blk.o \
|
||||||
|
@ -213,8 +211,6 @@ SRCS= ext2_err.c \
|
||||||
$(srcdir)/tst_getsize.c \
|
$(srcdir)/tst_getsize.c \
|
||||||
$(srcdir)/tst_iscan.c \
|
$(srcdir)/tst_iscan.c \
|
||||||
$(srcdir)/undo_io.c \
|
$(srcdir)/undo_io.c \
|
||||||
$(srcdir)/patch.c \
|
|
||||||
$(srcdir)/patch_io.c \
|
|
||||||
$(srcdir)/unix_io.c \
|
$(srcdir)/unix_io.c \
|
||||||
$(srcdir)/unlink.c \
|
$(srcdir)/unlink.c \
|
||||||
$(srcdir)/valid_blk.c \
|
$(srcdir)/valid_blk.c \
|
||||||
|
@ -1103,18 +1099,6 @@ undo_io.o: $(srcdir)/undo_io.c $(top_builddir)/lib/config.h \
|
||||||
$(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
|
$(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
|
||||||
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
|
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
|
||||||
$(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
|
$(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
|
||||||
patch.o: $(srcdir)/patch.c $(top_builddir)/lib/config.h \
|
|
||||||
$(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
|
|
||||||
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
|
|
||||||
$(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
|
|
||||||
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
|
|
||||||
$(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
|
|
||||||
patch_io.o: $(srcdir)/patch_io.c $(top_builddir)/lib/config.h \
|
|
||||||
$(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
|
|
||||||
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
|
|
||||||
$(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
|
|
||||||
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
|
|
||||||
$(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
|
|
||||||
unix_io.o: $(srcdir)/unix_io.c $(top_builddir)/lib/config.h \
|
unix_io.o: $(srcdir)/unix_io.c $(top_builddir)/lib/config.h \
|
||||||
$(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
|
$(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
|
||||||
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
|
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
|
||||||
|
|
|
@ -185,9 +185,8 @@ struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
|
||||||
struct opaque_ext2_group_desc *gdp,
|
struct opaque_ext2_group_desc *gdp,
|
||||||
dgrp_t group)
|
dgrp_t group)
|
||||||
{
|
{
|
||||||
int desc_size = EXT2_DESC_SIZE(fs->super) & ~7;
|
return (struct ext2_group_desc *)((char *)gdp +
|
||||||
|
group * EXT2_DESC_SIZE(fs->super));
|
||||||
return (struct ext2_group_desc *)((char *)gdp + group * desc_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the same but as an ext4 group desc for internal use here */
|
/* Do the same but as an ext4 group desc for internal use here */
|
||||||
|
|
|
@ -539,7 +539,4 @@ ec EXT2_ET_BAD_CRC,
|
||||||
ec EXT2_ET_CORRUPT_JOURNAL_SB,
|
ec EXT2_ET_CORRUPT_JOURNAL_SB,
|
||||||
"The journal superblock is corrupt"
|
"The journal superblock is corrupt"
|
||||||
|
|
||||||
ec EXT2_ET_INODE_CORRUPTED,
|
|
||||||
"Inode is corrupted"
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -145,11 +145,6 @@ extern io_manager undo_io_manager;
|
||||||
extern errcode_t set_undo_io_backing_manager(io_manager manager);
|
extern errcode_t set_undo_io_backing_manager(io_manager manager);
|
||||||
extern errcode_t set_undo_io_backup_file(char *file_name);
|
extern errcode_t set_undo_io_backup_file(char *file_name);
|
||||||
|
|
||||||
/* patch_io.c */
|
|
||||||
extern io_manager patch_io_manager;
|
|
||||||
extern errcode_t set_patch_io_backing_manager(io_manager manager);
|
|
||||||
extern errcode_t set_patch_io_patch_file(char *file_name);
|
|
||||||
|
|
||||||
/* test_io.c */
|
/* test_io.c */
|
||||||
extern io_manager test_io_manager, test_io_backing_manager;
|
extern io_manager test_io_manager, test_io_backing_manager;
|
||||||
extern void (*test_io_cb_read_blk)
|
extern void (*test_io_cb_read_blk)
|
||||||
|
|
|
@ -554,10 +554,6 @@ errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle)
|
||||||
memset(p + EXT2_GOOD_OLD_INODE_SIZE, 0, extra);
|
memset(p + EXT2_GOOD_OLD_INODE_SIZE, 0, extra);
|
||||||
inode->i_extra_isize = extra;
|
inode->i_extra_isize = extra;
|
||||||
}
|
}
|
||||||
if (inode->i_extra_isize & 3) {
|
|
||||||
err = EXT2_ET_INODE_CORRUPTED;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force the inlinedata attr to the front and the empty entries
|
* Force the inlinedata attr to the front and the empty entries
|
||||||
|
@ -810,10 +806,6 @@ errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle)
|
||||||
inode->i_extra_isize +
|
inode->i_extra_isize +
|
||||||
sizeof(__u32))
|
sizeof(__u32))
|
||||||
goto read_ea_block;
|
goto read_ea_block;
|
||||||
if (inode->i_extra_isize & 3) {
|
|
||||||
err = EXT2_ET_INODE_CORRUPTED;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for EA in the inode */
|
/* Look for EA in the inode */
|
||||||
memcpy(&ea_inode_magic, ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
|
memcpy(&ea_inode_magic, ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
|
||||||
|
|
|
@ -1,228 +0,0 @@
|
||||||
/**
|
|
||||||
* patch.c --- Common "patch" file functions
|
|
||||||
*
|
|
||||||
* Copyright (c) Vitaliy Filippov <vitalif@mail.ru> 2014
|
|
||||||
* License: GNU GPLv2 or later
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _LARGEFILE_SOURCE
|
|
||||||
#define _LARGEFILE64_SOURCE
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "patch.h"
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_retry_read(int fd, ssize_t size, void *buf)
|
|
||||||
{
|
|
||||||
ssize_t r, done = 0;
|
|
||||||
while (done < size)
|
|
||||||
{
|
|
||||||
r = read(fd, buf+done, size-done);
|
|
||||||
if (!r || (r < 0 && errno != EAGAIN))
|
|
||||||
break;
|
|
||||||
done += r;
|
|
||||||
}
|
|
||||||
if (done < size)
|
|
||||||
return errno;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_retry_write(int fd, ssize_t size, const void *buf)
|
|
||||||
{
|
|
||||||
ssize_t r, done = 0;
|
|
||||||
while (done < size)
|
|
||||||
{
|
|
||||||
r = write(fd, buf+done, size-done);
|
|
||||||
if (r <= 0 && errno != EAGAIN)
|
|
||||||
break;
|
|
||||||
done += r;
|
|
||||||
}
|
|
||||||
if (done < size)
|
|
||||||
return errno;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_retry_read_at(int fd, unsigned long long offset, ssize_t size, void *buf)
|
|
||||||
{
|
|
||||||
if ((unsigned long long)ext2fs_llseek(fd, offset, SEEK_SET) != offset)
|
|
||||||
return errno ? errno : EXT2_ET_LLSEEK_FAILED;
|
|
||||||
return ext2fs_patch_retry_read(fd, size, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_retry_write_at(int fd, unsigned long long offset, ssize_t size, const void *buf)
|
|
||||||
{
|
|
||||||
if ((unsigned long long)ext2fs_llseek(fd, offset, SEEK_SET) != offset)
|
|
||||||
return errno ? errno : EXT2_ET_LLSEEK_FAILED;
|
|
||||||
return ext2fs_patch_retry_write(fd, size, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_read_bmap(struct ext2fs_patch_file *data)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
int bufsize = 65536;
|
|
||||||
blk64_t i, r;
|
|
||||||
void *buf = malloc(bufsize);
|
|
||||||
if (!buf)
|
|
||||||
return ENOMEM;
|
|
||||||
ext2fs_llseek(data->patch_fd, data->block_size, SEEK_SET);
|
|
||||||
for (i = 0; i < data->size/8; )
|
|
||||||
{
|
|
||||||
r = bufsize;
|
|
||||||
if (data->size/8 - i < r)
|
|
||||||
r = data->size/8 - i;
|
|
||||||
retval = ext2fs_patch_retry_read(data->patch_fd, r, buf);
|
|
||||||
if (retval)
|
|
||||||
goto out;
|
|
||||||
ext2fs_set_generic_bmap_range(data->bmap, i*8, r*8, buf);
|
|
||||||
i += r;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
free(buf);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
int bufsize = 65536;
|
|
||||||
blk64_t i, r;
|
|
||||||
struct patchbd_super s;
|
|
||||||
void *buf = malloc(bufsize);
|
|
||||||
if (!buf)
|
|
||||||
return ENOMEM;
|
|
||||||
ext2fs_llseek(data->patch_fd, data->block_size, SEEK_SET);
|
|
||||||
for (i = 0; i < data->size/8; )
|
|
||||||
{
|
|
||||||
r = bufsize;
|
|
||||||
if (data->size/8 - i < r)
|
|
||||||
r = data->size/8 - i;
|
|
||||||
ext2fs_get_generic_bmap_range(data->bmap, i*8, r*8, buf);
|
|
||||||
retval = ext2fs_patch_retry_write(data->patch_fd, r, buf);
|
|
||||||
if (retval)
|
|
||||||
goto out;
|
|
||||||
i += r;
|
|
||||||
}
|
|
||||||
ext2fs_llseek(data->patch_fd, 0, SEEK_SET);
|
|
||||||
s.magic = PATCHBD_MAGIC;
|
|
||||||
s.patch_block = data->block_size;
|
|
||||||
s.patch_size = data->size;
|
|
||||||
write(data->patch_fd, &s, sizeof(struct patchbd_super));
|
|
||||||
out:
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_open(struct ext2fs_patch_file *data, char *patch_file, int flags)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
ext2_loff_t size;
|
|
||||||
struct patchbd_super s;
|
|
||||||
data->block_size = 0;
|
|
||||||
data->size = 0;
|
|
||||||
data->offset = 0;
|
|
||||||
data->bmap = NULL;
|
|
||||||
data->patch_file = strdup(patch_file);
|
|
||||||
data->patch_fd = open(data->patch_file, flags|O_RDWR, 0666);
|
|
||||||
if (data->patch_fd < 0)
|
|
||||||
return errno;
|
|
||||||
size = ext2fs_llseek(data->patch_fd, 0, SEEK_END);
|
|
||||||
if (size < 0)
|
|
||||||
return errno;
|
|
||||||
if (size > 0)
|
|
||||||
{
|
|
||||||
size = ext2fs_llseek(data->patch_fd, 0, SEEK_SET);
|
|
||||||
read(data->patch_fd, &s, sizeof(struct patchbd_super));
|
|
||||||
if (s.magic != PATCHBD_MAGIC)
|
|
||||||
return 0;
|
|
||||||
data->block_size = s.patch_block;
|
|
||||||
// if (data->block_size != 4096)
|
|
||||||
// return EINVAL;
|
|
||||||
data->size = s.patch_size;
|
|
||||||
retval = ext2fs_patch_init_bmap(data, NULL);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
retval = ext2fs_patch_read_bmap(data);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_close(struct ext2fs_patch_file *data)
|
|
||||||
{
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
if (data->bmap)
|
|
||||||
{
|
|
||||||
if (data->patch_fd >= 0)
|
|
||||||
ext2fs_patch_write_bmap(data);
|
|
||||||
ext2fs_free_generic_bmap(data->bmap);
|
|
||||||
data->bmap = NULL;
|
|
||||||
}
|
|
||||||
if (data->patch_fd >= 0)
|
|
||||||
{
|
|
||||||
close(data->patch_fd);
|
|
||||||
data->patch_fd = -1;
|
|
||||||
}
|
|
||||||
if (data->patch_file)
|
|
||||||
{
|
|
||||||
free(data->patch_file);
|
|
||||||
data->patch_file = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel channel)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
if (!data->bmap)
|
|
||||||
{
|
|
||||||
if (channel)
|
|
||||||
{
|
|
||||||
// channel is optional parameter, if passed, means 'take size from channel'
|
|
||||||
data->block_size = channel->block_size;
|
|
||||||
// if (data->block_size != 4096)
|
|
||||||
// return EINVAL;
|
|
||||||
retval = ext2fs_get_device_size2(channel->name, data->block_size, &data->size);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
else if (!data->block_size || !data->size)
|
|
||||||
return EINVAL;
|
|
||||||
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
|
||||||
0, data->size, data->size, "overwritten blocks", 0, &data->bmap);
|
|
||||||
data->offset = data->block_size + ((((data->size+7)>>3)+(data->block_size-1))&~(data->block_size-1));
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_write_blk64(struct ext2fs_patch_file *data, unsigned long long block, int count, const void *buf)
|
|
||||||
{
|
|
||||||
ssize_t size;
|
|
||||||
if (!data->bmap)
|
|
||||||
return EINVAL;
|
|
||||||
if (count < 0)
|
|
||||||
{
|
|
||||||
if ((unsigned)-count > data->block_size)
|
|
||||||
return EINVAL;
|
|
||||||
size = -count;
|
|
||||||
count = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
size = count*data->block_size;
|
|
||||||
ext2fs_mark_block_bitmap_range2(data->bmap, block, count);
|
|
||||||
return ext2fs_patch_retry_write_at(data->patch_fd, data->offset + block*data->block_size, size, buf);
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
/**
|
|
||||||
* patch.h --- Common "patch" file functions
|
|
||||||
*
|
|
||||||
* Patch file format:
|
|
||||||
* 1) sparse data blocks - same size as the patched filesystem, but only changed blocks are written
|
|
||||||
* 2) updated block bitmap - fs_size/block_size/8 bytes
|
|
||||||
* 3) 4 byte FS block size
|
|
||||||
* 4) 8 byte FS size in blocks
|
|
||||||
*
|
|
||||||
* Copyright (c) Vitaliy Filippov <vitalif@mail.ru> 2014
|
|
||||||
* License: GNU GPLv2 or later
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef E2_PATCH_H
|
|
||||||
#define E2_PATCH_H
|
|
||||||
|
|
||||||
#include "ext2_fs.h"
|
|
||||||
#include "ext2fs.h"
|
|
||||||
|
|
||||||
#define PATCHBD_MAGIC 0x44623950 // P9bD
|
|
||||||
|
|
||||||
struct ext2fs_patch_file
|
|
||||||
{
|
|
||||||
char *patch_file;
|
|
||||||
int patch_fd;
|
|
||||||
__u32 block_size;
|
|
||||||
blk64_t size;
|
|
||||||
ext2_loff_t offset;
|
|
||||||
ext2fs_generic_bitmap bmap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct patchbd_super
|
|
||||||
{
|
|
||||||
__u32 magic;
|
|
||||||
__u32 patch_block;
|
|
||||||
__u64 patch_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
errcode_t ext2fs_patch_retry_read(int fd, ssize_t size, void *buf);
|
|
||||||
errcode_t ext2fs_patch_retry_write(int fd, ssize_t size, const void *buf);
|
|
||||||
errcode_t ext2fs_patch_retry_read_at(int fd, unsigned long long offset, ssize_t size, void *buf);
|
|
||||||
errcode_t ext2fs_patch_retry_write_at(int fd, unsigned long long offset, ssize_t size, const void *buf);
|
|
||||||
errcode_t ext2fs_patch_read_bmap(struct ext2fs_patch_file *data);
|
|
||||||
errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data);
|
|
||||||
errcode_t ext2fs_patch_open(struct ext2fs_patch_file *data, char *patch_file, int flags);
|
|
||||||
errcode_t ext2fs_patch_close(struct ext2fs_patch_file *data);
|
|
||||||
errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel channel);
|
|
||||||
errcode_t ext2fs_patch_write_blk64(struct ext2fs_patch_file *data, unsigned long long block, int count, const void *buf);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,375 +0,0 @@
|
||||||
/*
|
|
||||||
* patch_io.c --- This is the "patch" io manager that writes the new data into
|
|
||||||
* a separate sparse file to apply it later.
|
|
||||||
*
|
|
||||||
* Copyright (c) Vitaliy Filippov <vitalif@mail.ru> 2014
|
|
||||||
* License: GNU GPLv2 or later
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _LARGEFILE_SOURCE
|
|
||||||
#define _LARGEFILE64_SOURCE
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "ext2_fs.h"
|
|
||||||
#include "ext2fs.h"
|
|
||||||
|
|
||||||
#include "patch.h"
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define ATTR(x) __attribute__(x)
|
|
||||||
#else
|
|
||||||
#define ATTR(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define EXT2_CHECK_MAGIC(struct, code) if ((struct)->magic != (code)) return (code)
|
|
||||||
|
|
||||||
struct patch_private_data
|
|
||||||
{
|
|
||||||
int magic;
|
|
||||||
struct ext2fs_patch_file patch;
|
|
||||||
/* The backing io channel */
|
|
||||||
io_channel real;
|
|
||||||
/* to support offset in unix I/O manager */
|
|
||||||
ext2_loff_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
static errcode_t patch_open(const char *name, int flags, io_channel *channel);
|
|
||||||
static errcode_t patch_close(io_channel channel);
|
|
||||||
static errcode_t patch_set_blksize(io_channel channel, int blksize);
|
|
||||||
static errcode_t patch_read_blk64(io_channel channel, unsigned long long block, int count, void *data);
|
|
||||||
static errcode_t patch_write_blk64(io_channel channel, unsigned long long block, int count, const void *data);
|
|
||||||
static errcode_t patch_read_blk(io_channel channel, unsigned long block, int count, void *data);
|
|
||||||
static errcode_t patch_write_blk(io_channel channel, unsigned long block, int count, const void *data);
|
|
||||||
static errcode_t patch_flush(io_channel channel);
|
|
||||||
static errcode_t patch_write_byte(io_channel channel, unsigned long offset, int size, const void *data);
|
|
||||||
static errcode_t patch_set_option(io_channel channel, const char *option, const char *arg);
|
|
||||||
static errcode_t patch_get_stats(io_channel channel, io_stats *stats);
|
|
||||||
|
|
||||||
static struct struct_io_manager struct_patch_manager = {
|
|
||||||
EXT2_ET_MAGIC_IO_MANAGER,
|
|
||||||
"Patch I/O Manager",
|
|
||||||
patch_open,
|
|
||||||
patch_close,
|
|
||||||
patch_set_blksize,
|
|
||||||
patch_read_blk,
|
|
||||||
patch_write_blk,
|
|
||||||
patch_flush,
|
|
||||||
patch_write_byte,
|
|
||||||
patch_set_option,
|
|
||||||
patch_get_stats,
|
|
||||||
patch_read_blk64,
|
|
||||||
patch_write_blk64,
|
|
||||||
};
|
|
||||||
|
|
||||||
io_manager patch_io_manager = &struct_patch_manager;
|
|
||||||
static char *patch_file;
|
|
||||||
static io_manager patch_io_backing_manager;
|
|
||||||
|
|
||||||
errcode_t set_patch_io_backing_manager(io_manager manager)
|
|
||||||
{
|
|
||||||
patch_io_backing_manager = manager;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t set_patch_io_patch_file(char *file)
|
|
||||||
{
|
|
||||||
patch_file = file;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_open(const char *name, int flags, io_channel *channel)
|
|
||||||
{
|
|
||||||
io_channel io = NULL;
|
|
||||||
struct patch_private_data *data = NULL;
|
|
||||||
errcode_t retval;
|
|
||||||
|
|
||||||
if (name == 0)
|
|
||||||
return EXT2_ET_BAD_DEVICE_NAME;
|
|
||||||
retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
|
|
||||||
if (retval)
|
|
||||||
goto cleanup;
|
|
||||||
memset(io, 0, sizeof(struct struct_io_channel));
|
|
||||||
io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
|
|
||||||
retval = ext2fs_get_mem(sizeof(struct patch_private_data), &data);
|
|
||||||
if (retval)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
io->manager = patch_io_manager;
|
|
||||||
retval = ext2fs_get_mem(strlen(name)+1, &io->name);
|
|
||||||
if (retval)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
strcpy(io->name, name);
|
|
||||||
io->private_data = data;
|
|
||||||
io->block_size = 1024;
|
|
||||||
io->read_error = 0;
|
|
||||||
io->write_error = 0;
|
|
||||||
io->refcount = 1;
|
|
||||||
|
|
||||||
memset(data, 0, sizeof(struct patch_private_data));
|
|
||||||
data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
|
|
||||||
|
|
||||||
if (patch_io_backing_manager)
|
|
||||||
{
|
|
||||||
retval = patch_io_backing_manager->open(name, flags & ~IO_FLAG_RW, &data->real);
|
|
||||||
if (retval)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (patch_file)
|
|
||||||
{
|
|
||||||
retval = ext2fs_patch_open(&data->patch, patch_file, O_CREAT);
|
|
||||||
if (retval)
|
|
||||||
goto cleanup;
|
|
||||||
if (data->patch.block_size)
|
|
||||||
{
|
|
||||||
retval = io_channel_set_blksize(data->real, data->patch.block_size);
|
|
||||||
if (retval)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*channel = io;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
ext2fs_patch_close(&data->patch);
|
|
||||||
if (data->real)
|
|
||||||
io_channel_close(data->real);
|
|
||||||
ext2fs_free_mem(&data);
|
|
||||||
}
|
|
||||||
if (io)
|
|
||||||
{
|
|
||||||
if (io->name)
|
|
||||||
ext2fs_free_mem(&io->name);
|
|
||||||
ext2fs_free_mem(&io);
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_close(io_channel channel)
|
|
||||||
{
|
|
||||||
struct patch_private_data *data;
|
|
||||||
errcode_t retval = 0;
|
|
||||||
|
|
||||||
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
|
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
|
||||||
|
|
||||||
if (--channel->refcount > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ext2fs_patch_close(&data->patch);
|
|
||||||
if (data->real)
|
|
||||||
retval = io_channel_close(data->real);
|
|
||||||
ext2fs_free_mem(&channel->private_data);
|
|
||||||
if (channel->name)
|
|
||||||
ext2fs_free_mem(&channel->name);
|
|
||||||
ext2fs_free_mem(&channel);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_set_blksize(io_channel channel, int blksize)
|
|
||||||
{
|
|
||||||
struct patch_private_data *data;
|
|
||||||
errcode_t retval = 0;
|
|
||||||
|
|
||||||
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
|
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
|
||||||
|
|
||||||
channel->block_size = (unsigned)blksize;
|
|
||||||
if (data->patch.block_size && data->patch.block_size != (unsigned)blksize)
|
|
||||||
return EINVAL;
|
|
||||||
if (data->real)
|
|
||||||
retval = io_channel_set_blksize(data->real, blksize);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_read_blk64(io_channel channel, unsigned long long block, int count, void *buf)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
struct patch_private_data *data;
|
|
||||||
int b, n;
|
|
||||||
|
|
||||||
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
|
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
|
||||||
|
|
||||||
if (count < 0)
|
|
||||||
{
|
|
||||||
if (-count <= channel->block_size)
|
|
||||||
{
|
|
||||||
if (data->patch.bmap && ext2fs_test_generic_bitmap(data->patch.bmap, block))
|
|
||||||
retval = ext2fs_patch_retry_read_at(data->patch.patch_fd, data->patch.offset + block*channel->block_size, -count, buf);
|
|
||||||
else
|
|
||||||
retval = io_channel_read_blk64(data->real, block, count, buf);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
for (b = 0; b < count; )
|
|
||||||
{
|
|
||||||
for (n = 0; (b+n < count) && data->patch.bmap && ext2fs_test_generic_bitmap(data->patch.bmap, block+b+n); n++) {}
|
|
||||||
if (n > 0)
|
|
||||||
{
|
|
||||||
retval = ext2fs_patch_retry_read_at(data->patch.patch_fd, data->patch.offset + (block+b)*channel->block_size, n*channel->block_size, buf+b*channel->block_size);
|
|
||||||
if (retval)
|
|
||||||
break;
|
|
||||||
b += n;
|
|
||||||
}
|
|
||||||
for (n = 0; (b+n < count) && (!data->patch.bmap || !ext2fs_test_generic_bitmap(data->patch.bmap, block+b+n)); n++) {}
|
|
||||||
if (n > 0)
|
|
||||||
{
|
|
||||||
retval = io_channel_read_blk64(data->real, block+b, n, buf+b*channel->block_size);
|
|
||||||
if (retval)
|
|
||||||
break;
|
|
||||||
b += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_read_blk(io_channel channel, unsigned long block, int count, void *buf)
|
|
||||||
{
|
|
||||||
return patch_read_blk64(channel, block, count, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_write_blk64(io_channel channel, unsigned long long block, int count, const void *buf)
|
|
||||||
{
|
|
||||||
struct patch_private_data *data;
|
|
||||||
errcode_t retval = 0;
|
|
||||||
|
|
||||||
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
|
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
|
||||||
|
|
||||||
retval = ext2fs_patch_init_bmap(&data->patch, channel);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
// libext2fs changes block size to 1024 in order to write the superblock, so we must support it...
|
|
||||||
if ((__u32)channel->block_size < data->patch.block_size)
|
|
||||||
{
|
|
||||||
void *buf2 = NULL;
|
|
||||||
unsigned long long block_real = block / (data->patch.block_size / channel->block_size);
|
|
||||||
int count_real = ( (block % (data->patch.block_size / channel->block_size))
|
|
||||||
+ (count > 0 ? count*channel->block_size : -count)
|
|
||||||
+ data->patch.block_size - 1 ) / data->patch.block_size;
|
|
||||||
retval = ext2fs_get_mem(count_real * data->patch.block_size, &buf2);
|
|
||||||
if (retval)
|
|
||||||
goto out;
|
|
||||||
retval = patch_read_blk64(channel, block_real, count_real, buf2);
|
|
||||||
if (retval)
|
|
||||||
goto out;
|
|
||||||
memcpy(buf2 + (block % (data->patch.block_size / channel->block_size)) * channel->block_size,
|
|
||||||
buf, (count > 0 ? count*channel->block_size : -count));
|
|
||||||
retval = ext2fs_patch_write_blk64(&data->patch, block_real, count_real, buf2);
|
|
||||||
out:
|
|
||||||
if (buf2)
|
|
||||||
ext2fs_free_mem(&buf2);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
else if ((__u32)channel->block_size > data->patch.block_size)
|
|
||||||
{
|
|
||||||
return EXT2_ET_UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
return ext2fs_patch_write_blk64(&data->patch, block, count, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_write_blk(io_channel channel, unsigned long block, int count, const void *buf)
|
|
||||||
{
|
|
||||||
return patch_write_blk64(channel, block, count, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_write_byte(io_channel channel, unsigned long offset, int size, const void *buf)
|
|
||||||
{
|
|
||||||
return EXT2_ET_UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Flush data buffers to disk.
|
|
||||||
*/
|
|
||||||
static errcode_t patch_flush(io_channel channel)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
struct patch_private_data *data;
|
|
||||||
|
|
||||||
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
|
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
|
||||||
|
|
||||||
if (data->real)
|
|
||||||
retval = io_channel_flush(data->real);
|
|
||||||
if (data->patch.patch_fd)
|
|
||||||
fsync(data->patch.patch_fd);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_set_option(io_channel channel, const char *option, const char *arg)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
struct patch_private_data *data;
|
|
||||||
unsigned long tmp;
|
|
||||||
char *end;
|
|
||||||
|
|
||||||
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
|
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Need to support offset option to work with
|
|
||||||
* Unix I/O manager
|
|
||||||
*/
|
|
||||||
if (data->real && data->real->manager->set_option)
|
|
||||||
retval = data->real->manager->set_option(data->real, option, arg);
|
|
||||||
if (!retval && !strcmp(option, "offset"))
|
|
||||||
{
|
|
||||||
if (!arg)
|
|
||||||
return EXT2_ET_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
tmp = strtoul(arg, &end, 0);
|
|
||||||
if (*end)
|
|
||||||
return EXT2_ET_INVALID_ARGUMENT;
|
|
||||||
data->offset = tmp;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_get_stats(io_channel channel, io_stats *stats)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
struct patch_private_data *data;
|
|
||||||
|
|
||||||
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
|
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
|
||||||
|
|
||||||
if (data->real)
|
|
||||||
retval = (data->real->manager->get_stats)(data->real, stats);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
|
@ -307,8 +307,6 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
|
||||||
/* this is error case: i_extra_size is too large */
|
/* this is error case: i_extra_size is too large */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (extra_isize & 3)
|
|
||||||
return; /* Illegal inode extra_isize */
|
|
||||||
|
|
||||||
inode_size = EXT2_GOOD_OLD_INODE_SIZE + extra_isize;
|
inode_size = EXT2_GOOD_OLD_INODE_SIZE + extra_isize;
|
||||||
if (inode_includes(inode_size, i_checksum_hi))
|
if (inode_includes(inode_size, i_checksum_hi))
|
||||||
|
|
|
@ -300,7 +300,6 @@ static errcode_t raw_write_blk(io_channel channel,
|
||||||
goto short_write;
|
goto short_write;
|
||||||
size -= actual;
|
size -= actual;
|
||||||
buf += actual;
|
buf += actual;
|
||||||
location += actual;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,12 @@ INSTALL = @INSTALL@
|
||||||
@FUSE_CMT@FUSE_PROG= fuse2fs
|
@FUSE_CMT@FUSE_PROG= fuse2fs
|
||||||
|
|
||||||
SPROGS= mke2fs badblocks tune2fs dumpe2fs $(BLKID_PROG) logsave \
|
SPROGS= mke2fs badblocks tune2fs dumpe2fs $(BLKID_PROG) logsave \
|
||||||
$(E2IMAGE_PROG) @FSCK_PROG@ e2undo e2patch
|
$(E2IMAGE_PROG) @FSCK_PROG@ e2undo
|
||||||
USPROGS= mklost+found filefrag e2freefrag $(UUIDD_PROG) \
|
USPROGS= mklost+found filefrag e2freefrag $(UUIDD_PROG) \
|
||||||
$(E4DEFRAG_PROG) $(E4CRYPT_PROG) $(FUSE_PROG)
|
$(E4DEFRAG_PROG) $(E4CRYPT_PROG) $(FUSE_PROG)
|
||||||
SMANPAGES= tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 \
|
SMANPAGES= tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 \
|
||||||
e2label.8 $(FINDFS_MAN) $(BLKID_MAN) $(E2IMAGE_MAN) \
|
e2label.8 $(FINDFS_MAN) $(BLKID_MAN) $(E2IMAGE_MAN) \
|
||||||
logsave.8 filefrag.8 e2freefrag.8 e2undo.8 e2patch.8 \
|
logsave.8 filefrag.8 e2freefrag.8 e2undo.8 \
|
||||||
$(UUIDD_MAN) $(E4DEFRAG_MAN) $(E4CRYPT_MAN) @FSCK_MAN@
|
$(UUIDD_MAN) $(E4DEFRAG_MAN) $(E4CRYPT_MAN) @FSCK_MAN@
|
||||||
FMANPAGES= mke2fs.conf.5 ext4.5
|
FMANPAGES= mke2fs.conf.5 ext4.5
|
||||||
|
|
||||||
|
@ -63,7 +63,6 @@ FSCK_OBJS= fsck.o base_device.o ismounted.o
|
||||||
BLKID_OBJS= blkid.o
|
BLKID_OBJS= blkid.o
|
||||||
FILEFRAG_OBJS= filefrag.o
|
FILEFRAG_OBJS= filefrag.o
|
||||||
E2UNDO_OBJS= e2undo.o
|
E2UNDO_OBJS= e2undo.o
|
||||||
E2PATCH_OBJS= e2patch.o
|
|
||||||
E4DEFRAG_OBJS= e4defrag.o
|
E4DEFRAG_OBJS= e4defrag.o
|
||||||
E4CRYPT_OBJS= e4crypt.o
|
E4CRYPT_OBJS= e4crypt.o
|
||||||
E2FREEFRAG_OBJS= e2freefrag.o
|
E2FREEFRAG_OBJS= e2freefrag.o
|
||||||
|
@ -89,7 +88,6 @@ PROFILED_BLKID_OBJS= profiled/blkid.o
|
||||||
PROFILED_FILEFRAG_OBJS= profiled/filefrag.o
|
PROFILED_FILEFRAG_OBJS= profiled/filefrag.o
|
||||||
PROFILED_E2FREEFRAG_OBJS= profiled/e2freefrag.o
|
PROFILED_E2FREEFRAG_OBJS= profiled/e2freefrag.o
|
||||||
PROFILED_E2UNDO_OBJS= profiled/e2undo.o
|
PROFILED_E2UNDO_OBJS= profiled/e2undo.o
|
||||||
PROFILED_E2PATCH_OBJS= profiled/e2patch.o
|
|
||||||
PROFILED_E4DEFRAG_OBJS= profiled/e4defrag.o
|
PROFILED_E4DEFRAG_OBJS= profiled/e4defrag.o
|
||||||
PROFILED_E4CRYPT_OBJS= profiled/e4crypt.o
|
PROFILED_E4CRYPT_OBJS= profiled/e4crypt.o
|
||||||
PROFILED_FUSE2FS_OJBS= profiled/fuse2fs.o profiled/journal.o \
|
PROFILED_FUSE2FS_OJBS= profiled/fuse2fs.o profiled/journal.o \
|
||||||
|
@ -100,7 +98,7 @@ SRCS= $(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c $(srcdir)/
|
||||||
$(srcdir)/badblocks.c $(srcdir)/fsck.c $(srcdir)/util.c \
|
$(srcdir)/badblocks.c $(srcdir)/fsck.c $(srcdir)/util.c \
|
||||||
$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
|
$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
|
||||||
$(srcdir)/filefrag.c $(srcdir)/base_device.c \
|
$(srcdir)/filefrag.c $(srcdir)/base_device.c \
|
||||||
$(srcdir)/ismounted.c $(srcdir)/e2undo.c $(srcdir)/e2patch.c \
|
$(srcdir)/ismounted.c $(srcdir)/e2undo.c \
|
||||||
$(srcdir)/e2freefrag.c $(srcdir)/create_inode.c \
|
$(srcdir)/e2freefrag.c $(srcdir)/create_inode.c \
|
||||||
$(srcdir)/fuse2fs.c \
|
$(srcdir)/fuse2fs.c \
|
||||||
$(srcdir)/../debugfs/journal.c $(srcdir)/../e2fsck/revoke.c \
|
$(srcdir)/../debugfs/journal.c $(srcdir)/../e2fsck/revoke.c \
|
||||||
|
@ -135,7 +133,7 @@ all:: profiled $(SPROGS) $(UPROGS) $(USPROGS) $(SMANPAGES) $(UMANPAGES) \
|
||||||
$(FMANPAGES) $(LPROGS) $(E4DEFRAG_PROG) $(E4CRYPT_PROGS) e2fuzz
|
$(FMANPAGES) $(LPROGS) $(E4DEFRAG_PROG) $(E4CRYPT_PROGS) e2fuzz
|
||||||
|
|
||||||
@PROFILE_CMT@all:: tune2fs.profiled blkid.profiled e2image.profiled \
|
@PROFILE_CMT@all:: tune2fs.profiled blkid.profiled e2image.profiled \
|
||||||
e2undo.profiled e2patch.profiled mke2fs.profiled dumpe2fs.profiled fsck.profiled \
|
e2undo.profiled mke2fs.profiled dumpe2fs.profiled fsck.profiled \
|
||||||
logsave.profiled filefrag.profiled uuidgen.profiled $(UUIDD_PROFILED) \
|
logsave.profiled filefrag.profiled uuidgen.profiled $(UUIDD_PROFILED) \
|
||||||
e2image.profiled e4defrag.profiled e4crypt.profiled \
|
e2image.profiled e4defrag.profiled e4crypt.profiled \
|
||||||
e2freefrag.profiled
|
e2freefrag.profiled
|
||||||
|
@ -228,16 +226,6 @@ e2undo.profiled: $(E2UNDO_OBJS) $(PROFILED_DEPLIBS)
|
||||||
$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e2undo.profiled \
|
$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e2undo.profiled \
|
||||||
$(PROFILED_E2UNDO_OBJS) $(PROFILED_LIBS) $(LIBINTL) $(SYSLIBS)
|
$(PROFILED_E2UNDO_OBJS) $(PROFILED_LIBS) $(LIBINTL) $(SYSLIBS)
|
||||||
|
|
||||||
e2patch: $(E2PATCH_OBJS) $(DEPLIBS)
|
|
||||||
$(E) " LD $@"
|
|
||||||
$(Q) $(CC) $(ALL_LDFLAGS) -o e2patch $(E2PATCH_OBJS) $(LIBS) \
|
|
||||||
$(LIBINTL) $(SYSLIBS)
|
|
||||||
|
|
||||||
e2patch.profiled: $(E2PATCH_OBJS) $(PROFILED_DEPLIBS)
|
|
||||||
$(E) " LD $@"
|
|
||||||
$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e2patch.profiled \
|
|
||||||
$(PROFILED_E2PATCH_OBJS) $(PROFILED_LIBS) $(LIBINTL) $(SYSLIBS)
|
|
||||||
|
|
||||||
e4defrag: $(E4DEFRAG_OBJS) $(DEPLIBS)
|
e4defrag: $(E4DEFRAG_OBJS) $(DEPLIBS)
|
||||||
$(E) " LD $@"
|
$(E) " LD $@"
|
||||||
$(Q) $(CC) $(ALL_LDFLAGS) -o e4defrag $(E4DEFRAG_OBJS) $(LIBS) \
|
$(Q) $(CC) $(ALL_LDFLAGS) -o e4defrag $(E4DEFRAG_OBJS) $(LIBS) \
|
||||||
|
@ -451,10 +439,6 @@ e2undo.8: $(DEP_SUBSTITUTE) $(srcdir)/e2undo.8.in
|
||||||
$(E) " SUBST $@"
|
$(E) " SUBST $@"
|
||||||
$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2undo.8.in e2undo.8
|
$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2undo.8.in e2undo.8
|
||||||
|
|
||||||
e2patch.8: $(DEP_SUBSTITUTE) $(srcdir)/e2patch.8.in
|
|
||||||
$(E) " SUBST $@"
|
|
||||||
$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2patch.8.in e2patch.8
|
|
||||||
|
|
||||||
findfs.8: $(DEP_SUBSTITUTE) $(srcdir)/findfs.8.in
|
findfs.8: $(DEP_SUBSTITUTE) $(srcdir)/findfs.8.in
|
||||||
$(E) " SUBST $@"
|
$(E) " SUBST $@"
|
||||||
$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/findfs.8.in findfs.8
|
$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/findfs.8.in findfs.8
|
||||||
|
@ -685,7 +669,7 @@ clean::
|
||||||
e2initrd_helper partinfo prof_err.[ch] default_profile.c \
|
e2initrd_helper partinfo prof_err.[ch] default_profile.c \
|
||||||
uuidd e2image tune2fs.static tst_ismounted fsck.profiled \
|
uuidd e2image tune2fs.static tst_ismounted fsck.profiled \
|
||||||
blkid.profiled tune2fs.profiled e2image.profiled \
|
blkid.profiled tune2fs.profiled e2image.profiled \
|
||||||
e2undo.profiled e2patch.profiled mke2fs.profiled dumpe2fs.profiled \
|
e2undo.profiled mke2fs.profiled dumpe2fs.profiled \
|
||||||
logsave.profiled filefrag.profiled uuidgen.profiled \
|
logsave.profiled filefrag.profiled uuidgen.profiled \
|
||||||
uuidd.profiled e2image.profiled e2fuzz mke2fs.conf \
|
uuidd.profiled e2image.profiled e2fuzz mke2fs.conf \
|
||||||
profiled/*.o \#* *.s *.o *.a *~ core gmon.out
|
profiled/*.o \#* *.s *.o *.a *~ core gmon.out
|
||||||
|
@ -808,12 +792,6 @@ e2undo.o: $(srcdir)/e2undo.c $(top_builddir)/lib/config.h \
|
||||||
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
|
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
|
||||||
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
|
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
|
||||||
$(top_srcdir)/lib/support/nls-enable.h
|
$(top_srcdir)/lib/support/nls-enable.h
|
||||||
e2patch.o: $(srcdir)/e2patch.c $(top_builddir)/lib/config.h \
|
|
||||||
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
|
|
||||||
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
|
|
||||||
$(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
|
|
||||||
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
|
|
||||||
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h
|
|
||||||
e2freefrag.o: $(srcdir)/e2freefrag.c $(top_builddir)/lib/config.h \
|
e2freefrag.o: $(srcdir)/e2freefrag.c $(top_builddir)/lib/config.h \
|
||||||
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
|
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
|
||||||
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
|
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
.TH E2PATCH 8 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@"
|
|
||||||
.SH NAME
|
|
||||||
e2patch \- patch tool for safely applying libext2fs patch files to block devices
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B e2patch backup \fI<device>\fR \fI<patch_file>\fR \fI<backup_file>\fR
|
|
||||||
.br
|
|
||||||
.B e2patch apply \fI<device>\fR \fI<patch_file>\fR
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.B e2patch
|
|
||||||
applies and restores "patches" produced by e2fsprogs with patch file option
|
|
||||||
(\fBresize2fs -T <patch_file>\fR) to block devices.
|
|
||||||
.PP
|
|
||||||
"Patch files" are sparse files containing overwritten device blocks and
|
|
||||||
a block bitmap.
|
|
||||||
.PP
|
|
||||||
"Patch files" are faster, safer and simpler to use than "undo files"
|
|
||||||
(\fBe2undo\fR and \fBresize2fs -z <undo_file>\fR), even though their original
|
|
||||||
design goal is similar.
|
|
||||||
.SH COMMANDS
|
|
||||||
.TP
|
|
||||||
.B e2patch backup \fI<device>\fR \fI<patch_file>\fR \fI<backup_file>\fR
|
|
||||||
Creates a backup in <backup_file> for restoring after bad patch <patch_file>.
|
|
||||||
Backup can then also be applied with \fBe2patch apply\fR
|
|
||||||
.TP
|
|
||||||
.B e2patch apply \fI<device>\fR \fI<patch_file>\fR
|
|
||||||
Apply <patch_file> to <device>.
|
|
||||||
.SH AUTHOR
|
|
||||||
Written by Vitaliy Filippov <vitalif@mail.ru>
|
|
||||||
.SH SEE ALSO
|
|
||||||
.BR resize2fs (8),
|
|
||||||
.BR e2undo (8).
|
|
166
misc/e2patch.c
166
misc/e2patch.c
|
@ -1,166 +0,0 @@
|
||||||
/**
|
|
||||||
* e2patch.c --- Utility to apply/restore patches created by patch_io_manager.
|
|
||||||
*
|
|
||||||
* Copyright (c) Vitaliy Filippov <vitalif@mail.ru> 2014
|
|
||||||
* License: GNU GPLv2 or later
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "ext2fs/ext2_fs.h"
|
|
||||||
#include "ext2fs/ext2fs.h"
|
|
||||||
|
|
||||||
#include "ext2fs/patch.h"
|
|
||||||
|
|
||||||
#define BUF 0x10000
|
|
||||||
#define _(a) (a)
|
|
||||||
|
|
||||||
errcode_t make_backup_patch(char *device, char *io_options, char *patch_file, char *backup_file)
|
|
||||||
{
|
|
||||||
io_manager mgr = unix_io_manager;
|
|
||||||
io_channel io;
|
|
||||||
errcode_t retval;
|
|
||||||
blk64_t blk, start, buf_blocks;
|
|
||||||
int eq;
|
|
||||||
void *buf = NULL;
|
|
||||||
struct ext2fs_patch_file patch = { 0 }, backup = { 0 };
|
|
||||||
retval = mgr->open(device, IO_FLAG_EXCLUSIVE, &io);
|
|
||||||
if (retval) goto out;
|
|
||||||
if (io_options &&
|
|
||||||
(retval = io_channel_set_options(io, io_options)))
|
|
||||||
goto out;
|
|
||||||
retval = ext2fs_patch_open(&patch, patch_file, 0);
|
|
||||||
if (retval) goto out;
|
|
||||||
retval = ext2fs_patch_open(&backup, backup_file, O_CREAT);
|
|
||||||
if (retval) goto out;
|
|
||||||
backup.block_size = patch.block_size;
|
|
||||||
backup.size = patch.size;
|
|
||||||
ext2fs_patch_init_bmap(&backup, NULL);
|
|
||||||
buf_blocks = BUF/patch.block_size;
|
|
||||||
retval = mgr->set_blksize(io, patch.block_size);
|
|
||||||
if (retval) goto out;
|
|
||||||
buf = malloc(BUF);
|
|
||||||
for (start = 0, blk = 0; blk <= patch.size; blk++)
|
|
||||||
{
|
|
||||||
if ((eq = !ext2fs_test_generic_bitmap(patch.bmap, blk)) || blk >= patch.size || blk-start >= buf_blocks)
|
|
||||||
{
|
|
||||||
if (start != blk)
|
|
||||||
{
|
|
||||||
retval = io_channel_read_blk64(io, start, blk-start, buf);
|
|
||||||
if (retval) goto out;
|
|
||||||
retval = ext2fs_patch_write_blk64(&backup, start, blk-start, buf);
|
|
||||||
if (retval) goto out;
|
|
||||||
}
|
|
||||||
start = blk+eq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
if (buf)
|
|
||||||
free(buf);
|
|
||||||
ext2fs_patch_close(&backup);
|
|
||||||
ext2fs_patch_close(&patch);
|
|
||||||
mgr->close(io);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
errcode_t apply_patch(char *device, char *io_options, char *patch_file)
|
|
||||||
{
|
|
||||||
io_manager mgr = unix_io_manager;
|
|
||||||
io_channel io;
|
|
||||||
errcode_t retval;
|
|
||||||
blk64_t blk, start, buf_blocks;
|
|
||||||
int eq;
|
|
||||||
void *buf = NULL;
|
|
||||||
struct ext2fs_patch_file patch = { 0 };
|
|
||||||
retval = mgr->open(device, IO_FLAG_EXCLUSIVE|IO_FLAG_RW, &io);
|
|
||||||
if (retval) goto out;
|
|
||||||
if (io_options &&
|
|
||||||
(retval = io_channel_set_options(io, io_options)))
|
|
||||||
goto out;
|
|
||||||
retval = ext2fs_patch_open(&patch, patch_file, 0);
|
|
||||||
if (retval) goto out;
|
|
||||||
buf_blocks = BUF/patch.block_size;
|
|
||||||
retval = mgr->set_blksize(io, patch.block_size);
|
|
||||||
if (retval) goto out;
|
|
||||||
buf = malloc(BUF);
|
|
||||||
for (start = 0, blk = 0; blk <= patch.size; blk++)
|
|
||||||
{
|
|
||||||
if ((eq = blk < patch.size && !ext2fs_test_generic_bitmap(patch.bmap, blk)) || blk >= patch.size || blk-start >= buf_blocks)
|
|
||||||
{
|
|
||||||
if (start != blk)
|
|
||||||
{
|
|
||||||
retval = ext2fs_patch_retry_read_at(patch.patch_fd, patch.offset + start*patch.block_size, (blk-start)*patch.block_size, buf);
|
|
||||||
if (retval) goto out;
|
|
||||||
retval = io_channel_write_blk64(io, start, blk-start, buf);
|
|
||||||
if (retval) goto out;
|
|
||||||
}
|
|
||||||
start = blk+eq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
if (buf)
|
|
||||||
free(buf);
|
|
||||||
ext2fs_patch_close(&patch);
|
|
||||||
mgr->close(io);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int narg, char **args)
|
|
||||||
{
|
|
||||||
errcode_t retval;
|
|
||||||
char *io_options = NULL;
|
|
||||||
if (narg >= 5 && !strcmp(args[1], "backup"))
|
|
||||||
{
|
|
||||||
io_options = strchr(args[2], '?');
|
|
||||||
if (io_options)
|
|
||||||
*io_options++ = 0;
|
|
||||||
retval = make_backup_patch(args[2], io_options, args[3], args[4]);
|
|
||||||
}
|
|
||||||
else if (narg >= 4 && !strcmp(args[1], "apply"))
|
|
||||||
{
|
|
||||||
io_options = strchr(args[2], '?');
|
|
||||||
if (io_options)
|
|
||||||
*io_options++ = 0;
|
|
||||||
retval = apply_patch(args[2], io_options, args[3]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"Patch tool for safely applying changes to block devices\n"
|
|
||||||
"License: GNU GPLv2 or later\n"
|
|
||||||
"Copyright (c) Vitaliy Filippov, 2014\n\n"
|
|
||||||
"To create a backup for restoring after bad patch:\n"
|
|
||||||
" e2patch backup <filesystem> <patch_file> <backup_file>\n"
|
|
||||||
"To apply a patch:\n"
|
|
||||||
" e2patch apply <filesystem> <patch_file>\n"
|
|
||||||
);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (retval)
|
|
||||||
{
|
|
||||||
com_err("e2patch", retval, _("while trying to %s"), args[1]);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -474,10 +474,6 @@ static int frag_report(const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force_bmap || rc < 0) { /* FIEMAP failed, try FIBMAP instead */
|
if (force_bmap || rc < 0) { /* FIEMAP failed, try FIBMAP instead */
|
||||||
if (numblocks > (unsigned long)-1L) {
|
|
||||||
fprintf(stderr, "%s: File too big to use FIBMAP\n", filename);
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
expected = filefrag_fibmap(fd, blk_shift, &num_extents,
|
expected = filefrag_fibmap(fd, blk_shift, &num_extents,
|
||||||
&st, numblocks, is_ext2);
|
&st, numblocks, is_ext2);
|
||||||
if (expected < 0) {
|
if (expected < 0) {
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
features = has_journal
|
features = has_journal
|
||||||
}
|
}
|
||||||
ext4 = {
|
ext4 = {
|
||||||
features = has_journal,extent,huge_file,flex_bg,64bit,dir_nlink,extra_isize
|
features = has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize
|
||||||
inode_size = 256
|
inode_size = 256
|
||||||
}
|
}
|
||||||
ext4dev = {
|
ext4dev = {
|
||||||
features = has_journal,extent,huge_file,flex_bg,inline_data,64bit,dir_nlink,extra_isize
|
features = has_journal,extent,huge_file,flex_bg,metadata_csum,inline_data,64bit,dir_nlink,extra_isize
|
||||||
inode_size = 256
|
inode_size = 256
|
||||||
options = test_fs=1
|
options = test_fs=1
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ misc/e2image.c
|
||||||
misc/e2initrd_helper.c
|
misc/e2initrd_helper.c
|
||||||
misc/e2label.c
|
misc/e2label.c
|
||||||
misc/e2undo.c
|
misc/e2undo.c
|
||||||
misc/e2patch.c
|
|
||||||
misc/e4crypt.c
|
misc/e4crypt.c
|
||||||
misc/e4defrag.c
|
misc/e4defrag.c
|
||||||
misc/filefrag.c
|
misc/filefrag.c
|
||||||
|
|
614
po/e2fsprogs.pot
614
po/e2fsprogs.pot
File diff suppressed because it is too large
Load Diff
BIN
po/zh_CN.gmo
BIN
po/zh_CN.gmo
Binary file not shown.
895
po/zh_CN.po
895
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
|
@ -46,8 +46,8 @@ static char *device_name, *io_options;
|
||||||
|
|
||||||
static void usage (char *prog)
|
static void usage (char *prog)
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-N new_inodes] [-P] "
|
fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P] "
|
||||||
"[-p] device [-b|-s|new_size] [-T patch_file] [-z undo_file]\n\n"),
|
"[-p] device [-b|-s|new_size] [-z undo_file]\n\n"),
|
||||||
prog);
|
prog);
|
||||||
|
|
||||||
exit (1);
|
exit (1);
|
||||||
|
@ -167,20 +167,6 @@ static void bigalloc_check(ext2_filsys fs, int force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resize2fs_setup_patch(const char *device, char *patch_file,
|
|
||||||
io_manager *io_ptr)
|
|
||||||
{
|
|
||||||
set_patch_io_backing_manager(*io_ptr);
|
|
||||||
set_patch_io_patch_file(patch_file);
|
|
||||||
*io_ptr = patch_io_manager;
|
|
||||||
printf(_("To make backup before applying changes run:\n"
|
|
||||||
" e2patch backup %s %s %s.backup\n"
|
|
||||||
"Then, to apply the operation to the real filesystem run:\n"
|
|
||||||
" e2patch apply %s %s\n"),
|
|
||||||
device, patch_file, patch_file, device, patch_file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int resize2fs_setup_tdb(const char *device, char *undo_file,
|
static int resize2fs_setup_tdb(const char *device, char *undo_file,
|
||||||
io_manager *io_ptr)
|
io_manager *io_ptr)
|
||||||
{
|
{
|
||||||
|
@ -272,7 +258,6 @@ int main (int argc, char ** argv)
|
||||||
blk64_t new_size = 0;
|
blk64_t new_size = 0;
|
||||||
blk64_t max_size = 0;
|
blk64_t max_size = 0;
|
||||||
blk64_t min_size = 0;
|
blk64_t min_size = 0;
|
||||||
__u32 new_inodes = 0;
|
|
||||||
io_manager io_ptr;
|
io_manager io_ptr;
|
||||||
char *new_size_str = 0;
|
char *new_size_str = 0;
|
||||||
int use_stride = -1;
|
int use_stride = -1;
|
||||||
|
@ -282,7 +267,7 @@ int main (int argc, char ** argv)
|
||||||
unsigned int blocksize;
|
unsigned int blocksize;
|
||||||
long sysval;
|
long sysval;
|
||||||
int len, mount_flags;
|
int len, mount_flags;
|
||||||
char *mtpt, *undo_file = NULL, *patch_file = NULL;
|
char *mtpt, *undo_file = NULL;
|
||||||
|
|
||||||
#ifdef ENABLE_NLS
|
#ifdef ENABLE_NLS
|
||||||
setlocale(LC_MESSAGES, "");
|
setlocale(LC_MESSAGES, "");
|
||||||
|
@ -299,7 +284,7 @@ int main (int argc, char ** argv)
|
||||||
if (argc && *argv)
|
if (argc && *argv)
|
||||||
program_name = *argv;
|
program_name = *argv;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "d:fFhMPN:pS:bsT:z:")) != EOF) {
|
while ((c = getopt(argc, argv, "d:fFhMPpS:bsz:")) != EOF) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(program_name);
|
usage(program_name);
|
||||||
|
@ -316,9 +301,6 @@ int main (int argc, char ** argv)
|
||||||
case 'P':
|
case 'P':
|
||||||
print_min_size = 1;
|
print_min_size = 1;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
|
||||||
new_inodes = strtoul(optarg, 0, 0);
|
|
||||||
break;
|
|
||||||
case 'd':
|
case 'd':
|
||||||
flags |= atoi(optarg);
|
flags |= atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -334,9 +316,6 @@ int main (int argc, char ** argv)
|
||||||
case 's':
|
case 's':
|
||||||
flags |= RESIZE_DISABLE_64BIT;
|
flags |= RESIZE_DISABLE_64BIT;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
|
||||||
patch_file = optarg;
|
|
||||||
break;
|
|
||||||
case 'z':
|
case 'z':
|
||||||
undo_file = optarg;
|
undo_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -423,11 +402,7 @@ int main (int argc, char ** argv)
|
||||||
io_flags = EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE;
|
io_flags = EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE;
|
||||||
|
|
||||||
io_flags |= EXT2_FLAG_64BITS;
|
io_flags |= EXT2_FLAG_64BITS;
|
||||||
if (patch_file) {
|
if (undo_file) {
|
||||||
retval = resize2fs_setup_patch(device_name, patch_file, &io_ptr);
|
|
||||||
if (retval)
|
|
||||||
exit(1);
|
|
||||||
} else if (undo_file) {
|
|
||||||
retval = resize2fs_setup_tdb(device_name, undo_file, &io_ptr);
|
retval = resize2fs_setup_tdb(device_name, undo_file, &io_ptr);
|
||||||
if (retval)
|
if (retval)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -608,7 +583,7 @@ int main (int argc, char ** argv)
|
||||||
"feature.\n"));
|
"feature.\n"));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else if (new_size == ext2fs_blocks_count(fs->super) && !new_inodes) {
|
} else if (new_size == ext2fs_blocks_count(fs->super)) {
|
||||||
fprintf(stderr, _("The filesystem is already %llu (%dk) "
|
fprintf(stderr, _("The filesystem is already %llu (%dk) "
|
||||||
"blocks long. Nothing to do!\n\n"), new_size,
|
"blocks long. Nothing to do!\n\n"), new_size,
|
||||||
blocksize / 1024);
|
blocksize / 1024);
|
||||||
|
@ -637,7 +612,7 @@ int main (int argc, char ** argv)
|
||||||
printf(_("Resizing the filesystem on "
|
printf(_("Resizing the filesystem on "
|
||||||
"%s to %llu (%dk) blocks.\n"),
|
"%s to %llu (%dk) blocks.\n"),
|
||||||
device_name, new_size, blocksize / 1024);
|
device_name, new_size, blocksize / 1024);
|
||||||
retval = resize_fs(fs, &new_size, new_inodes, flags,
|
retval = resize_fs(fs, &new_size, flags,
|
||||||
((flags & RESIZE_PERCENT_COMPLETE) ?
|
((flags & RESIZE_PERCENT_COMPLETE) ?
|
||||||
resize_progress_func : 0));
|
resize_progress_func : 0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,12 +159,6 @@ program will heuristically determine the RAID stride that was specified
|
||||||
when the filesystem was created. This option allows the user to
|
when the filesystem was created. This option allows the user to
|
||||||
explicitly specify a RAID stride setting to be used by resize2fs instead.
|
explicitly specify a RAID stride setting to be used by resize2fs instead.
|
||||||
.TP
|
.TP
|
||||||
.BI \-T " patch_file"
|
|
||||||
Do not apply changes to the real filesystem; write updates into a sparse file
|
|
||||||
named 'patch_file' to safely apply them later with e2patch(8) utility.
|
|
||||||
You'll also be able to create a backup before applying patch and safely
|
|
||||||
restore it in case of power outage or system crash.
|
|
||||||
.TP
|
|
||||||
.BI \-z " undo_file"
|
.BI \-z " undo_file"
|
||||||
Before overwriting a file system block, write the old contents of the block to
|
Before overwriting a file system block, write the old contents of the block to
|
||||||
an undo file. This undo file can be used with e2undo(8) to restore the old
|
an undo file. This undo file can be used with e2undo(8) to restore the old
|
||||||
|
|
|
@ -45,21 +45,19 @@ static void fix_uninit_block_bitmaps(ext2_filsys fs);
|
||||||
static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size);
|
static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size);
|
||||||
static errcode_t blocks_to_move(ext2_resize_t rfs);
|
static errcode_t blocks_to_move(ext2_resize_t rfs);
|
||||||
static errcode_t block_mover(ext2_resize_t rfs);
|
static errcode_t block_mover(ext2_resize_t rfs);
|
||||||
static errcode_t inodes_to_move(ext2_resize_t rfs);
|
|
||||||
static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
|
static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
|
||||||
static errcode_t inode_ref_fix(ext2_resize_t rfs);
|
static errcode_t inode_ref_fix(ext2_resize_t rfs);
|
||||||
static errcode_t move_itables(ext2_resize_t rfs);
|
static errcode_t move_itables(ext2_resize_t rfs);
|
||||||
static errcode_t move_inode_tables(ext2_resize_t rfs);
|
|
||||||
static errcode_t fix_resize_inode(ext2_filsys fs);
|
static errcode_t fix_resize_inode(ext2_filsys fs);
|
||||||
static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
|
static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
|
||||||
static errcode_t fix_sb_journal_backup(ext2_filsys fs);
|
static errcode_t fix_sb_journal_backup(ext2_filsys fs);
|
||||||
static errcode_t mark_table_blocks(ext2_filsys fs,
|
static errcode_t mark_table_blocks(ext2_filsys fs,
|
||||||
ext2fs_block_bitmap bmap, int skip_inode_tables);
|
ext2fs_block_bitmap bmap);
|
||||||
static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs);
|
static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs);
|
||||||
static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
|
static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
|
||||||
ext2fs_block_bitmap meta_bmap);
|
ext2fs_block_bitmap meta_bmap);
|
||||||
static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size);
|
static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size);
|
||||||
static errcode_t move_bg_metadata(ext2_resize_t rfs, __u32 new_inodes);
|
static errcode_t move_bg_metadata(ext2_resize_t rfs);
|
||||||
static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs);
|
static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -96,7 +94,7 @@ static int lazy_itable_init;
|
||||||
/*
|
/*
|
||||||
* This is the top-level routine which does the dirty deed....
|
* This is the top-level routine which does the dirty deed....
|
||||||
*/
|
*/
|
||||||
errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, __u32 new_inodes, int flags,
|
errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
|
||||||
errcode_t (*progress)(ext2_resize_t rfs, int pass,
|
errcode_t (*progress)(ext2_resize_t rfs, int pass,
|
||||||
unsigned long cur,
|
unsigned long cur,
|
||||||
unsigned long max_val))
|
unsigned long max_val))
|
||||||
|
@ -144,7 +142,7 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, __u32 new_inodes, int fla
|
||||||
print_resource_track(rfs, &rtrack, fs->io);
|
print_resource_track(rfs, &rtrack, fs->io);
|
||||||
|
|
||||||
init_resource_track(&rtrack, "move_bg_metadata", fs->io);
|
init_resource_track(&rtrack, "move_bg_metadata", fs->io);
|
||||||
retval = move_bg_metadata(rfs, new_inodes);
|
retval = move_bg_metadata(rfs);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
print_resource_track(rfs, &rtrack, fs->io);
|
print_resource_track(rfs, &rtrack, fs->io);
|
||||||
|
@ -190,18 +188,6 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, __u32 new_inodes, int fla
|
||||||
goto errout;
|
goto errout;
|
||||||
print_resource_track(rfs, &rtrack, fs->io);
|
print_resource_track(rfs, &rtrack, fs->io);
|
||||||
|
|
||||||
init_resource_track(&rtrack, "inodes_to_move", fs->io);
|
|
||||||
retval = inodes_to_move(rfs);
|
|
||||||
if (retval)
|
|
||||||
goto errout;
|
|
||||||
print_resource_track(rfs, &rtrack, fs->io);
|
|
||||||
|
|
||||||
init_resource_track(&rtrack, "move_inode_tables", fs->io);
|
|
||||||
retval = move_inode_tables(rfs);
|
|
||||||
if (retval)
|
|
||||||
goto errout;
|
|
||||||
print_resource_track(rfs, &rtrack, fs->io);
|
|
||||||
|
|
||||||
init_resource_track(&rtrack, "inode_scan_and_fix", fs->io);
|
init_resource_track(&rtrack, "inode_scan_and_fix", fs->io);
|
||||||
retval = inode_scan_and_fix(rfs);
|
retval = inode_scan_and_fix(rfs);
|
||||||
if (retval)
|
if (retval)
|
||||||
|
@ -214,11 +200,11 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, __u32 new_inodes, int fla
|
||||||
goto errout;
|
goto errout;
|
||||||
print_resource_track(rfs, &rtrack, fs->io);
|
print_resource_track(rfs, &rtrack, fs->io);
|
||||||
|
|
||||||
/* init_resource_track(&rtrack, "move_itables", fs->io);
|
init_resource_track(&rtrack, "move_itables", fs->io);
|
||||||
retval = move_itables(rfs);
|
retval = move_itables(rfs);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
print_resource_track(rfs, &rtrack, fs->io);*/
|
print_resource_track(rfs, &rtrack, fs->io);
|
||||||
|
|
||||||
retval = clear_sparse_super2_last_group(rfs);
|
retval = clear_sparse_super2_last_group(rfs);
|
||||||
if (retval)
|
if (retval)
|
||||||
|
@ -358,39 +344,8 @@ static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Inode table resizing:
|
|
||||||
* 1) move_bg_metadata(), calls set_inode_count(): set new inode count
|
|
||||||
* 2) adjust_superblock(): extend bitmaps, write group descriptors
|
|
||||||
* 3) blocks_to_move(): allocate new inode tables and, when extending inode tables,
|
|
||||||
* mark extra blocks needed for new inode tables as 'blocks to move'
|
|
||||||
* 4) block_mover(): move blocks out of the way as usual
|
|
||||||
* 5) inodes_to_move(): when shrinking inode tables, move inodes from the end
|
|
||||||
* of each group's inode table (still operating on old fs inode tables).
|
|
||||||
* it would be possible to rewrite blocks on step 7, but we need to read
|
|
||||||
* extents, and they may be overwritten by inode tables on step 6.
|
|
||||||
* so, rewrite blocks used by inodes here!
|
|
||||||
* 6) move_inode_tables(): move inode tables
|
|
||||||
* 7) inode_scan_and_fix(): rewrite all inode, extent, extattr and ACL checksums
|
|
||||||
* 8) inode_ref_fix(): translate inode numbers (operating on new fs inode tables)
|
|
||||||
*/
|
|
||||||
static int set_inode_count(ext2_filsys fs, __u32 new_inodes)
|
|
||||||
{
|
|
||||||
__u32 old_ipg = fs->super->s_inodes_per_group;
|
|
||||||
__u32 new_ipg = ((new_inodes + fs->group_desc_count - 1) / fs->group_desc_count);
|
|
||||||
new_ipg = (((new_ipg * EXT2_INODE_SIZE(fs->super)) + EXT2_BLOCK_SIZE(fs->super) - 1) / EXT2_BLOCK_SIZE(fs->super))
|
|
||||||
* EXT2_BLOCK_SIZE(fs->super) / EXT2_INODE_SIZE(fs->super);
|
|
||||||
if (new_ipg == old_ipg)
|
|
||||||
return -1;
|
|
||||||
fs->inode_blocks_per_group = new_ipg * EXT2_INODE_SIZE(fs->super) / EXT2_BLOCK_SIZE(fs->super);
|
|
||||||
fs->super->s_inodes_per_group = new_ipg;
|
|
||||||
fs->super->s_inodes_count = fs->group_desc_count * fs->super->s_inodes_per_group;
|
|
||||||
fs->super->s_free_inodes_count += fs->group_desc_count * (new_ipg - old_ipg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move bitmaps/inode tables out of the way. */
|
/* Move bitmaps/inode tables out of the way. */
|
||||||
static errcode_t move_bg_metadata(ext2_resize_t rfs, __u32 new_inodes)
|
static errcode_t move_bg_metadata(ext2_resize_t rfs)
|
||||||
{
|
{
|
||||||
dgrp_t i;
|
dgrp_t i;
|
||||||
blk64_t b, c, d, old_desc_blocks, new_desc_blocks, j;
|
blk64_t b, c, d, old_desc_blocks, new_desc_blocks, j;
|
||||||
|
@ -399,12 +354,7 @@ static errcode_t move_bg_metadata(ext2_resize_t rfs, __u32 new_inodes)
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
int cluster_ratio;
|
int cluster_ratio;
|
||||||
|
|
||||||
if (new_inodes) {
|
if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
|
||||||
if (set_inode_count(rfs->new_fs, new_inodes) != 0)
|
|
||||||
new_inodes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!new_inodes && !(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
retval = ext2fs_allocate_block_bitmap(rfs->old_fs, "oldfs", &old_map);
|
retval = ext2fs_allocate_block_bitmap(rfs->old_fs, "oldfs", &old_map);
|
||||||
|
@ -694,7 +644,7 @@ static errcode_t free_gdp_blocks(ext2_filsys fs,
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
retval = mark_table_blocks(fs, bg_map, 0);
|
retval = mark_table_blocks(fs, bg_map);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1061,7 +1011,7 @@ retry:
|
||||||
* number of the block group descriptors.
|
* number of the block group descriptors.
|
||||||
*/
|
*/
|
||||||
if (reserve_blocks)
|
if (reserve_blocks)
|
||||||
mark_table_blocks(fs, reserve_blocks, 0);
|
mark_table_blocks(fs, reserve_blocks);
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
return (retval);
|
return (retval);
|
||||||
|
@ -1195,7 +1145,7 @@ errout:
|
||||||
* filesystem meta-data blocks.
|
* filesystem meta-data blocks.
|
||||||
*/
|
*/
|
||||||
static errcode_t mark_table_blocks(ext2_filsys fs,
|
static errcode_t mark_table_blocks(ext2_filsys fs,
|
||||||
ext2fs_block_bitmap bmap, int skip_inode_tables)
|
ext2fs_block_bitmap bmap)
|
||||||
{
|
{
|
||||||
dgrp_t i;
|
dgrp_t i;
|
||||||
blk64_t blk;
|
blk64_t blk;
|
||||||
|
@ -1206,12 +1156,10 @@ static errcode_t mark_table_blocks(ext2_filsys fs,
|
||||||
/*
|
/*
|
||||||
* Mark the blocks used for the inode table
|
* Mark the blocks used for the inode table
|
||||||
*/
|
*/
|
||||||
if (!skip_inode_tables) {
|
blk = ext2fs_inode_table_loc(fs, i);
|
||||||
blk = ext2fs_inode_table_loc(fs, i);
|
if (blk)
|
||||||
if (blk)
|
ext2fs_mark_block_bitmap_range2(bmap, blk,
|
||||||
ext2fs_mark_block_bitmap_range2(bmap, blk,
|
fs->inode_blocks_per_group);
|
||||||
fs->inode_blocks_per_group);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark block used for the block bitmap
|
* Mark block used for the block bitmap
|
||||||
|
@ -1335,69 +1283,12 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
retval = mark_table_blocks(old_fs, meta_bmap, 0);
|
retval = mark_table_blocks(old_fs, meta_bmap);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
fs = rfs->new_fs;
|
fs = rfs->new_fs;
|
||||||
|
|
||||||
/**
|
|
||||||
* If we're resizing inode tables, we need to reallocate all of them
|
|
||||||
*/
|
|
||||||
if (rfs->old_fs->inode_blocks_per_group != fs->inode_blocks_per_group) {
|
|
||||||
dgrp_t flexbg_size, flex_count, grp_in_flex;
|
|
||||||
ext2fs_block_bitmap empty_bmap;
|
|
||||||
/* // this is how mke2fs allocates inode tables...
|
|
||||||
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, fs,
|
|
||||||
fs->super->s_first_data_block,
|
|
||||||
ext2fs_blocks_count(fs->super)-1,
|
|
||||||
ext2fs_blocks_count(fs->super)-1, "subcluster inode table bitmap", 0, &empty_bmap);*/
|
|
||||||
retval = ext2fs_allocate_block_bitmap(fs, _("metadata without inode tables"), &empty_bmap);
|
|
||||||
if (retval) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
retval = mark_table_blocks(fs, empty_bmap, 1);
|
|
||||||
if (retval) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
if (EXT2_HAS_INCOMPAT_FEATURE(fs->super, EXT4_FEATURE_INCOMPAT_FLEX_BG)
|
|
||||||
&& fs->super->s_log_groups_per_flex) {
|
|
||||||
flexbg_size = 1 << fs->super->s_log_groups_per_flex;
|
|
||||||
} else {
|
|
||||||
flexbg_size = 1;
|
|
||||||
}
|
|
||||||
flex_count = (fs->group_desc_count + flexbg_size - 1) / flexbg_size;
|
|
||||||
for (g = 0; g < fs->group_desc_count; g++) {
|
|
||||||
ext2fs_inode_table_loc_set(fs, g, 0);
|
|
||||||
retval = ext2fs_allocate_group_table(fs, g, empty_bmap);
|
|
||||||
if (retval) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
/* ext2fs_mark_block_bitmap_range2(empty_bmap,
|
|
||||||
ext2fs_inode_table_loc(fs, g), fs->inode_blocks_per_group);*/
|
|
||||||
group_blk = ext2fs_inode_table_loc(fs, g);
|
|
||||||
if (g > 0 && group_blk < ext2fs_inode_table_loc(fs, g-1)+fs->inode_blocks_per_group) {
|
|
||||||
ext2fs_unmark_block_bitmap_range2(fs->block_map, group_blk, fs->inode_blocks_per_group);
|
|
||||||
group_blk = ext2fs_inode_table_loc(fs, g-1)+fs->inode_blocks_per_group;
|
|
||||||
ext2fs_inode_table_loc_set(fs, g, group_blk);
|
|
||||||
ext2fs_group_desc_csum_set(fs, g);
|
|
||||||
ext2fs_mark_block_bitmap_range2(fs->block_map, group_blk, fs->inode_blocks_per_group);
|
|
||||||
}
|
|
||||||
group_blk += fs->inode_blocks_per_group;
|
|
||||||
// We may need to move some blocks away (mainly if extending inode tables)
|
|
||||||
for (blk = ext2fs_inode_table_loc(fs, g); blk < group_blk; blk++) {
|
|
||||||
if (blk < ext2fs_blocks_count(old_fs->super) &&
|
|
||||||
ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
|
|
||||||
!ext2fs_test_block_bitmap2(meta_bmap, blk)) {
|
|
||||||
ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
|
|
||||||
rfs->needed_blocks++;
|
|
||||||
}
|
|
||||||
ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ext2fs_free_block_bitmap(empty_bmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're shrinking the filesystem, we need to move any
|
* If we're shrinking the filesystem, we need to move any
|
||||||
* group's metadata blocks (either allocation bitmaps or the
|
* group's metadata blocks (either allocation bitmaps or the
|
||||||
|
@ -1496,7 +1387,7 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
retval = mark_table_blocks(fs, new_meta_bmap, 0);
|
retval = mark_table_blocks(fs, new_meta_bmap);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
@ -1957,7 +1848,7 @@ static int process_block(ext2_filsys fs, blk64_t *block_nr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pb->is_dir && fs->dblist) {
|
if (pb->is_dir) {
|
||||||
retval = ext2fs_add_dir_block2(fs->dblist, pb->ino,
|
retval = ext2fs_add_dir_block2(fs->dblist, pb->ino,
|
||||||
block, (int) blockcnt);
|
block, (int) blockcnt);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
|
@ -2004,27 +1895,27 @@ static errcode_t migrate_ea_block(ext2_resize_t rfs, ext2_ino_t ino,
|
||||||
errcode_t err = 0;
|
errcode_t err = 0;
|
||||||
|
|
||||||
/* No EA block or no remapping? Quit early. */
|
/* No EA block or no remapping? Quit early. */
|
||||||
if (ext2fs_file_acl_block(rfs->new_fs, inode) == 0 || !rfs->bmap)
|
if (ext2fs_file_acl_block(rfs->old_fs, inode) == 0 || !rfs->bmap)
|
||||||
return 0;
|
return 0;
|
||||||
new_block = extent_translate(rfs->new_fs, rfs->bmap,
|
new_block = extent_translate(rfs->old_fs, rfs->bmap,
|
||||||
ext2fs_file_acl_block(rfs->new_fs, inode));
|
ext2fs_file_acl_block(rfs->old_fs, inode));
|
||||||
if (new_block == 0)
|
if (new_block == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Set the new ACL block */
|
/* Set the new ACL block */
|
||||||
ext2fs_file_acl_block_set(rfs->new_fs, inode, new_block);
|
ext2fs_file_acl_block_set(rfs->old_fs, inode, new_block);
|
||||||
|
|
||||||
/* Update checksum */
|
/* Update checksum */
|
||||||
if (ext2fs_has_feature_metadata_csum(rfs->new_fs->super)) {
|
if (ext2fs_has_feature_metadata_csum(rfs->new_fs->super)) {
|
||||||
err = ext2fs_get_mem(rfs->new_fs->blocksize, &buf);
|
err = ext2fs_get_mem(rfs->old_fs->blocksize, &buf);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
rfs->new_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
err = ext2fs_read_ext_attr3(rfs->new_fs, new_block, buf, ino);
|
err = ext2fs_read_ext_attr3(rfs->old_fs, new_block, buf, ino);
|
||||||
rfs->new_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
err = ext2fs_write_ext_attr3(rfs->new_fs, new_block, buf, ino);
|
err = ext2fs_write_ext_attr3(rfs->old_fs, new_block, buf, ino);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -2095,213 +1986,58 @@ static void quiet_com_err_proc(const char *whoami EXT2FS_ATTR((unused)),
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TRANSLATE_IPG(ino,old_fs,new_fs) (1 + (((ino)-1) % (old_fs)->super->s_inodes_per_group) + \
|
|
||||||
((ino)-1) / (old_fs)->super->s_inodes_per_group * (new_fs)->super->s_inodes_per_group)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move inodes and rewrite references to blocks moved in blocks_to_move()
|
|
||||||
*/
|
|
||||||
static errcode_t inodes_to_move(ext2_resize_t rfs)
|
|
||||||
{
|
|
||||||
struct process_block_struct pb;
|
|
||||||
ext2_ino_t ino, new_inode, tr_ino;
|
|
||||||
struct ext2_inode *inode = NULL;
|
|
||||||
ext2_inode_scan scan = NULL;
|
|
||||||
errcode_t retval;
|
|
||||||
dgrp_t g, old_g;
|
|
||||||
char *block_buf = 0;
|
|
||||||
ext2_ino_t start_to_move;
|
|
||||||
int inode_size;
|
|
||||||
int shrink_inodes = rfs->old_fs->inode_blocks_per_group > rfs->new_fs->inode_blocks_per_group;
|
|
||||||
int change_inodes = rfs->old_fs->inode_blocks_per_group != rfs->new_fs->inode_blocks_per_group;
|
|
||||||
|
|
||||||
if ((rfs->old_fs->group_desc_count <=
|
|
||||||
rfs->new_fs->group_desc_count) &&
|
|
||||||
!rfs->bmap &&
|
|
||||||
!change_inodes)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan);
|
|
||||||
if (retval) goto errout;
|
|
||||||
|
|
||||||
start_to_move = (rfs->new_fs->group_desc_count *
|
|
||||||
rfs->old_fs->super->s_inodes_per_group);
|
|
||||||
for (ino = start_to_move+1; ino <= rfs->old_fs->group_desc_count * rfs->old_fs->super->s_inodes_per_group; ino++) {
|
|
||||||
ext2fs_mark_inode_bitmap2(rfs->old_fs->inode_map, ino);
|
|
||||||
}
|
|
||||||
if (shrink_inodes) {
|
|
||||||
for (g = 0; g < rfs->old_fs->group_desc_count; g++) {
|
|
||||||
ext2_ino_t first_ino = 1+rfs->old_fs->super->s_inodes_per_group*g;
|
|
||||||
for (ino = first_ino+rfs->new_fs->super->s_inodes_per_group; ino < first_ino+rfs->old_fs->super->s_inodes_per_group; ino++) {
|
|
||||||
ext2fs_mark_inode_bitmap2(rfs->old_fs->inode_map, ino);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = ext2fs_get_array(rfs->new_fs->blocksize, 3, &block_buf);
|
|
||||||
if (retval) goto errout;
|
|
||||||
|
|
||||||
inode_size = EXT2_INODE_SIZE(rfs->new_fs->super);
|
|
||||||
inode = malloc(inode_size);
|
|
||||||
if (!inode) {
|
|
||||||
retval = ENOMEM;
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
pb.rfs = rfs;
|
|
||||||
pb.inode = inode;
|
|
||||||
pb.error = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First, copy all of the inodes that need to be moved
|
|
||||||
* elsewhere in the inode table
|
|
||||||
*/
|
|
||||||
while (1) {
|
|
||||||
retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
|
|
||||||
if (retval) goto errout;
|
|
||||||
if (!ino)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO)
|
|
||||||
continue; /* inode not in use */
|
|
||||||
|
|
||||||
new_inode = ino;
|
|
||||||
if (ino > start_to_move ||
|
|
||||||
(shrink_inodes && (ino-1) % rfs->old_fs->super->s_inodes_per_group >= rfs->new_fs->super->s_inodes_per_group))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Find a new inode. Now that extents and directory blocks
|
|
||||||
* are tied to the inode number through the checksum, we must
|
|
||||||
* set up the new inode before we start rewriting blocks.
|
|
||||||
*/
|
|
||||||
retval = ext2fs_new_inode(rfs->old_fs, 0, 0, 0, &new_inode);
|
|
||||||
if (retval)
|
|
||||||
goto errout;
|
|
||||||
|
|
||||||
/* Translate inode number according to new inodes_per_group */
|
|
||||||
tr_ino = TRANSLATE_IPG(new_inode, rfs->old_fs, rfs->new_fs);
|
|
||||||
|
|
||||||
old_g = ext2fs_group_of_ino(rfs->old_fs, ino);
|
|
||||||
ext2fs_inode_alloc_stats2(rfs->old_fs, new_inode, +1, LINUX_S_ISDIR(inode->i_mode));
|
|
||||||
if (old_g < rfs->new_fs->group_desc_count)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Don't bother to adjust free_inodes_count for group because freed
|
|
||||||
* inodes will be accounted as part of inodes_per_group change
|
|
||||||
*/
|
|
||||||
if (LINUX_S_ISDIR(inode->i_mode))
|
|
||||||
ext2fs_bg_used_dirs_count_set(rfs->new_fs, old_g, ext2fs_bg_used_dirs_count(rfs->new_fs, old_g) - 1);
|
|
||||||
ext2fs_group_desc_csum_set(rfs->new_fs, old_g);
|
|
||||||
}
|
|
||||||
ext2fs_inode_alloc_stats2(rfs->new_fs, tr_ino, +1, LINUX_S_ISDIR(inode->i_mode));
|
|
||||||
inode->i_ctime = time(0);
|
|
||||||
retval = ext2fs_write_inode_full(rfs->old_fs, new_inode, inode, inode_size);
|
|
||||||
if (retval)
|
|
||||||
goto errout;
|
|
||||||
|
|
||||||
#ifdef RESIZE2FS_DEBUG
|
|
||||||
if (rfs->flags & RESIZE_DEBUG_INODEMAP)
|
|
||||||
printf("Inode moved %u->%u\n", ino, new_inode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!rfs->imap) {
|
|
||||||
retval = ext2fs_create_extent_table(&rfs->imap, 0);
|
|
||||||
if (retval)
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
ext2fs_add_extent_entry(rfs->imap, ino, new_inode);
|
|
||||||
|
|
||||||
// continue with rewritten inode number
|
|
||||||
ino = new_inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update inodes to point to new blocks.
|
|
||||||
*/
|
|
||||||
if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) && rfs->bmap) {
|
|
||||||
pb.changed = 0;
|
|
||||||
pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
|
|
||||||
pb.ino = ino;
|
|
||||||
pb.old_ino = ino; // FIXME debug output will show translated inodes
|
|
||||||
pb.has_extents = inode->i_flags & EXT4_EXTENTS_FL;
|
|
||||||
rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
|
||||||
retval = ext2fs_block_iterate3(rfs->old_fs,
|
|
||||||
ino, 0, block_buf,
|
|
||||||
process_block, &pb);
|
|
||||||
rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
|
||||||
if (retval)
|
|
||||||
goto errout;
|
|
||||||
if (pb.error) {
|
|
||||||
retval = pb.error;
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errout:
|
|
||||||
if (scan)
|
|
||||||
ext2fs_close_inode_scan(scan);
|
|
||||||
if (block_buf)
|
|
||||||
ext2fs_free_mem(&block_buf);
|
|
||||||
free(inode);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remap extattr blocks, rewrite inode and extattr checksums
|
|
||||||
* and schedule directory blocks for inode remapping
|
|
||||||
*/
|
|
||||||
static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
|
static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
|
||||||
{
|
{
|
||||||
struct process_block_struct pb;
|
struct process_block_struct pb;
|
||||||
ext2_ino_t ino, tr_ino;
|
ext2_ino_t ino, new_inode;
|
||||||
struct ext2_inode *inode = NULL;
|
struct ext2_inode *inode = NULL;
|
||||||
ext2_inode_scan scan = NULL;
|
ext2_inode_scan scan = NULL;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
dgrp_t g;
|
|
||||||
char *block_buf = 0;
|
char *block_buf = 0;
|
||||||
|
ext2_ino_t start_to_move;
|
||||||
int inode_size;
|
int inode_size;
|
||||||
int change_inodes = rfs->old_fs->inode_blocks_per_group != rfs->new_fs->inode_blocks_per_group;
|
|
||||||
|
|
||||||
if ((rfs->old_fs->group_desc_count <=
|
if ((rfs->old_fs->group_desc_count <=
|
||||||
rfs->new_fs->group_desc_count) &&
|
rfs->new_fs->group_desc_count) &&
|
||||||
!rfs->bmap &&
|
!rfs->bmap)
|
||||||
!change_inodes)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
set_com_err_hook(quiet_com_err_proc);
|
set_com_err_hook(quiet_com_err_proc);
|
||||||
|
|
||||||
retval = ext2fs_open_inode_scan(rfs->new_fs, 0, &scan);
|
retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan);
|
||||||
if (retval) goto errout;
|
if (retval) goto errout;
|
||||||
|
|
||||||
retval = ext2fs_init_dblist(rfs->new_fs, 0);
|
retval = ext2fs_init_dblist(rfs->old_fs, 0);
|
||||||
if (retval) goto errout;
|
if (retval) goto errout;
|
||||||
retval = ext2fs_get_array(rfs->new_fs->blocksize, 3, &block_buf);
|
retval = ext2fs_get_array(rfs->old_fs->blocksize, 3, &block_buf);
|
||||||
if (retval) goto errout;
|
if (retval) goto errout;
|
||||||
|
|
||||||
|
start_to_move = (rfs->new_fs->group_desc_count *
|
||||||
|
rfs->new_fs->super->s_inodes_per_group);
|
||||||
|
|
||||||
if (rfs->progress) {
|
if (rfs->progress) {
|
||||||
retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
|
retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
|
||||||
0, rfs->new_fs->group_desc_count);
|
0, rfs->old_fs->group_desc_count);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs);
|
ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs);
|
||||||
|
pb.rfs = rfs;
|
||||||
|
pb.inode = inode;
|
||||||
|
pb.error = 0;
|
||||||
|
new_inode = EXT2_FIRST_INODE(rfs->new_fs->super);
|
||||||
inode_size = EXT2_INODE_SIZE(rfs->new_fs->super);
|
inode_size = EXT2_INODE_SIZE(rfs->new_fs->super);
|
||||||
inode = malloc(inode_size);
|
inode = malloc(inode_size);
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
retval = ENOMEM;
|
retval = ENOMEM;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
pb.rfs = rfs;
|
|
||||||
pb.inode = inode;
|
|
||||||
pb.error = 0;
|
|
||||||
/*
|
/*
|
||||||
* First, copy all of the inodes that need to be moved
|
* First, copy all of the inodes that need to be moved
|
||||||
* elsewhere in the inode table
|
* elsewhere in the inode table
|
||||||
*/
|
*/
|
||||||
while (1) {
|
while (1) {
|
||||||
rfs->new_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
|
||||||
retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
|
retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
|
||||||
rfs->new_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
|
||||||
if (retval) goto errout;
|
if (retval) goto errout;
|
||||||
if (!ino)
|
if (!ino)
|
||||||
break;
|
break;
|
||||||
|
@ -2310,58 +2046,95 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
|
||||||
continue; /* inode not in use */
|
continue; /* inode not in use */
|
||||||
|
|
||||||
pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
|
pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
|
||||||
pb.changed = change_inodes;
|
pb.changed = 0;
|
||||||
|
|
||||||
/* Remap EA block */
|
/* Remap EA block */
|
||||||
retval = migrate_ea_block(rfs, ino, inode, &pb.changed);
|
retval = migrate_ea_block(rfs, ino, inode, &pb.changed);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
|
new_inode = ino;
|
||||||
|
if (ino <= start_to_move)
|
||||||
|
goto remap_blocks; /* Don't need to move inode. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a new inode. Now that extents and directory blocks
|
||||||
|
* are tied to the inode number through the checksum, we must
|
||||||
|
* set up the new inode before we start rewriting blocks.
|
||||||
|
*/
|
||||||
|
retval = ext2fs_new_inode(rfs->new_fs, 0, 0, 0, &new_inode);
|
||||||
|
if (retval)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
|
ext2fs_inode_alloc_stats2(rfs->new_fs, new_inode, +1,
|
||||||
|
pb.is_dir);
|
||||||
|
inode->i_ctime = time(0);
|
||||||
|
retval = ext2fs_write_inode_full(rfs->old_fs, new_inode,
|
||||||
|
inode, inode_size);
|
||||||
|
if (retval)
|
||||||
|
goto errout;
|
||||||
|
pb.changed = 0;
|
||||||
|
|
||||||
|
#ifdef RESIZE2FS_DEBUG
|
||||||
|
if (rfs->flags & RESIZE_DEBUG_INODEMAP)
|
||||||
|
printf("Inode moved %u->%u\n", ino, new_inode);
|
||||||
|
#endif
|
||||||
|
if (!rfs->imap) {
|
||||||
|
retval = ext2fs_create_extent_table(&rfs->imap, 0);
|
||||||
|
if (retval)
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
ext2fs_add_extent_entry(rfs->imap, ino, new_inode);
|
||||||
|
|
||||||
|
remap_blocks:
|
||||||
if (pb.changed)
|
if (pb.changed)
|
||||||
retval = ext2fs_write_inode_full(rfs->new_fs,
|
retval = ext2fs_write_inode_full(rfs->old_fs,
|
||||||
ino,
|
new_inode,
|
||||||
inode, inode_size);
|
inode, inode_size);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
/* Rewrite extent block checksums with new inode number */
|
/* Rewrite extent block checksums with new inode number */
|
||||||
if (ext2fs_has_feature_metadata_csum(rfs->new_fs->super) &&
|
if (ext2fs_has_feature_metadata_csum(rfs->old_fs->super) &&
|
||||||
(inode->i_flags & EXT4_EXTENTS_FL)) {
|
(inode->i_flags & EXT4_EXTENTS_FL)) {
|
||||||
rfs->new_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
retval = rewrite_extents(rfs->new_fs, ino);
|
retval = rewrite_extents(rfs->old_fs, new_inode);
|
||||||
rfs->new_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Schedule directory blocks for inode remapping. Need to write out dir blocks
|
* Update inodes to point to new blocks; schedule directory
|
||||||
|
* blocks for inode remapping. Need to write out dir blocks
|
||||||
* with new inode numbers if we have metadata_csum enabled.
|
* with new inode numbers if we have metadata_csum enabled.
|
||||||
*/
|
*/
|
||||||
if (ext2fs_inode_has_valid_blocks2(rfs->new_fs, inode) && pb.is_dir) {
|
if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) &&
|
||||||
pb.ino = ino;
|
(rfs->bmap || pb.is_dir)) {
|
||||||
pb.old_ino = ino; // FIXME: Debug output will show translated inodes
|
pb.ino = new_inode;
|
||||||
|
pb.old_ino = ino;
|
||||||
pb.has_extents = inode->i_flags & EXT4_EXTENTS_FL;
|
pb.has_extents = inode->i_flags & EXT4_EXTENTS_FL;
|
||||||
rfs->new_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
retval = ext2fs_block_iterate3(rfs->new_fs,
|
retval = ext2fs_block_iterate3(rfs->old_fs,
|
||||||
ino, 0, block_buf,
|
new_inode, 0, block_buf,
|
||||||
process_block, &pb);
|
process_block, &pb);
|
||||||
rfs->new_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
if (pb.error) {
|
if (pb.error) {
|
||||||
retval = pb.error;
|
retval = pb.error;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
} else if ((inode->i_flags & EXT4_INLINE_DATA_FL) && pb.is_dir) {
|
} else if ((inode->i_flags & EXT4_INLINE_DATA_FL) &&
|
||||||
|
(rfs->bmap || pb.is_dir)) {
|
||||||
/* inline data dir; update it too */
|
/* inline data dir; update it too */
|
||||||
retval = ext2fs_add_dir_block2(rfs->new_fs->dblist,
|
retval = ext2fs_add_dir_block2(rfs->old_fs->dblist,
|
||||||
tr_ino, 0, 0);
|
new_inode, 0, 0);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
io_channel_flush(rfs->new_fs->io);
|
io_channel_flush(rfs->old_fs->io);
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
reset_com_err_hook();
|
reset_com_err_hook();
|
||||||
|
@ -2377,140 +2150,6 @@ errout:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static errcode_t move_inode_tables(ext2_resize_t rfs)
|
|
||||||
{
|
|
||||||
dgrp_t g, end_g, group_count;
|
|
||||||
dgrp_t move_start, move_count;
|
|
||||||
__u32 old_ipg = rfs->old_fs->super->s_inodes_per_group;
|
|
||||||
__u32 new_ipg = rfs->new_fs->super->s_inodes_per_group;
|
|
||||||
__u32 old_ibg = rfs->old_fs->inode_blocks_per_group;
|
|
||||||
__u32 new_ibg = rfs->new_fs->inode_blocks_per_group;
|
|
||||||
int retval;
|
|
||||||
blk64_t size, blk, ib;
|
|
||||||
int change_inodes = old_ibg != new_ibg;
|
|
||||||
__u32 unused, ino, old_ino, i;
|
|
||||||
ext2fs_block_bitmap meta_bmap = NULL;
|
|
||||||
|
|
||||||
retval = ext2fs_allocate_block_bitmap(rfs->new_fs, _("meta-data blocks"), &meta_bmap);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
retval = mark_table_blocks(rfs->new_fs, meta_bmap, 1);
|
|
||||||
|
|
||||||
printf("inode blocks per group: %u to %u\n", old_ibg, new_ibg);
|
|
||||||
size = old_ibg;
|
|
||||||
size = size < new_ibg ? size : new_ibg;
|
|
||||||
move_count = 0;
|
|
||||||
group_count = rfs->new_fs->group_desc_count;
|
|
||||||
group_count = group_count < rfs->old_fs->group_desc_count ? group_count : rfs->old_fs->group_desc_count;
|
|
||||||
for (g = 0; g < group_count; g++)
|
|
||||||
{
|
|
||||||
if (change_inodes)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* new_fs may have incorrect itable_unused because we're not adjusting it
|
|
||||||
* before calling inode_alloc_stats2 in inodes_to_move().
|
|
||||||
* and it's OK to take free_inodes_count from old_fs because any inodes
|
|
||||||
* that are freed may only lay in shrinked inode table areas.
|
|
||||||
*/
|
|
||||||
unused = ext2fs_bg_itable_unused(rfs->old_fs, g);
|
|
||||||
if (new_ipg < old_ipg && unused < old_ipg-new_ipg)
|
|
||||||
unused = 0;
|
|
||||||
else
|
|
||||||
unused = unused + new_ipg - old_ipg;
|
|
||||||
ext2fs_bg_itable_unused_set(rfs->new_fs, g, unused);
|
|
||||||
ext2fs_bg_free_inodes_count_set(rfs->new_fs, g,
|
|
||||||
ext2fs_bg_free_inodes_count(rfs->old_fs, g) + new_ipg - old_ipg);
|
|
||||||
ext2fs_group_desc_csum_set(rfs->new_fs, g);
|
|
||||||
}
|
|
||||||
printf("g%u = [%u?] %u->%u free=%u->%u unused=%u->%u\n", g,
|
|
||||||
g > 0 ? ext2fs_inode_table_loc(rfs->old_fs, g-1)+old_ibg : 0,
|
|
||||||
ext2fs_inode_table_loc(rfs->old_fs, g),
|
|
||||||
ext2fs_inode_table_loc(rfs->new_fs, g),
|
|
||||||
ext2fs_bg_free_inodes_count(rfs->old_fs, g),
|
|
||||||
ext2fs_bg_free_inodes_count(rfs->new_fs, g),
|
|
||||||
ext2fs_bg_itable_unused(rfs->old_fs, g),
|
|
||||||
ext2fs_bg_itable_unused(rfs->new_fs, g));
|
|
||||||
if (change_inodes || ext2fs_inode_table_loc(rfs->new_fs, g) != ext2fs_inode_table_loc(rfs->old_fs, g))
|
|
||||||
{
|
|
||||||
move_count++;
|
|
||||||
if (move_count == 1)
|
|
||||||
move_start = g;
|
|
||||||
// check for overlap
|
|
||||||
if (g < rfs->new_fs->group_desc_count-1 &&
|
|
||||||
ext2fs_inode_table_loc(rfs->new_fs, g)+new_ibg > ext2fs_inode_table_loc(rfs->old_fs, g+1))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (move_count > 0)
|
|
||||||
{
|
|
||||||
end_g = g;
|
|
||||||
for (i = 0, g = move_start+move_count-1; i < move_count; i++, g--)
|
|
||||||
{
|
|
||||||
if (!ext2fs_has_group_desc_csum(rfs->new_fs) ||
|
|
||||||
!ext2fs_bg_flags_test(rfs->new_fs, g, EXT2_BG_INODE_UNINIT))
|
|
||||||
{
|
|
||||||
retval = io_channel_read_blk64(rfs->new_fs->io, ext2fs_inode_table_loc(rfs->old_fs, g), size, rfs->itable_buf);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
retval = io_channel_write_blk64(rfs->new_fs->io, ext2fs_inode_table_loc(rfs->new_fs, g), size, rfs->itable_buf);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
if (new_ibg > old_ibg)
|
|
||||||
{
|
|
||||||
retval = ext2fs_zero_blocks2(rfs->new_fs,
|
|
||||||
ext2fs_inode_table_loc(rfs->new_fs, g)+old_ibg,
|
|
||||||
new_ibg-old_ibg, NULL, NULL);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
blk = ext2fs_inode_table_loc(rfs->old_fs, g);
|
|
||||||
for (ib = 0; ib < old_ibg; ib++)
|
|
||||||
if (!ext2fs_test_block_bitmap2(meta_bmap, blk+ib))
|
|
||||||
ext2fs_unmark_block_bitmap2(rfs->new_fs->block_map, blk+ib);
|
|
||||||
ext2fs_mark_block_bitmap_range2(rfs->new_fs->block_map, ext2fs_inode_table_loc(rfs->new_fs, g), new_ibg);
|
|
||||||
}
|
|
||||||
move_start = move_count = 0;
|
|
||||||
g = end_g;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (old_ipg < new_ipg)
|
|
||||||
{
|
|
||||||
for (g = 0; g < group_count; g++)
|
|
||||||
{
|
|
||||||
for (i = 0, old_ino = 1 + old_ipg*g, ino = 1 + new_ipg*g; i < old_ipg; i++, ino++, old_ino++)
|
|
||||||
{
|
|
||||||
if (ext2fs_test_inode_bitmap2(rfs->old_fs->inode_map, old_ino))
|
|
||||||
ext2fs_mark_inode_bitmap2(rfs->new_fs->inode_map, ino);
|
|
||||||
else
|
|
||||||
ext2fs_unmark_inode_bitmap2(rfs->new_fs->inode_map, ino);
|
|
||||||
}
|
|
||||||
for (i = old_ipg, ino = 1 + new_ipg*g + old_ipg; i < new_ipg; i++, ino++)
|
|
||||||
ext2fs_unmark_inode_bitmap2(rfs->new_fs->inode_map, ino);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (old_ipg > new_ipg)
|
|
||||||
{
|
|
||||||
dgrp_t n;
|
|
||||||
for (n = 0, g = group_count-1; n < group_count; n++, g--)
|
|
||||||
{
|
|
||||||
for (i = 0, old_ino = 1 + old_ipg*g, ino = 1 + new_ipg*g; i < new_ipg; i++, ino++, old_ino++)
|
|
||||||
{
|
|
||||||
if (ext2fs_test_inode_bitmap2(rfs->old_fs->inode_map, old_ino))
|
|
||||||
ext2fs_mark_inode_bitmap2(rfs->new_fs->inode_map, ino);
|
|
||||||
else
|
|
||||||
ext2fs_unmark_inode_bitmap2(rfs->new_fs->inode_map, ino);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ext2fs_free_block_bitmap(meta_bmap);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------
|
/* --------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Resize processing, phase 4.
|
* Resize processing, phase 4.
|
||||||
|
@ -2537,10 +2176,9 @@ static int check_and_change_inodes(ext2_ino_t dir,
|
||||||
ext2_ino_t new_inode;
|
ext2_ino_t new_inode;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
ext2_ino_t old_dir = TRANSLATE_IPG(dir, is->rfs->new_fs, is->rfs->old_fs);
|
|
||||||
|
|
||||||
if (is->rfs->progress && offset == 0) {
|
if (is->rfs->progress && offset == 0) {
|
||||||
io_channel_flush(is->rfs->new_fs->io);
|
io_channel_flush(is->rfs->old_fs->io);
|
||||||
is->err = (is->rfs->progress)(is->rfs,
|
is->err = (is->rfs->progress)(is->rfs,
|
||||||
E2_RSZ_INODE_REF_UPD_PASS,
|
E2_RSZ_INODE_REF_UPD_PASS,
|
||||||
++is->num, is->max_dirs);
|
++is->num, is->max_dirs);
|
||||||
|
@ -2553,25 +2191,16 @@ static int check_and_change_inodes(ext2_ino_t dir,
|
||||||
* old fs, then we must rewrite all dir blocks with new checksums.
|
* old fs, then we must rewrite all dir blocks with new checksums.
|
||||||
*/
|
*/
|
||||||
if (ext2fs_has_feature_metadata_csum(is->rfs->old_fs->super) &&
|
if (ext2fs_has_feature_metadata_csum(is->rfs->old_fs->super) &&
|
||||||
!ext2fs_test_inode_bitmap2(is->rfs->old_fs->inode_map, old_dir))
|
!ext2fs_test_inode_bitmap2(is->rfs->old_fs->inode_map, dir))
|
||||||
ret |= DIRENT_CHANGED;
|
ret |= DIRENT_CHANGED;
|
||||||
|
|
||||||
if (!dirent->inode)
|
if (!dirent->inode)
|
||||||
{
|
|
||||||
if (old_dir != dir)
|
|
||||||
ret |= DIRENT_CHANGED;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
new_inode = 0;
|
new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode);
|
||||||
if (is->rfs->imap)
|
|
||||||
new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode);
|
|
||||||
if (!new_inode)
|
if (!new_inode)
|
||||||
new_inode = dirent->inode;
|
|
||||||
new_inode = TRANSLATE_IPG(new_inode, is->rfs->old_fs, is->rfs->new_fs);
|
|
||||||
if (new_inode == dirent->inode && old_dir == dir)
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#ifdef RESIZE2FS_DEBUG
|
#ifdef RESIZE2FS_DEBUG
|
||||||
if (is->rfs->flags & RESIZE_DEBUG_INODEMAP)
|
if (is->rfs->flags & RESIZE_DEBUG_INODEMAP)
|
||||||
printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n",
|
printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n",
|
||||||
|
@ -2582,10 +2211,10 @@ static int check_and_change_inodes(ext2_ino_t dir,
|
||||||
dirent->inode = new_inode;
|
dirent->inode = new_inode;
|
||||||
|
|
||||||
/* Update the directory mtime and ctime */
|
/* Update the directory mtime and ctime */
|
||||||
retval = ext2fs_read_inode(is->rfs->new_fs, dir, &inode);
|
retval = ext2fs_read_inode(is->rfs->old_fs, dir, &inode);
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
inode.i_mtime = inode.i_ctime = time(0);
|
inode.i_mtime = inode.i_ctime = time(0);
|
||||||
is->err = ext2fs_write_inode(is->rfs->new_fs, dir, &inode);
|
is->err = ext2fs_write_inode(is->rfs->old_fs, dir, &inode);
|
||||||
if (is->err)
|
if (is->err)
|
||||||
return ret | DIRENT_ABORT;
|
return ret | DIRENT_ABORT;
|
||||||
}
|
}
|
||||||
|
@ -2597,9 +2226,8 @@ static errcode_t inode_ref_fix(ext2_resize_t rfs)
|
||||||
{
|
{
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
struct istruct is;
|
struct istruct is;
|
||||||
int change_inodes = rfs->old_fs->inode_blocks_per_group != rfs->new_fs->inode_blocks_per_group;
|
|
||||||
|
|
||||||
if (!change_inodes && !rfs->imap)
|
if (!rfs->imap)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2607,7 +2235,7 @@ static errcode_t inode_ref_fix(ext2_resize_t rfs)
|
||||||
* inode references
|
* inode references
|
||||||
*/
|
*/
|
||||||
is.num = 0;
|
is.num = 0;
|
||||||
is.max_dirs = ext2fs_dblist_count2(rfs->new_fs->dblist);
|
is.max_dirs = ext2fs_dblist_count2(rfs->old_fs->dblist);
|
||||||
is.rfs = rfs;
|
is.rfs = rfs;
|
||||||
is.err = 0;
|
is.err = 0;
|
||||||
|
|
||||||
|
@ -2618,11 +2246,11 @@ static errcode_t inode_ref_fix(ext2_resize_t rfs)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
rfs->new_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
retval = ext2fs_dblist_dir_iterate(rfs->new_fs->dblist,
|
retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist,
|
||||||
DIRENT_FLAG_INCLUDE_EMPTY, 0,
|
DIRENT_FLAG_INCLUDE_EMPTY, 0,
|
||||||
check_and_change_inodes, &is);
|
check_and_change_inodes, &is);
|
||||||
rfs->new_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
if (is.err) {
|
if (is.err) {
|
||||||
|
@ -2635,8 +2263,7 @@ static errcode_t inode_ref_fix(ext2_resize_t rfs)
|
||||||
is.max_dirs, is.max_dirs);
|
is.max_dirs, is.max_dirs);
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
if (rfs->imap)
|
ext2fs_free_extent_table(rfs->imap);
|
||||||
ext2fs_free_extent_table(rfs->imap);
|
|
||||||
rfs->imap = 0;
|
rfs->imap = 0;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -2692,7 +2319,7 @@ static errcode_t move_itables(ext2_resize_t rfs)
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
retval = mark_table_blocks(fs, new_bmap, 0);
|
retval = mark_table_blocks(fs, new_bmap);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
@ -2804,7 +2431,7 @@ static errcode_t move_itables(ext2_resize_t rfs)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mark_table_blocks(fs, fs->block_map, 0);
|
mark_table_blocks(fs, fs->block_map);
|
||||||
ext2fs_flush(fs);
|
ext2fs_flush(fs);
|
||||||
#ifdef RESIZE2FS_DEBUG
|
#ifdef RESIZE2FS_DEBUG
|
||||||
if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
|
if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
|
||||||
|
|
|
@ -141,7 +141,7 @@ struct ext2_resize_struct {
|
||||||
|
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
extern errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, __u32 new_inodes, int flags,
|
extern errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
|
||||||
errcode_t (*progress)(ext2_resize_t rfs,
|
errcode_t (*progress)(ext2_resize_t rfs,
|
||||||
int pass, unsigned long cur,
|
int pass, unsigned long cur,
|
||||||
unsigned long max));
|
unsigned long max));
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
Bad required extra isize in superblock (1). Fix? yes
|
|
||||||
|
|
||||||
Bad desired extra isize in superblock (1024). Fix? yes
|
|
||||||
|
|
||||||
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: ***** FILE SYSTEM WAS MODIFIED *****
|
|
||||||
test_filesys: 11/32 files (0.0% non-contiguous), 28/200 blocks
|
|
||||||
Exit status is 1
|
|
|
@ -1,7 +0,0 @@
|
||||||
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/32 files (0.0% non-contiguous), 28/200 blocks
|
|
||||||
Exit status is 0
|
|
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
check invalid extra_isize fields in superblock
|
|
|
@ -1,7 +1,4 @@
|
||||||
Pass 1: Checking inodes, blocks, and sizes
|
Pass 1: Checking inodes, blocks, and sizes
|
||||||
Inode 12 has a extra size (126) which is invalid
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Pass 2: Checking directory structure
|
Pass 2: Checking directory structure
|
||||||
Directory inode 12, block #0, offset 4: directory corrupted
|
Directory inode 12, block #0, offset 4: directory corrupted
|
||||||
Salvage? yes
|
Salvage? yes
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
* file may be redistributed under the GNU Public License v2.
|
* file may be redistributed under the GNU Public License v2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define E2FSPROGS_VERSION "1.43.3"
|
#define E2FSPROGS_VERSION "1.43.2"
|
||||||
#define E2FSPROGS_DATE "04-Sep-2016"
|
#define E2FSPROGS_DATE "01-Sep-2016"
|
||||||
|
|
Loading…
Reference in New Issue