aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md26
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac3
-rw-r--r--include/common.h1
-rw-r--r--include/libubi.h2
-rw-r--r--include/mtd/ubi-user.h3
-rw-r--r--lib/libmtd.c2
-rw-r--r--lib/libubi.c1
-rw-r--r--misc-utils/docfdisk.c11
-rw-r--r--misc-utils/serve_image.c2
-rw-r--r--tests/jittertest/JitterTest.c52
-rw-r--r--tests/jittertest/Makemodule.am6
-rwxr-xr-xtests/jittertest/filename_bounds.sh.in115
-rw-r--r--tests/jittertest/plotJittervsFill.c17
-rw-r--r--tests/mtd-tests/flash_speed.c6
-rw-r--r--tests/ubifs_tools-tests/Makemodule.am5
-rw-r--r--ubi-utils/ubiattach.c30
-rw-r--r--ubi-utils/ubirsvol.c9
-rw-r--r--ubifs-utils/Makemodule.am4
-rw-r--r--ubifs-utils/common/atomic.h6
-rw-r--r--ubifs-utils/common/defs.h5
-rw-r--r--ubifs-utils/common/devtable.c1
-rw-r--r--ubifs-utils/fsck.ubifs/check_files.c16
-rw-r--r--ubifs-utils/fsck.ubifs/extract_files.c97
-rw-r--r--ubifs-utils/fsck.ubifs/handle_disconnected.c6
-rw-r--r--ubifs-utils/fsck.ubifs/problem.c20
-rw-r--r--ubifs-utils/fsck.ubifs/rebuild_fs.c4
-rw-r--r--ubifs-utils/libubifs/README2
-rw-r--r--ubifs-utils/libubifs/dir.c4
-rw-r--r--ubifs-utils/libubifs/find.c40
-rw-r--r--ubifs-utils/libubifs/journal.c1
-rw-r--r--ubifs-utils/libubifs/lpt.c1
-rw-r--r--ubifs-utils/libubifs/lpt_commit.c4
-rw-r--r--ubifs-utils/libubifs/replay.c1
-rw-r--r--ubifs-utils/libubifs/tnc_commit.c2
-rw-r--r--ubifs-utils/libubifs/ubifs.h1
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"