fallocate: Added posix_fallocate() support.

No all filesystems support Linux fallocate. The new option allow use
posix implementation if necessary.

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Denis Chaplygin 2017-01-31 12:51:28 +01:00 committed by Karel Zak
parent 7572fb2b8c
commit 833f9a7aae
4 changed files with 67 additions and 1 deletions

View File

@ -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>

View 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]),

View 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

View 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);