Use PRIu32, PRIu64, and PRIcno, which corresponds to the defined type
nilfs_cno_t, for format strings in printf(), etc, and remove type cast
for corresponding arguments if possible.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
To clarify the correspondence with the header file "check_mount.h",
which corresponds to the main function check_mount(), rename the
implementation file "ismounted.c" to "check_mount.c".
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
The function 'check_mount' is shared among several utilities but lacks a
proper header declaration, relying instead on ad-hoc 'extern' declarations
in each source file. This triggers a Sparse warning suggesting the symbol
should be static.
Introduce a new header file "check_mount.h" to centralize the prototype
declaration. Include this header in the defining file and all users,
removing the redundant manual declarations.
This resolves the following Sparse warning:
ismounted.c:119:5: warning: symbol 'check_mount' was not declared. Should
it be static?
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
The one-bit bitfields in 'struct nilfs_cnormap' are currently defined
as 'int'. On two's complement systems, a one-bit signed integer can
only represent 0 and -1, which is not suitable for boolean flags
intended to hold 0 or 1.
Change them to 'unsigned int' to ensure they can represent 0 and 1
correctly.
While at it, clean up the comments for these members to improve
readability.
This resolves the following Sparse errors reported:
cnormap.c:64:35: error: dubious one-bit signed bitfield
cnormap.c:69:42: error: dubious one-bit signed bitfield
cnormap.c:70:43: error: dubious one-bit signed bitfield
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Fix the following Sparse warning reported in nilfs_get_segment():
nilfs.c:1032:29: warning: Using plain integer as NULL pointer
The first argument of mmap() expects a pointer, so use NULL instead of
the plain integer 0.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Running Sparse on nilfs-utils generates warnings in
"include/linux/nilfs2_ondisk.h" because standard user-space
environments lack the restricted type definitions for double-
underscored kernel macros (e.g., __le32_to_cpu).
Alias these kernel macros to the local versions in compat.h that
carry the necessary __force cast attributes.
Reorder header includes to ensure compat.h is parsed before
nilfs2_ondisk.h so that the aliases take effect during static
analysis.
Additionally, pre-include <asm/byteorder.h> in compat.h to prevent
macro redefinition warnings caused by the include order change.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Migrate the libuuid detection to use pkg-config via PKG_CHECK_MODULES.
This allows for better portability on systems where library paths may
differ from standard locations.
To align with pkg-config standards (which typically provide include
paths ending in .../uuid), the source code includes are updated from
<uuid/uuid.h> to <uuid.h>.
A fallback mechanism using AC_CHECK_LIB is retained for environments
without pkg-config, ensuring backward compatibility.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Currently, the dependency on libuuid is handled inconsistently; it is
implicitly coupled with the libblkid check, and Makefiles rely on
hardcoded '-luuid' flags.
Refactor the libuuid handling by introducing UUID_LIBS and UUID_CFLAGS
variables and decoupling the check from libblkid. Standardize the
library usage across Makefiles and source headers and removes hardcoded
flags.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Add support for generating pkg-config files, which contain build
dependency information for shared libraries, and add a brief
explanation of the changes in the README file.
The location where the pkg-config files are installed is
auto-detected, but you can change the install location or disable the
generation of the pkg-config files alltogether using the
--with-pkgconfigdir option. (This can also be disabled with the
--without-pkgconfigdir option.)
This can help external tools use the libraries, but currently it is
intended as a convenience for external development tools to easily
accommodate differences in build environments.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
To comply with modern distribution standards, disable the installation
of static archives by default.
As a result of libtool's behavior, .la files are still installed for
dynamically linked libraries, so they will need to be explicitly
removed if undesired.
To maintain the self-contained requirement for nilfs_cleanerd, the
build now uses libtool convenience libraries.
Users requiring static linking for external projects must now
explicitly use --enable-static during configuration.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Introduce a new build-time option --enable-usrmerge to support modern
Linux distributions following the "UsrMerge" and "Bin-Sbin merge"
schemes.
Traditional systems install core binaries to /sbin, while UsrMerge
systems use /usr/sbin. The latest distributions (e.g., Fedora Rawhide)
are further unifying these into /usr/bin.
Key changes:
- Add --enable-usrmerge=TYPE option (no, sbin, bin, or auto).
- Implement robust automatic detection in configure.ac:
- Detects 'bin' type (Bin-Sbin merge) if /usr/sbin and /usr/bin are
the same physical directory (-ef check), if RPM macros define
_sbindir as /usr/bin, or if key binaries are already linked.
- Detects 'sbin' type (UsrMerge) if /sbin is a symlink to /usr/sbin.
- Introduce core_sbindir and badblocksdir to decouple installation
paths from internal path references.
- Define CORE_SBINDIR and BADBLOCKSDIR macros via CPPFLAGS to replace
hardcoded "/sbin/" paths in mkfs.c and cleaner_exec.c.
- Automate creation of compatibility symbolic links in /usr/sbin when
installing to /usr/bin, provided that /usr/sbin exists.
- Update AC_PATH_PROG for ldconfig to search in /usr/sbin as well.
This ensures that NILFS utilities are installed to the correct
locations and maintain internal consistency across various Linux
distribution hierarchies.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
nilfs_find_fs(), called from nilfs_open(), parses "/proc/mounts" using its
own routines, but these parsing routines have a problem in that they
cannot handle escaped path strings. For example, if the mount point path
name contains spaces, the search will fail.
This is causing errors when running lscp, lssu, and other nilfs tools.
Fix this issue by avoiding custom parsing and using standard mount table
access routines such as setmntent(), getmntent_r(), endmntent(), and
hasmntopt().
Closes: https://github.com/nilfs-dev/nilfs-utils/issues/22
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Although nilfs_cleaner_find_fs() uses endmntent() to close the file
descriptor for "/proc/mounts", its uses fopen() directly to open it
instead of setmntent(). This asymmetry is undesirable because it can
cause unintended problems such as lock inconsistencies. Therefore,
properly use setmntent().
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
If nilfs_acc_blocks_segment() fails, nilfs_acc_blocks() returns an
error without releasing the segment allocated by nilfs_get_segment()
with nilfs_put_segment().
Fix this potential leak issue by calling nilfs_put_segment() regardless
of whether the call to nilfs_acc_blocks_segment() is successful or not.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Add export functions to get the absolute path name or file descriptor
of the mount point directory (file system root directory).
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
In the current libnilfs implementation, nilfs_open() returns the first
matching mount when searching the mount table. Therefore, when the
same mount points are stacked, the inaccessible mount point will be
unexpectedly selected.
Fix this issue by choosing the last match instead of the first one
when searching the mount table.
The changes required here also fixes potential memory leaks related to
device pathname and mount point pathname strings when nilfs_find_fs()
is called multiple times.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
When nilfs_open() opens a mount point to obtain an ioctl FD, it may be
overlaid by another mount and may be a directory of a file system
mounted with a different device.
Most nilfs utilities cannot operate in situations where the mount
point is hidden, but with the current implementation, an ioctl FD is
opened for the overlying file system, and ioctl commands are issued
wrongly for it.
Fix this issue by detecting such condition and returning a ENOENT error
in that case.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
In the current implementation, if nilfs_open() fails to retrieve an
existing nilfs mount from the mount table, it returns an error with
errno = ENOENT, resulting in inappropriate error messages, such as the
following:
$ lscp /dev/sdb1
lscp: cannot open NILFS on /dev/sdb1: No such file or directory
Fix this issue by changing the error code set in errno to ENXIO.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
The check_mount() function used to check the mount of a block device
does not support determining the mount status when the source is an
image file mounted via a loop device.
As a result, nilfs-tune can rewrite the loop device mount source file
without the force option "-f".
Fix this issue by making check_mount() detect if a loop device is
attached and a file system is mounted on it.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
This moves the definition of PATH_MAX, including completions where
PATH_MAX is undefined, to "compat.h" so that it does not have to be
defined in multiple places.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Unlike mkfs.nilfs2, nilfs-tune and dumpseg commands will cause errors
if used directly on a disk image files. This is because
__nilfs_sb_read(), which reads superblocks, uses the BLKGETSIZE64 ioctl
command to get the device size, which fails for disk image files.
Fix this issue by using the size information obtained from the fstat
system call for regular files.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Change the location of the uapi header files "nilfs2_ondisk.h" and
"nilfs2_api.h" to the "linux" subdirectory, as they are located in Linux
kernel-related development packages.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
An issue exists where scrapped segments generated during recovery of
dsync blocks are incorrectly determined to be protected due to
comparisons using invalid segment summary sequence numbers on disk.
Segments that are incorrectly determined to be protected will not be
reclaimed for a long period of time, occupying disk space unnecessarily.
In addition, it may prevent nilfs-resize from shrinking the file system.
Fix these issues by using segment usage information to determine whether
a segment has been scrapped, in which case it is considered unprotected
without comparing sequence numbers.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Update email addresses of NTT developers since lab.ntt.co.jp email
domain has been deprecated due to company policy.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Under certain high concurrency loads, NILFS2 can produce a segment that
crashes the cleanerd process with a conflicting data buffer error. The
segment is perfectly valid and the file system is not corrupted.
However, the cleanerd process can no longer be started and the file
system will eventually fill up and cannot be used any more.
The reason for this crash is, that a single logical segment can contain
multiple partial segments. If a block is written in one partial segment
and then immediately overwritten in another partial segment, then these
blocks have the same inode number, checkpoint number and offset.
However, these three numbers are used by the kernel to uniquely
identify a block. If the cleaner tries to clean two blocks that point
to the exact same buffer_head in the kernel, it creates a conflicting
data buffer error.
The solution is to detect these blocks and treat them as dead blocks.
If vd_period.p_end is equal to the checkpoint number, it means that the
block was overwritten within the same logical segment. So it must be
dead, and there is another block with the same ino, cno, and offset,
which is alive.
Signed-off-by: Andreas Rohner <andreas.rohner@gmx.net>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Remove "libnilfscleaner.so" dynamic link library and instead build
private library "libcleaner.la" for clients of cleanerd such as
nilfs-clean command.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Replace __u64, __u32, __u8, __s64, and __s32 with standard uint64_t,
uint32_t, uint8_t, int64_t and int32_t types, respectively, except for
nilfs2_api.h and nilfs2_ondisk.h.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Re-define operations on nilfs options as inline functions using new
generic functions nilfs_opt_{test,set,clear}() in order to make them
more flexible for future extension.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Add generic lock operations for nilfs to hide nilfs->n_sems[] array
from libnilfs interface, and use them to acquire, trylock, or release
the lock.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Accesses to finfo in nilfs_file_next() and nilfs_file_init() can
overrun since the termination condition of the file iterator is tested
after these functions return and the position of finfo is checked
afterwards as well.
This fixes the issue by inserting pre-checks for the position of finfo
before reading it.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Add a member which keeps the size of segment summary information to
nilfs_file struct for convenience.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
On-disk summary information of files can fall into inconsistent
states in theory:
- The block count recorded in finfo can exceed the number of
remaining payload blocks.
- The number of data blocks recorded in finfo can be larger than the
number of total blocks of the file, or
- The total size of finfo and binfo structures can exceed the size of
summary information of the partial segment.
This adds sanity checks for these glitches to nilfs_file, and adds a
framework to handle these errors as well.
Also, this enhances the error output routine of dumpseg command to
handle these errors nicely.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Add a function to calculate the number of summary blocks and use it in
nilfs_file_init().
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Add a function to calculate the size of finfo and binfo structures
that a given file occupies within segment summary information, where
we make the helper separating the logic from nilfs_file_next().
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
The macros NILFS_BINFO_XXX_SIZE are used only by functions
in segment.c. Move them into the library implementation.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Increment API version for libnilfs and libnilfsgc to reflect the
removal/addition/change of exported functions.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
The concept of "super file" is very confusing and nonsensical.
Get rid of the term from nilfs-utils.
The term is only used in the name of nilfs_file_is_super() test
function, so this alters the function name.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Add a test function nilfs_segment_is_protected() to libnilfsgc, where
the function returns if a given segment is protected or not. Also,
the cleaner daemon and nilfs-resize command are changed to use it.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Include "sys/mman.h" header file in the list of the AC_CHECK_HEADERS
macro to make sure the existence, and use HAVE_SYS_MMAN_H macro
instead of HAVE_MMAP for the test whether to include the header file.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
On-disk sizes recorded in segment summary header can be too short or
too large.
This adds three errors on sizes related to partial segment:
- partial segment block count
- segment summary header size, and
- segment summary information size
and adds their sanity checks to libsegment.
Also, this enhances the error output routine of dumpseg command to
handle these errors nicely.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Use likely() and unlikely() macros for condition statements
that determine branching to error-handling.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
If ss_bytes, an on-disk segment summary data, stores a value that is
not a multiple of eight, memory access for reading file/block
information can cause a bad alignment exception depending on the
architecture.
To prevent the issue, this introduces an error handling framework to
the psegment iterator, inserts a sanity check in
nilfs_psegment_is_valid() function that detects the bad alignment
condition and reports it with the framework, and applies these changes
to dumpseg command and gc library.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Rewrite nilfs_get_segment() and nilfs_put_segment() so that
nilfs_get_segment() stores related information (segment size, start
block number, number of blocks, memory address, etc) in a new data
structure, nilfs_segment, and nilfs_put_segment() releases the memory
allocated or mapped by nilfs_get_segment() based on the information in
nilfs_segment.
This also simplifies nilfs_psegment struct and functions wrt iterator
for partial segment, that is, nilfs_psegment_init(),
nilfs_psegment_is_end(), nilfs_psegment_next(), and
nilfs_psegment_for_each().
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Apply offsetofend() macro to calculate offset of the end position of
ss_sumsum field on segment summary struct.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
nilfs_psegment_is_valid() can cause memory access overrun at
crc32_le() when the size of segment summary which comes from an
on-disk data, ss_sumbytes, is either too small or too large.
This fixes the overrun issue by adding a range check for the size of
segment summary.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
The termination condition test of nilfs_psegment_is_end() underflows
if p_blocknr gets larger than (p_segblocknr + p_maxblocks). This can
happen since p_blocknr is increased by an on-disk data, ss_nblocks.
This patch fixes the underflow by transforming the termination
condition test.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Fix an underflow issue on p_maxblocks member of nilfs_psegment struct
that can happen if an on-disk layout data s_first_data_block exceeds
the block count of segment.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>