diff options
36 files changed, 373 insertions, 136 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 57afc62..0093558 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). -## [Unreleased] +## [2.3.1] - 2026-04-13 +### Added + - ubirsvol: resize using all available free space if size is specified as 0 + +### Fixed + - ubifs-utils: link libmissing.a in case execinfo.h isn't present + - ubifs-utils: common: fix memory leak in devtable.c + - Broken check for GCC compiler versions + - ubifs-utils: missing header file includes + - ubifs-utils: tests: missing files in release tarball + - mtd-tests: flash_speed: really skip destructive tests + - mtd-tests: flash_speed: wrong error message in read_eraseblock() + - serve_image: fix _POSIX_C_SOURCE define + - ubiattach: fix wording in usage example + - fsck.ubifs: don't use pointers that reference out-of-scope variables + - fsck.ubifs: fix platform dependant `ino_t` and `loff_t` formatting + - docfdisk.c: fix potential arithmetic overflows in partition size + - jittertest: reject overlong file names + +## [2.3.0] - 2025-02-15 ### Added - fsck.ubifs: Add fsck utility for ubifs - ubifs-utils: Support Address-Sanitizier debug @@ -17,6 +36,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - mkfs.jffs2: fix segfault when parsing dev table - nand-utils: nanddump: Explicitely use the page size when relevant - misc-utils: add missing error handling for 'bam' allocation in ftl_check.c + - mtdinfo: type mis-match in printf format string + - nanddump: const cast warning + - flashcp: uninitialized variable + - jffs2reader: potential null pointer dereference + - tests: checkfs: Add previous prototype for do_pwr_dn() ### Changed - mkfs.ubifs: re-sync with the kernel code diff --git a/Makefile.am b/Makefile.am index c756127..ba54acc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,9 @@ test_SCRIPTS = test_DATA = TESTS = +TEST_EXTENSIONS = .sh +SH_LOG_COMPILER = $(SHELL) +AM_TESTS_ENVIRONMENT = TESTBINDIR='$(abs_top_builddir)'; export TESTBINDIR; EXTRA_DIST = COPYING CHANGELOG.md README.txt include lib/Makemodule.am diff --git a/configure.ac b/configure.ac index b160c03..09f2191 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.60]) -m4_define([RELEASE], 2.2.1) +m4_define([RELEASE], 2.3.1) AC_INIT([mtd-utils], [RELEASE], [linux-mtd@lists.infradead.org], mtd-utils) @@ -304,6 +304,7 @@ AC_CONFIG_FILES([tests/fs-tests/fs_help_all.sh tests/fs-tests/fs_run_all.sh tests/fs-tests/stress/fs_stress00.sh tests/fs-tests/stress/fs_stress01.sh + tests/jittertest/filename_bounds.sh tests/ubi-tests/runubitests.sh tests/ubi-tests/ubi-stress-test.sh tests/ubifs_tools-tests/lib/common.sh diff --git a/include/common.h b/include/common.h index 303d30d..d443e17 100644 --- a/include/common.h +++ b/include/common.h @@ -26,7 +26,6 @@ #include <string.h> #include <fcntl.h> #include <errno.h> -#include <features.h> #include <inttypes.h> #include <unistd.h> #include <sys/sysmacros.h> diff --git a/include/libubi.h b/include/libubi.h index b5b3d8f..9203416 100644 --- a/include/libubi.h +++ b/include/libubi.h @@ -56,6 +56,7 @@ typedef void * libubi_t; * @max_beb_per1024: Maximum expected bad eraseblocks per 1024 eraseblocks * @disable_fm: whether disable fastmap * @need_resv_pool: whether reserve free pebs for filling pool/wl_pool + * @wl_threshold: wear-leveling threshold (0 means use kernel default) */ struct ubi_attach_request { @@ -66,6 +67,7 @@ struct ubi_attach_request int max_beb_per1024; bool disable_fm; bool need_resv_pool; + int wl_threshold; }; /** diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index bb5c0f9..601f3f4 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -284,7 +284,8 @@ struct ubi_attach_req { int16_t max_beb_per1024; int8_t disable_fm; int8_t need_resv_pool; - int8_t padding[8]; + int32_t wl_threshold; + int8_t padding[4]; }; /* diff --git a/lib/libmtd.c b/lib/libmtd.c index f588e09..96a2167 100644 --- a/lib/libmtd.c +++ b/lib/libmtd.c @@ -902,7 +902,7 @@ static int mtd_valid_erase_block(const struct mtd_dev_info *mtd, int eb) } static int mtd_xlock(const struct mtd_dev_info *mtd, int fd, int eb, - int blocks, int req, const char *sreq) + int blocks, unsigned long req, const char *sreq) { int ret; struct erase_info_user ei; diff --git a/lib/libubi.c b/lib/libubi.c index 86736dd..5d55148 100644 --- a/lib/libubi.c +++ b/lib/libubi.c @@ -769,6 +769,7 @@ int ubi_attach(libubi_t desc, const char *node, struct ubi_attach_request *req) r.vid_hdr_offset = req->vid_hdr_offset; r.disable_fm = req->disable_fm ? 1 : 0; r.need_resv_pool = req->need_resv_pool ? 1 : 0; + r.wl_threshold = req->wl_threshold; if (req->max_beb_per1024) { /* diff --git a/misc-utils/docfdisk.c b/misc-utils/docfdisk.c index 486ce29..7b936d5 100644 --- a/misc-utils/docfdisk.c +++ b/misc-utils/docfdisk.c @@ -253,8 +253,17 @@ int main(int argc, char **argv) for (i = 0; i < npart; i++) { ip = &(mh->Partitions[i]); ip->firstUnit = cpu_to_le32(block); - if (!nblocks[i]) + if (!nblocks[i]) { + if (block >= totblocks) { + printf("No space left on device for partition.\n"); + return 1; + } nblocks[i] = totblocks - block; + } + if (nblocks[i] > totblocks || block > totblocks - nblocks[i]) { + printf("Requested partition size exceeds available device space.\n"); + return 1; + } ip->virtualUnits = cpu_to_le32(nblocks[i]); block += nblocks[i]; ip->lastUnit = cpu_to_le32(block-1); diff --git a/misc-utils/serve_image.c b/misc-utils/serve_image.c index 6c8c8fb..ec2090f 100644 --- a/misc-utils/serve_image.c +++ b/misc-utils/serve_image.c @@ -1,5 +1,5 @@ #define PROGRAM_NAME "serve_image" -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200809L #include <time.h> #include <errno.h> diff --git a/tests/jittertest/JitterTest.c b/tests/jittertest/JitterTest.c index 2bee0b0..a3e3764 100644 --- a/tests/jittertest/JitterTest.c +++ b/tests/jittertest/JitterTest.c @@ -205,6 +205,7 @@ static int RunAsRTTask = FALSE; /* default action unless priority is /********************* Local Function Prototypes **********************/ void HandleCmdLineArgs(int argc, char *argv[]); +static void SaveFileName(char *pDest, size_t destSize, const char *pFileName); void SetFileName(char * pFileName); void SetInterruptPeriod(char * pASCIIInterruptPeriodMilliSec); void SetSchedulerPriority(char * pASCIISchedulerPriority); @@ -830,9 +831,14 @@ void HandleCmdLineArgs( (strcmp(argv[argNum],"-r") == STRINGS_EQUAL)) { /* Set the file to read*/ ++argNum; - - strncpy(ReadFile, argv[argNum], sizeof(ReadFile)); - DoRead = TRUE; + if (argNum < argc) { + SaveFileName(ReadFile, sizeof(ReadFile), argv[argNum]); + DoRead = TRUE; + } + else { + printf("*** Read file name not specified. ***\n"); + exit(0); + } } else if ((strcmp(argv[argNum],"--write_bytes") == @@ -858,9 +864,13 @@ void HandleCmdLineArgs( (strcmp(argv[argNum],"-c") == STRINGS_EQUAL)) { /* Set the file to log console log on. */ ++argNum; - - strncpy(LogFile, argv[argNum], sizeof(LogFile) - 1); - LogFile[sizeof(LogFile) - 1] = '\0'; + if (argNum < argc) { + SaveFileName(LogFile, sizeof(LogFile), argv[argNum]); + } + else { + printf("*** Console log file name not specified. ***\n"); + exit(0); + } } else if ((strcmp(argv[argNum],"--grab_kprofile") == @@ -913,27 +923,37 @@ void HandleCmdLineArgs( /*********************************************************************** - * SetFileName - * This function sets the output file name. + * SaveFileName + * This function validates and saves a file name. * output: N/A ***********************************************************************/ -void SetFileName( - char * pFileName) /* ptr to desired output file name */ +static void SaveFileName( + char *pDest, /* ptr to destination buffer */ + size_t destSize, /* destination buffer size */ + const char *pFileName) /* ptr to desired file name */ { size_t fileNameLen; /* file name length (bytes) */ - /* Check file name length. */ fileNameLen = strlen(pFileName); - if (fileNameLen > (size_t) MAX_FILE_NAME_LEN) { + if (fileNameLen > destSize - 1) { printf("File name %s exceeds maximum length %d.\n", - pFileName, MAX_FILE_NAME_LEN); + pFileName, (int)(destSize - 1)); exit(0); } - /* File name length is OK so save the file name. */ - strcpy(OutFileName, pFileName); + strcpy(pDest, pFileName); +} - return; + +/*********************************************************************** + * SetFileName + * This function sets the output file name. + * output: N/A + ***********************************************************************/ +void SetFileName( + char * pFileName) /* ptr to desired output file name */ +{ + SaveFileName(OutFileName, sizeof(OutFileName), pFileName); } diff --git a/tests/jittertest/Makemodule.am b/tests/jittertest/Makemodule.am index d280192..2cb85c1 100644 --- a/tests/jittertest/Makemodule.am +++ b/tests/jittertest/Makemodule.am @@ -6,6 +6,8 @@ plotJittervsFill_CPPFLAGS = $(AM_CPPFLAGS) test_PROGRAMS += JitterTest plotJittervsFill -test_SCRIPTS += tests/jittertest/filljffs2.sh +test_SCRIPTS += tests/jittertest/filljffs2.sh tests/jittertest/filename_bounds.sh +TESTS += tests/jittertest/filename_bounds.sh -EXTRA_DIST += tests/jittertest/README tests/jittertest/filljffs2.sh +EXTRA_DIST += tests/jittertest/README tests/jittertest/filljffs2.sh \ + tests/jittertest/filename_bounds.sh.in diff --git a/tests/jittertest/filename_bounds.sh.in b/tests/jittertest/filename_bounds.sh.in new file mode 100755 index 0000000..0dfba74 --- /dev/null +++ b/tests/jittertest/filename_bounds.sh.in @@ -0,0 +1,115 @@ +#!/bin/sh + +TESTBINDIR=${TESTBINDIR-@TESTBINDIR@} + +tmpdir= +jt_pid= +watchdog_pid= + +fatal() +{ + echo "Error: $1" 1>&2 + exit 1 +} + +cleanup() +{ + if [ -n "$watchdog_pid" ]; then + kill "$watchdog_pid" >/dev/null 2>&1 || : + wait "$watchdog_pid" 2>/dev/null || : + fi + + if [ -n "$jt_pid" ]; then + kill "$jt_pid" >/dev/null 2>&1 || : + wait "$jt_pid" 2>/dev/null || : + fi + + if [ -n "$tmpdir" ]; then + rm -rf "$tmpdir" + fi +} + +trap 'status=$?; trap - EXIT; cleanup; exit $status' EXIT +trap 'exit 1' HUP INT QUIT TERM + +make_name() +{ + char="$1" + length="$2" + name= + i=0 + + while [ "$i" -lt "$length" ]; do + name="${name}${char}" + i=$((i + 1)) + done + + printf '%s' "$name" +} + +tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/mtd-utils-jittertest.XXXXXX") || + fatal "mktemp failed" +cd "$tmpdir" || fatal "cannot change to temp dir" + +plot_valid=$(make_name a 249) +: > "$plot_valid" || fatal "cannot create valid plot input" +"$TESTBINDIR/plotJittervsFill" -f "$plot_valid" >plot-valid.out 2>plot-valid.err || + fatal "plotJittervsFill rejected a 249-byte file name" +if grep -q "exceeds maximum length" plot-valid.out plot-valid.err; then + fatal "plotJittervsFill reported a max-length error for a 249-byte file name" +fi + +plot_invalid=$(make_name b 250) +"$TESTBINDIR/plotJittervsFill" -f "$plot_invalid" >plot-invalid.out 2>plot-invalid.err || : +if ! grep -q "exceeds maximum length" plot-invalid.out plot-invalid.err; then + fatal "plotJittervsFill did not reject a 250-byte file name" +fi +if grep -q "Unable to open input log file" plot-invalid.out plot-invalid.err; then + fatal "plotJittervsFill reached fopen() for an overlong file name" +fi + +jt_read_valid=$(make_name r 32) +"$TESTBINDIR/JitterTest" -c /dev/null -f out.dat -r "$jt_read_valid" >jt-valid.out 2>jt-valid.err & +jt_pid=$! +( + sleep 10 + kill -TERM "$jt_pid" >/dev/null 2>&1 || : + sleep 1 + kill -KILL "$jt_pid" >/dev/null 2>&1 || : +) & +watchdog_pid=$! +sleep 1 +kill -INT "$jt_pid" >/dev/null 2>&1 || fatal "cannot stop JitterTest" +wait "$jt_pid" || fatal "JitterTest failed with a 32-byte read file name" +jt_pid= +kill "$watchdog_pid" >/dev/null 2>&1 || : +wait "$watchdog_pid" 2>/dev/null || : +watchdog_pid= +if ! grep -q "Press Ctrl+C to exit the program." jt-valid.out; then + fatal "JitterTest did not start normally with a 32-byte read file name" +fi +if ! grep -q "JitterTest exiting." jt-valid.out; then + fatal "JitterTest did not exit cleanly after SIGINT" +fi + +jt_read_invalid=$(make_name s 33) +"$TESTBINDIR/JitterTest" -c /dev/null -f out.dat -r "$jt_read_invalid" \ + >jt-read-invalid.out 2>jt-read-invalid.err || : +if ! grep -q "exceeds maximum length" jt-read-invalid.out jt-read-invalid.err; then + fatal "JitterTest did not reject a 33-byte read file name" +fi +if grep -q "Press Ctrl+C to exit the program." jt-read-invalid.out jt-read-invalid.err; then + fatal "JitterTest started despite an overlong read file name" +fi + +jt_console_invalid=$(make_name c 33) +"$TESTBINDIR/JitterTest" -c "$jt_console_invalid" -f out.dat \ + >jt-console-invalid.out 2>jt-console-invalid.err || : +if ! grep -q "exceeds maximum length" jt-console-invalid.out jt-console-invalid.err; then + fatal "JitterTest did not reject a 33-byte console file name" +fi +if grep -q "Press Ctrl+C to exit the program." jt-console-invalid.out jt-console-invalid.err; then + fatal "JitterTest started despite an overlong console file name" +fi + +echo "SUCCESS" diff --git a/tests/jittertest/plotJittervsFill.c b/tests/jittertest/plotJittervsFill.c index 03929a9..8929f9a 100644 --- a/tests/jittertest/plotJittervsFill.c +++ b/tests/jittertest/plotJittervsFill.c @@ -75,6 +75,21 @@ static int Debug = 0; /* Debug level. Each "-d" on the cmd line increases the le #define MIN_JITTER_THRESHOLD 1 /* ms minimum jitter threshold */ +static void SetLogFileName( + const char *pFileName) /* ptr to desired input file name */ +{ + size_t fileNameLen; /* file name length (bytes) */ + + fileNameLen = strlen(pFileName); + if (fileNameLen > sizeof(LogFile) - 1) { + printf("File name %s exceeds maximum length %d.\n", + pFileName, (int)(sizeof(LogFile) - 1)); + exit(0); + } + + strcpy(LogFile, pFileName); +} + static void PrintHelpInfo(void) { printf("Usage: plotJittervsFill [options] -f [--file] <input log file name> -t [--jitter_threshold] <jitter threshold in ms>\n"); @@ -122,7 +137,7 @@ static void HandleCmdLineArgs( /* Set the name of the output file. */ ++argNum; if (argNum < argc) { - strncpy(LogFile, argv[argNum], sizeof(LogFile)); + SetLogFileName(argv[argNum]); } else { printf("*** Input file name not specified. ***\n"); diff --git a/tests/mtd-tests/flash_speed.c b/tests/mtd-tests/flash_speed.c index 11f396c..3319452 100644 --- a/tests/mtd-tests/flash_speed.c +++ b/tests/mtd-tests/flash_speed.c @@ -190,7 +190,7 @@ static int read_eraseblock(int ebnum) { int err = mtd_read(&mtd, fd, ebnum, 0, iobuf, mtd.eb_size); if (err) - fprintf(stderr, "Error writing block %d!\n", ebnum); + fprintf(stderr, "Error reading block %d!\n", ebnum); return err; } @@ -490,7 +490,7 @@ int main(int argc, char **argv) } /* Multi-block erase all eraseblocks */ - if (!skip) { + if (flags & DESTRUCTIVE && !skip) { for (k = 1; k < 7; ++k) { blocks = 1 << k; printf("Testing %dx multi-block erase speed\n", blocks); @@ -518,7 +518,7 @@ int main(int argc, char **argv) /* Write a page and immediately after try to read another page. Report * the latency difference when performed on different banks (NOR only). */ - if (speb >= 0 && mtd.subpage_size == 1) { + if (flags & DESTRUCTIVE && speb >= 0 && mtd.subpage_size == 1) { long rww_duration_w, rww_latency_end; long rww_duration_rnw, rww_duration_r_end; bool rww_r_end_first; diff --git a/tests/ubifs_tools-tests/Makemodule.am b/tests/ubifs_tools-tests/Makemodule.am index 1715757..5fe4f83 100644 --- a/tests/ubifs_tools-tests/Makemodule.am +++ b/tests/ubifs_tools-tests/Makemodule.am @@ -10,7 +10,7 @@ test_SCRIPTS += \ tests/ubifs_tools-tests/fsck_tests/fsck_bad_image.sh \ tests/ubifs_tools-tests/mkfs_tests/build_fs_from_dir.sh -test_DATA += \ +TEST_IMAGE_FILES = \ tests/ubifs_tools-tests/images/good.gz \ tests/ubifs_tools-tests/images/sb_fanout.gz \ tests/ubifs_tools-tests/images/sb_fmt_version.gz \ @@ -64,3 +64,6 @@ test_DATA += \ tests/ubifs_tools-tests/images/dir_lost_not_recover.gz \ tests/ubifs_tools-tests/images/root_dir.gz \ tests/ubifs_tools-tests/images/empty_tnc.gz + +test_DATA += $(TEST_IMAGE_FILES) +EXTRA_DIST += $(TEST_IMAGE_FILES) diff --git a/ubi-utils/ubiattach.c b/ubi-utils/ubiattach.c index e758dab..0789a5f 100644 --- a/ubi-utils/ubiattach.c +++ b/ubi-utils/ubiattach.c @@ -44,6 +44,7 @@ struct args { int max_beb_per1024; bool disable_fm; bool need_resv_pool; + int wl_threshold; }; static struct args args = { @@ -55,6 +56,7 @@ static struct args args = { .max_beb_per1024 = 0, .disable_fm = false, .need_resv_pool = false, + .wl_threshold = 0, }; static const char doc[] = PROGRAM_NAME " version " VERSION @@ -76,6 +78,9 @@ static const char optionsstr[] = "-r, --reserve-pool Slow down the frequency of updating fastmap by reserving\n" " pebs for filling pool/wl_pool, which can prolong flash\n" " service life.\n" +"-w, --wl-threshold Set the wear-leveling threshold for this UBI device.\n" +" If 0, the kernel default value is used.\n" +" Accepted range is 2-65536.\n" "-h, --help print help message\n" "-V, --version print program version"; @@ -85,6 +90,7 @@ static const char usage[] = "\t[--mtdn=<MTD device number>] [--devn=<UBI device number>]\n" "\t[--dev-path=<path to device>] [-f] [--disable-fastmap] [-r] [--reserve-pool]\n" "\t[--max-beb-per1024=<maximum bad block number per 1024 blocks>]\n" +"\t[--wl-threshold=<wear-leveling threshold>]\n" "UBI control device defaults to " DEFAULT_CTRL_DEV " if not supplied.\n" "Example 1: " PROGRAM_NAME " -p /dev/mtd0 - attach /dev/mtd0 to UBI\n" "Example 2: " PROGRAM_NAME " -m 0 - attach MTD device 0 (mtd0) to UBI\n" @@ -92,9 +98,9 @@ static const char usage[] = " and create UBI device number 3 (ubi3)\n" "Example 4: " PROGRAM_NAME " -m 1 -b 25 - attach /dev/mtd1 to UBI and reserve\n" " 25*C/1024 eraseblocks for bad block handling, where C is the flash\n" -" is total flash chip eraseblocks count, that is flash chip size in\n" -" eraseblocks (including bad eraseblocks). E.g., if the flash chip\n" -" has 4096 PEBs, 100 will be reserved."; +" chip total eraseblocks count, that is flash chip size in eraseblocks\n" +" (including bad eraseblocks). E.g., if the flash chip has 4096 PEBs,\n" +" 100 will be reserved."; static const struct option long_options[] = { { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, @@ -104,6 +110,7 @@ static const struct option long_options[] = { { .name = "max-beb-per1024", .has_arg = 1, .flag = NULL, .val = 'b' }, { .name = "disable-fastmap", .has_arg = 0, .flag = NULL, .val = 'f' }, { .name = "reserve-pool", .has_arg = 0, .flag = NULL, .val = 'r' }, + { .name = "wl-threshold", .has_arg = 1, .flag = NULL, .val = 'w' }, { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, { NULL, 0, NULL, 0}, @@ -114,7 +121,7 @@ static int parse_opt(int argc, char * const argv[]) while (1) { int key, error = 0; - key = getopt_long(argc, argv, "p:m:d:O:b:frhV", long_options, NULL); + key = getopt_long(argc, argv, "p:m:d:O:b:frw:hV", long_options, NULL); if (key == -1) break; @@ -162,6 +169,20 @@ static int parse_opt(int argc, char * const argv[]) args.need_resv_pool = true; break; + case 'w': + { + unsigned long tmp = simple_strtoul(optarg, &error); + + if (error || (tmp && (tmp < 2 || tmp > 65536))) + return errmsg("bad wear-leveling threshold: \"%s\" (2-65536)", + optarg); + if (tmp == 0) + warnmsg("wear-leveling threshold use the default kernel value"); + args.wl_threshold = tmp; + + break; + } + case 'h': printf("%s\n\n", doc); printf("%s\n\n", usage); @@ -234,6 +255,7 @@ int main(int argc, char * const argv[]) req.max_beb_per1024 = args.max_beb_per1024; req.disable_fm = args.disable_fm; req.need_resv_pool = args.need_resv_pool; + req.wl_threshold = args.wl_threshold; err = ubi_attach(libubi, args.node, &req); if (err < 0) { diff --git a/ubi-utils/ubirsvol.c b/ubi-utils/ubirsvol.c index 73d2f68..55f6794 100644 --- a/ubi-utils/ubirsvol.c +++ b/ubi-utils/ubirsvol.c @@ -57,8 +57,10 @@ static const char optionsstr[] = "-N, --name=<volume name> volume name to resize\n" "-s, --size=<bytes> volume size volume size in bytes, kilobytes (KiB)\n" " or megabytes (MiB)\n" +" zero size means use all available free bytes\n" "-S, --lebs=<LEBs count> alternative way to give volume size in logical\n" " eraseblocks\n" +" zero size means use all available free LEBs\n" "-h, -?, --help print help message\n" "-V, --version print program version"; @@ -114,13 +116,13 @@ static int parse_opt(int argc, char * const argv[]) switch (key) { case 's': args.bytes = util_get_bytes(optarg); - if (args.bytes <= 0) + if (args.bytes < 0) return errmsg("bad volume size: \"%s\"", optarg); break; case 'S': args.lebs = simple_strtoull(optarg, &error); - if (error || args.lebs <= 0) + if (error || args.lebs < 0) return errmsg("bad LEB count: \"%s\"", optarg); break; @@ -233,6 +235,9 @@ int main(int argc, char * const argv[]) if (args.lebs != -1) args.bytes = (long long)vol_info.leb_size * args.lebs; + if (args.lebs == 0 || args.bytes == 0) + args.bytes = vol_info.rsvd_bytes + dev_info.avail_bytes; + err = ubi_rsvol(libubi, args.node, args.vol_id, args.bytes); if (err) { sys_errmsg("cannot UBI resize volume"); diff --git a/ubifs-utils/Makemodule.am b/ubifs-utils/Makemodule.am index 21ba059..f84569a 100644 --- a/ubifs-utils/Makemodule.am +++ b/ubifs-utils/Makemodule.am @@ -72,7 +72,7 @@ mkfs_ubifs_SOURCES = \ ubifs-utils/mkfs.ubifs/mkfs.ubifs.c mkfs_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(ZSTD_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) $(OPENSSL_LIBS) \ - $(DUMP_STACK_LD) $(ASAN_LIBS) -lm -lpthread + $(DUMP_STACK_LD) $(ASAN_LIBS) -lm -lpthread libmissing.a mkfs_ubifs_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) $(ZSTD_CFLAGS) $(UUID_CFLAGS) $(LIBSELINUX_CFLAGS) \ -I$(top_srcdir)/ubi-utils/include -I$(top_srcdir)/ubifs-utils/common -I $(top_srcdir)/ubifs-utils/libubifs @@ -90,7 +90,7 @@ fsck_ubifs_SOURCES = \ ubifs-utils/fsck.ubifs/handle_disconnected.c fsck_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(ZSTD_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) $(OPENSSL_LIBS) \ - $(DUMP_STACK_LD) $(ASAN_LIBS) -lm -lpthread + $(DUMP_STACK_LD) $(ASAN_LIBS) -lm -lpthread libmissing.a fsck_ubifs_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) $(ZSTD_CFLAGS) $(UUID_CFLAGS) $(LIBSELINUX_CFLAGS) \ -I$(top_srcdir)/ubi-utils/include -I$(top_srcdir)/ubifs-utils/common -I $(top_srcdir)/ubifs-utils/libubifs \ -I$(top_srcdir)/ubifs-utils/fsck.ubifs diff --git a/ubifs-utils/common/atomic.h b/ubifs-utils/common/atomic.h index f287d43..95754b2 100644 --- a/ubifs-utils/common/atomic.h +++ b/ubifs-utils/common/atomic.h @@ -2,8 +2,12 @@ #ifndef __ATOMIC_H__ #define __ATOMIC_H__ +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + /* Check GCC version, just to be safe */ -#if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 1) +#if GCC_VERSION < 40100 # error atomic.h works only with GCC newer than version 4.1 #endif /* GNUC >= 4.1 */ diff --git a/ubifs-utils/common/defs.h b/ubifs-utils/common/defs.h index 7ff1771..d5edbf6 100644 --- a/ubifs-utils/common/defs.h +++ b/ubifs-utils/common/defs.h @@ -13,8 +13,11 @@ #include <errno.h> #include <time.h> #include <assert.h> +#if HAVE_EXECINFO_H #include <execinfo.h> - +#else +#include "libmissing.h" +#endif #include "ubifs.h" /* common.h requires the PROGRAM_NAME macro */ diff --git a/ubifs-utils/common/devtable.c b/ubifs-utils/common/devtable.c index 7347f09..2e581ff 100644 --- a/ubifs-utils/common/devtable.c +++ b/ubifs-utils/common/devtable.c @@ -392,6 +392,7 @@ int parse_devtable(const char *tbl_file) out_close: fclose(f); + free(line); free_devtable_info(); return -1; } diff --git a/ubifs-utils/fsck.ubifs/check_files.c b/ubifs-utils/fsck.ubifs/check_files.c index 1e1a77b..615f6bc 100644 --- a/ubifs-utils/fsck.ubifs/check_files.c +++ b/ubifs-utils/fsck.ubifs/check_files.c @@ -57,12 +57,13 @@ static int construct_file(struct ubifs_info *c, union ubifs_key *key, struct rb_root *tree = &FSCK(c)->scanned_files; struct scanned_node *sn = NULL; struct ubifs_ch *ch = (struct ubifs_ch *)node; + struct scanned_ino_node ino_node; + struct scanned_dent_node dent_node; + struct scanned_data_node data_node; switch (ch->node_type) { case UBIFS_INO_NODE: { - struct scanned_ino_node ino_node; - if (!parse_ino_node(c, lnum, offs, node, key, &ino_node)) { if (fix_problem(c, INVALID_INO_NODE, NULL)) return add_invalid_node(c, key, lnum, offs, iter); @@ -74,8 +75,6 @@ static int construct_file(struct ubifs_info *c, union ubifs_key *key, case UBIFS_DENT_NODE: case UBIFS_XENT_NODE: { - struct scanned_dent_node dent_node; - if (!parse_dent_node(c, lnum, offs, node, key, &dent_node)) { if (fix_problem(c, INVALID_DENT_NODE, NULL)) return add_invalid_node(c, key, lnum, offs, iter); @@ -86,8 +85,6 @@ static int construct_file(struct ubifs_info *c, union ubifs_key *key, } case UBIFS_DATA_NODE: { - struct scanned_data_node data_node; - if (!parse_data_node(c, lnum, offs, node, key, &data_node)) { if (fix_problem(c, INVALID_DATA_NODE, NULL)) return add_invalid_node(c, key, lnum, offs, iter); @@ -101,8 +98,8 @@ static int construct_file(struct ubifs_info *c, union ubifs_key *key, } dbg_fsck("construct file(%lu) for %s node, TNC location %d:%d, in %s", - inum, ubifs_get_key_name(key_type(c, key)), sn->lnum, sn->offs, - c->dev_name); + (unsigned long)inum, ubifs_get_key_name(key_type(c, key)), + sn->lnum, sn->offs, c->dev_name); return insert_or_update_file(c, tree, sn, key_type(c, key), inum); } @@ -344,7 +341,8 @@ void update_files_size(struct ubifs_info *c) if (file && file->ino.header.exist && file->ino.size < e->d_size) { dbg_fsck("update file(%lu) size %llu->%llu, in %s", - e->inum, file->ino.size, + (unsigned long)e->inum, + file->ino.size, (unsigned long long)e->d_size, c->dev_name); file->ino.size = e->d_size; diff --git a/ubifs-utils/fsck.ubifs/extract_files.c b/ubifs-utils/fsck.ubifs/extract_files.c index c83d377..2e47b42 100644 --- a/ubifs-utils/fsck.ubifs/extract_files.c +++ b/ubifs-utils/fsck.ubifs/extract_files.c @@ -10,6 +10,8 @@ #include <getopt.h> #include <sys/stat.h> +#include <linux/limits.h> + #include "linux_err.h" #include "bitops.h" #include "kmem.h" @@ -76,21 +78,21 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (!inum || inum > INUM_WATERMARK) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node(bad inum %lu) at %d:%d, in %s", - inum, lnum, offs, c->dev_name); + (unsigned long)inum, lnum, offs, c->dev_name); else log_out(c, "bad inode node(bad inum %lu) at %d:%d", - inum, lnum, offs); + (unsigned long)inum, lnum, offs); goto out; } if (ch->node_type != key_type(c, key)) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(inconsistent node type %d vs key_type %d) at %d:%d, in %s", - inum, ch->node_type, key_type(c, key), + (unsigned long)inum, ch->node_type, key_type(c, key), lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(inconsistent node type %d vs key_type %d) at %d:%d", - inum, ch->node_type, key_type(c, key), + (unsigned long)inum, ch->node_type, key_type(c, key), lnum, offs); goto out; } @@ -112,43 +114,43 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (inum == UBIFS_ROOT_INO && !S_ISDIR(ino_node->mode)) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(root inode is not dir, tyoe %u) at %d:%d, in %s", - inum, ino_node->mode & S_IFMT, lnum, offs, + (unsigned long)inum, ino_node->mode & S_IFMT, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(root inode is not dir, tyoe %u) at %d:%d", - inum, ino_node->mode & S_IFMT, lnum, offs); + (unsigned long)inum, ino_node->mode & S_IFMT, lnum, offs); goto out; } if (ino_node->size > c->max_inode_sz) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(size %llu is too large) at %d:%d, in %s", - inum, ino_node->size, lnum, offs, c->dev_name); + (unsigned long)inum, ino_node->size, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(size %llu is too large) at %d:%d", - inum, ino_node->size, lnum, offs); + (unsigned long)inum, ino_node->size, lnum, offs); goto out; } if (le16_to_cpu(ino->compr_type) >= UBIFS_COMPR_TYPES_CNT) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(unknown compression type %d) at %d:%d, in %s", - inum, le16_to_cpu(ino->compr_type), lnum, offs, + (unsigned long)inum, le16_to_cpu(ino->compr_type), lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(unknown compression type %d) at %d:%d", - inum, le16_to_cpu(ino->compr_type), lnum, offs); + (unsigned long)inum, le16_to_cpu(ino->compr_type), lnum, offs); goto out; } if (ino_node->xnms + ino_node->xcnt > XATTR_LIST_MAX) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(too big xnames %u xcount %u) at %d:%d, in %s", - inum, ino_node->xnms, ino_node->xcnt, + (unsigned long)inum, ino_node->xnms, ino_node->xcnt, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(too big xnames %u xcount %u) at %d:%d", - inum, ino_node->xnms, ino_node->xcnt, + (unsigned long)inum, ino_node->xnms, ino_node->xcnt, lnum, offs); goto out; } @@ -156,20 +158,20 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (data_len < 0 || data_len > UBIFS_MAX_INO_DATA) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(invalid data len %d) at %d:%d, in %s", - inum, data_len, lnum, offs, c->dev_name); + (unsigned long)inum, data_len, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(invalid data len %d) at %d:%d", - inum, data_len, lnum, offs); + (unsigned long)inum, data_len, lnum, offs); goto out; } if (UBIFS_INO_NODE_SZ + data_len != node_len) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(inconsistent data len %d vs node len %d) at %d:%d, in %s", - inum, data_len, node_len, lnum, offs, c->dev_name); + (unsigned long)inum, data_len, node_len, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(inconsistent data len %d vs node len %d) at %d:%d", - inum, data_len, node_len, lnum, offs); + (unsigned long)inum, data_len, node_len, lnum, offs); goto out; } @@ -177,33 +179,33 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (!S_ISREG(ino_node->mode)) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(bad type %u for xattr) at %d:%d, in %s", - inum, ino_node->mode & S_IFMT, + (unsigned long)inum, ino_node->mode & S_IFMT, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(bad type %u for xattr) at %d:%d", - inum, ino_node->mode & S_IFMT, + (unsigned long)inum, ino_node->mode & S_IFMT, lnum, offs); goto out; } if (data_len != ino_node->size) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(inconsistent data_len %d vs size %llu for xattr) at %d:%d, in %s", - inum, data_len, ino_node->size, + (unsigned long)inum, data_len, ino_node->size, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(inconsistent data_len %d vs size %llu for xattr) at %d:%d", - inum, data_len, ino_node->size, + (unsigned long)inum, data_len, ino_node->size, lnum, offs); goto out; } if (ino_node->xcnt || ino_node->xsz || ino_node->xnms) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(non zero xattr count %u xattr size %u xattr names %u for xattr) at %d:%d, in %s", - inum, ino_node->xcnt, ino_node->xsz, + (unsigned long)inum, ino_node->xcnt, ino_node->xsz, ino_node->xnms, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(non zero xattr count %u xattr size %u xattr names %u for xattr) at %d:%d", - inum, ino_node->xcnt, ino_node->xsz, + (unsigned long)inum, ino_node->xcnt, ino_node->xsz, ino_node->xnms, lnum, offs); goto out; } @@ -214,10 +216,10 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (!ino_node->is_xattr && data_len != 0) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(bad data len %d for reg file) at %d:%d, in %s", - inum, data_len, lnum, offs, c->dev_name); + (unsigned long)inum, data_len, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(bad data len %d for reg file) at %d:%d", - inum, data_len, lnum, offs); + (unsigned long)inum, data_len, lnum, offs); goto out; } break; @@ -225,10 +227,10 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (data_len != 0) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(bad data len %d for dir file) at %d:%d, in %s", - inum, data_len, lnum, offs, c->dev_name); + (unsigned long)inum, data_len, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(bad data len %d for dir file) at %d:%d", - inum, data_len, lnum, offs); + (unsigned long)inum, data_len, lnum, offs); goto out; } break; @@ -247,10 +249,10 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, */ if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad symlink inode node %lu(bad data len %d) at %d:%d, in %s", - inum, data_len, lnum, offs, c->dev_name); + (unsigned long)inum, data_len, lnum, offs, c->dev_name); else log_out(c, "bad symlink inode node %lu(bad data len %d) at %d:%d", - inum, data_len, lnum, offs); + (unsigned long)inum, data_len, lnum, offs); goto out; } break; @@ -264,11 +266,11 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (data_len != sz_new && data_len != sz_huge) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(bad data len %d for char/block file, expect %d or %d) at %d:%d, in %s", - inum, data_len, sz_new, sz_huge, lnum, + (unsigned long)inum, data_len, sz_new, sz_huge, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(bad data len %d for char/block file, expect %d or %d) at %d:%d", - inum, data_len, sz_new, sz_huge, lnum, + (unsigned long)inum, data_len, sz_new, sz_huge, lnum, offs); goto out; } @@ -280,10 +282,10 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, if (data_len != 0) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(bad data len %d for fifo/sock file) at %d:%d, in %s", - inum, data_len, lnum, offs, c->dev_name); + (unsigned long)inum, data_len, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(bad data len %d for fifo/sock file) at %d:%d", - inum, data_len, lnum, offs); + (unsigned long)inum, data_len, lnum, offs); goto out; } break; @@ -291,21 +293,21 @@ bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node, /* invalid file type. */ if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(unknown type %u) at %d:%d, in %s", - inum, ino_node->mode & S_IFMT, lnum, offs, c->dev_name); + (unsigned long)inum, ino_node->mode & S_IFMT, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(unknown type %u) at %d:%d", - inum, ino_node->mode & S_IFMT, lnum, offs); + (unsigned long)inum, ino_node->mode & S_IFMT, lnum, offs); goto out; } if (ino_node->is_encrypted && !inode_can_be_encrypted(c, ino_node)) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad inode node %lu(encrypted but cannot be encrypted, type %u, is_xattr %d, fs_encrypted %d) at %d:%d, in %s", - inum, ino_node->mode & S_IFMT, ino_node->is_xattr, + (unsigned long)inum, ino_node->mode & S_IFMT, ino_node->is_xattr, c->encrypted, lnum, offs, c->dev_name); else log_out(c, "bad inode node %lu(encrypted but cannot be encrypted, type %u, is_xattr %d, fs_encrypted %d) at %d:%d", - inum, ino_node->mode & S_IFMT, ino_node->is_xattr, + (unsigned long)inum, ino_node->mode & S_IFMT, ino_node->is_xattr, c->encrypted, lnum, offs); goto out; } @@ -355,12 +357,12 @@ bool parse_dent_node(struct ubifs_info *c, int lnum, int offs, void *node, if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad %s node(len %d nlen %d type %d inum %lu key_type %d node_type %d) at %d:%d, in %s", ch->node_type == UBIFS_XENT_NODE ? "xattr entry" : "directory entry", - node_len, nlen, dent->type, inum, key_type, + node_len, nlen, dent->type, (unsigned long)inum, key_type, ch->node_type, lnum, offs, c->dev_name); else log_out(c, "bad %s node(len %d nlen %d type %d inum %lu key_type %d node_type %d) at %d:%d", ch->node_type == UBIFS_XENT_NODE ? "xattr entry" : "directory entry", - node_len, nlen, dent->type, inum, key_type, + node_len, nlen, dent->type, (unsigned long)inum, key_type, ch->node_type, lnum, offs); goto out; } @@ -417,10 +419,10 @@ bool parse_data_node(struct ubifs_info *c, int lnum, int offs, void *node, if (!inum || inum > INUM_WATERMARK) { if (FSCK(c)->mode == REBUILD_MODE) dbg_fsck("bad data node(bad inum %lu) at %d:%d, in %s", - inum, lnum, offs, c->dev_name); + (unsigned long)inum, lnum, offs, c->dev_name); else log_out(c, "bad data node(bad inum %lu) at %d:%d", - inum, lnum, offs); + (unsigned long)inum, lnum, offs); goto out; } @@ -483,7 +485,7 @@ bool parse_trun_node(struct ubifs_info *c, int lnum, int offs, void *node, if (!inum || inum > INUM_WATERMARK) { dbg_fsck("bad truncation node(bad inum %lu) at %d:%d, in %s", - inum, lnum, offs, c->dev_name); + (unsigned long)inum, lnum, offs, c->dev_name); goto out; } @@ -494,8 +496,9 @@ bool parse_trun_node(struct ubifs_info *c, int lnum, int offs, void *node, if (old_size < 0 || old_size > c->max_inode_sz || new_size < 0 || new_size > c->max_inode_sz || old_size <= new_size) { - dbg_fsck("bad truncation node(new size %ld old size %ld inum %lu) at %d:%d, in %s", - new_size, old_size, inum, lnum, offs, c->dev_name); + dbg_fsck("bad truncation node(new size %lld old size %lld inum %lu) at %d:%d, in %s", + (long long)new_size, (long long)old_size, + (unsigned long)inum, lnum, offs, c->dev_name); goto out; } @@ -1005,7 +1008,7 @@ int file_is_valid(struct ubifs_info *c, struct scanned_file *file, struct scanned_data_node *data_node; LIST_HEAD(drop_list); - dbg_fsck("check validation of file %lu, in %s", file->inum, c->dev_name); + dbg_fsck("check validation of file %lu, in %s", (unsigned long)file->inum, c->dev_name); if (!file->ino.header.exist) { handle_invalid_file(c, FILE_HAS_NO_INODE, file, NULL); @@ -1273,12 +1276,12 @@ retry: handle_invalid_file(c, FILE_IS_DISCONNECTED, file, NULL); else handle_invalid_file(c, FILE_HAS_NO_DENT, file, NULL); - dbg_fsck("file %lu is unreachable, in %s", file->inum, c->dev_name); + dbg_fsck("file %lu is unreachable, in %s", (unsigned long)file->inum, c->dev_name); return false; } reachable: - dbg_fsck("file %lu is reachable, in %s", file->inum, c->dev_name); + dbg_fsck("file %lu is reachable, in %s", (unsigned long)file->inum, c->dev_name); return true; } @@ -1496,7 +1499,7 @@ static int correct_file_info(struct ubifs_info *c, struct scanned_file *file) handle_invalid_file(c, FILE_IS_INCONSISTENT, file, NULL); lnum = file->ino.header.lnum; dbg_fsck("correct file(inum:%lu type:%s), nlink %u->%u, xattr cnt %u->%u, xattr size %u->%u, xattr names %u->%u, size %llu->%llu, at %d:%d, in %s", - file->inum, file->ino.is_xattr ? "xattr" : + (unsigned long)file->inum, file->ino.is_xattr ? "xattr" : ubifs_get_type_name(ubifs_get_dent_type(file->ino.mode)), file->ino.nlink, file->calc_nlink, file->ino.xcnt, file->calc_xcnt, diff --git a/ubifs-utils/fsck.ubifs/handle_disconnected.c b/ubifs-utils/fsck.ubifs/handle_disconnected.c index be62522..9e5d925 100644 --- a/ubifs-utils/fsck.ubifs/handle_disconnected.c +++ b/ubifs-utils/fsck.ubifs/handle_disconnected.c @@ -117,7 +117,7 @@ static int handle_disonnected_file(struct ubifs_info *c, struct ubifs_inode *target_ui; err = snprintf(file_name, sizeof(file_name), - "INO_%lu_%u", file->inum, index); + "INO_%lu_%u", (unsigned long)file->inum, index); if (err < 0) goto free_ui; fname_name(&nm) = file_name; @@ -138,7 +138,7 @@ static int handle_disonnected_file(struct ubifs_info *c, kfree(ui); kfree(lost_found_ui); log_out(c, "Too many duplicated names(%u) in lost+found for inum %lu", - index, file->inum); + index, (unsigned long)file->inum); goto delete_file; } @@ -150,7 +150,7 @@ static int handle_disonnected_file(struct ubifs_info *c, goto delete_file; } dbg_fsck("recover disconnected file %lu, in %s", - file->inum, c->dev_name); + (unsigned long)file->inum, c->dev_name); free_ui: kfree(ui); diff --git a/ubifs-utils/fsck.ubifs/problem.c b/ubifs-utils/fsck.ubifs/problem.c index 916c976..edb5f57 100644 --- a/ubifs-utils/fsck.ubifs/problem.c +++ b/ubifs-utils/fsck.ubifs/problem.c @@ -147,7 +147,7 @@ static void print_problem(const struct ubifs_info *c, { const struct invalid_file_problem *ifp = (const struct invalid_file_problem *)priv; - log_out(c, "problem: %s, ino %lu", problem->desc, ifp->file->inum); + log_out(c, "problem: %s, ino %lu", problem->desc, (unsigned long)ifp->file->inum); break; } case FILE_HAS_INCONSIST_TYPE: @@ -156,7 +156,7 @@ static void print_problem(const struct ubifs_info *c, const struct scanned_dent_node *dent_node = (const struct scanned_dent_node *)ifp->priv; log_out(c, "problem: %s, ino %lu, inode type %s%s, dentry %s has type %s%s", - problem->desc, ifp->file->inum, + problem->desc, (unsigned long)ifp->file->inum, ubifs_get_type_name(ubifs_get_dent_type(ifp->file->ino.mode)), ifp->file->ino.is_xattr ? "(xattr)" : "", c->encrypted && !ifp->file->ino.is_xattr ? "<encrypted>" : dent_node->name, @@ -171,7 +171,7 @@ static void print_problem(const struct ubifs_info *c, const struct scanned_dent_node *dent_node = (const struct scanned_dent_node *)ifp->priv; log_out(c, "problem: %s, ino %lu, type %s%s, dentry %s", - problem->desc, ifp->file->inum, + problem->desc, (unsigned long)ifp->file->inum, ubifs_get_type_name(ubifs_get_dent_type(ifp->file->ino.mode)), ifp->file->ino.is_xattr ? "(xattr)" : "", c->encrypted && !ifp->file->ino.is_xattr ? "<encrypted>" : dent_node->name); @@ -183,7 +183,7 @@ static void print_problem(const struct ubifs_info *c, const struct scanned_data_node *data_node = (const struct scanned_data_node *)ifp->priv; log_out(c, "problem: %s, ino %lu, type %s%s, data block %u", - problem->desc, ifp->file->inum, + problem->desc, (unsigned long)ifp->file->inum, ubifs_get_type_name(ubifs_get_dent_type(ifp->file->ino.mode)), ifp->file->ino.is_xattr ? "(xattr)" : "", key_block(c, &data_node->key)); @@ -198,7 +198,7 @@ static void print_problem(const struct ubifs_info *c, const struct invalid_file_problem *ifp = (const struct invalid_file_problem *)priv; log_out(c, "problem: %s, ino %lu type %s%s", problem->desc, - ifp->file->inum, + (unsigned long)ifp->file->inum, ubifs_get_type_name(ubifs_get_dent_type(ifp->file->ino.mode)), ifp->file->ino.is_xattr ? "(xattr)" : ""); break; @@ -209,9 +209,9 @@ static void print_problem(const struct ubifs_info *c, const struct scanned_file *host = (const struct scanned_file *)ifp->priv; log_out(c, "problem: %s, ino %lu type %s%s, host ino %lu type %s%s", - problem->desc, ifp->file->inum, + problem->desc, (unsigned long)ifp->file->inum, ubifs_get_type_name(ubifs_get_dent_type(ifp->file->ino.mode)), - ifp->file->ino.is_xattr ? "(xattr)" : "", host->inum, + ifp->file->ino.is_xattr ? "(xattr)" : "", (unsigned long)host->inum, ubifs_get_type_name(ubifs_get_dent_type(host->ino.mode)), host->ino.is_xattr ? "(xattr)" : ""); break; @@ -222,7 +222,7 @@ static void print_problem(const struct ubifs_info *c, const struct scanned_dent_node *dent_node = (const struct scanned_dent_node *)ifp->priv; log_out(c, "problem: %s, ino %lu, unreachable dentry %s, type %s%s", - problem->desc, ifp->file->inum, + problem->desc, (unsigned long)ifp->file->inum, c->encrypted && !ifp->file->ino.is_xattr ? "<encrypted>" : dent_node->name, ubifs_get_type_name(dent_node->type), key_type(c, &dent_node->key) == UBIFS_XENT_KEY ? "(xattr)" : ""); @@ -235,7 +235,7 @@ static void print_problem(const struct ubifs_info *c, log_out(c, "problem: %s, ino %lu type %s, nlink %u xcnt %u xsz %u xnms %u size %llu, " "should be nlink %u xcnt %u xsz %u xnms %u size %llu", - problem->desc, file->inum, + problem->desc, (unsigned long)file->inum, file->ino.is_xattr ? "xattr" : ubifs_get_type_name(ubifs_get_dent_type(file->ino.mode)), file->ino.nlink, file->ino.xcnt, file->ino.xsz, file->ino.xnms, file->ino.size, @@ -299,7 +299,7 @@ static void print_problem(const struct ubifs_info *c, const struct scanned_file *file = (const struct scanned_file *)priv; log_out(c, "problem: %s, ino %lu, size %llu", problem->desc, - file->inum, file->ino.size); + (unsigned long)file->inum, file->ino.size); break; } default: diff --git a/ubifs-utils/fsck.ubifs/rebuild_fs.c b/ubifs-utils/fsck.ubifs/rebuild_fs.c index b82d728..b399b3e 100644 --- a/ubifs-utils/fsck.ubifs/rebuild_fs.c +++ b/ubifs-utils/fsck.ubifs/rebuild_fs.c @@ -697,7 +697,7 @@ static void extract_dentry_tree(struct ubifs_info *c) file = list_entry(unreachable.next, struct scanned_file, list); dbg_fsck("remove unreachable file %lu, in %s", - file->inum, c->dev_name); + (unsigned long)file->inum, c->dev_name); list_del(&file->list); destroy_file_content(c, file); rb_erase(&file->rb, tree); @@ -1097,7 +1097,7 @@ static int record_file_used_lebs(struct ubifs_info *c, struct scanned_data_node *data_node; dbg_fsck("recovered file(inum:%lu name:%s type:%s), in %s", - file->inum, get_file_name(c, file), + (unsigned long)file->inum, get_file_name(c, file), file->ino.is_xattr ? "xattr" : ubifs_get_type_name(ubifs_get_dent_type(file->ino.mode)), c->dev_name); diff --git a/ubifs-utils/libubifs/README b/ubifs-utils/libubifs/README index 551ed8e..dd9322a 100644 --- a/ubifs-utils/libubifs/README +++ b/ubifs-utils/libubifs/README @@ -1,4 +1,4 @@ -UBIFS Library (Imported from linux kernel 6.8-rc2 41bccc98fb7931d63) +UBIFS Library (Imported from linux kernel 6.13-rc7 aa22f4da2a46) * ubifs.h is a selection of definitions from fs/ubifs/ubifs.h from the linux kernel. * key.h is copied from fs/ubifs/key.h from the linux kernel. diff --git a/ubifs-utils/libubifs/dir.c b/ubifs-utils/libubifs/dir.c index 89f77eb..2eb4e75 100644 --- a/ubifs-utils/libubifs/dir.c +++ b/ubifs-utils/libubifs/dir.c @@ -249,7 +249,7 @@ int ubifs_mkdir(struct ubifs_info *c, struct ubifs_inode *dir_ui, * directory inode. */ dbg_gen("dent '%s', mode %#hx in dir ino %lu", - fname_name(nm), mode, dir->inum); + fname_name(nm), mode, (unsigned long)dir->inum); /* New dir is not allowed to be created under an encrypted directory. */ ubifs_assert(c, !(dir_ui->flags & UBIFS_CRYPT_FL)); @@ -315,7 +315,7 @@ int ubifs_link_recovery(struct ubifs_info *c, struct ubifs_inode *dir_ui, * changing the parent inode. */ dbg_gen("dent '%s' to ino %lu (nlink %d) in dir ino %lu", - fname_name(nm), inode->inum, inode->nlink, dir->inum); + fname_name(nm), (unsigned long)inode->inum, inode->nlink, (unsigned long)dir->inum); /* New dir is not allowed to be created under an encrypted directory. */ ubifs_assert(c, !(dir_ui->flags & UBIFS_CRYPT_FL)); diff --git a/ubifs-utils/libubifs/find.c b/ubifs-utils/libubifs/find.c index ecf689c..364252e 100644 --- a/ubifs-utils/libubifs/find.c +++ b/ubifs-utils/libubifs/find.c @@ -80,7 +80,7 @@ static int valuable(struct ubifs_info *c, const struct ubifs_lprops *lprops) * @c: the UBIFS file-system description object * @lprops: LEB properties to scan * @in_tree: whether the LEB properties are in main memory - * @data: information passed to and from the caller of the scan + * @arg: information passed to and from the caller of the scan * * This function returns a code that indicates whether the scan should continue * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree @@ -89,8 +89,9 @@ static int valuable(struct ubifs_info *c, const struct ubifs_lprops *lprops) */ static int scan_for_dirty_cb(struct ubifs_info *c, const struct ubifs_lprops *lprops, int in_tree, - struct scan_data *data) + void *arg) { + struct scan_data *data = arg; int ret = LPT_SCAN_CONTINUE; /* Exclude LEBs that are currently in use */ @@ -173,8 +174,7 @@ static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c, data.pick_free = pick_free; data.lnum = -1; data.exclude_index = exclude_index; - err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, - (ubifs_lpt_scan_callback)scan_for_dirty_cb, + err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, scan_for_dirty_cb, &data); if (err) return ERR_PTR(err); @@ -347,7 +347,7 @@ out: * @c: the UBIFS file-system description object * @lprops: LEB properties to scan * @in_tree: whether the LEB properties are in main memory - * @data: information passed to and from the caller of the scan + * @arg: information passed to and from the caller of the scan * * This function returns a code that indicates whether the scan should continue * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree @@ -356,8 +356,9 @@ out: */ static int scan_for_free_cb(struct ubifs_info *c, const struct ubifs_lprops *lprops, int in_tree, - struct scan_data *data) + void *arg) { + struct scan_data *data = arg; int ret = LPT_SCAN_CONTINUE; /* Exclude LEBs that are currently in use */ @@ -453,7 +454,7 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c, data.pick_free = pick_free; data.lnum = -1; err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, - (ubifs_lpt_scan_callback)scan_for_free_cb, + scan_for_free_cb, &data); if (err) return ERR_PTR(err); @@ -587,7 +588,7 @@ out: * @c: the UBIFS file-system description object * @lprops: LEB properties to scan * @in_tree: whether the LEB properties are in main memory - * @data: information passed to and from the caller of the scan + * @arg: information passed to and from the caller of the scan * * This function returns a code that indicates whether the scan should continue * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree @@ -596,8 +597,9 @@ out: */ static int scan_for_idx_cb(struct ubifs_info *c, const struct ubifs_lprops *lprops, int in_tree, - struct scan_data *data) + void *arg) { + struct scan_data *data = arg; int ret = LPT_SCAN_CONTINUE; /* Exclude LEBs that are currently in use */ @@ -632,8 +634,7 @@ static const struct ubifs_lprops *scan_for_leb_for_idx(struct ubifs_info *c) int err; data.lnum = -1; - err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, - (ubifs_lpt_scan_callback)scan_for_idx_cb, + err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, scan_for_idx_cb, &data); if (err) return ERR_PTR(err); @@ -733,11 +734,10 @@ out: return err; } -static int cmp_dirty_idx(const struct ubifs_lprops **a, - const struct ubifs_lprops **b) +static int cmp_dirty_idx(const void *a, const void *b) { - const struct ubifs_lprops *lpa = *a; - const struct ubifs_lprops *lpb = *b; + const struct ubifs_lprops *lpa = *(const struct ubifs_lprops **)a; + const struct ubifs_lprops *lpb = *(const struct ubifs_lprops **)b; return lpa->dirty + lpa->free - lpb->dirty - lpb->free; } @@ -761,7 +761,7 @@ int ubifs_save_dirty_idx_lnums(struct ubifs_info *c) sizeof(void *) * c->dirty_idx.cnt); /* Sort it so that the dirtiest is now at the end */ sort(c->dirty_idx.arr, c->dirty_idx.cnt, sizeof(void *), - (int (*)(const void *, const void *))cmp_dirty_idx, NULL); + cmp_dirty_idx, NULL); dbg_find("found %d dirty index LEBs", c->dirty_idx.cnt); if (c->dirty_idx.cnt) dbg_find("dirtiest index LEB is %d with dirty %d and free %d", @@ -780,7 +780,7 @@ int ubifs_save_dirty_idx_lnums(struct ubifs_info *c) * @c: the UBIFS file-system description object * @lprops: LEB properties to scan * @in_tree: whether the LEB properties are in main memory - * @data: information passed to and from the caller of the scan + * @arg: information passed to and from the caller of the scan * * This function returns a code that indicates whether the scan should continue * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree @@ -789,8 +789,9 @@ int ubifs_save_dirty_idx_lnums(struct ubifs_info *c) */ static int scan_dirty_idx_cb(struct ubifs_info *c, const struct ubifs_lprops *lprops, int in_tree, - struct scan_data *data) + void *arg) { + struct scan_data *data = arg; int ret = LPT_SCAN_CONTINUE; /* Exclude LEBs that are currently in use */ @@ -849,8 +850,7 @@ static int find_dirty_idx_leb(struct ubifs_info *c) if (c->pnodes_have >= c->pnode_cnt) /* All pnodes are in memory, so skip scan */ return -ENOSPC; - err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, - (ubifs_lpt_scan_callback)scan_dirty_idx_cb, + err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, scan_dirty_idx_cb, &data); if (err) return err; diff --git a/ubifs-utils/libubifs/journal.c b/ubifs-utils/libubifs/journal.c index e78ea14..45d82fd 100644 --- a/ubifs-utils/libubifs/journal.c +++ b/ubifs-utils/libubifs/journal.c @@ -46,6 +46,7 @@ * all the nodes. */ +#include <sys/stat.h> #include "bitops.h" #include "kmem.h" #include "ubifs.h" diff --git a/ubifs-utils/libubifs/lpt.c b/ubifs-utils/libubifs/lpt.c index 8e20a17..f2f2727 100644 --- a/ubifs-utils/libubifs/lpt.c +++ b/ubifs-utils/libubifs/lpt.c @@ -2009,6 +2009,7 @@ out_err: * @pnode: where to keep a pnode * @cnode: where to keep a cnode * @in_tree: is the node in the tree in memory + * @ptr: union of node pointers * @ptr.nnode: pointer to the nnode (if it is an nnode) which may be here or in * the tree * @ptr.pnode: ditto for pnode diff --git a/ubifs-utils/libubifs/lpt_commit.c b/ubifs-utils/libubifs/lpt_commit.c index ee84f80..79f7b14 100644 --- a/ubifs-utils/libubifs/lpt_commit.c +++ b/ubifs-utils/libubifs/lpt_commit.c @@ -580,7 +580,7 @@ struct ubifs_pnode *ubifs_find_next_pnode(struct ubifs_info *c, /* Go right */ nnode = ubifs_get_nnode(c, nnode, iip); if (IS_ERR(nnode)) - return (void *)nnode; + return ERR_CAST(nnode); /* Go down to level 1 */ while (nnode->level > 1) { @@ -597,7 +597,7 @@ struct ubifs_pnode *ubifs_find_next_pnode(struct ubifs_info *c, } nnode = ubifs_get_nnode(c, nnode, iip); if (IS_ERR(nnode)) - return (void *)nnode; + return ERR_CAST(nnode); } for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) diff --git a/ubifs-utils/libubifs/replay.c b/ubifs-utils/libubifs/replay.c index 3943b32..9d61133 100644 --- a/ubifs-utils/libubifs/replay.c +++ b/ubifs-utils/libubifs/replay.c @@ -34,6 +34,7 @@ * @lnum: logical eraseblock number of the node * @offs: node offset * @len: node length + * @hash: node hash * @deletion: non-zero if this entry corresponds to a node deletion * @sqnum: node sequence number * @list: links the replay list diff --git a/ubifs-utils/libubifs/tnc_commit.c b/ubifs-utils/libubifs/tnc_commit.c index d797006..66922d4 100644 --- a/ubifs-utils/libubifs/tnc_commit.c +++ b/ubifs-utils/libubifs/tnc_commit.c @@ -663,6 +663,8 @@ static int get_znodes_to_commit(struct ubifs_info *c) znode->alt = 0; cnext = find_next_dirty(znode); if (!cnext) { + ubifs_assert(c, !znode->parent); + znode->cparent = NULL; znode->cnext = c->cnext; break; } diff --git a/ubifs-utils/libubifs/ubifs.h b/ubifs-utils/libubifs/ubifs.h index 0908a22..1c7bc7b 100644 --- a/ubifs-utils/libubifs/ubifs.h +++ b/ubifs-utils/libubifs/ubifs.h @@ -11,6 +11,7 @@ #ifndef __UBIFS_H__ #define __UBIFS_H__ +#include <fcntl.h> #include <string.h> #include "linux_types.h" |
