X-Git-Url: http://git.apps.os.sepia.ceph.com/?p=xfstests-dev.git;a=blobdiff_plain;f=src%2Falloc.c;h=4a446ca827d8e1d377b53ffd5eb79b157ca541f7;hp=e3f7afa8add0cfd213cdb50baa5e98b88babb62e;hb=479b5b5786dbf872ca0789ebb708243ca029086f;hpb=8ce73f86267bbe0e9ee9199527413f601ee2ff42 diff --git a/src/alloc.c b/src/alloc.c index e3f7afa8..4a446ca8 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,37 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + * Copyright (c) 2000-2003 Silicon Graphics, Inc. + * All Rights Reserved. */ #include "global.h" +/* + * Block I/O parameterization. A basic block (BB) is the lowest size of + * filesystem allocation, and must equal 512. Length units given to bio + * routines are in BB's. + */ + +/* Assume that if we have BTOBB, then we have the rest */ +#ifndef BTOBB +#define BBSHIFT 9 +#define BBSIZE (1<> BBSHIFT) +#define BTOBBT(bytes) ((__u64)(bytes) >> BBSHIFT) +#define BBTOB(bbs) ((bbs) << BBSHIFT) +#define OFFTOBBT(bytes) ((__u64)(bytes) >> BBSHIFT) + +#define SEEKLIMIT32 0x7fffffff +#define BBSEEKLIMIT32 BTOBBT(SEEKLIMIT32) +#define SEEKLIMIT 0x7fffffffffffffffLL +#define BBSEEKLIMIT OFFTOBBT(SEEKLIMIT) +#endif + +#ifndef OFFTOBB +#define OFFTOBB(bytes) (((__u64)(bytes) + BBSIZE - 1) >> BBSHIFT) +#define BBTOOFF(bbs) ((__u64)(bbs) << BBSHIFT) +#endif + #define FSBTOBB(f) (OFFTOBBT(FSBTOOFF(f))) #define BBTOFSB(b) (OFFTOFSB(BBTOOFF(b))) #define OFFTOFSB(o) ((o) / blocksize) @@ -58,74 +59,151 @@ void usage(void) } -int fd; -int blocksize = 0; +int fd = -1; +int blocksize; +char *filename; /* params are in bytes */ void map(off64_t off, off64_t len) { - struct getbmap bm[2]={{0}}; + struct getbmap bm[2]; + bzero(bm, sizeof(bm)); + bm[0].bmv_count = 2; bm[0].bmv_offset = OFFTOBB(off); if (len==(off64_t)-1) { /* unsigned... */ bm[0].bmv_length = -1; printf(" MAP off=%lld, len=%lld [%lld-]\n", - (__s64)off, (__s64)len, - (__s64)BBTOFSB(bm[0].bmv_offset)); + (long long)off, (long long)len, + (long long)BBTOFSB(bm[0].bmv_offset)); } else { bm[0].bmv_length = OFFTOBB(len); printf(" MAP off=%lld, len=%lld [%lld,%lld]\n", - (__s64)off, (__s64)len, - (__s64)BBTOFSB(bm[0].bmv_offset), - (__s64)BBTOFSB(bm[0].bmv_length)); + (long long)off, (long long)len, + (long long)BBTOFSB(bm[0].bmv_offset), + (long long)BBTOFSB(bm[0].bmv_length)); } printf(" [ofs,count]: start..end\n"); for (;;) { - if (ioctl(fd, XFS_IOC_GETBMAP, bm) < 0) { +#ifdef XFS_IOC_GETBMAP + if (xfsctl(filename, fd, XFS_IOC_GETBMAP, bm) < 0) { +#else +#ifdef F_GETBMAP + if (fcntl(fd, F_GETBMAP, bm) < 0) { +#else +bozo! +#endif +#endif perror("getbmap"); break; } + if (bm[0].bmv_entries == 0) break; + printf(" [%lld,%lld]: ", - (__s64)BBTOFSB(bm[1].bmv_offset), - (__s64)BBTOFSB(bm[1].bmv_length)); + (long long)BBTOFSB(bm[1].bmv_offset), + (long long)BBTOFSB(bm[1].bmv_length)); + if (bm[1].bmv_block == -1) printf("hole"); else printf("%lld..%lld", - (__s64)BBTOFSB(bm[1].bmv_block), - (__s64)BBTOFSB(bm[1].bmv_block + + (long long)BBTOFSB(bm[1].bmv_block), + (long long)BBTOFSB(bm[1].bmv_block + bm[1].bmv_length - 1)); printf("\n"); } } +#ifdef HAVE_FALLOCATE +# define USE_LINUX_PREALLOCATE +enum linux_opno { + FREESP = 0, + ALLOCSP, + UNRESVSP, + RESVSP, +}; + +/* emulate the irix preallocation functions with linux vfs calls */ +static int +linux_preallocate( + int fd, + enum linux_opno opno, + const struct flock64 *f) +{ + struct stat sbuf; + int ret; + + assert(f->l_whence == SEEK_SET); + + switch (opno) { + case FREESP: + return ftruncate(fd, f->l_start); + case ALLOCSP: + ret = fstat(fd, &sbuf); + if (ret) + return ret; + + return fallocate(fd, 0, sbuf.st_size, + f->l_start - sbuf.st_size); + case UNRESVSP: + return fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + f->l_start, f->l_len); + case RESVSP: + return fallocate(fd, FALLOC_FL_KEEP_SIZE, f->l_start, f->l_len); + } + + /* should never get here */ + errno = EINVAL; + return -1; +} +#endif + int main(int argc, char **argv) { int c; char *dirname = NULL; int done = 0; + int status = 0; struct flock64 f; - char *filename = NULL; off64_t len; char line[1024]; off64_t off; int oflags; - static char *opnames[] = - { "freesp", "allocsp", "unresvsp", "resvsp" }; + static char *opnames[] = { "freesp", + "allocsp", + "unresvsp", + "resvsp" }; int opno; - static int optab[] = - { XFS_IOC_FREESP64, XFS_IOC_ALLOCSP64, XFS_IOC_UNRESVSP64, XFS_IOC_RESVSP64 }; + +#if defined(HAVE_FALLOCATE) + /* see static function above */ +#elif defined(XFS_IOC_FREESP64) +#define USE_XFSCTL + /* Assume that if we have FREESP64 then we have the rest */ + static int optab[] = { XFS_IOC_FREESP64, + XFS_IOC_ALLOCSP64, + XFS_IOC_UNRESVSP64, + XFS_IOC_RESVSP64 }; +#elif defined(F_FREESP64) +#define USE_FCNTL + static int optab[] = { F_FREESP64, + F_ALLOCSP64, + F_UNRESVSP64, + F_RESVSP64 }; +#else +# error Dont know how to preallocate space! +#endif int rflag = 0; struct statvfs64 svfs; int tflag = 0; int nflag = 0; int unlinkit = 0; - __int64_t v; + int64_t v; while ((c = getopt(argc, argv, "b:d:f:rtn")) != -1) { switch (c) { @@ -181,32 +259,60 @@ main(int argc, char **argv) perror(filename); exit(1); } - if (unlinkit) - unlink(filename); if (!blocksize) { - if (fstatvfs64(fd, &svfs) < 0) { - perror(filename); - exit(1); - } + if (fstatvfs64(fd, &svfs) < 0) { + perror(filename); + status = 1; + goto done; + } blocksize = (int)svfs.f_bsize; - } - if (blocksize<0) { - fprintf(stderr,"illegal blocksize %d\n", blocksize); - exit(1); - } + } + if (blocksize<0) { + fprintf(stderr,"illegal blocksize %d\n", blocksize); + status = 1; + goto done; + } printf(" blocksize %d\n", blocksize); if (rflag) { struct fsxattr a; - if (ioctl(fd, XFS_IOC_FSGETXATTR, &a) < 0) { +#ifdef XFS_IOC_FSGETXATTR + if (xfsctl(filename, fd, XFS_IOC_FSGETXATTR, &a) < 0) { perror("XFS_IOC_FSGETXATTR"); - exit(1); + status = 1; + goto done; + } +#else +#ifdef F_FSGETXATTR + if (fcntl(fd, F_FSGETXATTR, &a) < 0) { + perror("F_FSGETXATTR"); + status = 1; + goto done; } +#else +bozo! +#endif +#endif + a.fsx_xflags |= XFS_XFLAG_REALTIME; - if (ioctl(fd, XFS_IOC_FSSETXATTR, &a) < 0) { + +#ifdef XFS_IOC_FSSETXATTR + if (xfsctl(filename, fd, XFS_IOC_FSSETXATTR, &a) < 0) { perror("XFS_IOC_FSSETXATTR"); - exit(1); + status = 1; + goto done; + } +#else +#ifdef F_FSSETXATTR + if (fcntl(fd, F_FSSETXATTR, &a) < 0) { + perror("F_FSSETXATTR"); + status = 1; + goto done; } +#else +bozo! +#endif +#endif } while (!done) { char *p; @@ -246,10 +352,18 @@ main(int argc, char **argv) len = v; printf(" CMD %s, off=%lld, len=%lld\n", - opnames[opno], (__s64)off, (__s64)len); + opnames[opno], (long long)off, (long long)len); f.l_len = len; - c = ioctl(fd, optab[opno], &f); +#if defined(USE_LINUX_PREALLOCATE) + c = linux_preallocate(fd, opno, &f); +#elif defined(USE_XFSCTL) + c = xfsctl(filename, fd, optab[opno], &f); +#elif defined(USE_FCNTL) + c = fcntl(fd, optab[opno], &f); +#else +# error Dont know how to preallocate space! +#endif if (c < 0) { perror(opnames[opno]); break; @@ -284,7 +398,7 @@ main(int argc, char **argv) off = FSBTOOFF(v); else off = v; - printf(" TRUNCATE off=%lld\n", (__s64)off); + printf(" TRUNCATE off=%lld\n", (long long)off); if (ftruncate64(fd, off) < 0) { perror("ftruncate"); break; @@ -307,8 +421,12 @@ main(int argc, char **argv) break; } } - if (!nflag) printf("\n"); - close(fd); - exit(0); + if (!nflag) printf("\n"); +done: + if (fd != -1) + close(fd); + if (unlinkit) + unlink(filename); + exit(status); /* NOTREACHED */ }