Skip to content

Commit 4381f21

Browse files
committed
FreeBSD: Correct _PC_MIN_HOLE_SIZE
The actual minimum hole size on ZFS is variable, but we always report SPA_MINBLOCKSIZE, which is 512. This may lead applications to believe that they can reliably create holes at 512-byte boundaries and waste resources trying to punch holes that ZFS ends up filling anyway. * In the general case, if the vnode is a regular file, return its current block size, or the record size if the file is smaller than its own block size. If the vnode is a directory, return the dataset record size. If it is neither a regular file nor a directory, return EINVAL. * In the control directory case, always return EINVAL. Signed-off-by: Dag-Erling Smørgrav <[email protected]>
1 parent cb3c18a commit 4381f21

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

module/os/freebsd/zfs/zfs_ctldir.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,8 +764,7 @@ zfsctl_common_pathconf(struct vop_pathconf_args *ap)
764764
return (0);
765765

766766
case _PC_MIN_HOLE_SIZE:
767-
*ap->a_retval = (int)SPA_MINBLOCKSIZE;
768-
return (0);
767+
return (EINVAL);
769768

770769
case _PC_ACL_EXTENDED:
771770
*ap->a_retval = 0;

module/os/freebsd/zfs/zfs_vnops_os.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4118,6 +4118,7 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
41184118
{
41194119
znode_t *zp;
41204120
zfsvfs_t *zfsvfs;
4121+
uint_t blksize, iosize;
41214122
int error;
41224123

41234124
switch (cmd) {
@@ -4129,8 +4130,20 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
41294130
*valp = 64;
41304131
return (0);
41314132
case _PC_MIN_HOLE_SIZE:
4132-
*valp = (int)SPA_MINBLOCKSIZE;
4133-
return (0);
4133+
iosize = vp->v_mount->mnt_stat.f_iosize;
4134+
if (vp->v_type == VREG) {
4135+
zp = VTOZ(vp);
4136+
blksize = zp->z_blksz;
4137+
if (zp->z_size <= blksize)
4138+
blksize = MAX(blksize, iosize);
4139+
*valp = (int)blksize;
4140+
return (0);
4141+
}
4142+
if (vp->v_type == VDIR) {
4143+
*valp = (int)iosize;
4144+
return (0);
4145+
}
4146+
return (EINVAL);
41344147
case _PC_ACL_EXTENDED:
41354148
#if 0 /* POSIX ACLs are not implemented for ZFS on FreeBSD yet. */
41364149
zp = VTOZ(vp);

0 commit comments

Comments
 (0)