From 3c67a9f792d8a0b473144c5d05e1ecb4b57a37fd Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 22 Mar 2010 21:53:41 -0400 Subject: [PATCH] Add fallocate.c to contrib from Eric Sandeen Signed-off-by: "Theodore Ts'o" --- contrib/fallocate.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 contrib/fallocate.c diff --git a/contrib/fallocate.c b/contrib/fallocate.c new file mode 100644 index 0000000..23684f3 --- /dev/null +++ b/contrib/fallocate.c @@ -0,0 +1,152 @@ +/* + * fallocate - utility to use the fallocate system call + * + * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * Written by Eric Sandeen + * + * cvtnum routine taken from xfsprogs, + * Copyright (c) 2003-2005 Silicon Graphics, Inc. + * + * 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. + * + * This program is distributed in the hope that it would 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, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +// #include +#define FALLOC_FL_KEEP_SIZE 0x01 + +void usage(void) +{ + printf("Usage: fallocate [-n] [-o offset] -l length filename\n"); + exit(EXIT_FAILURE); +} + +#define EXABYTES(x) ((long long)(x) << 60) +#define PETABYTES(x) ((long long)(x) << 50) +#define TERABYTES(x) ((long long)(x) << 40) +#define GIGABYTES(x) ((long long)(x) << 30) +#define MEGABYTES(x) ((long long)(x) << 20) +#define KILOBYTES(x) ((long long)(x) << 10) + +long long +cvtnum(char *s) +{ + long long i; + char *sp; + int c; + + i = strtoll(s, &sp, 0); + if (i == 0 && sp == s) + return -1LL; + if (*sp == '\0') + return i; + if (sp[1] != '\0') + return -1LL; + + c = tolower(*sp); + switch (c) { + case 'k': + return KILOBYTES(i); + case 'm': + return MEGABYTES(i); + case 'g': + return GIGABYTES(i); + case 't': + return TERABYTES(i); + case 'p': + return PETABYTES(i); + case 'e': + return EXABYTES(i); + } + + return -1LL; +} + +int main(int argc, char **argv) +{ + int fd; + char *fname; + int opt; + loff_t length = -2LL; + loff_t offset = 0; + int falloc_mode = 0; + int error; + + while ((opt = getopt(argc, argv, "nl:o:")) != -1) { + switch(opt) { + case 'n': + /* do not change filesize */ + falloc_mode = FALLOC_FL_KEEP_SIZE; + break; + case 'l': + length = cvtnum(optarg); + break; + case 'o': + offset = cvtnum(optarg); + break; + default: + usage(); + } + } + + if (length == -2LL) { + printf("Error: no length argument specified\n"); + usage(); + } + + if (length <= 0) { + printf("Error: invalid length value specified\n"); + usage(); + } + + if (offset < 0) { + printf("Error: invalid offset value specified\n"); + usage(); + } + + if (optind == argc) { + printf("Error: no filename specified\n"); + usage(); + } + + fname = argv[optind++]; + + /* Should we create the file if it doesn't already exist? */ + fd = open(fname, O_WRONLY|O_DIRECTORY); + if (fd < 0) { + perror("Error opening file"); + exit(EXIT_FAILURE); + } + + error = syscall(SYS_fallocate, fd, falloc_mode, offset, length); + + if (error < 0) { + perror("fallocate failed"); + exit(EXIT_FAILURE); + } + + close(fd); + return 0; +} -- 1.8.3.1