diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index 2a7bcb9b0a69..10f8d8ff14fe 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -486,7 +486,11 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len) cred_t *cr = CRED(); int error = -EOPNOTSUPP; +#ifdef FALLOC_FL_PUNCH_HOLE + if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) +#else if (mode & FALLOC_FL_KEEP_SIZE) +#endif return (-EOPNOTSUPP); crhold(cr); @@ -494,7 +498,13 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len) #ifdef FALLOC_FL_PUNCH_HOLE if (mode & FALLOC_FL_PUNCH_HOLE) { flock64_t bf; + loff_t olen; + olen = i_size_read(ip); + if (offset > olen) + return (0); + if (offset + len > olen) + len = olen - offset; bf.l_type = F_WRLCK; bf.l_whence = 0; bf.l_start = offset; @@ -502,6 +512,9 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len) bf.l_pid = 0; error = -zfs_space(ip, F_FREESP, &bf, FWRITE, offset, cr); + if (!error) + truncate_inode_pages_range(ip->i_mapping, offset, + offset + len - 1); } #endif /* FALLOC_FL_PUNCH_HOLE */