From: Zhang Yi <yi.zh...@huawei.com>

The Linux kernel is planning to supports FALLOC_FL_WRITE_ZEROES in
fallocate(2). Add FALLOC_FL_ZERO_RANGE support to fallocate utility by
introducing a new option -w|--write-zeroes.

Signed-off-by: Zhang Yi <yi.zh...@huawei.com>
---
 sys-utils/fallocate.1.adoc | 11 +++++++++--
 sys-utils/fallocate.c      | 20 ++++++++++++++++----
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/sys-utils/fallocate.1.adoc b/sys-utils/fallocate.1.adoc
index 44ee0ef4c..f9226b909 100644
--- a/sys-utils/fallocate.1.adoc
+++ b/sys-utils/fallocate.1.adoc
@@ -12,7 +12,7 @@ fallocate - preallocate or deallocate space to a file
 
 == SYNOPSIS
 
-*fallocate* [*-c*|*-p*|*-z*] [*-o* _offset_] *-l* _length_ [*-n*] _filename_
+*fallocate* [*-c*|*-p*|*-z*|*-w*] [*-o* _offset_] *-l* _length_ [*-n*] 
_filename_
 
 *fallocate* *-d* [*-o* _offset_] [*-l* _length_] _filename_
 
@@ -28,7 +28,7 @@ The exit status returned by *fallocate* is 0 on success and 1 
on failure.
 
 The _length_ and _offset_ arguments may be followed by the multiplicative 
suffixes KiB (=1024), MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB, 
and YiB (the "iB" is optional, e.g., "K" has the same meaning as "KiB") or the 
suffixes KB (=1000), MB (=1000*1000), and so on for GB, TB, PB, EB, ZB, and YB.
 
-The options *--collapse-range*, *--dig-holes*, *--punch-hole*, *--zero-range* 
and *--posix* are mutually exclusive.
+The options *--collapse-range*, *--dig-holes*, *--punch-hole*, *--zero-range*, 
*--write-zeroes* and *--posix* are mutually exclusive.
 
 *-c*, *--collapse-range*::
 Removes a byte range from a file, without leaving a hole. The byte range to be 
collapsed starts at _offset_ and continues for _length_ bytes. At the 
completion of the operation, the contents of the file starting at the location 
__offset__+_length_ will be appended at the location _offset_, and the file 
will be _length_ bytes smaller. The option *--keep-size* may not be specified 
for the collapse-range operation.
@@ -76,6 +76,13 @@ Option *--keep-size* can be specified to prevent file length 
modification.
 +
 Available since Linux 3.14 for ext4 (only for extent-based files) and XFS.
 
+*-w*, *--write-zeroes*::
+Zeroes space in the byte range starting at _offset_ and continuing for 
_length_ bytes. Within the specified range, blocks are preallocated for the 
regions that span the holes in the file. After a successful call, subsequent 
reads from this range will return zeroes.
++
+Zeroing is done within the filesystem by preferably submitting write zeores 
commands, the alternative way is submitting actual zeroed data, the specified 
range will be converted into written extents. The write zeroes command is 
significantly faster than write actual data if the device supports unmap write 
zeroes, and the specified range will not be physically zeroed out on the device.
++
+Options *--keep-size* can not be specified for the write-zeroes operation.
+
 include::man-common/help-version.adoc[]
 
 == AUTHORS
diff --git a/sys-utils/fallocate.c b/sys-utils/fallocate.c
index fff75b03f..69e1e1e5b 100644
--- a/sys-utils/fallocate.c
+++ b/sys-utils/fallocate.c
@@ -41,7 +41,7 @@
 #if defined(HAVE_LINUX_FALLOC_H) && \
     (!defined(FALLOC_FL_KEEP_SIZE) || !defined(FALLOC_FL_PUNCH_HOLE) || \
      !defined(FALLOC_FL_COLLAPSE_RANGE) || !defined(FALLOC_FL_ZERO_RANGE) || \
-     !defined(FALLOC_FL_INSERT_RANGE))
+     !defined(FALLOC_FL_INSERT_RANGE) || !defined(FALLOC_FL_WRITE_ZEROES))
 # include <linux/falloc.h>     /* non-libc fallback for FALLOC_FL_* flags */
 #endif
 
@@ -66,6 +66,10 @@
 # define FALLOC_FL_INSERT_RANGE                0x20
 #endif
 
+#ifndef FALLOC_FL_WRITE_ZEROES
+# define FALLOC_FL_WRITE_ZEROES                0x80
+#endif
+
 #include "nls.h"
 #include "strutils.h"
 #include "c.h"
@@ -95,6 +99,7 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_(" -o, --offset <num>   offset for range operations, in 
bytes\n"), out);
        fputs(_(" -p, --punch-hole     replace a range with a hole (implies 
-n)\n"), out);
        fputs(_(" -z, --zero-range     zero and ensure allocation of a 
range\n"), out);
+       fputs(_(" -w, --write-zeroes   write zeroes and ensure allocation of a 
range\n"), out);
 #ifdef HAVE_POSIX_FALLOCATE
        fputs(_(" -x, --posix          use posix_fallocate(3) instead of 
fallocate(2)\n"), out);
 #endif
@@ -305,6 +310,7 @@ int main(int argc, char **argv)
            { "dig-holes",      no_argument,       NULL, 'd' },
            { "insert-range",   no_argument,       NULL, 'i' },
            { "zero-range",     no_argument,       NULL, 'z' },
+           { "write-zeroes",   no_argument,       NULL, 'w' },
            { "offset",         required_argument, NULL, 'o' },
            { "length",         required_argument, NULL, 'l' },
            { "posix",          no_argument,       NULL, 'x' },
@@ -313,8 +319,8 @@ int main(int argc, char **argv)
        };
 
        static const ul_excl_t excl[] = {       /* rows and cols in ASCII order 
*/
-               { 'c', 'd', 'i', 'p', 'x', 'z'},
-               { 'c', 'i', 'n', 'x' },
+               { 'c', 'd', 'i', 'p', 'w', 'x', 'z'},
+               { 'c', 'i', 'n', 'w', 'x' },
                { 0 }
        };
        int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
@@ -324,7 +330,7 @@ int main(int argc, char **argv)
        textdomain(PACKAGE);
        close_stdout_atexit();
 
-       while ((c = getopt_long(argc, argv, "hvVncpdizxl:o:", longopts, NULL))
+       while ((c = getopt_long(argc, argv, "hvVncpdizwxl:o:", longopts, NULL))
                        != -1) {
 
                err_exclusive_options(c, longopts, excl, excl_st);
@@ -354,6 +360,9 @@ int main(int argc, char **argv)
                case 'z':
                        mode |= FALLOC_FL_ZERO_RANGE;
                        break;
+               case 'w':
+                       mode |= FALLOC_FL_WRITE_ZEROES;
+                       break;
                case 'x':
 #ifdef HAVE_POSIX_FALLOCATE
                        posix = 1;
@@ -430,6 +439,9 @@ int main(int argc, char **argv)
                        else if (mode & FALLOC_FL_ZERO_RANGE)
                                fprintf(stdout, _("%s: %s (%ju bytes) 
zeroed.\n"),
                                                                filename, str, 
length);
+                       else if (mode & FALLOC_FL_WRITE_ZEROES)
+                               fprintf(stdout, _("%s: %s (%ju bytes) write 
zeroed.\n"),
+                                                               filename, str, 
length);
                        else
                                fprintf(stdout, _("%s: %s (%ju bytes) 
allocated.\n"),
                                                                filename, str, 
length);
-- 
2.46.1


Reply via email to