/* * 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 */ #include #include #include #include #include #include #include #include #include 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_CREAT); if (fd < 0) { perror("Error opening file"); exit(EXIT_FAILURE); } error = fallocate(fd, falloc_mode, offset, length); // error = syscall(SYS_fallocate, fd, falloc_mode, offset, length); if (error < 0) { perror("fallocate failed"); exit(EXIT_FAILURE); } close(fd); return 0; }