Implement the truncate_range() inode operation.
This operation allows "hole punching" in ZFS files. On Solaris this is done via the vop_space() system call, which maps to the zfs_space() function. So we just need to write zpl_truncate_range() as a wrapper around zfs_space(). Note that this only works for regular files, not ZVOLs. This is currently an insecure implementation without permission checking, although this isn't that big of a deal since truncate_range() isn't even callable from userspace. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Issue #334
This commit is contained in:
parent
93648f314c
commit
5cb63a57f8
@ -315,6 +315,33 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
zpl_truncate_range(struct inode* ip, loff_t start, loff_t end)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
flock64_t bf;
|
||||
|
||||
ASSERT3S(start, <=, end);
|
||||
|
||||
/*
|
||||
* zfs_freesp() will interpret (len == 0) as meaning "truncate until
|
||||
* the end of the file". We don't want that.
|
||||
*/
|
||||
if (start == end)
|
||||
return;
|
||||
|
||||
crhold(cr);
|
||||
|
||||
bf.l_type = F_WRLCK;
|
||||
bf.l_whence = 0;
|
||||
bf.l_start = start;
|
||||
bf.l_len = end - start;
|
||||
bf.l_pid = 0;
|
||||
zfs_space(ip, F_FREESP, &bf, FWRITE, start, cr);
|
||||
|
||||
crfree(cr);
|
||||
}
|
||||
|
||||
const struct inode_operations zpl_inode_operations = {
|
||||
.create = zpl_create,
|
||||
.link = zpl_link,
|
||||
@ -330,6 +357,7 @@ const struct inode_operations zpl_inode_operations = {
|
||||
.getxattr = generic_getxattr,
|
||||
.removexattr = generic_removexattr,
|
||||
.listxattr = zpl_xattr_list,
|
||||
.truncate_range = zpl_truncate_range,
|
||||
};
|
||||
|
||||
const struct inode_operations zpl_dir_inode_operations = {
|
||||
|
Loading…
Reference in New Issue
Block a user