summaryrefslogtreecommitdiff
path: root/e2fsck
diff options
context:
space:
mode:
Diffstat (limited to 'e2fsck')
-rw-r--r--e2fsck/Makefile.in201
-rw-r--r--e2fsck/badblocks.c10
-rw-r--r--e2fsck/dirinfo.c9
-rw-r--r--e2fsck/e2fsck.8.in2
-rw-r--r--e2fsck/e2fsck.c2
-rw-r--r--e2fsck/e2fsck.conf.5.in53
-rw-r--r--e2fsck/e2fsck.h28
-rw-r--r--e2fsck/ea_refcount.c39
-rw-r--r--e2fsck/ehandler.c2
-rw-r--r--e2fsck/iscan.c5
-rw-r--r--e2fsck/jfs_user.h21
-rw-r--r--e2fsck/journal.c114
-rw-r--r--e2fsck/logfile.c25
-rw-r--r--e2fsck/message.c12
-rw-r--r--e2fsck/pass1.c173
-rw-r--r--e2fsck/pass1b.c45
-rw-r--r--e2fsck/pass2.c34
-rw-r--r--e2fsck/pass3.c80
-rw-r--r--e2fsck/pass4.c5
-rw-r--r--e2fsck/pass5.c201
-rw-r--r--e2fsck/problem.c55
-rw-r--r--e2fsck/problem.h13
-rw-r--r--e2fsck/profile.c7
-rw-r--r--e2fsck/quota.c48
-rw-r--r--e2fsck/recovery.c55
-rw-r--r--e2fsck/region.c2
-rw-r--r--e2fsck/rehash.c32
-rw-r--r--e2fsck/scantest.c3
-rw-r--r--e2fsck/sigcatcher.c9
-rw-r--r--e2fsck/super.c51
-rw-r--r--e2fsck/unix.c261
-rw-r--r--e2fsck/util.c52
32 files changed, 964 insertions, 685 deletions
diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in
index d5589858..4b10f6fd 100644
--- a/e2fsck/Makefile.in
+++ b/e2fsck/Makefile.in
@@ -16,19 +16,20 @@ MANPAGES= e2fsck.8
FMANPAGES= e2fsck.conf.5
LIBS= $(LIBQUOTA) $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBBLKID) $(LIBUUID) \
- $(LIBINTL) $(LIBE2P)
+ $(LIBINTL) $(LIBE2P) $(SYSLIBS)
DEPLIBS= $(DEPLIBQUOTA) $(LIBEXT2FS) $(DEPLIBCOM_ERR) $(DEPLIBBLKID) \
$(DEPLIBUUID) $(DEPLIBE2P)
STATIC_LIBS= $(STATIC_LIBQUOTA) $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) \
- $(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(LIBINTL) $(STATIC_LIBE2P)
+ $(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(LIBINTL) $(STATIC_LIBE2P) \
+ $(SYSLIBS)
STATIC_DEPLIBS= $(DEPSTATIC_LIBQUOTA) $(STATIC_LIBEXT2FS) \
$(DEPSTATIC_LIBCOM_ERR) $(DEPSTATIC_LIBBLKID) \
$(DEPSTATIC_LIBUUID) $(DEPSTATIC_LIBE2P)
PROFILED_LIBS= $(PROFILED_LIBQUOTA) $(PROFILED_LIBEXT2FS) \
$(PROFILED_LIBCOM_ERR) $(PROFILED_LIBBLKID) $(PROFILED_LIBUUID) \
- $(PROFILED_LIBE2P) $(LIBINTL) \
+ $(PROFILED_LIBE2P) $(LIBINTL) $(SYSLIBS)
PROFILED_DEPLIBS= $(DEPPROFILED_LIBQUOTA) $(PROFILED_LIBEXT2FS) \
$(DEPPROFILED_LIBCOM_ERR) $(DEPPROFILED_LIBBLKID) \
$(DEPPROFILED_LIBUUID) $(DEPPROFILED_LIBE2P)
@@ -38,6 +39,7 @@ COMPILE_ET=$(top_builddir)/lib/et/compile_et --build-tree
.c.o:
$(E) " CC $<"
$(Q) $(CC) -c $(ALL_CFLAGS) $< -o $@
+ $(Q) $(CHECK_CMD) $(ALL_CFLAGS) $<
@PROFILE_CMT@ $(Q) $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
#
@@ -129,21 +131,22 @@ e2fsck.static: $(OBJS) $(STATIC_DEPLIBS)
$(E) " LD $@"
$(Q) $(LD) $(LDFLAGS_STATIC) -o e2fsck.static $(OBJS) $(STATIC_LIBS)
-e2fsck.profiled: $(PROFILED_OBJS) $(PROFILED_DEPLIBS)
+e2fsck.profiled: $(OBJS) $(PROFILED_DEPLIBS)
$(E) " LD $@"
$(Q) $(LD) $(ALL_LDFLAGS) -g -pg -o e2fsck.profiled $(PROFILED_OBJS) \
$(PROFILED_LIBS)
gen_crc32table: $(srcdir)/gen_crc32table.c
$(E) " CC $@"
- $(Q) $(BUILD_CC) $(BUILD_CFLAGS) -o gen_crc32table \
+ $(Q) $(BUILD_CC) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o gen_crc32table \
$(srcdir)/gen_crc32table.c
crc32table.h: gen_crc32table
$(E) " GEN32TABLE $@"
$(Q) ./gen_crc32table > crc32table.h
-tst_sigcatcher: $(srcdir)/sigcatcher.c
+tst_sigcatcher: $(srcdir)/sigcatcher.c sigcatcher.o
+ $(E) " CC $@"
$(Q) $(CC) $(BUILD_LDFLAGS) $(ALL_CFLAGS) $(RDYNAMIC) \
$(srcdir)/sigcatcher.c -DDEBUG -o tst_sigcatcher
@@ -151,26 +154,27 @@ tst_problem: $(srcdir)/problem.c $(srcdir)/problem.h $(LIBEXT2FS) \
$(DEPLIBCOM_ERR)
$(Q) $(CC) $(BUILD_LDFLAGS) $(ALL_CFLAGS) -o tst_problem \
$(srcdir)/problem.c -DUNITTEST $(LIBEXT2FS) $(LIBCOM_ERR) \
- $(LIBINTL)
+ $(LIBINTL) $(SYSLIBS)
tst_crc32: $(srcdir)/crc32.c $(LIBEXT2FS) $(DEPLIBCOM_ERR)
$(Q) $(CC) $(BUILD_LDFLAGS) $(ALL_CFLAGS) -o tst_crc32 $(srcdir)/crc32.c \
- -DUNITTEST $(LIBEXT2FS) $(LIBCOM_ERR)
+ -DUNITTEST $(LIBEXT2FS) $(LIBCOM_ERR) $(SYSLIBS)
tst_refcount: ea_refcount.c $(DEPLIBCOM_ERR)
$(E) " LD $@"
$(Q) $(CC) -o tst_refcount $(srcdir)/ea_refcount.c \
- $(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR) $(LIBEXT2FS)
+ $(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR) $(LIBEXT2FS) \
+ $(SYSLIBS)
tst_logfile: $(srcdir)/logfile.c
$(E) " LD $@"
$(Q) $(CC) -o tst_logfile $(srcdir)/logfile.c $(ALL_CFLAGS) \
- -DTEST_PROGRAM
+ -DTEST_PROGRAM $(SYSLIBS)
tst_region: region.c $(DEPLIBCOM_ERR)
$(E) " LD $@"
$(Q) $(CC) -o tst_region $(srcdir)/region.c \
- $(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR)
+ $(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR) $(SYSLIBS)
check:: tst_refcount tst_region tst_crc32 tst_problem
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_refcount
@@ -216,11 +220,11 @@ installdirs:
install: $(PROGS) $(MANPAGES) $(FMANPAGES) installdirs
$(Q) for i in $(PROGS); do \
- echo " INSTALL $(root_sbindir)/$$i"; \
+ $(ES) " INSTALL $(root_sbindir)/$$i"; \
$(INSTALL_PROGRAM) $$i $(DESTDIR)$(root_sbindir)/$$i; \
done
$(Q) for i in ext2 ext3 ext4 ext4dev; do \
- echo " LINK $(root_sbindir)/fsck.$$i"; \
+ $(ES) " LINK $(root_sbindir)/fsck.$$i"; \
(cd $(DESTDIR)$(root_sbindir); \
$(LN) $(LINK_INSTALL_FLAGS) e2fsck fsck.$$i); \
done
@@ -228,25 +232,25 @@ install: $(PROGS) $(MANPAGES) $(FMANPAGES) installdirs
for j in $(COMPRESS_EXT); do \
$(RM) -f $(DESTDIR)$(man8dir)/$$i.$$j; \
done; \
- echo " INSTALL_DATA $(man8dir)/$$i"; \
+ $(ES) " INSTALL_DATA $(man8dir)/$$i"; \
$(INSTALL_DATA) $$i $(DESTDIR)$(man8dir)/$$i; \
done
$(Q) for i in $(FMANPAGES); do \
for j in $(COMPRESS_EXT); do \
$(RM) -f $(DESTDIR)$(man5dir)/$$i.$$j; \
done; \
- echo " INSTALL_DATA $(man5dir)/$$i"; \
+ $(ES) " INSTALL_DATA $(man5dir)/$$i"; \
$(INSTALL_DATA) $$i $(DESTDIR)$(man5dir)/$$i; \
done
$(Q) for i in ext2 ext3 ext4 ext4dev; do \
- echo " LINK $(man8dir)/fsck.$$i.8"; \
+ $(ES) " LINK $(man8dir)/fsck.$$i.8"; \
(cd $(DESTDIR)$(man8dir); \
$(LN) $(LINK_INSTALL_FLAGS) e2fsck.8 fsck.$$i.8); \
done
install-strip: install
$(Q) for i in $(PROGS); do \
- echo " STRIP $(root_sbindir)/$$i"; \
+ $(ES) " STRIP $(root_sbindir)/$$i"; \
$(STRIP) $(DESTDIR)$(root_sbindir)/$$i; \
done
@@ -269,7 +273,7 @@ uninstall:
$(DESTDIR)$(root_sbindir)/fsck.ext4 \
$(DESTDIR)$(root_sbindir)/fsck.ext4dev
-clean:
+clean::
$(RM) -f $(PROGS) \#* *\# *.s *.o *.a *~ core e2fsck.static \
e2fsck.shared e2fsck.profiled flushb e2fsck.8 \
tst_problem tst_crc32 tst_region tst_refcount gen_crc32table \
@@ -293,9 +297,9 @@ e2fsck.o: $(srcdir)/e2fsck.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
crc32.o: $(srcdir)/crc32.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -303,9 +307,9 @@ crc32.o: $(srcdir)/crc32.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/crc32defs.h crc32table.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/crc32defs.h crc32table.h
gen_crc32table.o: $(srcdir)/gen_crc32table.c $(srcdir)/crc32defs.h
dict.o: $(srcdir)/dict.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/dict.h
@@ -316,9 +320,9 @@ super.o: $(srcdir)/super.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
pass1.o: $(srcdir)/pass1.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -326,9 +330,9 @@ pass1.o: $(srcdir)/pass1.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
pass1b.o: $(srcdir)/pass1b.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
@@ -336,9 +340,9 @@ pass1b.o: $(srcdir)/pass1b.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/ext3_extents.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h $(srcdir)/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h $(srcdir)/dict.h
pass2.o: $(srcdir)/pass2.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -346,9 +350,9 @@ pass2.o: $(srcdir)/pass2.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h $(srcdir)/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h $(srcdir)/dict.h
pass3.o: $(srcdir)/pass3.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -356,9 +360,9 @@ pass3.o: $(srcdir)/pass3.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
pass4.o: $(srcdir)/pass4.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -366,9 +370,9 @@ pass4.o: $(srcdir)/pass4.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
pass5.o: $(srcdir)/pass5.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -376,9 +380,9 @@ pass5.o: $(srcdir)/pass5.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -386,10 +390,11 @@ journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
- $(top_srcdir)/lib/ext2fs/kernel-list.h $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
+ $(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h \
+ $(srcdir)/problem.h
recovery.o: $(srcdir)/recovery.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -397,10 +402,10 @@ recovery.o: $(srcdir)/recovery.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
- $(top_srcdir)/lib/ext2fs/kernel-list.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
+ $(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h
revoke.o: $(srcdir)/revoke.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -408,10 +413,10 @@ revoke.o: $(srcdir)/revoke.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
- $(top_srcdir)/lib/ext2fs/kernel-list.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
+ $(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h
badblocks.o: $(srcdir)/badblocks.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
@@ -419,8 +424,9 @@ badblocks.o: $(srcdir)/badblocks.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/ext3_extents.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
util.o: $(srcdir)/util.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -428,8 +434,9 @@ util.o: $(srcdir)/util.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
unix.o: $(srcdir)/unix.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/e2p/e2p.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -437,9 +444,10 @@ unix.o: $(srcdir)/unix.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h $(top_srcdir)/version.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h \
+ $(top_srcdir)/version.h
dirinfo.o: $(srcdir)/dirinfo.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -447,9 +455,9 @@ dirinfo.o: $(srcdir)/dirinfo.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(top_srcdir)/lib/ext2fs/tdb.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(top_srcdir)/lib/ext2fs/tdb.h
dx_dirinfo.o: $(srcdir)/dx_dirinfo.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -457,8 +465,9 @@ dx_dirinfo.o: $(srcdir)/dx_dirinfo.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
ehandler.o: $(srcdir)/ehandler.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -466,8 +475,9 @@ ehandler.o: $(srcdir)/ehandler.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
problem.o: $(srcdir)/problem.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -475,9 +485,9 @@ problem.o: $(srcdir)/problem.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h $(srcdir)/problemP.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h $(srcdir)/problemP.h
message.o: $(srcdir)/message.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -485,9 +495,9 @@ message.o: $(srcdir)/message.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
ea_refcount.o: $(srcdir)/ea_refcount.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -495,8 +505,9 @@ ea_refcount.o: $(srcdir)/ea_refcount.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
rehash.o: $(srcdir)/rehash.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -504,9 +515,9 @@ rehash.o: $(srcdir)/rehash.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/problem.h
region.o: $(srcdir)/region.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -514,8 +525,9 @@ region.o: $(srcdir)/region.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
profile.o: $(srcdir)/profile.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/profile.h prof_err.h
@@ -526,8 +538,9 @@ sigcatcher.o: $(srcdir)/sigcatcher.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
logfile.o: $(srcdir)/logfile.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
@@ -535,17 +548,7 @@ logfile.o: $(srcdir)/logfile.c $(top_builddir)/lib/config.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h
+ $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/quotaio.h \
+ $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h \
+ $(top_srcdir)/lib/../e2fsck/dict.h
prof_err.o: prof_err.c
-quota.o: $(srcdir)/quota.c $(top_builddir)/lib/config.h \
- $(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.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 \
- $(srcdir)/profile.h prof_err.h $(top_srcdir)/lib/quota/mkquota.h \
- $(top_srcdir)/lib/quota/quota.h $(top_srcdir)/lib/../e2fsck/dict.h \
- $(srcdir)/problem.h $(top_srcdir)/lib/quota/quotaio.h \
- $(top_srcdir)/lib/quota/dqblk_v2.h $(top_srcdir)/lib/quota/quotaio_tree.h
diff --git a/e2fsck/badblocks.c b/e2fsck/badblocks.c
index 71b1c56e..7f3641b5 100644
--- a/e2fsck/badblocks.c
+++ b/e2fsck/badblocks.c
@@ -42,7 +42,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
check_bb_inode_blocks, 0);
if (retval) {
- com_err("ext2fs_block_iterate", retval,
+ com_err("ext2fs_block_iterate", retval, "%s",
_("while sanity checking the bad blocks inode"));
goto fatal;
}
@@ -54,7 +54,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
if (!replace_bad_blocks) {
retval = ext2fs_read_bb_inode(fs, &bb_list);
if (retval) {
- com_err("ext2fs_read_bb_inode", retval,
+ com_err("ext2fs_read_bb_inode", retval, "%s",
_("while reading the bad blocks inode"));
goto fatal;
}
@@ -90,7 +90,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
else
pclose(f);
if (retval) {
- com_err("ext2fs_read_bb_FILE", retval,
+ com_err("ext2fs_read_bb_FILE", retval, "%s",
_("while reading in list of bad blocks from file"));
goto fatal;
}
@@ -101,7 +101,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
printf("%s: Updating bad block inode.\n", ctx->device_name);
retval = ext2fs_update_bb_inode(fs, bb_list);
if (retval) {
- com_err("ext2fs_update_bb_inode", retval,
+ com_err("ext2fs_update_bb_inode", retval, "%s",
_("while updating bad block inode"));
goto fatal;
}
@@ -111,6 +111,8 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
fatal:
ctx->flags |= E2F_FLAG_ABORT;
+ if (bb_list)
+ ext2fs_badblocks_list_free(bb_list);
return;
}
diff --git a/e2fsck/dirinfo.c b/e2fsck/dirinfo.c
index c81777a5..dbaf4712 100644
--- a/e2fsck/dirinfo.c
+++ b/e2fsck/dirinfo.c
@@ -42,6 +42,7 @@ static void setup_tdb(e2fsck_t ctx, ext2_ino_t num_dirs)
struct dir_info_db *db = ctx->dir_info;
unsigned int threshold;
errcode_t retval;
+ mode_t save_umask;
char *tdb_dir, uuid[40];
int fd, enable;
@@ -62,7 +63,9 @@ static void setup_tdb(e2fsck_t ctx, ext2_ino_t num_dirs)
uuid_unparse(ctx->fs->super->s_uuid, uuid);
sprintf(db->tdb_fn, "%s/%s-dirinfo-XXXXXX", tdb_dir, uuid);
+ save_umask = umask(077);
fd = mkstemp(db->tdb_fn);
+ umask(save_umask);
if (fd < 0) {
db->tdb = NULL;
return;
@@ -320,7 +323,7 @@ int e2fsck_get_num_dirinfo(e2fsck_t ctx)
return ctx->dir_info ? ctx->dir_info->count : 0;
}
-extern struct dir_info_iter *e2fsck_dir_info_iter_begin(e2fsck_t ctx)
+struct dir_info_iter *e2fsck_dir_info_iter_begin(e2fsck_t ctx)
{
struct dir_info_iter *iter;
struct dir_info_db *db = ctx->dir_info;
@@ -334,8 +337,8 @@ extern struct dir_info_iter *e2fsck_dir_info_iter_begin(e2fsck_t ctx)
return iter;
}
-extern void e2fsck_dir_info_iter_end(e2fsck_t ctx EXT2FS_ATTR((unused)),
- struct dir_info_iter *iter)
+void e2fsck_dir_info_iter_end(e2fsck_t ctx EXT2FS_ATTR((unused)),
+ struct dir_info_iter *iter)
{
free(iter->tdb_iter.dptr);
ext2fs_free_mem(&iter);
diff --git a/e2fsck/e2fsck.8.in b/e2fsck/e2fsck.8.in
index b59a270f..f5ed7582 100644
--- a/e2fsck/e2fsck.8.in
+++ b/e2fsck/e2fsck.8.in
@@ -201,7 +201,7 @@ filesystem check (discarding blocks is useful on solid state devices and sparse
filesystem has been fully checked and only if it does not contain recognizable
errors. However there might be cases where
.B e2fsck
-does not fully recognise a problem and hence in this case this
+does not fully recognize a problem and hence in this case this
option may prevent you from further manual data recovery.
.TP
.BI nodiscard
diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
index 994f80e8..0ec15404 100644
--- a/e2fsck/e2fsck.c
+++ b/e2fsck/e2fsck.c
@@ -199,7 +199,7 @@ void e2fsck_free_context(e2fsck_t ctx)
*/
typedef void (*pass_t)(e2fsck_t ctx);
-pass_t e2fsck_passes[] = {
+static pass_t e2fsck_passes[] = {
e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
e2fsck_pass5, 0 };
diff --git a/e2fsck/e2fsck.conf.5.in b/e2fsck/e2fsck.conf.5.in
index 0d4651bd..9ebfbbf8 100644
--- a/e2fsck/e2fsck.conf.5.in
+++ b/e2fsck/e2fsck.conf.5.in
@@ -97,9 +97,8 @@ incorrectly set at the time when e2fsck is run.
Historically this was usually due to some distributions
having buggy init scripts and/or installers that didn't
correctly detect this case and take appropriate
-countermeasures. However, it's still possible, despite the
-best efforts of init script and installer authors to not be
-able to detect this misconfiguration, usually due to a
+countermeasures. Unfortunately, this is occasionally
+true even today, usually due to a
buggy or misconfigured virtualization manager or the
installer not having access to a network time server
during the installation process. So by default, we allow
@@ -123,6 +122,18 @@ can not be trusted; and to skip time-based checks if this is true. If
this boolean is set to true, then e2fsck will always assume that the
system clock can not be trusted.
.TP
+.I buggy_init_scripts
+This boolean relation is an alias for
+.I accept_time_fudge
+for backwards compatibility; it used to
+be that the behavior defined by
+.I accept_time_fudge
+above defaulted to false, and
+.I buggy_init_scripts
+would enable superblock time field to be wrong by up to 24 hours. When
+we changed the default, we also renamed this boolean relation to
+.IR accept_time_fudge.
+.TP
.I clear_test_fs_flag
This boolean relation controls whether or not
.BR e2fsck (8)
@@ -136,6 +147,16 @@ filesystem checks (either based on time or number of mounts) should
be doubled if the system is running on battery. This setting defaults to
true.
.TP
+.I indexed_dir_slack_percentage
+When
+.BR e2fsck (8)
+repacks a indexed directory, reserve the specified percentage of
+empty space in each leaf nodes so that a few new entries can
+be added to the directory without splitting leaf nodes, so that
+the average fill ratio of directories can be maintained at a
+higher, more efficient level. This relation defaults to 20
+percent.
+.TP
.I log_dir
If the
.I log_filename
@@ -184,15 +205,23 @@ of that type are squelched. This can be useful if the console is slow
(i.e., connected to a serial port) and so a large amount of output could
end up delaying the boot process for a long time (potentially hours).
.TP
-.I indexed_dir_slack_percentage
-When
-.BR e2fsck (8)
-repacks a indexed directory, reserve the specified percentage of
-empty space in each leaf nodes so that a few new entries can
-be added to the directory without splitting leaf nodes, so that
-the average fill ratio of directories can be maintained at a
-higher, more efficient level. This relation defaults to 20
-percent.
+.I report_features
+If this boolean relation is true, e2fsck will print the file system
+features as part of its verbose reporting (i.e., if the
+.B -v
+option is specified)
+.TP
+.I report_time
+If this boolean relation is true, e2fsck will run as if the options
+.B -tt
+are always specified. This will cause e2fsck to print timing statistics
+on a pass by pass basis for full file system checks.
+.TP
+.I report_verbose
+If this boolean relation is true, e2fsck will run as if the option
+.B -v
+is always specified. This will cause e2fsck to print some additional
+information at the end of each full file system check.
.SH THE [problems] STANZA
Each tag in the
.I [problems]
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 971390e2..c71a0a54 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -67,7 +67,7 @@
#define E2FSCK_ATTR(x)
#endif
-#include "quota/mkquota.h"
+#include "quota/quotaio.h"
/*
* Exit codes used by fsck-type programs
@@ -119,9 +119,9 @@ struct dx_dir_info {
struct dx_dirblock_info {
int type;
- blk_t phys;
+ blk64_t phys;
int flags;
- blk_t parent;
+ blk64_t parent;
ext2_dirhash_t min_hash;
ext2_dirhash_t max_hash;
ext2_dirhash_t node_min_hash;
@@ -189,8 +189,9 @@ struct resource_track {
#define E2F_FLAG_GOT_DEVSIZE 0x0800 /* Device size has been fetched */
#define E2F_FLAG_EXITING 0x1000 /* E2fsck exiting due to errors */
#define E2F_FLAG_TIME_INSANE 0x2000 /* Time is insane */
+#define E2F_FLAG_PROBLEMS_FIXED 0x4000 /* At least one problem was fixed */
-#define E2F_RESET_FLAGS (E2F_FLAG_TIME_INSANE)
+#define E2F_RESET_FLAGS (E2F_FLAG_TIME_INSANE | E2F_FLAG_PROBLEMS_FIXED)
/*
* Defines for indicating the e2fsck pass number
@@ -435,25 +436,24 @@ extern struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control);
/* ea_refcount.c */
extern errcode_t ea_refcount_create(int size, ext2_refcount_t *ret);
extern void ea_refcount_free(ext2_refcount_t refcount);
-extern errcode_t ea_refcount_fetch(ext2_refcount_t refcount, blk_t blk,
- int *ret);
+extern errcode_t ea_refcount_fetch(ext2_refcount_t refcount, blk64_t blk, int *ret);
extern errcode_t ea_refcount_increment(ext2_refcount_t refcount,
- blk_t blk, int *ret);
+ blk64_t blk, int *ret);
extern errcode_t ea_refcount_decrement(ext2_refcount_t refcount,
- blk_t blk, int *ret);
+ blk64_t blk, int *ret);
extern errcode_t ea_refcount_store(ext2_refcount_t refcount,
- blk_t blk, int count);
+ blk64_t blk, int count);
extern blk_t ext2fs_get_refcount_size(ext2_refcount_t refcount);
extern void ea_refcount_intr_begin(ext2_refcount_t refcount);
-extern blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret);
+extern blk64_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret);
/* ehandler.c */
extern const char *ehandler_operation(const char *op);
extern void ehandler_init(io_channel channel);
/* journal.c */
-extern int e2fsck_check_ext3_journal(e2fsck_t ctx);
-extern int e2fsck_run_ext3_journal(e2fsck_t ctx);
+extern errcode_t e2fsck_check_ext3_journal(e2fsck_t ctx);
+extern errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx);
extern void e2fsck_move_ext3_journal(e2fsck_t ctx);
extern int e2fsck_fix_ext3_journal_hint(e2fsck_t ctx);
@@ -466,7 +466,7 @@ extern void e2fsck_hide_quota(e2fsck_t ctx);
/* pass1.c */
extern void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags,
ext2_icount_t *ret);
-extern void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
+extern void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int use_shortcuts);
extern int e2fsck_pass1_check_device_inode(ext2_filsys fs,
struct ext2_inode *inode);
extern int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
@@ -548,7 +548,7 @@ extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
#ifdef MTRACE
extern void mtrace_print(char *mesg);
#endif
-extern blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
+extern blk64_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
const char *name, io_manager manager);
extern int ext2_file_type(unsigned int mode);
extern int write_all(int fd, char *buf, size_t count);
diff --git a/e2fsck/ea_refcount.c b/e2fsck/ea_refcount.c
index e66e6363..fcfaf497 100644
--- a/e2fsck/ea_refcount.c
+++ b/e2fsck/ea_refcount.c
@@ -25,7 +25,7 @@
* checked, its bit is set in the block_ea_map bitmap.
*/
struct ea_refcount_el {
- blk_t ea_blk;
+ blk64_t ea_blk;
int ea_count;
};
@@ -111,7 +111,7 @@ static void refcount_collapse(ext2_refcount_t refcount)
* specified position.
*/
static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
- blk_t blk, int pos)
+ blk64_t blk, int pos)
{
struct ea_refcount_el *el;
errcode_t retval;
@@ -153,7 +153,7 @@ static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
* and we can't find an entry, create one in the sorted list.
*/
static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
- blk_t blk, int create)
+ blk64_t blk, int create)
{
int low, high, mid;
@@ -206,7 +206,7 @@ retry:
return 0;
}
-errcode_t ea_refcount_fetch(ext2_refcount_t refcount, blk_t blk,
+errcode_t ea_refcount_fetch(ext2_refcount_t refcount, blk64_t blk,
int *ret)
{
struct ea_refcount_el *el;
@@ -220,7 +220,7 @@ errcode_t ea_refcount_fetch(ext2_refcount_t refcount, blk_t blk,
return 0;
}
-errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
+errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk64_t blk, int *ret)
{
struct ea_refcount_el *el;
@@ -234,7 +234,7 @@ errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
return 0;
}
-errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
+errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk64_t blk, int *ret)
{
struct ea_refcount_el *el;
@@ -249,7 +249,7 @@ errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
return 0;
}
-errcode_t ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
+errcode_t ea_refcount_store(ext2_refcount_t refcount, blk64_t blk, int count)
{
struct ea_refcount_el *el;
@@ -277,7 +277,7 @@ void ea_refcount_intr_begin(ext2_refcount_t refcount)
}
-blk_t ea_refcount_intr_next(ext2_refcount_t refcount,
+blk64_t ea_refcount_intr_next(ext2_refcount_t refcount,
int *ret)
{
struct ea_refcount_el *list;
@@ -310,7 +310,8 @@ errcode_t ea_refcount_validate(ext2_refcount_t refcount, FILE *out)
}
for (i=1; i < refcount->count; i++) {
if (refcount->list[i-1].ea_blk >= refcount->list[i].ea_blk) {
- fprintf(out, "%s: list[%d].blk=%u, list[%d].blk=%u\n",
+ fprintf(out,
+ "%s: list[%d].blk=%llu, list[%d].blk=%llu\n",
bad, i-1, refcount->list[i-1].ea_blk,
i, refcount->list[i].ea_blk);
ret = EXT2_ET_INVALID_ARGUMENT;
@@ -370,7 +371,7 @@ int main(int argc, char **argv)
int i = 0;
ext2_refcount_t refcount;
int size, arg;
- blk_t blk;
+ blk64_t blk;
errcode_t retval;
while (1) {
@@ -396,20 +397,20 @@ int main(int argc, char **argv)
case BCODE_STORE:
blk = (blk_t) bcode_program[i++];
arg = bcode_program[i++];
- printf("Storing blk %u with value %d\n", blk, arg);
+ printf("Storing blk %llu with value %d\n", blk, arg);
retval = ea_refcount_store(refcount, blk, arg);
if (retval)
com_err("ea_refcount_store", retval,
- "while storing blk %u", blk);
+ "while storing blk %llu", blk);
break;
case BCODE_FETCH:
blk = (blk_t) bcode_program[i++];
retval = ea_refcount_fetch(refcount, blk, &arg);
if (retval)
com_err("ea_refcount_fetch", retval,
- "while fetching blk %u", blk);
+ "while fetching blk %llu", blk);
else
- printf("bcode_fetch(%u) returns %d\n",
+ printf("bcode_fetch(%llu) returns %d\n",
blk, arg);
break;
case BCODE_INCR:
@@ -417,9 +418,9 @@ int main(int argc, char **argv)
retval = ea_refcount_increment(refcount, blk, &arg);
if (retval)
com_err("ea_refcount_increment", retval,
- "while incrementing blk %u", blk);
+ "while incrementing blk %llu", blk);
else
- printf("bcode_increment(%u) returns %d\n",
+ printf("bcode_increment(%llu) returns %d\n",
blk, arg);
break;
case BCODE_DECR:
@@ -427,9 +428,9 @@ int main(int argc, char **argv)
retval = ea_refcount_decrement(refcount, blk, &arg);
if (retval)
com_err("ea_refcount_decrement", retval,
- "while decrementing blk %u", blk);
+ "while decrementing blk %llu", blk);
else
- printf("bcode_decrement(%u) returns %d\n",
+ printf("bcode_decrement(%llu) returns %d\n",
blk, arg);
break;
case BCODE_VALIDATE:
@@ -446,7 +447,7 @@ int main(int argc, char **argv)
blk = ea_refcount_intr_next(refcount, &arg);
if (!blk)
break;
- printf("\tblk=%u, count=%d\n", blk, arg);
+ printf("\tblk=%llu, count=%d\n", blk, arg);
}
break;
case BCODE_COLLAPSE:
diff --git a/e2fsck/ehandler.c b/e2fsck/ehandler.c
index 6eecf33f..6dddf9c1 100644
--- a/e2fsck/ehandler.c
+++ b/e2fsck/ehandler.c
@@ -60,7 +60,7 @@ static errcode_t e2fsck_handle_read_error(io_channel channel,
preenhalt(ctx);
if (ask(ctx, _("Ignore error"), 1)) {
if (ask(ctx, _("Force rewrite"), 1))
- io_channel_write_blk64(channel, block, 1, data);
+ io_channel_write_blk64(channel, block, count, data);
return 0;
}
diff --git a/e2fsck/iscan.c b/e2fsck/iscan.c
index f5286b74..52cad11e 100644
--- a/e2fsck/iscan.c
+++ b/e2fsck/iscan.c
@@ -16,9 +16,6 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#ifdef HAVE_MNTENT_H
-#include <mntent.h>
-#endif
#include <sys/ioctl.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
@@ -110,7 +107,7 @@ int main (int argc, char *argv[])
retval = ext2fs_open(device_name, 0,
0, 0, unix_io_manager, &fs);
if (retval) {
- com_err(program_name, retval, _("while trying to open %s"),
+ com_err(program_name, retval, _("while trying to open '%s'"),
device_name);
exit(1);
}
diff --git a/e2fsck/jfs_user.h b/e2fsck/jfs_user.h
index 9e333060..bfc1bcde 100644
--- a/e2fsck/jfs_user.h
+++ b/e2fsck/jfs_user.h
@@ -18,7 +18,7 @@ struct buffer_head {
e2fsck_t b_ctx;
io_channel b_io;
int b_size;
- blk_t b_blocknr;
+ unsigned long long b_blocknr;
int b_dirty;
int b_uptodate;
int b_err;
@@ -75,20 +75,31 @@ typedef __u64 __be64;
* We use the standard libext2fs portability tricks for inline
* functions.
*/
+#ifdef NO_INLINE_FUNCS
extern lkmem_cache_t * do_cache_create(int len);
extern void do_cache_destroy(lkmem_cache_t *cache);
extern size_t journal_tag_bytes(journal_t *journal);
+#endif
#if (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
#ifdef E2FSCK_INCLUDE_INLINE_FUNCS
-#define _INLINE_ extern
+#if (__STDC_VERSION__ >= 199901L)
+#define _INLINE_ extern inline
#else
+#define _INLINE_ inline
+#endif
+#else /* !E2FSCK_INCLUDE_INLINE FUNCS */
+#if (__STDC_VERSION__ >= 199901L)
+#define _INLINE_ inline
+#else /* not C99 */
#ifdef __GNUC__
#define _INLINE_ extern __inline__
#else /* For Watcom C */
#define _INLINE_ extern inline
-#endif
-#endif
+#endif /* __GNUC__ */
+#endif /* __STDC_VERSION__ >= 199901L */
+#endif /* E2FSCK_INCLUDE_INLINE_FUNCS */
+
_INLINE_ lkmem_cache_t * do_cache_create(int len)
{
@@ -121,7 +132,7 @@ _INLINE_ size_t journal_tag_bytes(journal_t *journal)
/*
* Kernel compatibility functions are defined in journal.c
*/
-int journal_bmap(journal_t *journal, blk64_t block, unsigned long *phys);
+int journal_bmap(journal_t *journal, blk64_t block, unsigned long long *phys);
struct buffer_head *getblk(kdev_t ctx, blk64_t blocknr, int blocksize);
void sync_blockdev(kdev_t kdev);
void ll_rw_block(int rw, int dummy, struct buffer_head *bh[]);
diff --git a/e2fsck/journal.c b/e2fsck/journal.c
index 915b8bbf..11ccec58 100644
--- a/e2fsck/journal.c
+++ b/e2fsck/journal.c
@@ -44,7 +44,7 @@ static int bh_count = 0;
* to use the recovery.c file virtually unchanged from the kernel, so we
* don't have to do much to keep kernel and user recovery in sync.
*/
-int journal_bmap(journal_t *journal, blk64_t block, unsigned long *phys)
+int journal_bmap(journal_t *journal, blk64_t block, unsigned long long *phys)
{
#ifdef USE_INODE_IO
*phys = block;
@@ -62,7 +62,7 @@ int journal_bmap(journal_t *journal, blk64_t block, unsigned long *phys)
retval= ext2fs_bmap2(inode->i_ctx->fs, inode->i_ino,
&inode->i_ext2, NULL, 0, block, 0, &pblk);
*phys = pblk;
- return (retval);
+ return (int) retval;
#endif
}
@@ -80,8 +80,8 @@ struct buffer_head *getblk(kdev_t kdev, blk64_t blocknr, int blocksize)
if (journal_enable_debug >= 3)
bh_count++;
#endif
- jfs_debug(4, "getblk for block %lu (%d bytes)(total %d)\n",
- (unsigned long) blocknr, blocksize, bh_count);
+ jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
+ (unsigned long long) blocknr, blocksize, bh_count);
bh->b_ctx = kdev->k_ctx;
if (kdev->k_dev == K_DEV_FS)
@@ -108,44 +108,45 @@ void sync_blockdev(kdev_t kdev)
void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
{
- int retval;
+ errcode_t retval;
struct buffer_head *bh;
for (; nr > 0; --nr) {
bh = *bhp++;
if (rw == READ && !bh->b_uptodate) {
- jfs_debug(3, "reading block %lu/%p\n",
- (unsigned long) bh->b_blocknr, (void *) bh);
+ jfs_debug(3, "reading block %llu/%p\n",
+ bh->b_blocknr, (void *) bh);
retval = io_channel_read_blk64(bh->b_io,
bh->b_blocknr,
1, bh->b_data);
if (retval) {
com_err(bh->b_ctx->device_name, retval,
- "while reading block %lu\n",
- (unsigned long) bh->b_blocknr);
- bh->b_err = retval;
+ "while reading block %llu\n",
+ bh->b_blocknr);
+ bh->b_err = (int) retval;
continue;
}
bh->b_uptodate = 1;
} else if (rw == WRITE && bh->b_dirty) {
- jfs_debug(3, "writing block %lu/%p\n",
- (unsigned long) bh->b_blocknr, (void *) bh);
+ jfs_debug(3, "writing block %llu/%p\n",
+ bh->b_blocknr,
+ (void *) bh);
retval = io_channel_write_blk64(bh->b_io,
bh->b_blocknr,
1, bh->b_data);
if (retval) {
com_err(bh->b_ctx->device_name, retval,
- "while writing block %lu\n",
- (unsigned long) bh->b_blocknr);
- bh->b_err = retval;
+ "while writing block %llu\n",
+ bh->b_blocknr);
+ bh->b_err = (int) retval;
continue;
}
bh->b_dirty = 0;
bh->b_uptodate = 1;
} else {
- jfs_debug(3, "no-op %s for block %lu\n",
+ jfs_debug(3, "no-op %s for block %llu\n",
rw == READ ? "read" : "write",
- (unsigned long) bh->b_blocknr);
+ bh->b_blocknr);
}
}
}
@@ -164,8 +165,8 @@ void brelse(struct buffer_head *bh)
{
if (bh->b_dirty)
ll_rw_block(WRITE, 1, &bh);
- jfs_debug(3, "freeing block %lu/%p (total %d)\n",
- (unsigned long) bh->b_blocknr, (void *) bh, --bh_count);
+ jfs_debug(3, "freeing block %llu/%p (total %d)\n",
+ bh->b_blocknr, (void *) bh, --bh_count);
ext2fs_free_mem(&bh);
}
@@ -237,7 +238,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
journal_t *journal = NULL;
errcode_t retval = 0;
io_manager io_ptr = 0;
- unsigned long start = 0;
+ unsigned long long start = 0;
int ext_journal = 0;
int tried_backup_jnl = 0;
@@ -313,7 +314,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
BLOCK_FLAG_HOLE, 0,
process_journal_block, &pb);
if ((pb.last_block + 1) * ctx->fs->blocksize <
- EXT2_I_SIZE(&j_inode->i_ext2)) {
+ (int) EXT2_I_SIZE(&j_inode->i_ext2)) {
retval = EXT2_ET_JOURNAL_TOO_SMALL;
goto try_backup_journal;
}
@@ -338,7 +339,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
#else
journal->j_inode = j_inode;
ctx->journal_io = ctx->fs->io;
- if ((retval = journal_bmap(journal, 0, &start)) != 0)
+ if ((retval = (errcode_t) journal_bmap(journal, 0, &start)) != 0)
goto errout;
#endif
} else {
@@ -371,15 +372,27 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
#ifndef USE_INODE_IO
if (ext_journal)
#endif
- retval = io_ptr->open(journal_name,
- IO_FLAG_RW | IO_FLAG_EXCLUSIVE,
+ {
+ int flags = IO_FLAG_RW;
+ if (!(ctx->mount_flags & EXT2_MF_ISROOT &&
+ ctx->mount_flags & EXT2_MF_READONLY))
+ flags |= IO_FLAG_EXCLUSIVE;
+ if ((ctx->mount_flags & EXT2_MF_READONLY) &&
+ (ctx->options & E2F_OPT_FORCE))
+ flags &= ~IO_FLAG_EXCLUSIVE;
+
+
+ retval = io_ptr->open(journal_name, flags,
&ctx->journal_io);
+ }
if (retval)
goto errout;
io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
if (ext_journal) {
+ blk64_t maxlen;
+
if (ctx->fs->blocksize == 1024)
start = 1;
bh = getblk(dev_journal, start, ctx->fs->blocksize);
@@ -413,7 +426,8 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
goto errout;
}
- journal->j_maxlen = ext2fs_blocks_count(&jsuper);
+ maxlen = ext2fs_blocks_count(&jsuper);
+ journal->j_maxlen = (maxlen < 1ULL << 32) ? maxlen : (1ULL << 32) - 1;
start++;
}
@@ -507,7 +521,7 @@ static errcode_t e2fsck_journal_load(journal_t *journal)
ll_rw_block(READ, 1, &jbh);
if (jbh->b_err) {
- com_err(ctx->device_name, jbh->b_err,
+ com_err(ctx->device_name, jbh->b_err, "%s",
_("reading journal superblock\n"));
return jbh->b_err;
}
@@ -690,7 +704,7 @@ static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
* This function makes sure that the superblock fields regarding the
* journal are consistent.
*/
-int e2fsck_check_ext3_journal(e2fsck_t ctx)
+errcode_t e2fsck_check_ext3_journal(e2fsck_t ctx)
{
struct ext2_super_block *sb = ctx->fs->super;
journal_t *journal;
@@ -699,7 +713,7 @@ int e2fsck_check_ext3_journal(e2fsck_t ctx)
struct problem_context pctx;
problem_t problem;
int reset = 0, force_fsck = 0;
- int retval;
+ errcode_t retval;
/* If we don't have any journal features, don't do anything more */
if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
@@ -802,6 +816,19 @@ no_has_journal:
*/
}
+ /*
+ * If we don't need to do replay the journal, check to see if
+ * the journal's errno is set; if so, we need to mark the file
+ * system as being corrupt and clear the journal's s_errno.
+ */
+ if (!(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
+ journal->j_superblock->s_errno) {
+ ctx->fs->super->s_state |= EXT2_ERROR_FS;
+ ext2fs_mark_super_dirty(ctx->fs);
+ journal->j_superblock->s_errno = 0;
+ mark_buffer_dirty(journal->j_sb_buffer);
+ }
+
e2fsck_journal_release(ctx, journal, reset, 0);
return retval;
}
@@ -810,7 +837,7 @@ static errcode_t recover_ext3_journal(e2fsck_t ctx)
{
struct problem_context pctx;
journal_t *journal;
- int retval;
+ errcode_t retval;
clear_problem_context(&pctx);
@@ -834,15 +861,7 @@ static errcode_t recover_ext3_journal(e2fsck_t ctx)
if (journal->j_failed_commit) {
pctx.ino = journal->j_failed_commit;
fix_problem(ctx, PR_0_JNL_TXN_CORRUPT, &pctx);
- ctx->fs->super->s_state |= EXT2_ERROR_FS;
- ext2fs_mark_super_dirty(ctx->fs);
- }
-
-
- if (journal->j_superblock->s_errno) {
- ctx->fs->super->s_state |= EXT2_ERROR_FS;
- ext2fs_mark_super_dirty(ctx->fs);
- journal->j_superblock->s_errno = 0;
+ journal->j_superblock->s_errno = -EINVAL;
mark_buffer_dirty(journal->j_sb_buffer);
}
@@ -853,7 +872,7 @@ errout:
return retval;
}
-int e2fsck_run_ext3_journal(e2fsck_t ctx)
+errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx)
{
io_manager io_ptr = ctx->fs->io->manager;
int blocksize = ctx->fs->blocksize;
@@ -900,8 +919,14 @@ int e2fsck_run_ext3_journal(e2fsck_t ctx)
ctx->fs->super->s_kbytes_written += kbytes_written;
/* Set the superblock flags */
- e2fsck_clear_recover(ctx, recover_retval);
- return recover_retval;
+ e2fsck_clear_recover(ctx, recover_retval != 0);
+
+ /*
+ * Do one last sanity check, and propagate journal->s_errno to
+ * the EXT2_ERROR_FS flag in the fs superblock if needed.
+ */
+ retval = e2fsck_check_ext3_journal(ctx);
+ return retval ? retval : recover_retval;
}
/*
@@ -920,7 +945,8 @@ void e2fsck_move_ext3_journal(e2fsck_t ctx)
ext2_ino_t ino;
errcode_t retval;
const char * const * cpp;
- int group, mount_flags;
+ dgrp_t group;
+ int mount_flags;
clear_problem_context(&pctx);
@@ -1051,8 +1077,10 @@ int e2fsck_fix_ext3_journal_hint(e2fsck_t ctx)
if (!journal_name)
return 0;
- if (stat(journal_name, &st) < 0)
+ if (stat(journal_name, &st) < 0) {
+ free(journal_name);
return 0;
+ }
if (st.st_rdev != sb->s_journal_dev) {
clear_problem_context(&pctx);
diff --git a/e2fsck/logfile.c b/e2fsck/logfile.c
index 76ae52d1..c48b8eb8 100644
--- a/e2fsck/logfile.c
+++ b/e2fsck/logfile.c
@@ -13,6 +13,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "e2fsck.h"
#include <pwd.h>
@@ -33,19 +36,25 @@ static void alloc_string(struct string *s, int len)
static void append_string(struct string *s, const char *a, int len)
{
+ int needlen;
+
if (!len)
len = strlen(a);
- if (s->end + len >= s->len) {
- char *n = realloc(s, s->len * 2);
+ needlen = s->end + len + 1;
+ if (needlen > s->len) {
+ char *n;
+
+ if (s->len * 2 > needlen)
+ needlen = s->len * 2;
+ n = realloc(s->s, needlen);
if (n) {
s->s = n;
- s->len = s->len * 2;
+ s->len = needlen;
} else {
- len = s->len - s->end - 1;
- if (len <= 0)
- return;
+ /* Don't append if we ran out of memory */
+ return;
}
}
memcpy(s->s + s->end, a, len);
@@ -126,7 +135,11 @@ static void expand_percent_expression(e2fsck_t ctx, char ch,
strcpy(buf, "tytso");
break;
#else
+#ifdef HAVE_GETPWUID_R
getpwuid_r(getuid(), &pw_struct, buf, sizeof(buf), &pw);
+#else
+ pw = getpwuid(getuid());
+#endif
if (pw)
append_string(s, pw->pw_name, 0);
return;
diff --git a/e2fsck/message.c b/e2fsck/message.c
index 980dc4b8..7b843594 100644
--- a/e2fsck/message.c
+++ b/e2fsck/message.c
@@ -197,7 +197,7 @@ static void safe_print(FILE *f, const char *cp, int len)
static void print_pathname(FILE *f, ext2_filsys fs, ext2_ino_t dir,
ext2_ino_t ino)
{
- errcode_t retval;
+ errcode_t retval = 0;
char *path;
if (!dir && (ino < num_special_inodes)) {
@@ -226,7 +226,8 @@ static void print_time(FILE *f, time_t t)
time_str = getenv("TZ");
if (!time_str)
time_str = "";
- do_gmt = !strcmp(time_str, "GMT0");
+ do_gmt = !strcmp(time_str, "GMT") ||
+ !strcmp(time_str, "GMT0");
}
#endif
time_str = asctime((do_gmt > 0) ? gmtime(&t) : localtime(&t));
@@ -361,8 +362,7 @@ static _INLINE_ void expand_dirent_expression(FILE *f, ext2_filsys fs, char ch,
struct problem_context *ctx)
{
struct ext2_dir_entry *dirent;
- unsigned int rec_len;
- int len;
+ unsigned int rec_len, len;
if (!ctx || !ctx->dirent)
goto no_dirent;
@@ -451,7 +451,7 @@ static _INLINE_ void expand_percent_expression(FILE *f, ext2_filsys fs,
fprintf(f, "%*u", width, ctx->dir);
break;
case 'g':
- fprintf(f, "%*d", width, ctx->group);
+ fprintf(f, "%*u", width, ctx->group);
break;
case 'i':
fprintf(f, "%*u", width, ctx->ino);
@@ -490,7 +490,7 @@ static _INLINE_ void expand_percent_expression(FILE *f, ext2_filsys fs,
#endif
break;
case 'S':
- fprintf(f, "%u", get_backup_sb(NULL, fs, NULL, NULL));
+ fprintf(f, "%llu", get_backup_sb(NULL, fs, NULL, NULL));
break;
case 's':
fprintf(f, "%*s", width, ctx->str ? ctx->str : "NULL");
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index c7645d15..9ef724ad 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -274,16 +274,15 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
struct ext2_super_block *sb = ctx->fs->super;
struct ext2_inode_large *inode;
struct ext2_ext_attr_entry *entry;
- char *start, *end;
+ char *start;
unsigned int storage_size, remain;
- int problem = 0;
+ problem_t problem = 0;
inode = (struct ext2_inode_large *) pctx->inode;
storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
inode->i_extra_isize;
start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
inode->i_extra_isize + sizeof(__u32);
- end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
entry = (struct ext2_ext_attr_entry *) start;
/* scan all entry's headers first */
@@ -308,7 +307,7 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
/* check value size */
- if (entry->e_value_size == 0 || entry->e_value_size > remain) {
+ if (entry->e_value_size > remain) {
pctx->num = entry->e_value_size;
problem = PR_1_ATTR_VALUE_SIZE;
goto fix;
@@ -510,8 +509,8 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
}
}
-extern void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags,
- ext2_icount_t *ret)
+void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags,
+ ext2_icount_t *ret)
{
unsigned int threshold;
ext2_ino_t num_dirs;
@@ -547,9 +546,9 @@ void e2fsck_pass1(e2fsck_t ctx)
__u64 max_sizes;
ext2_filsys fs = ctx->fs;
ext2_ino_t ino = 0;
- struct ext2_inode *inode;
- ext2_inode_scan scan;
- char *block_buf;
+ struct ext2_inode *inode = NULL;
+ ext2_inode_scan scan = NULL;
+ char *block_buf = NULL;
#ifdef RESOURCE_TRACK
struct resource_track rtrack;
#endif
@@ -560,7 +559,7 @@ void e2fsck_pass1(e2fsck_t ctx)
const char *old_op;
unsigned int save_type;
int imagic_fs, extent_fs;
- int busted_fs_time = 0;
+ int low_dtime_check = 1;
int inode_size;
init_resource_track(&rtrack, ctx->fs->io);
@@ -663,8 +662,7 @@ void e2fsck_pass1(e2fsck_t ctx)
if (pctx.errcode) {
fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
- ext2fs_free_mem(&inode);
- return;
+ goto endit;
}
/*
@@ -687,8 +685,7 @@ void e2fsck_pass1(e2fsck_t ctx)
if (pctx.errcode) {
fix_problem(ctx, PR_1_CONVERT_SUBCLUSTER, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
- ext2fs_free_mem(&inode);
- return;
+ goto endit;
}
block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
"block interate buffer");
@@ -700,25 +697,25 @@ void e2fsck_pass1(e2fsck_t ctx)
if (pctx.errcode) {
fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
- ext2fs_free_mem(&block_buf);
- ext2fs_free_mem(&inode);
- return;
+ goto endit;
}
ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
ctx->stashed_inode = inode;
scan_struct.ctx = ctx;
scan_struct.block_buf = block_buf;
ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
- if (ctx->progress)
- if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
- return;
+ if (ctx->progress && ((ctx->progress)(ctx, 1, 0,
+ ctx->fs->group_desc_count)))
+ goto endit;
if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
- (fs->super->s_mtime < fs->super->s_inodes_count))
- busted_fs_time = 1;
+ (fs->super->s_mtime < fs->super->s_inodes_count) ||
+ (fs->super->s_mkfs_time &&
+ fs->super->s_mkfs_time < fs->super->s_inodes_count))
+ low_dtime_check = 0;
if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
- !(fs->super->s_mmp_block <= fs->super->s_first_data_block ||
- fs->super->s_mmp_block >= fs->super->s_blocks_count))
+ fs->super->s_mmp_block > fs->super->s_first_data_block &&
+ fs->super->s_mmp_block < ext2fs_blocks_count(fs->super))
ext2fs_mark_block_bitmap2(ctx->block_found_map,
fs->super->s_mmp_block);
@@ -743,7 +740,7 @@ void e2fsck_pass1(e2fsck_t ctx)
if (pctx.errcode) {
fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto endit;
}
if (!ino)
break;
@@ -757,7 +754,7 @@ void e2fsck_pass1(e2fsck_t ctx)
pctx.num = inode->i_links_count;
fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto endit;
}
}
@@ -847,7 +844,7 @@ void e2fsck_pass1(e2fsck_t ctx)
pctx.num = 4;
fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto endit;
}
pb.ino = EXT2_BAD_INO;
pb.num_blocks = pb.last_block = 0;
@@ -864,12 +861,12 @@ void e2fsck_pass1(e2fsck_t ctx)
if (pctx.errcode) {
fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto endit;
}
if (pb.bbcheck)
if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto endit;
}
ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
clear_problem_context(&pctx);
@@ -928,8 +925,8 @@ void e2fsck_pass1(e2fsck_t ctx)
ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
if ((fs->super->s_feature_ro_compat &
EXT4_FEATURE_RO_COMPAT_QUOTA) &&
- (fs->super->s_usr_quota_inum == ino) ||
- (fs->super->s_grp_quota_inum == ino)) {
+ ((fs->super->s_usr_quota_inum == ino) ||
+ (fs->super->s_grp_quota_inum == ino))) {
if (!LINUX_S_ISREG(inode->i_mode) &&
fix_problem(ctx, PR_1_QUOTA_BAD_MODE,
&pctx)) {
@@ -951,7 +948,7 @@ void e2fsck_pass1(e2fsck_t ctx)
inode_size, "pass1");
}
} else if (ino < EXT2_FIRST_INODE(fs->super)) {
- int problem = 0;
+ problem_t problem = 0;
ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
if (ino == EXT2_BOOT_LOADER_INO) {
@@ -993,7 +990,7 @@ void e2fsck_pass1(e2fsck_t ctx)
* than nothing. The right answer is that there
* shouldn't be any bugs in the orphan list handling. :-)
*/
- if (inode->i_dtime && !busted_fs_time &&
+ if (inode->i_dtime && low_dtime_check &&
inode->i_dtime < ctx->fs->super->s_inodes_count) {
if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
inode->i_dtime = inode->i_links_count ?
@@ -1147,17 +1144,18 @@ void e2fsck_pass1(e2fsck_t ctx)
check_blocks(ctx, &pctx, block_buf);
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
+ goto endit;
if (process_inode_count >= ctx->process_inode_size) {
process_inodes(ctx, block_buf);
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
+ goto endit;
}
}
process_inodes(ctx, block_buf);
ext2fs_close_inode_scan(scan);
+ scan = NULL;
/*
* If any extended attribute blocks' reference counts need to
@@ -1196,7 +1194,7 @@ void e2fsck_pass1(e2fsck_t ctx)
if (!fix_problem(ctx, PR_1_RESIZE_INODE_CREATE,
&pctx)) {
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto endit;
}
pctx.errcode = 0;
}
@@ -1234,10 +1232,15 @@ void e2fsck_pass1(e2fsck_t ctx)
endit:
e2fsck_use_inode_shortcuts(ctx, 0);
- ext2fs_free_mem(&block_buf);
- ext2fs_free_mem(&inode);
+ if (scan)
+ ext2fs_close_inode_scan(scan);
+ if (block_buf)
+ ext2fs_free_mem(&block_buf);
+ if (inode)
+ ext2fs_free_mem(&inode);
- print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
+ if ((ctx->flags & E2F_FLAG_SIGNAL_MASK) == 0)
+ print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
}
/*
@@ -1432,6 +1435,16 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
}
}
+static _INLINE_ void mark_blocks_used(e2fsck_t ctx, blk64_t block,
+ unsigned int num)
+{
+ if (ext2fs_test_block_bitmap_range2(ctx->block_found_map, block, num))
+ ext2fs_mark_block_bitmap_range2(ctx->block_found_map, block, num);
+ else
+ while (num--)
+ mark_block_used(ctx, block++);
+}
+
/*
* Adjust the extended attribute block's reference counts at the end
* of pass 1, either by subtracting out references for EA blocks that
@@ -1751,15 +1764,16 @@ void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
struct process_block_struct *pb,
- blk64_t start_block,
+ blk64_t start_block, blk64_t end_block,
+ blk64_t eof_block,
ext2_extent_handle_t ehandle)
{
struct ext2fs_extent extent;
- blk64_t blk;
+ blk64_t blk, last_lblk;
e2_blkcnt_t blockcnt;
unsigned int i;
int is_dir, is_leaf;
- errcode_t problem;
+ problem_t problem;
struct ext2_extent_info info;
pctx->errcode = ext2fs_extent_get_info(ehandle, &info);
@@ -1771,6 +1785,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
while (!pctx->errcode && info.num_entries-- > 0) {
is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
+ last_lblk = extent.e_lblk + extent.e_len - 1;
problem = 0;
if (extent.e_pblk == 0 ||
@@ -1779,18 +1794,27 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
problem = PR_1_EXTENT_BAD_START_BLK;
else if (extent.e_lblk < start_block)
problem = PR_1_OUT_OF_ORDER_EXTENTS;
- else if (extent.e_len == 0)
+ else if ((end_block && last_lblk > end_block) &&
+ (!(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT &&
+ last_lblk > eof_block)))
+ problem = PR_1_EXTENT_END_OUT_OF_BOUNDS;
+ else if (is_leaf && extent.e_len == 0)
problem = PR_1_EXTENT_LENGTH_ZERO;
else if (is_leaf &&
(extent.e_pblk + extent.e_len) >
ext2fs_blocks_count(ctx->fs->super))
problem = PR_1_EXTENT_ENDS_BEYOND;
+ else if (is_leaf && is_dir &&
+ ((extent.e_lblk + extent.e_len) >
+ (1 << (21 - ctx->fs->super->s_log_block_size))))
+ problem = PR_1_TOOBIG_DIR;
if (problem) {
- report_problem:
+report_problem:
pctx->blk = extent.e_pblk;
pctx->blk2 = extent.e_lblk;
pctx->num = extent.e_len;
+ pctx->blkcount = extent.e_lblk + extent.e_len;
if (fix_problem(ctx, problem, pctx)) {
e2fsck_read_bitmaps(ctx);
pctx->errcode =
@@ -1799,6 +1823,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
pctx->str = "ext2fs_extent_delete";
return;
}
+ ext2fs_extent_fix_parents(ehandle);
pctx->errcode = ext2fs_extent_get(ehandle,
EXT2_EXTENT_CURRENT,
&extent);
@@ -1812,6 +1837,8 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
}
if (!is_leaf) {
+ blk64_t lblk = extent.e_lblk;
+
blk = extent.e_pblk;
pctx->errcode = ext2fs_extent_get(ehandle,
EXT2_EXTENT_DOWN, &extent);
@@ -1822,7 +1849,20 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
goto report_problem;
return;
}
- scan_extent_node(ctx, pctx, pb, extent.e_lblk, ehandle);
+ /* The next extent should match this index's logical start */
+ if (extent.e_lblk != lblk) {
+ struct ext2_extent_info e_info;
+
+ ext2fs_extent_get_info(ehandle, &e_info);
+ pctx->blk = lblk;
+ pctx->blk2 = extent.e_lblk;
+ pctx->num = e_info.curr_level - 1;
+ problem = PR_1_EXTENT_INDEX_START_INVALID;
+ if (fix_problem(ctx, problem, pctx))
+ ext2fs_extent_fix_parents(ehandle);
+ }
+ scan_extent_node(ctx, pctx, pb, extent.e_lblk,
+ last_lblk, eof_block, ehandle);
if (pctx->errcode)
return;
pctx->errcode = ext2fs_extent_get(ehandle,
@@ -1857,7 +1897,8 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
}
pb->fragmented = 1;
}
- while (is_dir && ++pb->last_db_block < extent.e_lblk) {
+ while (is_dir && (++pb->last_db_block <
+ (e2_blkcnt_t) extent.e_lblk)) {
pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
pb->ino, 0,
pb->last_db_block);
@@ -1867,15 +1908,19 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
goto failed_add_dir_block;
}
}
+ if (!ctx->fs->cluster_ratio_bits) {
+ mark_blocks_used(ctx, extent.e_pblk, extent.e_len);
+ pb->num_blocks += extent.e_len;
+ }
for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
i < extent.e_len;
blk++, blockcnt++, i++) {
- if (!(ctx->fs->cluster_ratio_bits &&
- pb->previous_block &&
+ if (ctx->fs->cluster_ratio_bits &&
+ !(pb->previous_block &&
(EXT2FS_B2C(ctx->fs, blk) ==
EXT2FS_B2C(ctx->fs, pb->previous_block)) &&
(blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
- (blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
+ ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
mark_block_used(ctx, blk);
pb->num_blocks++;
}
@@ -1898,10 +1943,10 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
if (is_dir && extent.e_len > 0)
pb->last_db_block = blockcnt - 1;
pb->previous_block = extent.e_pblk + extent.e_len - 1;
- start_block = pb->last_block = extent.e_lblk + extent.e_len - 1;
+ start_block = pb->last_block = last_lblk;
if (is_leaf && !is_dir &&
!(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT))
- pb->last_init_lblock = extent.e_lblk + extent.e_len - 1;
+ pb->last_init_lblock = last_lblk;
next:
pctx->errcode = ext2fs_extent_get(ehandle,
EXT2_EXTENT_NEXT_SIB,
@@ -1920,6 +1965,7 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
ext2_filsys fs = ctx->fs;
ext2_ino_t ino = pctx->ino;
errcode_t retval;
+ blk64_t eof_lblk;
pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
if (pctx->errcode) {
@@ -1937,7 +1983,9 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
ctx->extent_depth_count[info.max_depth]++;
}
- scan_extent_node(ctx, pctx, pb, 0, ehandle);
+ eof_lblk = ((EXT2_I_SIZE(inode) + fs->blocksize - 1) >>
+ EXT2_BLOCK_SIZE_BITS(fs->super)) - 1;
+ scan_extent_node(ctx, pctx, pb, 0, 0, eof_lblk, ehandle);
if (pctx->errcode &&
fix_problem(ctx, PR_1_EXTENT_ITERATE_FAILURE, pctx)) {
pb->num_blocks = 0;
@@ -1960,7 +2008,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
struct process_block_struct pb;
ext2_ino_t ino = pctx->ino;
struct ext2_inode *inode = pctx->inode;
- int bad_size = 0;
+ unsigned bad_size = 0;
int dirty_inode = 0;
int extent_fs;
__u64 size;
@@ -2119,7 +2167,8 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
}
pctx->num = 0;
}
- if (LINUX_S_ISREG(inode->i_mode) && EXT2_I_SIZE(inode) >= 0x80000000UL)
+ if (LINUX_S_ISREG(inode->i_mode) &&
+ ext2fs_needs_large_file_feature(EXT2_I_SIZE(inode)))
ctx->large_files++;
if ((pb.num_blocks != ext2fs_inode_i_blocks(fs, inode)) ||
((fs->super->s_feature_ro_compat &
@@ -2211,7 +2260,7 @@ static int process_block(ext2_filsys fs,
struct problem_context *pctx;
blk64_t blk = *block_nr;
int ret_code = 0;
- int problem = 0;
+ problem_t problem = 0;
e2fsck_t ctx;
p = (struct process_block_struct *) priv_data;
@@ -2324,7 +2373,7 @@ static int process_block(ext2_filsys fs,
(EXT2FS_B2C(ctx->fs, blk) ==
EXT2FS_B2C(ctx->fs, p->previous_block)) &&
(blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
- (blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
+ ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
mark_block_used(ctx, blk);
p->num_blocks++;
}
@@ -2522,14 +2571,16 @@ static int process_bad_block(ext2_filsys fs,
return 0;
}
-static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
+static void new_table_block(e2fsck_t ctx, blk64_t first_block, dgrp_t group,
const char *name, int num, blk64_t *new_block)
{
ext2_filsys fs = ctx->fs;
dgrp_t last_grp;
blk64_t old_block = *new_block;
blk64_t last_block;
- int i, is_flexbg, flexbg, flexbg_size;
+ dgrp_t flexbg;
+ unsigned flexbg_size;
+ int i, is_flexbg;
char *buf;
struct problem_context pctx;
@@ -2655,7 +2706,7 @@ static void mark_table_blocks(e2fsck_t ctx)
ext2_filsys fs = ctx->fs;
blk64_t b;
dgrp_t i;
- int j;
+ unsigned int j;
struct problem_context pctx;
clear_problem_context(&pctx);
@@ -2822,11 +2873,11 @@ static void e2fsck_block_alloc_stats(ext2_filsys fs, blk64_t blk, int inuse)
}
}
-void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
+void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int use_shortcuts)
{
ext2_filsys fs = ctx->fs;
- if (bool) {
+ if (use_shortcuts) {
fs->get_blocks = pass1_get_blocks;
fs->check_directory = pass1_check_directory;
fs->read_inode = pass1_read_inode;
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index 93fb630d..13bd9e98 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -88,8 +88,8 @@ static int process_pass1b_block(ext2_filsys fs, blk64_t *blocknr,
int ref_offset, void *priv_data);
static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
struct dup_inode *dp, char *block_buf);
-static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
- struct dup_inode *dp, char* block_buf);
+static errcode_t clone_file(e2fsck_t ctx, ext2_ino_t ino,
+ struct dup_inode *dp, char* block_buf);
static int check_if_fs_block(e2fsck_t ctx, blk64_t test_block);
static int check_if_fs_cluster(e2fsck_t ctx, blk64_t cluster);
@@ -624,7 +624,6 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
{
ext2_filsys fs = ctx->fs;
struct process_block_struct pb;
- struct ext2_inode inode;
struct problem_context pctx;
unsigned int count;
@@ -635,33 +634,35 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
pctx.str = "delete_file";
pb.cur_cluster = ~0;
- e2fsck_read_inode(ctx, ino, &inode, "delete_file");
- if (ext2fs_inode_has_valid_blocks2(fs, &inode))
- pctx.errcode = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY,
- block_buf, delete_file_block, &pb);
+ if (ext2fs_inode_has_valid_blocks2(fs, &dp->inode))
+ pctx.errcode = ext2fs_block_iterate3(fs, ino,
+ BLOCK_FLAG_READ_ONLY,
+ block_buf,
+ delete_file_block, &pb);
if (pctx.errcode)
fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
if (ctx->inode_bad_map)
ext2fs_unmark_inode_bitmap2(ctx->inode_bad_map, ino);
- ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
- quota_data_sub(ctx->qctx, &inode, ino, pb.dup_blocks * fs->blocksize);
- quota_data_inodes(ctx->qctx, &inode, ino, -1);
+ ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(dp->inode.i_mode));
+ quota_data_sub(ctx->qctx, &dp->inode, ino,
+ pb.dup_blocks * fs->blocksize);
+ quota_data_inodes(ctx->qctx, &dp->inode, ino, -1);
/* Inode may have changed by block_iterate, so reread it */
- e2fsck_read_inode(ctx, ino, &inode, "delete_file");
- e2fsck_clear_inode(ctx, ino, &inode, 0, "delete_file");
- if (ext2fs_file_acl_block(fs, &inode) &&
+ e2fsck_read_inode(ctx, ino, &dp->inode, "delete_file");
+ e2fsck_clear_inode(ctx, ino, &dp->inode, 0, "delete_file");
+ if (ext2fs_file_acl_block(fs, &dp->inode) &&
(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
count = 1;
pctx.errcode = ext2fs_adjust_ea_refcount2(fs,
- ext2fs_file_acl_block(fs, &inode),
+ ext2fs_file_acl_block(fs, &dp->inode),
block_buf, -1, &count);
if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
pctx.errcode = 0;
count = 1;
}
if (pctx.errcode) {
- pctx.blk = ext2fs_file_acl_block(fs, &inode);
+ pctx.blk = ext2fs_file_acl_block(fs, &dp->inode);
fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
}
/*
@@ -672,12 +673,12 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
*/
if ((count == 0) ||
ext2fs_test_block_bitmap2(ctx->block_dup_map,
- ext2fs_file_acl_block(fs, &inode))) {
- blk64_t blk = ext2fs_file_acl_block(fs, &inode);
+ ext2fs_file_acl_block(fs, &dp->inode))) {
+ blk64_t blk = ext2fs_file_acl_block(fs, &dp->inode);
delete_file_block(fs, &blk,
BLOCK_COUNT_EXTATTR, 0, 0, &pb);
- ext2fs_file_acl_block_set(fs, &inode, blk);
- quota_data_sub(ctx->qctx, &inode, ino, fs->blocksize);
+ ext2fs_file_acl_block_set(fs, &dp->inode, blk);
+ quota_data_sub(ctx->qctx, &dp->inode, ino, fs->blocksize);
}
}
}
@@ -778,8 +779,8 @@ static int clone_file_block(ext2_filsys fs,
return 0;
}
-static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
- struct dup_inode *dp, char* block_buf)
+static errcode_t clone_file(e2fsck_t ctx, ext2_ino_t ino,
+ struct dup_inode *dp, char* block_buf)
{
ext2_filsys fs = ctx->fs;
errcode_t retval;
@@ -816,7 +817,7 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
goto errout;
}
if (cs.errcode) {
- com_err("clone_file", cs.errcode,
+ com_err("clone_file", cs.errcode, "%s",
_("returned from clone_file_block"));
retval = cs.errcode;
goto errout;
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 882950d6..7277a7b3 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -351,9 +351,9 @@ static int check_dot(e2fsck_t ctx,
{
struct ext2_dir_entry *nextdir;
unsigned int rec_len, new_len;
- int status = 0;
- int created = 0;
- int problem = 0;
+ int status = 0;
+ int created = 0;
+ problem_t problem = 0;
if (!dirent->inode)
problem = PR_2_MISSING_DOT;
@@ -410,7 +410,7 @@ static int check_dotdot(e2fsck_t ctx,
struct ext2_dir_entry *dirent,
ext2_ino_t ino, struct problem_context *pctx)
{
- int problem = 0;
+ problem_t problem = 0;
unsigned int rec_len;
if (!dirent->inode)
@@ -668,7 +668,7 @@ static void salvage_directory(ext2_filsys fs,
*/
if ((left < 0) &&
((int) rec_len + left > 8) &&
- (name_len + 8 <= (int) rec_len + left) &&
+ ((int) name_len + 8 <= (int) rec_len + left) &&
dirent->inode <= fs->super->s_inodes_count &&
strnlen(dirent->name, name_len) == name_len) {
(void) ext2fs_set_rec_len(fs, (int) rec_len + left, dirent);
@@ -727,7 +727,7 @@ static int check_dir_block(ext2_filsys fs,
struct check_dir_struct *cd;
char *buf;
e2fsck_t ctx;
- int problem;
+ problem_t problem;
struct ext2_dx_root_info *root;
struct ext2_dx_countlimit *limit;
static dict_t de_dict;
@@ -844,7 +844,7 @@ out_htree:
dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
prev = 0;
do {
- int group;
+ dgrp_t group;
ext2_ino_t first_unused_inode;
problem = 0;
@@ -1132,7 +1132,7 @@ out_htree:
}
}
if (dir_modified) {
- cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
+ cd->pctx.errcode = ext2fs_write_dir_block3(fs, block_nr, buf, 0);
if (cd->pctx.errcode) {
if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
&cd->pctx))
@@ -1189,7 +1189,6 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
struct del_block del_block;
e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
- e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode");
clear_problem_context(&pctx);
pctx.ino = ino;
@@ -1224,9 +1223,10 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
}
if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
- return;
+ goto clear_inode;
- if (LINUX_S_ISREG(inode.i_mode) && EXT2_I_SIZE(&inode) >= 0x80000000UL)
+ if (LINUX_S_ISREG(inode.i_mode) &&
+ ext2fs_needs_large_file_feature(EXT2_I_SIZE(&inode)))
ctx->large_files--;
del_block.ctx = ctx;
@@ -1239,6 +1239,10 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
ctx->flags |= E2F_FLAG_ABORT;
return;
}
+clear_inode:
+ /* Inode may have changed by block_iterate, so reread it */
+ e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
+ e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode");
}
/*
@@ -1256,8 +1260,8 @@ static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
}
-extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
- ext2_ino_t ino, char *buf)
+int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
+ ext2_ino_t ino, char *buf)
{
ext2_filsys fs = ctx->fs;
struct ext2_inode inode;
@@ -1265,7 +1269,7 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
int not_fixed = 0;
unsigned char *frag, *fsize;
struct problem_context pctx;
- int problem = 0;
+ problem_t problem = 0;
e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
@@ -1452,7 +1456,7 @@ static int allocate_dir_block(e2fsck_t ctx,
return 1;
}
- pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
+ pctx->errcode = ext2fs_write_dir_block3(fs, blk, block, 0);
ext2fs_free_mem(&block);
if (pctx->errcode) {
pctx->str = "ext2fs_write_dir_block";
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 565b8e33..32c05b5b 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -53,7 +53,7 @@ static ext2fs_inode_bitmap inode_done_map = 0;
void e2fsck_pass3(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
- struct dir_info_iter *iter;
+ struct dir_info_iter *iter = NULL;
#ifdef RESOURCE_TRACK
struct resource_track rtrack;
#endif
@@ -108,12 +108,11 @@ void e2fsck_pass3(e2fsck_t ctx)
if (check_directory(ctx, dir->ino, &pctx))
goto abort_exit;
}
- e2fsck_dir_info_iter_end(ctx, iter);
/*
* Force the creation of /lost+found if not present
*/
- if ((ctx->flags & E2F_OPT_READONLY) == 0)
+ if ((ctx->options & E2F_OPT_READONLY) == 0)
e2fsck_get_lost_and_found(ctx, 1);
/*
@@ -123,6 +122,8 @@ void e2fsck_pass3(e2fsck_t ctx)
e2fsck_rehash_directories(ctx);
abort_exit:
+ if (iter)
+ e2fsck_dir_info_iter_end(ctx, iter);
e2fsck_free_dir_info(ctx);
if (inode_loop_detect) {
ext2fs_free_inode_bitmap(inode_loop_detect);
@@ -198,9 +199,9 @@ static void check_root(e2fsck_t ctx)
return;
}
- pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
+ pctx.errcode = ext2fs_write_dir_block3(fs, blk, block, 0);
if (pctx.errcode) {
- pctx.str = "ext2fs_write_dir_block";
+ pctx.str = "ext2fs_write_dir_block3";
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
return;
@@ -444,7 +445,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
return 0;
}
- retval = ext2fs_write_dir_block(fs, blk, block);
+ retval = ext2fs_write_dir_block3(fs, blk, block, 0);
ext2fs_free_mem(&block);
if (retval) {
pctx.errcode = retval;
@@ -712,12 +713,23 @@ static int expand_dir_proc(ext2_filsys fs,
last_blk = *blocknr;
return 0;
}
- retval = ext2fs_new_block2(fs, last_blk, ctx->block_found_map,
- &new_blk);
- if (retval) {
- es->err = retval;
- return BLOCK_ABORT;
+
+ if (blockcnt &&
+ (EXT2FS_B2C(fs, last_blk) == EXT2FS_B2C(fs, last_blk + 1)))
+ new_blk = last_blk + 1;
+ else {
+ last_blk &= ~EXT2FS_CLUSTER_MASK(fs);
+ retval = ext2fs_new_block2(fs, last_blk, ctx->block_found_map,
+ &new_blk);
+ if (retval) {
+ es->err = retval;
+ return BLOCK_ABORT;
+ }
+ es->newblocks++;
+ ext2fs_block_alloc_stats2(fs, new_blk, +1);
}
+ last_blk = new_blk;
+
if (blockcnt > 0) {
retval = ext2fs_new_dir_block(fs, 0, 0, &block);
if (retval) {
@@ -725,7 +737,7 @@ static int expand_dir_proc(ext2_filsys fs,
return BLOCK_ABORT;
}
es->num--;
- retval = ext2fs_write_dir_block(fs, new_blk, block);
+ retval = ext2fs_write_dir_block3(fs, new_blk, block, 0);
} else {
retval = ext2fs_get_mem(fs->blocksize, &block);
if (retval) {
@@ -742,8 +754,6 @@ static int expand_dir_proc(ext2_filsys fs,
ext2fs_free_mem(&block);
*blocknr = new_blk;
ext2fs_mark_block_bitmap2(ctx->block_found_map, new_blk);
- ext2fs_block_alloc_stats2(fs, new_blk, +1);
- es->newblocks++;
if (es->num == 0)
return (BLOCK_CHANGED | BLOCK_ABORT);
@@ -751,6 +761,27 @@ static int expand_dir_proc(ext2_filsys fs,
return BLOCK_CHANGED;
}
+/*
+ * Ensure that all blocks are marked in the block_found_map, since it's
+ * possible that the library allocated an extent node block or a block map
+ * block during the directory rebuilding; these new allocations are not
+ * captured in block_found_map. This is bad since we could later use
+ * block_found_map to allocate more blocks.
+ */
+static int find_new_blocks_proc(ext2_filsys fs,
+ blk64_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk64_t ref_block EXT2FS_ATTR((unused)),
+ int ref_offset EXT2FS_ATTR((unused)),
+ void *priv_data)
+{
+ struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
+ e2fsck_t ctx = es->ctx;
+
+ ext2fs_mark_block_bitmap2(ctx->block_found_map, *blocknr);
+ return 0;
+}
+
errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
int num, int guaranteed_size)
{
@@ -758,6 +789,7 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
errcode_t retval;
struct expand_dir_struct es;
struct ext2_inode inode;
+ blk64_t sz, before, after;
if (!(fs->flags & EXT2_FLAG_RW))
return EXT2_ET_RO_FILSYS;
@@ -779,11 +811,27 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
es.newblocks = 0;
es.ctx = ctx;
+ before = ext2fs_free_blocks_count(fs->super);
retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
0, expand_dir_proc, &es);
if (es.err)
return es.err;
+ after = ext2fs_free_blocks_count(fs->super);
+
+ /*
+ * If the free block count has dropped by more than the blocks we
+ * allocated ourselves, then we must've allocated some extent/map
+ * blocks. Therefore, we must iterate this dir's blocks again to
+ * ensure that all newly allocated blocks are captured in
+ * block_found_map.
+ */
+ if ((before - after) > es.newblocks) {
+ retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_READ_ONLY,
+ 0, find_new_blocks_proc, &es);
+ if (es.err)
+ return es.err;
+ }
/*
* Update the size and block count fields in the inode.
@@ -792,7 +840,9 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
if (retval)
return retval;
- inode.i_size = (es.last_block + 1) * fs->blocksize;
+ sz = (es.last_block + 1) * fs->blocksize;
+ inode.i_size = sz;
+ inode.i_size_high = sz >> 32;
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
quota_data_add(ctx->qctx, &inode, dir, es.newblocks * fs->blocksize);
diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c
index 1e632807..21d93f0c 100644
--- a/e2fsck/pass4.c
+++ b/e2fsck/pass4.c
@@ -99,7 +99,7 @@ void e2fsck_pass4(e2fsck_t ctx)
struct problem_context pctx;
__u16 link_count, link_counted;
char *buf = 0;
- int group, maxgroup;
+ dgrp_t group, maxgroup;
init_resource_track(&rtrack, ctx->fs->io);
@@ -123,7 +123,7 @@ void e2fsck_pass4(e2fsck_t ctx)
/* Protect loop from wrap-around if s_inodes_count maxed */
for (i=1; i <= fs->super->s_inodes_count && i > 0; i++) {
- int isdir = ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i);
+ int isdir;
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
goto errout;
@@ -157,6 +157,7 @@ void e2fsck_pass4(e2fsck_t ctx)
ext2fs_icount_fetch(ctx->inode_count, i,
&link_counted);
}
+ isdir = ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i);
if (isdir && (link_counted > EXT2_LINK_MAX))
link_counted = 1;
if (link_counted != link_count) {
diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c
index 148473ce..b31490fe 100644
--- a/e2fsck/pass5.c
+++ b/e2fsck/pass5.c
@@ -99,12 +99,11 @@ static void e2fsck_discard_blocks(e2fsck_t ctx, blk64_t start,
* is 1-based, it means that we need to adjust it by -1 in this
* function to compute right offset in the particular inode table.
*/
-static void e2fsck_discard_inodes(e2fsck_t ctx, int group,
- int start, int count)
+static void e2fsck_discard_inodes(e2fsck_t ctx, dgrp_t group,
+ ext2_ino_t start, int count)
{
ext2_filsys fs = ctx->fs;
blk64_t blk, num;
- int orig = count;
/*
* Sanity check for 'start'
@@ -152,7 +151,7 @@ static void e2fsck_discard_inodes(e2fsck_t ctx, int group,
#define NO_BLK ((blk64_t) -1)
-static void print_bitmap_problem(e2fsck_t ctx, int problem,
+static void print_bitmap_problem(e2fsck_t ctx, problem_t problem,
struct problem_context *pctx)
{
switch (problem) {
@@ -196,28 +195,33 @@ static void check_block_bitmaps(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
blk64_t i;
- int *free_array;
- int group = 0;
- int blocks = 0;
+ unsigned int *free_array;
+ dgrp_t g, group = 0;
+ unsigned int blocks = 0;
blk64_t free_blocks = 0;
blk64_t first_free = ext2fs_blocks_count(fs->super);
- int group_free = 0;
+ unsigned int group_free = 0;
int actual, bitmap;
struct problem_context pctx;
- int problem, save_problem, fixit, had_problem;
+ problem_t problem, save_problem;
+ int fixit, had_problem;
errcode_t retval;
int csum_flag;
- int skip_group = 0;
int old_desc_blocks = 0;
int count = 0;
int cmp_block = 0;
int redo_flag = 0;
blk64_t super_blk, old_desc_blk, new_desc_blk;
- io_manager manager = ctx->fs->io->manager;
+ char *actual_buf, *bitmap_buf;
+
+ actual_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
+ "actual bitmap buffer");
+ bitmap_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
+ "bitmap block buffer");
clear_problem_context(&pctx);
- free_array = (int *) e2fsck_allocate_memory(ctx,
- fs->group_desc_count * sizeof(int), "free block count array");
+ free_array = (unsigned int *) e2fsck_allocate_memory(ctx,
+ fs->group_desc_count * sizeof(unsigned int), "free block count array");
if ((B2C(fs->super->s_first_data_block) <
ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
@@ -255,82 +259,51 @@ redo_counts:
had_problem = 0;
save_problem = 0;
pctx.blk = pctx.blk2 = NO_BLK;
- if (csum_flag &&
- (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
- skip_group++;
for (i = B2C(fs->super->s_first_data_block);
i < ext2fs_blocks_count(fs->super);
i += EXT2FS_CLUSTER_RATIO(fs)) {
+ int first_block_in_bg = (B2C(i) -
+ B2C(fs->super->s_first_data_block)) %
+ fs->super->s_clusters_per_group == 0;
+ int n, nbytes = fs->super->s_clusters_per_group / 8;
+
actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i);
- if (skip_group) {
- if ((B2C(i) - B2C(fs->super->s_first_data_block)) %
- fs->super->s_clusters_per_group == 0) {
- super_blk = 0;
- old_desc_blk = 0;
- new_desc_blk = 0;
- ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
- &old_desc_blk, &new_desc_blk, 0);
-
- if (fs->super->s_feature_incompat &
- EXT2_FEATURE_INCOMPAT_META_BG)
- old_desc_blocks =
- fs->super->s_first_meta_bg;
- else
- old_desc_blocks = fs->desc_blocks +
- fs->super->s_reserved_gdt_blocks;
-
- count = 0;
- cmp_block = fs->super->s_clusters_per_group;
- if (group == (int)fs->group_desc_count - 1)
- cmp_block = EXT2FS_NUM_B2C(fs,
- ext2fs_group_blocks_count(fs, group));
- }
+ /*
+ * Try to optimize pass5 by extracting a bitmap block
+ * as expected from what we have on disk, and then
+ * comparing the two. If they are identical, then
+ * update the free block counts and go on to the next
+ * block group. This is much faster than doing the
+ * individual bit-by-bit comparison. The one downside
+ * is that this doesn't work if we are asking e2fsck
+ * to do a discard operation.
+ */
+ if (!first_block_in_bg ||
+ (group == (int)fs->group_desc_count - 1) ||
+ (ctx->options & E2F_OPT_DISCARD))
+ goto no_optimize;
+
+ retval = ext2fs_get_block_bitmap_range2(ctx->block_found_map,
+ B2C(i), fs->super->s_clusters_per_group,
+ actual_buf);
+ if (retval)
+ goto no_optimize;
+ retval = ext2fs_get_block_bitmap_range2(fs->block_map,
+ B2C(i), fs->super->s_clusters_per_group,
+ bitmap_buf);
+ if (retval)
+ goto no_optimize;
+ if (memcmp(actual_buf, bitmap_buf, nbytes) != 0)
+ goto no_optimize;
+ n = ext2fs_bitcount(actual_buf, nbytes);
+ group_free = fs->super->s_clusters_per_group - n;
+ free_blocks += group_free;
+ i += EXT2FS_C2B(fs, fs->super->s_clusters_per_group - 1);
+ goto next_group;
+ no_optimize:
- bitmap = 0;
- if (EQ_CLSTR(i, super_blk) ||
- (old_desc_blk && old_desc_blocks &&
- GE_CLSTR(i, old_desc_blk) &&
- LE_CLSTR(i, old_desc_blk + old_desc_blocks-1)) ||
- (new_desc_blk && EQ_CLSTR(i, new_desc_blk)) ||
- EQ_CLSTR(i, ext2fs_block_bitmap_loc(fs, group)) ||
- EQ_CLSTR(i, ext2fs_inode_bitmap_loc(fs, group)) ||
- (GE_CLSTR(i, ext2fs_inode_table_loc(fs, group)) &&
- LE_CLSTR(i, (ext2fs_inode_table_loc(fs, group) +
- fs->inode_blocks_per_group - 1)))) {
- bitmap = 1;
- actual = (actual != 0);
- count++;
- cmp_block--;
- } else if ((EXT2FS_B2C(fs, i) - count -
- EXT2FS_B2C(fs, fs->super->s_first_data_block)) %
- fs->super->s_clusters_per_group == 0) {
- /*
- * When the compare data blocks in block bitmap
- * are 0, count the free block,
- * skip the current block group.
- */
- if (ext2fs_test_block_bitmap_range2(
- ctx->block_found_map,
- EXT2FS_B2C(fs, i),
- cmp_block)) {
- /*
- * -1 means to skip the current block
- * group.
- */
- blocks = fs->super->s_clusters_per_group - 1;
- group_free = cmp_block;
- free_blocks += cmp_block;
- /*
- * The current block group's last block
- * is set to i.
- */
- i += EXT2FS_C2B(fs, cmp_block - 1);
- bitmap = 1;
- goto do_counts;
- }
- }
- } else if (redo_flag)
+ if (redo_flag)
bitmap = actual;
else
bitmap = ext2fs_fast_test_block_bitmap2(fs->block_map, i);
@@ -349,14 +322,15 @@ redo_counts:
*/
problem = PR_5_BLOCK_USED;
- if (skip_group) {
+ if (ext2fs_bg_flags_test(fs, group,
+ EXT2_BG_BLOCK_UNINIT)) {
struct problem_context pctx2;
pctx2.blk = i;
pctx2.group = group;
- if (fix_problem(ctx, PR_5_BLOCK_UNINIT,&pctx2)){
- ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
- skip_group = 0;
- }
+ if (fix_problem(ctx, PR_5_BLOCK_UNINIT,
+ &pctx2))
+ ext2fs_bg_flags_clear(fs, group,
+ EXT2_BG_BLOCK_UNINIT);
}
}
if (pctx.blk == NO_BLK) {
@@ -364,8 +338,8 @@ redo_counts:
save_problem = problem;
} else {
if ((problem == save_problem) &&
- (pctx.blk2 == i-1))
- pctx.blk2++;
+ (pctx.blk2 == i - EXT2FS_CLUSTER_RATIO(fs)))
+ pctx.blk2 += EXT2FS_CLUSTER_RATIO(fs);
else {
print_bitmap_problem(ctx, save_problem, &pctx);
pctx.blk = pctx.blk2 = i;
@@ -403,22 +377,17 @@ redo_counts:
if (!bitmap && i >= first_free)
e2fsck_discard_blocks(ctx, first_free,
(i - first_free) + 1);
+ next_group:
first_free = ext2fs_blocks_count(fs->super);
free_array[group] = group_free;
group ++;
blocks = 0;
group_free = 0;
- skip_group = 0;
if (ctx->progress)
if ((ctx->progress)(ctx, 5, group,
fs->group_desc_count*2))
goto errout;
- if (csum_flag &&
- (i != ext2fs_blocks_count(fs->super)-1) &&
- ext2fs_bg_flags_test(fs, group,
- EXT2_BG_BLOCK_UNINIT))
- skip_group++;
}
}
if (pctx.blk != NO_BLK)
@@ -450,15 +419,15 @@ redo_counts:
} else if (fixit == 0)
ext2fs_unmark_valid(fs);
- for (i = 0; i < fs->group_desc_count; i++) {
- if (free_array[i] != ext2fs_bg_free_blocks_count(fs, i)) {
- pctx.group = i;
- pctx.blk = ext2fs_bg_free_blocks_count(fs, i);
- pctx.blk2 = free_array[i];
+ for (g = 0; g < fs->group_desc_count; g++) {
+ if (free_array[g] != ext2fs_bg_free_blocks_count(fs, g)) {
+ pctx.group = g;
+ pctx.blk = ext2fs_bg_free_blocks_count(fs, g);
+ pctx.blk2 = free_array[g];
if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
&pctx)) {
- ext2fs_bg_free_blocks_count_set(fs, i, free_array[i]);
+ ext2fs_bg_free_blocks_count_set(fs, g, free_array[g]);
ext2fs_mark_super_dirty(fs);
} else
ext2fs_unmark_valid(fs);
@@ -473,11 +442,12 @@ redo_counts:
if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
ext2fs_free_blocks_count_set(fs->super, free_blocks);
ext2fs_mark_super_dirty(fs);
- } else
- ext2fs_unmark_valid(fs);
+ }
}
errout:
ext2fs_free_mem(&free_array);
+ ext2fs_free_mem(&actual_buf);
+ ext2fs_free_mem(&bitmap_buf);
}
static void check_inode_bitmaps(e2fsck_t ctx)
@@ -487,26 +457,26 @@ static void check_inode_bitmaps(e2fsck_t ctx)
unsigned int free_inodes = 0;
int group_free = 0;
int dirs_count = 0;
- int group = 0;
+ dgrp_t group = 0;
unsigned int inodes = 0;
- int *free_array;
- int *dir_array;
+ ext2_ino_t *free_array;
+ ext2_ino_t *dir_array;
int actual, bitmap;
errcode_t retval;
struct problem_context pctx;
- int problem, save_problem, fixit, had_problem;
+ problem_t problem, save_problem;
+ int fixit, had_problem;
int csum_flag;
int skip_group = 0;
int redo_flag = 0;
- io_manager manager = ctx->fs->io->manager;
- int first_free = fs->super->s_inodes_per_group + 1;
+ ext2_ino_t first_free = fs->super->s_inodes_per_group + 1;
clear_problem_context(&pctx);
- free_array = (int *) e2fsck_allocate_memory(ctx,
- fs->group_desc_count * sizeof(int), "free inode count array");
+ free_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
+ fs->group_desc_count * sizeof(ext2_ino_t), "free inode count array");
- dir_array = (int *) e2fsck_allocate_memory(ctx,
- fs->group_desc_count * sizeof(int), "directory count array");
+ dir_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
+ fs->group_desc_count * sizeof(ext2_ino_t), "directory count array");
if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) ||
(fs->super->s_inodes_count >
@@ -749,8 +719,7 @@ do_counts:
if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
fs->super->s_free_inodes_count = free_inodes;
ext2fs_mark_super_dirty(fs);
- } else
- ext2fs_unmark_valid(fs);
+ }
}
errout:
ext2fs_free_mem(&free_array);
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index d51a4087..2296c970 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -119,11 +119,13 @@ static struct e2fsck_problem problem_table[] = {
/* Superblock corrupt */
{ PR_0_SB_CORRUPT,
- N_("\nThe @S could not be read or does not describe a correct ext2\n"
- "@f. If the @v is valid and it really contains an ext2\n"
+ N_("\nThe @S could not be read or does not describe a valid ext2/ext3/ext4\n"
+ "@f. If the @v is valid and it really contains an ext2/ext3/ext4\n"
"@f (and not swap or ufs or something else), then the @S\n"
"is corrupt, and you might try running e2fsck with an alternate @S:\n"
- " e2fsck -b %S <@v>\n\n"),
+ " e2fsck -b 8193 <@v>\n"
+ " or\n"
+ " e2fsck -b 32768 <@v>\n\n"),
PROMPT_NONE, PR_FATAL },
/* Filesystem size is wrong */
@@ -410,7 +412,7 @@ static struct e2fsck_problem problem_table[] = {
/* Making quota file hidden */
{ PR_0_HIDE_QUOTA,
- N_("Making @q @is hidden.\n\n"),
+ N_("Making @q @i %i (%Q) hidden.\n"),
PROMPT_NONE, PR_PREEN_OK },
/* Superblock has invalid MMP block. */
@@ -433,6 +435,11 @@ static struct e2fsck_problem problem_table[] = {
N_("ext2fs_check_desc: %m\n"),
PROMPT_NONE, 0 },
+ /* 64bit is set but extents is unset. */
+ { PR_0_64BIT_WITHOUT_EXTENTS,
+ N_("@S 64bit filesystems needs extents to access the whole disk. "),
+ PROMPT_FIX, PR_PREEN_OK | PR_NO_OK},
+
/* Pass 1 errors */
/* Pass 1: Checking inodes, blocks, and sizes */
@@ -946,6 +953,20 @@ static struct e2fsck_problem problem_table[] = {
N_("@i %i has zero length extent\n\t(@n logical @b %c, physical @b %b)\n"),
PROMPT_CLEAR, 0 },
+ /*
+ * Interior extent node logical offset doesn't match first node below it
+ */
+ { PR_1_EXTENT_INDEX_START_INVALID,
+ N_("Interior @x node level %N of @i %i:\n"
+ "Logical start %b does not match logical start %c at next level. "),
+ PROMPT_FIX, 0 },
+
+ /* Extent end is out of bounds for the tree */
+ { PR_1_EXTENT_END_OUT_OF_BOUNDS,
+ N_("@i %i, end of extent exceeds allowed value\n\t(logical @b %c, physical @b %b, len %N)\n"),
+ PROMPT_CLEAR, 0 },
+
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
@@ -1050,12 +1071,12 @@ static struct e2fsck_problem problem_table[] = {
N_("@n @i number for '.' in @d @i %i.\n"),
PROMPT_FIX, 0 },
- /* Directory entry has bad inode number */
+ /* Entry 'xxxx' in /a/b/c has bad inode number.*/
{ PR_2_BAD_INO,
N_("@E has @n @i #: %Di.\n"),
PROMPT_CLEAR, 0 },
- /* Directory entry has deleted or unused inode */
+ /* Entry 'xxxx' in /a/b/c has deleted/unused inode nnnnn.*/
{ PR_2_UNUSED_INODE,
N_("@E has @D/unused @i %Di. "),
PROMPT_CLEAR, PR_PREEN_OK },
@@ -1621,7 +1642,7 @@ static struct e2fsck_problem problem_table[] = {
/* Free inodes count wrong */
{ PR_5_FREE_INODE_COUNT,
N_("Free @is count wrong (%i, counted=%j).\n"),
- PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
+ PROMPT_FIX, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
/* Free blocks count for group wrong */
{ PR_5_FREE_BLOCK_COUNT_GROUP,
@@ -1631,7 +1652,7 @@ static struct e2fsck_problem problem_table[] = {
/* Free blocks count wrong */
{ PR_5_FREE_BLOCK_COUNT,
N_("Free @bs count wrong (%b, counted=%c).\n"),
- PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
+ PROMPT_FIX, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
/* Programming error: bitmap endpoints don't match */
{ PR_5_BMAP_ENDPOINTS,
@@ -1691,6 +1712,11 @@ static struct e2fsck_problem problem_table[] = {
N_("Recreate @j"),
PROMPT_NULL, PR_PREEN_OK | PR_NO_OK },
+ /* Update quota information if it is inconsistent */
+ { PR_6_UPDATE_QUOTAS,
+ N_("Update quota info for quota type %N"),
+ PROMPT_NULL, PR_PREEN_OK },
+
{ 0 }
};
@@ -1784,11 +1810,11 @@ void clear_problem_context(struct problem_context *ctx)
static void reconfigure_bool(e2fsck_t ctx, struct e2fsck_problem *ptr,
const char *key, int mask, const char *name)
{
- int bool;
+ int val;
- bool = (ptr->flags & mask);
- profile_get_boolean(ctx->profile, "problems", key, name, bool, &bool);
- if (bool)
+ val = (ptr->flags & mask);
+ profile_get_boolean(ctx->profile, "problems", key, name, val, &val);
+ if (val)
ptr->flags |= mask;
else
ptr->flags &= ~mask;
@@ -1811,7 +1837,7 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
return 0;
}
if (!(ptr->flags & PR_CONFIG)) {
- char key[9], *new_desc;
+ char key[9], *new_desc = NULL;
sprintf(key, "0x%06x", code);
@@ -1946,6 +1972,9 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
if (ptr->flags & PR_AFTER_CODE)
answer = fix_problem(ctx, ptr->second_code, pctx);
+ if (answer && (ptr->prompt != PROMPT_NONE))
+ ctx->flags |= E2F_FLAG_PROBLEMS_FIXED;
+
return answer;
}
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 07df8107..6cb09cfb 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -18,7 +18,7 @@ struct problem_context {
struct ext2_dir_entry *dirent;
blk64_t blk, blk2;
e2_blkcnt_t blkcount;
- int group;
+ dgrp_t group;
__u32 csum1, csum2;
__u64 num;
const char *str;
@@ -249,6 +249,9 @@ struct problem_context {
/* Checking group descriptor failed */
#define PR_0_CHECK_DESC_FAILED 0x000045
+/* 64bit is set but extents are not set. */
+#define PR_0_64BIT_WITHOUT_EXTENTS 0x000048
+
/*
* Pass 1 errors
*/
@@ -558,6 +561,10 @@ struct problem_context {
/* Extent has zero length */
#define PR_1_EXTENT_LENGTH_ZERO 0x010066
+/* Index start doesn't match start of next extent down */
+#define PR_1_EXTENT_INDEX_START_INVALID 0x01006D
+
+#define PR_1_EXTENT_END_OUT_OF_BOUNDS 0x01006E
/*
* Pass 1b errors
*/
@@ -586,7 +593,6 @@ struct problem_context {
/* Error adjusting EA refcount */
#define PR_1B_ADJ_EA_REFCOUNT 0x011007
-
/* Pass 1C: Scan directories for inodes with dup blocks. */
#define PR_1C_PASS_HEADER 0x012000
@@ -1028,6 +1034,9 @@ struct problem_context {
/* Recreate the journal if E2F_FLAG_JOURNAL_INODE flag is set */
#define PR_6_RECREATE_JOURNAL 0x060001
+/* Update quota information if it is inconsistent */
+#define PR_6_UPDATE_QUOTAS 0x060002
+
/*
* Function declarations
*/
diff --git a/e2fsck/profile.c b/e2fsck/profile.c
index 019c6f58..c4528c8e 100644
--- a/e2fsck/profile.c
+++ b/e2fsck/profile.c
@@ -318,6 +318,9 @@ profile_init(const char **files, profile_t *ret_profile)
/* if the filenames list is not specified return an empty profile */
if ( files ) {
for (fs = files; !PROFILE_LAST_FILESPEC(*fs); fs++) {
+ if (array)
+ free_list(array);
+ array = NULL;
retval = get_dirlist(*fs, &array);
if (retval == 0) {
if (!array)
@@ -1542,7 +1545,7 @@ profile_get_integer(profile_t profile, const char *name, const char *subname,
/* Empty string is no good. */
return PROF_BAD_INTEGER;
errno = 0;
- ret_long = strtol (value, &end_value, 10);
+ ret_long = strtol(value, &end_value, 0);
/* Overflow or underflow. */
if ((ret_long == LONG_MIN || ret_long == LONG_MAX) && errno != 0)
@@ -1584,7 +1587,7 @@ profile_get_uint(profile_t profile, const char *name, const char *subname,
/* Empty string is no good. */
return PROF_BAD_INTEGER;
errno = 0;
- ret_long = strtoul (value, &end_value, 10);
+ ret_long = strtoul(value, &end_value, 0);
/* Overflow or underflow. */
if ((ret_long == ULONG_MAX) && errno != 0)
diff --git a/e2fsck/quota.c b/e2fsck/quota.c
index 3ae934a0..c6bbb9af 100644
--- a/e2fsck/quota.c
+++ b/e2fsck/quota.c
@@ -15,21 +15,26 @@
#include "e2fsck.h"
#include "problem.h"
-#include "quota/mkquota.h"
#include "quota/quotaio.h"
static void move_quota_inode(ext2_filsys fs, ext2_ino_t from_ino,
ext2_ino_t to_ino, int qtype)
{
- struct ext2_super_block *sb = fs->super;
- ext2_ino_t ino;
struct ext2_inode inode;
errcode_t retval;
char qf_name[QUOTA_NAME_LEN];
- if (ext2fs_read_inode(fs, from_ino, &inode))
+ /* We need the inode bitmap to be loaded */
+ if (ext2fs_read_bitmaps(fs))
return;
+ retval = ext2fs_read_inode(fs, from_ino, &inode);
+ if (retval) {
+ com_err("ext2fs_read_inode", retval, "%s",
+ _("in move_quota_inode"));
+ return;
+ }
+
inode.i_links_count = 1;
inode.i_mode = LINUX_S_IFREG | 0600;
inode.i_flags = EXT2_IMMUTABLE_FL;
@@ -37,11 +42,20 @@ static void move_quota_inode(ext2_filsys fs, ext2_ino_t from_ino,
EXT3_FEATURE_INCOMPAT_EXTENTS)
inode.i_flags |= EXT4_EXTENTS_FL;
- ext2fs_write_new_inode(fs, to_ino, &inode);
+ retval = ext2fs_write_new_inode(fs, to_ino, &inode);
+ if (retval) {
+ com_err("ext2fs_write_new_inode", retval, "%s",
+ _("in move_quota_inode"));
+ return;
+ }
+
/* unlink the old inode */
quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name);
ext2fs_unlink(fs, EXT2_ROOT_INO, qf_name, from_ino, 0);
ext2fs_inode_alloc_stats(fs, from_ino, -1);
+ /* Clear out the original inode in the inode-table block. */
+ memset(&inode, 0, sizeof(struct ext2_inode));
+ ext2fs_write_inode(fs, from_ino, &inode);
}
void e2fsck_hide_quota(e2fsck_t ctx)
@@ -56,31 +70,19 @@ void e2fsck_hide_quota(e2fsck_t ctx)
!(sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_QUOTA))
return;
- /* We need the inode bitmap to be loaded */
- if (ext2fs_read_bitmaps(fs))
- return;
-
- if (!sb->s_usr_quota_inum && !sb->s_grp_quota_inum)
- /* nothing to do */
- return;
-
- if (sb->s_usr_quota_inum == EXT4_USR_QUOTA_INO &&
- sb->s_grp_quota_inum == EXT4_GRP_QUOTA_INO)
- /* nothing to do */
- return;
-
- if (!fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx))
- return;
-
+ pctx.ino = sb->s_usr_quota_inum;
if (sb->s_usr_quota_inum &&
- sb->s_usr_quota_inum != EXT4_USR_QUOTA_INO) {
+ (sb->s_usr_quota_inum != EXT4_USR_QUOTA_INO) &&
+ fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) {
move_quota_inode(fs, sb->s_usr_quota_inum, EXT4_USR_QUOTA_INO,
USRQUOTA);
sb->s_usr_quota_inum = EXT4_USR_QUOTA_INO;
}
+ pctx.ino = sb->s_grp_quota_inum;
if (sb->s_grp_quota_inum &&
- sb->s_grp_quota_inum != EXT4_GRP_QUOTA_INO) {
+ (sb->s_grp_quota_inum != EXT4_GRP_QUOTA_INO) &&
+ fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) {
move_quota_inode(fs, sb->s_grp_quota_inum, EXT4_GRP_QUOTA_INO,
GRPQUOTA);
sb->s_grp_quota_inum = EXT4_GRP_QUOTA_INO;
diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c
index b669941b..e4e5ae1d 100644
--- a/e2fsck/recovery.c
+++ b/e2fsck/recovery.c
@@ -71,7 +71,7 @@ static int do_readahead(journal_t *journal, unsigned int start)
{
int err;
unsigned int max, nbufs, next;
- unsigned long blocknr;
+ unsigned long long blocknr;
struct buffer_head *bh;
struct buffer_head * bufs[MAXBUF];
@@ -133,7 +133,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal,
unsigned int offset)
{
int err;
- unsigned long blocknr;
+ unsigned long long blocknr;
struct buffer_head *bh;
*bhp = NULL;
@@ -283,12 +283,9 @@ int journal_recover(journal_t *journal)
int journal_skip_recovery(journal_t *journal)
{
int err;
- journal_superblock_t * sb;
-
struct recovery_info info;
memset (&info, 0, sizeof(info));
- sb = journal->j_superblock;
err = do_one_pass(journal, &info, PASS_SCAN);
@@ -297,6 +294,8 @@ int journal_skip_recovery(journal_t *journal)
++journal->j_transaction_sequence;
} else {
#ifdef CONFIG_JBD_DEBUG
+ journal_superblock_t *sb = journal->j_superblock;
+
int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence);
#endif
jbd_debug(1,
@@ -309,7 +308,6 @@ int journal_skip_recovery(journal_t *journal)
return err;
}
-#if 0
static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag)
{
unsigned long long block = be32_to_cpu(tag->t_blocknr);
@@ -317,17 +315,16 @@ static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag
block |= (__u64)be32_to_cpu(tag->t_blocknr_high) << 32;
return block;
}
-#endif
/*
* calc_chksums calculates the checksums for the blocks described in the
* descriptor block.
*/
static int calc_chksums(journal_t *journal, struct buffer_head *bh,
- unsigned long *next_log_block, __u32 *crc32_sum)
+ unsigned long long *next_log_block, __u32 *crc32_sum)
{
int i, num_blks, err;
- unsigned long io_block;
+ unsigned long long io_block;
struct buffer_head *obh;
num_blks = count_tags(journal, bh);
@@ -340,7 +337,7 @@ static int calc_chksums(journal_t *journal, struct buffer_head *bh,
err = jread(&obh, journal, io_block);
if (err) {
printk(KERN_ERR "JBD: IO error %d recovering block "
- "%lu in log\n", err, io_block);
+ "%llu in log\n", err, io_block);
return 1;
} else {
*crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data,
@@ -355,7 +352,7 @@ static int do_one_pass(journal_t *journal,
struct recovery_info *info, enum passtype pass)
{
unsigned int first_commit_ID, next_commit_ID;
- unsigned long next_log_block;
+ unsigned long long next_log_block;
int err, success = 0;
journal_superblock_t * sb;
journal_header_t * tmp;
@@ -365,11 +362,6 @@ static int do_one_pass(journal_t *journal,
int tag_bytes = journal_tag_bytes(journal);
__u32 crc32_sum = ~0; /* Transactional Checksums */
- /* Precompute the maximum metadata descriptors in a descriptor block */
- int MAX_BLOCKS_PER_DESC;
- MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
- / tag_bytes);
-
/*
* First thing is to establish what we expect to find in the log
* (in terms of transaction IDs), and where (in terms of log
@@ -410,14 +402,14 @@ static int do_one_pass(journal_t *journal,
if (tid_geq(next_commit_ID, info->end_transaction))
break;
- jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n",
+ jbd_debug(2, "Scanning for sequence ID %u at %llu/%lu\n",
next_commit_ID, next_log_block, journal->j_last);
/* Skip over each chunk of the transaction looking
* either the next descriptor block or the final commit
* record. */
- jbd_debug(3, "JBD: checking block %ld\n", next_log_block);
+ jbd_debug(3, "JBD: checking block %llu\n", next_log_block);
err = jread(&bh, journal, next_log_block);
if (err)
goto failed;
@@ -485,7 +477,7 @@ static int do_one_pass(journal_t *journal,
tagp = &bh->b_data[sizeof(journal_header_t)];
while ((tagp - bh->b_data + tag_bytes)
<= journal->j_blocksize) {
- unsigned long io_block;
+ unsigned long long io_block;
tag = (journal_block_tag_t *) tagp;
flags = be32_to_cpu(tag->t_flags);
@@ -499,13 +491,14 @@ static int do_one_pass(journal_t *journal,
success = err;
printk (KERN_ERR
"JBD: IO error %d recovering "
- "block %ld in log\n",
+ "block %llu in log\n",
err, io_block);
} else {
- unsigned long blocknr;
+ unsigned long long blocknr;
J_ASSERT(obh != NULL);
- blocknr = be32_to_cpu(tag->t_blocknr);
+ blocknr = read_tag_block(tag_bytes,
+ tag);
/* If the block has been
* revoked, then we're all done
@@ -733,15 +726,19 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
record_len = 8;
while (offset < max) {
- unsigned long blocknr;
+ unsigned long long blocknr;
int err;
- if (record_len == 4)
- blocknr = ext2fs_be32_to_cpu(*((__be32 *)(bh->b_data +
- offset)));
- else
- blocknr = ext2fs_be64_to_cpu(*((__be64 *)(bh->b_data +
- offset)));
+ if (record_len == 4) {
+ __be32 b;
+ memcpy(&b, bh->b_data + offset, sizeof(__be32));
+ blocknr = ext2fs_be32_to_cpu(b);
+ } else {
+ __be64 b;
+ memcpy(&b, bh->b_data + offset, sizeof(__be64));
+ blocknr = ext2fs_be64_to_cpu(b);
+ }
+
offset += record_len;
err = journal_set_revoke(journal, blocknr, sequence);
if (err)
diff --git a/e2fsck/region.c b/e2fsck/region.c
index e9abb569..4b669f08 100644
--- a/e2fsck/region.c
+++ b/e2fsck/region.c
@@ -171,7 +171,7 @@ void region_print(region_t region, FILE *f)
int main(int argc, char **argv)
{
- region_t r;
+ region_t r = NULL;
int pc = 0, ret;
region_addr_t start, end;
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index 15993b3f..3aafbb12 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -55,11 +55,11 @@
struct fill_dir_struct {
char *buf;
struct ext2_inode *inode;
- int err;
+ errcode_t err;
e2fsck_t ctx;
struct hash_entry *harray;
int max_array, num_array;
- int dir_size;
+ unsigned int dir_size;
int compress;
ino_t parent;
};
@@ -122,7 +122,7 @@ static int fill_dir_block(ext2_filsys fs,
if (((dir_offset + rec_len) > fs->blocksize) ||
(rec_len < 8) ||
((rec_len % 4) != 0) ||
- (((dirent->name_len & 0xFF)+8) > rec_len)) {
+ (((dirent->name_len & 0xFF)+8U) > rec_len)) {
fd->err = EXT2_ET_DIR_CORRUPTED;
return BLOCK_ABORT;
}
@@ -370,7 +370,7 @@ static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
mutate_name(new_name, &new_len);
for (j=0; j < fd->num_array; j++) {
if ((i==j) ||
- ((ent->dir->name_len & 0xFF) !=
+ ((new_len & 0xFF) !=
(fd->harray[j].dir->name_len & 0xFF)) ||
(strncmp(new_name, fd->harray[j].dir->name,
new_len & 0xFF)))
@@ -404,10 +404,9 @@ static errcode_t copy_dir_entries(e2fsck_t ctx,
char *block_start;
struct hash_entry *ent;
struct ext2_dir_entry *dirent;
- unsigned int rec_len, prev_rec_len;
- int i, left;
+ unsigned int rec_len, prev_rec_len, left, slack, offset;
+ int i;
ext2_dirhash_t prev_hash;
- int offset, slack;
if (ctx->htree_slack_percentage == 255) {
profile_get_uint(ctx->profile, "options",
@@ -627,7 +626,7 @@ struct write_dir_struct {
struct out_dir *outdir;
errcode_t err;
e2fsck_t ctx;
- int cleared;
+ blk64_t cleared;
};
/*
@@ -649,10 +648,18 @@ static int write_dir_block(ext2_filsys fs,
if (blockcnt >= wd->outdir->num) {
e2fsck_read_bitmaps(wd->ctx);
blk = *block_nr;
- ext2fs_unmark_block_bitmap2(wd->ctx->block_found_map, blk);
- ext2fs_block_alloc_stats2(fs, blk, -1);
+ /*
+ * In theory, we only release blocks from the end of the
+ * directory file, so it's fine to clobber a whole cluster at
+ * once.
+ */
+ if (blk % EXT2FS_CLUSTER_RATIO(fs) == 0) {
+ ext2fs_unmark_block_bitmap2(wd->ctx->block_found_map,
+ blk);
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ wd->cleared++;
+ }
*block_nr = 0;
- wd->cleared++;
return BLOCK_CHANGED;
}
if (blockcnt < 0)
@@ -828,7 +835,7 @@ void e2fsck_rehash_directories(e2fsck_t ctx)
struct dir_info_iter * dirinfo_iter = 0;
ext2_ino_t ino;
errcode_t retval;
- int cur, max, all_dirs, dir_index, first = 1;
+ int cur, max, all_dirs, first = 1;
init_resource_track(&rtrack, ctx->fs->io);
all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
@@ -840,7 +847,6 @@ void e2fsck_rehash_directories(e2fsck_t ctx)
clear_problem_context(&pctx);
- dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
cur = 0;
if (all_dirs) {
dirinfo_iter = e2fsck_dir_info_iter_begin(ctx);
diff --git a/e2fsck/scantest.c b/e2fsck/scantest.c
index 852ff86b..16380b31 100644
--- a/e2fsck/scantest.c
+++ b/e2fsck/scantest.c
@@ -12,9 +12,6 @@
#include <getopt.h>
#endif
#include <unistd.h>
-#ifdef HAVE_MNTENT_H
-#include <mntent.h>
-#endif
#include <sys/ioctl.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
diff --git a/e2fsck/sigcatcher.c b/e2fsck/sigcatcher.c
index 10b93287..e4d60ce8 100644
--- a/e2fsck/sigcatcher.c
+++ b/e2fsck/sigcatcher.c
@@ -251,6 +251,7 @@ static struct str_table sigbus_code_table[] = {
END_TABLE
};
+#if 0 /* should this be hooked in somewhere? */
static struct str_table sigstrap_code_table[] = {
#ifdef TRAP_BRKPT
DEFINE_ENTRY(TRAP_BRKPT)
@@ -260,6 +261,7 @@ static struct str_table sigstrap_code_table[] = {
#endif
END_TABLE
};
+#endif
static struct str_table sigcld_code_table[] = {
#ifdef CLD_EXITED
@@ -283,6 +285,7 @@ static struct str_table sigcld_code_table[] = {
END_TABLE
};
+#if 0 /* should this be hooked in somewhere? */
static struct str_table sigpoll_code_table[] = {
#ifdef POLL_IN
DEFINE_ENTRY(POLL_IN)
@@ -304,6 +307,7 @@ static struct str_table sigpoll_code_table[] = {
#endif
END_TABLE
};
+#endif
static const char *lookup_table(int num, struct str_table *table)
{
@@ -327,7 +331,8 @@ static const char *lookup_table_fallback(int num, struct str_table *table)
return buf;
}
-static void die_signal_handler(int signum, siginfo_t *siginfo, void *context)
+static void die_signal_handler(int signum, siginfo_t *siginfo,
+ void *context EXT2FS_ATTR((unused)))
{
void *stack_syms[32];
int frames;
@@ -368,7 +373,7 @@ static void die_signal_handler(int signum, siginfo_t *siginfo, void *context)
fprintf(stderr, "fault addr=%p", siginfo->si_addr);
fprintf(stderr, "\n");
-#ifdef HAVE_BACKTRACE
+#if defined(HAVE_BACKTRACE) && !defined(DISABLE_BACKTRACE)
frames = backtrace(stack_syms, 32);
backtrace_symbols_fd(stack_syms, frames, 2);
#endif
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 6c18d0ef..81503d4b 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -22,6 +22,7 @@
#define MIN_CHECK 1
#define MAX_CHECK 2
+#define LOG2_CHECK 4
static void check_super_value(e2fsck_t ctx, const char *descr,
unsigned long value, int flags,
@@ -29,8 +30,9 @@ static void check_super_value(e2fsck_t ctx, const char *descr,
{
struct problem_context pctx;
- if (((flags & MIN_CHECK) && (value < min_val)) ||
- ((flags & MAX_CHECK) && (value > max_val))) {
+ if ((flags & MIN_CHECK && value < min_val) ||
+ (flags & MAX_CHECK && value > max_val) ||
+ (flags & LOG2_CHECK && (value & (value - 1)) != 0)) {
clear_problem_context(&pctx);
pctx.num = value;
pctx.str = descr;
@@ -143,6 +145,7 @@ static int release_inode_block(ext2_filsys fs,
}
ext2fs_block_alloc_stats2(fs, blk, -1);
+ ctx->free_blocks++;
return retval;
}
@@ -211,9 +214,11 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
ino);
return 1;
}
- if (count == 0)
+ if (count == 0) {
ext2fs_block_alloc_stats2(fs,
ext2fs_file_acl_block(fs, inode), -1);
+ ctx->free_blocks++;
+ }
ext2fs_file_acl_block_set(fs, inode, 0);
}
return 0;
@@ -286,6 +291,7 @@ static int release_orphan_inodes(e2fsck_t ctx)
if (!inode.i_links_count) {
ext2fs_inode_alloc_stats2(fs, ino, -1,
LINUX_S_ISDIR(inode.i_mode));
+ ctx->free_inodes++;
inode.i_dtime = ctx->now;
} else {
inode.i_dtime = 0;
@@ -313,7 +319,8 @@ void check_resize_inode(e2fsck_t ctx)
struct problem_context pctx;
int i, gdt_off, ind_off;
dgrp_t j;
- blk64_t blk, pblk, expect;
+ blk_t blk, pblk;
+ blk_t expect; /* for resize inode, which is 32-bit only */
__u32 *dind_buf = 0, *ind_buf;
errcode_t retval;
@@ -460,11 +467,11 @@ void check_super_block(e2fsck_t ctx)
ext2_filsys fs = ctx->fs;
blk64_t first_block, last_block;
struct ext2_super_block *sb = fs->super;
+ unsigned int ipg_max;
problem_t problem;
blk64_t blocks_per_group = fs->super->s_blocks_per_group;
__u32 bpg_max, cpg_max;
int inodes_per_block;
- int ipg_max;
int inode_size;
int accept_time_fudge;
int broken_system_clock;
@@ -522,14 +529,17 @@ void check_super_block(e2fsck_t ctx)
MAX_CHECK, 0, ext2fs_blocks_count(sb) / 2);
check_super_value(ctx, "reserved_gdt_blocks",
sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
- fs->blocksize/4);
+ fs->blocksize / sizeof(__u32));
+ check_super_value(ctx, "desc_size",
+ sb->s_desc_size, MAX_CHECK | LOG2_CHECK, 0,
+ EXT2_MAX_DESC_SIZE);
if (sb->s_rev_level > EXT2_GOOD_OLD_REV)
check_super_value(ctx, "first_ino", sb->s_first_ino,
MIN_CHECK | MAX_CHECK,
EXT2_GOOD_OLD_FIRST_INO, sb->s_inodes_count);
inode_size = EXT2_INODE_SIZE(sb);
check_super_value(ctx, "inode_size",
- inode_size, MIN_CHECK | MAX_CHECK,
+ inode_size, MIN_CHECK | MAX_CHECK | LOG2_CHECK,
EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
if (sb->s_blocks_per_group != (sb->s_clusters_per_group *
EXT2FS_CLUSTER_RATIO(fs))) {
@@ -539,13 +549,6 @@ void check_super_block(e2fsck_t ctx)
ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
return;
}
- if (inode_size & (inode_size - 1)) {
- pctx.num = inode_size;
- pctx.str = "inode_size";
- fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
- ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
- return;
- }
if ((ctx->flags & E2F_FLAG_GOT_DEVSIZE) &&
(ctx->num_blocks < ext2fs_blocks_count(sb))) {
@@ -577,6 +580,17 @@ void check_super_block(e2fsck_t ctx)
}
}
+ /* Is 64bit set and extents unset? */
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_INCOMPAT_64BIT) &&
+ !EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+ EXT3_FEATURE_INCOMPAT_EXTENTS) &&
+ fix_problem(ctx, PR_0_64BIT_WITHOUT_EXTENTS, &pctx)) {
+ fs->super->s_feature_incompat |=
+ EXT3_FEATURE_INCOMPAT_EXTENTS;
+ ext2fs_mark_super_dirty(fs);
+ }
+
/*
* Verify the group descriptors....
*/
@@ -708,8 +722,11 @@ void check_super_block(e2fsck_t ctx)
#ifndef EXT2_SKIP_UUID
/*
* If the UUID field isn't assigned, assign it.
+ * Skip if checksums are enabled and the filesystem is mounted,
+ * if the id changes under the kernel remounting rw may fail.
*/
- if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
+ if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid) &&
+ (!csum_flag || !(ctx->mount_flags & EXT2_MF_MOUNTED))) {
if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
uuid_generate(sb->s_uuid);
fs->flags |= EXT2_FLAG_DIRTY;
@@ -910,8 +927,7 @@ int check_backup_super_block(e2fsck_t ctx)
if (!ext2fs_bg_has_super(fs, g))
continue;
- sb = fs->super->s_first_data_block +
- (g * fs->super->s_blocks_per_group);
+ sb = ext2fs_group_first_block2(fs, g);
retval = io_channel_read_blk(fs->io, sb, -SUPERBLOCK_SIZE,
buf);
@@ -941,6 +957,7 @@ int check_backup_super_block(e2fsck_t ctx)
SUPER_INCOMPAT_DIFFERENT(s_feature_incompat) ||
SUPER_RO_COMPAT_DIFFERENT(s_feature_ro_compat) ||
SUPER_DIFFERENT(s_blocks_count) ||
+ SUPER_DIFFERENT(s_blocks_count_hi) ||
SUPER_DIFFERENT(s_inodes_count) ||
memcmp(fs->super->s_uuid, backup_sb->s_uuid,
sizeof(fs->super->s_uuid)))
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index 190deaf9..74ef32d4 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -33,9 +33,6 @@ extern int optind;
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#ifdef HAVE_MNTENT_H
-#include <mntent.h>
-#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
@@ -80,13 +77,13 @@ static void usage(e2fsck_t ctx)
"\t\t[-E extended-options] device\n"),
ctx->program_name);
- fprintf(stderr, _("\nEmergency help:\n"
+ fprintf(stderr, "%s", _("\nEmergency help:\n"
" -p Automatic repair (no questions)\n"
" -n Make no changes to the filesystem\n"
" -y Assume \"yes\" to all questions\n"
" -c Check for bad blocks and add them to the badblock list\n"
" -f Force checking even if filesystem is marked clean\n"));
- fprintf(stderr, _(""
+ fprintf(stderr, "%s", _(""
" -v Be verbose\n"
" -b superblock Use alternative superblock\n"
" -B blocksize Force blocksize when looking for superblock\n"
@@ -105,8 +102,9 @@ static void show_stats(e2fsck_t ctx)
blk64_t blocks, blocks_used;
unsigned int dir_links;
unsigned int num_files, num_links;
+ __u32 *mask, m;
int frag_percent_file, frag_percent_dir, frag_percent_total;
- int i, j;
+ int i, j, printed = 0;
dir_links = 2 * ctx->fs_directory_count - 1;
num_files = ctx->fs_total_count - dir_links;
@@ -137,21 +135,40 @@ static void show_stats(e2fsck_t ctx)
blocks_used, blocks);
return;
}
- log_out(ctx, P_("\n%8u inode used (%2.2f%%)\n",
- "\n%8u inodes used (%2.2f%%)\n",
+ profile_get_boolean(ctx->profile, "options", "report_features", 0, 0,
+ &i);
+ if (verbose && i) {
+ log_out(ctx, "\nFilesystem features:");
+ mask = &ctx->fs->super->s_feature_compat;
+ for (i = 0; i < 3; i++, mask++) {
+ for (j = 0, m = 1; j < 32; j++, m <<= 1) {
+ if (*mask & m) {
+ log_out(ctx, " %s",
+ e2p_feature2string(i, m));
+ printed++;
+ }
+ }
+ }
+ if (printed == 0)
+ log_out(ctx, " (none)");
+ log_out(ctx, "\n");
+ }
+
+ log_out(ctx, P_("\n%12u inode used (%2.2f%%, out of %u)\n",
+ "\n%12u inodes used (%2.2f%%, out of %u)\n",
inodes_used), inodes_used,
- 100.0 * inodes_used / inodes);
- log_out(ctx, P_("%8u non-contiguous file (%0d.%d%%)\n",
- "%8u non-contiguous files (%0d.%d%%)\n",
+ 100.0 * inodes_used / inodes, inodes);
+ log_out(ctx, P_("%12u non-contiguous file (%0d.%d%%)\n",
+ "%12u non-contiguous files (%0d.%d%%)\n",
ctx->fs_fragmented),
ctx->fs_fragmented, frag_percent_file / 10,
frag_percent_file % 10);
- log_out(ctx, P_("%8u non-contiguous directory (%0d.%d%%)\n",
- "%8u non-contiguous directories (%0d.%d%%)\n",
+ log_out(ctx, P_("%12u non-contiguous directory (%0d.%d%%)\n",
+ "%12u non-contiguous directories (%0d.%d%%)\n",
ctx->fs_fragmented_dir),
ctx->fs_fragmented_dir, frag_percent_dir / 10,
frag_percent_dir % 10);
- log_out(ctx, _(" # of inodes with ind/dind/tind blocks: "
+ log_out(ctx, _(" # of inodes with ind/dind/tind blocks: "
"%u/%u/%u\n"),
ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
@@ -159,7 +176,7 @@ static void show_stats(e2fsck_t ctx)
if (ctx->extent_depth_count[j])
break;
if (++j) {
- log_out(ctx, _(" Extent depth histogram: "));
+ log_out(ctx, "%s", _(" Extent depth histogram: "));
for (i=0; i < j; i++) {
if (i)
fputc('/', stdout);
@@ -168,39 +185,39 @@ static void show_stats(e2fsck_t ctx)
log_out(ctx, "\n");
}
- log_out(ctx, P_("%8llu block used (%2.2f%%)\n",
- "%8llu blocks used (%2.2f%%)\n",
- blocks_used), blocks_used, 100.0 * blocks_used / blocks);
- log_out(ctx, P_("%8u bad block\n", "%8u bad blocks\n",
+ log_out(ctx, P_("%12llu block used (%2.2f%%, out of %llu)\n",
+ "%12llu blocks used (%2.2f%%, out of %llu)\n",
+ blocks_used),
+ blocks_used, 100.0 * blocks_used / blocks, blocks);
+ log_out(ctx, P_("%12u bad block\n", "%12u bad blocks\n",
ctx->fs_badblocks_count), ctx->fs_badblocks_count);
- log_out(ctx, P_("%8u large file\n", "%8u large files\n",
+ log_out(ctx, P_("%12u large file\n", "%12u large files\n",
ctx->large_files), ctx->large_files);
- log_out(ctx, P_("\n%8u regular file\n", "\n%8u regular files\n",
+ log_out(ctx, P_("\n%12u regular file\n", "\n%12u regular files\n",
ctx->fs_regular_count), ctx->fs_regular_count);
- log_out(ctx, P_("%8u directory\n", "%8u directories\n",
+ log_out(ctx, P_("%12u directory\n", "%12u directories\n",
ctx->fs_directory_count), ctx->fs_directory_count);
- log_out(ctx, P_("%8u character device file\n",
- "%8u character device files\n", ctx->fs_chardev_count),
+ log_out(ctx, P_("%12u character device file\n",
+ "%12u character device files\n", ctx->fs_chardev_count),
ctx->fs_chardev_count);
- log_out(ctx, P_("%8u block device file\n", "%8u block device files\n",
+ log_out(ctx, P_("%12u block device file\n", "%12u block device files\n",
ctx->fs_blockdev_count), ctx->fs_blockdev_count);
- log_out(ctx, P_("%8u fifo\n", "%8u fifos\n", ctx->fs_fifo_count),
+ log_out(ctx, P_("%12u fifo\n", "%12u fifos\n", ctx->fs_fifo_count),
ctx->fs_fifo_count);
- log_out(ctx, P_("%8u link\n", "%8u links\n",
- ctx->fs_links_count - dir_links),
+ log_out(ctx, P_("%12u link\n", "%12u links\n", num_links),
ctx->fs_links_count - dir_links);
- log_out(ctx, P_("%8u symbolic link", "%8u symbolic links",
+ log_out(ctx, P_("%12u symbolic link", "%12u symbolic links",
ctx->fs_symlinks_count), ctx->fs_symlinks_count);
log_out(ctx, P_(" (%u fast symbolic link)\n",
" (%u fast symbolic links)\n",
ctx->fs_fast_symlinks_count),
ctx->fs_fast_symlinks_count);
- log_out(ctx, P_("%8u socket\n", "%8u sockets\n", ctx->fs_sockets_count),
+ log_out(ctx, P_("%12u socket\n", "%12u sockets\n",
+ ctx->fs_sockets_count),
ctx->fs_sockets_count);
- log_out(ctx, "--------\n");
- log_out(ctx, P_("%8u file\n", "%8u files\n",
- ctx->fs_total_count - dir_links),
- ctx->fs_total_count - dir_links);
+ log_out(ctx, "------------\n");
+ log_out(ctx, P_("%12u file\n", "%12u files\n", num_files),
+ num_files);
}
static void check_mount(e2fsck_t ctx)
@@ -222,31 +239,36 @@ static void check_mount(e2fsck_t ctx)
* filesystem and it's mounted read-only, and we're not doing
* a read/write check, then everything's fine.
*/
- if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
+ if ((!(ctx->mount_flags & (EXT2_MF_MOUNTED | EXT2_MF_BUSY))) ||
((ctx->mount_flags & EXT2_MF_ISROOT) &&
(ctx->mount_flags & EXT2_MF_READONLY) &&
!(ctx->options & E2F_OPT_WRITECHECK)))
return;
- if ((ctx->options & E2F_OPT_READONLY) &&
+ if (((ctx->options & E2F_OPT_READONLY) ||
+ ((ctx->options & E2F_OPT_FORCE) &&
+ (ctx->mount_flags & EXT2_MF_READONLY))) &&
!(ctx->options & E2F_OPT_WRITECHECK)) {
- log_out(ctx, _("Warning! %s is mounted.\n"),
- ctx->filesystem_name);
+ log_out(ctx, _("Warning! %s is %s.\n"),
+ ctx->filesystem_name,
+ ctx->mount_flags & EXT2_MF_MOUNTED ?
+ "mounted" : "in use");
return;
}
- log_out(ctx, _("%s is mounted. "), ctx->filesystem_name);
- if (!ctx->interactive)
+ log_out(ctx, _("%s is %s.\n"), ctx->filesystem_name,
+ ctx->mount_flags & EXT2_MF_MOUNTED ? "mounted" : "in use");
+ if (!ctx->interactive || ctx->mount_flags & EXT2_MF_BUSY)
fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
puts("\007\007\007\007");
- log_out(ctx, _("\n\nWARNING!!! "
+ log_out(ctx, "%s", _("\n\nWARNING!!! "
"The filesystem is mounted. "
"If you continue you ***WILL***\n"
"cause ***SEVERE*** filesystem damage.\n\n"));
puts("\007\007\007");
cont = ask_yn(ctx, _("Do you really want to continue"), 0);
if (!cont) {
- printf (_("check aborted.\n"));
+ printf("%s", _("check aborted.\n"));
exit (0);
}
return;
@@ -262,7 +284,7 @@ static int is_on_batt(void)
f = fopen("/sys/class/power_supply/AC/online", "r");
if (f) {
- if (fscanf(f, "%d\n", &acflag) == 1) {
+ if (fscanf(f, "%u\n", &acflag) == 1) {
fclose(f);
return (!acflag);
}
@@ -315,6 +337,9 @@ static void check_if_skip(e2fsck_t ctx)
int broken_system_clock;
time_t lastcheck;
+ if (ctx->flags & E2F_FLAG_PROBLEMS_FIXED)
+ return;
+
profile_get_boolean(ctx->profile, "options", "broken_system_clock",
0, 0, &broken_system_clock);
if (ctx->flags & E2F_FLAG_TIME_INSANE)
@@ -366,7 +391,7 @@ static void check_if_skip(e2fsck_t ctx)
if (reason) {
log_out(ctx, "%s", ctx->device_name);
log_out(ctx, reason, reason_arg);
- log_out(ctx, _(", check forced.\n"));
+ log_out(ctx, "%s", _(", check forced.\n"));
return;
}
@@ -418,12 +443,14 @@ static void check_if_skip(e2fsck_t ctx)
if (next_check <= 5) {
if (next_check == 1) {
if (batt)
- log_out(ctx, _(" (check deferred; "
- "on battery)"));
+ log_out(ctx, "%s",
+ _(" (check deferred; on battery)"));
else
- log_out(ctx, _(" (check after next mount)"));
+ log_out(ctx, "%s",
+ _(" (check after next mount)"));
} else
- log_out(ctx, _(" (check in %ld mounts)"), next_check);
+ log_out(ctx, _(" (check in %ld mounts)"),
+ next_check);
}
log_out(ctx, "\n");
skip:
@@ -440,7 +467,7 @@ struct percent_tbl {
int max_pass;
int table[32];
};
-struct percent_tbl e2fsck_tbl = {
+static struct percent_tbl e2fsck_tbl = {
5, { 0, 70, 90, 92, 95, 100 }
};
static char bar[128], spaces[128];
@@ -459,7 +486,7 @@ static float calc_percent(struct percent_tbl *tbl, int pass, int curr,
+ tbl->table[pass-1]);
}
-extern void e2fsck_clear_progbar(e2fsck_t ctx)
+void e2fsck_clear_progbar(e2fsck_t ctx)
{
if (!(ctx->flags & E2F_FLAG_PROG_BAR))
return;
@@ -641,7 +668,7 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
ea_ver = strtoul(arg, &p, 0);
if (*p ||
((ea_ver != 1) && (ea_ver != 2))) {
- fprintf(stderr,
+ fprintf(stderr, "%s",
_("Invalid EA version.\n"));
extended_usage++;
continue;
@@ -725,6 +752,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
return retval;
*ret_ctx = ctx;
+ e2fsck_global_ctx = ctx;
setvbuf(stdout, NULL, _IONBF, BUFSIZ);
setvbuf(stderr, NULL, _IONBF, BUFSIZ);
@@ -847,6 +875,8 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
case 'L':
replace_bad_blocks++;
case 'l':
+ if (bad_blocks_file)
+ free(bad_blocks_file);
bad_blocks_file = string_copy(ctx, optarg, 0);
break;
case 'd':
@@ -884,17 +914,17 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
usage(ctx);
if ((ctx->options & E2F_OPT_NO) &&
(ctx->options & E2F_OPT_COMPRESS_DIRS)) {
- com_err(ctx->program_name, 0,
+ com_err(ctx->program_name, 0, "%s",
_("The -n and -D options are incompatible."));
fatal_error(ctx, 0);
}
if ((ctx->options & E2F_OPT_NO) && cflag) {
- com_err(ctx->program_name, 0,
+ com_err(ctx->program_name, 0, "%s",
_("The -n and -c options are incompatible."));
fatal_error(ctx, 0);
}
if ((ctx->options & E2F_OPT_NO) && bad_blocks_file) {
- com_err(ctx->program_name, 0,
+ com_err(ctx->program_name, 0, "%s",
_("The -n and -l/-L options are incompatible."));
fatal_error(ctx, 0);
}
@@ -918,6 +948,15 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
profile_set_syntax_err_cb(syntax_err_report);
profile_init(config_fn, &ctx->profile);
+ profile_get_boolean(ctx->profile, "options", "report_time", 0, 0,
+ &c);
+ if (c)
+ ctx->options |= E2F_OPT_TIME | E2F_OPT_TIME2;
+ profile_get_boolean(ctx->profile, "options", "report_verbose", 0, 0,
+ &c);
+ if (c)
+ verbose = 1;
+
/* Turn off discard in read-only mode */
if ((ctx->options & E2F_OPT_NO) &&
(ctx->options & E2F_OPT_DISCARD))
@@ -940,8 +979,8 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
close(fd);
}
if (cflag && bad_blocks_file) {
- fprintf(stderr, _("The -c and the -l/-L options may "
- "not be both used at the same time.\n"));
+ fprintf(stderr, "%s", _("The -c and the -l/-L options may not "
+ "be both used at the same time.\n"));
exit(FSCK_USAGE);
}
#ifdef HAVE_SIGNAL_H
@@ -955,7 +994,6 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
#ifdef SA_RESTART
sa.sa_flags = SA_RESTART;
#endif
- e2fsck_global_ctx = ctx;
sa.sa_handler = signal_progress_on;
sigaction(SIGUSR1, &sa, 0);
sa.sa_handler = signal_progress_off;
@@ -1031,16 +1069,18 @@ static errcode_t try_open_fs(e2fsck_t ctx, int flags, io_manager io_ptr,
retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
flags, 0, 0, io_ptr, ret_fs);
- if (ret_fs)
+ if (retval == 0) {
+ (*ret_fs)->priv_data = ctx;
e2fsck_set_bitmap_type(*ret_fs, EXT2FS_BMAP64_RBTREE,
"default", NULL);
+ }
return retval;
}
static const char *my_ver_string = E2FSPROGS_VERSION;
static const char *my_ver_date = E2FSPROGS_DATE;
-int e2fsck_check_mmp(ext2_filsys fs, e2fsck_t ctx)
+static errcode_t e2fsck_check_mmp(ext2_filsys fs, e2fsck_t ctx)
{
struct mmp_struct *mmp_s;
unsigned int mmp_check_interval;
@@ -1102,12 +1142,12 @@ check_error:
retval = 0;
}
} else if (retval == EXT2_ET_MMP_FAILED) {
- com_err(ctx->program_name, retval,
+ com_err(ctx->program_name, retval, "%s",
_("while checking MMP block"));
dump_mmp_msg(fs->mmp_buf, NULL);
} else if (retval == EXT2_ET_MMP_FSCK_ON ||
retval == EXT2_ET_MMP_UNKNOWN_SEQ) {
- com_err(ctx->program_name, retval,
+ com_err(ctx->program_name, retval, "%s",
_("while checking MMP block"));
dump_mmp_msg(fs->mmp_buf,
_("If you are sure the filesystem is not "
@@ -1132,7 +1172,7 @@ int main (int argc, char *argv[])
const char *lib_ver_date;
int my_ver, lib_ver;
e2fsck_t ctx;
- blk_t orig_superblock;
+ blk64_t orig_superblock;
struct problem_context pctx;
int flags, run_result;
int journal_size;
@@ -1140,6 +1180,7 @@ int main (int argc, char *argv[])
int old_bitmaps;
__u32 features[3];
char *cp;
+ int qtype = -99; /* quota type */
clear_problem_context(&pctx);
sigcatcher_setup();
@@ -1159,14 +1200,14 @@ int main (int argc, char *argv[])
my_ver = ext2fs_parse_version_string(my_ver_string);
lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
if (my_ver > lib_ver) {
- fprintf( stderr, _("Error: ext2fs library version "
- "out of date!\n"));
+ fprintf( stderr, "%s",
+ _("Error: ext2fs library version out of date!\n"));
show_version_only++;
}
retval = PRS(argc, argv, &ctx);
if (retval) {
- com_err("e2fsck", retval,
+ com_err("e2fsck", retval, "%s",
_("while trying to initialize program"));
exit(FSCK_ERROR);
}
@@ -1220,10 +1261,15 @@ restart:
&old_bitmaps);
if (!old_bitmaps)
flags |= EXT2_FLAG_64BITS;
- if ((ctx->options & E2F_OPT_READONLY) == 0)
+ if ((ctx->options & E2F_OPT_READONLY) == 0) {
flags |= EXT2_FLAG_RW;
- if ((ctx->mount_flags & EXT2_MF_MOUNTED) == 0)
- flags |= EXT2_FLAG_EXCLUSIVE;
+ if (!(ctx->mount_flags & EXT2_MF_ISROOT &&
+ ctx->mount_flags & EXT2_MF_READONLY))
+ flags |= EXT2_FLAG_EXCLUSIVE;
+ if ((ctx->mount_flags & EXT2_MF_READONLY) &&
+ (ctx->options & E2F_OPT_FORCE))
+ flags &= ~EXT2_FLAG_EXCLUSIVE;
+ }
retval = try_open_fs(ctx, flags, io_ptr, &fs);
@@ -1295,32 +1341,34 @@ failure:
com_err(ctx->program_name, retval, _("while trying to open %s"),
ctx->filesystem_name);
if (retval == EXT2_ET_REV_TOO_HIGH) {
- log_out(ctx, _("The filesystem revision is apparently "
- "too high for this version of e2fsck.\n"
- "(Or the filesystem superblock "
- "is corrupt)\n\n"));
+ log_out(ctx, "%s",
+ _("The filesystem revision is apparently "
+ "too high for this version of e2fsck.\n"
+ "(Or the filesystem superblock "
+ "is corrupt)\n\n"));
fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
} else if (retval == EXT2_ET_SHORT_READ)
- log_out(ctx, _("Could this be a zero-length "
- "partition?\n"));
+ log_out(ctx, "%s",
+ _("Could this be a zero-length partition?\n"));
else if ((retval == EPERM) || (retval == EACCES))
log_out(ctx, _("You must have %s access to the "
- "filesystem or be root\n"),
+ "filesystem or be root\n"),
(ctx->options & E2F_OPT_READONLY) ?
"r/o" : "r/w");
else if (retval == ENXIO)
- log_out(ctx, _("Possibly non-existent or "
- "swap device?\n"));
+ log_out(ctx, "%s",
+ _("Possibly non-existent or swap device?\n"));
else if (retval == EBUSY)
- log_out(ctx, _("Filesystem mounted or opened "
- "exclusively by another program?\n"));
+ log_out(ctx, "%s", _("Filesystem mounted or opened "
+ "exclusively by another program?\n"));
else if (retval == ENOENT)
- log_out(ctx, _("Possibly non-existent device?\n"));
+ log_out(ctx, "%s",
+ _("Possibly non-existent device?\n"));
#ifdef EROFS
else if (retval == EROFS)
- log_out(ctx, _("Disk write-protected; use the -n "
- "option to do a read-only\n"
- "check of the device.\n"));
+ log_out(ctx, "%s", _("Disk write-protected; use the "
+ "-n option to do a read-only\n"
+ "check of the device.\n"));
#endif
else
fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
@@ -1374,7 +1422,6 @@ failure:
}
ctx->fs = fs;
- fs->priv_data = ctx;
fs->now = ctx->now;
sb = fs->super;
@@ -1421,10 +1468,6 @@ failure:
fprintf(ctx->logf, "Filesystem UUID: %s\n",
e2p_uuid2str(sb->s_uuid));
- if ((ctx->mount_flags & EXT2_MF_MOUNTED) &&
- !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER))
- goto skip_journal;
-
/*
* Make sure the ext3 superblock fields are consistent.
*/
@@ -1442,9 +1485,9 @@ failure:
*/
if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
if (ctx->options & E2F_OPT_READONLY) {
- log_out(ctx, _("Warning: skipping journal recovery "
- "because doing a read-only filesystem "
- "check.\n"));
+ log_out(ctx, "%s",
+ _("Warning: skipping journal recovery because "
+ "doing a read-only filesystem check.\n"));
io_channel_flush(ctx->fs->io);
} else {
if (ctx->flags & E2F_FLAG_RESTARTED) {
@@ -1455,7 +1498,8 @@ failure:
* device driver is being bogus.
*/
com_err(ctx->program_name, 0,
- _("unable to set superblock flags on %s\n"), ctx->device_name);
+ _("unable to set superblock flags "
+ "on %s\n"), ctx->device_name);
fatal_error(ctx, 0);
}
retval = e2fsck_run_ext3_journal(ctx);
@@ -1472,7 +1516,6 @@ failure:
}
}
-skip_journal:
/*
* Check for compatibility with the feature sets. We need to
* be more stringent than ext2fs_open().
@@ -1562,8 +1605,8 @@ print_unsupp_features:
log_out(ctx, _("%s: %s while reading bad blocks inode\n"),
ctx->program_name, error_message(retval));
preenhalt(ctx);
- log_out(ctx, _("This doesn't bode well, "
- "but we'll try to go on...\n"));
+ log_out(ctx, "%s", _("This doesn't bode well, "
+ "but we'll try to go on...\n"));
}
/*
@@ -1578,7 +1621,6 @@ print_unsupp_features:
journal_size = -1;
if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_QUOTA) {
- int qtype;
/* Quotas were enabled. Do quota accounting during fsck. */
if ((sb->s_usr_quota_inum && sb->s_grp_quota_inum) ||
(!sb->s_usr_quota_inum && !sb->s_grp_quota_inum))
@@ -1614,23 +1656,36 @@ print_unsupp_features:
"journal\n", error_message(retval));
goto no_journal;
}
- log_out(ctx, _(" Done.\n"));
- log_out(ctx, _("\n*** journal has been re-created - "
- "filesystem is now ext3 again ***\n"));
+ log_out(ctx, "%s", _(" Done.\n"));
+ log_out(ctx, "%s",
+ _("\n*** journal has been re-created - "
+ "filesystem is now ext3 again ***\n"));
}
}
no_journal:
if (ctx->qctx) {
- quota_write_inode(ctx->qctx, -1);
+ int i, needs_writeout;
+ for (i = 0; i < MAXQUOTAS; i++) {
+ if (qtype != -1 && qtype != i)
+ continue;
+ needs_writeout = 0;
+ pctx.num = i;
+ retval = quota_compare_and_update(ctx->qctx, i,
+ &needs_writeout);
+ if ((retval || needs_writeout) &&
+ fix_problem(ctx, PR_6_UPDATE_QUOTAS, &pctx))
+ quota_write_inode(ctx->qctx, i);
+ }
quota_release_context(&ctx->qctx);
}
if (run_result == E2F_FLAG_RESTART) {
- log_out(ctx, _("Restarting e2fsck from the beginning...\n"));
+ log_out(ctx, "%s",
+ _("Restarting e2fsck from the beginning...\n"));
retval = e2fsck_reset_context(ctx);
if (retval) {
- com_err(ctx->program_name, retval,
+ com_err(ctx->program_name, retval, "%s",
_("while resetting context"));
fatal_error(ctx, 0);
}
@@ -1706,7 +1761,7 @@ no_journal:
!(ctx->options & E2F_OPT_READONLY)) {
retval = ext2fs_set_gdt_csum(ctx->fs);
if (retval) {
- com_err(ctx->program_name, retval,
+ com_err(ctx->program_name, retval, "%s",
_("while setting block group checksum info"));
fatal_error(ctx, 0);
}
diff --git a/e2fsck/util.c b/e2fsck/util.c
index 7c4caab0..43486313 100644
--- a/e2fsck/util.c
+++ b/e2fsck/util.c
@@ -55,7 +55,7 @@ void fatal_error(e2fsck_t ctx, const char *msg)
fprintf (stderr, "e2fsck: %s\n", msg);
if (!fs)
goto out;
- if (fs->io) {
+ if (fs->io && fs->super) {
ext2fs_mmp_stop(ctx->fs);
if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
io_channel_flush(ctx->fs->io);
@@ -121,7 +121,8 @@ void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
#endif
ret = malloc(size);
if (!ret) {
- sprintf(buf, "Can't allocate %s\n", description);
+ sprintf(buf, "Can't allocate %u bytes for %s\n",
+ size, description);
fatal_error(ctx, buf);
}
memset(ret, 0, size);
@@ -219,7 +220,7 @@ int ask_yn(e2fsck_t ctx, const char * string, int def)
log_out(ctx, "\n");
longjmp(e2fsck_global_ctx->abort_loc, 1);
}
- log_out(ctx, _("cancelled!\n"));
+ log_out(ctx, "%s", _("cancelled!\n"));
return 0;
}
if (strchr(short_yes, (char) c)) {
@@ -234,9 +235,9 @@ int ask_yn(e2fsck_t ctx, const char * string, int def)
break;
}
if (def)
- log_out(ctx, _("yes\n"));
+ log_out(ctx, "%s", _("yes\n"));
else
- log_out(ctx, _("no\n"));
+ log_out(ctx, "%s", _("no\n"));
#ifdef HAVE_TERMIOS_H
tcsetattr (0, TCSANOW, &termios);
#endif
@@ -438,7 +439,7 @@ void print_resource_track(e2fsck_t ctx, const char *desc,
void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
struct ext2_inode * inode, const char *proc)
{
- int retval;
+ errcode_t retval;
retval = ext2fs_read_inode(ctx->fs, ino, inode);
if (retval) {
@@ -452,7 +453,7 @@ void e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino,
struct ext2_inode *inode, int bufsize,
const char *proc)
{
- int retval;
+ errcode_t retval;
retval = ext2fs_read_inode_full(ctx->fs, ino, inode, bufsize);
if (retval) {
@@ -462,11 +463,11 @@ void e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino,
}
}
-extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
- struct ext2_inode * inode, int bufsize,
- const char *proc)
+void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
+ struct ext2_inode * inode, int bufsize,
+ const char *proc)
{
- int retval;
+ errcode_t retval;
retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
if (retval) {
@@ -476,10 +477,10 @@ extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
}
}
-extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
- struct ext2_inode * inode, const char *proc)
+void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
+ struct ext2_inode * inode, const char *proc)
{
- int retval;
+ errcode_t retval;
retval = ext2fs_write_inode(ctx->fs, ino, inode);
if (retval) {
@@ -500,14 +501,14 @@ void mtrace_print(char *mesg)
}
#endif
-blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
- io_manager manager)
+blk64_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
+ io_manager manager)
{
struct ext2_super_block *sb;
io_channel io = NULL;
void *buf = NULL;
int blocksize;
- blk_t superblock, ret_sb = 8193;
+ blk64_t superblock, ret_sb = 8193;
if (fs && fs->super) {
ret_sb = (fs->super->s_blocks_per_group +
@@ -616,7 +617,7 @@ int ext2_file_type(unsigned int mode)
errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
blk_t *ret_blk, int *ret_count)
{
- int j, count, next_update, next_update_incr;
+ int j, count;
static char *buf;
errcode_t retval;
@@ -632,17 +633,13 @@ errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
if (!buf) {
buf = malloc(fs->blocksize * STRIDE_LENGTH);
if (!buf) {
- com_err("malloc", ENOMEM,
+ com_err("malloc", ENOMEM, "%s",
_("while allocating zeroizing buffer"));
exit(1);
}
memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
}
/* OK, do the write loop */
- next_update = 0;
- next_update_incr = num / 100;
- if (next_update_incr < 1)
- next_update_incr = 1;
for (j = 0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
count = num - j;
if (count > STRIDE_LENGTH)
@@ -795,14 +792,13 @@ void e2fsck_set_bitmap_type(ext2_filsys fs, unsigned int default_type,
const char *profile_name, unsigned int *old_type)
{
unsigned type;
- errcode_t retval;
+ e2fsck_t ctx = (e2fsck_t) fs->priv_data;
if (old_type)
*old_type = fs->default_bitmap_type;
- profile_get_uint(e2fsck_global_ctx->profile, "bitmaps",
- profile_name, 0, default_type, &type);
- profile_get_uint(e2fsck_global_ctx->profile, "bitmaps",
- "all", 0, type, &type);
+ profile_get_uint(ctx->profile, "bitmaps", profile_name, 0,
+ default_type, &type);
+ profile_get_uint(ctx->profile, "bitmaps", "all", 0, type, &type);
fs->default_bitmap_type = type ? type : default_type;
}