Compare commits

..
15 Commits
Author SHA1 Message Date
lgcosta e760d19017 Fix second use-after-free in the rollback path; clang battery re-validated
build / build (clang, ) (push) Failing after 6s
build / build (clang, --enable-warnings) (push) Failing after 6s
build / build (gcc, ) (push) Failing after 6s
build / build (gcc, --enable-io-failure-emulation) (push) Failing after 6s
build / build (gcc, --enable-warnings) (push) Failing after 7s
build / out-of-tree (push) Failing after 6s
build / sanitizers (push) Failing after 5s
ASan with halt_on_error caught a second dangling read on the exact path
--rollback-fsck-changes exits through: fsck_rollback() called freemem(fs)
at fsck/main.c:1313 and then printed the closing banner via
fsck_progress(...), which dereferences fs (fsck_data(fs) etc.).

Print the banner before the cleanup, matching the order the_end() and the
rebuild paths already use. No behavior change otherwise -- the same bytes
are emitted, only before the free.

Re-validated after the fix:
- clang+ASan/UBSan with halt_on_error: rollback save/restore, garbage-magic
  rejection, resize 64->128 MiB, mkfs, check, tune, debugreiserfs -- zero
  sanitizer errors; restore still prints "blocks restored" and the final
  banner.
- host functional battery (gcc, --enable-warnings): 12/12.
- host clang out-of-tree build: 0 warnings; clang rollback path exercised
  without sanitizers: exit semantics unchanged.
- Debian VM, CC=clang battery on this exact tree: 12/12, 0 warnings.

tests/vm/RESULTS.md documents the finding (item 6 in the clang section).
2026-11-12 09:11:55 -03:00
lgcosta 7b5421ce49 Support clang builds; fix the defects clang and its sanitizers exposed
build / build (clang, ) (push) Failing after 7s
build / build (clang, --enable-warnings) (push) Failing after 5s
build / build (gcc, ) (push) Failing after 5s
build / build (gcc, --enable-io-failure-emulation) (push) Failing after 5s
build / build (gcc, --enable-warnings) (push) Failing after 6s
build / out-of-tree (push) Failing after 6s
build / sanitizers (push) Failing after 5s
Clang (22.1.8 on the host, 14.0.6 in the Debian VM) now builds the tree
warning-free with --enable-warnings, in-tree and out-of-tree, with -j, and
the full VM battery passes with CC=clang: 12/12. ASan/UBSan builds run the
real tool paths (mkfs, check, tune, resize, rollback save/restore/reject)
with halt_on_error and report zero errors. Documented in tests/vm/RESULTS.md;
the CI gained clang+warnings, out-of-tree and sanitizer jobs.

Fixes found by this work:

- reiserfscore/Makefile.am: reiserfs_err.c and reiserfs_err.h shared one
  recipe. With -j, make runs the recipe once per stale target, so two
  compile_et invocations race: one deletes reiserfs_err.c ("no input
  files") while another job compiles it. Attached the recipe to
  reiserfs_err.c only; reiserfs_err.h merely depends on it. Reproduced
  with clang+ASan, stable across 5 clang / 3 asan / 3 gcc parallel builds.

- reiserfscore/Makefile.am: the rule read the source-local
  reiserfs_err.et, so VPATH builds could not find it. Use $(srcdir)/.
  make distcheck now passes.

- reiserfscore/reiserfslib.c: reiserfs_close() did fsync(fs->fs_dev) after
  reiserfs_free() released fs -- a 4-byte heap-use-after-free, flagged
  exactly at reiserfslib.c:406/407 by ASan (found by clang+ASan; gcc never
  caught it because the freed heap usually still holds the old value).
  Moved fsync before the free; reiserfs_flush() has already written
  journal and dirty buffers at that point and free_buffers() never
  writes, so the ordering preserves durability semantics.

- fsck/semantic_check.c, fsck/semantic_rebuild.c: three %K arguments passed
  &tmp_deh->deh2_dir_id where a struct reiserfs_key * is expected. It
  printed the right values only because deh2_dir_id sits at offset 4 and
  the key is read from the pointer as if dir_id sat at offset 0. Build a
  proper local key with set_key_dirid()/set_key_objectid() (the same
  idiom debugreiserfs/scan.c already uses). Verified -Waddress-of-packed-
  member (clang-only) is gone and output is unchanged.

- reiserfscore/hashes.c: four unreachable *(int *)0 = 0 stores (guarded by
  len >= 16/12/8/4 tests that cannot hold after the while (len >= 16)
  loop, len <= 15). Removed; clang's -Wnull-dereference goes quiet.
  Behavior verified: keyed_hash/yura_hash/r5_hash outputs for 16 inputs
  from 0 to 17 bytes are byte-identical before and after.

run_in_vm.sh: propagate CC into the guest, force a remount of /mnt/data
(the host rewrites the backing file under the guest), exclude generated
reiserfs_err.[ch] from the source tar. run_tests.sh: report which compiler
the battery actually used.
2026-11-12 08:51:29 -03:00
lgcosta 5a7382185b Add a libvirt/KVM test environment and fix the gcc-12 warning it found
build / build (clang, ) (push) Failing after 6s
build / build (gcc, ) (push) Failing after 6s
build / build (gcc, --enable-io-failure-emulation) (push) Failing after 6s
build / build (gcc, --enable-warnings) (push) Failing after 5s
The VM harness (tests/vm/) builds and exercises the tools on real Debian and
Alpine guests, driving the serial console (no sshd/cloud-init dependency).

Results on Debian 12 (glibc 2.36, gcc 12.2): 12/12 checks pass, 0 warnings
with -Wall -Wextra, including a real 128M -> 256M resize and the rollback
save/restore/reject paths.

Results on Alpine 3.20 (musl 1.2.5): the build cannot start. configure stops
at "reiserfsprogs requires a method to add printf modifiers" because
reiserfscore/prints.c depends on glibc's register_printf_specifier(3) and
<printf.h>, which musl does not provide. This is pre-existing and out of
scope here; measured at 341 use sites across 20+ files, all routed through
reiserfs_warning()/reiserfs_info(). Documented in tests/vm/RESULTS.md.

Fix the one real defect the harness surfaced:

fsck/semantic_check.c: check_check_regular_file() is called with NULL for
new_ih (line 466), so the block that would fill *new_ih is unreachable and
check_semantic_pass() never returns RELOCATED through that path. The
"case RELOCATED:" arm still reads relocated_ih.ih_key, which gcc 12.2
reports as "may be used uninitialized" (-Wmaybe-uninitialized); gcc 16 does
not, because it proves the path dead. Zero-initialise the struct and say why.

Verified: 0 warnings on gcc 12.2 after the change, and the Debian battery
stays at 12/12.
2026-11-12 00:11:31 -03:00
lgcosta 293e6a7280 Fix real bugs and clean up the build with -Wall -Wextra
build / build (clang, ) (push) Failing after 12s
build / build (gcc, ) (push) Failing after 9s
build / build (gcc, --enable-io-failure-emulation) (push) Failing after 8s
build / build (gcc, --enable-warnings) (push) Failing after 6s
Build: add --enable-warnings (-Wall -Wextra); the tree is now warning-free
with it, so distributions can opt in without risking a surprise -Werror
breakage from a future compiler.

Real bugs fixed (each verified by a reproducer):

- lib/io.c: open_rollback_file() read 28 bytes into char[28] with no NUL
  and then strcmp()'d it against a 28-character magic, reading one byte
  past the array. The condition was also inverted, so a *valid* rollback
  file was rejected -- but only sometimes: the missing NUL made the result
  depend on stack garbage (verified: -O0 rejects, -O2 accepts). The whole
  --save-rollback/--rollback-changes path was unreliable. Now the buffer is
  sized for the terminator, zeroed, and the comparison is `!= 0`.
  Verified end to end: save -> reopen -> restore reports "2 blocks
  restored, 0 skipped"; a random file is rejected.

- reiserfscore/reiserfslib.c, reiserfscore/journal.c: asprintf() was
  called with &fs->fs_file_name / &fs->fs_j_file_name, but those fields
  are `char *`, not `char **`. Passing a `char **` where `char *` is
  expected wrote through the wrong pointer -- silent memory corruption on
  any allocation. Fixed by using the new checked helper.

- reiserfscore/node_formats.c: `code < 0` on an unsigned parameter was
  dead code; the guard never fired.

- resize_reiserfs: missing `break` after -j made -j fall into -f, so
  "-j dev" silently also forced the operation. Sign-compare on the
  count_blocks() ternary and on count + blocks.

- lib/misc.c: strncat with bound == strlen(src) (equivalent to strcat) into
  char[256] from a char[256] dirent name -- up to 261 bytes. Replaced with
  snprintf plus an explicit fit check.

- lib/misc.c: die() used vsprintf into a fixed 1024-byte buffer.

- strncpy with bound == destination size (mkreiserfs, tune, progbar) never
  terminated; replaced with snprintf.

Allocator: drop the homegrown magic-header allocator. It wrote "_mem_begin_"
/ "mem_end" through strcpy inside the allocation, kept the size in an
`int`, and its only safety check (checkmem) was never called -- every call
site is commented out. Replaced with a size_t header that is over-aligned
via max_align_t, so malloc alignment guarantees still hold. expandmem()
now takes the old size from the header instead of a caller-supplied value
that could disagree with it.

Warnings: annotate the deliberate fallthroughs (fsck pass cascade, unit
suffix parsing, percentage parsing), fix the remaining sign-compare and
missing-field-initializer sites, and compute addresses of packed members
via char* + offsetof instead of &member.

Portability: asm/types.h -> linux/types.h, malloc.h and sys/vfs.h dropped
from includes.h (nothing used them), sys/vfs.h -> sys/statfs.h for
statfs(2).

Version: reiserfsprogs.spec said 3.6.23 while configure.ac said 3.6.25.

Remove the dead `#if 0` main() from hashes.c.

Add .github/workflows/build.yml: gcc, clang, --enable-warnings and
--enable-io-failure-emulation, each followed by a format/check/inspect
smoke test on a real image.

Verified: ./autogen.sh && ./configure --enable-warnings && make is clean
from scratch (0 warnings, 51 compile/link steps). mkreiserfs, reiserfsck
--check, debugreiserfs -S, reiserfstune -l and a real resize_reiserfs
128M -> 256M all succeed, and fsck reports the resized image clean.
2026-11-11 22:02:38 -03:00
lgcosta 41fb30313e README: document bootstrap/build steps
The generated autotools files are not tracked, so a fresh clone must run
autogen.sh before configure. State that and the build dependencies.
2026-11-11 21:30:11 -03:00
lgcosta d3925f1521 Modernize the build system so it builds on current toolchains
The autotools setup could not bootstrap with modern autoconf/libtool:
`autoreconf -fi` failed with "possibly undefined macro: AC_PROG_LIBTOOL",
and several other macros used here were removed or deprecated long ago.

configure.ac:
  - AC_PROG_LIBTOOL -> LT_INIT (with AC_CONFIG_MACRO_DIRS/AC_CONFIG_AUX_DIR);
    add AM_PROG_AR required by newer libtool/automake.
  - AM_CONFIG_HEADER -> AC_CONFIG_HEADERS; AC_OUTPUT(files...) -> AC_OUTPUT
    with an explicit AC_CONFIG_FILES list.
  - AC_TRY_COMPILE -> AC_COMPILE_IFELSE; drop AC_HEADER_STDC,
    AC_PROG_GCC_TRADITIONAL, AC_STRUCT_ST_RDEV, AC_C_CONST and AC_C_INLINE
    (all obsolete or unconditionally available).
  - Drop AC_FUNC_MEMCMP/STRFTIME/VPRINTF; the corresponding HAVE_* macros
    were never referenced. Keep the register_printf_* check but test the
    ac_cv_func_* names that AC_CHECK_FUNCS actually sets.
  - Pin -std=gnu11 (the sources predate C99 and rely on implicit-int-era
    behaviour that newer C standards reject) and fix the -Wuninitialized
    probe, which never set its cache variable.
  - off_t/blkcnt_t sizeof fallbacks 64 -> 8 (bytes, not bits).

reiserfscore.pc.in: substitute @PACKAGE_VERSION@; REISERFSPROGS_VERSION was
never defined, so the generated .pc always carried an empty Version.

lib/parse_time.c: define _GNU_SOURCE, not _XOPEN_SOURCE. The valueless
_XOPEN_SOURCE disables _DEFAULT_SOURCE, which hides loff_t in <sys/types.h>
and broke the build. Every other translation unit already uses _GNU_SOURCE.

reiserfscore/xattr.c: drop the unused <sys/acl.h> include; no libacl symbol
is used (the reiserfs_acl_* structs come from reiserfs_fs.h), and the header
is not a declared build dependency.

Add autogen.sh to regenerate the build system after a fresh clone, and
update .gitignore for the build-aux/m4 layout and generated artifacts.

Verified: ./autogen.sh && ./configure && make completes on gcc 16 /
automake 1.18 / autoconf 2.72. mkreiserfs, reiserfsck --check,
debugreiserfs -S and reiserfstune all run against a freshly formatted
64 MiB image.
2026-11-11 21:29:42 -03:00
Lucas C. Villa Real f97d2e9dd7 Fixes a NULL pointer dereference caused by reiserfsck. buffer_info_init_bh()
is called with a NULL "tb" argument, but the inline implementation of that
function was not prepared to handle it:

    Core was generated by `/Data/Compile/Sources/reiserfsprogs-3.6.25/fsck/.libs/lt-reiserfsck --fix-fixab'.
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0  0x00007fe0d63ef48d in buffer_info_init_bh (tb=0x0, bi=0x7fff03ad3630, bh=0xb60db0) at ../include/reiserfs_fs.h:1584
    1584        bi->bi_fs    = tb->tb_fs;
    (gdb) bt
    #0  0x00007fe0d63ef48d in buffer_info_init_bh (tb=0x0, bi=0x7fff03ad3630, bh=0xb60db0) at ../include/reiserfs_fs.h:1584
    #1  0x00007fe0d63f21f9 in delete_item (fs=0xb40710, bh=0xb60db0, item_num=0) at lbalance.c:1157
    #2  0x000000000040a3aa in pass0_correct_leaf (fs=0xb40710, bh=0xb60db0) at pass0.c:768
    #3  0x000000000040deab in do_pass_0 (fs=0xb40710) at pass0.c:1928
    #4  0x000000000040f74f in misc_set_bit (nr=4257615, addr=0x7fff03ad3770) at ../include/misc.h:94
    #5  0x0000000000406cb0 in rebuild_tree (fs=0xb40710) at main.c:941
    #6  0x00000000004088ba in misc_set_bit (nr=140733255074915, addr=0x42a630 <__libc_csu_init+64>) at ../include/misc.h:92
    #7  0x00007fe0d5e58291 in __libc_start_main (main=0x4081a4 <main+64>, argc=7, argv=0x7fff03ad38e8, init=<optimized out>, fini=<optimized out>,
        rtld_fini=<optimized out>, stack_end=0x7fff03ad38d8) at ../csu/libc-start.c:289
    #8  0x00000000004048ca in deregister_tm_clones ()
    #9  0x00007fff03ad38d8 in ?? ()
    #10 0x000000000000001c in ?? ()
    #11 0x0000000000000007 in ?? ()
    #12 0x00007fff03ad43ec in ?? ()
    #13 0x00007fff03ad4430 in ?? ()
    #14 0x00007fff03ad443e in ?? ()
    #15 0x00007fff03ad4446 in ?? ()
    #16 0x00007fff03ad444c in ?? ()
    #17 0x00007fff03ad4454 in ?? ()
    #18 0x00007fff03ad4463 in ?? ()
    #19 0x0000000000000000 in ?? ()
    (gdb) up
    #1  0x00007fe0d63f21f9 in delete_item (fs=0xb40710, bh=0xb60db0, item_num=0) at lbalance.c:1157
    1157        buffer_info_init_bh(NULL, &bi, bh);

Signed-off-by: Lucas C. Villa Real <lucasvr@gobolinux.org>
2017-01-09 15:43:26 -02:00
Jeff Mahoney 14b57362f7 build: libcom_err is required
configure is issuing a warning when libcom_err is missing but it should
fail instead.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2016-06-07 10:29:14 -04:00
Jeff Mahoney 278866b5be reiserfscore: add reiserfs_err.et to EXTRA_DIST
Without it, 'make dist' will not include it in the tarball.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2016-06-07 10:29:09 -04:00
Jeff Mahoney 1be2deaac0 Release 3.6.25. 2016-06-06 14:05:43 -04:00
Jeff Mahoney 3c0f2812b0 reiserfsprogs: use com_err in reiserfs_open
We dump failure messages to the terminal regardless of whether the caller
wants them or not.  This can be annoying when used as part of a general
tool that tests to see which file system is on a device by calling
its open routine.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2016-06-06 14:05:36 -04:00
Jeff Mahoney 59dc067e79 reiserfscore: fix "new_insert_key may be used uninitialized..."
new_insert_key only makes any sense when it's associated with a
new_insert_ptr, which is initialized to NULL and changed to a
buffer_head when we also initialize new_insert_key.  We can key off
of that to avoid the uninitialized warning.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2016-06-06 13:32:40 -04:00
Jeff Mahoney df843a34a6 reiserfsprogs: fix issues with inline functions
There are several cases in which inline functions are declared in
header files.  This causes warnings with newer versions of gcc.
This patch converts them to static inlines.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2016-06-06 13:32:05 -04:00
David Prévot d5571fa1db man: Fixes a little glitch in the man page.
From: Debian Bug #733764

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2016-06-06 12:47:44 -04:00
Jeff Mahoney 0407950dfe manpages: escape dashes
This patch is originally from the Debian package but no
authorship information was contained within it.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2016-06-06 12:46:16 -04:00
54 changed files with 1518 additions and 427 deletions

No files matched your search

+165
View File
@@ -0,0 +1,165 @@
name: build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- cc: gcc
extra: ""
- cc: gcc
extra: "--enable-warnings"
- cc: clang
extra: ""
# clang builds warning-free with -Wall -Wextra; keep this job as
# the regression gate for that guarantee.
- cc: clang
extra: "--enable-warnings"
- cc: gcc
extra: "--enable-io-failure-emulation"
env:
CC: ${{ matrix.cc }}
steps:
- uses: actions/checkout@v4
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
autoconf automake libtool pkg-config \
libcom-err-dev uuid-dev \
build-essential clang
- name: Bootstrap
run: ./autogen.sh
- name: Configure
run: ./configure ${{ matrix.extra }}
- name: Build
run: make -j"$(nproc)"
- name: Fail on any compiler warning
if: matrix.extra == '--enable-warnings'
run: |
make -j"$(nproc)" clean >/dev/null 2>&1 || true
make -j"$(nproc)" > build.log 2>&1 || { cat build.log; exit 1; }
if grep -q "warning:" build.log; then
grep "warning:" build.log
echo "build is not -Wall -Wextra clean"
exit 1
fi
- name: Smoke test
run: |
set -e
dd if=/dev/zero of=smoke.img bs=1M count=64 status=none
./mkreiserfs/mkreiserfs -f -q smoke.img
./fsck/reiserfsck --check -f -q -y smoke.img
./debugreiserfs/debugreiserfs -S smoke.img
out-of-tree:
# Parallel builds from a separate build directory; historically this
# tripped the compile_et target race, so keep it covered.
runs-on: ubuntu-latest
env:
CC: gcc
steps:
- uses: actions/checkout@v4
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
autoconf automake libtool pkg-config \
libcom-err-dev uuid-dev build-essential
- name: Bootstrap
run: ./autogen.sh
- name: Configure (out-of-tree)
run: |
mkdir -p "$RUNNER_TEMP/rfs-build"
cd "$RUNNER_TEMP/rfs-build"
"$GITHUB_WORKSPACE/configure" --enable-warnings
- name: Build
run: make -C "$RUNNER_TEMP/rfs-build" -j"$(nproc)"
- name: Smoke test
run: |
set -e
cd "$RUNNER_TEMP/rfs-build"
dd if=/dev/zero of=smoke.img bs=1M count=64 status=none
./mkreiserfs/mkreiserfs -f -q smoke.img
./fsck/reiserfsck --check -f -q -y smoke.img
sanitizers:
# clang + AddressSanitizer + UndefinedBehaviorSanitizer over the real
# tool paths (format, check, resize, rollback). Leak detection is off:
# the one-shot tools deliberately keep process-lifetime allocations.
runs-on: ubuntu-latest
env:
CC: clang
steps:
- uses: actions/checkout@v4
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
autoconf automake libtool pkg-config \
libcom-err-dev uuid-dev build-essential clang
- name: Bootstrap
run: ./autogen.sh
- name: Configure with sanitizers
run: >
./configure --enable-warnings
CFLAGS="-g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer"
- name: Build
run: make -j"$(nproc)"
- name: Exercise tools under sanitizers
env:
ASAN_OPTIONS: detect_leaks=0:halt_on_error=1
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
run: |
set -e
dd if=/dev/zero of=/tmp/s.img bs=1M count=64 status=none
./mkreiserfs/mkreiserfs -f -q -l SAN /tmp/s.img
./fsck/reiserfsck --check -f -q -y /tmp/s.img
./debugreiserfs/debugreiserfs -S /tmp/s.img
./tune/reiserfstune -l SAN2 -f /tmp/s.img
# resize: 64M -> 128M
dd if=/dev/zero of=/tmp/b.img bs=1M count=64 status=none
./mkreiserfs/mkreiserfs -f -q /tmp/b.img
truncate -s 128M /tmp/b.img
./resize_reiserfs/resize_reiserfs -s +64M -f /tmp/b.img
./fsck/reiserfsck --check -f -q -y /tmp/b.img
# rollback save + restore
cp /tmp/s.img /tmp/r.img
./fsck/reiserfsck --fix-fixable -y -q -R /tmp/rb.dat /tmp/r.img
./fsck/reiserfsck --rollback-fsck-changes -y -q -R /tmp/rb.dat /tmp/r.img
# rollback file with garbage magic must be rejected
head -c 100 /dev/urandom > /tmp/bad.dat
if ./fsck/reiserfsck --rollback-fsck-changes -y -q -R /tmp/bad.dat /tmp/r.img 2>&1 \
| grep -q "does not look like a rollback file"; then
echo "rollback garbage correctly rejected"
else
echo "rollback garbage was NOT rejected"
exit 1
fi
+31 -9
View File
@@ -1,32 +1,54 @@
# Editor / OS cruft
*~ *~
*.[ao] core
*.8 tags
# Autotools generated files (run ./autogen.sh to regenerate)
INSTALL INSTALL
Makefile.in Makefile.in
aclocal.m4 aclocal.m4
autom4te.cache/
compile
config.guess config.guess
config.sub config.sub
config.h.in
configure configure
depcomp depcomp
config.h.in
install-sh install-sh
missing missing
aclocal.m4 ltmain.sh
autom4te.cache ar-lib
tags /build-aux/
.pc /m4/
# configure / make output
Makefile Makefile
.deps .deps/
.libs/
*.o
*.a
*.lo
*.la
config.log config.log
config.status config.status
config.h
include/config.h include/config.h
include/credits.h include/credits.h
include/stamp-h1 include/stamp-h1
libtool
reiserfscore/reiserfs_err.c
reiserfscore/reiserfs_err.h
reiserfscore/reiserfscore.pc
reiserfsprogs-*.tar.* # Generated man pages (from *.8.in)
*.8
# Built programs
/debugreiserfs/debugreiserfs /debugreiserfs/debugreiserfs
/fsck/reiserfsck /fsck/reiserfsck
/mkreiserfs/mkreiserfs /mkreiserfs/mkreiserfs
/resize_reiserfs/resize_reiserfs /resize_reiserfs/resize_reiserfs
/tune/reiserfstune /tune/reiserfstune
# Release tarballs
reiserfsprogs-*.tar.*
+37
View File
@@ -1,3 +1,40 @@
2016-06-06
3.6.25 release.
reiserfsprogs: use com_err in reiserfs_open
reiserfscore: fix "new_insert_key may be used uninitialized..."
reiserfsprogs: fix issues with inline functions
man: Fixes a little glitch in the man page.
manpages: escape dashes
fsck: remove namesys.com reference in error text
reiserfscore: constify struct pointer arguments
reiserfscore: constify strings
reiserfslib: add basic extended attribute helpers
reiserfslib: add file data and directory iterators
mkreiserfs: move block_size_ok out of reiserfscore
debugreiserfs: fix incorrect memset size in unpack_stat_data
reiserfsprogs: remove dead code
debugreiserfs: fix use after free while closing log
reiserfsprogs: add helpers for constant endian routines
build: introduce shared libreiserfscore.so and export it
reiserfsprogs: convert reiserfs_filsys_t from structure to pointer-to-structure
reiserfsprogs: annotate for endian safeness
reiserfsprogs: fix remaining sparse warnings
reiserfsprogs: Fix sparse "warning: Using plain integer as NULL pointer"
sparse: move bitops functions to include/misc.h
reiserfscore: rename usearch_by_position to reiserfs_search_by_position
reiserfscore: make reiserfs_open's filename argument const
swab: protect le32_to_cpu and friends against being defined twice
reiserfs_fs.h: Eliminate overlays in offset_v2 helpers
reiserfscore: move endian helpers for offset_v2 into header
reiserfs_fs.h: Fix ifndef for multiple inclusion
cleanup: remove unused argument to reiserfs_invalidate_buffer
cleanup: remove dead code
cleanup: remove unnecessary fs pointer passed with buffer_infos
cleanup: factor out buffer_info initialization into helpers
cleanup: rename key and item_head accessors to more friendly names
cleanup: remove trailing whitespace
cleanup: run indent with the Linux Kernel style across all code
cleanup: rename common structure names
2013-08-25 2013-08-25
3.6.24 release. 3.6.24 release.
reiserfsprogs: autogenerate the version number in the man pages reiserfsprogs: autogenerate the version number in the man pages
+24
View File
@@ -53,3 +53,27 @@ the code and documentation are to avoid confusion by users, not to avoid
proper attribution. Reiserfsprogs has been maintained by the ReiserFS proper attribution. Reiserfsprogs has been maintained by the ReiserFS
development community for some time and can be reached at development community for some time and can be reached at
reiserfs-devel@vger.kernel.org. reiserfs-devel@vger.kernel.org.
[BUILDING]
The generated autotools files (configure, Makefile.in, ...) are not kept in
the repository. After a fresh clone, bootstrap them first:
./autogen.sh
./configure
make
Build dependencies: a C compiler, autoconf, automake, libtool, pkg-config,
libcom_err (com_err development files) and, optionally, libuuid.
Supported compilers: gcc and clang. Both build warning-free with
./configure --enable-warnings && make (i.e. -Wall -Wextra).
Out-of-tree (separate build directory) and parallel (-j) builds are
supported. Sanitizer builds are exercised in CI:
CC=clang ./configure --enable-warnings \
CFLAGS="-g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer"
Note: reiserfsprogs requires a libc with printf format extensions
(glibc's register_printf_specifier/register_printf_modifier). It does not
build against musl; see tests/vm/RESULTS.md. A libvirt/KVM test
environment for Debian and Alpine lives in tests/vm/.
Executable
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
# Regenerate the autotools build system (configure, Makefile.in, ...).
# Run this after a fresh clone; release tarballs ship the generated files.
set -e
srcdir=$(dirname "$0")
cd "$srcdir"
mkdir -p m4 build-aux
autoreconf -fi
echo
echo "Now run ./configure && make"
+74 -53
View File
@@ -1,18 +1,21 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_INIT([reiserfsprogs], [3.6.24], [reiserfs-devel@vger.kernel.org]) AC_INIT([reiserfsprogs], [3.6.25], [reiserfs-devel@vger.kernel.org])
AC_CANONICAL_HOST AC_CANONICAL_HOST
AC_PREREQ(2.50) AC_PREREQ([2.64])
AC_CONFIG_MACRO_DIRS([m4])
AC_CONFIG_AUX_DIR([build-aux])
AH_TEMPLATE([HAVE_LIBUUID], [Define for enable libuuid using.]) AH_TEMPLATE([HAVE_LIBUUID], [Define for enable libuuid using.])
AM_INIT_AUTOMAKE([1.11.1 dist-xz silent-rules]) AM_INIT_AUTOMAKE([1.11.1 foreign dist-xz silent-rules subdir-objects])
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
AM_MAINTAINER_MODE AM_MAINTAINER_MODE
dnl We install in /sbin, the utils are to be available on boot dnl We install in /sbin, the utils are to be available on boot
dnl AC_PREFIX(/) dnl AC_PREFIX(/)
AM_CONFIG_HEADER(include/config.h) AC_CONFIG_HEADERS([include/config.h])
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CC AC_PROG_CC
@@ -20,45 +23,57 @@ AC_PROG_AWK
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AC_PROG_LIBTOOL AM_PROG_AR
dnl libtool, replaces the long-obsolete AC_PROG_LIBTOOL
LT_INIT
dnl Checks for libraries. dnl Checks for libraries.
# Check for LIBUUID # Check for LIBUUID
AC_CHECK_LIB(uuid, uuid_generate, , AC_MSG_WARN(libuuid could not be found)) AC_CHECK_LIB([uuid], [uuid_generate], [], [AC_MSG_WARN([libuuid could not be found])])
UUID_LIBS="$LIBS" UUID_LIBS="$LIBS"
AC_SUBST(UUID_LIBS) AC_SUBST([UUID_LIBS])
AC_CHECK_LIB([com_err], [_et_list], [], [AC_MSG_ERROR([libcom_err could not be found])])
COM_ERR_LIBS="$LIBS"
AC_SUBST([COM_ERR_LIBS])
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h limits.h malloc.h sys/ioctl.h unistd.h uuid/uuid.h])
AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/ioctl.h unistd.h uuid/uuid.h)
AC_HEADER_MAJOR AC_HEADER_MAJOR
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_STRUCT_ST_RDEV
dnl Use a deterministic language level: the code predates C99 and C23
dnl removes constructs (e.g. implicit int in some spots) it relies on.
AC_MSG_CHECKING([whether $CC accepts -std=gnu11])
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -std=gnu11"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no]); CFLAGS="$saved_CFLAGS"])
# Checking for compiler warning options # Checking for compiler warning options
AC_CACHE_CHECK([whether -Wuninitialized works], [ac_cv_wuninitialized_flag], [ AC_CACHE_CHECK([whether -Wuninitialized works], [ac_cv_wuninitialized_flag], [
saved_CPPFLAGS="$CPPFLAGS" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
CPPFLAGS="-O1 -Wuninitialized" [ac_cv_wuninitialized_flag=yes], [ac_cv_wuninitialized_flag=no])
AC_TRY_COMPILE(, , [ac_cv_wuninitialized_flag=yes], [ac_cv_wuninitialized_flag=no])
CPPFLAGS="$saved_CPPFLAGS"
]) ])
AC_CACHE_CHECK([whether -Wno-unused-parameter works], [ac_cv_wno_unused_parameter_flag], [ AC_CACHE_CHECK([whether -Wno-unused-parameter works], [ac_cv_wno_unused_parameter_flag], [
saved_CPPFLAGS="$CPPFLAGS" saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="-Wno-unused-parameter" CPPFLAGS="$CPPFLAGS -Wno-unused-parameter"
AC_TRY_COMPILE(, , [ac_cv_wno_unused_parameter_flag=yes], [ac_cv_wno_unused_parameter_flag=no]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[ac_cv_wno_unused_parameter_flag=yes], [ac_cv_wno_unused_parameter_flag=no])
CPPFLAGS="$saved_CPPFLAGS" CPPFLAGS="$saved_CPPFLAGS"
]) ])
AC_CACHE_CHECK([whether -Wredundant-decls works], [ac_cv_wredundant_decls_flag], [ AC_CACHE_CHECK([whether -Wredundant-decls works], [ac_cv_wredundant_decls_flag], [
saved_CPPFLAGS="$CPPFLAGS" saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="-Wredundant-decls" CPPFLAGS="$CPPFLAGS -Wredundant-decls"
AC_TRY_COMPILE(, , [ac_cv_wredundant_decls_flag=yes], [ac_cv_wredundant_decls_flag=no]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[ac_cv_wredundant_decls_flag=yes], [ac_cv_wredundant_decls_flag=no])
CPPFLAGS="$saved_CPPFLAGS" CPPFLAGS="$saved_CPPFLAGS"
]) ])
@@ -66,48 +81,52 @@ AC_CACHE_CHECK([whether -Wredundant-decls works], [ac_cv_wredundant_decls_flag],
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
if test -z "${ac_cv_sys_file_offset_bits}"; then if test -z "${ac_cv_sys_file_offset_bits}"; then
AC_MSG_WARN(Can't detect right _FILE_OFFSET_BITS. Will be forced to 64bit.) AC_MSG_WARN([Can't detect right _FILE_OFFSET_BITS. Will be forced to 64bit.])
ac_cv_sys_file_offset_bits=64 ac_cv_sys_file_offset_bits=64
fi fi
AC_CHECK_SIZEOF(off_t, 64, [ AC_CHECK_SIZEOF([off_t], [8], [
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
]) ])
AC_CHECK_SIZEOF(blkcnt_t, 64, [ AC_CHECK_SIZEOF([blkcnt_t], [8], [
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
]) ])
dnl Checks for library functions. dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL AC_CHECK_FUNCS([strerror strstr strtol statfs getmntent hasmntopt memset time \
AC_FUNC_MEMCMP uname strptime ctime_r register_printf_modifier \
AC_FUNC_STRFTIME register_printf_specifier])
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror strstr strtol statfs getmntent hasmntopt memset time \
uname strptime ctime_r register_printf_modifier \
register_printf_specifier)
if test -z "${ac_cv_func_register_printf_function}" -a -z "${ac_cv_func_register_printf_specifier}"; then if test "x$ac_cv_func_register_printf_specifier" != xyes -a \
AC_MSG_ERROR(reiserfsprogs requires a method to add printf modifiers) "x$ac_cv_func_register_printf_modifier" != xyes; then
AC_MSG_ERROR([reiserfsprogs requires a method to add printf modifiers])
fi fi
dnl -Wall -Wextra is clean as of this release; keep it opt-in so that
dnl distributions building with -Werror are not surprised by a future
dnl compiler adding a new diagnostic.
AC_ARG_ENABLE([warnings],
[AS_HELP_STRING([--enable-warnings], [build with -Wall -Wextra])])
if test "$enable_warnings" = "yes" ; then
CFLAGS="$CFLAGS -Wall -Wextra"
fi
dnl Never enable this. It is for debugging only dnl Never enable this. It is for debugging only
AC_ARG_ENABLE(io-failure-emulation, AC_ARG_ENABLE([io-failure-emulation],
[AS_HELP_STRING([--enable-io-failure-emulation], [Never use this. It is for debugging only])]) [AS_HELP_STRING([--enable-io-failure-emulation], [Never use this. It is for debugging only])])
if test "$enable_io_failure_emulation" = "yes" ; then if test "$enable_io_failure_emulation" = "yes" ; then
AC_MSG_WARN([Careful! IO failure emulation is ON]) AC_MSG_WARN([Careful! IO failure emulation is ON])
AC_DEFINE(IO_FAILURE_EMULATION, 1, [gets set when configure --enable-io-failure-emulation]) AC_DEFINE([IO_FAILURE_EMULATION], [1], [gets set when configure --enable-io-failure-emulation])
fi fi
if test "x$ac_cv_wno_unused_parameter_flag" = xyes; then if test "x$ac_cv_wno_unused_parameter_flag" = xyes; then
CFLAGS="$CFLAGS -Wno-unused-parameter" CFLAGS="$CFLAGS -Wno-unused-parameter"
else
CFLAGS="$CFLAGS -Wno-unused"
fi fi
if test "x$ac_cv_wredundant_decls_flag" = xyes; then if test "x$ac_cv_wredundant_decls_flag" = xyes; then
@@ -120,23 +139,25 @@ fi
CPPFLAGS="-I\$(top_srcdir)/include $CPPFLAGS" CPPFLAGS="-I\$(top_srcdir)/include $CPPFLAGS"
AC_OUTPUT( AC_CONFIG_FILES([
include/Makefile Makefile
mkreiserfs/Makefile include/Makefile
mkreiserfs/mkreiserfs.8 lib/Makefile
resize_reiserfs/Makefile reiserfscore/Makefile
resize_reiserfs/resize_reiserfs.8 reiserfscore/reiserfscore.pc
fsck/Makefile fsck/Makefile
fsck/reiserfsck.8 fsck/reiserfsck.8
lib/Makefile mkreiserfs/Makefile
Makefile mkreiserfs/mkreiserfs.8
reiserfscore/Makefile debugreiserfs/Makefile
reiserfscore/reiserfscore.pc debugreiserfs/debugreiserfs.8
debugreiserfs/Makefile resize_reiserfs/Makefile
debugreiserfs/debugreiserfs.8 resize_reiserfs/resize_reiserfs.8
tune/Makefile tune/Makefile
tune/reiserfstune.8 tune/reiserfstune.8
) ])
AC_OUTPUT
AC_MSG_NOTICE([ AC_MSG_NOTICE([
+8 -8
View File
@@ -31,7 +31,7 @@ an IDE disk partition or /dev/sdXX for a SCSI disk partition).
.SH OPTIONS .SH OPTIONS
.TP .TP
\fB-j\fR \fIdevice\fR \fB-j\fR \fIdevice\fR
prints the contents of the journal. The option -p allows it to pack the journal prints the contents of the journal. The option \-p allows it to pack the journal
with other metadata into the archive. with other metadata into the archive.
.TP .TP
\fB-J\fR \fB-J\fR
@@ -61,22 +61,22 @@ prints the specified block of the filesystem.
.\" formatted nodes found. Can be used to find specific key in the filesystem. .\" formatted nodes found. Can be used to find specific key in the filesystem.
.\" .TP .\" .TP
.B -p .B -p
extracts the filesystem's metadata with \fBdebugreiserfs\fR -p /dev/xxx | gzip -c > extracts the filesystem's metadata with \fBdebugreiserfs\fR \-p /dev/xxx | gzip \-c >
xxx.gz. None of your data are packed unless a filesystem corruption presents when xxx.gz. None of your data are packed unless a filesystem corruption presents when
the whole block having this corruption is packed. You send us the output, and we use the whole block having this corruption is packed. You send us the output, and we use
it to create a filesystem with the same strucure as yours using \fBdebugreiserfs -u\fR. it to create a filesystem with the same strucure as yours using \fBdebugreiserfs \-u\fR.
When the data file is not too large, this usually allows us to quickly reproduce When the data file is not too large, this usually allows us to quickly reproduce
and debug the problem. and debug the problem.
.TP .TP
.B -u .B -u
builds the ReiserFS filesystem image with gunzip -c xxx.gz | \fBdebugreiserfs\fR builds the ReiserFS filesystem image with gunzip \-c xxx.gz | \fBdebugreiserfs\fR
-u /dev/image of the previously packed metadata with \fBdebugreiserfs -p\fR. The \-u /dev/image of the previously packed metadata with \fBdebugreiserfs \-p\fR. The
result image is not the same as the original filesystem, because mostly only metadata result image is not the same as the original filesystem, because mostly only metadata
were packed with \fBdebugreiserfs -p\fR, but the filesystem structure is completely were packed with \fBdebugreiserfs \-p\fR, but the filesystem structure is completely
recreated. recreated.
.TP .TP
.B -S .B -S
When -S is not specified -p When \-S is not specified \-p
.\" and -s .\" and -s
deals with blocks marked used in the filesystem bitmap only. With this option deals with blocks marked used in the filesystem bitmap only. With this option
set \fBdebugreiserfs\fR will work with the entire device. set \fBdebugreiserfs\fR will work with the entire device.
@@ -84,7 +84,7 @@ set \fBdebugreiserfs\fR will work with the entire device.
.B -q .B -q
When When
.\" -s or .\" -s or
-p is in use, suppress showing the speed of progress. \-p is in use, suppress showing the speed of progress.
.SH AUTHOR .SH AUTHOR
This version of \fBdebugreiserfs\fR has been written by Vitaly Fertman This version of \fBdebugreiserfs\fR has been written by Vitaly Fertman
<vitaly@namesys.com>. <vitaly@namesys.com>.
+8 -6
View File
@@ -4,6 +4,8 @@
*/ */
#include "debugreiserfs.h" #include "debugreiserfs.h"
#include "misc.h"
#include <com_err.h>
reiserfs_filsys_t fs; reiserfs_filsys_t fs;
@@ -263,13 +265,13 @@ static char *parse_options(struct debugreiserfs_data *data,
!= EOF) { != EOF) {
switch (c) { switch (c) {
case 'a': /* -r will read this, -n and -N will write to it */ case 'a': /* -r will read this, -n and -N will write to it */
asprintf(&data->map_file, "%s", optarg); xasprintf(&data->map_file, "%s", optarg);
break; break;
case 'b': case 'b':
/* will load bitmap from a file and read only blocks /* will load bitmap from a file and read only blocks
marked in it. This is for -p and -k */ marked in it. This is for -p and -k */
asprintf(&data->input_bitmap, "%s", optarg); xasprintf(&data->input_bitmap, "%s", optarg);
data->scan_area = EXTERN_BITMAP; data->scan_area = EXTERN_BITMAP;
break; break;
@@ -337,7 +339,7 @@ static char *parse_options(struct debugreiserfs_data *data,
break; break;
case 'r': case 'r':
asprintf(&data->recovery_file, "%s", optarg); xasprintf(&data->recovery_file, "%s", optarg);
data->mode = DO_RECOVER; data->mode = DO_RECOVER;
break; break;
@@ -378,7 +380,7 @@ static char *parse_options(struct debugreiserfs_data *data,
break; break;
case 'B': /*disabled for a while */ case 'B': /*disabled for a while */
asprintf(&badblocks_file, "%s", optarg); xasprintf(&badblocks_file, "%s", optarg);
data->mode = DO_EXTRACT_BADBLOCKS; data->mode = DO_EXTRACT_BADBLOCKS;
break; break;
case 'q': case 'q':
@@ -683,7 +685,7 @@ static void debugreiserfs_zero_reiserfs(reiserfs_filsys_t fs)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *file_name; char *file_name;
int error; long error;
struct debugreiserfs_data *data; struct debugreiserfs_data *data;
FILE *log; FILE *log;
@@ -701,7 +703,7 @@ int main(int argc, char *argv[])
if (no_reiserfs_found(fs)) { if (no_reiserfs_found(fs)) {
reiserfs_exit(1, "\n\ndebugreiserfs: can not open reiserfs on " reiserfs_exit(1, "\n\ndebugreiserfs: can not open reiserfs on "
"\"%s\": %s\n\n", file_name, "\"%s\": %s\n\n", file_name,
error ? strerror(error) error ? error_message(error)
: "no filesystem found"); : "no filesystem found");
exit(1); exit(1);
} }
+29 -7
View File
@@ -106,13 +106,35 @@ struct packed_item {
__u32 type_2_mask_18_len_12; __u32 type_2_mask_18_len_12;
}; };
/* defined as inlines in both pack.c and unpack.c */ static inline void set_pi_type(struct packed_item *pi, __u32 val)
inline void set_pi_type(struct packed_item *pi, __u32 val); {
inline __u32 get_pi_type(const struct packed_item *pi); set_bit_field_XX(32, pi, val, 0, 2);
inline void set_pi_mask(struct packed_item *pi, __u32 val); }
inline __u32 get_pi_mask(const struct packed_item *pi);
inline void set_pi_item_len(struct packed_item *pi, __u32 val); static inline __u32 get_pi_type(const struct packed_item *pi)
inline __u32 get_pi_item_len(const struct packed_item *pi); {
get_bit_field_XX(32, pi, 0, 2);
}
static inline void set_pi_mask(struct packed_item *pi, __u32 val)
{
set_bit_field_XX(32, pi, val, 2, 18);
}
static inline __u32 get_pi_mask(const struct packed_item *pi)
{
get_bit_field_XX(32, pi, 2, 18);
}
static inline void set_pi_item_len(struct packed_item *pi, __u32 val)
{
set_bit_field_XX(32, pi, val, 20, 12);
}
static inline __u32 get_pi_item_len(const struct packed_item *pi)
{
get_bit_field_XX(32, pi, 20, 12);
}
#define HAS_DIR_ID 0x01 #define HAS_DIR_ID 0x01
#define HAS_GEN_COUNTER 0x02 #define HAS_GEN_COUNTER 0x02
-30
View File
@@ -16,36 +16,6 @@ reiserfs_bitmap_t *what_to_pack;
unsigned long sent_bytes; /* how many bytes sent to stdout */ unsigned long sent_bytes; /* how many bytes sent to stdout */
unsigned long had_to_be_sent; /* how many bytes were to be sent */ unsigned long had_to_be_sent; /* how many bytes were to be sent */
inline void set_pi_type(struct packed_item *pi, __u32 val)
{
set_bit_field_XX(32, pi, val, 0, 2);
}
inline __u32 get_pi_type(const struct packed_item *pi)
{
get_bit_field_XX(32, pi, 0, 2);
}
inline void set_pi_mask(struct packed_item *pi, __u32 val)
{
set_bit_field_XX(32, pi, val, 2, 18);
}
__u32 get_pi_mask(const struct packed_item *pi)
{
get_bit_field_XX(32, pi, 2, 18);
}
inline void set_pi_item_len(struct packed_item *pi, __u32 val)
{
set_bit_field_XX(32, pi, val, 20, 12);
}
inline __u32 get_pi_item_len(const struct packed_item *pi)
{
get_bit_field_XX(32, pi, 20, 12);
}
static void pack_ih(struct packed_item *pi, struct item_head *ih) static void pack_ih(struct packed_item *pi, struct item_head *ih)
{ {
__u32 v32; __u32 v32;
+5 -4
View File
@@ -4,6 +4,7 @@
*/ */
#include "debugreiserfs.h" #include "debugreiserfs.h"
#include "misc.h"
#include <regex.h> #include <regex.h>
#include <obstack.h> #include <obstack.h>
#include <search.h> #include <search.h>
@@ -253,7 +254,7 @@ static struct saved_name *scan_for_key(const struct reiserfs_key *key)
char *name; char *name;
struct saved_name *new, *name_in; struct saved_name *new, *name_in;
asprintf(&name, "%u_%u", get_key_dirid(key), get_key_objectid(key)); xasprintf(&name, "%u_%u", get_key_dirid(key), get_key_objectid(key));
new = new =
obstack_alloc(&name_store, obstack_alloc(&name_store,
sizeof(struct saved_name) + strlen(name)); sizeof(struct saved_name) + strlen(name));
@@ -591,7 +592,7 @@ static void flush_map(reiserfs_filsys_t fs,
__u32 v32; __u32 v32;
if (!map_file(fs)) if (!map_file(fs))
asprintf(&map_file(fs), "%s", ".map"); xasprintf(&map_file(fs), "%s", ".map");
//reiserfs_warning (stderr, "Saving maps into %s\n", map_file (fs)); //reiserfs_warning (stderr, "Saving maps into %s\n", map_file (fs));
fp = fopen(map_file(fs), "a"); fp = fopen(map_file(fs), "a");
@@ -814,7 +815,7 @@ static void make_map(const void *nodep, VISIT value, int level)
if (value == leaf || value == postorder) { if (value == leaf || value == postorder) {
while (name) { while (name) {
if (map_file(fs)) { if (map_file(fs)) {
asprintf(&file_name, "%s.%d", map_file(fs), xasprintf(&file_name, "%s.%d", map_file(fs),
++nr); ++nr);
reiserfs_warning(log_to, reiserfs_warning(log_to,
"%d - (%d): [%K]:\"%s\": stored in the %s\n", "%d - (%d): [%K]:\"%s\": stored in the %s\n",
@@ -1006,7 +1007,7 @@ void do_scan(reiserfs_filsys_t fs)
int type; int type;
char *answer = 0; char *answer = 0;
size_t n = 0; size_t n = 0;
struct reiserfs_key key = { 0, 0, }; struct reiserfs_key key = { 0 };
unsigned long done, total; unsigned long done, total;
if (debug_mode(fs) == DO_LOOK_FOR_NAME) { if (debug_mode(fs) == DO_LOOK_FOR_NAME) {
+2
View File
@@ -514,11 +514,13 @@ void unpack_partition(int fd, int jfd)
case '1': case '1':
fread(c, 1, 1, stdin); /* that was 100%, read in first 0 */ fread(c, 1, 1, stdin); /* that was 100%, read in first 0 */
/* fall through */
case '2': case '2':
case '4': case '4':
case '6': case '6':
case '8': case '8':
fread(c, 1, 1, stdin); fread(c, 1, 1, stdin);
/* fall through */
case '0': case '0':
fread(c + 1, 1, 1, stdin); /* read % */ fread(c + 1, 1, 1, stdin); /* read % */
+1 -1
View File
@@ -387,7 +387,7 @@ static int bad_direct_item(reiserfs_filsys_t fs,
return 0; return 0;
} }
inline void handle_one_pointer(reiserfs_filsys_t fs, static inline void handle_one_pointer(reiserfs_filsys_t fs,
struct buffer_head *bh, __le32 * item, struct buffer_head *bh, __le32 * item,
int offset) int offset)
{ {
+12 -12
View File
@@ -52,18 +52,18 @@ int main(int argc, char *argv[]);
* options * options
*/ */
#define OPT_INTERACTIVE 1 << 0 #define OPT_INTERACTIVE 1U << 0
#define OPT_ADJUST_FILE_SIZE 1 << 1 /* not default yet */ #define OPT_ADJUST_FILE_SIZE 1U << 1 /* not default yet */
#define OPT_QUIET 1 << 2 /* no "speed" info */ #define OPT_QUIET 1U << 2 /* no "speed" info */
#define OPT_SILENT 1 << 3 /* no complains about found corruptions */ #define OPT_SILENT 1U << 3 /* no complains about found corruptions */
#define OPT_BACKGROUND 1 << 4 #define OPT_BACKGROUND 1U << 4
#define OPT_SKIP_JOURNAL 1 << 5 #define OPT_SKIP_JOURNAL 1U << 5
#define OPT_HASH_DEFINED 1 << 6 #define OPT_HASH_DEFINED 1U << 6
#define OPT_SAVE_PASSES_DUMP 1 << 7 #define OPT_SAVE_PASSES_DUMP 1U << 7
#define OPT_SAVE_ROLLBACK 1 << 8 #define OPT_SAVE_ROLLBACK 1U << 8
#define OPT_YES 1 << 9 #define OPT_YES 1U << 9
#define BADBLOCKS_FILE 1 << 10 #define BADBLOCKS_FILE 1U << 10
#define OPT_FORCE 1 << 11 #define OPT_FORCE 1U << 11
/* pass0.c */ /* pass0.c */
extern reiserfs_bitmap_t *leaves_bitmap; extern reiserfs_bitmap_t *leaves_bitmap;
+2 -1
View File
@@ -4,6 +4,7 @@
*/ */
#include "fsck.h" #include "fsck.h"
#include "misc.h"
void erase_name(int len); void erase_name(int len);
void print_name(char *name, int len); void print_name(char *name, int len);
@@ -180,7 +181,7 @@ static __u64 _look_for_lost(reiserfs_filsys_t fs, int link_lost_dirs)
(&ih->ih_key)); (&ih->ih_key));
} }
asprintf(&lost_name, "%u_%u", xasprintf(&lost_name, "%u_%u",
get_key_dirid(&tmp_ih.ih_key), get_key_dirid(&tmp_ih.ih_key),
get_key_objectid(&tmp_ih.ih_key)); get_key_objectid(&tmp_ih.ih_key));
+24 -15
View File
@@ -4,6 +4,7 @@
*/ */
#include "fsck.h" #include "fsck.h"
#include "misc.h"
#include <getopt.h> #include <getopt.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/mman.h> #include <sys/mman.h>
@@ -198,7 +199,7 @@ static char *parse_options(struct fsck_data *data, int argc, char *argv[])
break; break;
#endif #endif
case 'd': /* --create-passes-dump */ case 'd': /* --create-passes-dump */
asprintf(&data->rebuild.passes_dump_file_name, "%s", xasprintf(&data->rebuild.passes_dump_file_name, "%s",
optarg); optarg);
data->options |= OPT_SAVE_PASSES_DUMP; data->options |= OPT_SAVE_PASSES_DUMP;
break; break;
@@ -208,7 +209,7 @@ static char *parse_options(struct fsck_data *data, int argc, char *argv[])
break; break;
case 'h': /* --hash: suppose that this hash was used on a filesystem */ case 'h': /* --hash: suppose that this hash was used on a filesystem */
asprintf(&data->rebuild.defined_hash, "%s", optarg); xasprintf(&data->rebuild.defined_hash, "%s", optarg);
if (name2func(data->rebuild.defined_hash) == NULL) if (name2func(data->rebuild.defined_hash) == NULL)
reiserfs_panic reiserfs_panic
("reiserfsck: Unknown hash is specified: %s", ("reiserfsck: Unknown hash is specified: %s",
@@ -221,12 +222,12 @@ static char *parse_options(struct fsck_data *data, int argc, char *argv[])
break; break;
case 'R': /* preparing rollback data */ case 'R': /* preparing rollback data */
asprintf(&data->rebuild.rollback_file, "%s", optarg); xasprintf(&data->rebuild.rollback_file, "%s", optarg);
data->options |= OPT_SAVE_ROLLBACK; data->options |= OPT_SAVE_ROLLBACK;
break; break;
case 'B': /* list of phisically corrupted blocks */ case 'B': /* list of phisically corrupted blocks */
asprintf(&badblocks_file, "%s", optarg); xasprintf(&badblocks_file, "%s", optarg);
data->options |= BADBLOCKS_FILE; data->options |= BADBLOCKS_FILE;
break; break;
@@ -916,25 +917,29 @@ static void rebuild_tree(reiserfs_filsys_t fs)
"reiserfsck --rebuild-tree started at %s" "reiserfsck --rebuild-tree started at %s"
"###########\n", ctime(&t)); "###########\n", ctime(&t));
/* Deliberate cascade: each pass falls into the next so that a rebuild
always runs every stage from the requested starting point on. */
switch (where_to_start_from(fs)) { switch (where_to_start_from(fs)) {
case START_FROM_THE_BEGINNING: case START_FROM_THE_BEGINNING:
reset_super_block(fs); reset_super_block(fs);
pass_0(fs); pass_0(fs);
/* fall through */
case START_FROM_PASS_1: case START_FROM_PASS_1:
reset_super_block(fs); reset_super_block(fs);
pass_1(fs); pass_1(fs);
/* fall through */
case START_FROM_PASS_2: case START_FROM_PASS_2:
pass_2(fs); pass_2(fs);
/* fall through */
case START_FROM_SEMANTIC: case START_FROM_SEMANTIC:
pass_3_semantic(fs); pass_3_semantic(fs);
/* fall through */
/* if --lost+found is set - link unaccessed directories to lost+found /* if --lost+found is set - link unaccessed directories to lost+found
directory */ directory */
case START_FROM_LOST_FOUND: case START_FROM_LOST_FOUND:
pass_3a_look_for_lost(fs); pass_3a_look_for_lost(fs);
/* fall through */
case START_FROM_PASS_4: case START_FROM_PASS_4:
/* 4. look for unaccessed items in the leaves */ /* 4. look for unaccessed items in the leaves */
@@ -1267,7 +1272,7 @@ static int open_devices_for_rollback(char *file_name, struct fsck_data *data)
fs = getmem(sizeof(*fs)); fs = getmem(sizeof(*fs));
fs->fs_dev = fd; fs->fs_dev = fd;
fs->fs_vp = data; fs->fs_vp = data;
asprintf(&fs->fs_file_name, "%s", file_name); xasprintf(&fs->fs_file_name, "%s", file_name);
if (data->journal_dev_name && strcmp(data->journal_dev_name, file_name)) { if (data->journal_dev_name && strcmp(data->journal_dev_name, file_name)) {
fs->fs_journal_dev = open(data->journal_dev_name, fs->fs_journal_dev = open(data->journal_dev_name,
@@ -1298,16 +1303,19 @@ static void fsck_rollback(reiserfs_filsys_t fs)
fsck_progress_file(fs)); fsck_progress_file(fs));
close_rollback_file(); close_rollback_file();
/* print the closing banner while fs is still valid: freemem(fs)
below releases it. Same order as the_end() and the rebuild
paths (ASan caught the opposite order here). */
time(&t);
fsck_progress("###########\n"
"reiserfsck finished at %s" "###########\n", ctime(&t));
close(fs->fs_journal_dev); close(fs->fs_journal_dev);
free(fs->fs_file_name); free(fs->fs_file_name);
fs->fs_file_name = NULL; fs->fs_file_name = NULL;
close(fs->fs_dev); close(fs->fs_dev);
freemem(fs); freemem(fs);
time(&t);
fsck_progress("###########\n"
"reiserfsck finished at %s" "###########\n", ctime(&t));
exit(EXIT_FIXED); exit(EXIT_FIXED);
} }
@@ -1318,7 +1326,7 @@ int main(int argc, char *argv[])
struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY }; struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
char *width; char *width;
int retval; int retval;
int error; long error;
width = getenv("COLUMNS"); width = getenv("COLUMNS");
if (width) if (width)
@@ -1391,7 +1399,7 @@ int main(int argc, char *argv[])
if (error) { if (error) {
reiserfs_exit(EXIT_OPER, "Failed to open the device " reiserfs_exit(EXIT_OPER, "Failed to open the device "
"'%s': %s\n\n", file_name, "'%s': %s\n\n", file_name,
strerror(error)); error_message(error));
} }
if (data->mode != FSCK_SB) { if (data->mode != FSCK_SB) {
@@ -1454,7 +1462,8 @@ int main(int argc, char *argv[])
if (auto_check(fs)) if (auto_check(fs))
break; break;
data->mode = FSCK_FIX_FIXABLE; data->mode = FSCK_FIX_FIXABLE;
case FSCK_CHECK: /* fall through */
case FSCK_CHECK: /* and FSCK_FIX_FIXABLE */
case FSCK_FIX_FIXABLE: case FSCK_FIX_FIXABLE:
check_fs(fs); check_fs(fs);
break; break;
+3 -5
View File
@@ -4,6 +4,7 @@
*/ */
#include "fsck.h" #include "fsck.h"
#include "misc.h"
/* on pass2 we take leaves which could not be inserted into tree /* on pass2 we take leaves which could not be inserted into tree
during pass1 and insert each item separately. It is possible that during pass1 and insert each item separately. It is possible that
@@ -74,7 +75,7 @@ static __u64 link_one(struct relocated *file)
struct reiserfs_key obj_key; struct reiserfs_key obj_key;
__u64 len = 0; __u64 len = 0;
asprintf(&name, "%lu,%lu", file->old_dir_id, file->new_objectid); xasprintf(&name, "%lu,%lu", file->old_dir_id, file->new_objectid);
set_key_dirid(&obj_key, file->old_dir_id); set_key_dirid(&obj_key, file->old_dir_id);
set_key_objectid(&obj_key, file->new_objectid); set_key_objectid(&obj_key, file->new_objectid);
@@ -118,15 +119,12 @@ void linked_already(const struct reiserfs_key *new_key /*, link_func_t link_func
void link_relocated_files(void) void link_relocated_files(void)
{ {
struct relocated *tmp; struct relocated *tmp;
int count;
count = 0;
while (relocated_list) { while (relocated_list) {
link_one(relocated_list); link_one(relocated_list);
tmp = relocated_list; tmp = relocated_list;
relocated_list = relocated_list->next; relocated_list = relocated_list->next;
freemem(tmp); freemem(tmp);
count++;
} }
} }
@@ -369,7 +367,7 @@ static void put_directory_item_into_tree(struct item_head *comingih, char *item)
" badly hashed entry", i, namelen, name, " badly hashed entry", i, namelen, name,
&comingih->ih_key); &comingih->ih_key);
asprintf(&buf, "%.*s", namelen, name); xasprintf(&buf, "%.*s", namelen, name);
/* 1 for fsck is important: if there is no any items of this /* 1 for fsck is important: if there is no any items of this
directory in the tree yet - new item will be inserted directory in the tree yet - new item will be inserted
marked not reached */ marked not reached */
+20 -19
View File
@@ -59,10 +59,10 @@ for directories, and deleting invalid directory entries.
.B --rebuild-tree .B --rebuild-tree
This option rebuilds the entire filesystem tree using leaf nodes This option rebuilds the entire filesystem tree using leaf nodes
found on the device. Normally you only need this option if the found on the device. Normally you only need this option if the
\fBreiserfsck --check\fR reports "Running with \fB--rebuild-tree\fR \fBreiserfsck \-\-check\fR reports "Running with \fB\-\-rebuild-tree\fR
is required". You are strongly encouraged to make a backup copy is required". You are strongly encouraged to make a backup copy
of the whole partition before attempting the \fB--rebuild-tree\fR of the whole partition before attempting the \fB--rebuild-tree\fR
option. Once \fBreiserfsck --rebuild-tree\fR is started it must option. Once \fBreiserfsck \-\-rebuild-tree\fR is started it must
finish its work (and you should not interrupt it), otherwise the finish its work (and you should not interrupt it), otherwise the
filesystem will be left in the unmountable state to avoid subsequent filesystem will be left in the unmountable state to avoid subsequent
data corruptions. data corruptions.
@@ -95,7 +95,7 @@ byte are corrected by \fB--fix-fixable\fR.
This option sets the badblock list to be the list of blocks specified in This option sets the badblock list to be the list of blocks specified in
the given `file`. The filesystem badblock list is cleared before the new the given `file`. The filesystem badblock list is cleared before the new
list is added. It can be used with \fB--fix-fixable\fR to fix the list of list is added. It can be used with \fB--fix-fixable\fR to fix the list of
badblocks (see \fBdebugreiserfs -B\fR). If the device has bad blocks, every badblocks (see \fBdebugreiserfs \-B\fR). If the device has bad blocks, every
time it must be given with the \fB--rebuild-tree\fR option. time it must be given with the \fB--rebuild-tree\fR option.
.TP .TP
\fB--logfile \fIfile\fR, \fB-l \fI file\fR \fB--logfile \fIfile\fR, \fB-l \fI file\fR
@@ -114,7 +114,7 @@ telling you what it is going to do. It will assuem you confirm. For safety,
it does not work with the \fB--rebuild-tree\fR option. it does not work with the \fB--rebuild-tree\fR option.
.TP .TP
\fB-a\fR, \fB-p\fR \fB-a\fR, \fB-p\fR
These options are usually passed by fsck -A during the automatic checking These options are usually passed by fsck \-A during the automatic checking
of those partitions listed in /etc/fstab. These options cause \fBreiserfsck\fR of those partitions listed in /etc/fstab. These options cause \fBreiserfsck\fR
to print some information about the specified filesystem, to check if error to print some information about the specified filesystem, to check if error
flags in the superblock are set and to do some light-weight checks. If these flags in the superblock are set and to do some light-weight checks. If these
@@ -129,7 +129,8 @@ Force checking even if the file system seems clean.
.B -V .B -V
This option prints the reiserfsprogs version and then exit. This option prints the reiserfsprogs version and then exit.
.TP .TP
\fB-r\fR This option does nothing at all; it is provided only for .B -r
This option does nothing at all; it is provided only for
backwards compatibility. backwards compatibility.
.SH EXPERT OPTIONS .SH EXPERT OPTIONS
DO NOT USE THESE OPTIONS UNLESS YOU KNOW WHAT YOU ARE DOING. DO NOT USE THESE OPTIONS UNLESS YOU KNOW WHAT YOU ARE DOING.
@@ -149,23 +150,23 @@ the used space on the partition.
1. You think something may be wrong with a reiserfs partition on /dev/hda1 1. You think something may be wrong with a reiserfs partition on /dev/hda1
or you would just like to perform a periodic disk check. or you would just like to perform a periodic disk check.
2. Run \fBreiserfsck --check --logfile check.log /dev/hda1\fR. If \fBreiserfsck 2. Run \fBreiserfsck \-\-check \-\-logfile check.log /dev/hda1\fR. If \fBreiserfsck
--check\fR exits with status 0 it means no errors were discovered. \-\-check\fR exits with status 0 it means no errors were discovered.
3. If \fBreiserfsck --check\fR exits with status 1 (and reports about fixable 3. If \fBreiserfsck \-\-check\fR exits with status 1 (and reports about fixable
corruptions) it means that you should run \fBreiserfsck --fix-fixable --logfile corruptions) it means that you should run \fBreiserfsck \-\-fix-fixable \-\-logfile
fixable.log /dev/hda1\fR. fixable.log /dev/hda1\fR.
4. If \fBreiserfsck --check\fR exits with status 2 (and reports about fatal 4. If \fBreiserfsck \-\-check\fR exits with status 2 (and reports about fatal
corruptions) it means that you need to run \fBreiserfsck --rebuild-tree\fR. corruptions) it means that you need to run \fBreiserfsck \-\-rebuild\-tree\fR.
If \fBreiserfsck --check\fR fails in some way you should also run \fBreiserfsck If \fBreiserfsck \-\-check\fR fails in some way you should also run \fBreiserfsck
--rebuild-tree\fR, but we also encourage you to submit this as a bug report. \-\-rebuild-tree\fR, but we also encourage you to submit this as a bug report.
5. Before running \fBreiserfsck --rebuild-tree\fR, please make a backup of 5. Before running \fBreiserfsck \-\-rebuild-tree\fR, please make a backup of
the whole partition before proceeding. Then run \fBreiserfsck --rebuild-tree the whole partition before proceeding. Then run \fBreiserfsck \-\-rebuild-tree
--logfile rebuild.log /dev/hda1\fR. \-\-logfile rebuild.log /dev/hda1\fR.
6. If the \fBreiserfsck --rebuild-tree\fR step fails or does not recover what 6. If the \fBreiserfsck \-\-rebuild-tree\fR step fails or does not recover what
you expected, please submit this as a bug report. Try to provide as much you expected, please submit this as a bug report. Try to provide as much
information as possible including your platform and Linux kernel version. We information as possible including your platform and Linux kernel version. We
will try to help solve the problem. will try to help solve the problem.
@@ -180,11 +181,11 @@ will try to help solve the problem.
.br .br
\ \fI4\fR \-\ File system fatal errors left uncorrected, \ \fI4\fR \-\ File system fatal errors left uncorrected,
.br .br
\ \fBreiserfsck --rebuild-tree\fR needs to be launched. \ \fBreiserfsck \-\-rebuild-tree\fR needs to be launched.
.br .br
\ \fI6\fR \-\ File system fixable errors left uncorrected, \ \fI6\fR \-\ File system fixable errors left uncorrected,
.br .br
\ \fBreiserfsck --fix-fixable\fR needs to be launched. \ \fBreiserfsck \-\-fix-fixable\fR needs to be launched.
.br .br
\ \fI8\fR \-\ Operational error. \ \fI8\fR \-\ Operational error.
.br .br
+24 -9
View File
@@ -3,6 +3,7 @@
*/ */
#include "fsck.h" #include "fsck.h"
#include "misc.h"
static struct reiserfs_key *trunc_links = NULL; static struct reiserfs_key *trunc_links = NULL;
static __u32 links_num = 0; static __u32 links_num = 0;
@@ -366,7 +367,7 @@ start_again:
memcpy(dir_item, ih_item_body(bh, ih), get_ih_item_len(ih)); memcpy(dir_item, ih_item_body(bh, ih), get_ih_item_len(ih));
/* next item key */ /* next item key */
if (PATH_LAST_POSITION(&path) == (B_NR_ITEMS(bh) - 1) && if (PATH_LAST_POSITION(&path) + 1 == B_NR_ITEMS(bh) &&
(rdkey = uget_rkey(&path))) (rdkey = uget_rkey(&path)))
copy_key(key, rdkey); copy_key(key, rdkey);
else { else {
@@ -550,7 +551,10 @@ static int check_semantic_pass(struct reiserfs_key *key,
for (i = pos_in_item; i < get_ih_entry_count(&tmp_ih); for (i = pos_in_item; i < get_ih_entry_count(&tmp_ih);
i++, deh++) { i++, deh++) {
struct item_head relocated_ih; /* Only meaningful when check_check_regular_file() returns
RELOCATED; that path currently passes NULL for new_ih,
so this stays zero-initialised. */
struct item_head relocated_ih = { 0 };
int ret = OK; int ret = OK;
if (name) { if (name) {
@@ -559,7 +563,7 @@ static int check_semantic_pass(struct reiserfs_key *key,
} }
namelen = name_in_entry_length(&tmp_ih, deh, i); namelen = name_in_entry_length(&tmp_ih, deh, i);
asprintf(&name, "%.*s", namelen, name_in_entry(deh, i)); xasprintf(&name, "%.*s", namelen, name_in_entry(deh, i));
entry_len = entry_length(&tmp_ih, deh, i); entry_len = entry_length(&tmp_ih, deh, i);
get_object_key(deh, &object_key, &entry_key, &tmp_ih); get_object_key(deh, &object_key, &entry_key, &tmp_ih);
@@ -634,6 +638,7 @@ static int check_semantic_pass(struct reiserfs_key *key,
("check_semantic_pass: Name \"%.*s\" in directory %K points to " ("check_semantic_pass: Name \"%.*s\" in directory %K points to "
"nowhere\n", namelen, name, "nowhere\n", namelen, name,
&tmp_ih.ih_key); &tmp_ih.ih_key);
/* fall through */
case LOOP_FOUND: case LOOP_FOUND:
if (fsck_mode(fs) == FSCK_FIX_FIXABLE) { if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
reiserfs_remove_entry(fs, &entry_key); reiserfs_remove_entry(fs, &entry_key);
@@ -671,16 +676,27 @@ static int check_semantic_pass(struct reiserfs_key *key,
} else { } else {
/* update key dir entry points to */ /* update key dir entry points to */
struct reiserfs_de_head *tmp_deh; struct reiserfs_de_head *tmp_deh;
struct reiserfs_key deh_key;
tmp_deh = tmp_deh =
B_I_DEH(get_bh(&path), B_I_DEH(get_bh(&path),
tp_item_head(&path)) + tp_item_head(&path)) +
path.pos_in_item; path.pos_in_item;
/* Build a proper key from the entry's
dirid/objectid. Passing
&tmp_deh->deh2_dir_id as a
reiserfs_key * only worked by
offset coincidence and trips
-Waddress-of-packed-member. */
set_key_dirid(&deh_key,
get_deh_dirid(tmp_deh));
set_key_objectid(&deh_key,
get_deh_objectid(tmp_deh));
fsck_log fsck_log
("The directory %K pointing to %K (\"%.*s\") updated to point " ("The directory %K pointing to %K (\"%.*s\") updated to point "
"to ", &tmp_ih.ih_key, "to ", &tmp_ih.ih_key, &deh_key,
&tmp_deh->deh2_dir_id, namelen, namelen, name);
name);
set_deh_dirid(tmp_deh, set_deh_dirid(tmp_deh,
get_key_dirid get_key_dirid
(&relocated_ih.ih_key)); (&relocated_ih.ih_key));
@@ -689,9 +705,8 @@ static int check_semantic_pass(struct reiserfs_key *key,
(&relocated_ih. (&relocated_ih.
ih_key)); ih_key));
fsck_log("%K (\"%.*s\")\n", fsck_log("%K (\"%.*s\")\n", &deh_key,
&tmp_deh->deh2_dir_id, namelen, namelen, name);
name);
mark_buffer_dirty(get_bh(&path)); mark_buffer_dirty(get_bh(&path));
} }
dir_size += DEH_SIZE + entry_len; dir_size += DEH_SIZE + entry_len;
+16 -3
View File
@@ -4,6 +4,7 @@
*/ */
#include "fsck.h" #include "fsck.h"
#include "misc.h"
int screen_width; int screen_width;
static int screen_curr_pos; static int screen_curr_pos;
@@ -639,7 +640,7 @@ static char *get_next_directory_item(struct reiserfs_key *key, /* on return this
memcpy(dir_item, ih_item_body(bh, ih), get_ih_item_len(ih)); memcpy(dir_item, ih_item_body(bh, ih), get_ih_item_len(ih));
/* next item key */ /* next item key */
if (PATH_LAST_POSITION(&path) == (B_NR_ITEMS(bh) - 1) && if (PATH_LAST_POSITION(&path) + 1 == B_NR_ITEMS(bh) &&
(rdkey = uget_rkey(&path))) (rdkey = uget_rkey(&path)))
copy_key(key, rdkey); copy_key(key, rdkey);
else { else {
@@ -923,7 +924,7 @@ start_again: /* when directory was relocated */
} }
namelen = name_in_entry_length(&tmp_ih, deh, i); namelen = name_in_entry_length(&tmp_ih, deh, i);
asprintf(&name, "%.*s", namelen, name_in_entry(deh, i)); xasprintf(&name, "%.*s", namelen, name_in_entry(deh, i));
entry_len = entry_length(&tmp_ih, deh, i); entry_len = entry_length(&tmp_ih, deh, i);
@@ -1005,11 +1006,23 @@ start_again: /* when directory was relocated */
} else { } else {
/* update key dir entry points to */ /* update key dir entry points to */
struct reiserfs_de_head *tmp_deh; struct reiserfs_de_head *tmp_deh;
struct reiserfs_key deh_key;
tmp_deh = tmp_deh =
B_I_DEH(get_bh(&path), B_I_DEH(get_bh(&path),
tp_item_head(&path)) + tp_item_head(&path)) +
path.pos_in_item; path.pos_in_item;
/* Build a proper key from the entry's
dirid/objectid. Passing
&tmp_deh->deh2_dir_id as a
reiserfs_key * only worked by
offset coincidence and trips
-Waddress-of-packed-member. */
set_key_dirid(&deh_key,
get_deh_dirid(tmp_deh));
set_key_objectid(&deh_key,
get_deh_objectid(tmp_deh));
fsck_log fsck_log
("The entry %K (\"%.*s\") in directory %K updated to point to ", ("The entry %K (\"%.*s\") in directory %K updated to point to ",
&object_key, namelen, name, &object_key, namelen, name,
@@ -1022,7 +1035,7 @@ start_again: /* when directory was relocated */
(&relocated_ih. (&relocated_ih.
ih_key)); ih_key));
fsck_log("%K\n", &tmp_deh->deh2_dir_id); fsck_log("%K\n", &deh_key);
mark_buffer_dirty(get_bh(&path)); mark_buffer_dirty(get_bh(&path));
} }
dir_size += DEH_SIZE + entry_len; dir_size += DEH_SIZE + entry_len;
+13 -5
View File
@@ -190,6 +190,7 @@ void rebuild_sb(reiserfs_filsys_t fs, char *filename, struct fsck_data *data)
size_t n = 0; size_t n = 0;
struct stat stat_buf; struct stat stat_buf;
int retval, exit_code = EXIT_OK; int retval, exit_code = EXIT_OK;
long error;
if (!no_reiserfs_found(fs)) { if (!no_reiserfs_found(fs)) {
sb = getmem(sizeof(*sb)); sb = getmem(sizeof(*sb));
@@ -381,24 +382,31 @@ void rebuild_sb(reiserfs_filsys_t fs, char *filename, struct fsck_data *data)
switch (version) { switch (version) {
case 1: case 1:
fs = reiserfs_create(filename, REISERFS_FORMAT_3_6, fs = reiserfs_create(filename, REISERFS_FORMAT_3_6,
block_count, retval, 1, 1); block_count, retval, 1, 1,
&error);
break; break;
case 2: case 2:
fs = reiserfs_create(filename, REISERFS_FORMAT_3_5, fs = reiserfs_create(filename, REISERFS_FORMAT_3_5,
block_count, retval, 1, 1); block_count, retval, 1, 1,
&error);
break; break;
case 3: case 3:
fs = reiserfs_create(filename, REISERFS_FORMAT_3_6, fs = reiserfs_create(filename, REISERFS_FORMAT_3_6,
block_count, retval, 1, 0); block_count, retval, 1, 0,
&error);
break; break;
case 4: case 4:
fs = reiserfs_create(filename, REISERFS_FORMAT_3_5, fs = reiserfs_create(filename, REISERFS_FORMAT_3_5,
block_count, retval, 1, 0); block_count, retval, 1, 0,
&error);
break; break;
} }
if (fs == NULL) if (fs == NULL) {
fprintf(stderr, "reiserfs_create failed: %s\n",
error_message(error));
return; return;
}
sb = fs->fs_ondisk_sb; sb = fs->fs_ondisk_sb;
fs->fs_vp = data; fs->fs_vp = data;
+2 -2
View File
@@ -13,8 +13,8 @@ static int do_items_have_the_same_type(const struct item_head *ih,
static int are_items_in_the_same_node(const struct reiserfs_path *path) static int are_items_in_the_same_node(const struct reiserfs_path *path)
{ {
return (PATH_LAST_POSITION(path) < return (PATH_LAST_POSITION(path) + 1 <
B_NR_ITEMS(PATH_PLAST_BUFFER(path)) - 1) ? 1 : 0; B_NR_ITEMS(PATH_PLAST_BUFFER(path))) ? 1 : 0;
} }
static void cut_last_unfm_pointer(struct reiserfs_path *path, static void cut_last_unfm_pointer(struct reiserfs_path *path,
+16 -7
View File
@@ -36,10 +36,10 @@
void check_memory_msg(void); void check_memory_msg(void);
void die(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); void die(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
int xasprintf(char **ret, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
void *getmem(int size); void *getmem(int size);
void *mem_alloc(int size); void *mem_alloc(int size);
void freemem(void *p); void freemem(void *p);
void checkmem(const char *p, int size);
void *expandmem(void *p, int size, int by); void *expandmem(void *p, int size, int by);
unsigned int get_mem_size(const char *p); unsigned int get_mem_size(const char *p);
void check_and_free_mem(void); void check_and_free_mem(void);
@@ -222,13 +222,22 @@ static inline unsigned long long misc_find_next_set_bit(const void *vaddr,
return res + (p - addr) * 8; return res + (p - addr) * 8;
} }
#define STAT_FIELD_H(Field, Type) \ #define STAT_FIELD(Field, Type) \
inline Type misc_device_##Field(const char *device); static inline Type misc_device_##Field(const char *device) \
{ \
struct stat st; \
\
if (stat(device, &st) == 0) \
return st.st_##Field; \
\
fprintf(stderr, "Stat of the device '%s' failed.", device); \
exit(8); \
}
STAT_FIELD_H(mode, mode_t); STAT_FIELD(mode, mode_t);
STAT_FIELD_H(rdev, dev_t); STAT_FIELD(rdev, dev_t);
STAT_FIELD_H(size, off_t); STAT_FIELD(size, off_t);
STAT_FIELD_H(blocks, blkcnt_t); STAT_FIELD(blocks, blkcnt_t);
__u16 mask16(int from, int count); __u16 mask16(int from, int count);
__u32 mask32(int from, int count); __u32 mask32(int from, int count);
+15 -3
View File
@@ -32,6 +32,7 @@
#ifndef REISERFSPROGS_FS_H #ifndef REISERFSPROGS_FS_H
#define REISERFSPROGS_FS_H #define REISERFSPROGS_FS_H
#include <stddef.h>
#include <linux/types.h> #include <linux/types.h>
#include "swab.h" #include "swab.h"
@@ -174,7 +175,12 @@ struct reiserfs_super_block_v1 {
#define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1)) /* 76 bytes */ #define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1)) /* 76 bytes */
#define sb_jp(sb) (&((sb)->s_v1.sb_journal)) /* &(sb)->s_v1.sb_journal would take the address of a member inside a
packed struct, which is legal here (offset 12) but trips
-Waddress-of-packed-member on every use. Spell it out instead. */
#define sb_jp(sb) ((struct journal_params *) \
((char *)(sb) + offsetof(struct reiserfs_super_block, s_v1) + \
offsetof(struct reiserfs_super_block_v1, sb_journal)))
/* values for sb_version field of struct reiserfs_super_block. sb_version is /* values for sb_version field of struct reiserfs_super_block. sb_version is
only reliable on filesystem with non-standard journal */ only reliable on filesystem with non-standard journal */
@@ -636,6 +642,12 @@ struct item_head {
/* size of item header */ /* size of item header */
#define IH_SIZE (sizeof(struct item_head)) #define IH_SIZE (sizeof(struct item_head))
/* Address of the packed ih_format field, computed without forming a pointer
to a member of a packed struct (which trips -Waddress-of-packed-member).
ih_format is naturally aligned, so dereferencing the result is fine. */
#define ih_format_ptr(ih) \
((__le16 *)((char *)(ih) + offsetof(struct item_head, ih_format)))
/* set/get fields of item head on disk with these defines */ /* set/get fields of item head on disk with these defines */
#define get_ih_entry_count(ih) get_le16 (ih, u.ih2_entry_count) #define get_ih_entry_count(ih) get_le16 (ih, u.ih2_entry_count)
#define set_ih_entry_count(ih,val) set_le16 (ih, u.ih2_entry_count, val) #define set_ih_entry_count(ih,val) set_le16 (ih, u.ih2_entry_count, val)
@@ -1061,7 +1073,7 @@ struct reiserfs_path {
}; };
#define INITIALIZE_REISERFS_PATH(var) \ #define INITIALIZE_REISERFS_PATH(var) \
struct reiserfs_path var = {ILLEGAL_PATH_ELEMENT_OFFSET, } struct reiserfs_path var = { .path_length = ILLEGAL_PATH_ELEMENT_OFFSET }
/* Get path element by path and path position. */ /* Get path element by path and path position. */
#define PATH_OFFSET_PELEMENT(p_s_path,n_offset) ((p_s_path)->path_elements +(n_offset)) #define PATH_OFFSET_PELEMENT(p_s_path,n_offset) ((p_s_path)->path_elements +(n_offset))
@@ -1581,7 +1593,7 @@ static inline void buffer_info_init_bh(const struct tree_balance *tb,
struct buffer_info *bi, struct buffer_info *bi,
struct buffer_head *bh) struct buffer_head *bh)
{ {
bi->bi_fs = tb->tb_fs; bi->bi_fs = tb ? tb->tb_fs : NULL;
bi->bi_bh = bh; bi->bi_bh = bh;
bi->bi_parent = NULL; bi->bi_parent = NULL;
bi->bi_position = 0; bi->bi_position = 0;
+7 -5
View File
@@ -11,6 +11,7 @@
typedef struct reiserfs_filsys * reiserfs_filsys_t; typedef struct reiserfs_filsys * reiserfs_filsys_t;
#include <com_err.h>
#include "reiserfs_fs.h" #include "reiserfs_fs.h"
struct _bitmap { struct _bitmap {
@@ -75,11 +76,12 @@ typedef struct _transaction reiserfs_trans_t;
void init_tb_struct(struct tree_balance *tb, reiserfs_filsys_t , void init_tb_struct(struct tree_balance *tb, reiserfs_filsys_t ,
struct reiserfs_path *path, int size); struct reiserfs_path *path, int size);
reiserfs_filsys_t reiserfs_open(const char *filename, int flags, int *error, reiserfs_filsys_t reiserfs_open(const char *filename, int flags, long *error,
void *vp, int skip_check); void *vp, int skip_check);
reiserfs_filsys_t reiserfs_create(const char *filename, int version, reiserfs_filsys_t reiserfs_create(const char *filename, int version,
unsigned long block_count, int block_size, unsigned long block_count, int block_size,
int default_journal, int new_format); int default_journal, int new_format,
long *error);
void reiserfs_flush(reiserfs_filsys_t ); void reiserfs_flush(reiserfs_filsys_t );
void reiserfs_free(reiserfs_filsys_t ); void reiserfs_free(reiserfs_filsys_t );
void reiserfs_close(reiserfs_filsys_t ); void reiserfs_close(reiserfs_filsys_t );
@@ -170,17 +172,17 @@ typedef int (*reiserfs_file_iterate_direct_fn)(reiserfs_filsys_t fs,
const char *body, size_t len, const char *body, size_t len,
void *data); void *data);
int reiserfs_iterate_file_data(reiserfs_filsys_t fs, int reiserfs_iterate_file_data(reiserfs_filsys_t fs,
const struct reiserfs_key const *short_key, const struct reiserfs_key *short_key,
reiserfs_file_iterate_indirect_fn indirect_fn, reiserfs_file_iterate_indirect_fn indirect_fn,
reiserfs_file_iterate_direct_fn direct_fn, reiserfs_file_iterate_direct_fn direct_fn,
void *data); void *data);
typedef int (*reiserfs_iterate_dir_fn)(reiserfs_filsys_t fs, typedef int (*reiserfs_iterate_dir_fn)(reiserfs_filsys_t fs,
const struct reiserfs_key const *dir_short_key, const struct reiserfs_key *dir_short_key,
const char *name, size_t len, const char *name, size_t len,
__u32 deh_dirid, __u32 deh_objectid, void *data); __u32 deh_dirid, __u32 deh_objectid, void *data);
int reiserfs_iterate_dir(reiserfs_filsys_t fs, int reiserfs_iterate_dir(reiserfs_filsys_t fs,
const struct reiserfs_key const *dir_short_key, const struct reiserfs_key *dir_short_key,
const reiserfs_iterate_dir_fn callback, void *data); const reiserfs_iterate_dir_fn callback, void *data);
+7 -6
View File
@@ -7,7 +7,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <asm/types.h> #include <linux/types.h>
void check_memory_msg(void) void check_memory_msg(void)
{ {
@@ -585,8 +585,8 @@ static void erase_rollback_file(char *rollback_file)
int open_rollback_file(char *rollback_file, FILE * log) int open_rollback_file(char *rollback_file, FILE * log)
{ {
char string[28];
struct stat buf; struct stat buf;
char string[sizeof(ROLLBACK_FILE_START_MAGIC)] = { 0 };
if (rollback_file == NULL) if (rollback_file == NULL)
return -1; return -1;
@@ -603,8 +603,8 @@ int open_rollback_file(char *rollback_file, FILE * log)
return -1; return -1;
} }
fread(string, 28, 1, s_rollback_file); fread(string, sizeof(ROLLBACK_FILE_START_MAGIC) - 1, 1, s_rollback_file);
if (!strcmp(string, ROLLBACK_FILE_START_MAGIC)) { if (strcmp(string, ROLLBACK_FILE_START_MAGIC) != 0) {
fprintf(stderr, fprintf(stderr,
"Specified file (%s) does not look like a rollback file\n", "Specified file (%s) does not look like a rollback file\n",
rollback_file); rollback_file);
@@ -775,8 +775,9 @@ void do_fsck_rollback(int fd_device, int fd_journal_device, FILE * progress)
printf("\n"); printf("\n");
if (log_file) if (log_file)
fprintf(log_file, "rollback: (%u) blocks restored\n", fprintf(log_file,
count_rollbacked); "rollback: (%u) blocks restored, %u skipped\n",
count_rollbacked, count_failed);
} }
/* /*
+82 -100
View File
@@ -9,10 +9,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <mntent.h> #include <mntent.h>
#include <sys/vfs.h> #include <sys/statfs.h>
#include <time.h> #include <time.h>
#include <utime.h> #include <utime.h>
#include <ctype.h> #include <ctype.h>
@@ -27,147 +28,123 @@
#include <sys/mount.h> #include <sys/mount.h>
/* End Debian mods */ /* End Debian mods */
#define STAT_FIELD(Field, Type) \
inline Type misc_device_##Field(const char *device) { \
struct stat st; \
\
if (stat(device, &st) == 0) \
return st.st_##Field; \
\
fprintf(stderr, "Stat of the device '%s' failed.", device); \
exit(8); \
}
STAT_FIELD(mode, mode_t);
STAT_FIELD(rdev, dev_t);
STAT_FIELD(size, off_t);
STAT_FIELD(blocks, blkcnt_t);
void die(const char *fmt, ...) void die(const char *fmt, ...)
{ {
static char buf[1024]; static char buf[1024];
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
vsprintf(buf, fmt, args); vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args); va_end(args);
fprintf(stderr, "\n%s\n", buf); fprintf(stderr, "\n%s\n", buf);
abort(); abort();
} }
#define MEM_BEGIN "_mem_begin_" /*
#define MEM_END "mem_end" * Small size-tracking allocator. Every block handed out by getmem()/
#define MEM_FREED "__free_" * mem_alloc()/expandmem() is preceded by a header recording its usable
#define CONTROL_SIZE (strlen (MEM_BEGIN) + 1 + sizeof (int) + strlen (MEM_END) + 1) * size. get_mem_size() reports it back and expandmem() uses it to grow
* in place without the caller having to remember the old size.
*
* The header is over-aligned so the returned pointer keeps malloc's
* alignment guarantees for any type.
*/
union mem_header {
struct {
size_t size;
} h;
max_align_t align;
};
/* asprintf() wrapper: allocation failure is fatal, matching the rest of
this file (die()). Use it where the old code ignored asprintf()'s
return value and then dereferenced the pointer. */
int xasprintf(char **ret, const char *fmt, ...)
{
va_list args;
int rc;
va_start(args, fmt);
rc = vasprintf(ret, fmt, args);
va_end(args);
if (rc < 0)
die("xasprintf: out of memory");
return rc;
}
#define MEM_HEADER_SIZE (sizeof(union mem_header))
static union mem_header *mem_header_of(const void *p)
{
return (union mem_header *)((char *)p - MEM_HEADER_SIZE);
}
unsigned int get_mem_size(const char *p) unsigned int get_mem_size(const char *p)
{ {
const char *begin; return mem_header_of(p)->h.size;
begin = p - strlen(MEM_BEGIN) - 1 - sizeof(int);
return *(int *)(begin + strlen(MEM_BEGIN) + 1);
} }
void checkmem(const char *p, int size) void *mem_alloc(int size)
{ {
const char *begin; union mem_header *hdr;
const char *end; char *mem;
begin = p - strlen(MEM_BEGIN) - 1 - sizeof(int); if (size < 0)
if (strcmp(begin, MEM_BEGIN)) die("mem_alloc: negative size (%d)", size);
die("checkmem: memory corrupted - invalid head sign");
if (*(int *)(begin + strlen(MEM_BEGIN) + 1) != size) hdr = malloc(MEM_HEADER_SIZE + (size_t) size);
die("checkmem: memory corrupted - invalid size"); if (!hdr)
die("mem_alloc: no more memory (%d)", size);
end = begin + size + CONTROL_SIZE - strlen(MEM_END) - 1; hdr->h.size = size;
if (strcmp(end, MEM_END)) mem = (char *)hdr + MEM_HEADER_SIZE;
die("checkmem: memory corrupted - invalid end sign");
return mem;
} }
void *getmem(int size) void *getmem(int size)
{ {
char *mem; char *mem;
if ((mem = mem_alloc(size)) == NULL) mem = mem_alloc(size);
die("getmem: no more memory (%d)", size);
memset(mem, 0, size); memset(mem, 0, size);
// checkmem (mem, size);
return mem;
}
void *mem_alloc(int size)
{
char *p;
char *mem;
p = (char *)malloc(CONTROL_SIZE + size);
if (!p)
die("getmem: no more memory (%d)", size);
/* Write the MEM_BEGIN magic in the beginning of allocated memory. */
strcpy(p, MEM_BEGIN);
p += strlen(MEM_BEGIN) + 1;
/* Write the size after the magic. */
*(int *)p = size;
p += sizeof(int);
mem = p;
p += size;
strcpy(p, MEM_END);
return mem; return mem;
} }
void *expandmem(void *vp, int size, int by) void *expandmem(void *vp, int size, int by)
{ {
int allocated; union mem_header *hdr;
char *mem, *p = vp; char *mem;
int expand_by = by; size_t old_size = vp ? (size_t) mem_header_of(vp)->h.size : 0;
size_t new_size = old_size + by;
if (p) { if (by < 0)
checkmem(p, size); die("expandmem: negative increment (%d)", by);
allocated = CONTROL_SIZE + size;
p -= (strlen(MEM_BEGIN) + 1 + sizeof(int)); hdr = realloc(vp ? mem_header_of(vp) : NULL, MEM_HEADER_SIZE + new_size);
} else { if (!hdr)
allocated = 0;
/* add control bytes to the new allocated area */
expand_by += CONTROL_SIZE;
}
p = realloc(p, allocated + expand_by);
if (!p)
die("expandmem: no more memory (%d)", size); die("expandmem: no more memory (%d)", size);
if (!vp) {
strcpy(p, MEM_BEGIN);
}
mem = p + strlen(MEM_BEGIN) + 1 + sizeof(int);
*(int *)(p + strlen(MEM_BEGIN) + 1) = size + by; mem = (char *)hdr + MEM_HEADER_SIZE;
/* fill new allocated area by 0s */ hdr->h.size = new_size;
/* fill the newly allocated area with 0s */
if (by > 0) if (by > 0)
memset(mem + size, 0, by); memset(mem + old_size, 0, by);
strcpy(mem + size + by, MEM_END);
// checkmem (mem, size + by);
return mem; return mem;
} }
void freemem(void *vp) void freemem(void *vp)
{ {
char *p = vp; if (!vp)
int size;
if (!p)
return; return;
size = get_mem_size(vp);
checkmem(p, size);
p -= (strlen(MEM_BEGIN) + 1 + sizeof(int)); free(mem_header_of(vp));
strcpy(p, MEM_FREED);
strcpy(p + size + CONTROL_SIZE - strlen(MEM_END) - 1, MEM_FREED);
free(p);
} }
typedef int (*func_t) (const char *); typedef int (*func_t) (const char *);
@@ -730,13 +707,18 @@ int prepare_dma_check(dma_info_t *dma_info)
} }
while ((dirent = readdir(dir)) != NULL) { while ((dirent = readdir(dir)) != NULL) {
int n;
if (strncmp(dirent->d_name, ".", 1) == 0 if (strncmp(dirent->d_name, ".", 1) == 0
|| strncmp(dirent->d_name, "..", 2) == 0) || strncmp(dirent->d_name, "..", 2) == 0)
continue; continue;
memset(buf, 0, 256);
strncat(buf, "/dev/", 5); /* "/dev/" + name; skip names that do not fit
strncat(buf, dirent->d_name, rather than truncating into a wrong path */
strlen(dirent->d_name)); n = snprintf(buf, sizeof(buf), "/dev/%s",
dirent->d_name);
if (n < 0 || (size_t) n >= sizeof(buf))
continue;
if (stat(buf, &st)) if (stat(buf, &st))
break; break;
+1 -1
View File
@@ -1,4 +1,4 @@
#define _XOPEN_SOURCE #define _GNU_SOURCE
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
+1 -1
View File
@@ -15,7 +15,7 @@ void progbar_init(struct progbar *ctx, const char *units, FILE * fp)
memset(bar, '=', sizeof(bar) - 1); memset(bar, '=', sizeof(bar) - 1);
if (!spaces[0]) if (!spaces[0])
memset(spaces, ' ', sizeof(spaces) - 1); memset(spaces, ' ', sizeof(spaces) - 1);
strncpy(ctx->units, units, sizeof(ctx->units)); snprintf(ctx->units, sizeof(ctx->units), "%s", units);
ctx->file = fp; ctx->file = fp;
} }
+1 -1
View File
@@ -88,7 +88,7 @@ be adjusted.
\fB-B\fR | \fB--badblocks \fIfile \fB-B\fR | \fB--badblocks \fIfile
\fIFile\fR is the file name of the file that contains the list of blocks to be \fIFile\fR is the file name of the file that contains the list of blocks to be
marked as bad on the filesystem. This list can be created by marked as bad on the filesystem. This list can be created by
\fB/sbin/badblocks -b block-size device\fR. \fB/sbin/badblocks \-b block-size device\fR.
.TP .TP
\fB-f\fR \fB-f\fR
Forces \fBmkreiserfs\fR to continue even when the device is the whole disk, Forces \fBmkreiserfs\fR to continue even when the device is the whole disk,
+10 -3
View File
@@ -122,7 +122,11 @@ static void make_super_block(reiserfs_filsys_t fs)
reiserfs_warning(stderr, reiserfs_warning(stderr,
"\nSpecified LABEL is longer then 16 " "\nSpecified LABEL is longer then 16 "
"characters, will be truncated\n\n"); "characters, will be truncated\n\n");
strncpy(fs->fs_ondisk_sb->s_label, LABEL, 16); /* on-disk label is a fixed 16-byte field; keep it
NUL-terminated for the userspace readers below */
snprintf(fs->fs_ondisk_sb->s_label,
sizeof(fs->fs_ondisk_sb->s_label),
"%s", LABEL);
} }
set_sb_v2_flag(fs->fs_ondisk_sb, reiserfs_attrs_cleared); set_sb_v2_flag(fs->fs_ondisk_sb, reiserfs_attrs_cleared);
} }
@@ -576,6 +580,7 @@ int main(int argc, char **argv)
__u64 fs_size = 0; __u64 fs_size = 0;
int c; int c;
static int flag; static int flag;
long error;
program_name = strrchr(argv[0], '/'); program_name = strrchr(argv[0], '/');
@@ -642,7 +647,7 @@ int main(int argc, char **argv)
break; break;
case 'B': /* --badblock-list */ case 'B': /* --badblock-list */
asprintf(&badblocks_file, "%s", optarg); xasprintf(&badblocks_file, "%s", optarg);
break; break;
case 'h': /* --hash */ case 'h': /* --hash */
@@ -751,9 +756,11 @@ int main(int argc, char **argv)
return 1; return 1;
fs = reiserfs_create(device_name, select_format(), fs_size, Block_size, fs = reiserfs_create(device_name, select_format(), fs_size, Block_size,
Create_default_journal, 1); Create_default_journal, 1, &error);
if (!fs) { if (!fs) {
reiserfs_warning(stderr, "reiserfs_create failed: %s %ld\n",
error_message(error), error);
return 1; return 1;
} }
+21 -2
View File
@@ -1,9 +1,28 @@
lib_LTLIBRARIES = libreiserfscore.la lib_LTLIBRARIES = libreiserfscore.la
reiserfsdir = $(includedir)/reiserfs
reiserfs_HEADERS = reiserfs_err.h
# compile_et writes reiserfs_err.c AND reiserfs_err.h in one pass. Keep the
# recipe on a single target: when one recipe is shared by two targets, parallel
# make can run it concurrently for both, and one run deletes the .c while
# another job is still compiling it ("no input files"). reiserfs_err.h only
# depends on reiserfs_err.c, so the recipe always runs exactly once.
reiserfs_err.c: $(srcdir)/reiserfs_err.et
$(RM) -f reiserfs_err.c reiserfs_err.h
compile_et $(srcdir)/reiserfs_err.et
reiserfs_err.h: reiserfs_err.c
BUILT_SOURCES = reiserfs_err.h reiserfs_err.c
CLEANFILES = reiserfs_err.h reiserfs_err.c
EXTRA_DIST = reiserfs_err.et
libreiserfscore_la_SOURCES = do_balan.c fix_node.c hashes.c ibalance.c \ libreiserfscore_la_SOURCES = do_balan.c fix_node.c hashes.c ibalance.c \
lbalance.c prints.c stree.c node_formats.c \ lbalance.c prints.c stree.c node_formats.c \
reiserfslib.c bitmap.c journal.c xattr.c includes.h reiserfslib.c bitmap.c journal.c xattr.c \
libreiserfscore_la_LIBADD = ../lib/libmisc.la includes.h reiserfs_err.c
libreiserfscore_la_LIBADD = ../lib/libmisc.la -lcom_err
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = reiserfscore.pc pkgconfig_DATA = reiserfscore.pc
+1 -1
View File
@@ -1538,7 +1538,7 @@ void do_balance(struct tree_balance *tb, /* tree_balance structure
insert_ptr[0] = (struct buffer_head *)body; insert_ptr[0] = (struct buffer_head *)body;
/* we must prepare insert_key */ /* we must prepare insert_key */
if (PATH_H_B_ITEM_ORDER(tb->tb_path, 0) /*LAST_POSITION (tb->tb_path) */ if ((int)PATH_H_B_ITEM_ORDER(tb->tb_path, 0) /*LAST_POSITION (tb->tb_path) */
/*item_pos */ == -1) { /*item_pos */ == -1) {
/* get delimiting key from buffer in tree */ /* get delimiting key from buffer in tree */
copy_key(&insert_key[0].ih_key, copy_key(&insert_key[0].ih_key,
+4 -36
View File
@@ -22,7 +22,7 @@
// r5 // r5
// //
#include <asm/types.h> #include <linux/types.h>
#define DELTA 0x9E3779B9 #define DELTA 0x9E3779B9
#define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */ #define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
@@ -83,10 +83,9 @@ u32 keyed_hash(const signed char *msg, int len)
msg += 16; msg += 16;
} }
/* len <= 15 here: the while loop above consumed every full 16-byte
block, so the "len >= 16" test that used to sit here was dead. */
if (len >= 12) { if (len >= 12) {
if (len >= 16)
*(int *)0 = 0;
a = (u32) msg[0] | a = (u32) msg[0] |
(u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24; (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
b = (u32) msg[4] | b = (u32) msg[4] |
@@ -101,8 +100,6 @@ u32 keyed_hash(const signed char *msg, int len)
d |= msg[i]; d |= msg[i];
} }
} else if (len >= 8) { } else if (len >= 8) {
if (len >= 12)
*(int *)0 = 0;
a = (u32) msg[0] | a = (u32) msg[0] |
(u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24; (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
b = (u32) msg[4] | b = (u32) msg[4] |
@@ -114,8 +111,6 @@ u32 keyed_hash(const signed char *msg, int len)
c |= msg[i]; c |= msg[i];
} }
} else if (len >= 4) { } else if (len >= 4) {
if (len >= 8)
*(int *)0 = 0;
a = (u32) msg[0] | a = (u32) msg[0] |
(u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24; (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
@@ -125,8 +120,7 @@ u32 keyed_hash(const signed char *msg, int len)
b |= msg[i]; b |= msg[i];
} }
} else { } else {
if (len >= 4) /* len <= 3 here. */
*(int *)0 = 0;
a = b = c = d = pad; a = b = c = d = pad;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
a <<= 8; a <<= 8;
@@ -190,29 +184,3 @@ u32 r5_hash(const signed char *msg, int len)
} }
return a; return a;
} }
#if 0
#include <stdio.h>
int main(void)
{
char *name = 0;
size_t n = 0;
while (1) {
getline(&name, &n, stdin);
if (!strcmp(name, "\n"))
break;
name[strlen(name) - 1] = 0;
printf("tea %lu\n, r5 %lu\nyura %lu\n",
keyed_hash(name, strlen(name)) & 0x7fffff80,
r5_hash(name, strlen(name)) & 0x7fffff80,
yura_hash(name, strlen(name)) & 0x7fffff80);
free(name);
name = 0;
n = 0;
}
}
#endif
+2 -1
View File
@@ -881,8 +881,9 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
insert_key, insert_ptr); insert_key, insert_ptr);
} }
memcpy(new_insert_key_addr, &new_insert_key, KEY_SIZE);
insert_ptr[0] = new_insert_ptr; insert_ptr[0] = new_insert_ptr;
if (new_insert_ptr)
memcpy(new_insert_key_addr, &new_insert_key, KEY_SIZE);
return order; return order;
} }
+2 -3
View File
@@ -10,12 +10,11 @@
#include "io.h" #include "io.h"
#include "misc.h" #include "misc.h"
#include "reiserfs_lib.h" #include "reiserfs_lib.h"
#include "reiserfs_err.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <asm/types.h> #include <linux/types.h>
#include <fcntl.h> #include <fcntl.h>
#include <malloc.h>
#include <sys/vfs.h>
#include <time.h> #include <time.h>
+2 -2
View File
@@ -506,7 +506,7 @@ int reiserfs_open_journal(reiserfs_filsys_t fs, const char *j_filename,
if (fs->fs_journal_dev == -1) if (fs->fs_journal_dev == -1)
return -1; return -1;
asprintf(&fs->fs_j_file_name, "%s", j_filename); xasprintf(&fs->fs_j_file_name, "%s", j_filename);
if (get_jp_journal_size(sb_jp(sb)) < JOURNAL_MIN_SIZE) { if (get_jp_journal_size(sb_jp(sb)) < JOURNAL_MIN_SIZE) {
reiserfs_warning(stderr, "Journal of (%lu) block size found on " reiserfs_warning(stderr, "Journal of (%lu) block size found on "
@@ -694,7 +694,7 @@ int reiserfs_create_journal(reiserfs_filsys_t fs, const char *j_device, /* journ
return 0; return 0;
} }
asprintf(&fs->fs_j_file_name, "%s", j_device); xasprintf(&fs->fs_j_file_name, "%s", j_device);
if (len < JOURNAL_MIN_SIZE + 1) { if (len < JOURNAL_MIN_SIZE + 1) {
reiserfs_warning(stderr, reiserfs_warning(stderr,
+5 -5
View File
@@ -610,7 +610,7 @@ int find_hash_in_use(const char *name, int namelen, __u32 offset,
char *code2name(unsigned int code) char *code2name(unsigned int code)
{ {
if (code >= HASH_AMOUNT || code < 0) if (code >= HASH_AMOUNT)
return NULL; return NULL;
return hashes[code].name; return hashes[code].name;
} }
@@ -1031,22 +1031,22 @@ int name_length(const char *name, int key_format)
/* key format is stored in 12 bits starting from 0-th of item_head's ih2_format*/ /* key format is stored in 12 bits starting from 0-th of item_head's ih2_format*/
__u16 get_ih_key_format(const struct item_head * ih) __u16 get_ih_key_format(const struct item_head * ih)
{ {
get_bit_field_XX(16, &ih->ih_format, 0, 12); get_bit_field_XX(16, ih_format_ptr(ih), 0, 12);
} }
__u16 get_ih_flags(const struct item_head *ih) __u16 get_ih_flags(const struct item_head *ih)
{ {
get_bit_field_XX(16, &ih->ih_format, 12, 4); get_bit_field_XX(16, ih_format_ptr(ih), 12, 4);
} }
void set_ih_key_format(struct item_head *ih, __u16 val) void set_ih_key_format(struct item_head *ih, __u16 val)
{ {
set_bit_field_XX(16, &ih->ih_format, val, 0, 12); set_bit_field_XX(16, ih_format_ptr(ih), val, 0, 12);
} }
void set_ih_flags(struct item_head *ih, __u16 val) void set_ih_flags(struct item_head *ih, __u16 val)
{ {
set_bit_field_XX(16, &ih->ih_format, val, 12, 4); set_bit_field_XX(16, ih_format_ptr(ih), val, 12, 4);
} }
/* access to fields of stat data (both v1 and v2) */ /* access to fields of stat data (both v1 and v2) */
+27
View File
@@ -0,0 +1,27 @@
# reiserfs_err.et - Error codes for reiserfscore
#
# Copyright (C) 2016 SUSE
#
error_table reiserfs
ec REISERFS_ET_BREAD_FAILED,
"bread failed to read block"
ec REISERFS_ET_BAD_MAGIC,
"the reiserfs superblock cannot be found"
ec REISERFS_ET_BAD_SUPER,
"a superblock with wrong parameters was found in the block"
ec REISERFS_ET_SMALL_PARTITION,
"Your partition is not big enough to contain the filesystem"
ec REISERFS_ET_NOT_ENOUGH_BLOCKS,
"not enough blocks on device"
ec REISERFS_ET_TOO_SMALL,
"cannot create a file system that small"
ec REISERFS_ET_GETBLK_FAILED,
"getblk failed"
end
+1 -1
View File
@@ -5,6 +5,6 @@ includedir=@includedir@
Name: reiserfscore Name: reiserfscore
Description: ReiserFS Core Library Description: ReiserFS Core Library
Version: @REISERFSPROGS_VERSION@ Version: @PACKAGE_VERSION@
Cflags: -I${includedir}/reiserfs -I${includedir} Cflags: -I${includedir}/reiserfs -I${includedir}
Libs: -L${libdir} -lreiserfscore Libs: -L${libdir} -lreiserfscore
+34 -41
View File
@@ -56,7 +56,7 @@ int is_block_count_correct(unsigned long journal_offset,
is refused. Journal and bitmap are to be opened separately. is refused. Journal and bitmap are to be opened separately.
skip_check is set to 1 if checks of openned SB should be omitted.*/ skip_check is set to 1 if checks of openned SB should be omitted.*/
reiserfs_filsys_t reiserfs_open(const char *filename, int flags, reiserfs_filsys_t reiserfs_open(const char *filename, int flags,
int *error, void *vp, int check) long *error, void *vp, int check)
{ {
reiserfs_filsys_t fs; reiserfs_filsys_t fs;
struct buffer_head *bh; struct buffer_head *bh;
@@ -67,8 +67,7 @@ reiserfs_filsys_t reiserfs_open(const char *filename, int flags,
/* convert root dir key and parent root dir key to little endian format */ /* convert root dir key and parent root dir key to little endian format */
make_const_keys(); make_const_keys();
if (error) *error = 0;
*error = 0;
fd = open(filename, flags fd = open(filename, flags
#if defined(O_LARGEFILE) #if defined(O_LARGEFILE)
@@ -76,24 +75,21 @@ reiserfs_filsys_t reiserfs_open(const char *filename, int flags,
#endif #endif
); );
if (fd == -1) { if (fd == -1) {
if (error) *error = errno;
*error = errno;
return NULL; return NULL;
} }
fs = getmem(sizeof(*fs)); fs = getmem(sizeof(*fs));
fs->fs_dev = fd; fs->fs_dev = fd;
fs->fs_vp = vp; fs->fs_vp = vp;
asprintf(&fs->fs_file_name, "%s", filename); xasprintf(&fs->fs_file_name, "%s", filename);
/* reiserfs super block is either in 16-th or in 2-nd 4k block of the /* reiserfs super block is either in 16-th or in 2-nd 4k block of the
device */ device */
for (i = 2; i < 17; i += 14) { for (i = 2; i < 17; i += 14) {
bh = bread(fd, i, 4096); bh = bread(fd, i, 4096);
if (!bh) { if (!bh) {
reiserfs_warning(stderr, *error = REISERFS_ET_BREAD_FAILED;
"reiserfs_open: bread failed reading block %d\n",
i);
} else { } else {
sb = (struct reiserfs_super_block *)bh->b_data; sb = (struct reiserfs_super_block *)bh->b_data;
@@ -105,9 +101,7 @@ reiserfs_filsys_t reiserfs_open(const char *filename, int flags,
} }
} }
reiserfs_warning(stderr, *error = REISERFS_ET_BAD_MAGIC;
"\nreiserfs_open: the reiserfs superblock cannot be found on %s.\n",
filename);
freemem(fs); freemem(fs);
close(fd); close(fd);
@@ -117,9 +111,7 @@ reiserfs_filsys_t reiserfs_open(const char *filename, int flags,
found: found:
if (!is_blocksize_correct(get_sb_block_size(sb))) { if (!is_blocksize_correct(get_sb_block_size(sb))) {
reiserfs_warning(stderr, *error = REISERFS_ET_BAD_SUPER;
"reiserfs_open: a superblock with wrong parameters "
"was found in the block (%d).\n", i);
freemem(fs); freemem(fs);
close(fd); close(fd);
brelse(bh); brelse(bh);
@@ -135,12 +127,7 @@ found:
get_sb_block_size(sb)); get_sb_block_size(sb));
if (!tmp_bh) { if (!tmp_bh) {
reiserfs_warning(stderr, *error = REISERFS_ET_SMALL_PARTITION;
"\n%s: Your partition is not big enough to contain the \n"
"filesystem of (%lu) blocks as was specified in the found super block.\n",
__FUNCTION__,
get_sb_block_count(sb) - 1);
freemem(fs); freemem(fs);
close(fd); close(fd);
brelse(bh); brelse(bh);
@@ -158,9 +145,7 @@ found:
brelse(bh); brelse(bh);
bh = bread(fd, i, fs->fs_blocksize); bh = bread(fd, i, fs->fs_blocksize);
if (!bh) { if (!bh) {
reiserfs_warning(stderr, *error = REISERFS_ET_BREAD_FAILED;
"reiserfs_open: bread failed reading block %d, size %d\n",
i, fs->fs_blocksize);
freemem(fs); freemem(fs);
return NULL; return NULL;
} }
@@ -189,32 +174,32 @@ reiserfs_filsys_t reiserfs_create(const char *filename,
int version, int version,
unsigned long block_count, unsigned long block_count,
int block_size, int block_size,
int default_journal, int new_format) int default_journal, int new_format,
long *error)
{ {
reiserfs_filsys_t fs; reiserfs_filsys_t fs;
time_t now; time_t now;
unsigned int bmap_nr = reiserfs_bmap_nr(block_count, block_size);; unsigned int bmap_nr = reiserfs_bmap_nr(block_count, block_size);;
*error = 0;
/* convert root dir key and parent root dir key to little endian format */ /* convert root dir key and parent root dir key to little endian format */
make_const_keys(); make_const_keys();
if (count_blocks(filename, block_size) < block_count) { if (count_blocks(filename, block_size) < block_count) {
reiserfs_warning(stderr, *error = REISERFS_ET_NOT_ENOUGH_BLOCKS;
"reiserfs_create: no enough blocks on device\n");
return NULL; return NULL;
} }
if (!is_block_count_correct(REISERFS_DISK_OFFSET_IN_BYTES / block_size, if (!is_block_count_correct(REISERFS_DISK_OFFSET_IN_BYTES / block_size,
block_size, block_count, 0)) { block_size, block_count, 0)) {
reiserfs_warning(stderr, *error = REISERFS_ET_TOO_SMALL;
"reiserfs_create: can not create that small "
"(%u blocks) filesystem\n", block_count);
return NULL; return NULL;
} }
fs = getmem(sizeof(*fs)); fs = getmem(sizeof(*fs));
if (!fs) { if (!fs) {
reiserfs_warning(stderr, "reiserfs_create: getmem failed\n"); *error = errno;
return NULL; return NULL;
} }
@@ -224,15 +209,13 @@ reiserfs_filsys_t reiserfs_create(const char *filename,
#endif #endif
); );
if (fs->fs_dev == -1) { if (fs->fs_dev == -1) {
reiserfs_warning(stderr, *error = errno;
"reiserfs_create: could not open %s: %s\n",
filename, strerror(errno));
freemem(fs); freemem(fs);
return NULL; return NULL;
} }
fs->fs_blocksize = block_size; fs->fs_blocksize = block_size;
asprintf(&fs->fs_file_name, "%s", filename); xasprintf(&fs->fs_file_name, "%s", filename);
fs->fs_format = version; fs->fs_format = version;
if (new_format) if (new_format)
@@ -245,7 +228,7 @@ reiserfs_filsys_t reiserfs_create(const char *filename,
block_size, block_size); block_size, block_size);
if (!fs->fs_super_bh) { if (!fs->fs_super_bh) {
reiserfs_warning(stderr, "reiserfs_create: getblk failed\n"); *error = REISERFS_ET_GETBLK_FAILED;
return NULL; return NULL;
} }
@@ -420,8 +403,13 @@ void reiserfs_close(reiserfs_filsys_t fs)
reiserfs_close_ondisk_bitmap(fs); reiserfs_close_ondisk_bitmap(fs);
reiserfs_flush(fs); reiserfs_flush(fs);
reiserfs_free(fs); /* fsync must run while fs is still valid: reiserfs_free() releases
the handler, and reading fs->fs_dev after it was a use-after-free.
reiserfs_flush() has already written the journal and every dirty
buffer (free_buffers() inside reiserfs_free only validates and
frees), so the data is on the device by this point. */
fsync(fs->fs_dev); fsync(fs->fs_dev);
reiserfs_free(fs);
} }
int reiserfs_new_blocknrs(reiserfs_filsys_t fs, int reiserfs_new_blocknrs(reiserfs_filsys_t fs,
@@ -681,7 +669,7 @@ struct reiserfs_key *uget_rkey(const struct reiserfs_path *path)
struct reiserfs_key *reiserfs_next_key(const struct reiserfs_path *path) struct reiserfs_key *reiserfs_next_key(const struct reiserfs_path *path)
{ {
if (get_item_pos(path) < B_NR_ITEMS(get_bh(path)) - 1) if (get_item_pos(path) + 1 < B_NR_ITEMS(get_bh(path)))
return leaf_key(get_bh(path), get_item_pos(path) + 1); return leaf_key(get_bh(path), get_item_pos(path) + 1);
return uget_rkey(path); return uget_rkey(path);
@@ -1071,7 +1059,7 @@ int reiserfs_add_entry(reiserfs_filsys_t fs, const struct reiserfs_key *dir,
const char *name, int name_len, const char *name, int name_len,
const struct reiserfs_key *key, __u16 fsck_need) const struct reiserfs_key *key, __u16 fsck_need)
{ {
struct item_head entry_ih = { {0,}, }; struct item_head entry_ih = { 0 };
char *entry; char *entry;
int retval; int retval;
INITIALIZE_REISERFS_PATH(path); INITIALIZE_REISERFS_PATH(path);
@@ -1475,7 +1463,7 @@ void add_badblock_list(reiserfs_filsys_t fs, int replace)
} }
int reiserfs_iterate_file_data(reiserfs_filsys_t fs, int reiserfs_iterate_file_data(reiserfs_filsys_t fs,
const struct reiserfs_key const *short_key, const struct reiserfs_key *short_key,
reiserfs_file_iterate_indirect_fn indirect_fn, reiserfs_file_iterate_indirect_fn indirect_fn,
reiserfs_file_iterate_direct_fn direct_fn, reiserfs_file_iterate_direct_fn direct_fn,
void *data) void *data)
@@ -1572,7 +1560,7 @@ fail:
} }
int reiserfs_iterate_dir(reiserfs_filsys_t fs, int reiserfs_iterate_dir(reiserfs_filsys_t fs,
const struct reiserfs_key const *dir_short_key, const struct reiserfs_key *dir_short_key,
const reiserfs_iterate_dir_fn callback, void *data) const reiserfs_iterate_dir_fn callback, void *data)
{ {
INITIALIZE_REISERFS_PATH(path); INITIALIZE_REISERFS_PATH(path);
@@ -1647,3 +1635,8 @@ fail:
pathrelse(&path); pathrelse(&path);
return ret; return ret;
} }
void __attribute__ ((constructor)) init(void)
{
initialize_reiserfs_error_table();
}
-1
View File
@@ -1,7 +1,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <sys/acl.h>
#include "reiserfs_lib.h" #include "reiserfs_lib.h"
static inline unsigned short from32to16(unsigned int x) static inline unsigned short from32to16(unsigned int x)
+1 -1
View File
@@ -1,4 +1,4 @@
%define reiserfsprogsversion 3.6.23 %define reiserfsprogsversion 3.6.25
Vendor: Hans Reiser Vendor: Hans Reiser
Distribution: Hans Reiser Distribution: Hans Reiser
+1 -1
View File
@@ -102,7 +102,7 @@ with a
.br .br
\ umount /mnt \ umount /mnt
.br .br
\ resize_reiserfs -s -1G /dev/hda8 \ resize_reiserfs \-s \-1G /dev/hda8
.br .br
\ mount /dev/hda8 /mnt \ mount /dev/hda8 /mnt
.br .br
+7 -4
View File
@@ -48,9 +48,11 @@ static long long int calc_new_fs_size(unsigned long count,
case 'G': case 'G':
case 'g': case 'g':
bytes *= 1024; bytes *= 1024;
/* fall through */
case 'M': case 'M':
case 'm': case 'm':
bytes *= 1024; bytes *= 1024;
/* fall through */
case 'K': case 'K':
case 'k': case 'k':
bytes *= 1024; bytes *= 1024;
@@ -58,7 +60,7 @@ static long long int calc_new_fs_size(unsigned long count,
blocks = bytes / bs; blocks = bytes / bs;
return rel ? count + blocks : blocks; return rel ? (long long int)count + blocks : blocks;
} }
/* print some fs parameters */ /* print some fs parameters */
@@ -191,7 +193,7 @@ int main(int argc, char *argv[])
struct reiserfs_super_block *sb; struct reiserfs_super_block *sb;
int c; int c;
int error; long error;
struct reiserfs_super_block *sb_old; struct reiserfs_super_block *sb_old;
@@ -215,6 +217,7 @@ int main(int argc, char *argv[])
reiserfs_exit(1, reiserfs_exit(1,
"Missing argument to -j option"); "Missing argument to -j option");
jdevice_name = optarg; jdevice_name = optarg;
break;
case 'f': case 'f':
opt_force = 1; opt_force = 1;
break; break;
@@ -253,7 +256,7 @@ int main(int argc, char *argv[])
if (!fs) { if (!fs) {
if (error) { if (error) {
reiserfs_exit(1, "cannot open '%s': %s", reiserfs_exit(1, "cannot open '%s': %s",
devname, strerror(error)); devname, error_message(error));
} else { } else {
exit(1); exit(1);
} }
@@ -292,7 +295,7 @@ int main(int argc, char *argv[])
block_count_new = bytes_count_str ? block_count_new = bytes_count_str ?
calc_new_fs_size(get_sb_block_count(sb), calc_new_fs_size(get_sb_block_count(sb),
fs->fs_blocksize, bytes_count_str) : fs->fs_blocksize, bytes_count_str) :
count_blocks(devname, fs->fs_blocksize); (long long int)count_blocks(devname, fs->fs_blocksize);
if (resizer_check_fs_size(fs, block_count_new)) if (resizer_check_fs_size(fs, block_count_new))
return 1; return 1;
+106
View File
@@ -0,0 +1,106 @@
# Ambiente de testes em VM
Este documento descreve o ambiente de validação do reiserfsprogs em máquinas
virtuais (libvirt/KVM), usado para exercitar o build e as ferramentas em
distribuições diferentes da máquina de desenvolvimento.
O ambiente é **efêmero**: as VMs ficam em `/var/tmp/vmtest` e não fazem parte
do repositório. Os scripts que o reproduzem estão em `tests/vm/`.
## Requisitos do host
| Componente | Verificação |
|---|---|
| KVM | `ls -l /dev/kvm` |
| libvirt (user session) | `virsh -c qemu:///session list --all` |
| `virt-install`, `qemu-img` | `which virt-install qemu-img` |
| `guestfs-tools` (offline) | `which virt-customize` |
| `mkisofs` ou `xorriso` | `which mkisofs xorriso` |
No Fedora: `sudo dnf install libvirt-daemon-kvm qemu-kvm virt-install
guestfs-tools genisoimage`.
O ambiente usa **qemu:///session** (sem root). Não requer a rede `default`
do libvirt: a conectividade vem do backend `passt` em modo *user*.
## Topologia
```mermaid
graph LR
H[host] -->|qemu:///session| D[rfs-debian<br/>Debian 12 · gcc + clang]
H -->|qemu:///session| A[rfs-alpine<br/>Alpine 3.20 · gcc/musl]
D -->|passt :2222| S[ssh opcional]
A -->|passt| S
H -->|attach-disk| V[vdb: fontes + run_tests.sh]
```
Cada VM recebe:
* imagem cloud (qcow2) redimensionada para 8 GiB;
* um disco de dados `vdb` (ext4) com `rfs-src.tar.gz` e `run_tests.sh`;
* acesso por **console serial** (pty do libvirt), que é o canal de
automação usado — independente de rede.
## Por que console serial e não SSH
Nas imagens cloud o `sshd` demora a subir e o `cloud-init` nem sempre aplica
a senha (o datasource NoCloud exige rótulo `cidata` e o CD precisa estar no
Barramento certo). O console serial está disponível assim que o getty sobe e
é suficiente para: autenticar, copiar arquivos (já estão no `vdb`) e rodar
qualquer comando. Por isso o `tests/vm/guestcmd.py` dirige o pty.
## Ciclo de uso
```sh
cd tests/vm
# 1. preparar imagens e VMs (uma vez)
./setup_env.sh
# 2. rodar a bateria em uma VM
./run_in_vm.sh rfs-debian # gcc do guest
CC=clang ./run_in_vm.sh rfs-debian # clang do guest
./run_in_vm.sh rfs-alpine # esperado FALHAR no configure (musl)
# 3. destruir tudo
./teardown_env.sh
```
No Debian, instale o clang no guest uma vez (a rede user-mode do `passt`
precisa de resolver manual antes do apt):
```sh
python3 guestcmd.py rfs-debian 'ip addr add 192.168.1.5/24 dev enp1s0;
ip link set enp1s0 up; ip route add default via 192.168.1.1;
echo nameserver 8.8.8.8 > /etc/resolv.conf;
apt-get update -qq && DEBIAN_FRONTEND=noninteractive \
apt-get install -y -qq clang'
```
## Compiladores suportados
O projeto compila **sem warnings** com `-Wall -Wextra` em gcc (>= 12) e
clang (>= 14; validado em 14.0.6 e 22.1.8). Os mesmos builds são exercitados
sob **AddressSanitizer + UndefinedBehaviorSanitizer** (`CC=clang
CFLAGS="-g -O1 -fsanitize=address,undefined ..."`) tanto no host (CI) quanto
manualmente; resultados em `RESULTS.md`.
## O que a bateria cobre (`tests/vm/run_tests.sh`)
Executado **dentro** do guest, sobre o código extraído do `vdb`:
1. `autogen.sh && configure --enable-warnings && make -j` — build limpo;
2. contagem de warnings (esperado: 0);
3. `mkreiserfs` em imagem de 64 MiB;
4. `reiserfsck --check` (esperado: *No corruptions found*);
5. `debugreiserfs -S` (superblock consistente);
6. `reiserfstune -l` (troca de label);
7. `resize_reiserfs` 128 MiB → 256 MiB;
8. `reiserfsck` pós-resize;
9. rollback: `-R` grava, `--rollback-fsck-changes` restaura, arquivo
inválido é rejeitado.
## Resultados obtidos
Ver `tests/vm/RESULTS.md`.
+208
View File
@@ -0,0 +1,208 @@
# Resultados dos testes em VM
Bateria executada com `tests/vm/run_in_vm.sh` em duas distribuições, ambas em
KVM (`qemu:///session`), com o código de `293e6a7`.
## Ambiente
| | Debian 12 (bookworm) | Alpine 3.20.3 |
|---|---|---|
| Kernel | 6.1.0-54-cloud-amd64 | 6.6.49-0-virt |
| libc | glibc 2.36 | **musl 1.2.5** |
| gcc | 12.2.0 | 13.2.1 |
| init | systemd + cloud-init | OpenRC + cloud-init |
## Resultado por item
| # | Teste | Debian | Alpine |
|---|---|---|---|
| 1 | `autogen.sh` | passa | passa |
| 1 | `configure --enable-warnings` | passa | **falha** (ver abaixo) |
| 1 | `make -j` | passa, **0 warnings** | não alcançado |
| 2 | `mkreiserfs` | passa | não alcançado |
| 3 | `reiserfsck --check` | passa | não alcançado |
| 4 | `debugreiserfs -S` | passa | não alcançado |
| 5 | `reiserfstune -l` | passa | não alcançado |
| 6 | `resize_reiserfs` 128→256 MiB | passa | não alcançado |
| 7 | `fsck` pós-resize | passa | não alcançado |
| 8 | rollback: grava | passa | não alcançado |
| 8 | rollback: restaura | passa | não alcançado |
| 8 | rollback: magic inválida rejeitada | passa | não alcançado |
| 8 | rollback: arquivo inexistente rejeitado | passa | não alcançado |
**Debian: 12/12.** Alpine: bloqueado no item 1.
## Achado 1 (bloqueante): não compila em musl
O `configure` do Alpine falha com:
```
checking for register_printf_modifier... no
checking for register_printf_specifier... no
configure: error: reiserfsprogs requires a method to add printf modifiers
```
Causa: `reiserfscore/prints.c` usa `register_printf_specifier(3)`, extensão
**glibc-only** (`<printf.h>`). O musl não fornece `printf.h` nem essas
funções. O `configure.ac` trata isso como erro fatal explícito — o
comportamento é correto, mas o projeto **não compila fora da glibc**.
Alcance medido:
| Especificador | Uso |
|---|---|
| `%k` | 139 |
| `%K` | 106 |
| `%H` | 52 |
| `%M` | 25 |
| `%b` | 9 |
| `%U` | 4 |
| `%y` | 2 |
| `%30H`, `%20y`, `%20k`, `%20K` | 4 |
| **total** | **341** |
Todos passam por `reiserfs_warning()` / `reiserfs_info()`. Portar exigiria
substituir o mecanismo por funções de formatação explícitas (por exemplo
`char *format_key(const struct reiserfs_key *)` com `%s`), uma mudança de API
interna ampla — não um ajuste local.
**Impacto prático**: reiserfsprogs fica restrito à glibc. Como o único uso
atual da ferramenta é resgate de dados, isso importa: live images de
recuperação baseadas em Alpine/musl não conseguem compilar o projeto.
## Achado 2 (corrigido nesta rodada): warning real no gcc 12
O gcc 12.2 do Debian acusou, duas vezes:
```
../include/reiserfs_fs.h:63:54: warning: ‘relocated_ih’ may be used uninitialized
```
O gcc 16 do host não acusa. Investigação:
* `fsck/semantic_check.c:620` passa `&relocated_ih` para
`check_semantic_pass()`;
* o bloco que escreveria `*new_ih` está **comentado** (linhas 471–486);
* a chamada em `check_check_regular_file()` (linha 466) passa
`NULL` como `new_ih`, com o comentário `/* relocate ? new_ih : */ NULL`;
* portanto `RELOCATED` nunca é retornado por esse caminho e
`case RELOCATED:` (linha 665) leria `relocated_ih` não inicializado.
Não é alcançável hoje, mas é uma leitura potencial de lixo de pilha atrás de
um `#case` que o compilador não consegue descartar. Correção: inicialização
explícita `= { 0 }` com comentário explicando por que permanece zero.
Verificado: **0 warnings no gcc 12.2 após a correção**.
Em `fsck/semantic_rebuild.c` o caminho equivalente é seguro: o bloco
`if (relocate) { ... *new_ih = *ih; retval = RELOCATED; }` está ativo
(linhas 808–822), então `new_ih` é escrito antes do `case RELOCATED:`
(linha 999).
## Validação com clang
Ferramentaria: Fedora 44 (host) com **clang 22.1.8**, Debian 12 na VM com
**clang 14.0.6**. Todos os builds abaixo usam `--enable-warnings`
(-Wall -Wextra).
| Build | Resultado |
|---|---|
| host clang in-tree, -j | 0/5 falhas, **0 warnings** |
| host clang out-of-tree, -j | passa, 0 warnings |
| host clang + ASan/UBSan out-of-tree, -j | 0/3 falhas, 0 warnings |
| host gcc out-of-tree, -j | 3/3 limpo |
| host `make distcheck` | passa (VPATH + install/uninstall + tarballs) |
| VM Debian clang 14.0.6, bateria completa | **12/12, 0 warnings** |
### O que clang expôs (e foi corrigido)
1. **Corrida de build paralela em `compile_et`** (`reiserfscore/Makefile.am`):
`reiserfs_err.c` e `reiserfs_err.h` eram alvos de UMA mesma receita; com
`-j` o make executa a receita duas vezes em paralelo e um processo apaga
o `.c` enquanto o outro compila → `clang: error: no input files`.
Reproduzido com clang+ASan; a correção vale para qualquer compilador.
A receita ficou atrelada apenas a `reiserfs_err.c`, e
`reiserfs_err.h: reiserfs_err.c` apenas ordena os dois. 5/5 builds
paralelos limpos após a correção.
2. **Build out-of-tree quebrado** (pré-existente, também com gcc): a regra
referenciava `reiserfs_err.et` sem `$(srcdir)/`. Corrigido junto.
3. **`-Waddress-of-packed-member`** (só o clang aponta; 3 sítios):
`fsck/semantic_check.c` e `fsck/semantic_rebuild.c` passavam
`&tmp_deh->deh2_dir_id` como argumento `%K`, que espera
`struct reiserfs_key *`. Funcionava por coincidência de offsets
(`deh2_dir_id` em 4 lido como `k2_dir_id` em 0 do cast). Agora montam uma
`reiserfs_key` local via `set_key_dirid`/`set_key_objectid` — saída
idêntica, sem depender de coincidência.
4. **`-Wnull-dereference` em `reiserfscore/hashes.c`**: quatro stores mortos
`*(int *)0 = 0` protegidos por condições inalcançáveis (após o loop
`while (len >= 16)`, `len <= 15`; os ramos testavam `len >= 16/12/8/4`).
Removidos. Comportamento verificado: saída de `keyed_hash`, `yura_hash` e
`r5_hash` para 16 entradas (vazio a 17 bytes) **byte a byte idêntica**
antes e depois (diff vazio).
5. **heap-use-after-free real, encontrado por ASan com clang**:
`reiserfs_close()` chamava `fsync(fs->fs_dev)` DEPOIS de
`reiserfs_free()` liberar `fs` — leitura pendente de 4 bytes em
memória libertada (o ASan apontou exatamente `reiserfslib.c:406/407`; o
gcc nunca acusou porque o heap ainda "devolve" o valor velho). Corrigido
movendo o `fsync` para antes do free — a escrita já está no dispositivo
neste ponto (`reiserfs_flush()` despeja journal e buffers; os
`free_buffers()` de `reiserfs_free()` apenas validam e libertam, sem
escrever).
6. **segundo heap-use-after-free, também no caminho de rollback**
(`fsck/main.c:1313`, `fsck_rollback()`): a função fazia `freemem(fs)` e
depois imprimia o banner final via `fsck_progress(...)`, que
desreferencia `fs` (`fsck_data(fs)` etc.). Capturado por ASan em uma
reexecução explícita do `--rollback-fsck-changes` com `halt_on_error`
(a rodada inicial de smoke não exercitou esse ramo até o fim).
Corrigido: o banner é impresso antes da limpeza, na mesma ordem usada
por `the_end()` e pelos caminhos de rebuild. Revalidado: save, restore,
rejeição de magic inválida e resize sob ASan+UBSan com `halt_on_error=1`
— **zero erros**, saída funcional inalterada.
Ambos os builds saneados (mkfs, check, tune, debugreiserfs, resize
64→128 MiB e rollback completo) passam com **zero erros**; a bateria
completa no host gcc continua 12/12.
### Não-bugs registrados
- LeakSanitizer: 136 bytes, 1 alocação em `debugreiserfs` (`getmem` no
`main`, de vida de processo; o `exit` recolhe). Aceitável para
ferramenta one-shot; por isso o job de CI com sanitizadores roda com
`detect_leaks=0`.
- `AddressSanitizer: WARNING: unexpected format specifier ... %U`: o
interceptor do ASan não conhece os especificadores customizados do
projeto. Informativo, uma vez por processo.
## Achado 3: limitação do ambiente (não do código)
Nas imagens cloud o `cloud-init` não aplicou a senha do usuário: o datasource
NoCloud exige o rótulo `cidata` e o CD correto, e o `sshd` demora a subir.
O console serial, porém, fica disponível assim que o getty sobe — por isso o
`tests/vm/guestcmd.py` dirige o pty e é o canal de automação usado. Isso não
afeta o produto; afeta apenas como os testes são conduzidos.
Além disso, a rede user-mode (`passt`) não entrega DHCP nem DNS por padrão: a
interface sobe como `enp1s0` mas fica sem IP. Foi necessário configurar IP e
resolver manualmente para instalar pacotes nas VMs.
## Como reproduzir
```sh
cd tests/vm
./setup_env.sh # imagens + VMs (uma vez)
./run_in_vm.sh rfs-debian # gcc: build + bateria completa
CC=clang ./run_in_vm.sh rfs-debian # clang no guest (instalar antes: ver README)
./run_in_vm.sh rfs-alpine # deve falhar no configure (esperado)
./teardown_env.sh
# host: builds paralelos in-tree e out-of-tree, distcheck
make distcheck
CC=clang ./configure --enable-warnings && make -j"$(nproc)"
```
Detalhes do ambiente, topologia e limitações: `tests/vm/README.md`.
+126
View File
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""Roda um comando no guest atraves do console serial do libvirt.
O console serial e o unico canal garantido nas imagens cloud minimas: nao
depende de sshd, de cloud-init nem de rede. Este script sincroniza com o
prompt, autentica (root/rfstest) e executa o comando, lendo a saida do pty
em blocos pequenos para evitar a sobreposicao de eco que ocorre em comandos
longos.
Uso:
guestcmd.py <dominio> '<comando>'
guestcmd.py <dominio> -f <arquivo> # executa um script local
"""
import base64
import os
import re
import select
import subprocess
import sys
import time
USER = "root"
PASSWORD = "rfstest"
def console_pty(domain):
xml = subprocess.run(["virsh", "dumpxml", domain],
capture_output=True, text=True).stdout
m = (re.search(r"<console[^>]*>\s*<source path='([^']+)'", xml)
or re.search(r"<serial[^>]*>\s*<source path='([^']+)'", xml))
if not m:
sys.exit(f"console serial nao encontrada para {domain}")
return m.group(1)
class Console:
def __init__(self, path):
self.fd = os.open(path, os.O_RDWR | os.O_NOCTTY)
def send(self, s):
os.write(self.fd, s.encode())
def drain(self, seconds):
buf = b""
end = time.time() + seconds
while time.time() < end:
r, _, _ = select.select([self.fd], [], [], 0.3)
if not r:
continue
try:
chunk = os.read(self.fd, 65536)
except OSError:
break
if not chunk:
break
buf += chunk
return buf
def login(self):
self.send("\n")
time.sleep(1.0)
snap = self.drain(2.5).decode(errors="replace").lower()
if "login:" not in snap:
return # ja autenticado
self.send(USER + "\n")
self.drain(3.0)
self.send(PASSWORD + "\n")
time.sleep(2.0)
self.drain(2.0)
def run(self, command, timeout=120.0):
"""Executa e devolve a saida, sincronizando por marcador no pty."""
out_path = "/tmp/.guestcmd.out"
self.send(f"rm -f {out_path}; ( {command} ) > {out_path} 2>&1; "
f"echo __GC_DONE__\n")
deadline = time.time() + timeout
while time.time() < deadline:
if b"__GC_DONE__" in self.drain(2.0):
break
else:
return "(timeout)\n"
# tamanho em bytes
self.send(f"wc -c < {out_path}\n")
time.sleep(1.2)
raw = self.drain(2.0).decode(errors="replace")
nums = re.findall(r"\d+", raw)
size = int(nums[-1]) if nums else 0
# ler em blocos base64 (evita eco/sobreposicao)
data = b""
while len(data) < size:
self.send(f"dd if={out_path} bs=1 skip={len(data)} count=150 "
f"2>/dev/null | base64 -w0; echo\n")
time.sleep(0.8)
enc = self.drain(2.0).decode(errors="replace")
token = "".join(re.findall(r"[A-Za-z0-9+/=]{4,}", enc))
if not token:
break
try:
data += base64.b64decode(token + "=" * (-len(token) % 4))
except Exception:
break
return data.decode(errors="replace")
def main():
if len(sys.argv) < 3:
sys.exit(__doc__)
domain = sys.argv[1]
console = Console(console_pty(domain))
console.login()
if sys.argv[2] == "-f":
with open(sys.argv[3]) as fh:
script = fh.read().replace("'", "'\\''")
command = f"sh -c '{script}'"
else:
command = sys.argv[2]
sys.stdout.write(console.run(command))
sys.stdout.write("\n")
if __name__ == "__main__":
main()
+58
View File
@@ -0,0 +1,58 @@
#!/bin/sh
# Envia o codigo-fonte e o script de teste para dentro de uma VM e executa.
#
# Uso: run_in_vm.sh <dominio>
# CC=clang run_in_vm.sh rfs-debian # build no guest com clang
# Requer: guestcmd.py (mesmo diretorio), mkisofs, libvirt, sudo (loop mount).
set -e
DOMAIN=${1:?uso: run_in_vm.sh <dominio>}
HERE=$(cd "$(dirname "$0")" && pwd)
REPO=$(cd "$HERE/../.." && pwd)
WORK=${WORK:-/var/tmp/vmtest}
echo "== empacotando o codigo-fonte =="
tar czf "$WORK/rfs-src.tar.gz" -C "$REPO" \
--exclude=.git --exclude='*.o' --exclude='*.lo' --exclude='*.la' \
--exclude='.libs' --exclude=build-aux --exclude=m4 \
--exclude=autom4te.cache --exclude=config.h --exclude=config.log \
--exclude=config.status --exclude=libtool \
--exclude='Makefile' --exclude='Makefile.in' --exclude=configure \
--exclude=aclocal.m4 --exclude='*.8' --exclude=stamp-h1 \
--exclude='reiserfscore/reiserfs_err.c' \
--exclude='reiserfscore/reiserfs_err.h' \
.
echo "== montando o disco de dados =="
rm -rf /tmp/vmdata.$$ && mkdir -p /tmp/vmdata.$$
sudo mount -o loop "$WORK/data.img" /tmp/vmdata.$$
sudo cp "$WORK/rfs-src.tar.gz" "$HERE/run_tests.sh" /tmp/vmdata.$$
sync
sudo umount /tmp/vmdata.$$ && rmdir /tmp/vmdata.$$
echo "== transferindo para $DOMAIN =="
ATTACH=/tmp/vdb.$$.xml
cat > "$ATTACH" <<EOF
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='$WORK/data.img'/>
<target dev='vdb' bus='virtio'/>
</disk>
EOF
virsh attach-device "$DOMAIN" "$ATTACH" --live >/dev/null 2>&1 || true
rm -f "$ATTACH"
echo "== extraindo e rodando os testes ${CC:+com CC=$CC} =="
"$HERE/guestcmd.py" "$DOMAIN" "
set -e
mkdir -p /mnt/data
# remount forcado: o host trocou o conteudo do disco por baixo do guest
umount /mnt/data 2>/dev/null || true
mount -o ro /dev/vdb /mnt/data
rm -rf /root/rfs
mkdir -p /root/rfs
tar xzf /mnt/data/rfs-src.tar.gz -C /root/rfs
cp /mnt/data/run_tests.sh /root/run_tests.sh
chmod +x /root/run_tests.sh
SRC=/root/rfs ${CC:+CC=$CC }sh /root/run_tests.sh
" 1800
+135
View File
@@ -0,0 +1,135 @@
#!/bin/sh
# Bateria de testes do reiserfsprogs, executada DENTRO do guest.
# Espera receber o codigo-fonte em $SRC (padrao: /root/rfs).
#
# Uso (dentro da VM):
# SRC=/root/rfs sh run_tests.sh
set -u
SRC=${SRC:-/root/rfs}
PASS=0
FAIL=0
ok() { echo "PASS: $1"; PASS=$((PASS + 1)); }
bad() { echo "FAIL: $1"; FAIL=$((FAIL + 1)); }
cd "$SRC" || { echo "FAIL: $SRC nao existe"; exit 1; }
echo "=== ambiente ==="
uname -srm
echo "CC=${CC:-cc}"
${CC:-cc} --version 2>/dev/null | head -1 || echo "sem ${CC:-cc}"
ldd --version 2>&1 | head -1
echo
echo "=== 1. bootstrap + build com -Wall -Wextra ==="
make distclean >/dev/null 2>&1
if ./autogen.sh >/tmp/ag.log 2>&1 && ./configure --enable-warnings >/tmp/cfg.log 2>&1 \
&& make -j"$(nproc 2>/dev/null || echo 2)" >/tmp/mk.log 2>&1; then
ok "autogen.sh + configure + make"
else
bad "build"
echo "--- configure ---"; tail -15 /tmp/cfg.log
echo "--- make ---"; tail -25 /tmp/mk.log
echo
echo "RESULTADO: $PASS passaram, $FAIL falharam"
exit 1
fi
# grep -c retorna 1 quando nao ha ocorrencias; capturar so a primeira linha
WARN=$(grep -c "warning:" /tmp/mk.log 2>/dev/null | head -1)
WARN=${WARN:-0}
if [ "$WARN" = "0" ]; then
ok "0 warnings com -Wall -Wextra"
else
bad "$WARN warnings"
grep "warning:" /tmp/mk.log | head -10
fi
echo
echo "=== 2. mkfs ==="
rm -f /tmp/t.img
dd if=/dev/zero of=/tmp/t.img bs=1M count=64 status=none 2>/dev/null
if ./mkreiserfs/mkreiserfs -f -q -l TESTVOL /tmp/t.img >/dev/null 2>&1; then
ok "mkreiserfs"
else
bad "mkreiserfs"
fi
echo
echo "=== 3. reiserfsck --check ==="
if ./fsck/reiserfsck --check -f -q -y /tmp/t.img 2>&1 | grep -q "No corruptions found"; then
ok "reiserfsck --check"
else
bad "reiserfsck --check"
fi
echo
echo "=== 4. debugreiserfs -S ==="
if ./debugreiserfs/debugreiserfs -S /tmp/t.img 2>&1 | grep -q "Filesystem state: consistent"; then
ok "debugreiserfs -S"
else
bad "debugreiserfs -S"
fi
echo
echo "=== 5. reiserfstune -l ==="
if ./tune/reiserfstune -l NEWLABEL -f /tmp/t.img >/dev/null 2>&1; then
ok "reiserfstune -l"
else
bad "reiserfstune -l"
fi
echo
echo "=== 6. resize 128M -> 256M ==="
rm -f /tmp/big.img
dd if=/dev/zero of=/tmp/big.img bs=1M count=128 status=none 2>/dev/null
./mkreiserfs/mkreiserfs -f -q /tmp/big.img >/dev/null 2>&1
truncate -s 256M /tmp/big.img
if ./resize_reiserfs/resize_reiserfs -s +128M -f /tmp/big.img 2>&1 \
| grep -q "Resizing finished successfully"; then
ok "resize_reiserfs"
else
bad "resize_reiserfs"
fi
echo
echo "=== 7. fsck pos-resize ==="
if ./fsck/reiserfsck --check -f -q -y /tmp/big.img 2>&1 | grep -q "No corruptions found"; then
ok "fsck apos resize"
else
bad "fsck apos resize"
fi
echo
echo "=== 8. rollback (save/restore/reject) ==="
cp /tmp/t.img /tmp/rb.img
rm -f /tmp/rb.dat
./fsck/reiserfsck --fix-fixable -y -q -R /tmp/rb.dat /tmp/rb.img >/dev/null 2>&1
if [ -f /tmp/rb.dat ]; then
ok "rollback file criado"
else
bad "rollback file nao criado"
fi
if ./fsck/reiserfsck --rollback-fsck-changes -y -q -R /tmp/rb.dat /tmp/rb.img 2>&1 \
| grep -q "blocks restored"; then
ok "rollback-fsck-changes"
else
bad "rollback-fsck-changes"
fi
head -c 100 /dev/urandom > /tmp/rollback-invalido.dat
if ./fsck/reiserfsck --rollback-fsck-changes -y -q -R /tmp/rollback-invalido.dat /tmp/rb.img 2>&1 \
| grep -q "does not look like a rollback file"; then
ok "rollback com magic invalida rejeitado"
else
bad "rollback com magic invalida aceito"
fi
if ./fsck/reiserfsck --rollback-fsck-changes -y -q -R /tmp/nao-existe.dat /tmp/rb.img 2>&1 \
| grep -q "Cannot stat rollback file"; then
ok "rollback inexistente rejeitado"
else
bad "rollback inexistente aceito"
fi
echo
echo "RESULTADO: $PASS passaram, $FAIL falharam"
[ "$FAIL" -eq 0 ]
+91
View File
@@ -0,0 +1,91 @@
#!/bin/sh
# Prepara o ambiente de VMs: imagens, seed e maquinas virtuais.
# Requer: libvirt (qemu:///session), virt-install, qemu-img, mkisofs.
set -e
HERE=$(cd "$(dirname "$0")" && pwd)
WORK=${WORK:-/var/tmp/vmtest}
CONN=qemu:///session
mkdir -p "$WORK"
cd "$WORK"
fetch() {
url=$1; out=$2
[ -s "$out" ] && { echo " $out ja existe"; return; }
echo " baixando $out"
curl -fsSL -o "$out.part" "$url"
mv "$out.part" "$out"
}
echo "== imagens =="
fetch https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2 debian.qcow2
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/cloud/nocloud_alpine-3.20.3-x86_64-bios-cloudinit-r0.qcow2 alpine.qcow2
echo "== redimensionando =="
for img in debian.qcow2 alpine.qcow2; do
size=$(qemu-img info --output=json "$img" | grep -oP '"virtual-size":\s*\K[0-9]+')
if [ "${size:-0}" -lt 8589934592 ]; then
qemu-img resize "$img" 8G
else
echo " $img ja tem 8G"
fi
done
echo "== disco de dados (fontes + script de teste) =="
if [ ! -s data.img ]; then
dd if=/dev/zero of=data.img bs=1M count=8 status=none
mkfs.ext4 -q -F data.img
fi
echo "== seed cloud-init =="
cat > user-data <<'EOF'
#cloud-config
hostname: rfs-test
ssh_pwauth: true
disable_root: false
users:
- name: root
lock_passwd: false
plain_text_passwd: rfstest
chpasswd:
expire: false
EOF
cat > meta-data <<'EOF'
instance-id: rfs-test-1
local-hostname: rfs-test
EOF
cat > network-config <<'EOF'
version: 2
ethernets:
eth0:
dhcp4: true
EOF
rm -f seed.iso
mkisofs -output seed.iso -volid cidata -joliet -rock \
user-data meta-data network-config >/dev/null 2>&1
echo "== definindo VMs =="
define_vm() {
name=$1; img=$2; variant=$3; mem=$4
if virsh -c "$CONN" dominfo "$name" >/dev/null 2>&1; then
echo " $name ja existe"
return
fi
virt-install -c "$CONN" \
--name "$name" \
--memory "$mem" --vcpus 2 \
--disk "path=$WORK/$img,format=qcow2,bus=virtio" \
--disk "path=$WORK/seed.iso,device=cdrom" \
--os-variant "$variant" \
--network user,model=virtio \
--graphics none --console pty \
--import --noautoconsole >/dev/null
echo " criada: $name"
}
define_vm rfs-debian debian.qcow2 debian12 2048
define_vm rfs-alpine alpine.qcow2 alpinelinux3.20 1024
echo
echo "Pronto. Use tests/vm/run_in_vm.sh <vm> para testar."
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
# Destrói as VMs do ambiente de teste. Nao remove as imagens baixadas.
set -e
CONN=qemu:///session
for d in rfs-debian rfs-alpine; do
if virsh -c "$CONN" dominfo "$d" >/dev/null 2>&1; then
virsh -c "$CONN" destroy "$d" >/dev/null 2>&1 || true
virsh -c "$CONN" undefine "$d" --remove-all-storage >/dev/null 2>&1 || true
echo "removida: $d"
else
echo "ausente: $d"
fi
done
+7 -7
View File
@@ -197,14 +197,14 @@ it working with its journal on the device /dev/journal
.nf .nf
.IP .IP
boot kernel patched with special "relocatable journal support" patch boot kernel patched with special "relocatable journal support" patch
reiserfstune /dev/hda1 --journal-new-device /dev/journal -f reiserfstune /dev/hda1 \-\-journal\-new\-device /dev/journal \-f
mount /dev/hda1 and use. mount /dev/hda1 and use.
You would like to change max transaction size to 512 blocks You would like to change max transaction size to 512 blocks
reiserfstune -t 512 /dev/hda1 reiserfstune \-t 512 /dev/hda1
You would like to use your file system on another kernel that doesn't You would like to use your file system on another kernel that doesn't
contain relocatable journal support. contain relocatable journal support.
umount /dev/hda1 umount /dev/hda1
reiserfstune /dev/hda1 -j /dev/journal --journal-new-device /dev/hda1 --make-journal-standard reiserfstune /dev/hda1 \-j /dev/journal \-\-journal\-new\-device /dev/hda1 \-\-make\-journal\-standard
mount /dev/hda1 and use. mount /dev/hda1 and use.
.LP .LP
2. You would like to have ReiserFS on /dev/hda1 and to be able to 2. You would like to have ReiserFS on /dev/hda1 and to be able to
@@ -215,13 +215,13 @@ device containing the filesystem.
boot kernel patched with special "relocatable journal support" patch boot kernel patched with special "relocatable journal support" patch
mkreiserfs /dev/hda1 mkreiserfs /dev/hda1
you got solid state disk (perhaps /dev/sda, they typically look like scsi disks) you got solid state disk (perhaps /dev/sda, they typically look like scsi disks)
reiserfstune --journal-new-device /dev/sda1 -f /dev/hda1 reiserfstune \-\-journal\-new\-device /dev/sda1 \-f /dev/hda1
Your scsi device dies, it is three in the morning, you have an extra IDE device Your scsi device dies, it is three in the morning, you have an extra IDE device
lying around lying around
reiserfsck --no-journal-available /dev/hda1 reiserfsck \-\-no\-journal\-available /dev/hda1
or or
reiserfsck --rebuild-tree --no-journal-available /dev/hda1 reiserfsck \-\-rebuild-tree \-\-no\-journal\-available /dev/hda1
reiserfstune --no-journal-available --journal-new-device /dev/hda1 /dev/hda1 reiserfstune \-\-no\-journal\-available \-\-journal\-new\-device /dev/hda1 /dev/hda1
using /dev/hda1 under patched kernel using /dev/hda1 under patched kernel
.SH AUTHOR .SH AUTHOR
This version of \fBreiserfstune\fR has been written by Vladimir This version of \fBreiserfstune\fR has been written by Vladimir
+12 -5
View File
@@ -6,6 +6,7 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include "tune.h" #include "tune.h"
#include "misc.h"
#include <getopt.h> #include <getopt.h>
#include <stdarg.h> #include <stdarg.h>
@@ -398,6 +399,7 @@ int main(int argc, char **argv)
struct reiserfs_journal_header *j_head; struct reiserfs_journal_header *j_head;
reiserfs_trans_t old, new; reiserfs_trans_t old, new;
int Is_journal_or_maxtrans_size_specified = 0; int Is_journal_or_maxtrans_size_specified = 0;
long error;
program_name = strrchr(argv[0], '/'); program_name = strrchr(argv[0], '/');
@@ -486,11 +488,11 @@ int main(int argc, char **argv)
Force++; Force++;
break; break;
case 'b': /* --add-badblocks */ case 'b': /* --add-badblocks */
asprintf(&badblocks_file, "%s", optarg); xasprintf(&badblocks_file, "%s", optarg);
Bads = 1; Bads = 1;
break; break;
case 'B': /* --badblocks */ case 'B': /* --badblocks */
asprintf(&badblocks_file, "%s", optarg); xasprintf(&badblocks_file, "%s", optarg);
Bads = 2; Bads = 2;
break; break;
case 'u': case 'u':
@@ -560,9 +562,10 @@ int main(int argc, char **argv)
/* device to be formatted */ /* device to be formatted */
device_name = argv[optind]; device_name = argv[optind];
fs = reiserfs_open(device_name, O_RDONLY, NULL, NULL, 1); fs = reiserfs_open(device_name, O_RDONLY, &error, NULL, 1);
if (no_reiserfs_found(fs)) { if (no_reiserfs_found(fs)) {
message("Cannot open reiserfs on %s", device_name); message("Cannot open reiserfs on %s: %s", device_name,
error_message(error));
return 1; return 1;
} }
@@ -673,7 +676,11 @@ int main(int argc, char **argv)
if (strlen(LABEL) > 16) if (strlen(LABEL) > 16)
message message
("Specified LABEL is longer then 16 characters, will be truncated\n"); ("Specified LABEL is longer then 16 characters, will be truncated\n");
strncpy(fs->fs_ondisk_sb->s_label, LABEL, 16); /* on-disk label is a fixed 16-byte field; keep it
NUL-terminated for the userspace readers below */
snprintf(fs->fs_ondisk_sb->s_label,
sizeof(fs->fs_ondisk_sb->s_label),
"%s", LABEL);
need_dirty = 1; need_dirty = 1;
} }
if (Max_mnt_count && if (Max_mnt_count &&