[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Trying to finalize loose ends of truncate.c fallocate
From: |
Matej Cepl |
Subject: |
[PATCH] Trying to finalize loose ends of truncate.c fallocate |
Date: |
Fri, 27 Feb 2009 14:36:07 +0100 |
* man/mkfile.8.xml: temporarily example of manpage for mkfile
* src/mkfile: script to use truncate to emulate mkfile(8)
* src/truncate.c: add option -a to user posix_fallocate before
creating a file
* tests/misc/truncate-fallocate: test truncate fallocate
functionality
* tests/misc/truncate-mkfile: test mkfile(8)
Signed-off-by: Matej Cepl <address@hidden>
---
doc/coreutils.texi | 9 ++++
man/mkfile.8.xml | 94 +++++++++++++++++++++++++++++++++++++++++
src/mkfile | 81 +++++++++++++++++++++++++++++++++++
src/truncate.c | 48 +++++++++++++++------
tests/Makefile.am | 1 +
tests/misc/truncate-fallocate | 57 +++++++++++++++++++++++++
tests/misc/truncate-mkfile | 72 +++++++++++++++++++++++++++++++
7 files changed, 349 insertions(+), 13 deletions(-)
create mode 100644 man/mkfile.8.xml
create mode 100755 src/mkfile
create mode 100755 tests/misc/truncate-fallocate
create mode 100755 tests/misc/truncate-mkfile
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 2c1fae5..d318e8d 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -10491,6 +10491,15 @@ The program accepts the following options. Also see
@ref{Common options}.
@table @samp
address@hidden -a
address@hidden --fallocate
address@hidden -a
address@hidden --fallocate
+When extending file use system call @command{fallocate}, which
+ensures that disk space is allocated for @var{FILE}. After a successful
+call subsequent writes in the specified files are guaranteed
+not to fail because of lack of disk space.
+
@item -c
@itemx --no-create
@opindex -c
diff --git a/man/mkfile.8.xml b/man/mkfile.8.xml
new file mode 100644
index 0000000..ba3d0b4
--- /dev/null
+++ b/man/mkfile.8.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<!-- lifted from troff+man by doclifter -->
+<refentry id='mkfile8'>
+<!-- Copyright (c) 2007 -->
+<!-- MATEJ Cepl. All rights reserved. -->
+<!-- Copyright (c) 2001, 2003, 2004 -->
+<!-- HATANOU Tomomi. All rights reserved. -->
+
+<!-- Redistribution and use in source and binary forms, with or without -->
+<!-- modification, are permitted provided that the following conditions -->
+<!-- are met: -->
+<!-- 1. Redistributions of source code must retain the above copyright -->
+<!-- notice, this list of conditions and the following disclaimer. -->
+<!-- 2. Redistributions in binary form must reproduce the above copyright -->
+<!-- notice, this list of conditions and the following disclaimer in the
-->
+<!-- documentation and/or other materials provided with the distribution.
-->
+<!-- @(#)mkfile.8 1.3 (HATANOU Tomomi) 2004/01/21 -->
+
+<info>
+ <date>2007-09-03</date>
+ <author>MatÄj Cepl <address@hidden></author>
+</info>
+<refmeta>
+<refentrytitle>MKFILE</refentrytitle>
+<manvolnum>8</manvolnum>
+<refmiscinfo class='date'>2007-09-03</refmiscinfo>
+<refmiscinfo class='source'>GNU</refmiscinfo>
+<refmiscinfo class='manual'>GNU</refmiscinfo>
+</refmeta>
+<refnamediv id='name'>
+<refname>mkfile</refname>
+<refpurpose>create a file</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+<refsynopsisdiv id='synopsis'>
+<cmdsynopsis>
+ <command>mkfile</command> <arg choice='opt'>-n </arg>
+ <arg choice='opt'>-v </arg>
+ <arg choice='plain'><replaceable>size</replaceable></arg>
+ <group choice='plain'><arg
choice='plain'><replaceable>e</replaceable></arg><arg
choice='plain'><replaceable>p</replaceable></arg><arg
choice='plain'><replaceable>t</replaceable></arg><arg
choice='plain'><replaceable>g</replaceable></arg><arg
choice='plain'><replaceable>m</replaceable></arg><arg
choice='plain'><replaceable>k</replaceable></arg><arg
choice='plain'><replaceable>b</replaceable></arg><arg
choice='plain'><replaceable>filename</replaceable></arg></group>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+
+<refsect1 id='description'><title>DESCRIPTION</title>
+<para>creates a file named
+<emphasis remap='I'>filename</emphasis>
+that are suitable for use as NFS-mounted swap areas,
+or as local swap areas.
+The file is padded with zeros by default.
+The default
+<emphasis remap='I'>size</emphasis>
+is in bytes, but it can be flagged as exabytes, petabytes, terabytes,
gigabytes, megabytes, kilobytes, or blocks, with the e, p, t, g, m, k, or b
suffixes, respectively.</para>
+</refsect1>
+
+<refsect1 id='options'><title>OPTIONS</title>
+<para>The following options are available:</para>
+<variablelist remap='TP'>
+ <varlistentry>
+ <term><option>-n</option></term>
+ <listitem>
+<para>Create an empty file.
+The size is noted, but disk blocks are not allocated
+until data is written to them.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-v</option></term>
+ <listitem>
+<para>Verbose.
+Report the names and sizes of created files.</para>
+
+ </listitem>
+ </varlistentry>
+</variablelist>
+</refsect1>
+
+<refsect1 id='see_also'><title>SEE ALSO</title>
+<para><citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>,</para>
+</refsect1>
+
+<refsect1 id='bugs'><title>BUGS</title>
+<para>Option
+<option>-n</option>
+is not tested well.</para>
+</refsect1>
+
+<refsect1 id='history'><title>HISTORY</title>
+<para>A command first appeared in SunOS.</para>
+</refsect1>
+</refentry>
diff --git a/src/mkfile b/src/mkfile
new file mode 100755
index 0000000..0c020ad
--- /dev/null
+++ b/src/mkfile
@@ -0,0 +1,81 @@
+#!/bin/bash
+# the original manpage is on
+# http://developer.apple.com/documentation/Darwin/Reference\
+# /ManPages/man8/mkfile.8.html
+# and
+# http://docs.sun.com/app/docs/doc/819-2240/6n4htdnbv?a=view
+SPARSE=0
+VERBOSE=0
+OPTFLAGS=""
+VERSION="1.0"
+COMMANDNAME="$0"
+
+function usage() {
+ cat - <<\EOF
+Usage: mkfile OPTION... SIZE FILE
+Create a new FILE of the specified size (possibly with sparse file) that is
+suitable for use as NFS-mounted swap areas, or as local swap areas.
+
+A FILE argument that does exist is overwritten.
+
+Mandatory arguments to long options are mandatory for short options too.
+ -n create a sparse file (the size is noted, but disk blocks are not
+ allocated until data is written to them)
+ -v be verbose (report the size of the file created)
+ -h display this help and exit
+
+SIZE is a number which may be followed by one of the following suffixes:
+KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.
+
+SIZE may also be prefixed by one of the following modifying characters:
+`+' extend by, `-' reduce by, `<' at most, `>' at least,
+`/' round down to multiple of, `%' round up to multiple of.
+
+SEE ALSO
+swapon(8)
+
+HISTORY
+A command first appeared in SunOS.
+
+Report truncate bugs to address@hidden
+GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
+General help using GNU software: <http://www.gnu.org/gethelp/>
+Report mkfile translation bugs to <http://translationproject.org/team/>
+EOF
+}
+
+while getopts ":vnh" OPTION ; do
+ case $OPTION in
+ v)
+ VERBOSE=1
+ ;;
+ n)
+ SPARSE=1
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+if [ $SPARSE -eq 0 ] ; then
+ OPTFLAGS=$OPTFLAGS"-a "
+fi
+
+shift $(($OPTIND - 1))
+SIZE="$1"
+
+shift 1
+FILE="$1"
+
+truncate $OPTFLAGS $SIZE $FILE
+RET=$?
+
+if [ $RET -eq 0 ] &&Â [ $VERBOSE -eq 1 ] ; then
+ echo >&2 "Created file $FILE of the size "$(stat --format="%s" $FILE)"."
+fi
diff --git a/src/truncate.c b/src/truncate.c
index c6f12b7..6eaeac0 100644
--- a/src/truncate.c
+++ b/src/truncate.c
@@ -15,6 +15,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Pádraig Brady
+ Extended to use posix_fallocate by MatÄj Cepl <address@hidden>
This is backwards compatible with the FreeBSD utility, but is more
flexible wrt the size specifications and the use of long options,
@@ -50,10 +51,13 @@ static bool block_mode;
/* (-r) Reference file to use size from */
static char const *ref_file;
-static struct option const longopts[] =
-{
+/* (-a) Use fallocate to create a file */
+static bool fallocate_mode;
+
+static struct option const longopts[] = {
{"no-create", no_argument, NULL, 'c'},
{"io-blocks", no_argument, NULL, 'o'},
+ {"fallocate", no_argument, NULL, 'a'},
{"reference", required_argument, NULL, 'r'},
{"size", required_argument, NULL, 's'},
{GETOPT_HELP_OPTION_DECL},
@@ -71,13 +75,12 @@ typedef enum
This supports dd BLOCK size suffixes + lowercase g,t,m for bsd compat
Note we don't support dd's b=512, c=1, w=2 or 21x512MiB formats. */
static int
-parse_len (char const *str, off_t *size)
+parse_len (char const *str, off_t * size)
{
enum strtol_error e;
intmax_t tmp_size;
e = xstrtoimax (str, NULL, 10, &tmp_size, "EgGkKmMPtTYZ0");
- if (e == LONGINT_OK
- && !(OFF_T_MIN <= tmp_size && tmp_size <= OFF_T_MAX))
+ if (e == LONGINT_OK && !(OFF_T_MIN <= tmp_size && tmp_size <= OFF_T_MAX))
e = LONGINT_OVERFLOW;
if (e == LONGINT_OK)
@@ -114,6 +117,9 @@ reads as zero bytes.\n\
Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
+ -a, --fallocate when extending a file use fallocate.\n\
+"), stdout);
+ fputs (_("\
-c, --no-create do not create any files\n\
"), stdout);
fputs (_("\
@@ -161,8 +167,7 @@ do_ftruncate (int fd, char const *fname, off_t ssize,
rel_mode_t rel_mode)
error (0, 0,
_("overflow in %" PRIdMAX
" * %" PRIdMAX " byte blocks for file %s"),
- (intmax_t) ssize, (intmax_t) blksize,
- quote (fname));
+ (intmax_t) ssize, (intmax_t) blksize, quote (fname));
return 1;
}
ssize *= blksize;
@@ -210,7 +215,7 @@ do_ftruncate (int fd, char const *fname, off_t ssize,
rel_mode_t rel_mode)
}
else
{
- if (ssize > OFF_T_MAX - (off_t)fsize)
+ if (ssize > OFF_T_MAX - (off_t) fsize)
{
error (0, 0, _("overflow extending size of file %s"),
quote (fname));
@@ -224,6 +229,20 @@ do_ftruncate (int fd, char const *fname, off_t ssize,
rel_mode_t rel_mode)
if (nsize < 0)
nsize = 0;
+ /* posix_fallocate() is available since glibc 2.1.94.
+ * fallocate is in Linux since kernel 2.6.23.
+ */
+ if (fallocate_mode)
+ {
+ int ret = 0;
+ if ((ret = posix_fallocate (fd, 0, nsize)) != 0)
+ {
+ error (0, ret, _("cannot fallocate size %d for file %s"), nsize,
+ quote (fname));
+ return 1;
+ }
+ }
+
if (ftruncate (fd, nsize) == -1) /* note updates mtime & ctime */
{
/* Complain only when ftruncate fails on a regular file, a
@@ -255,7 +274,7 @@ int
main (int argc, char **argv)
{
bool got_size = false;
- off_t size IF_LINT (= 0);
+ off_t size IF_LINT ( = 0);
rel_mode_t rel_mode = rm_abs;
mode_t omode;
int c, errors = 0, fd = -1, oflags;
@@ -269,10 +288,14 @@ main (int argc, char **argv)
atexit (close_stdout);
- while ((c = getopt_long (argc, argv, "cor:s:", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "acor:s:", longopts, NULL)) != -1)
{
switch (c)
{
+ case 'a':
+ fallocate_mode = true;
+ break;
+
case 'c':
no_create = true;
break;
@@ -330,9 +353,9 @@ main (int argc, char **argv)
got_size = true;
break;
- case_GETOPT_HELP_CHAR;
+ case_GETOPT_HELP_CHAR;
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
@@ -402,7 +425,6 @@ main (int argc, char **argv)
continue;
}
-
if (fd != -1)
{
errors += do_ftruncate (fd, fname, size, rel_mode);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 07e9473..d6e6426 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -231,6 +231,7 @@ TESTS = \
misc/truncate-overflow \
misc/truncate-parameters \
misc/truncate-relative \
+ misc/truncate-fallocate \
misc/tsort \
misc/tty-eof \
misc/unexpand \
diff --git a/tests/misc/truncate-fallocate b/tests/misc/truncate-fallocate
new file mode 100755
index 0000000..bce4083
--- /dev/null
+++ b/tests/misc/truncate-fallocate
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# Copyright (C) 2008 Free Software Foundation, Inc.
+# Written by MatÄj Cepl <address@hidden>
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+export LANG=C
+TESTSIZE=200k
+TESTFILE=testfile
+
+if test "$VERBOSE" = yes; then
+ set -x
+ truncate --version
+fi
+
+. $srcdir/lang-default
+. $srcdir/test-lib.sh
+skip_if_root_
+
+trap EXIT rm -f $TESTFILE
+
+fail=0
+
+[ -f $TESTFILE ] && rm -f $TESTFILE
+truncate -a -s $TESTSIZE $TESTFILE || fail=1
+
+if [ ! $fail -eq 1 ] ; then
+ size=$(stat --format="%s" $TESTFILE)
+ if [ "$(($size - 204800))" -gt 1024 ] ; then
+ echo "Cannot create file $TESTFILE of $TESTSIZE size."
+ fail=1
+ fi
+fi
+
+[ -f $TESTFILE ] && rm -f $TESTFILE
+if [ ! $fail -eq 1 ] ; then
+ truncate -a $TESTFILE || fail=1
+fi
+
+[ -f $TESTFILE ] && rm -f $TESTFILE
+if [ ! $fail -eq 1 ] ; then
+ truncate -s || fail=1
+fi
+
+Exit $fail
diff --git a/tests/misc/truncate-mkfile b/tests/misc/truncate-mkfile
new file mode 100755
index 0000000..90531a6
--- /dev/null
+++ b/tests/misc/truncate-mkfile
@@ -0,0 +1,72 @@
+#!/bin/sh
+# make sure truncate gives reasonable diagnostics
+
+# Copyright (C) 2008 Free Software Foundation, Inc.
+# Written by MatÄj Cepl <address@hidden>
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+export LANG=C
+TESTSIZE=200k
+TESTFILE=testfile
+
+if test "$VERBOSE" = yes; then
+ set -x
+ truncate --version
+fi
+
+. $srcdir/lang-default
+. $srcdir/test-lib.sh
+skip_if_root_
+
+trap EXIT rm -f $TESTFILE
+
+fail=0
+
+[ -f $TESTFILE ] && rm -f $TESTFILE
+mkfile $TESTSIZE $TESTFILE || fail=1
+
+if [ ! $fail -eq 1 ] ; then
+ size=$(stat --format="%s" $TESTFILE)
+ if [ "$(($size - 204800))" -gt 1024 ] ; then
+ echo "Cannot create file $TESTFILE of $TESTSIZE size."
+ fail=1
+ fi
+fi
+
+# Sparse file creation
+[ -f $TESTFILE ] && rm -f $TESTFILE
+mkfile -n $TESTSIZE $TESTFILE || fail=1
+
+if [ ! $fail -eq 1 ] ; then
+ size=$(stat --format="%s" $TESTFILE)
+ blocks=$(stat --format="%s" $TESTFILE)
+ if [ "$(($size - 204800))" -gt 1024 ] ; then
+ echo "Cannot create file $TESTFILE of $TESTSIZE size."
+ fail=1
+ fi
+fi
+
+# Non-sensical option
+[ -f $TESTFILE ] && rm -f $TESTFILE
+if [ ! $fail -eq 1 ] ; then
+ truncate -s $TESTFILE && fail=1
+fi
+
+[ -f $TESTFILE ] && rm -f $TESTFILE
+if [ ! $fail -eq 1 ] ; then
+ truncate -s || fail=1
+fi
+
+Exit $fail
--
1.6.0.6
- mkfile -- create large files efficiently, Matej Cepl, 2009/02/06
- [PATCH] mkfile -- create large files efficiently, Matej Cepl, 2009/02/06
- Re: mkfile -- create large files efficiently, Pádraig Brady, 2009/02/06
- Re: mkfile -- create large files efficiently, Matej Cepl, 2009/02/07
- Re: mkfile -- create large files efficiently, Pádraig Brady, 2009/02/07
- Re: mkfile -- create large files efficiently, Matej Cepl, 2009/02/08
- Re: mkfile -- create large files efficiently, Pádraig Brady, 2009/02/08
- Re: mkfile -- create large files efficiently, Jim Meyering, 2009/02/09
- [PATCH] Trying to finalize loose ends of truncate.c fallocate,
Matej Cepl <=
- Re: [PATCH] Trying to finalize loose ends of truncate.c fallocate, Eric Blake, 2009/02/27
- Re: [PATCH] Trying to finalize loose ends of truncate.c fallocate, Pádraig Brady, 2009/02/27
- Re: [PATCH] Trying to finalize loose ends of truncate.c fallocate, Matej Cepl, 2009/02/27
- Re: [PATCH] Trying to finalize loose ends of truncate.c fallocate, Eric Blake, 2009/02/28
- Re: mkfile -- create large files efficiently, Matej Cepl, 2009/02/27
- [PATCH] Following up on the comments from the upstream, Matej Cepl, 2009/02/27
- Re: mkfile -- create large files efficiently, Jim Meyering, 2009/02/28