Files
apfstests/src/alloc.c
T
Dave Chinner c432589da3 src/: spdx license conversion
Mostly scripted like all the others, manually added tags to
Makefile, nsexec.c and t_mmap_writev.c. Manually touched up
open_by_handle.c and t_encrypted_d_revalidate.c post script.

Notes for future reference:
- src/log-writes/ code has no explicit copyright or license tags,
  nor does the upstream repository, hence license is unknown.
  Need Josef to clarify the license and send a patch adding SPDX
  tags to those files.

- src/perf code has no explicit copyright or license tags, but it
  was code submitted explictly for fstests so it is assumed to be
  GPLv2.0 and tagged as such. If this is incorrect, Josef will need
  to clarify copyright and the license and send patches to correct
  it.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
2018-06-22 10:38:07 +08:00

389 lines
8.5 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* 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 BBMASK (BBSIZE-1)
#define BTOBB(bytes) (((__u64)(bytes) + 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)
#define FSBTOOFF(f) ((f) * blocksize)
void usage(void)
{
printf("usage: alloc [-b blocksize] [-d dir] [-f file] [-n] [-r] [-t]\n"
"flags:\n"
" -n - non-interractive mode\n"
" -r - real time file\n"
" -t - truncate on open\n"
"\n"
"commands:\n"
" r [offset] [length] - reserve\n"
" u [offset] [length] - unreserve\n"
" a [offset] [length] - alloc *** identical to free\n"
" f [offset] [length] - free *** identical to alloc\n"
" m/p [offset] [length] - print map\n"
" s - sync file\n"
" t [offset] - truncate\n"
" q - quit\n"
" h/? - this help\n");
}
int fd = -1;
int blocksize;
char *filename;
/* params are in bytes */
void map(off64_t off, off64_t len)
{
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",
(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",
(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 (;;) {
#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]: ",
(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",
(long long)BBTOFSB(bm[1].bmv_block),
(long long)BBTOFSB(bm[1].bmv_block +
bm[1].bmv_length - 1));
printf("\n");
}
}
int
main(int argc, char **argv)
{
int c;
char *dirname = NULL;
int done = 0;
int status = 0;
struct flock64 f;
off64_t len;
char line[1024];
off64_t off;
int oflags;
static char *opnames[] = { "freesp",
"allocsp",
"unresvsp",
"resvsp" };
int opno;
/* Assume that if we have FREESP64 then we have the rest */
#ifdef XFS_IOC_FREESP64
#define USE_XFSCTL
static int optab[] = { XFS_IOC_FREESP64,
XFS_IOC_ALLOCSP64,
XFS_IOC_UNRESVSP64,
XFS_IOC_RESVSP64 };
#else
#ifdef F_FREESP64
#define USE_FCNTL
static int optab[] = { F_FREESP64,
F_ALLOCSP64,
F_UNRESVSP64,
F_RESVSP64 };
#else
bozo!
#endif
#endif
int rflag = 0;
struct statvfs64 svfs;
int tflag = 0;
int nflag = 0;
int unlinkit = 0;
int64_t v;
while ((c = getopt(argc, argv, "b:d:f:rtn")) != -1) {
switch (c) {
case 'b':
blocksize = atoi(optarg);
break;
case 'd':
if (filename) {
printf("can't specify both -d and -f\n");
exit(1);
}
dirname = optarg;
break;
case 'f':
if (dirname) {
printf("can't specify both -d and -f\n");
exit(1);
}
filename = optarg;
break;
case 'r':
rflag = 1;
break;
case 't':
tflag = 1;
break;
case 'n':
nflag++;
break;
default:
printf("unknown option\n");
usage();
exit(1);
}
}
if (!dirname && !filename)
dirname = ".";
if (!filename) {
static char tmpfile[] = "allocXXXXXX";
mkstemp(tmpfile);
filename = malloc(strlen(tmpfile) + strlen(dirname) + 2);
sprintf(filename, "%s/%s", dirname, tmpfile);
unlinkit = 1;
}
oflags = O_RDWR | O_CREAT | (tflag ? O_TRUNC : 0);
fd = open(filename, oflags, 0666);
if (!nflag) {
printf("alloc:\n");
printf(" filename %s\n", filename);
}
if (fd < 0) {
perror(filename);
exit(1);
}
if (!blocksize) {
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);
status = 1;
goto done;
}
printf(" blocksize %d\n", blocksize);
if (rflag) {
struct fsxattr a;
#ifdef XFS_IOC_FSGETXATTR
if (xfsctl(filename, fd, XFS_IOC_FSGETXATTR, &a) < 0) {
perror("XFS_IOC_FSGETXATTR");
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;
#ifdef XFS_IOC_FSSETXATTR
if (xfsctl(filename, fd, XFS_IOC_FSSETXATTR, &a) < 0) {
perror("XFS_IOC_FSSETXATTR");
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;
if (!nflag) printf("alloc> ");
fflush(stdout);
if (!fgets(line, 1024, stdin)) break;
p=line+strlen(line);
if (p!=line&&p[-1]=='\n') p[-1]=0;
opno = 0;
switch (line[0]) {
case 'r':
opno++;
case 'u':
opno++;
case 'a':
opno++;
case 'f':
v = strtoll(&line[2], &p, 0);
if (*p == 'b') {
off = FSBTOOFF(v);
p++;
} else
off = v;
f.l_whence = SEEK_SET;
f.l_start = off;
if (*p == '\0')
v = -1;
else
v = strtoll(p, &p, 0);
if (*p == 'b') {
len = FSBTOOFF(v);
p++;
} else
len = v;
printf(" CMD %s, off=%lld, len=%lld\n",
opnames[opno], (long long)off, (long long)len);
f.l_len = len;
#ifdef USE_XFSCTL
c = xfsctl(filename, fd, optab[opno], &f);
#else
#ifdef USE_FCNTL
c = fcntl(fd, optab[opno], &f);
#else
bozo!
#endif
#endif
if (c < 0) {
perror(opnames[opno]);
break;
}
map(off,len);
break;
case 'p':
case 'm':
p = &line[1];
v = strtoll(p, &p, 0);
if (*p == 'b') {
off = FSBTOOFF(v);
p++;
} else
off = v;
if (*p == '\0')
len = -1;
else {
v = strtoll(p, &p, 0);
if (*p == 'b')
len = FSBTOOFF(v);
else
len = v;
}
map(off,len);
break;
case 't':
p = &line[1];
v = strtoll(p, &p, 0);
if (*p == 'b')
off = FSBTOOFF(v);
else
off = v;
printf(" TRUNCATE off=%lld\n", (long long)off);
if (ftruncate64(fd, off) < 0) {
perror("ftruncate");
break;
}
break;
case 's':
printf(" SYNC\n");
fsync(fd);
break;
case 'q':
printf(" QUIT\n");
done = 1;
break;
case '?':
case 'h':
usage();
break;
default:
printf("unknown command '%s'\n", line);
break;
}
}
if (!nflag) printf("\n");
done:
if (fd != -1)
close(fd);
if (unlinkit)
unlink(filename);
exit(status);
/* NOTREACHED */
}