mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-04-12 22:51:46 +03:00
ZVOL: Restrict cloning with different properties
While technically its not a problem to clone between ZVOLs with different properties, it might create expectation of new properties being applied during data move, while actually it won't happen. For copies and checksum it may mean incorrect safety expectations. For dedup, compression and special_small_blocks -- performance and space usage. This is a replica of #18180 from FS. Reviewed-by: Ameer Hamza <ahamza@ixsystems.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com> Closes #18315
This commit is contained in:
parent
15e37e0919
commit
3583fa38e8
@ -108,6 +108,7 @@ unsigned int zvol_request_sync = 0;
|
||||
struct hlist_head *zvol_htable;
|
||||
static list_t zvol_state_list;
|
||||
krwlock_t zvol_state_lock;
|
||||
extern int zfs_bclone_strict_properties;
|
||||
extern int zfs_bclone_wait_dirty;
|
||||
zv_taskq_t zvol_taskqs;
|
||||
|
||||
@ -683,10 +684,47 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cloning between datasets with different properties is possible,
|
||||
* but it may cause confusions when copying data between them and
|
||||
* expecting new properties to apply.
|
||||
*/
|
||||
if (zfs_bclone_strict_properties && inos != outos &&
|
||||
!dmu_objset_is_snapshot(inos) &&
|
||||
(inos->os_checksum != outos->os_checksum ||
|
||||
inos->os_compress != outos->os_compress ||
|
||||
inos->os_copies != outos->os_copies ||
|
||||
inos->os_dedup_checksum != outos->os_dedup_checksum)) {
|
||||
error = SET_ERROR(EXDEV);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (zv_src->zv_volblocksize != zv_dst->zv_volblocksize) {
|
||||
error = SET_ERROR(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cloning between datasets with different special_small_blocks would
|
||||
* bypass storage tier migration that would occur with a regular copy.
|
||||
*/
|
||||
if (zfs_bclone_strict_properties && inos != outos &&
|
||||
!dmu_objset_is_snapshot(inos) &&
|
||||
spa_has_special(dmu_objset_spa(inos))) {
|
||||
uint64_t in_smallblk = inos->os_zpl_special_smallblock;
|
||||
uint64_t out_smallblk = outos->os_zpl_special_smallblock;
|
||||
if (in_smallblk != out_smallblk) {
|
||||
uint64_t min_smallblk = MIN(in_smallblk, out_smallblk);
|
||||
uint64_t max_smallblk = MAX(in_smallblk, out_smallblk);
|
||||
if (min_smallblk < zv_src->zv_volblocksize &&
|
||||
(inos->os_compress != ZIO_COMPRESS_OFF ||
|
||||
max_smallblk >= zv_src->zv_volblocksize)) {
|
||||
error = SET_ERROR(EXDEV);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inoff >= zv_src->zv_volsize || outoff >= zv_dst->zv_volsize) {
|
||||
goto out;
|
||||
}
|
||||
@ -701,6 +739,15 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
|
||||
if (len == 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Callers might not be able to detect properly that we are read-only,
|
||||
* so check it explicitly here.
|
||||
*/
|
||||
if (zv_dst->zv_flags & ZVOL_RDONLY) {
|
||||
error = SET_ERROR(EROFS);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* No overlapping if we are cloning within the same file
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user