Skip to content

Commit 059ae68

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. 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 059ae68

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-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: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4118,6 +4118,8 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
41184118
{
41194119
znode_t *zp;
41204120
zfsvfs_t *zfsvfs;
4121+
uint32_t blksize;
4122+
u_longlong_t nblocks;
41214123
int error;
41224124

41234125
switch (cmd) {
@@ -4129,8 +4131,20 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
41294131
*valp = 64;
41304132
return (0);
41314133
case _PC_MIN_HOLE_SIZE:
4132-
*valp = (int)SPA_MINBLOCKSIZE;
4133-
return (0);
4134+
if (vp->v_type == VREG) {
4135+
zp = VTOZ(vp);
4136+
sa_object_size(zp->z_sa_hdl, &blksize, &nblocks);
4137+
if (nblocks < 2)
4138+
blksize = MAX(blksize,
4139+
vp->v_mount->mnt_stat.f_iosize);
4140+
*valp = (int)blksize;
4141+
return (0);
4142+
}
4143+
if (vp->v_type == VDIR) {
4144+
*valp = (int)vp->v_mount->mnt_stat.f_iosize;
4145+
return (0);
4146+
}
4147+
return (EINVAL);
41344148
case _PC_ACL_EXTENDED:
41354149
#if 0 /* POSIX ACLs are not implemented for ZFS on FreeBSD yet. */
41364150
zp = VTOZ(vp);

0 commit comments

Comments
 (0)