Restrict short block cloning requests

If we are copying only one block and it is smaller than recordsize
property, do not allow destination to grow beyond one block if it
is not there yet.  Otherwise the destination will get stuck with
that block size forever, that can be as small as 512 bytes, no
matter how big the destination grow later.

Reviewed-by: Kay Pedersen <mail@mkwg.de>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #15321
This commit is contained in:
Alexander Motin 2023-09-29 11:22:46 -04:00 committed by GitHub
parent f9c39dc862
commit e135388564
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1206,6 +1206,19 @@ zfs_clone_range(znode_t *inzp, uint64_t *inoffp, znode_t *outzp,
goto unlock;
}
/*
* If we are copying only one block and it is smaller than recordsize
* property, do not allow destination to grow beyond one block if it
* is not there yet. Otherwise the destination will get stuck with
* that block size forever, that can be as small as 512 bytes, no
* matter how big the destination grow later.
*/
if (len <= inblksz && inblksz < outzfsvfs->z_max_blksz &&
outzp->z_size <= inblksz && outoff + len > inblksz) {
error = SET_ERROR(EINVAL);
goto unlock;
}
error = zn_rlimit_fsize(outoff + len);
if (error != 0) {
goto unlock;