1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003 Silicon Graphics, Inc.
10 * Block I/O parameterization. A basic block (BB) is the lowest size of
11 * filesystem allocation, and must equal 512. Length units given to bio
12 * routines are in BB's.
15 /* Assume that if we have BTOBB, then we have the rest */
18 #define BBSIZE (1<<BBSHIFT)
19 #define BBMASK (BBSIZE-1)
20 #define BTOBB(bytes) (((__u64)(bytes) + BBSIZE - 1) >> BBSHIFT)
21 #define BTOBBT(bytes) ((__u64)(bytes) >> BBSHIFT)
22 #define BBTOB(bbs) ((bbs) << BBSHIFT)
23 #define OFFTOBBT(bytes) ((__u64)(bytes) >> BBSHIFT)
25 #define SEEKLIMIT32 0x7fffffff
26 #define BBSEEKLIMIT32 BTOBBT(SEEKLIMIT32)
27 #define SEEKLIMIT 0x7fffffffffffffffLL
28 #define BBSEEKLIMIT OFFTOBBT(SEEKLIMIT)
32 #define OFFTOBB(bytes) (((__u64)(bytes) + BBSIZE - 1) >> BBSHIFT)
33 #define BBTOOFF(bbs) ((__u64)(bbs) << BBSHIFT)
36 #define FSBTOBB(f) (OFFTOBBT(FSBTOOFF(f)))
37 #define BBTOFSB(b) (OFFTOFSB(BBTOOFF(b)))
38 #define OFFTOFSB(o) ((o) / blocksize)
39 #define FSBTOOFF(f) ((f) * blocksize)
43 printf("usage: alloc [-b blocksize] [-d dir] [-f file] [-n] [-r] [-t]\n"
45 " -n - non-interractive mode\n"
46 " -r - real time file\n"
47 " -t - truncate on open\n"
50 " r [offset] [length] - reserve\n"
51 " u [offset] [length] - unreserve\n"
52 " a [offset] [length] - alloc *** identical to free\n"
53 " f [offset] [length] - free *** identical to alloc\n"
54 " m/p [offset] [length] - print map\n"
56 " t [offset] - truncate\n"
58 " h/? - this help\n");
66 /* params are in bytes */
67 void map(off64_t off, off64_t len)
71 bzero(bm, sizeof(bm));
74 bm[0].bmv_offset = OFFTOBB(off);
75 if (len==(off64_t)-1) { /* unsigned... */
76 bm[0].bmv_length = -1;
77 printf(" MAP off=%lld, len=%lld [%lld-]\n",
78 (long long)off, (long long)len,
79 (long long)BBTOFSB(bm[0].bmv_offset));
81 bm[0].bmv_length = OFFTOBB(len);
82 printf(" MAP off=%lld, len=%lld [%lld,%lld]\n",
83 (long long)off, (long long)len,
84 (long long)BBTOFSB(bm[0].bmv_offset),
85 (long long)BBTOFSB(bm[0].bmv_length));
88 printf(" [ofs,count]: start..end\n");
90 #ifdef XFS_IOC_GETBMAP
91 if (xfsctl(filename, fd, XFS_IOC_GETBMAP, bm) < 0) {
94 if (fcntl(fd, F_GETBMAP, bm) < 0) {
103 if (bm[0].bmv_entries == 0)
106 printf(" [%lld,%lld]: ",
107 (long long)BBTOFSB(bm[1].bmv_offset),
108 (long long)BBTOFSB(bm[1].bmv_length));
110 if (bm[1].bmv_block == -1)
114 (long long)BBTOFSB(bm[1].bmv_block),
115 (long long)BBTOFSB(bm[1].bmv_block +
116 bm[1].bmv_length - 1));
121 #ifdef HAVE_FALLOCATE
122 # define USE_LINUX_PREALLOCATE
130 /* emulate the irix preallocation functions with linux vfs calls */
134 enum linux_opno opno,
135 const struct flock64 *f)
140 assert(f->l_whence == SEEK_SET);
144 return ftruncate(fd, f->l_start);
146 ret = fstat(fd, &sbuf);
150 return fallocate(fd, 0, sbuf.st_size,
151 f->l_start - sbuf.st_size);
153 return fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
154 f->l_start, f->l_len);
156 return fallocate(fd, FALLOC_FL_KEEP_SIZE, f->l_start, f->l_len);
159 /* should never get here */
166 main(int argc, char **argv)
169 char *dirname = NULL;
177 static char *opnames[] = { "freesp",
183 #if defined(HAVE_FALLOCATE)
184 /* see static function above */
185 #elif defined(XFS_IOC_FREESP64)
187 /* Assume that if we have FREESP64 then we have the rest */
188 static int optab[] = { XFS_IOC_FREESP64,
192 #elif defined(F_FREESP64)
194 static int optab[] = { F_FREESP64,
199 # error Dont know how to preallocate space!
202 struct statvfs64 svfs;
208 while ((c = getopt(argc, argv, "b:d:f:rtn")) != -1) {
211 blocksize = atoi(optarg);
215 printf("can't specify both -d and -f\n");
222 printf("can't specify both -d and -f\n");
237 printf("unknown option\n");
242 if (!dirname && !filename)
245 static char tmpfile[] = "allocXXXXXX";
248 filename = malloc(strlen(tmpfile) + strlen(dirname) + 2);
249 sprintf(filename, "%s/%s", dirname, tmpfile);
252 oflags = O_RDWR | O_CREAT | (tflag ? O_TRUNC : 0);
253 fd = open(filename, oflags, 0666);
256 printf(" filename %s\n", filename);
263 if (fstatvfs64(fd, &svfs) < 0) {
268 blocksize = (int)svfs.f_bsize;
271 fprintf(stderr,"illegal blocksize %d\n", blocksize);
275 printf(" blocksize %d\n", blocksize);
279 #ifdef XFS_IOC_FSGETXATTR
280 if (xfsctl(filename, fd, XFS_IOC_FSGETXATTR, &a) < 0) {
281 perror("XFS_IOC_FSGETXATTR");
287 if (fcntl(fd, F_FSGETXATTR, &a) < 0) {
288 perror("F_FSGETXATTR");
297 a.fsx_xflags |= XFS_XFLAG_REALTIME;
299 #ifdef XFS_IOC_FSSETXATTR
300 if (xfsctl(filename, fd, XFS_IOC_FSSETXATTR, &a) < 0) {
301 perror("XFS_IOC_FSSETXATTR");
307 if (fcntl(fd, F_FSSETXATTR, &a) < 0) {
308 perror("F_FSSETXATTR");
320 if (!nflag) printf("alloc> ");
322 if (!fgets(line, 1024, stdin)) break;
325 if (p!=line&&p[-1]=='\n') p[-1]=0;
336 v = strtoll(&line[2], &p, 0);
342 f.l_whence = SEEK_SET;
347 v = strtoll(p, &p, 0);
354 printf(" CMD %s, off=%lld, len=%lld\n",
355 opnames[opno], (long long)off, (long long)len);
358 #if defined(USE_LINUX_PREALLOCATE)
359 c = linux_preallocate(fd, opno, &f);
360 #elif defined(USE_XFSCTL)
361 c = xfsctl(filename, fd, optab[opno], &f);
362 #elif defined(USE_FCNTL)
363 c = fcntl(fd, optab[opno], &f);
365 # error Dont know how to preallocate space!
368 perror(opnames[opno]);
377 v = strtoll(p, &p, 0);
386 v = strtoll(p, &p, 0);
396 v = strtoll(p, &p, 0);
401 printf(" TRUNCATE off=%lld\n", (long long)off);
402 if (ftruncate64(fd, off) < 0) {
420 printf("unknown command '%s'\n", line);
424 if (!nflag) printf("\n");