]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fallocate: Added posix_fallocate() support.
authorDenis Chaplygin <dchaplyg@redhat.com>
Tue, 31 Jan 2017 11:51:28 +0000 (12:51 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 31 Jan 2017 11:51:28 +0000 (12:51 +0100)
No all filesystems support Linux fallocate. The new option allow use
posix implementation if necessary.

Signed-off-by: Karel Zak <kzak@redhat.com>
AUTHORS
configure.ac
sys-utils/fallocate.1
sys-utils/fallocate.c

diff --git a/AUTHORS b/AUTHORS
index 9bf4f25dcb336924760a205b170e4218281500f4..04d1276387910d046babb26b64600c87bf7847e1 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -186,6 +186,7 @@ CONTRIBUTORS:
       David Shea <dshea@redhat.com>
       David Woodhouse <dwmw2@infradead.org>
       Deiz <silverwraithii@gmail.com>
+      Denis Chaplygin <dchaplyg@redhat.com>
       Denis ChengRq <crquan@gmail.com>
       Dennis Gilmore <dennis@ausil.us>
       Dennis H Jensen <dennis.h.jensen@siemens.com>
index fa3e6c83130cd6f63e5c562aa9b8c89c47bdd391..37599212cef04b18a2c783f526b302e6f0e314b4 100644 (file)
@@ -1195,6 +1195,34 @@ AS_IF([test "x$build_fallocate" = xyes], [
   AC_MSG_RESULT([no])])
 ])
 
+AS_IF([test "x$build_fallocate" = xyes], [
+  dnl check for valid posix_fallocate() function
+  AC_MSG_CHECKING([for valid posix_fallocate() function])
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_LINUX_FALLOC_H
+# include <linux/falloc.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+]],[[
+   long ret;
+   ret = posix_fallocate(0, 0xfffffffful, 0xfffffffful);
+   if (ret != 0) {
+      return 1;
+   }
+   ]])],[
+  AC_MSG_RESULT([yes])
+  AC_DEFINE([HAVE_POSIX_FALLOCATE], [1], [Have valid posix_fallocate() function])],[
+  AC_MSG_RESULT([no])])
+])
+
 
 AC_ARG_ENABLE([unshare],
   AS_HELP_STRING([--disable-unshare], [do not build unshare]),
index 6133b71c82d86ea759ea9cbe8c02d03d8a348917..0cbb5c9944689327fbc0a3e932334f748efb0fbc 100644 (file)
@@ -17,6 +17,13 @@ fallocate \- preallocate or deallocate space to a file
 .RB [ \-l
 .IR length ]
 .I filename
+.PP
+.B fallocate \-x
+.RB [ \-o
+.IR offset ]
+.RB \-l
+.IR length
+.I filename
 .SH DESCRIPTION
 .B fallocate
 is used to manipulate the allocated disk space for a file, either to deallocate
@@ -88,6 +95,10 @@ Btrfs (since Linux 3.7) and tmpfs (since Linux 3.5).
 .BR \-v , " \-\-verbose"
 Enable verbose mode.
 .TP
+.BR \-x , " \-\-posix"
+Enable POSIX operation mode. In that mode allocation operation always completes,
+but it may take longer time when fast allocation is not supported by the underlying filesystem.
+.TP
 .BR \-z , " \-\-zero\-range"
 Zeroes space in the byte range starting at \fIoffset\fP and
 continuing for \fIlength\fR bytes.  Within the specified range, blocks are
index eb37b38388d013214cc9d9fbf6f3a68a88d36fd3..8cbb91c23c4d38723d869479e575f29b061bfc6b 100644 (file)
@@ -94,6 +94,9 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
        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);
+#ifdef HAVE_POSIX_FALLOCATE
+       fputs(_(" -x, --posix          use posix_fallocate(3) instead of fallocate(2)\n"), out);
+#endif
        fputs(_(" -v, --verbose        verbose mode\n"), out);
 
        fputs(USAGE_SEPARATOR, out);
@@ -134,6 +137,15 @@ static void xfallocate(int fd, int mode, off_t offset, off_t length)
        }
 }
 
+#ifdef HAVE_POSIX_FALLOCATE
+static void xposix_fallocate(int fd, off_t offset, off_t length)
+{
+       int error = posix_fallocate(fd, offset, length);
+       if (error < 0) {
+               err(EXIT_FAILURE, _("fallocate failed"));
+       }
+}
+#endif
 
 static int skip_hole(int fd, off_t *off)
 {
@@ -277,6 +289,7 @@ int main(int argc, char **argv)
        int     fd;
        int     mode = 0;
        int     dig = 0;
+       int posix = 0;
        loff_t  length = -2LL;
        loff_t  offset = 0;
 
@@ -291,6 +304,7 @@ int main(int argc, char **argv)
            { "zero-range",     0, 0, 'z' },
            { "offset",         1, 0, 'o' },
            { "length",         1, 0, 'l' },
+           { "posix",          0, 0, 'x' },
            { "verbose",        0, 0, 'v' },
            { NULL,             0, 0, 0 }
        };
@@ -298,6 +312,7 @@ int main(int argc, char **argv)
        static const ul_excl_t excl[] = {       /* rows and cols in in ASCII order */
                { 'c', 'd', 'p', 'z' },
                { 'c', 'n' },
+               { 'x', 'c', 'd', 'i', 'n', 'p', 'z'},
                { 0 }
        };
        int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
@@ -307,7 +322,7 @@ int main(int argc, char **argv)
        textdomain(PACKAGE);
        atexit(close_stdout);
 
-       while ((c = getopt_long(argc, argv, "hvVncpdizl:o:", longopts, NULL))
+       while ((c = getopt_long(argc, argv, "hvVncpdizxl:o:", longopts, NULL))
                        != -1) {
 
                err_exclusive_options(c, longopts, excl, excl_st);
@@ -340,6 +355,13 @@ int main(int argc, char **argv)
                case 'z':
                        mode |= FALLOC_FL_ZERO_RANGE;
                        break;
+               case 'x':
+#ifdef HAVE_POSIX_FALLOCATE
+                       posix = 1;
+                       break;
+#else
+                       errx(EXIT_FAILURE, _("posix_fallocate support is not compiled"))
+#endif
                case 'v':
                        verbose++;
                        break;
@@ -384,6 +406,10 @@ int main(int argc, char **argv)
 
        if (dig)
                dig_holes(fd, offset, length);
+#ifdef HAVE_POSIX_FALLOCATE
+       else if (posix)
+               xposix_fallocate(fd, offset, length);
+#endif
        else
                xfallocate(fd, mode, offset, length);