summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--configure.ac28
-rw-r--r--sys-utils/fallocate.111
-rw-r--r--sys-utils/fallocate.c28
4 files changed, 67 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index 9bf4f25dc..04d127638 100644
--- 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>
diff --git a/configure.ac b/configure.ac
index fa3e6c831..37599212c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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]),
diff --git a/sys-utils/fallocate.1 b/sys-utils/fallocate.1
index 6133b71c8..0cbb5c994 100644
--- a/sys-utils/fallocate.1
+++ b/sys-utils/fallocate.1
@@ -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
diff --git a/sys-utils/fallocate.c b/sys-utils/fallocate.c
index eb37b3838..8cbb91c23 100644
--- a/sys-utils/fallocate.c
+++ b/sys-utils/fallocate.c
@@ -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);