diff options
author | Theodore Ts'o <tytso@mit.edu> | 2010-03-22 21:53:41 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-03-22 22:01:07 -0400 |
commit | 3c67a9f792d8a0b473144c5d05e1ecb4b57a37fd (patch) | |
tree | d9c195d6856ea90a39da82a5f384c435dd87616c /contrib | |
parent | 19f433a5214e720a95bdbf78bdcdca353c25b770 (diff) | |
download | e2fsprogs-3c67a9f792d8a0b473144c5d05e1ecb4b57a37fd.tar.gz |
Add fallocate.c to contrib from Eric Sandeen
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/fallocate.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/contrib/fallocate.c b/contrib/fallocate.c new file mode 100644 index 00000000..23684f3d --- /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 <sandeen@redhat.com> + * + * 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 <sys/stat.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> + +// #include <linux/falloc.h> +#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; +} |