Files
scoutfs/utils/src/dev.c
Zach Brown 84454b38c5 Add mkfs -A for small device sizes
Normally mkfs would fail if we specify meta or data devices that are too
small.  We'd like to use small devices for test scenarios, though, so
add an option to allow specifying sizes smaller than the minumum
required sizes.

Signed-off-by: Zach Brown <zab@versity.com>
2021-07-07 14:13:14 -07:00

106 lines
2.1 KiB
C

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <errno.h>
#include <stdbool.h>
#include "sparse.h"
#include "dev.h"
int device_size(char *path, int fd,
u64 min_size, u64 max_size, bool allow_small_size,
char *use_type, u64 *size_ret)
{
struct stat st;
u64 size;
char *target_type;
int ret;
if (fstat(fd, &st)) {
ret = -errno;
fprintf(stderr, "failed to stat '%s': %s (%d)\n",
path, strerror(errno), errno);
return ret;
}
if (S_ISREG(st.st_mode)) {
size = st.st_size;
target_type = "file";
} else if (S_ISBLK(st.st_mode)) {
if (ioctl(fd, BLKGETSIZE64, &size)) {
ret = -errno;
fprintf(stderr, "BLKGETSIZE64 failed '%s': %s (%d)\n",
path, strerror(errno), errno);
return ret;
}
target_type = "device";
} else {
fprintf(stderr, "path isn't regular or device file '%s'\n",
path);
return -EINVAL;
}
if (max_size) {
if (size > max_size) {
printf("Limiting use of "BASE_SIZE_FMT
" %s device to "BASE_SIZE_FMT"\n",
BASE_SIZE_ARGS(size), use_type,
BASE_SIZE_ARGS(max_size));
size = max_size;
} else if (size < max_size) {
printf("Device size limit of "BASE_SIZE_FMT
" for %s device"
" is greater than "BASE_SIZE_FMT
" available, ignored.\n",
BASE_SIZE_ARGS(max_size), use_type,
BASE_SIZE_ARGS(size));
}
}
if (size < min_size) {
fprintf(stderr,
BASE_SIZE_FMT" %s too small for min "
BASE_SIZE_FMT" %s device%s\n",
BASE_SIZE_ARGS(size), target_type,
BASE_SIZE_ARGS(min_size), use_type,
allow_small_size ? ", allowing with -A" : "");
if (!allow_small_size)
return -EINVAL;
}
*size_ret = size;
return 0;
}
float size_flt(u64 nr, unsigned size)
{
float x = (float)nr * (float)size;
while (x >= 1024)
x /= 1024;
return x;
}
char *size_str(u64 nr, unsigned size)
{
float x = (float)nr * (float)size;
static char *suffixes[] = {
"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB",
};
int i = 0;
while (x >= 1024) {
x /= 1024;
i++;
}
return suffixes[i];
}