Files
Ming Lei 1a76834bcf fs: introduce FALLOC_FL_WRITE_ZEROES to fallocate
JIRA: https://issues.redhat.com/browse/RHEL-144763

commit 7bd43cc79cab3850f34da0a31d5b042b701590ef
Author: Zhang Yi <yi.zhang@huawei.com>
Date:   Thu Jun 19 19:18:03 2025 +0800

    fs: introduce FALLOC_FL_WRITE_ZEROES to fallocate

    With the development of flash-based storage devices, we can quickly
    write zeros to SSDs using the WRITE_ZERO command if the devices do not
    actually write physical zeroes to the media. Therefore, we can use this
    command to quickly preallocate a real all-zero file with written
    extents. This approach should be beneficial for subsequent pure
    overwriting within this file, as it can save on block allocation and,
    consequently, significant metadata changes, which should greatly improve
    overwrite performance on certain filesystems.

    Therefore, introduce a new operation FALLOC_FL_WRITE_ZEROES to
    fallocate. This flag is used to convert a specified range of a file to
    zeros by issuing a zeroing operation. Blocks should be allocated for the
    regions that span holes in the file, and the entire range is converted
    to written extents. If the underlying device supports the actual offload
    write zeroes command, the process of zeroing out operation can be
    accelerated. If it does not, we currently don't prevent the file system
    from writing actual zeros to the device. This provides users with a new
    method to quickly generate a zeroed file, users no longer need to write
    zero data to create a file with written extents.

    Users can determine whether a disk supports the unmap write zeroes
    feature through querying this sysfs interface:

        /sys/block/<disk>/queue/write_zeroes_unmap_max_hw_bytes

    Users can also enable or disable the unmap write zeroes operation
    through this sysfs interface:

        /sys/block/<disk>/queue/write_zeroes_unmap_max_bytes

    Finally, this flag cannot be specified in conjunction with the
    FALLOC_FL_KEEP_SIZE since allocating written extents beyond file EOF is
    not permitted. In addition, filesystems that always require out-of-place
    writes should not support this flag since they still need to allocated
    new blocks during subsequent overwrites.

    Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
    Link: https://lore.kernel.org/20250619111806.3546162-7-yi.zhang@huaweicloud.com
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Martin K. Petersen" <martin.petersen@oracle.com>
    Signed-off-by: Christian Brauner <brauner@kernel.org>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2026-02-28 19:32:47 +08:00

64 lines
1.8 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _FALLOC_H_
#define _FALLOC_H_
#include <uapi/linux/falloc.h>
/*
* Space reservation ioctls and argument structure
* are designed to be compatible with the legacy XFS ioctls.
*/
struct space_resv {
__s16 l_type;
__s16 l_whence;
__s64 l_start;
__s64 l_len; /* len == 0 means until end of file */
__s32 l_sysid;
__u32 l_pid;
__s32 l_pad[4]; /* reserved area */
};
#define FS_IOC_RESVSP _IOW('X', 40, struct space_resv)
#define FS_IOC_UNRESVSP _IOW('X', 41, struct space_resv)
#define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
#define FS_IOC_UNRESVSP64 _IOW('X', 43, struct space_resv)
#define FS_IOC_ZERO_RANGE _IOW('X', 57, struct space_resv)
/*
* Mask of all supported fallocate modes. Only one can be set at a time.
*
* In addition to the mode bit, the mode argument can also encode flags.
* FALLOC_FL_KEEP_SIZE is the only supported flag so far.
*/
#define FALLOC_FL_MODE_MASK (FALLOC_FL_ALLOCATE_RANGE | \
FALLOC_FL_PUNCH_HOLE | \
FALLOC_FL_COLLAPSE_RANGE | \
FALLOC_FL_ZERO_RANGE | \
FALLOC_FL_INSERT_RANGE | \
FALLOC_FL_UNSHARE_RANGE | \
FALLOC_FL_WRITE_ZEROES)
/* on ia32 l_start is on a 32-bit boundary */
#if defined(CONFIG_X86_64)
struct space_resv_32 {
__s16 l_type;
__s16 l_whence;
__s64 l_start __attribute__((packed));
/* len == 0 means until end of file */
__s64 l_len __attribute__((packed));
__s32 l_sysid;
__u32 l_pid;
__s32 l_pad[4]; /* reserve area */
};
#define FS_IOC_RESVSP_32 _IOW ('X', 40, struct space_resv_32)
#define FS_IOC_UNRESVSP_32 _IOW ('X', 41, struct space_resv_32)
#define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32)
#define FS_IOC_UNRESVSP64_32 _IOW ('X', 43, struct space_resv_32)
#define FS_IOC_ZERO_RANGE_32 _IOW ('X', 57, struct space_resv_32)
#endif
#endif /* _FALLOC_H_ */