Reserve snapraid- prefix for native ZFS snapshots and introduce fssnapshot_path

This commit is contained in:
Andrea Mazzoleni 2026-08-26 00:37:52 +02:00
parent 0e2d31d9db
commit 6583897fcf
4 changed files with 56 additions and 14 deletions

View file

@ -166,6 +166,17 @@ int fssnapshot_delete(const struct fssnapshot_struct* fss, const char* name);
*/
int fssnapshot_rename(const struct fssnapshot_struct* fss, const char* old_name, const char* new_name);
/**
* Get the path where a logical snapshot is accessible.
*
* @param fss Snapshot context
* @param name Logical snapshot name
* @param path Output path
* @param path_size Size of path
* @return 0 on success, -1 on failure
*/
int fssnapshot_path(const struct fssnapshot_struct* fss, const char* name, char* path, size_t path_size);
/*
* Log file.
*

View file

@ -743,6 +743,16 @@ int fssnapshot_rename(const struct fssnapshot_struct* fss, const char* old_name,
return 0;
}
int fssnapshot_path(const struct fssnapshot_struct* fss, const char* name, char* path, size_t path_size)
{
pathcpy(path, path_size, fss->snapshot_dir);
pathcat(path, path_size, name);
pathcatc(path, path_size, '/');
pathcat(path, path_size, fss->sub_dir);
return 0;
}
void fssnapshot_unmount(const struct fssnapshot_struct* fss)
{
/*

View file

@ -6036,10 +6036,9 @@ static int state_snapshot_dir(struct fssnapshot_struct* fss, const char* name, s
if (disk) {
char vol[PATH_MAX];
pathcpy(vol, sizeof(vol), fss->snapshot_dir);
pathcat(vol, sizeof(vol), name);
pathcatc(vol, sizeof(vol), '/');
pathcat(vol, sizeof(vol), fss->sub_dir);
if (fssnapshot_path(fss, name, vol, sizeof(vol)) != 0)
return -1;
pathcpy(disk->dir, sizeof(disk->dir), vol);
disk->dir_device = st.st_dev;
@ -6245,10 +6244,8 @@ void state_snapshot_write(struct snapraid_state* state, tommy_list* filterlist_d
/* set where to find deallocated files */
char vol[PATH_MAX];
pathcpy(vol, sizeof(vol), disk->fss.snapshot_dir);
pathcat(vol, sizeof(vol), SNAPSHOT_STABLE "/");
pathcat(vol, sizeof(vol), disk->fss.sub_dir);
state_dealloc(state, vol, &disk->dealloclist);
if (fssnapshot_path(&disk->fss, SNAPSHOT_STABLE, vol, sizeof(vol)) == 0)
state_dealloc(state, vol, &disk->dealloclist);
}
}
} else {

View file

@ -2294,13 +2294,24 @@ static int fssnapshot_stat_fs(const struct fssnapshot_struct* fss, const char* n
}
#endif
/*
* Native ZFS snapshots use a SnapRAID-specific prefix to avoid
* deleting or renaming unrelated user snapshots with generic
* names such as @scan, @pending, or @stable.
*/
#define ZFS_SNAPSHOT_PREFIX "snapraid-"
#if HAVE_LINUX_DEVICE
static int fssnapshot_stat_zfs(const struct fssnapshot_struct* fss, const char* name, struct stat* st)
{
char native_name[PATH_MAX];
char target_path[PATH_MAX];
pathcpy(native_name, sizeof(native_name), ZFS_SNAPSHOT_PREFIX);
pathcat(native_name, sizeof(native_name), name);
pathcpy(target_path, sizeof(target_path), fss->snapshot_dir);
pathcat(target_path, sizeof(target_path), name);
pathcat(target_path, sizeof(target_path), native_name);
/*
* Ensure to get into into the snapshot
@ -2351,7 +2362,7 @@ static int fssnapshot_stat_zfs(const struct fssnapshot_struct* fss, const char*
if (!entry)
break;
if (strcmp(entry->d_name, name) == 0) {
if (strcmp(entry->d_name, native_name) == 0) {
closedir(d);
return 0;
}
@ -2480,7 +2491,7 @@ static int fssnapshot_zfs_create(const struct fssnapshot_struct* fss, const char
/* LCOV_EXCL_STOP */
}
snprintf(snapshot, sizeof(snapshot), "%s@%s", fss->dataset, name);
snprintf(snapshot, sizeof(snapshot), "%s@" ZFS_SNAPSHOT_PREFIX "%s", fss->dataset, name);
if (os_validate_exec_input(snapshot) != 0) {
/* LCOV_EXCL_START */
@ -2609,7 +2620,7 @@ static int fssnapshot_zfs_delete(const struct fssnapshot_struct* fss, const char
/* LCOV_EXCL_STOP */
}
snprintf(snapshot, sizeof(snapshot), "%s@%s", fss->dataset, name);
snprintf(snapshot, sizeof(snapshot), "%s@" ZFS_SNAPSHOT_PREFIX "%s", fss->dataset, name);
if (os_validate_exec_input(snapshot) != 0) {
/* LCOV_EXCL_START */
@ -2689,8 +2700,8 @@ static int fssnapshot_zfs_rename(const struct fssnapshot_struct* fss, const char
/* LCOV_EXCL_STOP */
}
snprintf(old_snapshot, sizeof(old_snapshot), "%s@%s", fss->dataset, old_name);
snprintf(new_snapshot, sizeof(new_snapshot), "%s@%s", fss->dataset, new_name);
snprintf(old_snapshot, sizeof(old_snapshot), "%s@" ZFS_SNAPSHOT_PREFIX "%s", fss->dataset, old_name);
snprintf(new_snapshot, sizeof(new_snapshot), "%s@" ZFS_SNAPSHOT_PREFIX "%s", fss->dataset, new_name);
if (os_validate_exec_input(old_snapshot) != 0 || os_validate_exec_input(new_snapshot) != 0) {
/* LCOV_EXCL_START */
@ -2735,11 +2746,24 @@ int fssnapshot_rename(const struct fssnapshot_struct* fss, const char* old_name,
#endif
}
int fssnapshot_path(const struct fssnapshot_struct* fss, const char* name, char* path, size_t path_size)
{
pathcpy(path, path_size, fss->snapshot_dir);
if (fss->magic == ZFS_SUPER_MAGIC)
pathcat(path, path_size, ZFS_SNAPSHOT_PREFIX);
pathcat(path, path_size, name);
pathcatc(path, path_size, '/');
pathcat(path, path_size, fss->sub_dir);
return 0;
}
void fssnapshot_unmount(const struct fssnapshot_struct* fss)
{
(void)fss;
}
/****************************************************************************/
/* dev */