@@ -956,6 +956,28 @@ xfs_flush_unmap_range(
return 0;
}
+int
+xfs_file_zeroinit_space(
+ struct xfs_inode *ip,
+ xfs_off_t offset,
+ xfs_off_t len)
+{
+ struct inode *inode = VFS_I(ip);
+ int error;
+
+ trace_xfs_zeroinit_file_space(ip, offset, len);
+
+ if (IS_DAX(inode))
+ error = dax_zeroinit_range(inode, offset, len,
+ &xfs_read_iomap_ops);
+ else
+ error = iomap_zeroout_range(inode, offset, len,
+ &xfs_read_iomap_ops);
+ if (error == -ECANCELED)
+ return -EOPNOTSUPP;
+ return error;
+}
+
int
xfs_free_file_space(
struct xfs_inode *ip,
@@ -61,6 +61,8 @@ int xfs_collapse_file_space(struct xfs_inode *, xfs_off_t offset,
xfs_off_t len);
int xfs_insert_file_space(struct xfs_inode *, xfs_off_t offset,
xfs_off_t len);
+int xfs_file_zeroinit_space(struct xfs_inode *ip, xfs_off_t offset,
+ xfs_off_t length);
/* EOF block manipulation functions */
bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force);
@@ -899,7 +899,8 @@ xfs_break_layouts(
#define XFS_FALLOC_FL_SUPPORTED \
(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | \
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE | \
- FALLOC_FL_INSERT_RANGE | FALLOC_FL_UNSHARE_RANGE)
+ FALLOC_FL_INSERT_RANGE | FALLOC_FL_UNSHARE_RANGE | \
+ FALLOC_FL_ZEROINIT_RANGE)
STATIC long
xfs_file_fallocate(
@@ -950,13 +951,17 @@ xfs_file_fallocate(
* handled at the right time by xfs_prepare_shift().
*/
if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE |
- FALLOC_FL_COLLAPSE_RANGE)) {
+ FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZEROINIT_RANGE)) {
error = xfs_flush_unmap_range(ip, offset, len);
if (error)
goto out_unlock;
}
- if (mode & FALLOC_FL_PUNCH_HOLE) {
+ if (mode & FALLOC_FL_ZEROINIT_RANGE) {
+ error = xfs_file_zeroinit_space(ip, offset, len);
+ if (error)
+ goto out_unlock;
+ } else if (mode & FALLOC_FL_PUNCH_HOLE) {
error = xfs_free_file_space(ip, offset, len);
if (error)
goto out_unlock;
@@ -1534,6 +1534,7 @@ DEFINE_SIMPLE_IO_EVENT(xfs_zero_eof);
DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write);
DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write_unwritten);
DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write_append);
+DEFINE_SIMPLE_IO_EVENT(xfs_zeroinit_file_space);
DECLARE_EVENT_CLASS(xfs_itrunc_class,
TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size),