nilfs-clean: allow specifying filesystem node instead of device

Update nilfs-clean to accept a regular file or directory path on the
target filesystem in addition to a block device node.

This change is implemented within the private library libcleaner.
The functions nilfs_cleaner_launch() and nilfs_cleaner_open() in
lib/cleaner_ctl.c are modified to automatically resolve the backing
block device using the internal helper nilfs_lookup_device() if a
filesystem node is passed.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
This commit is contained in:
Ryusuke Konishi 2026-01-21 20:53:35 +09:00
parent ea6b9b84fd
commit ae0fc7c09b
3 changed files with 24 additions and 6 deletions

View File

@ -47,7 +47,7 @@ libnilfsgc_static_la_SOURCES = $(libnilfsgc_la_SOURCES)
libnilfsgc_static_la_LIBADD = libsegment.la $(LIB_POSIX_TIMER) \
libnilfs_static.la
libcleaner_la_SOURCES = cleaner_ctl.c
libcleaner_la_SOURCES = cleaner_ctl.c lookup_device.c
libcleaner_la_CFLAGS = $(AM_CFLAGS) $(UUID_CFLAGS)
libcleaner_la_LIBADD = librealpath.la libcleanerexec.la $(LIB_POSIX_MQ) \
$(UUID_LIBS) $(LIB_POSIX_TIMER)

View File

@ -83,6 +83,7 @@
#include "pathnames.h"
#include "realpath.h"
#include "util.h"
#include "lookup_device.h" /* nilfs_lookup_device() */
struct nilfs_cleaner {
pid_t cleanerd_pid;
@ -378,6 +379,7 @@ struct nilfs_cleaner *nilfs_cleaner_launch(const char *device,
unsigned long protperiod)
{
struct nilfs_cleaner *cleaner;
char *backdev = NULL;
int ret;
cleaner = malloc(sizeof(*cleaner));
@ -387,6 +389,12 @@ struct nilfs_cleaner *nilfs_cleaner_launch(const char *device,
cleaner->sendq = -1;
cleaner->recvq = -1;
ret = nilfs_lookup_device(device, &backdev);
if (unlikely(ret < 0))
goto error;
else if (ret > 0)
device = backdev; /* replace device in this function */
cleaner->device = strdup(device);
cleaner->mountdir = strdup(mntdir);
if (unlikely(!cleaner->device || !cleaner->mountdir))
@ -401,11 +409,14 @@ struct nilfs_cleaner *nilfs_cleaner_launch(const char *device,
if (unlikely(ret < 0))
goto abort;
free(backdev);
return cleaner; /* cleanerd started */
error:
nilfs_cleaner_logger(LOG_ERR, _("Error: %s"), strerror(errno));
abort:
free(backdev);
if (cleaner) {
free(cleaner->device); /* free(NULL) is just ignored */
free(cleaner->mountdir);
@ -418,6 +429,7 @@ struct nilfs_cleaner *nilfs_cleaner_open(const char *device,
const char *mntdir, int oflag)
{
struct nilfs_cleaner *cleaner;
char *backdev = NULL;
int ret;
cleaner = malloc(sizeof(*cleaner));
@ -427,6 +439,12 @@ struct nilfs_cleaner *nilfs_cleaner_open(const char *device,
cleaner->sendq = -1;
cleaner->recvq = -1;
ret = nilfs_lookup_device(device, &backdev);
if (unlikely(ret < 0))
goto error;
else if (ret > 0)
device = backdev; /* replace device in this function */
ret = nilfs_cleaner_find_fs(cleaner, device, mntdir);
if (unlikely(ret < 0))
goto abort;
@ -445,11 +463,14 @@ struct nilfs_cleaner *nilfs_cleaner_open(const char *device,
nilfs_cleaner_open_queue(cleaner) < 0)
goto abort;
free(backdev);
return cleaner;
error:
nilfs_cleaner_logger(LOG_ERR, _("Error: %s"), strerror(errno));
abort:
free(backdev);
if (cleaner) {
free(cleaner->device); /* free(NULL) is just ignored */
free(cleaner->mountdir);

View File

@ -93,7 +93,7 @@ static const struct option long_option[] = {
{NULL, 0, NULL, 0}
};
#define NILFS_CLEAN_USAGE \
"Usage: %s [options] [device]\n" \
"Usage: %s [options] [device|node]\n" \
" -b, --break,--stop\tstop running cleaner\n" \
" -c, --reload[=CONFFILE]\n" \
" \t\treload config\n" \
@ -115,7 +115,7 @@ static const struct option long_option[] = {
#define NILFS_CLEAN_USAGE \
"Usage: %s [-b] [-c [conffile]] [-h] [-l] [-m blocks]\n" \
" [-p protection-period] [-q] [-r] [-s] [-S gc-speed]\n" \
" [-v] [-V] [device]\n"
" [-v] [-V] [device|node]\n"
#endif /* _GNU_SOURCE */
@ -593,9 +593,6 @@ int main(int argc, char *argv[])
if (stat(device, &statbuf) < 0)
err(EXIT_FAILURE, _("cannot find '%s'"), device);
else if (!S_ISBLK(statbuf.st_mode))
errx(EXIT_FAILURE,
_("device must be a block device."));
}
if (optind < argc)
errx(EXIT_FAILURE, _("too many arguments."));