This is implemented in the same way as the other fallocate modes. All of them map to XFS ioctls that are implemented by xfs_change_file_space. However, we need to cap the length to the inode size if the user requested FALLOC_FL_KEEP_SIZE. Cc: Dave Chinner <dchinner@xxxxxxxxxx> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- fs/xfs/xfs_file.c | 36 ++++++++++++++++++++++++------------ 1 files changed, 24 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 9f7ec15..c811cf9 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -818,33 +818,45 @@ xfs_file_fallocate( loff_t new_size = 0; xfs_flock64_t bf; xfs_inode_t *ip = XFS_I(inode); - int cmd = XFS_IOC_RESVSP; + int cmd; int attr_flags = XFS_ATTR_NOLOCK; - if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) + if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | + FALLOC_FL_ZERO_RANGE)) return -EOPNOTSUPP; + BUG_ON((mode & FALLOC_FL_PUNCH_HOLE) && (mode & FALLOC_FL_ZERO_RANGE)); + bf.l_whence = 0; bf.l_start = offset; bf.l_len = len; xfs_ilock(ip, XFS_IOLOCK_EXCL); - if (mode & FALLOC_FL_PUNCH_HOLE) - cmd = XFS_IOC_UNRESVSP; - - /* check the new inode size is valid before allocating */ - if (!(mode & FALLOC_FL_KEEP_SIZE) && - offset + len > i_size_read(inode)) { - new_size = offset + len; - error = inode_newsize_ok(inode, new_size); - if (error) - goto out_unlock; + if (offset + len > i_size_read(inode)) { + if (mode & FALLOC_FL_KEEP_SIZE) { + if (offset > i_size_read(inode)) + goto out_unlock; + len = i_size_read(inode) - offset; + } else { + /* check validity of new inode size before allocating */ + new_size = offset + len; + error = inode_newsize_ok(inode, new_size); + if (error) + goto out_unlock; + } } if (file->f_flags & O_DSYNC) attr_flags |= XFS_ATTR_SYNC; + if (mode & FALLOC_FL_PUNCH_HOLE) + cmd = XFS_IOC_UNRESVSP; + else if (mode & FALLOC_FL_ZERO_RANGE) + cmd = XFS_IOC_ZERO_RANGE; + else + cmd = XFS_IOC_RESVSP; + error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags); if (error) goto out_unlock; -- 1.7.1 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs